mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-27 01:53: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 {
|
function sendMessage(msg: Message, forced = false): void {
|
||||||
msg.recvd = true;
|
msg.recvd = true;
|
||||||
if (forced || !Settings.SuppressMessages) {
|
if (forced || !Settings.SuppressMessages) {
|
||||||
showMessage(msg);
|
showMessage(msg.filename);
|
||||||
}
|
}
|
||||||
addMessageToServer(msg, "home");
|
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 =
|
const txt =
|
||||||
"Message received from unknown sender: <br><br>" +
|
"Message received from unknown sender: <br><br>" +
|
||||||
"<i>" +
|
"<i>" +
|
||||||
@ -39,12 +41,11 @@ function addMessageToServer(msg: Message, serverHostname: string): void {
|
|||||||
}
|
}
|
||||||
for (let i = 0; i < server.messages.length; ++i) {
|
for (let i = 0; i < server.messages.length; ++i) {
|
||||||
const other = server.messages[i];
|
const other = server.messages[i];
|
||||||
if (typeof other === "string") continue;
|
if (msg.filename === other) {
|
||||||
if (msg.filename === other.filename) {
|
|
||||||
return; //Already exists
|
return; //Already exists
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
server.messages.push(msg);
|
server.messages.push(msg.filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Checks if any of the 'timed' messages should be sent
|
//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 {
|
export interface INetscriptHelper {
|
||||||
updateDynamicRam(functionName: string, ram: number): void;
|
updateDynamicRam(functionName: string, ram: number): void;
|
||||||
makeRuntimeErrorMsg(functionName: string, message: string): void;
|
makeRuntimeErrorMsg(functionName: string, message: string): void;
|
||||||
string(funcName: string, argName: string, v: any): string;
|
string(funcName: string, argName: string, v: any): string;
|
||||||
number(funcName: string, argName: string, v: any): number;
|
number(funcName: string, argName: string, v: any): number;
|
||||||
boolean(v: any): boolean;
|
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;
|
setBitNodeNumber(n: number): void;
|
||||||
getMult(name: string): number;
|
getMult(name: string): number;
|
||||||
setMult(name: string, mult: number): void;
|
setMult(name: string, mult: number): void;
|
||||||
|
sourceFileLvl(n: number): number;
|
||||||
}
|
}
|
||||||
|
@ -283,6 +283,7 @@ export class PlayerObject implements IPlayer {
|
|||||||
setBitNodeNumber: (n: number) => void;
|
setBitNodeNumber: (n: number) => void;
|
||||||
getMult: (name: string) => number;
|
getMult: (name: string) => number;
|
||||||
setMult: (name: string, mult: number) => void;
|
setMult: (name: string, mult: number) => void;
|
||||||
|
sourceFileLvl: (n: number) => number;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
//Skills and stats
|
//Skills and stats
|
||||||
@ -576,6 +577,7 @@ export class PlayerObject implements IPlayer {
|
|||||||
|
|
||||||
this.getMult = generalMethods.getMult;
|
this.getMult = generalMethods.getMult;
|
||||||
this.setMult = generalMethods.setMult;
|
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;
|
if (!this.hasOwnProperty(name)) return;
|
||||||
(this as any)[name] = mult;
|
(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) {
|
if (anyPlayer.corporation === 0) {
|
||||||
anyPlayer.corporation = null;
|
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 Literature files, this array contains only the filename (string)
|
||||||
// For Messages, it contains the actual Message object
|
// For Messages, it contains the actual Message object
|
||||||
// TODO Separate literature files into its own property
|
// TODO Separate literature files into its own property
|
||||||
messages: (Message | string)[] = [];
|
messages: string[] = [];
|
||||||
|
|
||||||
// Name of company/faction/etc. that this server belongs to.
|
// Name of company/faction/etc. that this server belongs to.
|
||||||
// Optional, not applicable to all Servers
|
// Optional, not applicable to all Servers
|
||||||
|
@ -3,7 +3,6 @@ import { IRouter } from "../../ui/Router";
|
|||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { showMessage } from "../../Message/MessageHelpers";
|
import { showMessage } from "../../Message/MessageHelpers";
|
||||||
import { Message } from "../../Message/Message";
|
|
||||||
import { showLiterature } from "../../Literature/LiteratureHelpers";
|
import { showLiterature } from "../../Literature/LiteratureHelpers";
|
||||||
|
|
||||||
export function cat(
|
export function cat(
|
||||||
@ -29,12 +28,12 @@ export function cat(
|
|||||||
for (let i = 0; i < server.messages.length; ++i) {
|
for (let i = 0; i < server.messages.length; ++i) {
|
||||||
if (filename.endsWith(".lit") && server.messages[i] === filename) {
|
if (filename.endsWith(".lit") && server.messages[i] === filename) {
|
||||||
const file = server.messages[i];
|
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);
|
showLiterature(file);
|
||||||
return;
|
return;
|
||||||
} else if (filename.endsWith(".msg")) {
|
} else if (filename.endsWith(".msg")) {
|
||||||
const file = server.messages[i] as Message;
|
const file = server.messages[i];
|
||||||
if (file.filename !== filename) continue;
|
if (file !== filename) continue;
|
||||||
showMessage(file);
|
showMessage(file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ import { ITerminal } from "../ITerminal";
|
|||||||
import { IRouter } from "../../ui/Router";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { Message } from "../../Message/Message";
|
|
||||||
import { getFirstParentDirectory, isValidDirectoryPath, evaluateDirectoryPath } from "../../Terminal/DirectoryHelpers";
|
import { getFirstParentDirectory, isValidDirectoryPath, evaluateDirectoryPath } from "../../Terminal/DirectoryHelpers";
|
||||||
|
|
||||||
export function ls(
|
export function ls(
|
||||||
@ -103,8 +102,7 @@ export function ls(
|
|||||||
for (const script of s.scripts) handleFn(script.filename, allScripts);
|
for (const script of s.scripts) handleFn(script.filename, allScripts);
|
||||||
for (const txt of s.textFiles) handleFn(txt.fn, allTextFiles);
|
for (const txt of s.textFiles) handleFn(txt.fn, allTextFiles);
|
||||||
for (const contract of s.contracts) handleFn(contract.fn, allContracts);
|
for (const contract of s.contracts) handleFn(contract.fn, allContracts);
|
||||||
for (const msgOrLit of s.messages)
|
for (const msgOrLit of s.messages) handleFn(msgOrLit, allMessages);
|
||||||
msgOrLit instanceof Message ? handleFn(msgOrLit.filename, allMessages) : handleFn(msgOrLit, allMessages);
|
|
||||||
|
|
||||||
// Sort the files/folders alphabetically then print each
|
// Sort the files/folders alphabetically then print each
|
||||||
allPrograms.sort();
|
allPrograms.sort();
|
||||||
|
@ -34,7 +34,7 @@ export function scp(
|
|||||||
if (scriptname.endsWith(".lit")) {
|
if (scriptname.endsWith(".lit")) {
|
||||||
let found = false;
|
let found = false;
|
||||||
for (let i = 0; i < server.messages.length; ++i) {
|
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;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ export function determineAllPossibilitiesForTabCompletion(
|
|||||||
|
|
||||||
function addAllLitFiles(): void {
|
function addAllLitFiles(): void {
|
||||||
for (const file of currServ.messages) {
|
for (const file of currServ.messages) {
|
||||||
if (!(file instanceof Message)) {
|
if (!file.endsWith(".msg")) {
|
||||||
allPos.push(file);
|
allPos.push(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,8 +79,8 @@ export function determineAllPossibilitiesForTabCompletion(
|
|||||||
|
|
||||||
function addAllMessages(): void {
|
function addAllMessages(): void {
|
||||||
for (const file of currServ.messages) {
|
for (const file of currServ.messages) {
|
||||||
if (file instanceof Message) {
|
if (file.endsWith(".msg")) {
|
||||||
allPos.push(file.filename);
|
allPos.push(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
|
|||||||
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
|
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
|
||||||
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
|
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
|
||||||
Player.getHomeComputer().contracts.push(new CodingContract("linklist.cct"));
|
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");
|
Player.getHomeComputer().messages.push("af.lit");
|
||||||
expect(determineAllPossibilitiesForTabCompletion(Player, "rm ", 0)).equal([
|
expect(determineAllPossibilitiesForTabCompletion(Player, "rm ", 0)).equal([
|
||||||
"/www/script.js",
|
"/www/script.js",
|
||||||
@ -120,7 +120,7 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
|
|||||||
|
|
||||||
it("completes the cat command", () => {
|
it("completes the cat command", () => {
|
||||||
Player.getHomeComputer().writeToTextFile("/www/note.txt", "oh hai mark");
|
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");
|
Player.getHomeComputer().messages.push("af.lit");
|
||||||
expect(determineAllPossibilitiesForTabCompletion(Player, "cat ", 0)).equal([
|
expect(determineAllPossibilitiesForTabCompletion(Player, "cat ", 0)).equal([
|
||||||
"asl.msg",
|
"asl.msg",
|
||||||
|
Loading…
Reference in New Issue
Block a user