From b132efbdedec08bffbdfbdb960b1b9476662a3f1 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Tue, 12 Mar 2019 19:05:38 -0400 Subject: [PATCH] doc for sleeve api --- doc/source/advancedgameplay/sourcefiles.rst | 1 + doc/source/netscript.rst | 1 + doc/source/netscript/netscriptsleeveapi.rst | 65 +++++++++++++++++++ .../netscript/sleeveapi/commitCrime.rst | 11 ++++ .../netscript/sleeveapi/getInformation.rst | 65 +++++++++++++++++++ .../netscript/sleeveapi/getNumSleeves.rst | 6 ++ doc/source/netscript/sleeveapi/getStats.rst | 21 ++++++ doc/source/netscript/sleeveapi/getTask.rst | 18 +++++ .../netscript/sleeveapi/shockRecovery.rst | 8 +++ .../netscript/sleeveapi/synchronize.rst | 8 +++ .../sleeveapi/takeUniversityCourse.rst | 10 +++ doc/source/netscript/sleeveapi/travel.rst | 9 +++ .../netscript/sleeveapi/workForCompany.rst | 9 +++ .../netscript/sleeveapi/workForFaction.rst | 10 +++ .../netscript/sleeveapi/workoutAtGym.rst | 10 +++ src/NetscriptFunctions.js | 38 +++++++++++ 16 files changed, 290 insertions(+) create mode 100644 doc/source/netscript/netscriptsleeveapi.rst create mode 100644 doc/source/netscript/sleeveapi/commitCrime.rst create mode 100644 doc/source/netscript/sleeveapi/getInformation.rst create mode 100644 doc/source/netscript/sleeveapi/getNumSleeves.rst create mode 100644 doc/source/netscript/sleeveapi/getStats.rst create mode 100644 doc/source/netscript/sleeveapi/getTask.rst create mode 100644 doc/source/netscript/sleeveapi/shockRecovery.rst create mode 100644 doc/source/netscript/sleeveapi/synchronize.rst create mode 100644 doc/source/netscript/sleeveapi/takeUniversityCourse.rst create mode 100644 doc/source/netscript/sleeveapi/travel.rst create mode 100644 doc/source/netscript/sleeveapi/workForCompany.rst create mode 100644 doc/source/netscript/sleeveapi/workForFaction.rst create mode 100644 doc/source/netscript/sleeveapi/workoutAtGym.rst diff --git a/doc/source/advancedgameplay/sourcefiles.rst b/doc/source/advancedgameplay/sourcefiles.rst index bc7d46c91..b33bca7fa 100644 --- a/doc/source/advancedgameplay/sourcefiles.rst +++ b/doc/source/advancedgameplay/sourcefiles.rst @@ -48,6 +48,7 @@ List of all Source-Files | BitNode-9: Coming Soon | | +------------------------------------+-------------------------------------------------------------------------------------+ | BitNode-10: Digital Carbon | * Each level of this grants a Duplicate Sleeve | +| | * Allows the player to access the :ref:`netscript_sleeveapi` in other BitNodes | +------------------------------------+-------------------------------------------------------------------------------------+ | BitNode-11: The Big Crash | * Company favor increases both the player's salary and reputation gain at that | | | company by 1% per favor (rather than just the reputation gain) | diff --git a/doc/source/netscript.rst b/doc/source/netscript.rst index f2f1b9aa0..073d38323 100644 --- a/doc/source/netscript.rst +++ b/doc/source/netscript.rst @@ -29,4 +29,5 @@ to reach out to the developer! Bladeburner API Gang API Coding Contract API + Sleeve API Miscellaneous diff --git a/doc/source/netscript/netscriptsleeveapi.rst b/doc/source/netscript/netscriptsleeveapi.rst new file mode 100644 index 000000000..8f776b7b8 --- /dev/null +++ b/doc/source/netscript/netscriptsleeveapi.rst @@ -0,0 +1,65 @@ +.. _netscript_sleeveapi: + +Netscript Sleeve API +========================= +Netscript provides the following API for interacting with the game's Sleeve mechanic. + +The Sleeve API is **not** immediately available to the player and must be unlocked +later in the game. + +**WARNING: This page contains spoilers for the game** + +The Sleeve API is unlocked in BitNode-10. If you are in BitNode-10, you will +automatically gain access to this API. Otherwise, you must have Source-File 10 in +order to use this API in other BitNodes + +**Sleeve API functions must be accessed through the 'sleeve' namespace** + +In :ref:`netscript1`:: + + sleeve.synchronize(0); + sleeve.commitCrime(0, "shoplift"); + +In :ref:`netscriptjs`:: + + ns.sleeve.synchronize(0); + ns.sleeve.commitCrime(0, "shoplift"); + +.. toctree:: + :caption: Functions: + + commitCrime() + getNumSleeves() + getTask() + synchronize() + travel() + workForFaction() + getInformation() + getStats() + shockRecovery() + takeUniversityCourse() + workForCompany() + workoutAtGym() + + +Examples +-------- + +**Basic example usage**:: + + for(let i = 0; i < sleeve.getNumSleeves(); i++) { + sleeve.shockRecovery(i); + } + + await sleep(10*60*60); // wait 10h + + for(let i = 0; i < sleeve.getNumSleeves(); i++) { + sleeve.synchronize(i); + } + + await sleep(10*60*60); // wait 10h + + for(let i = 0; i < sleeve.getNumSleeves(); i++) { + sleeve.commitCrime(i, 'shoplift'); + } + diff --git a/doc/source/netscript/sleeveapi/commitCrime.rst b/doc/source/netscript/sleeveapi/commitCrime.rst new file mode 100644 index 000000000..7b8652f8a --- /dev/null +++ b/doc/source/netscript/sleeveapi/commitCrime.rst @@ -0,0 +1,11 @@ +commitCrime() Netscript Function +======================================= + +.. js:function:: commitCrime(sleeveNumber, name) + + :param int sleeveNumber: index of the sleeve to start commiting crime. + :param string name: Name of the crime. Must be an exact match. + + Return a boolean indicating whether or not this action was set successfully. + + Returns false if an invalid action is specified. diff --git a/doc/source/netscript/sleeveapi/getInformation.rst b/doc/source/netscript/sleeveapi/getInformation.rst new file mode 100644 index 000000000..de11ec982 --- /dev/null +++ b/doc/source/netscript/sleeveapi/getInformation.rst @@ -0,0 +1,65 @@ +getInformation() Netscript Function +======================================= + +.. js:function:: getInformation(sleeveNumber) + + :param int sleeveNumber: index of the sleeve to retrieve information. + + Return a struct containing tons of information about this sleeve + +.. code-block:: javascript + + { + city: location of the sleeve, + hp: current hp of the sleeve, + maxHp: max hp of the sleeve, + jobs: jobs available to the sleeve, + jobTitle: job titles available to the sleeve, + tor: does this sleeve have access to the tor router, + mult: { + agility: agility multiplier, + agilityExp: agility exp multiplier, + companyRep: company reputation multiplier, + crimeMoney: crime money multiplier, + crimeSuccess: crime success chance multiplier, + defense: defense multiplier, + defenseExp: defense exp multiplier, + dexterity: dexterity multiplier, + dexterityExp: dexterity exp multiplier, + factionRep: faction reputation multiplier, + hacking: hacking skill multiplier, + hackingExp: hacking exp multiplier, + strength: strength multiplier, + strengthExp: strength exp multiplier, + workMoney: work money multiplier, + }, + timeWorked: time spent on the current task in milliseconds, + earningsForSleeves : { earnings synchronized to other sleeves + workHackExpGain: hacking exp gained from work, + workStrExpGain: strength exp gained from work, + workDefExpGain: defense exp gained from work, + workDexExpGain: dexterity exp gained from work, + workAgiExpGain: agility exp gained from work, + workChaExpGain: charisma exp gained from work, + workMoneyGain: money gained from work, + }, + earningsForPlayer : { earnings synchronized to the player + workHackExpGain: hacking exp gained from work, + workStrExpGain: strength exp gained from work, + workDefExpGain: defense exp gained from work, + workDexExpGain: dexterity exp gained from work, + workAgiExpGain: agility exp gained from work, + workChaExpGain: charisma exp gained from work, + workMoneyGain: money gained from work, + }, + earningsForTask : { earnings for this sleeve + workHackExpGain: hacking exp gained from work, + workStrExpGain: strength exp gained from work, + workDefExpGain: defense exp gained from work, + workDexExpGain: dexterity exp gained from work, + workAgiExpGain: agility exp gained from work, + workChaExpGain: charisma exp gained from work, + workMoneyGain: money gained from work, + }, + workRepGain: sl.getRepGain(), + } diff --git a/doc/source/netscript/sleeveapi/getNumSleeves.rst b/doc/source/netscript/sleeveapi/getNumSleeves.rst new file mode 100644 index 000000000..25640992c --- /dev/null +++ b/doc/source/netscript/sleeveapi/getNumSleeves.rst @@ -0,0 +1,6 @@ +getNumSleeves() Netscript Function +======================================= + +.. js:function:: getNumSleeves() + + Return the number of duplicate sleeves the player has. diff --git a/doc/source/netscript/sleeveapi/getStats.rst b/doc/source/netscript/sleeveapi/getStats.rst new file mode 100644 index 000000000..f121ae475 --- /dev/null +++ b/doc/source/netscript/sleeveapi/getStats.rst @@ -0,0 +1,21 @@ +getStats() Netscript Function +======================================= + +.. js:function:: getStatus(sleeveNumber) + + :param int sleeveNumber: index of the sleeve to get stats of. + + Return a structure containing the stats of the sleeve + +.. code-block:: javascript + + { + shock: current shock of the sleeve [0-1], + sync: current sync of the sleeve [0-1], + hacking_skill: current hacking skill of the sleeve, + strength: current strength of the sleeve, + defense: current defense of the sleeve, + dexterity: current dexterity of the sleeve, + agility: current agility of the sleeve, + charisma: current charisma of the sleeve, + } diff --git a/doc/source/netscript/sleeveapi/getTask.rst b/doc/source/netscript/sleeveapi/getTask.rst new file mode 100644 index 000000000..e380da629 --- /dev/null +++ b/doc/source/netscript/sleeveapi/getTask.rst @@ -0,0 +1,18 @@ +getTask() Netscript Function +======================================= + +.. js:function:: getTask(sleeveNumber) + + :param int sleeveNumber: index of the sleeve to retrieve task from. + + Return the current task that the sleeve is performing. type is set to "Idle" if the sleeve isn't doing anything + +.. code-block:: javascript + + { + task: number, // task type + crime: number, // crime currently attempting, if any + location: number, // location of the task, if any + gymStatType: number, // stat being trained at the gym, if any + factionWorkType: number, // faction work type being performed, if any + } diff --git a/doc/source/netscript/sleeveapi/shockRecovery.rst b/doc/source/netscript/sleeveapi/shockRecovery.rst new file mode 100644 index 000000000..d176030f7 --- /dev/null +++ b/doc/source/netscript/sleeveapi/shockRecovery.rst @@ -0,0 +1,8 @@ +shockRecovery() Netscript Function +======================================= + +.. js:function:: shockRecovery(sleeveNumber) + + :param int sleeveNumber: index of the sleeve to start recovery. + + Return a boolean indicating whether or not this action was set successfully. \ No newline at end of file diff --git a/doc/source/netscript/sleeveapi/synchronize.rst b/doc/source/netscript/sleeveapi/synchronize.rst new file mode 100644 index 000000000..41af0165d --- /dev/null +++ b/doc/source/netscript/sleeveapi/synchronize.rst @@ -0,0 +1,8 @@ +synchronize() Netscript Function +======================================= + +.. js:function:: synchronize(sleeveNumber) + + :param int sleeveNumber: index of the sleeve to start synchronizing. + + Return a boolean indicating whether or not this action was set successfully. \ No newline at end of file diff --git a/doc/source/netscript/sleeveapi/takeUniversityCourse.rst b/doc/source/netscript/sleeveapi/takeUniversityCourse.rst new file mode 100644 index 000000000..9a87648de --- /dev/null +++ b/doc/source/netscript/sleeveapi/takeUniversityCourse.rst @@ -0,0 +1,10 @@ +takeUniversityCourse() Netscript Function +======================================= + +.. js:function:: takeUniversityCourse(sleeveNumber, university, className) + + :param int sleeveNumber: index of the sleeve to start taking class. + :param string university: name of the university to attend. + :param string className: name of the class to follow. + + Return a boolean indicating whether or not this action was set successfully. \ No newline at end of file diff --git a/doc/source/netscript/sleeveapi/travel.rst b/doc/source/netscript/sleeveapi/travel.rst new file mode 100644 index 000000000..fdae988eb --- /dev/null +++ b/doc/source/netscript/sleeveapi/travel.rst @@ -0,0 +1,9 @@ +travel() Netscript Function +======================================= + +.. js:function:: travel(sleeveNumber, cityName) + + :param int sleeveNumber: index of the sleeve to travel. + :param string cityName: name of the destination city. + + Return a boolean indicating whether or not the sleeve reached destination. \ No newline at end of file diff --git a/doc/source/netscript/sleeveapi/workForCompany.rst b/doc/source/netscript/sleeveapi/workForCompany.rst new file mode 100644 index 000000000..301bc04a7 --- /dev/null +++ b/doc/source/netscript/sleeveapi/workForCompany.rst @@ -0,0 +1,9 @@ +workForCompany() Netscript Function +======================================= + +.. js:function:: workForCompany(sleeveNumber, companyName) + + :param int sleeveNumber: index of the sleeve to work for the company. + :param string companyName: name of the company to work for. + + Return a boolean indicating whether or not the sleeve started working or this company. \ No newline at end of file diff --git a/doc/source/netscript/sleeveapi/workForFaction.rst b/doc/source/netscript/sleeveapi/workForFaction.rst new file mode 100644 index 000000000..2b94e99dd --- /dev/null +++ b/doc/source/netscript/sleeveapi/workForFaction.rst @@ -0,0 +1,10 @@ +workForFaction() Netscript Function +======================================= + +.. js:function:: workForFaction(sleeveNumber, factionName, factionWorkType) + + :param int sleeveNumber: index of the sleeve to work for the faction. + :param string factionName: name of the faction to work for. + :param string factionWorkType: name of the action to perform for this faction. + + Return a boolean indicating whether or not the sleeve started working or this faction. \ No newline at end of file diff --git a/doc/source/netscript/sleeveapi/workoutAtGym.rst b/doc/source/netscript/sleeveapi/workoutAtGym.rst new file mode 100644 index 000000000..f1207bc7a --- /dev/null +++ b/doc/source/netscript/sleeveapi/workoutAtGym.rst @@ -0,0 +1,10 @@ +workoutAtGym() Netscript Function +======================================= + +.. js:function:: workoutAtGym(sleeveNumber, gymName, stat) + + :param int sleeveNumber: index of the sleeve to workout at the gym. + :param string gymName: name of the gym. + :param string stat: name of the stat to train. + + Return a boolean indicating whether or not the sleeve started working out. \ No newline at end of file diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 4d573ae2e..2a06d7747 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -97,6 +97,7 @@ var hasCorporationSF = false, //Source-File 3 hasBladeburnerSF = false, //Source-File 6 hasBladeburner2079SF = false, //Source-File 7 hasWallStreetSF = false, //Source-File 8 + hasSleeveSF = false, //Source-File 10 hasBn11SF = false; //Source-File 11 var singularitySFLvl=1, wallStreetSFLvl=1; @@ -187,6 +188,7 @@ function initSingularitySFFlags() { hasWallStreetSF = true; wallStreetSFLvl = Player.sourceFiles[i].lvl; } + if (Player.sourceFiles[i].n === 10) {hasSleeveSF = true;} if (Player.sourceFiles[i].n === 11) {hasBn11SF = true;} } } @@ -4815,6 +4817,9 @@ function NetscriptFunctions(workerScript) { if (workerScript.checkingRam) { return updateStaticRam("getNumSleeves", CONSTANTS.ScriptSleeveBaseRamCost); } + if (Player.bitNodeN !== 10 && !hasSleeveSF) { + throw makeRuntimeRejectMsg(workerScript, "getNumSleeves() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } updateDynamicRam("getNumSleeves", CONSTANTS.ScriptSleeveBaseRamCost); return Player.sleeves.length; }, @@ -4822,6 +4827,9 @@ function NetscriptFunctions(workerScript) { if (workerScript.checkingRam) { return updateStaticRam("shockRecovery", CONSTANTS.ScriptSleeveBaseRamCost); } + if (Player.bitNodeN !== 10 && !hasSleeveSF) { + throw makeRuntimeRejectMsg(workerScript, "shockRecovery() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } updateDynamicRam("shockRecovery", CONSTANTS.ScriptSleeveBaseRamCost); if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { workerScript.log(`ERROR: sleeve.shockRecovery(${sleeveNumber}) failed because it is an invalid sleeve number.`); @@ -4834,6 +4842,9 @@ function NetscriptFunctions(workerScript) { if (workerScript.checkingRam) { return updateStaticRam("synchronize", CONSTANTS.ScriptSleeveBaseRamCost); } + if (Player.bitNodeN !== 10 && !hasSleeveSF) { + throw makeRuntimeRejectMsg(workerScript, "synchronize() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } updateDynamicRam("synchronize", CONSTANTS.ScriptSleeveBaseRamCost); if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { workerScript.log(`ERROR: sleeve.synchronize(${sleeveNumber}) failed because it is an invalid sleeve number.`); @@ -4846,6 +4857,9 @@ function NetscriptFunctions(workerScript) { if (workerScript.checkingRam) { return updateStaticRam("commitCrime", CONSTANTS.ScriptSleeveBaseRamCost); } + if (Player.bitNodeN !== 10 && !hasSleeveSF) { + throw makeRuntimeRejectMsg(workerScript, "commitCrime() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } updateDynamicRam("commitCrime", CONSTANTS.ScriptSleeveBaseRamCost); if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { workerScript.log(`ERROR: sleeve.commitCrime(${sleeveNumber}) failed because it is an invalid sleeve number.`); @@ -4858,6 +4872,9 @@ function NetscriptFunctions(workerScript) { if (workerScript.checkingRam) { return updateStaticRam("takeUniversityCourse", CONSTANTS.ScriptSleeveBaseRamCost); } + if (Player.bitNodeN !== 10 && !hasSleeveSF) { + throw makeRuntimeRejectMsg(workerScript, "takeUniversityCourse() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } updateDynamicRam("takeUniversityCourse", CONSTANTS.ScriptSleeveBaseRamCost); if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { workerScript.log(`ERROR: sleeve.takeUniversityCourse(${sleeveNumber}) failed because it is an invalid sleeve number.`); @@ -4870,6 +4887,9 @@ function NetscriptFunctions(workerScript) { if (workerScript.checkingRam) { return updateStaticRam("travel", CONSTANTS.ScriptSleeveBaseRamCost); } + if (Player.bitNodeN !== 10 && !hasSleeveSF) { + throw makeRuntimeRejectMsg(workerScript, "travel() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } updateDynamicRam("travel", CONSTANTS.ScriptSleeveBaseRamCost); if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { workerScript.log(`ERROR: sleeve.travel(${sleeveNumber}) failed because it is an invalid sleeve number.`); @@ -4882,6 +4902,9 @@ function NetscriptFunctions(workerScript) { if (workerScript.checkingRam) { return updateStaticRam("workForCompany", CONSTANTS.ScriptSleeveBaseRamCost); } + if (Player.bitNodeN !== 10 && !hasSleeveSF) { + throw makeRuntimeRejectMsg(workerScript, "workForCompany() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } updateDynamicRam("workForCompany", CONSTANTS.ScriptSleeveBaseRamCost); if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { workerScript.log(`ERROR: sleeve.workForCompany(${sleeveNumber}) failed because it is an invalid sleeve number.`); @@ -4894,6 +4917,9 @@ function NetscriptFunctions(workerScript) { if (workerScript.checkingRam) { return updateStaticRam("workForFaction", CONSTANTS.ScriptSleeveBaseRamCost); } + if (Player.bitNodeN !== 10 && !hasSleeveSF) { + throw makeRuntimeRejectMsg(workerScript, "workForFaction() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } updateDynamicRam("workForFaction", CONSTANTS.ScriptSleeveBaseRamCost); if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { workerScript.log(`ERROR: sleeve.workForFaction(${sleeveNumber}) failed because it is an invalid sleeve number.`); @@ -4906,6 +4932,9 @@ function NetscriptFunctions(workerScript) { if (workerScript.checkingRam) { return updateStaticRam("workoutAtGym", CONSTANTS.ScriptSleeveBaseRamCost); } + if (Player.bitNodeN !== 10 && !hasSleeveSF) { + throw makeRuntimeRejectMsg(workerScript, "workoutAtGym() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } updateDynamicRam("workoutAtGym", CONSTANTS.ScriptSleeveBaseRamCost); if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { workerScript.log(`ERROR: sleeve.workoutAtGym(${sleeveNumber}) failed because it is an invalid sleeve number.`); @@ -4918,6 +4947,9 @@ function NetscriptFunctions(workerScript) { if (workerScript.checkingRam) { return updateStaticRam("workoutAtGym", CONSTANTS.ScriptSleeveBaseRamCost); } + if (Player.bitNodeN !== 10 && !hasSleeveSF) { + throw makeRuntimeRejectMsg(workerScript, "getStats() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } updateDynamicRam("workoutAtGym", CONSTANTS.ScriptSleeveBaseRamCost); if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { workerScript.log(`ERROR: sleeve.workoutAtGym(${sleeveNumber}) failed because it is an invalid sleeve number.`); @@ -4940,6 +4972,9 @@ function NetscriptFunctions(workerScript) { if (workerScript.checkingRam) { return updateStaticRam("getTask", CONSTANTS.ScriptSleeveBaseRamCost); } + if (Player.bitNodeN !== 10 && !hasSleeveSF) { + throw makeRuntimeRejectMsg(workerScript, "getTask() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } updateDynamicRam("getTask", CONSTANTS.ScriptSleeveBaseRamCost); if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { workerScript.log(`ERROR: sleeve.getTask(${sleeveNumber}) failed because it is an invalid sleeve number.`); @@ -4959,6 +4994,9 @@ function NetscriptFunctions(workerScript) { if (workerScript.checkingRam) { return updateStaticRam("getInformation", CONSTANTS.ScriptSleeveBaseRamCost); } + if (Player.bitNodeN !== 10 && !hasSleeveSF) { + throw makeRuntimeRejectMsg(workerScript, "getInformation() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } updateDynamicRam("getInformation", CONSTANTS.ScriptSleeveBaseRamCost); if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { workerScript.log(`ERROR: sleeve.getInformation(${sleeveNumber}) failed because it is an invalid sleeve number.`);