mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-23 08:03:48 +01:00
Merge pull request #1484 from danielyxie/dev
Split some netscript functions
This commit is contained in:
commit
c7deb895ba
34
dist/vendor.bundle.js
vendored
34
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
15
doc/source/netscript/basicfunctions/alert.rst
Normal file
15
doc/source/netscript/basicfunctions/alert.rst
Normal file
@ -0,0 +1,15 @@
|
||||
alert() Netscript Function
|
||||
============================
|
||||
|
||||
.. js:function:: alert(message)
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param string message: message to display
|
||||
|
||||
Spawns an alert box.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
alert("Reached $1b");
|
17
doc/source/netscript/basicfunctions/toast.rst
Normal file
17
doc/source/netscript/basicfunctions/toast.rst
Normal file
@ -0,0 +1,17 @@
|
||||
toast() Netscript Function
|
||||
============================
|
||||
|
||||
.. js:function:: toast(message[, variant])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param string message: message to display
|
||||
:param success|info|warning|error variant: color of the toast
|
||||
|
||||
Spawns a toast (those bottom left notifications).
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
toast("Reached $1b");
|
||||
toast("Failed to hack home", "error");
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -13,12 +13,14 @@ import { Reviver } from "../utils/JSONReviver";
|
||||
function sendMessage(msg: Message, forced = false): void {
|
||||
msg.recvd = true;
|
||||
if (forced || !Settings.SuppressMessages) {
|
||||
showMessage(msg);
|
||||
showMessage(msg.filename);
|
||||
}
|
||||
addMessageToServer(msg, "home");
|
||||
}
|
||||
|
||||
function showMessage(msg: Message): void {
|
||||
function showMessage(name: string): void {
|
||||
const msg = Messages[name];
|
||||
if (!msg) throw new Error("trying to display unexistent message");
|
||||
const txt =
|
||||
"Message received from unknown sender: <br><br>" +
|
||||
"<i>" +
|
||||
@ -39,12 +41,11 @@ function addMessageToServer(msg: Message, serverHostname: string): void {
|
||||
}
|
||||
for (let i = 0; i < server.messages.length; ++i) {
|
||||
const other = server.messages[i];
|
||||
if (typeof other === "string") continue;
|
||||
if (msg.filename === other.filename) {
|
||||
if (msg.filename === other) {
|
||||
return; //Already exists
|
||||
}
|
||||
}
|
||||
server.messages.push(msg);
|
||||
server.messages.push(msg.filename);
|
||||
}
|
||||
|
||||
//Checks if any of the 'timed' messages should be sent
|
||||
|
File diff suppressed because it is too large
Load Diff
224
src/NetscriptFunctions/Augmentations.ts
Normal file
224
src/NetscriptFunctions/Augmentations.ts
Normal file
@ -0,0 +1,224 @@
|
||||
import { INetscriptHelper } from "./INetscriptHelper";
|
||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { purchaseAugmentation } from "../Faction/FactionHelpers";
|
||||
import { startWorkerScript } from "../NetscriptWorker";
|
||||
import { Augmentation } from "../Augmentation/Augmentation";
|
||||
import { Augmentations } from "../Augmentation/Augmentations";
|
||||
import { augmentationExists, installAugmentations } from "../Augmentation/AugmentationHelpers";
|
||||
import { prestigeAugmentation } from "../Prestige";
|
||||
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||
import { killWorkerScript } from "../Netscript/killWorkerScript";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { isString } from "../utils/helpers/isString";
|
||||
import { getRamCost } from "../Netscript/RamCostGenerator";
|
||||
import { RunningScript } from "../Script/RunningScript";
|
||||
|
||||
export interface INetscriptAugmentations {
|
||||
getOwnedAugmentations(purchased?: any): any;
|
||||
getOwnedSourceFiles(): any;
|
||||
getAugmentationsFromFaction(facname: any): any;
|
||||
getAugmentationCost(name: any): any;
|
||||
getAugmentationPrereq(name: any): any;
|
||||
getAugmentationPrice(name: any): any;
|
||||
getAugmentationRepReq(name: any): any;
|
||||
getAugmentationStats(name: any): any;
|
||||
purchaseAugmentation(faction: any, name: any): any;
|
||||
softReset(cbScript: any): any;
|
||||
installAugmentations(cbScript: any): any;
|
||||
}
|
||||
|
||||
export function NetscriptAugmentations(
|
||||
player: IPlayer,
|
||||
workerScript: WorkerScript,
|
||||
helper: INetscriptHelper,
|
||||
): INetscriptAugmentations {
|
||||
const getAugmentation = function (func: any, name: any): Augmentation {
|
||||
if (!augmentationExists(name)) {
|
||||
throw helper.makeRuntimeErrorMsg(func, `Invalid augmentation: '${name}'`);
|
||||
}
|
||||
|
||||
return Augmentations[name];
|
||||
};
|
||||
const runAfterReset = function (cbScript = null): void {
|
||||
//Run a script after reset
|
||||
if (cbScript && isString(cbScript)) {
|
||||
const home = player.getHomeComputer();
|
||||
for (const script of home.scripts) {
|
||||
if (script.filename === cbScript) {
|
||||
const ramUsage = script.ramUsage;
|
||||
const ramAvailable = home.maxRam - home.ramUsed;
|
||||
if (ramUsage > ramAvailable) {
|
||||
return; // Not enough RAM
|
||||
}
|
||||
const runningScriptObj = new RunningScript(script, []); // No args
|
||||
runningScriptObj.threads = 1; // Only 1 thread
|
||||
startWorkerScript(runningScriptObj, home);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return {
|
||||
getOwnedAugmentations: function (purchased: any = false): any {
|
||||
helper.updateDynamicRam("getOwnedAugmentations", getRamCost("getOwnedAugmentations"));
|
||||
helper.checkSingularityAccess("getOwnedAugmentations", 3);
|
||||
const res = [];
|
||||
for (let i = 0; i < player.augmentations.length; ++i) {
|
||||
res.push(player.augmentations[i].name);
|
||||
}
|
||||
if (purchased) {
|
||||
for (let i = 0; i < player.queuedAugmentations.length; ++i) {
|
||||
res.push(player.queuedAugmentations[i].name);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
},
|
||||
getOwnedSourceFiles: function (): any {
|
||||
helper.updateDynamicRam("getOwnedSourceFiles", getRamCost("getOwnedSourceFiles"));
|
||||
helper.checkSingularityAccess("getOwnedSourceFiles", 3);
|
||||
const res = [];
|
||||
for (let i = 0; i < player.sourceFiles.length; ++i) {
|
||||
res.push({
|
||||
n: player.sourceFiles[i].n,
|
||||
lvl: player.sourceFiles[i].lvl,
|
||||
});
|
||||
}
|
||||
return res;
|
||||
},
|
||||
getAugmentationsFromFaction: function (facname: any): any {
|
||||
helper.updateDynamicRam("getAugmentationsFromFaction", getRamCost("getAugmentationsFromFaction"));
|
||||
helper.checkSingularityAccess("getAugmentationsFromFaction", 3);
|
||||
const faction = helper.getFaction("getAugmentationsFromFaction", facname);
|
||||
|
||||
// If player has a gang with this faction, return all augmentations.
|
||||
if (player.hasGangWith(facname)) {
|
||||
const res = [];
|
||||
for (const augName in Augmentations) {
|
||||
const aug = Augmentations[augName];
|
||||
if (!aug.isSpecial) {
|
||||
res.push(augName);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return faction.augmentations.slice();
|
||||
},
|
||||
getAugmentationCost: function (name: any): any {
|
||||
helper.updateDynamicRam("getAugmentationCost", getRamCost("getAugmentationCost"));
|
||||
helper.checkSingularityAccess("getAugmentationCost", 3);
|
||||
const aug = getAugmentation("getAugmentationCost", name);
|
||||
return [aug.baseRepRequirement, aug.baseCost];
|
||||
},
|
||||
getAugmentationPrereq: function (name: any): any {
|
||||
helper.updateDynamicRam("getAugmentationPrereq", getRamCost("getAugmentationPrereq"));
|
||||
helper.checkSingularityAccess("getAugmentationPrereq", 3);
|
||||
const aug = getAugmentation("getAugmentationPrereq", name);
|
||||
return aug.prereqs.slice();
|
||||
},
|
||||
getAugmentationPrice: function (name: any): any {
|
||||
helper.updateDynamicRam("getAugmentationPrice", getRamCost("getAugmentationPrice"));
|
||||
helper.checkSingularityAccess("getAugmentationPrice", 3);
|
||||
const aug = getAugmentation("getAugmentationPrice", name);
|
||||
return aug.baseCost;
|
||||
},
|
||||
getAugmentationRepReq: function (name: any): any {
|
||||
helper.updateDynamicRam("getAugmentationRepReq", getRamCost("getAugmentationRepReq"));
|
||||
helper.checkSingularityAccess("getAugmentationRepReq", 3);
|
||||
const aug = getAugmentation("getAugmentationRepReq", name);
|
||||
return aug.baseRepRequirement;
|
||||
},
|
||||
getAugmentationStats: function (name: any): any {
|
||||
helper.updateDynamicRam("getAugmentationStats", getRamCost("getAugmentationStats"));
|
||||
helper.checkSingularityAccess("getAugmentationStats", 3);
|
||||
const aug = getAugmentation("getAugmentationStats", name);
|
||||
return Object.assign({}, aug.mults);
|
||||
},
|
||||
purchaseAugmentation: function (faction: any, name: any): any {
|
||||
helper.updateDynamicRam("purchaseAugmentation", getRamCost("purchaseAugmentation"));
|
||||
helper.checkSingularityAccess("purchaseAugmentation", 3);
|
||||
const fac = helper.getFaction("purchaseAugmentation", faction);
|
||||
const aug = getAugmentation("purchaseAugmentation", name);
|
||||
|
||||
let augs = [];
|
||||
if (player.hasGangWith(faction)) {
|
||||
for (const augName in Augmentations) {
|
||||
const tempAug = Augmentations[augName];
|
||||
if (!tempAug.isSpecial) {
|
||||
augs.push(augName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
augs = fac.augmentations;
|
||||
}
|
||||
|
||||
if (!augs.includes(name)) {
|
||||
workerScript.log("purchaseAugmentation", `Faction '${faction}' does not have the '${name}' augmentation.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
const isNeuroflux = aug.name === AugmentationNames.NeuroFluxGovernor;
|
||||
if (!isNeuroflux) {
|
||||
for (let j = 0; j < player.queuedAugmentations.length; ++j) {
|
||||
if (player.queuedAugmentations[j].name === aug.name) {
|
||||
workerScript.log("purchaseAugmentation", `You already have the '${name}' augmentation.`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (let j = 0; j < player.augmentations.length; ++j) {
|
||||
if (player.augmentations[j].name === aug.name) {
|
||||
workerScript.log("purchaseAugmentation", `You already have the '${name}' augmentation.`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fac.playerReputation < aug.baseRepRequirement) {
|
||||
workerScript.log("purchaseAugmentation", `You do not have enough reputation with '${fac.name}'.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
const res = purchaseAugmentation(aug, fac, true);
|
||||
workerScript.log("purchaseAugmentation", res);
|
||||
if (isString(res) && res.startsWith("You purchased")) {
|
||||
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
softReset: function (cbScript: any): any {
|
||||
helper.updateDynamicRam("softReset", getRamCost("softReset"));
|
||||
helper.checkSingularityAccess("softReset", 3);
|
||||
|
||||
workerScript.log("softReset", "Soft resetting. This will cause this script to be killed");
|
||||
setTimeout(() => {
|
||||
prestigeAugmentation();
|
||||
runAfterReset(cbScript);
|
||||
}, 0);
|
||||
|
||||
// Prevent workerScript from "finishing execution naturally"
|
||||
workerScript.running = false;
|
||||
killWorkerScript(workerScript);
|
||||
},
|
||||
installAugmentations: function (cbScript: any): any {
|
||||
helper.updateDynamicRam("installAugmentations", getRamCost("installAugmentations"));
|
||||
helper.checkSingularityAccess("installAugmentations", 3);
|
||||
|
||||
if (player.queuedAugmentations.length === 0) {
|
||||
workerScript.log("installAugmentations", "You do not have any Augmentations to be installed.");
|
||||
return false;
|
||||
}
|
||||
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
|
||||
workerScript.log("installAugmentations", "Installing Augmentations. This will cause this script to be killed");
|
||||
setTimeout(() => {
|
||||
installAugmentations();
|
||||
runAfterReset(cbScript);
|
||||
}, 0);
|
||||
|
||||
workerScript.running = false; // Prevent workerScript from "finishing execution naturally"
|
||||
killWorkerScript(workerScript);
|
||||
},
|
||||
};
|
||||
}
|
403
src/NetscriptFunctions/Bladeburner.ts
Normal file
403
src/NetscriptFunctions/Bladeburner.ts
Normal file
@ -0,0 +1,403 @@
|
||||
import { INetscriptHelper } from "./INetscriptHelper";
|
||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { Bladeburner } from "../Bladeburner/Bladeburner";
|
||||
import { getRamCost } from "../Netscript/RamCostGenerator";
|
||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||
|
||||
export interface INetscriptBladeburner {
|
||||
getContractNames(): any;
|
||||
getOperationNames(): any;
|
||||
getBlackOpNames(): any;
|
||||
getBlackOpRank(name?: any): any;
|
||||
getGeneralActionNames(): any;
|
||||
getSkillNames(): any;
|
||||
startAction(type?: any, name?: any): any;
|
||||
stopBladeburnerAction(): any;
|
||||
getCurrentAction(): any;
|
||||
getActionTime(type?: any, name?: any): any;
|
||||
getActionEstimatedSuccessChance(type?: any, name?: any): any;
|
||||
getActionRepGain(type?: any, name?: any, level?: any): any;
|
||||
getActionCountRemaining(type?: any, name?: any): any;
|
||||
getActionMaxLevel(type?: any, name?: any): any;
|
||||
getActionCurrentLevel(type?: any, name?: any): any;
|
||||
getActionAutolevel(type?: any, name?: any): any;
|
||||
setActionAutolevel(type?: any, name?: any, autoLevel?: any): any;
|
||||
setActionLevel(type?: any, name?: any, level?: any): any;
|
||||
getRank(): any;
|
||||
getSkillPoints(): any;
|
||||
getSkillLevel(skillName?: any): any;
|
||||
getSkillUpgradeCost(skillName?: any): any;
|
||||
upgradeSkill(skillName: any): any;
|
||||
getTeamSize(type?: any, name?: any): any;
|
||||
setTeamSize(type?: any, name?: any, size?: any): any;
|
||||
getCityEstimatedPopulation(cityName: any): any;
|
||||
getCityEstimatedCommunities(cityName: any): any;
|
||||
getCityChaos(cityName: any): any;
|
||||
getCity(): any;
|
||||
switchCity(cityName: any): any;
|
||||
getStamina(): any;
|
||||
joinBladeburnerFaction(): any;
|
||||
joinBladeburnerDivision(): any;
|
||||
getBonusTime(): any;
|
||||
}
|
||||
|
||||
export function NetscriptBladeburner(
|
||||
player: IPlayer,
|
||||
workerScript: WorkerScript,
|
||||
helper: INetscriptHelper,
|
||||
): INetscriptBladeburner {
|
||||
const checkBladeburnerAccess = function (func: any, skipjoined: any = false): void {
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Must have joined bladeburner");
|
||||
const apiAccess =
|
||||
player.bitNodeN === 7 ||
|
||||
player.sourceFiles.some((a) => {
|
||||
return a.n === 7;
|
||||
});
|
||||
if (!apiAccess) {
|
||||
const apiDenied = `You do not currently have access to the Bladeburner API. You must either be in BitNode-7 or have Source-File 7.`;
|
||||
throw helper.makeRuntimeErrorMsg(`bladeburner.${func}`, apiDenied);
|
||||
}
|
||||
if (!skipjoined) {
|
||||
const bladeburnerAccess = bladeburner instanceof Bladeburner;
|
||||
if (!bladeburnerAccess) {
|
||||
const bladeburnerDenied = `You must be a member of the Bladeburner division to use this API.`;
|
||||
throw helper.makeRuntimeErrorMsg(`bladeburner.${func}`, bladeburnerDenied);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const checkBladeburnerCity = function (func: any, city: any): void {
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Must have joined bladeburner");
|
||||
if (!bladeburner.cities.hasOwnProperty(city)) {
|
||||
throw helper.makeRuntimeErrorMsg(`bladeburner.${func}`, `Invalid city: ${city}`);
|
||||
}
|
||||
};
|
||||
|
||||
const getBladeburnerActionObject = function (func: any, type: any, name: any): any {
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Must have joined bladeburner");
|
||||
const actionId = bladeburner.getActionIdFromTypeAndName(type, name);
|
||||
if (!actionId) {
|
||||
throw helper.makeRuntimeErrorMsg(`bladeburner.${func}`, `Invalid action type='${type}', name='${name}'`);
|
||||
}
|
||||
const actionObj = bladeburner.getActionObject(actionId);
|
||||
if (!actionObj) {
|
||||
throw helper.makeRuntimeErrorMsg(`bladeburner.${func}`, `Invalid action type='${type}', name='${name}'`);
|
||||
}
|
||||
|
||||
return actionObj;
|
||||
};
|
||||
|
||||
return {
|
||||
getContractNames: function (): any {
|
||||
helper.updateDynamicRam("getContractNames", getRamCost("bladeburner", "getContractNames"));
|
||||
checkBladeburnerAccess("getContractNames");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.getContractNamesNetscriptFn();
|
||||
},
|
||||
getOperationNames: function (): any {
|
||||
helper.updateDynamicRam("getOperationNames", getRamCost("bladeburner", "getOperationNames"));
|
||||
checkBladeburnerAccess("getOperationNames");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.getOperationNamesNetscriptFn();
|
||||
},
|
||||
getBlackOpNames: function (): any {
|
||||
helper.updateDynamicRam("getBlackOpNames", getRamCost("bladeburner", "getBlackOpNames"));
|
||||
checkBladeburnerAccess("getBlackOpNames");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.getBlackOpNamesNetscriptFn();
|
||||
},
|
||||
getBlackOpRank: function (name: any = ""): any {
|
||||
helper.updateDynamicRam("getBlackOpRank", getRamCost("bladeburner", "getBlackOpRank"));
|
||||
checkBladeburnerAccess("getBlackOpRank");
|
||||
const action: any = getBladeburnerActionObject("getBlackOpRank", "blackops", name);
|
||||
return action.reqdRank;
|
||||
},
|
||||
getGeneralActionNames: function (): any {
|
||||
helper.updateDynamicRam("getGeneralActionNames", getRamCost("bladeburner", "getGeneralActionNames"));
|
||||
checkBladeburnerAccess("getGeneralActionNames");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.getGeneralActionNamesNetscriptFn();
|
||||
},
|
||||
getSkillNames: function (): any {
|
||||
helper.updateDynamicRam("getSkillNames", getRamCost("bladeburner", "getSkillNames"));
|
||||
checkBladeburnerAccess("getSkillNames");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.getSkillNamesNetscriptFn();
|
||||
},
|
||||
startAction: function (type: any = "", name: any = ""): any {
|
||||
helper.updateDynamicRam("startAction", getRamCost("bladeburner", "startAction"));
|
||||
checkBladeburnerAccess("startAction");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
try {
|
||||
return bladeburner.startActionNetscriptFn(player, type, name, workerScript);
|
||||
} catch (e: any) {
|
||||
throw helper.makeRuntimeErrorMsg("bladeburner.startAction", e);
|
||||
}
|
||||
},
|
||||
stopBladeburnerAction: function (): any {
|
||||
helper.updateDynamicRam("stopBladeburnerAction", getRamCost("bladeburner", "stopBladeburnerAction"));
|
||||
checkBladeburnerAccess("stopBladeburnerAction");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.resetAction();
|
||||
},
|
||||
getCurrentAction: function (): any {
|
||||
helper.updateDynamicRam("getCurrentAction", getRamCost("bladeburner", "getCurrentAction"));
|
||||
checkBladeburnerAccess("getCurrentAction");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.getTypeAndNameFromActionId(bladeburner.action);
|
||||
},
|
||||
getActionTime: function (type: any = "", name: any = ""): any {
|
||||
helper.updateDynamicRam("getActionTime", getRamCost("bladeburner", "getActionTime"));
|
||||
checkBladeburnerAccess("getActionTime");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
try {
|
||||
return bladeburner.getActionTimeNetscriptFn(player, type, name, workerScript);
|
||||
} catch (e: any) {
|
||||
throw helper.makeRuntimeErrorMsg("bladeburner.getActionTime", e);
|
||||
}
|
||||
},
|
||||
getActionEstimatedSuccessChance: function (type: any = "", name: any = ""): any {
|
||||
helper.updateDynamicRam(
|
||||
"getActionEstimatedSuccessChance",
|
||||
getRamCost("bladeburner", "getActionEstimatedSuccessChance"),
|
||||
);
|
||||
checkBladeburnerAccess("getActionEstimatedSuccessChance");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
try {
|
||||
return bladeburner.getActionEstimatedSuccessChanceNetscriptFn(player, type, name, workerScript);
|
||||
} catch (e: any) {
|
||||
throw helper.makeRuntimeErrorMsg("bladeburner.getActionEstimatedSuccessChance", e);
|
||||
}
|
||||
},
|
||||
getActionRepGain: function (type: any = "", name: any = "", level: any): any {
|
||||
helper.updateDynamicRam("getActionRepGain", getRamCost("bladeburner", "getActionRepGain"));
|
||||
checkBladeburnerAccess("getActionRepGain");
|
||||
const action = getBladeburnerActionObject("getActionRepGain", type, name);
|
||||
let rewardMultiplier;
|
||||
if (level == null || isNaN(level)) {
|
||||
rewardMultiplier = Math.pow(action.rewardFac, action.level - 1);
|
||||
} else {
|
||||
rewardMultiplier = Math.pow(action.rewardFac, level - 1);
|
||||
}
|
||||
|
||||
return action.rankGain * rewardMultiplier * BitNodeMultipliers.BladeburnerRank;
|
||||
},
|
||||
getActionCountRemaining: function (type: any = "", name: any = ""): any {
|
||||
helper.updateDynamicRam("getActionCountRemaining", getRamCost("bladeburner", "getActionCountRemaining"));
|
||||
checkBladeburnerAccess("getActionCountRemaining");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
try {
|
||||
return bladeburner.getActionCountRemainingNetscriptFn(type, name, workerScript);
|
||||
} catch (e: any) {
|
||||
throw helper.makeRuntimeErrorMsg("bladeburner.getActionCountRemaining", e);
|
||||
}
|
||||
},
|
||||
getActionMaxLevel: function (type: any = "", name: any = ""): any {
|
||||
helper.updateDynamicRam("getActionMaxLevel", getRamCost("bladeburner", "getActionMaxLevel"));
|
||||
checkBladeburnerAccess("getActionMaxLevel");
|
||||
const action = getBladeburnerActionObject("getActionMaxLevel", type, name);
|
||||
return action.maxLevel;
|
||||
},
|
||||
getActionCurrentLevel: function (type: any = "", name: any = ""): any {
|
||||
helper.updateDynamicRam("getActionCurrentLevel", getRamCost("bladeburner", "getActionCurrentLevel"));
|
||||
checkBladeburnerAccess("getActionCurrentLevel");
|
||||
const action = getBladeburnerActionObject("getActionCurrentLevel", type, name);
|
||||
return action.level;
|
||||
},
|
||||
getActionAutolevel: function (type: any = "", name: any = ""): any {
|
||||
helper.updateDynamicRam("getActionAutolevel", getRamCost("bladeburner", "getActionAutolevel"));
|
||||
checkBladeburnerAccess("getActionAutolevel");
|
||||
const action = getBladeburnerActionObject("getActionCurrentLevel", type, name);
|
||||
return action.autoLevel;
|
||||
},
|
||||
setActionAutolevel: function (type: any = "", name: any = "", autoLevel: any = true): any {
|
||||
helper.updateDynamicRam("setActionAutolevel", getRamCost("bladeburner", "setActionAutolevel"));
|
||||
checkBladeburnerAccess("setActionAutolevel");
|
||||
const action = getBladeburnerActionObject("setActionAutolevel", type, name);
|
||||
action.autoLevel = autoLevel;
|
||||
},
|
||||
setActionLevel: function (type: any = "", name: any = "", level: any = 1): any {
|
||||
helper.updateDynamicRam("setActionLevel", getRamCost("bladeburner", "setActionLevel"));
|
||||
checkBladeburnerAccess("setActionLevel");
|
||||
const action = getBladeburnerActionObject("setActionLevel", type, name);
|
||||
if (level < 1 || level > action.maxLevel) {
|
||||
throw helper.makeRuntimeErrorMsg(
|
||||
"bladeburner.setActionLevel",
|
||||
`Level must be between 1 and ${action.maxLevel}, is ${level}`,
|
||||
);
|
||||
}
|
||||
action.level = level;
|
||||
},
|
||||
getRank: function (): any {
|
||||
helper.updateDynamicRam("getRank", getRamCost("bladeburner", "getRank"));
|
||||
checkBladeburnerAccess("getRank");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.rank;
|
||||
},
|
||||
getSkillPoints: function (): any {
|
||||
helper.updateDynamicRam("getSkillPoints", getRamCost("bladeburner", "getSkillPoints"));
|
||||
checkBladeburnerAccess("getSkillPoints");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.skillPoints;
|
||||
},
|
||||
getSkillLevel: function (skillName: any = ""): any {
|
||||
helper.updateDynamicRam("getSkillLevel", getRamCost("bladeburner", "getSkillLevel"));
|
||||
checkBladeburnerAccess("getSkillLevel");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
try {
|
||||
return bladeburner.getSkillLevelNetscriptFn(skillName, workerScript);
|
||||
} catch (e: any) {
|
||||
throw helper.makeRuntimeErrorMsg("bladeburner.getSkillLevel", e);
|
||||
}
|
||||
},
|
||||
getSkillUpgradeCost: function (skillName: any = ""): any {
|
||||
helper.updateDynamicRam("getSkillUpgradeCost", getRamCost("bladeburner", "getSkillUpgradeCost"));
|
||||
checkBladeburnerAccess("getSkillUpgradeCost");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
try {
|
||||
return bladeburner.getSkillUpgradeCostNetscriptFn(skillName, workerScript);
|
||||
} catch (e: any) {
|
||||
throw helper.makeRuntimeErrorMsg("bladeburner.getSkillUpgradeCost", e);
|
||||
}
|
||||
},
|
||||
upgradeSkill: function (skillName: any): any {
|
||||
helper.updateDynamicRam("upgradeSkill", getRamCost("bladeburner", "upgradeSkill"));
|
||||
checkBladeburnerAccess("upgradeSkill");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
try {
|
||||
return bladeburner.upgradeSkillNetscriptFn(skillName, workerScript);
|
||||
} catch (e: any) {
|
||||
throw helper.makeRuntimeErrorMsg("bladeburner.upgradeSkill", e);
|
||||
}
|
||||
},
|
||||
getTeamSize: function (type: any = "", name: any = ""): any {
|
||||
helper.updateDynamicRam("getTeamSize", getRamCost("bladeburner", "getTeamSize"));
|
||||
checkBladeburnerAccess("getTeamSize");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
try {
|
||||
return bladeburner.getTeamSizeNetscriptFn(type, name, workerScript);
|
||||
} catch (e: any) {
|
||||
throw helper.makeRuntimeErrorMsg("bladeburner.getTeamSize", e);
|
||||
}
|
||||
},
|
||||
setTeamSize: function (type: any = "", name: any = "", size: any): any {
|
||||
helper.updateDynamicRam("setTeamSize", getRamCost("bladeburner", "setTeamSize"));
|
||||
checkBladeburnerAccess("setTeamSize");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
try {
|
||||
return bladeburner.setTeamSizeNetscriptFn(type, name, size, workerScript);
|
||||
} catch (e: any) {
|
||||
throw helper.makeRuntimeErrorMsg("bladeburner.setTeamSize", e);
|
||||
}
|
||||
},
|
||||
getCityEstimatedPopulation: function (cityName: any): any {
|
||||
helper.updateDynamicRam("getCityEstimatedPopulation", getRamCost("bladeburner", "getCityEstimatedPopulation"));
|
||||
checkBladeburnerAccess("getCityEstimatedPopulation");
|
||||
checkBladeburnerCity("getCityEstimatedPopulation", cityName);
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.cities[cityName].popEst;
|
||||
},
|
||||
getCityEstimatedCommunities: function (cityName: any): any {
|
||||
helper.updateDynamicRam("getCityEstimatedCommunities", getRamCost("bladeburner", "getCityEstimatedCommunities"));
|
||||
checkBladeburnerAccess("getCityEstimatedCommunities");
|
||||
checkBladeburnerCity("getCityEstimatedCommunities", cityName);
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.cities[cityName].commsEst;
|
||||
},
|
||||
getCityChaos: function (cityName: any): any {
|
||||
helper.updateDynamicRam("getCityChaos", getRamCost("bladeburner", "getCityChaos"));
|
||||
checkBladeburnerAccess("getCityChaos");
|
||||
checkBladeburnerCity("getCityChaos", cityName);
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.cities[cityName].chaos;
|
||||
},
|
||||
getCity: function (): any {
|
||||
helper.updateDynamicRam("getCity", getRamCost("bladeburner", "getCity"));
|
||||
checkBladeburnerAccess("getCityChaos");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.city;
|
||||
},
|
||||
switchCity: function (cityName: any): any {
|
||||
helper.updateDynamicRam("switchCity", getRamCost("bladeburner", "switchCity"));
|
||||
checkBladeburnerAccess("switchCity");
|
||||
checkBladeburnerCity("switchCity", cityName);
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return (bladeburner.city = cityName);
|
||||
},
|
||||
getStamina: function (): any {
|
||||
helper.updateDynamicRam("getStamina", getRamCost("bladeburner", "getStamina"));
|
||||
checkBladeburnerAccess("getStamina");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return [bladeburner.stamina, bladeburner.maxStamina];
|
||||
},
|
||||
joinBladeburnerFaction: function (): any {
|
||||
helper.updateDynamicRam("joinBladeburnerFaction", getRamCost("bladeburner", "joinBladeburnerFaction"));
|
||||
checkBladeburnerAccess("joinBladeburnerFaction", true);
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.joinBladeburnerFactionNetscriptFn(workerScript);
|
||||
},
|
||||
joinBladeburnerDivision: function (): any {
|
||||
helper.updateDynamicRam("joinBladeburnerDivision", getRamCost("bladeburner", "joinBladeburnerDivision"));
|
||||
if (player.bitNodeN === 7 || player.sourceFileLvl(7) > 0) {
|
||||
if (player.bitNodeN === 8) {
|
||||
return false;
|
||||
}
|
||||
if (player.bladeburner instanceof Bladeburner) {
|
||||
return true; // Already member
|
||||
} else if (
|
||||
player.strength >= 100 &&
|
||||
player.defense >= 100 &&
|
||||
player.dexterity >= 100 &&
|
||||
player.agility >= 100
|
||||
) {
|
||||
player.bladeburner = new Bladeburner(player);
|
||||
workerScript.log("joinBladeburnerDivision", "You have been accepted into the Bladeburner division");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
workerScript.log(
|
||||
"joinBladeburnerDivision",
|
||||
"You do not meet the requirements for joining the Bladeburner division",
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
getBonusTime: function (): any {
|
||||
helper.updateDynamicRam("getBonusTime", getRamCost("bladeburner", "getBonusTime"));
|
||||
checkBladeburnerAccess("getBonusTime");
|
||||
const bladeburner = player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return Math.round(bladeburner.storedCycles / 5);
|
||||
},
|
||||
};
|
||||
}
|
109
src/NetscriptFunctions/CodingContract.ts
Normal file
109
src/NetscriptFunctions/CodingContract.ts
Normal file
@ -0,0 +1,109 @@
|
||||
import { INetscriptHelper } from "./INetscriptHelper";
|
||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { getRamCost } from "../Netscript/RamCostGenerator";
|
||||
import { is2DArray } from "../utils/helpers/is2DArray";
|
||||
import { CodingContract } from "../CodingContracts";
|
||||
|
||||
export interface INetscriptCodingContract {
|
||||
attempt(answer: any, fn: any, ip?: any, options?: { returnReward: any }): any;
|
||||
getContractType(fn: any, ip?: any): any;
|
||||
getData(fn: any, ip?: any): any;
|
||||
getDescription(fn: any, ip?: any): any;
|
||||
getNumTriesRemaining(fn: any, ip?: any): any;
|
||||
}
|
||||
|
||||
export function NetscriptCodingContract(
|
||||
player: IPlayer,
|
||||
workerScript: WorkerScript,
|
||||
helper: INetscriptHelper,
|
||||
): INetscriptCodingContract {
|
||||
const getCodingContract = function (func: any, ip: any, fn: any): CodingContract {
|
||||
const server = helper.getServer(ip, func);
|
||||
const contract = server.getContract(fn);
|
||||
if (contract == null) {
|
||||
throw helper.makeRuntimeErrorMsg(`codingcontract.${func}`, `Cannot find contract '${fn}' on server '${ip}'`);
|
||||
}
|
||||
|
||||
return contract;
|
||||
};
|
||||
|
||||
return {
|
||||
attempt: function (answer: any, fn: any, ip: any = workerScript.hostname, { returnReward }: any = {}): any {
|
||||
helper.updateDynamicRam("attempt", getRamCost("codingcontract", "attempt"));
|
||||
const contract = getCodingContract("attempt", ip, fn);
|
||||
|
||||
// Convert answer to string. If the answer is a 2D array, then we have to
|
||||
// manually add brackets for the inner arrays
|
||||
if (is2DArray(answer)) {
|
||||
const answerComponents = [];
|
||||
for (let i = 0; i < answer.length; ++i) {
|
||||
answerComponents.push(["[", answer[i].toString(), "]"].join(""));
|
||||
}
|
||||
|
||||
answer = answerComponents.join(",");
|
||||
} else {
|
||||
answer = String(answer);
|
||||
}
|
||||
|
||||
const creward = contract.reward;
|
||||
if (creward === null) throw new Error("Somehow solved a contract that didn't have a reward");
|
||||
|
||||
const serv = helper.getServer(ip, "codingcontract.attempt");
|
||||
if (contract.isSolution(answer)) {
|
||||
const reward = player.gainCodingContractReward(creward, contract.getDifficulty());
|
||||
workerScript.log("attempt", `Successfully completed Coding Contract '${fn}'. Reward: ${reward}`);
|
||||
serv.removeContract(fn);
|
||||
return returnReward ? reward : true;
|
||||
} else {
|
||||
++contract.tries;
|
||||
if (contract.tries >= contract.getMaxNumTries()) {
|
||||
workerScript.log("attempt", `Coding Contract attempt '${fn}' failed. Contract is now self-destructing`);
|
||||
serv.removeContract(fn);
|
||||
} else {
|
||||
workerScript.log(
|
||||
"attempt",
|
||||
`Coding Contract attempt '${fn}' failed. ${contract.getMaxNumTries() - contract.tries} attempts remaining.`,
|
||||
);
|
||||
}
|
||||
|
||||
return returnReward ? "" : false;
|
||||
}
|
||||
},
|
||||
getContractType: function (fn: any, ip: any = workerScript.hostname): any {
|
||||
helper.updateDynamicRam("getContractType", getRamCost("codingcontract", "getContractType"));
|
||||
const contract = getCodingContract("getContractType", ip, fn);
|
||||
return contract.getType();
|
||||
},
|
||||
getData: function (fn: any, ip: any = workerScript.hostname): any {
|
||||
helper.updateDynamicRam("getData", getRamCost("codingcontract", "getData"));
|
||||
const contract = getCodingContract("getData", ip, fn);
|
||||
const data = contract.getData();
|
||||
if (data.constructor === Array) {
|
||||
// For two dimensional arrays, we have to copy the internal arrays using
|
||||
// slice() as well. As of right now, no contract has arrays that have
|
||||
// more than two dimensions
|
||||
const copy = data.slice();
|
||||
for (let i = 0; i < copy.length; ++i) {
|
||||
if (data[i].constructor === Array) {
|
||||
copy[i] = data[i].slice();
|
||||
}
|
||||
}
|
||||
|
||||
return copy;
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
},
|
||||
getDescription: function (fn: any, ip: any = workerScript.hostname): any {
|
||||
helper.updateDynamicRam("getDescription", getRamCost("codingcontract", "getDescription"));
|
||||
const contract = getCodingContract("getDescription", ip, fn);
|
||||
return contract.getDescription();
|
||||
},
|
||||
getNumTriesRemaining: function (fn: any, ip: any = workerScript.hostname): any {
|
||||
helper.updateDynamicRam("getNumTriesRemaining", getRamCost("codingcontract", "getNumTriesRemaining"));
|
||||
const contract = getCodingContract("getNumTriesRemaining", ip, fn);
|
||||
return contract.getMaxNumTries() - contract.tries;
|
||||
},
|
||||
};
|
||||
}
|
305
src/NetscriptFunctions/Corporation.ts
Normal file
305
src/NetscriptFunctions/Corporation.ts
Normal file
@ -0,0 +1,305 @@
|
||||
import { INetscriptHelper } from "./INetscriptHelper";
|
||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
|
||||
import { OfficeSpace } from "../Corporation/OfficeSpace";
|
||||
import { Employee } from "../Corporation/Employee";
|
||||
import { Product } from "../Corporation/Product";
|
||||
import { Material } from "../Corporation/Material";
|
||||
import { Warehouse } from "../Corporation/Warehouse";
|
||||
import { IIndustry } from "../Corporation/IIndustry";
|
||||
|
||||
import {
|
||||
NewIndustry,
|
||||
NewCity,
|
||||
UnlockUpgrade,
|
||||
LevelUpgrade,
|
||||
IssueDividends,
|
||||
SellMaterial,
|
||||
SellProduct,
|
||||
SetSmartSupply,
|
||||
BuyMaterial,
|
||||
AssignJob,
|
||||
UpgradeOfficeSize,
|
||||
ThrowParty,
|
||||
PurchaseWarehouse,
|
||||
UpgradeWarehouse,
|
||||
BuyCoffee,
|
||||
HireAdVert,
|
||||
MakeProduct,
|
||||
Research,
|
||||
ExportMaterial,
|
||||
CancelExportMaterial,
|
||||
SetMaterialMarketTA1,
|
||||
SetMaterialMarketTA2,
|
||||
SetProductMarketTA1,
|
||||
SetProductMarketTA2,
|
||||
} from "../Corporation/Actions";
|
||||
import { CorporationUnlockUpgrades } from "../Corporation/data/CorporationUnlockUpgrades";
|
||||
import { CorporationUpgrades } from "../Corporation/data/CorporationUpgrades";
|
||||
|
||||
export interface INetscriptCorporation {
|
||||
expandIndustry(industryName: any, divisionName: any): any;
|
||||
expandCity(divisionName: any, cityName: any): any;
|
||||
unlockUpgrade(upgradeName: any): any;
|
||||
levelUpgrade(upgradeName: any): any;
|
||||
issueDividends(percent: any): any;
|
||||
sellMaterial(divisionName: any, cityName: any, materialName: any, amt: any, price: any): any;
|
||||
sellProduct(divisionName: any, cityName: any, productName: any, amt: any, price: any, all: any): any;
|
||||
discontinueProduct(divisionName: any, productName: any): any;
|
||||
setSmartSupply(divisionName: any, cityName: any, enabled: any): any;
|
||||
buyMaterial(divisionName: any, cityName: any, materialName: any, amt: any): any;
|
||||
employees(divisionName: any, cityName: any): any;
|
||||
assignJob(divisionName: any, cityName: any, employeeName: any, job: any): any;
|
||||
hireEmployee(divisionName: any, cityName: any): any;
|
||||
upgradeOfficeSize(divisionName: any, cityName: any, size: any): any;
|
||||
throwParty(divisionName: any, cityName: any, costPerEmployee: any): any;
|
||||
purchaseWarehouse(divisionName: any, cityName: any): any;
|
||||
upgradeWarehouse(divisionName: any, cityName: any): any;
|
||||
buyCoffee(divisionName: any, cityName: any): any;
|
||||
hireAdVert(divisionName: any): any;
|
||||
makeProduct(divisionName: any, cityName: any, productName: any, designInvest: any, marketingInvest: any): any;
|
||||
research(divisionName: any, researchName: any): any;
|
||||
exportMaterial(
|
||||
sourceDivision: any,
|
||||
sourceCity: any,
|
||||
targetDivision: any,
|
||||
targetCity: any,
|
||||
materialName: any,
|
||||
amt: any,
|
||||
): any;
|
||||
cancelExportMaterial(
|
||||
sourceDivision: any,
|
||||
sourceCity: any,
|
||||
targetDivision: any,
|
||||
targetCity: any,
|
||||
materialName: any,
|
||||
amt: any,
|
||||
): any;
|
||||
setMaterialMarketTA1(divisionName: any, cityName: any, materialName: any, on: any): any;
|
||||
setMaterialMarketTA2(divisionName: any, cityName: any, materialName: any, on: any): any;
|
||||
setProductMarketTA1(divisionName: any, productName: any, on: any): any;
|
||||
setProductMarketTA2(divisionName: any, productName: any, on: any): any;
|
||||
getDivision(divisionName: any): any;
|
||||
getOffice(divisionName: any, cityName: any): any;
|
||||
getWarehouse(divisionName: any, cityName: any): any;
|
||||
getMaterial(divisionName: any, cityName: any, materialName: any): any;
|
||||
getProduct(divisionName: any, productName: any): any;
|
||||
getEmployee(divisionName: any, cityName: any, employeeName: any): any;
|
||||
}
|
||||
|
||||
export function NetscriptCorporation(
|
||||
player: IPlayer,
|
||||
workerScript: WorkerScript,
|
||||
helper: INetscriptHelper,
|
||||
): INetscriptCorporation {
|
||||
function getDivision(divisionName: any): IIndustry {
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("cannot be called without a corporation");
|
||||
const division = corporation.divisions.find((div) => div.name === divisionName);
|
||||
if (division === undefined) throw new Error(`No division named '${divisionName}'`);
|
||||
return division;
|
||||
}
|
||||
|
||||
function getOffice(divisionName: any, cityName: any): OfficeSpace {
|
||||
const division = getDivision(divisionName);
|
||||
if (!(cityName in division.offices)) throw new Error(`Invalid city name '${cityName}'`);
|
||||
const office = division.offices[cityName];
|
||||
if (office === 0) throw new Error(`${division.name} has not expanded to '${cityName}'`);
|
||||
return office;
|
||||
}
|
||||
|
||||
function getWarehouse(divisionName: any, cityName: any): Warehouse {
|
||||
const division = getDivision(divisionName);
|
||||
if (!(cityName in division.warehouses)) throw new Error(`Invalid city name '${cityName}'`);
|
||||
const warehouse = division.warehouses[cityName];
|
||||
if (warehouse === 0) throw new Error(`${division.name} has not expanded to '${cityName}'`);
|
||||
return warehouse;
|
||||
}
|
||||
|
||||
function getMaterial(divisionName: any, cityName: any, materialName: any): Material {
|
||||
const warehouse = getWarehouse(divisionName, cityName);
|
||||
const material = warehouse.materials[materialName];
|
||||
if (material === undefined) throw new Error(`Invalid material name: '${materialName}'`);
|
||||
return material;
|
||||
}
|
||||
|
||||
function getProduct(divisionName: any, productName: any): Product {
|
||||
const division = getDivision(divisionName);
|
||||
const product = division.products[productName];
|
||||
if (product === undefined) throw new Error(`Invalid product name: '${productName}'`);
|
||||
return product;
|
||||
}
|
||||
|
||||
function getEmployee(divisionName: any, cityName: any, employeeName: any): Employee {
|
||||
const office = getOffice(divisionName, cityName);
|
||||
const employee = office.employees.find((e) => e.name === employeeName);
|
||||
if (employee === undefined) throw new Error(`Invalid employee name: '${employeeName}'`);
|
||||
return employee;
|
||||
}
|
||||
// Hi, if you're reading this you're a bit nosy.
|
||||
// There's a corporation API but it's very imbalanced right now.
|
||||
// It's here so players can test with if they want.
|
||||
return {
|
||||
expandIndustry: function (industryName: any, divisionName: any): any {
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("Should not be called without a corporation");
|
||||
NewIndustry(corporation, industryName, divisionName);
|
||||
},
|
||||
expandCity: function (divisionName: any, cityName: any): any {
|
||||
const division = getDivision(divisionName);
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("Should not be called without a corporation");
|
||||
NewCity(corporation, division, cityName);
|
||||
},
|
||||
unlockUpgrade: function (upgradeName: any): any {
|
||||
const upgrade = Object.values(CorporationUnlockUpgrades).find((upgrade) => upgrade[2] === upgradeName);
|
||||
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("Should not be called without a corporation");
|
||||
UnlockUpgrade(corporation, upgrade);
|
||||
},
|
||||
levelUpgrade: function (upgradeName: any): any {
|
||||
const upgrade = Object.values(CorporationUpgrades).find((upgrade) => upgrade[4] === upgradeName);
|
||||
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("Should not be called without a corporation");
|
||||
LevelUpgrade(corporation, upgrade);
|
||||
},
|
||||
issueDividends: function (percent: any): any {
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("Should not be called without a corporation");
|
||||
IssueDividends(corporation, percent);
|
||||
},
|
||||
sellMaterial: function (divisionName: any, cityName: any, materialName: any, amt: any, price: any): any {
|
||||
const material = getMaterial(divisionName, cityName, materialName);
|
||||
SellMaterial(material, amt, price);
|
||||
},
|
||||
sellProduct: function (divisionName: any, cityName: any, productName: any, amt: any, price: any, all: any): any {
|
||||
const product = getProduct(divisionName, productName);
|
||||
SellProduct(product, cityName, amt, price, all);
|
||||
},
|
||||
discontinueProduct: function (divisionName: any, productName: any): any {
|
||||
getDivision(divisionName).discontinueProduct(getProduct(divisionName, productName));
|
||||
},
|
||||
setSmartSupply: function (divisionName: any, cityName: any, enabled: any): any {
|
||||
const warehouse = getWarehouse(divisionName, cityName);
|
||||
SetSmartSupply(warehouse, enabled);
|
||||
},
|
||||
// setSmartSupplyUseLeftovers: function (): any {},
|
||||
buyMaterial: function (divisionName: any, cityName: any, materialName: any, amt: any): any {
|
||||
const material = getMaterial(divisionName, cityName, materialName);
|
||||
BuyMaterial(material, amt);
|
||||
},
|
||||
employees: function (divisionName: any, cityName: any): any {
|
||||
const office = getOffice(divisionName, cityName);
|
||||
return office.employees.map((e) => Object.assign({}, e));
|
||||
},
|
||||
assignJob: function (divisionName: any, cityName: any, employeeName: any, job: any): any {
|
||||
const employee = getEmployee(divisionName, cityName, employeeName);
|
||||
AssignJob(employee, job);
|
||||
},
|
||||
hireEmployee: function (divisionName: any, cityName: any): any {
|
||||
const office = getOffice(divisionName, cityName);
|
||||
office.hireRandomEmployee();
|
||||
},
|
||||
upgradeOfficeSize: function (divisionName: any, cityName: any, size: any): any {
|
||||
const office = getOffice(divisionName, cityName);
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("Should not be called without a corporation");
|
||||
UpgradeOfficeSize(corporation, office, size);
|
||||
},
|
||||
throwParty: function (divisionName: any, cityName: any, costPerEmployee: any): any {
|
||||
const office = getOffice(divisionName, cityName);
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("Should not be called without a corporation");
|
||||
ThrowParty(corporation, office, costPerEmployee);
|
||||
},
|
||||
purchaseWarehouse: function (divisionName: any, cityName: any): any {
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("Should not be called without a corporation");
|
||||
PurchaseWarehouse(corporation, getDivision(divisionName), cityName);
|
||||
},
|
||||
upgradeWarehouse: function (divisionName: any, cityName: any): any {
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("Should not be called without a corporation");
|
||||
UpgradeWarehouse(corporation, getDivision(divisionName), getWarehouse(divisionName, cityName));
|
||||
},
|
||||
buyCoffee: function (divisionName: any, cityName: any): any {
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("Should not be called without a corporation");
|
||||
BuyCoffee(corporation, getDivision(divisionName), getOffice(divisionName, cityName));
|
||||
},
|
||||
hireAdVert: function (divisionName: any): any {
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("Should not be called without a corporation");
|
||||
HireAdVert(corporation, getDivision(divisionName), getOffice(divisionName, "Sector-12"));
|
||||
},
|
||||
makeProduct: function (
|
||||
divisionName: any,
|
||||
cityName: any,
|
||||
productName: any,
|
||||
designInvest: any,
|
||||
marketingInvest: any,
|
||||
): any {
|
||||
const corporation = player.corporation;
|
||||
if (corporation === null) throw new Error("Should not be called without a corporation");
|
||||
MakeProduct(corporation, getDivision(divisionName), cityName, productName, designInvest, marketingInvest);
|
||||
},
|
||||
research: function (divisionName: any, researchName: any): any {
|
||||
Research(getDivision(divisionName), researchName);
|
||||
},
|
||||
exportMaterial: function (
|
||||
sourceDivision: any,
|
||||
sourceCity: any,
|
||||
targetDivision: any,
|
||||
targetCity: any,
|
||||
materialName: any,
|
||||
amt: any,
|
||||
): any {
|
||||
ExportMaterial(targetDivision, targetCity, getMaterial(sourceDivision, sourceCity, materialName), amt + "");
|
||||
},
|
||||
cancelExportMaterial: function (
|
||||
sourceDivision: any,
|
||||
sourceCity: any,
|
||||
targetDivision: any,
|
||||
targetCity: any,
|
||||
materialName: any,
|
||||
amt: any,
|
||||
): any {
|
||||
CancelExportMaterial(targetDivision, targetCity, getMaterial(sourceDivision, sourceCity, materialName), amt + "");
|
||||
},
|
||||
setMaterialMarketTA1: function (divisionName: any, cityName: any, materialName: any, on: any): any {
|
||||
SetMaterialMarketTA1(getMaterial(divisionName, cityName, materialName), on);
|
||||
},
|
||||
setMaterialMarketTA2: function (divisionName: any, cityName: any, materialName: any, on: any) {
|
||||
SetMaterialMarketTA2(getMaterial(divisionName, cityName, materialName), on);
|
||||
},
|
||||
setProductMarketTA1: function (divisionName: any, productName: any, on: any): any {
|
||||
SetProductMarketTA1(getProduct(divisionName, productName), on);
|
||||
},
|
||||
setProductMarketTA2: function (divisionName: any, productName: any, on: any) {
|
||||
SetProductMarketTA2(getProduct(divisionName, productName), on);
|
||||
},
|
||||
// If you modify these objects you will affect them for real, it's not
|
||||
// copies.
|
||||
getDivision: function (divisionName: any): any {
|
||||
return getDivision(divisionName);
|
||||
},
|
||||
getOffice: function (divisionName: any, cityName: any): any {
|
||||
return getOffice(divisionName, cityName);
|
||||
},
|
||||
getWarehouse: function (divisionName: any, cityName: any): any {
|
||||
return getWarehouse(divisionName, cityName);
|
||||
},
|
||||
getMaterial: function (divisionName: any, cityName: any, materialName: any): any {
|
||||
return getMaterial(divisionName, cityName, materialName);
|
||||
},
|
||||
getProduct: function (divisionName: any, productName: any): any {
|
||||
return getProduct(divisionName, productName);
|
||||
},
|
||||
getEmployee: function (divisionName: any, cityName: any, employeeName: any): any {
|
||||
return getEmployee(divisionName, cityName, employeeName);
|
||||
},
|
||||
};
|
||||
}
|
187
src/NetscriptFunctions/Formulas.ts
Normal file
187
src/NetscriptFunctions/Formulas.ts
Normal file
@ -0,0 +1,187 @@
|
||||
import { INetscriptHelper } from "./INetscriptHelper";
|
||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { calculateServerGrowth } from "../Server/formulas/grow";
|
||||
import {
|
||||
calculateMoneyGainRate,
|
||||
calculateLevelUpgradeCost,
|
||||
calculateRamUpgradeCost,
|
||||
calculateCoreUpgradeCost,
|
||||
calculateNodeCost,
|
||||
} from "../Hacknet/formulas/HacknetNodes";
|
||||
import {
|
||||
calculateHashGainRate as HScalculateHashGainRate,
|
||||
calculateLevelUpgradeCost as HScalculateLevelUpgradeCost,
|
||||
calculateRamUpgradeCost as HScalculateRamUpgradeCost,
|
||||
calculateCoreUpgradeCost as HScalculateCoreUpgradeCost,
|
||||
calculateCacheUpgradeCost as HScalculateCacheUpgradeCost,
|
||||
calculateServerCost as HScalculateServerCost,
|
||||
} from "../Hacknet/formulas/HacknetServers";
|
||||
import { HacknetNodeConstants, HacknetServerConstants } from "../Hacknet/data/Constants";
|
||||
import { calculateSkill, calculateExp } from "../PersonObjects/formulas/skill";
|
||||
import {
|
||||
calculateHackingChance,
|
||||
calculateHackingExpGain,
|
||||
calculatePercentMoneyHacked,
|
||||
calculateHackingTime,
|
||||
calculateGrowTime,
|
||||
calculateWeakenTime,
|
||||
} from "../Hacking";
|
||||
|
||||
export interface INetscriptFormulas {
|
||||
basic: {
|
||||
calculateSkill(exp: any, mult?: any): any;
|
||||
calculateExp(skill: any, mult?: any): any;
|
||||
hackChance(server: any, player: any): any;
|
||||
hackExp(server: any, player: any): any;
|
||||
hackPercent(server: any, player: any): any;
|
||||
growPercent(server: any, threads: any, player: any, cores?: any): any;
|
||||
hackTime(server: any, player: any): any;
|
||||
growTime(server: any, player: any): any;
|
||||
weakenTime(server: any, player: any): any;
|
||||
};
|
||||
hacknetNodes: {
|
||||
moneyGainRate(level: any, ram: any, cores: any, mult?: any): any;
|
||||
levelUpgradeCost(startingLevel: any, extraLevels?: any, costMult?: any): any;
|
||||
ramUpgradeCost(startingRam: any, extraLevels?: any, costMult?: any): any;
|
||||
coreUpgradeCost(startingCore: any, extraCores?: any, costMult?: any): any;
|
||||
hacknetNodeCost(n: any, mult: any): any;
|
||||
constants(): any;
|
||||
};
|
||||
hacknetServers: {
|
||||
hashGainRate(level: any, ramUsed: any, maxRam: any, cores: any, mult?: any): any;
|
||||
levelUpgradeCost(startingLevel: any, extraLevels?: any, costMult?: any): any;
|
||||
ramUpgradeCost(startingRam: any, extraLevels?: any, costMult?: any): any;
|
||||
coreUpgradeCost(startingCore: any, extraCores?: any, costMult?: any): any;
|
||||
cacheUpgradeCost(startingCache: any, extraCache?: any): any;
|
||||
hashUpgradeCost(upgName: any, level: any): any;
|
||||
hacknetServerCost(n: any, mult: any): any;
|
||||
constants(): any;
|
||||
};
|
||||
}
|
||||
|
||||
export function NetscriptFormulas(
|
||||
player: IPlayer,
|
||||
workerScript: WorkerScript,
|
||||
helper: INetscriptHelper,
|
||||
): INetscriptFormulas {
|
||||
const checkFormulasAccess = function (func: any, n: any): void {
|
||||
if (
|
||||
(player.sourceFileLvl(5) < 1 && player.bitNodeN !== 5) ||
|
||||
(player.sourceFileLvl(n) < 1 && player.bitNodeN !== n)
|
||||
) {
|
||||
let extra = "";
|
||||
if (n !== 5) {
|
||||
extra = ` and Source-File ${n}-1`;
|
||||
}
|
||||
throw helper.makeRuntimeErrorMsg(`formulas.${func}`, `Requires Source-File 5-1${extra} to run.`);
|
||||
}
|
||||
};
|
||||
return {
|
||||
basic: {
|
||||
calculateSkill: function (exp: any, mult: any = 1): any {
|
||||
checkFormulasAccess("basic.calculateSkill", 5);
|
||||
return calculateSkill(exp, mult);
|
||||
},
|
||||
calculateExp: function (skill: any, mult: any = 1): any {
|
||||
checkFormulasAccess("basic.calculateExp", 5);
|
||||
return calculateExp(skill, mult);
|
||||
},
|
||||
hackChance: function (server: any, player: any): any {
|
||||
checkFormulasAccess("basic.hackChance", 5);
|
||||
return calculateHackingChance(server, player);
|
||||
},
|
||||
hackExp: function (server: any, player: any): any {
|
||||
checkFormulasAccess("basic.hackExp", 5);
|
||||
return calculateHackingExpGain(server, player);
|
||||
},
|
||||
hackPercent: function (server: any, player: any): any {
|
||||
checkFormulasAccess("basic.hackPercent", 5);
|
||||
return calculatePercentMoneyHacked(server, player);
|
||||
},
|
||||
growPercent: function (server: any, threads: any, player: any, cores: any = 1): any {
|
||||
checkFormulasAccess("basic.growPercent", 5);
|
||||
return calculateServerGrowth(server, threads, player, cores);
|
||||
},
|
||||
hackTime: function (server: any, player: any): any {
|
||||
checkFormulasAccess("basic.hackTime", 5);
|
||||
return calculateHackingTime(server, player);
|
||||
},
|
||||
growTime: function (server: any, player: any): any {
|
||||
checkFormulasAccess("basic.growTime", 5);
|
||||
return calculateGrowTime(server, player);
|
||||
},
|
||||
weakenTime: function (server: any, player: any): any {
|
||||
checkFormulasAccess("basic.weakenTime", 5);
|
||||
return calculateWeakenTime(server, player);
|
||||
},
|
||||
},
|
||||
hacknetNodes: {
|
||||
moneyGainRate: function (level: any, ram: any, cores: any, mult: any = 1): any {
|
||||
checkFormulasAccess("hacknetNodes.moneyGainRate", 5);
|
||||
return calculateMoneyGainRate(level, ram, cores, mult);
|
||||
},
|
||||
levelUpgradeCost: function (startingLevel: any, extraLevels: any = 1, costMult: any = 1): any {
|
||||
checkFormulasAccess("hacknetNodes.levelUpgradeCost", 5);
|
||||
return calculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
||||
},
|
||||
ramUpgradeCost: function (startingRam: any, extraLevels: any = 1, costMult: any = 1): any {
|
||||
checkFormulasAccess("hacknetNodes.ramUpgradeCost", 5);
|
||||
return calculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
||||
},
|
||||
coreUpgradeCost: function (startingCore: any, extraCores: any = 1, costMult: any = 1): any {
|
||||
checkFormulasAccess("hacknetNodes.coreUpgradeCost", 5);
|
||||
return calculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
||||
},
|
||||
hacknetNodeCost: function (n: any, mult: any): any {
|
||||
checkFormulasAccess("hacknetNodes.hacknetNodeCost", 5);
|
||||
return calculateNodeCost(n, mult);
|
||||
},
|
||||
constants: function (): any {
|
||||
checkFormulasAccess("hacknetNodes.constants", 5);
|
||||
return Object.assign({}, HacknetNodeConstants);
|
||||
},
|
||||
},
|
||||
hacknetServers: {
|
||||
hashGainRate: function (level: any, ramUsed: any, maxRam: any, cores: any, mult: any = 1): any {
|
||||
checkFormulasAccess("hacknetServers.hashGainRate", 9);
|
||||
return HScalculateHashGainRate(level, ramUsed, maxRam, cores, mult);
|
||||
},
|
||||
levelUpgradeCost: function (startingLevel: any, extraLevels: any = 1, costMult: any = 1): any {
|
||||
checkFormulasAccess("hacknetServers.levelUpgradeCost", 9);
|
||||
return HScalculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
||||
},
|
||||
ramUpgradeCost: function (startingRam: any, extraLevels: any = 1, costMult: any = 1): any {
|
||||
checkFormulasAccess("hacknetServers.ramUpgradeCost", 9);
|
||||
return HScalculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
||||
},
|
||||
coreUpgradeCost: function (startingCore: any, extraCores: any = 1, costMult: any = 1): any {
|
||||
checkFormulasAccess("hacknetServers.coreUpgradeCost", 9);
|
||||
return HScalculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
||||
},
|
||||
cacheUpgradeCost: function (startingCache: any, extraCache: any = 1): any {
|
||||
checkFormulasAccess("hacknetServers.cacheUpgradeCost", 9);
|
||||
return HScalculateCacheUpgradeCost(startingCache, extraCache);
|
||||
},
|
||||
hashUpgradeCost: function (upgName: any, level: any): any {
|
||||
checkFormulasAccess("hacknetServers.hashUpgradeCost", 9);
|
||||
const upg = player.hashManager.getUpgrade(upgName);
|
||||
if (!upg) {
|
||||
throw helper.makeRuntimeErrorMsg(
|
||||
"formulas.hacknetServers.calculateHashUpgradeCost",
|
||||
`Invalid Hash Upgrade: ${upgName}`,
|
||||
);
|
||||
}
|
||||
return upg.getCost(level);
|
||||
},
|
||||
hacknetServerCost: function (n: any, mult: any): any {
|
||||
checkFormulasAccess("hacknetServers.hacknetServerCost", 9);
|
||||
return HScalculateServerCost(n, mult);
|
||||
},
|
||||
constants: function (): any {
|
||||
checkFormulasAccess("hacknetServers.constants", 9);
|
||||
return Object.assign({}, HacknetServerConstants);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
@ -1,7 +1,13 @@
|
||||
import { BaseServer } from "../Server/BaseServer";
|
||||
import { Faction } from "../Faction/Faction";
|
||||
|
||||
export interface INetscriptHelper {
|
||||
updateDynamicRam(functionName: string, ram: number): void;
|
||||
makeRuntimeErrorMsg(functionName: string, message: string): void;
|
||||
string(funcName: string, argName: string, v: any): string;
|
||||
number(funcName: string, argName: string, v: any): number;
|
||||
boolean(v: any): boolean;
|
||||
getServer(ip: any, fn: any): BaseServer;
|
||||
checkSingularityAccess(func: string, n: number): void;
|
||||
getFaction(func: string, name: string): Faction;
|
||||
}
|
||||
|
377
src/NetscriptFunctions/StockMarket.ts
Normal file
377
src/NetscriptFunctions/StockMarket.ts
Normal file
@ -0,0 +1,377 @@
|
||||
import { INetscriptHelper } from "./INetscriptHelper";
|
||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { getRamCost } from "../Netscript/RamCostGenerator";
|
||||
import { buyStock, sellStock, shortStock, sellShort } from "../StockMarket/BuyingAndSelling";
|
||||
import { StockMarket, SymbolToStockMap, placeOrder, cancelOrder } from "../StockMarket/StockMarket";
|
||||
import { getBuyTransactionCost, getSellTransactionGain } from "../StockMarket/StockMarketHelpers";
|
||||
import { OrderTypes } from "../StockMarket/data/OrderTypes";
|
||||
import { PositionTypes } from "../StockMarket/data/PositionTypes";
|
||||
import { StockSymbols } from "../StockMarket/data/StockSymbols";
|
||||
import { getStockMarket4SDataCost, getStockMarket4STixApiCost } from "../StockMarket/StockMarketCosts";
|
||||
import { Stock } from "../StockMarket/Stock";
|
||||
|
||||
export interface INetscriptStockMarket {
|
||||
getStockSymbols(): any;
|
||||
getStockPrice(symbol: any): any;
|
||||
getStockAskPrice(symbol: any): any;
|
||||
getStockBidPrice(symbol: any): any;
|
||||
getStockPosition(symbol: any): any;
|
||||
getStockMaxShares(symbol: any): any;
|
||||
getStockPurchaseCost(symbol: any, shares: any, posType: any): any;
|
||||
getStockSaleGain(symbol: any, shares: any, posType: any): any;
|
||||
buyStock(symbol: any, shares: any): any;
|
||||
sellStock(symbol: any, shares: any): any;
|
||||
shortStock(symbol: any, shares: any): any;
|
||||
sellShort(symbol: any, shares: any): any;
|
||||
placeOrder(symbol: any, shares: any, price: any, type: any, pos: any): any;
|
||||
cancelOrder(symbol: any, shares: any, price: any, type: any, pos: any): any;
|
||||
getOrders(): any;
|
||||
getStockVolatility(symbol: any): any;
|
||||
getStockForecast(symbol: any): any;
|
||||
purchase4SMarketData(): void;
|
||||
purchase4SMarketDataTixApi(): void;
|
||||
}
|
||||
|
||||
export function NetscriptStockMarket(
|
||||
player: IPlayer,
|
||||
workerScript: WorkerScript,
|
||||
helper: INetscriptHelper,
|
||||
): INetscriptStockMarket {
|
||||
/**
|
||||
* Checks if the player has TIX API access. Throws an error if the player does not
|
||||
*/
|
||||
const checkTixApiAccess = function (callingFn: string): void {
|
||||
if (!player.hasWseAccount) {
|
||||
throw helper.makeRuntimeErrorMsg(callingFn, `You don't have WSE Access! Cannot use ${callingFn}()`);
|
||||
}
|
||||
if (!player.hasTixApiAccess) {
|
||||
throw helper.makeRuntimeErrorMsg(callingFn, `You don't have TIX API Access! Cannot use ${callingFn}()`);
|
||||
}
|
||||
};
|
||||
|
||||
const getStockFromSymbol = function (symbol: string, callingFn: string): Stock {
|
||||
const stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw helper.makeRuntimeErrorMsg(callingFn, `Invalid stock symbol: '${symbol}'`);
|
||||
}
|
||||
|
||||
return stock;
|
||||
};
|
||||
return {
|
||||
getStockSymbols: function (): any {
|
||||
helper.updateDynamicRam("getStockSymbols", getRamCost("getStockSymbols"));
|
||||
checkTixApiAccess("getStockSymbols");
|
||||
return Object.values(StockSymbols);
|
||||
},
|
||||
getStockPrice: function (symbol: any): any {
|
||||
helper.updateDynamicRam("getStockPrice", getRamCost("getStockPrice"));
|
||||
checkTixApiAccess("getStockPrice");
|
||||
const stock = getStockFromSymbol(symbol, "getStockPrice");
|
||||
|
||||
return stock.price;
|
||||
},
|
||||
getStockAskPrice: function (symbol: any): any {
|
||||
helper.updateDynamicRam("getStockAskPrice", getRamCost("getStockAskPrice"));
|
||||
checkTixApiAccess("getStockAskPrice");
|
||||
const stock = getStockFromSymbol(symbol, "getStockAskPrice");
|
||||
|
||||
return stock.getAskPrice();
|
||||
},
|
||||
getStockBidPrice: function (symbol: any): any {
|
||||
helper.updateDynamicRam("getStockBidPrice", getRamCost("getStockBidPrice"));
|
||||
checkTixApiAccess("getStockBidPrice");
|
||||
const stock = getStockFromSymbol(symbol, "getStockBidPrice");
|
||||
|
||||
return stock.getBidPrice();
|
||||
},
|
||||
getStockPosition: function (symbol: any): any {
|
||||
helper.updateDynamicRam("getStockPosition", getRamCost("getStockPosition"));
|
||||
checkTixApiAccess("getStockPosition");
|
||||
const stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw helper.makeRuntimeErrorMsg("getStockPosition", `Invalid stock symbol: ${symbol}`);
|
||||
}
|
||||
return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx];
|
||||
},
|
||||
getStockMaxShares: function (symbol: any): any {
|
||||
helper.updateDynamicRam("getStockMaxShares", getRamCost("getStockMaxShares"));
|
||||
checkTixApiAccess("getStockMaxShares");
|
||||
const stock = getStockFromSymbol(symbol, "getStockMaxShares");
|
||||
|
||||
return stock.maxShares;
|
||||
},
|
||||
getStockPurchaseCost: function (symbol: any, shares: any, posType: any): any {
|
||||
helper.updateDynamicRam("getStockPurchaseCost", getRamCost("getStockPurchaseCost"));
|
||||
checkTixApiAccess("getStockPurchaseCost");
|
||||
const stock = getStockFromSymbol(symbol, "getStockPurchaseCost");
|
||||
shares = Math.round(shares);
|
||||
|
||||
let pos;
|
||||
const sanitizedPosType = posType.toLowerCase();
|
||||
if (sanitizedPosType.includes("l")) {
|
||||
pos = PositionTypes.Long;
|
||||
} else if (sanitizedPosType.includes("s")) {
|
||||
pos = PositionTypes.Short;
|
||||
} else {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const res = getBuyTransactionCost(stock, shares, pos);
|
||||
if (res == null) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
getStockSaleGain: function (symbol: any, shares: any, posType: any): any {
|
||||
helper.updateDynamicRam("getStockSaleGain", getRamCost("getStockSaleGain"));
|
||||
checkTixApiAccess("getStockSaleGain");
|
||||
const stock = getStockFromSymbol(symbol, "getStockSaleGain");
|
||||
shares = Math.round(shares);
|
||||
|
||||
let pos;
|
||||
const sanitizedPosType = posType.toLowerCase();
|
||||
if (sanitizedPosType.includes("l")) {
|
||||
pos = PositionTypes.Long;
|
||||
} else if (sanitizedPosType.includes("s")) {
|
||||
pos = PositionTypes.Short;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const res = getSellTransactionGain(stock, shares, pos);
|
||||
if (res == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
buyStock: function (symbol: any, shares: any): any {
|
||||
helper.updateDynamicRam("buyStock", getRamCost("buyStock"));
|
||||
checkTixApiAccess("buyStock");
|
||||
const stock = getStockFromSymbol(symbol, "buyStock");
|
||||
const res = buyStock(stock, shares, workerScript, {});
|
||||
return res ? stock.price : 0;
|
||||
},
|
||||
sellStock: function (symbol: any, shares: any): any {
|
||||
helper.updateDynamicRam("sellStock", getRamCost("sellStock"));
|
||||
checkTixApiAccess("sellStock");
|
||||
const stock = getStockFromSymbol(symbol, "sellStock");
|
||||
const res = sellStock(stock, shares, workerScript, {});
|
||||
|
||||
return res ? stock.price : 0;
|
||||
},
|
||||
shortStock: function (symbol: any, shares: any): any {
|
||||
helper.updateDynamicRam("shortStock", getRamCost("shortStock"));
|
||||
checkTixApiAccess("shortStock");
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 1) {
|
||||
throw helper.makeRuntimeErrorMsg(
|
||||
"shortStock",
|
||||
"You must either be in BitNode-8 or you must have Source-File 8 Level 2.",
|
||||
);
|
||||
}
|
||||
}
|
||||
const stock = getStockFromSymbol(symbol, "shortStock");
|
||||
const res = shortStock(stock, shares, workerScript, {});
|
||||
|
||||
return res ? stock.price : 0;
|
||||
},
|
||||
sellShort: function (symbol: any, shares: any): any {
|
||||
helper.updateDynamicRam("sellShort", getRamCost("sellShort"));
|
||||
checkTixApiAccess("sellShort");
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 1) {
|
||||
throw helper.makeRuntimeErrorMsg(
|
||||
"sellShort",
|
||||
"You must either be in BitNode-8 or you must have Source-File 8 Level 2.",
|
||||
);
|
||||
}
|
||||
}
|
||||
const stock = getStockFromSymbol(symbol, "sellShort");
|
||||
const res = sellShort(stock, shares, workerScript, {});
|
||||
|
||||
return res ? stock.price : 0;
|
||||
},
|
||||
placeOrder: function (symbol: any, shares: any, price: any, type: any, pos: any): any {
|
||||
helper.updateDynamicRam("placeOrder", getRamCost("placeOrder"));
|
||||
checkTixApiAccess("placeOrder");
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 2) {
|
||||
throw helper.makeRuntimeErrorMsg(
|
||||
"placeOrder",
|
||||
"You must either be in BitNode-8 or you must have Source-File 8 Level 3.",
|
||||
);
|
||||
}
|
||||
}
|
||||
const stock = getStockFromSymbol(symbol, "placeOrder");
|
||||
|
||||
let orderType;
|
||||
let orderPos;
|
||||
const ltype = type.toLowerCase();
|
||||
if (ltype.includes("limit") && ltype.includes("buy")) {
|
||||
orderType = OrderTypes.LimitBuy;
|
||||
} else if (ltype.includes("limit") && ltype.includes("sell")) {
|
||||
orderType = OrderTypes.LimitSell;
|
||||
} else if (ltype.includes("stop") && ltype.includes("buy")) {
|
||||
orderType = OrderTypes.StopBuy;
|
||||
} else if (ltype.includes("stop") && ltype.includes("sell")) {
|
||||
orderType = OrderTypes.StopSell;
|
||||
} else {
|
||||
throw helper.makeRuntimeErrorMsg("placeOrder", `Invalid order type: ${type}`);
|
||||
}
|
||||
|
||||
const lpos = pos.toLowerCase();
|
||||
if (lpos.includes("l")) {
|
||||
orderPos = PositionTypes.Long;
|
||||
} else if (lpos.includes("s")) {
|
||||
orderPos = PositionTypes.Short;
|
||||
} else {
|
||||
throw helper.makeRuntimeErrorMsg("placeOrder", `Invalid position type: ${pos}`);
|
||||
}
|
||||
|
||||
return placeOrder(stock, shares, price, orderType, orderPos, workerScript);
|
||||
},
|
||||
cancelOrder: function (symbol: any, shares: any, price: any, type: any, pos: any): any {
|
||||
helper.updateDynamicRam("cancelOrder", getRamCost("cancelOrder"));
|
||||
checkTixApiAccess("cancelOrder");
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 2) {
|
||||
throw helper.makeRuntimeErrorMsg(
|
||||
"cancelOrder",
|
||||
"You must either be in BitNode-8 or you must have Source-File 8 Level 3.",
|
||||
);
|
||||
}
|
||||
}
|
||||
const stock = getStockFromSymbol(symbol, "cancelOrder");
|
||||
if (isNaN(shares) || isNaN(price)) {
|
||||
throw helper.makeRuntimeErrorMsg(
|
||||
"cancelOrder",
|
||||
`Invalid shares or price. Must be numeric. shares=${shares}, price=${price}`,
|
||||
);
|
||||
}
|
||||
let orderType;
|
||||
let orderPos;
|
||||
const ltype = type.toLowerCase();
|
||||
if (ltype.includes("limit") && ltype.includes("buy")) {
|
||||
orderType = OrderTypes.LimitBuy;
|
||||
} else if (ltype.includes("limit") && ltype.includes("sell")) {
|
||||
orderType = OrderTypes.LimitSell;
|
||||
} else if (ltype.includes("stop") && ltype.includes("buy")) {
|
||||
orderType = OrderTypes.StopBuy;
|
||||
} else if (ltype.includes("stop") && ltype.includes("sell")) {
|
||||
orderType = OrderTypes.StopSell;
|
||||
} else {
|
||||
throw helper.makeRuntimeErrorMsg("cancelOrder", `Invalid order type: ${type}`);
|
||||
}
|
||||
|
||||
const lpos = pos.toLowerCase();
|
||||
if (lpos.includes("l")) {
|
||||
orderPos = PositionTypes.Long;
|
||||
} else if (lpos.includes("s")) {
|
||||
orderPos = PositionTypes.Short;
|
||||
} else {
|
||||
throw helper.makeRuntimeErrorMsg("cancelOrder", `Invalid position type: ${pos}`);
|
||||
}
|
||||
const params = {
|
||||
stock: stock,
|
||||
shares: shares,
|
||||
price: price,
|
||||
type: orderType,
|
||||
pos: orderPos,
|
||||
};
|
||||
return cancelOrder(params, workerScript);
|
||||
},
|
||||
getOrders: function (): any {
|
||||
helper.updateDynamicRam("getOrders", getRamCost("getOrders"));
|
||||
checkTixApiAccess("getOrders");
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 2) {
|
||||
throw helper.makeRuntimeErrorMsg(
|
||||
"getOrders",
|
||||
"You must either be in BitNode-8 or have Source-File 8 Level 3.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const orders: any = {};
|
||||
|
||||
const stockMarketOrders = StockMarket["Orders"];
|
||||
for (const symbol in stockMarketOrders) {
|
||||
const orderBook = stockMarketOrders[symbol];
|
||||
if (orderBook.constructor === Array && orderBook.length > 0) {
|
||||
orders[symbol] = [];
|
||||
for (let i = 0; i < orderBook.length; ++i) {
|
||||
orders[symbol].push({
|
||||
shares: orderBook[i].shares,
|
||||
price: orderBook[i].price,
|
||||
type: orderBook[i].type,
|
||||
position: orderBook[i].pos,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return orders;
|
||||
},
|
||||
getStockVolatility: function (symbol: any): any {
|
||||
helper.updateDynamicRam("getStockVolatility", getRamCost("getStockVolatility"));
|
||||
if (!player.has4SDataTixApi) {
|
||||
throw helper.makeRuntimeErrorMsg("getStockVolatility", "You don't have 4S Market Data TIX API Access!");
|
||||
}
|
||||
const stock = getStockFromSymbol(symbol, "getStockVolatility");
|
||||
|
||||
return stock.mv / 100; // Convert from percentage to decimal
|
||||
},
|
||||
getStockForecast: function (symbol: any): any {
|
||||
helper.updateDynamicRam("getStockForecast", getRamCost("getStockForecast"));
|
||||
if (!player.has4SDataTixApi) {
|
||||
throw helper.makeRuntimeErrorMsg("getStockForecast", "You don't have 4S Market Data TIX API Access!");
|
||||
}
|
||||
const stock = getStockFromSymbol(symbol, "getStockForecast");
|
||||
|
||||
let forecast = 50;
|
||||
stock.b ? (forecast += stock.otlkMag) : (forecast -= stock.otlkMag);
|
||||
return forecast / 100; // Convert from percentage to decimal
|
||||
},
|
||||
purchase4SMarketData: function () {
|
||||
helper.updateDynamicRam("purchase4SMarketData", getRamCost("purchase4SMarketData"));
|
||||
checkTixApiAccess("purchase4SMarketData");
|
||||
|
||||
if (player.has4SData) {
|
||||
workerScript.log("purchase4SMarketData", "Already purchased 4S Market Data.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player.money.lt(getStockMarket4SDataCost())) {
|
||||
workerScript.log("purchase4SMarketData", "Not enough money to purchase 4S Market Data.");
|
||||
return false;
|
||||
}
|
||||
|
||||
player.has4SData = true;
|
||||
player.loseMoney(getStockMarket4SDataCost());
|
||||
workerScript.log("purchase4SMarketData", "Purchased 4S Market Data");
|
||||
return true;
|
||||
},
|
||||
purchase4SMarketDataTixApi: function () {
|
||||
helper.updateDynamicRam("purchase4SMarketDataTixApi", getRamCost("purchase4SMarketDataTixApi"));
|
||||
checkTixApiAccess("purchase4SMarketDataTixApi");
|
||||
|
||||
if (player.has4SDataTixApi) {
|
||||
workerScript.log("purchase4SMarketDataTixApi", "Already purchased 4S Market Data TIX API");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player.money.lt(getStockMarket4STixApiCost())) {
|
||||
workerScript.log("purchase4SMarketDataTixApi", "Not enough money to purchase 4S Market Data TIX API");
|
||||
return false;
|
||||
}
|
||||
|
||||
player.has4SDataTixApi = true;
|
||||
player.loseMoney(getStockMarket4STixApiCost());
|
||||
workerScript.log("purchase4SMarketDataTixApi", "Purchased 4S Market Data TIX API");
|
||||
return true;
|
||||
},
|
||||
};
|
||||
}
|
@ -276,4 +276,5 @@ export interface IPlayer {
|
||||
setBitNodeNumber(n: number): void;
|
||||
getMult(name: string): number;
|
||||
setMult(name: string, mult: number): void;
|
||||
sourceFileLvl(n: number): number;
|
||||
}
|
||||
|
@ -283,6 +283,7 @@ export class PlayerObject implements IPlayer {
|
||||
setBitNodeNumber: (n: number) => void;
|
||||
getMult: (name: string) => number;
|
||||
setMult: (name: string, mult: number) => void;
|
||||
sourceFileLvl: (n: number) => number;
|
||||
|
||||
constructor() {
|
||||
//Skills and stats
|
||||
@ -576,6 +577,7 @@ export class PlayerObject implements IPlayer {
|
||||
|
||||
this.getMult = generalMethods.getMult;
|
||||
this.setMult = generalMethods.setMult;
|
||||
this.sourceFileLvl = generalMethods.sourceFileLvl;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2654,3 +2654,10 @@ export function setMult(this: IPlayer, name: string, mult: number): void {
|
||||
if (!this.hasOwnProperty(name)) return;
|
||||
(this as any)[name] = mult;
|
||||
}
|
||||
|
||||
export function sourceFileLvl(this: IPlayer, n: number): number {
|
||||
for (const sf of this.sourceFiles) {
|
||||
if (sf.n === n) return sf.lvl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -164,6 +164,13 @@ function evaluateVersionCompatibility(ver: string): void {
|
||||
if (anyPlayer.corporation === 0) {
|
||||
anyPlayer.corporation = null;
|
||||
}
|
||||
// convert all Messages to just filename to save space.
|
||||
const home = anyPlayer.getHomeComputer();
|
||||
for (let i = 0; i < home.messages.length; i++) {
|
||||
if (home.messages[i].filename) {
|
||||
home.messages[i] = home.messages[i].filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ export class BaseServer {
|
||||
// For Literature files, this array contains only the filename (string)
|
||||
// For Messages, it contains the actual Message object
|
||||
// TODO Separate literature files into its own property
|
||||
messages: (Message | string)[] = [];
|
||||
messages: string[] = [];
|
||||
|
||||
// Name of company/faction/etc. that this server belongs to.
|
||||
// Optional, not applicable to all Servers
|
||||
|
@ -3,7 +3,6 @@ import { IRouter } from "../../ui/Router";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
import { showMessage } from "../../Message/MessageHelpers";
|
||||
import { Message } from "../../Message/Message";
|
||||
import { showLiterature } from "../../Literature/LiteratureHelpers";
|
||||
|
||||
export function cat(
|
||||
@ -29,12 +28,12 @@ export function cat(
|
||||
for (let i = 0; i < server.messages.length; ++i) {
|
||||
if (filename.endsWith(".lit") && server.messages[i] === filename) {
|
||||
const file = server.messages[i];
|
||||
if (file instanceof Message) throw new Error(".lit file should not be a .msg");
|
||||
if (file.endsWith(".msg")) throw new Error(".lit file should not be a .msg");
|
||||
showLiterature(file);
|
||||
return;
|
||||
} else if (filename.endsWith(".msg")) {
|
||||
const file = server.messages[i] as Message;
|
||||
if (file.filename !== filename) continue;
|
||||
const file = server.messages[i];
|
||||
if (file !== filename) continue;
|
||||
showMessage(file);
|
||||
return;
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ import { ITerminal } from "../ITerminal";
|
||||
import { IRouter } from "../../ui/Router";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
import { Message } from "../../Message/Message";
|
||||
import { getFirstParentDirectory, isValidDirectoryPath, evaluateDirectoryPath } from "../../Terminal/DirectoryHelpers";
|
||||
|
||||
export function ls(
|
||||
@ -103,8 +102,7 @@ export function ls(
|
||||
for (const script of s.scripts) handleFn(script.filename, allScripts);
|
||||
for (const txt of s.textFiles) handleFn(txt.fn, allTextFiles);
|
||||
for (const contract of s.contracts) handleFn(contract.fn, allContracts);
|
||||
for (const msgOrLit of s.messages)
|
||||
msgOrLit instanceof Message ? handleFn(msgOrLit.filename, allMessages) : handleFn(msgOrLit, allMessages);
|
||||
for (const msgOrLit of s.messages) handleFn(msgOrLit, allMessages);
|
||||
|
||||
// Sort the files/folders alphabetically then print each
|
||||
allPrograms.sort();
|
||||
|
@ -34,7 +34,7 @@ export function scp(
|
||||
if (scriptname.endsWith(".lit")) {
|
||||
let found = false;
|
||||
for (let i = 0; i < server.messages.length; ++i) {
|
||||
if (!(server.messages[i] instanceof Message) && server.messages[i] == scriptname) {
|
||||
if (server.messages[i] == scriptname) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ export function determineAllPossibilitiesForTabCompletion(
|
||||
|
||||
function addAllLitFiles(): void {
|
||||
for (const file of currServ.messages) {
|
||||
if (!(file instanceof Message)) {
|
||||
if (!file.endsWith(".msg")) {
|
||||
allPos.push(file);
|
||||
}
|
||||
}
|
||||
@ -79,8 +79,8 @@ export function determineAllPossibilitiesForTabCompletion(
|
||||
|
||||
function addAllMessages(): void {
|
||||
for (const file of currServ.messages) {
|
||||
if (file instanceof Message) {
|
||||
allPos.push(file.filename);
|
||||
if (file.endsWith(".msg")) {
|
||||
allPos.push(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
|
||||
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
|
||||
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
|
||||
Player.getHomeComputer().contracts.push(new CodingContract("linklist.cct"));
|
||||
Player.getHomeComputer().messages.push(new Message("asl.msg"));
|
||||
Player.getHomeComputer().messages.push("asl.msg");
|
||||
Player.getHomeComputer().messages.push("af.lit");
|
||||
expect(determineAllPossibilitiesForTabCompletion(Player, "rm ", 0)).equal([
|
||||
"/www/script.js",
|
||||
@ -120,7 +120,7 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
|
||||
|
||||
it("completes the cat command", () => {
|
||||
Player.getHomeComputer().writeToTextFile("/www/note.txt", "oh hai mark");
|
||||
Player.getHomeComputer().messages.push(new Message("asl.msg"));
|
||||
Player.getHomeComputer().messages.push("asl.msg");
|
||||
Player.getHomeComputer().messages.push("af.lit");
|
||||
expect(determineAllPossibilitiesForTabCompletion(Player, "cat ", 0)).equal([
|
||||
"asl.msg",
|
||||
|
Loading…
Reference in New Issue
Block a user