Added font size to text editor

This commit is contained in:
Olivier Gagnon 2021-10-04 21:06:55 -04:00
parent c47a5bc8cc
commit 48b839d68c
11 changed files with 372 additions and 306 deletions

36
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -54,10 +54,7 @@ import {
calculateWeakenTime,
} from "./Hacking";
import { calculateServerGrowth } from "./Server/formulas/grow";
import { Gang } from "./Gang/Gang";
import { AllGangs } from "./Gang/AllGangs";
import { GangMemberTasks } from "./Gang/GangMemberTasks";
import { GangMemberUpgrades } from "./Gang/GangMemberUpgrades";
import { Factions, factionExists } from "./Faction/Factions";
import { joinFaction, purchaseAugmentation } from "./Faction/FactionHelpers";
import { FactionWorkType } from "./Faction/FactionWorkTypeEnum";
@ -161,10 +158,9 @@ import { Augmentation } from "./Augmentation/Augmentation";
import { HacknetNode } from "./Hacknet/HacknetNode";
import { CodingContract } from "./CodingContracts";
import { GangMember } from "./Gang/GangMember";
import { GangMemberTask } from "./Gang/GangMemberTask";
import { Stock } from "./StockMarket/Stock";
import { BaseServer } from "./Server/BaseServer";
import { INetscriptGang, NetscriptGang } from "./NetscriptFunctions/Gang";
const defaultInterpreter = new Interpreter("", () => undefined);
@ -203,6 +199,7 @@ function toNative(pseudoObj: any): any {
interface NS {
[key: string]: any;
gang: INetscriptGang;
}
function NetscriptFunctions(workerScript: WorkerScript): NS {
@ -540,31 +537,6 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
return contract;
};
const checkGangApiAccess = function (func: any): void {
const gang = Player.gang;
if (gang === null) throw new Error("Must have joined gang");
const hasAccess = gang instanceof Gang;
if (!hasAccess) {
throw makeRuntimeErrorMsg(`gang.${func}`, `You do not currently have a Gang`);
}
};
const getGangMember = function (func: any, name: any): GangMember {
const gang = Player.gang;
if (gang === null) throw new Error("Must have joined gang");
for (const member of gang.members) if (member.name === name) return member;
throw makeRuntimeErrorMsg(`gang.${func}`, `Invalid gang member: '${name}'`);
};
const getGangTask = function (func: any, name: any): GangMemberTask {
const task = GangMemberTasks[name];
if (!task) {
throw makeRuntimeErrorMsg(`gang.${func}`, `Invalid task: '${name}'`);
}
return task;
};
const getBladeburnerActionObject = function (func: any, type: any, name: any): any {
const bladeburner = Player.bladeburner;
if (bladeburner === null) throw new Error("Must have joined bladeburner");
@ -783,6 +755,13 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
return out;
};
const helper = {
updateDynamicRam: updateDynamicRam,
makeRuntimeErrorMsg: makeRuntimeErrorMsg,
};
const gang = NetscriptGang(Player, workerScript, helper);
const functions = {
hacknet: {
numNodes: function (): any {
@ -4099,259 +4078,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
},
// Gang API
gang: {
createGang: function (faction: any): any {
updateDynamicRam("createGang", getRamCost("gang", "createGang"));
// this list is copied from Faction/ui/Root.tsx
const GangNames = [
"Slum Snakes",
"Tetrads",
"The Syndicate",
"The Dark Army",
"Speakers for the Dead",
"NiteSec",
"The Black Hand",
];
if (!Player.canAccessGang() || !GangNames.includes(faction)) return false;
if (Player.inGang()) return false;
if (!Player.factions.includes(faction)) return false;
const isHacking = faction === "NiteSec" || faction === "The Black Hand";
Player.startGang(faction, isHacking);
return true;
},
inGang: function (): any {
updateDynamicRam("inGang", getRamCost("gang", "inGang"));
return Player.inGang();
},
getMemberNames: function (): any {
updateDynamicRam("getMemberNames", getRamCost("gang", "getMemberNames"));
checkGangApiAccess("getMemberNames");
const gang = Player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
return gang.members.map((member) => member.name);
},
getGangInformation: function (): any {
updateDynamicRam("getGangInformation", getRamCost("gang", "getGangInformation"));
checkGangApiAccess("getGangInformation");
const gang = Player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
return {
faction: gang.facName,
isHacking: gang.isHackingGang,
moneyGainRate: gang.moneyGainRate,
power: gang.getPower(),
respect: gang.respect,
respectGainRate: gang.respectGainRate,
territory: gang.getTerritory(),
territoryClashChance: gang.territoryClashChance,
territoryWarfareEngaged: gang.territoryWarfareEngaged,
wantedLevel: gang.wanted,
wantedLevelGainRate: gang.wantedGainRate,
};
},
getOtherGangInformation: function (): any {
updateDynamicRam("getOtherGangInformation", getRamCost("gang", "getOtherGangInformation"));
checkGangApiAccess("getOtherGangInformation");
const cpy: any = {};
for (const gang in AllGangs) {
cpy[gang] = Object.assign({}, AllGangs[gang]);
}
return cpy;
},
getMemberInformation: function (name: any): any {
updateDynamicRam("getMemberInformation", getRamCost("gang", "getMemberInformation"));
checkGangApiAccess("getMemberInformation");
const member = getGangMember("getMemberInformation", name);
return {
name: member.name,
task: member.task,
earnedRespect: member.earnedRespect,
hack: member.hack,
str: member.str,
def: member.def,
dex: member.dex,
agi: member.agi,
cha: member.cha,
hack_exp: member.hack_exp,
str_exp: member.str_exp,
def_exp: member.def_exp,
dex_exp: member.dex_exp,
agi_exp: member.agi_exp,
cha_exp: member.cha_exp,
hack_mult: member.hack_mult,
str_mult: member.str_mult,
def_mult: member.def_mult,
dex_mult: member.dex_mult,
agi_mult: member.agi_mult,
cha_mult: member.cha_mult,
hack_asc_mult: member.calculateAscensionMult(member.hack_asc_points),
str_asc_mult: member.calculateAscensionMult(member.str_asc_points),
def_asc_mult: member.calculateAscensionMult(member.def_asc_points),
dex_asc_mult: member.calculateAscensionMult(member.dex_asc_points),
agi_asc_mult: member.calculateAscensionMult(member.agi_asc_points),
cha_asc_mult: member.calculateAscensionMult(member.cha_asc_points),
hack_asc_points: member.hack_asc_points,
str_asc_points: member.str_asc_points,
def_asc_points: member.def_asc_points,
dex_asc_points: member.dex_asc_points,
agi_asc_points: member.agi_asc_points,
cha_asc_points: member.cha_asc_points,
upgrades: member.upgrades.slice(),
augmentations: member.augmentations.slice(),
};
},
canRecruitMember: function (): any {
updateDynamicRam("canRecruitMember", getRamCost("gang", "canRecruitMember"));
checkGangApiAccess("canRecruitMember");
const gang = Player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
return gang.canRecruitMember();
},
recruitMember: function (name: any): any {
updateDynamicRam("recruitMember", getRamCost("gang", "recruitMember"));
checkGangApiAccess("recruitMember");
const gang = Player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
const recruited = gang.recruitMember(name);
if (recruited) {
workerScript.log("recruitMember", `Successfully recruited Gang Member '${name}'`);
} else {
workerScript.log("recruitMember", `Failed to recruit Gang Member '${name}'`);
}
return recruited;
},
getTaskNames: function (): any {
updateDynamicRam("getTaskNames", getRamCost("gang", "getTaskNames"));
checkGangApiAccess("getTaskNames");
const gang = Player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
const tasks = gang.getAllTaskNames();
tasks.unshift("Unassigned");
return tasks;
},
setMemberTask: function (memberName: any, taskName: any): any {
updateDynamicRam("setMemberTask", getRamCost("gang", "setMemberTask"));
checkGangApiAccess("setMemberTask");
const member = getGangMember("setMemberTask", memberName);
const success = member.assignToTask(taskName);
if (success) {
workerScript.log("setMemberTask", `Successfully assigned Gang Member '${memberName}' to '${taskName}' task`);
} else {
workerScript.log(
"setMemberTask",
`Failed to assign Gang Member '${memberName}' to '${taskName}' task. '${memberName}' is now Unassigned`,
);
}
return success;
},
getTaskStats: function (taskName: any): any {
updateDynamicRam("getTaskStats", getRamCost("gang", "getTaskStats"));
checkGangApiAccess("getTaskStats");
const task = getGangTask("getTaskStats", taskName);
const copy = Object.assign({}, task);
copy.territory = Object.assign({}, task.territory);
return copy;
},
getEquipmentNames: function (): any {
updateDynamicRam("getEquipmentNames", getRamCost("gang", "getEquipmentNames"));
checkGangApiAccess("getEquipmentNames");
return Object.keys(GangMemberUpgrades);
},
getEquipmentCost: function (equipName: any): any {
updateDynamicRam("getEquipmentCost", getRamCost("gang", "getEquipmentCost"));
checkGangApiAccess("getEquipmentCost");
const gang = Player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
const upg = GangMemberUpgrades[equipName];
if (upg === null) return Infinity;
return gang.getUpgradeCost(upg);
},
getEquipmentType: function (equipName: any): any {
updateDynamicRam("getEquipmentType", getRamCost("gang", "getEquipmentType"));
checkGangApiAccess("getEquipmentType");
const upg = GangMemberUpgrades[equipName];
if (upg == null) return "";
return upg.getType();
},
getEquipmentStats: function (equipName: any): any {
updateDynamicRam("getEquipmentStats", getRamCost("gang", "getEquipmentStats"));
checkGangApiAccess("getEquipmentStats");
const equipment = GangMemberUpgrades[equipName];
if (!equipment) {
throw makeRuntimeErrorMsg("getEquipmentStats", `Invalid equipment: ${equipName}`);
}
return Object.assign({}, equipment.mults);
},
purchaseEquipment: function (memberName: any, equipName: any): any {
updateDynamicRam("purchaseEquipment", getRamCost("gang", "purchaseEquipment"));
checkGangApiAccess("purchaseEquipment");
const gang = Player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
const member = getGangMember("purchaseEquipment", memberName);
const equipment = GangMemberUpgrades[equipName];
if (!equipment) return false;
const res = member.buyUpgrade(equipment, Player, gang);
if (res) {
workerScript.log("purchaseEquipment", `Purchased '${equipName}' for Gang member '${memberName}'`);
} else {
workerScript.log("purchaseEquipment", `Failed to purchase '${equipName}' for Gang member '${memberName}'`);
}
return res;
},
ascendMember: function (name: any): any {
updateDynamicRam("ascendMember", getRamCost("gang", "ascendMember"));
checkGangApiAccess("ascendMember");
const gang = Player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
const member = getGangMember("ascendMember", name);
if (!member.canAscend()) return;
return gang.ascendMember(member, workerScript);
},
setTerritoryWarfare: function (engage: any): any {
updateDynamicRam("setTerritoryWarfare", getRamCost("gang", "setTerritoryWarfare"));
checkGangApiAccess("setTerritoryWarfare");
const gang = Player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
if (engage) {
gang.territoryWarfareEngaged = true;
workerScript.log("setTerritoryWarfare", "Engaging in Gang Territory Warfare");
} else {
gang.territoryWarfareEngaged = false;
workerScript.log("setTerritoryWarfare", "Disengaging in Gang Territory Warfare");
}
},
getChanceToWinClash: function (otherGang: any): any {
updateDynamicRam("getChanceToWinClash", getRamCost("gang", "getChanceToWinClash"));
checkGangApiAccess("getChanceToWinClash");
const gang = Player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
if (AllGangs[otherGang] == null) {
throw makeRuntimeErrorMsg(`gang.getChanceToWinClash`, `Invalid gang: ${otherGang}`);
}
const playerPower = AllGangs[gang.facName].power;
const otherPower = AllGangs[otherGang].power;
return playerPower / (otherPower + playerPower);
},
getBonusTime: function (): any {
updateDynamicRam("getBonusTime", getRamCost("gang", "getBonusTime"));
checkGangApiAccess("getBonusTime");
const gang = Player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
return Math.round(gang.storedCycles / 5);
},
}, // end gang namespace
gang: gang,
// Bladeburner API
bladeburner: {

@ -0,0 +1,314 @@
import { INetscriptHelper } from "./INetscriptHelper";
import { IPlayer } from "../PersonObjects/IPlayer";
import { getRamCost } from "../Netscript/RamCostGenerator";
import { Gang } from "../Gang/Gang";
import { AllGangs } from "../Gang/AllGangs";
import { GangMemberTasks } from "../Gang/GangMemberTasks";
import { GangMemberUpgrades } from "../Gang/GangMemberUpgrades";
import { WorkerScript } from "../Netscript/WorkerScript";
import { GangMember } from "../Gang/GangMember";
import { GangMemberTask } from "../Gang/GangMemberTask";
export interface INetscriptGang {
createGang(faction: any): boolean;
inGang(): boolean;
getMemberNames(): string[];
getGangInformation(): any;
getOtherGangInformation(): any;
getMemberInformation(name: string): any;
canRecruitMember(): boolean;
recruitMember(name: string): boolean;
getTaskNames(): string[];
setMemberTask(memberName: string, taskName: string): boolean;
getTaskStats(taskName: string): any;
getEquipmentNames(): string[];
getEquipmentCost(equipName: string): number;
getEquipmentType(equipName: string): string;
getEquipmentStats(equipName: string): any;
purchaseEquipment(memberName: string, equipName: string): any;
ascendMember(name: string): any;
setTerritoryWarfare(engage: boolean): void;
getChanceToWinClash(otherGang: string): number;
getBonusTime(): number;
}
export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helper: INetscriptHelper): INetscriptGang {
const checkGangApiAccess = function (func: string): void {
const gang = player.gang;
if (gang === null) throw new Error("Must have joined gang");
const hasAccess = gang instanceof Gang;
if (!hasAccess) {
throw helper.makeRuntimeErrorMsg(`gang.${func}`, `You do not currently have a Gang`);
}
};
const getGangMember = function (func: string, name: string): GangMember {
const gang = player.gang;
if (gang === null) throw new Error("Must have joined gang");
for (const member of gang.members) if (member.name === name) return member;
throw helper.makeRuntimeErrorMsg(`gang.${func}`, `Invalid gang member: '${name}'`);
};
const getGangTask = function (func: string, name: string): GangMemberTask {
const task = GangMemberTasks[name];
if (!task) {
throw helper.makeRuntimeErrorMsg(`gang.${func}`, `Invalid task: '${name}'`);
}
return task;
};
return {
createGang: function (faction: string): any {
helper.updateDynamicRam("createGang", getRamCost("gang", "createGang"));
// this list is copied from Faction/ui/Root.tsx
const GangNames = [
"Slum Snakes",
"Tetrads",
"The Syndicate",
"The Dark Army",
"Speakers for the Dead",
"NiteSec",
"The Black Hand",
];
if (!player.canAccessGang() || !GangNames.includes(faction)) return false;
if (player.inGang()) return false;
if (!player.factions.includes(faction)) return false;
const isHacking = faction === "NiteSec" || faction === "The Black Hand";
player.startGang(faction, isHacking);
return true;
},
inGang: function (): any {
helper.updateDynamicRam("inGang", getRamCost("gang", "inGang"));
return player.inGang();
},
getMemberNames: function (): any {
helper.updateDynamicRam("getMemberNames", getRamCost("gang", "getMemberNames"));
checkGangApiAccess("getMemberNames");
const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
return gang.members.map((member) => member.name);
},
getGangInformation: function (): any {
helper.updateDynamicRam("getGangInformation", getRamCost("gang", "getGangInformation"));
checkGangApiAccess("getGangInformation");
const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
return {
faction: gang.facName,
isHacking: gang.isHackingGang,
moneyGainRate: gang.moneyGainRate,
power: gang.getPower(),
respect: gang.respect,
respectGainRate: gang.respectGainRate,
territory: gang.getTerritory(),
territoryClashChance: gang.territoryClashChance,
territoryWarfareEngaged: gang.territoryWarfareEngaged,
wantedLevel: gang.wanted,
wantedLevelGainRate: gang.wantedGainRate,
};
},
getOtherGangInformation: function (): any {
helper.updateDynamicRam("getOtherGangInformation", getRamCost("gang", "getOtherGangInformation"));
checkGangApiAccess("getOtherGangInformation");
const cpy: any = {};
for (const gang in AllGangs) {
cpy[gang] = Object.assign({}, AllGangs[gang]);
}
return cpy;
},
getMemberInformation: function (name: any): any {
helper.updateDynamicRam("getMemberInformation", getRamCost("gang", "getMemberInformation"));
checkGangApiAccess("getMemberInformation");
const member = getGangMember("getMemberInformation", name);
return {
name: member.name,
task: member.task,
earnedRespect: member.earnedRespect,
hack: member.hack,
str: member.str,
def: member.def,
dex: member.dex,
agi: member.agi,
cha: member.cha,
hack_exp: member.hack_exp,
str_exp: member.str_exp,
def_exp: member.def_exp,
dex_exp: member.dex_exp,
agi_exp: member.agi_exp,
cha_exp: member.cha_exp,
hack_mult: member.hack_mult,
str_mult: member.str_mult,
def_mult: member.def_mult,
dex_mult: member.dex_mult,
agi_mult: member.agi_mult,
cha_mult: member.cha_mult,
hack_asc_mult: member.calculateAscensionMult(member.hack_asc_points),
str_asc_mult: member.calculateAscensionMult(member.str_asc_points),
def_asc_mult: member.calculateAscensionMult(member.def_asc_points),
dex_asc_mult: member.calculateAscensionMult(member.dex_asc_points),
agi_asc_mult: member.calculateAscensionMult(member.agi_asc_points),
cha_asc_mult: member.calculateAscensionMult(member.cha_asc_points),
hack_asc_points: member.hack_asc_points,
str_asc_points: member.str_asc_points,
def_asc_points: member.def_asc_points,
dex_asc_points: member.dex_asc_points,
agi_asc_points: member.agi_asc_points,
cha_asc_points: member.cha_asc_points,
upgrades: member.upgrades.slice(),
augmentations: member.augmentations.slice(),
};
},
canRecruitMember: function (): any {
helper.updateDynamicRam("canRecruitMember", getRamCost("gang", "canRecruitMember"));
checkGangApiAccess("canRecruitMember");
const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
return gang.canRecruitMember();
},
recruitMember: function (name: any): any {
helper.updateDynamicRam("recruitMember", getRamCost("gang", "recruitMember"));
checkGangApiAccess("recruitMember");
const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
const recruited = gang.recruitMember(name);
if (recruited) {
workerScript.log("recruitMember", `Successfully recruited Gang Member '${name}'`);
} else {
workerScript.log("recruitMember", `Failed to recruit Gang Member '${name}'`);
}
return recruited;
},
getTaskNames: function (): any {
helper.updateDynamicRam("getTaskNames", getRamCost("gang", "getTaskNames"));
checkGangApiAccess("getTaskNames");
const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
const tasks = gang.getAllTaskNames();
tasks.unshift("Unassigned");
return tasks;
},
setMemberTask: function (memberName: any, taskName: any): any {
helper.updateDynamicRam("setMemberTask", getRamCost("gang", "setMemberTask"));
checkGangApiAccess("setMemberTask");
const member = getGangMember("setMemberTask", memberName);
const success = member.assignToTask(taskName);
if (success) {
workerScript.log("setMemberTask", `Successfully assigned Gang Member '${memberName}' to '${taskName}' task`);
} else {
workerScript.log(
"setMemberTask",
`Failed to assign Gang Member '${memberName}' to '${taskName}' task. '${memberName}' is now Unassigned`,
);
}
return success;
},
getTaskStats: function (taskName: any): any {
helper.updateDynamicRam("getTaskStats", getRamCost("gang", "getTaskStats"));
checkGangApiAccess("getTaskStats");
const task = getGangTask("getTaskStats", taskName);
const copy = Object.assign({}, task);
copy.territory = Object.assign({}, task.territory);
return copy;
},
getEquipmentNames: function (): any {
helper.updateDynamicRam("getEquipmentNames", getRamCost("gang", "getEquipmentNames"));
checkGangApiAccess("getEquipmentNames");
return Object.keys(GangMemberUpgrades);
},
getEquipmentCost: function (equipName: any): any {
helper.updateDynamicRam("getEquipmentCost", getRamCost("gang", "getEquipmentCost"));
checkGangApiAccess("getEquipmentCost");
const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
const upg = GangMemberUpgrades[equipName];
if (upg === null) return Infinity;
return gang.getUpgradeCost(upg);
},
getEquipmentType: function (equipName: any): any {
helper.updateDynamicRam("getEquipmentType", getRamCost("gang", "getEquipmentType"));
checkGangApiAccess("getEquipmentType");
const upg = GangMemberUpgrades[equipName];
if (upg == null) return "";
return upg.getType();
},
getEquipmentStats: function (equipName: any): any {
helper.updateDynamicRam("getEquipmentStats", getRamCost("gang", "getEquipmentStats"));
checkGangApiAccess("getEquipmentStats");
const equipment = GangMemberUpgrades[equipName];
if (!equipment) {
throw helper.makeRuntimeErrorMsg("getEquipmentStats", `Invalid equipment: ${equipName}`);
}
return Object.assign({}, equipment.mults);
},
purchaseEquipment: function (memberName: any, equipName: any): any {
helper.updateDynamicRam("purchaseEquipment", getRamCost("gang", "purchaseEquipment"));
checkGangApiAccess("purchaseEquipment");
const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
const member = getGangMember("purchaseEquipment", memberName);
const equipment = GangMemberUpgrades[equipName];
if (!equipment) return false;
const res = member.buyUpgrade(equipment, player, gang);
if (res) {
workerScript.log("purchaseEquipment", `Purchased '${equipName}' for Gang member '${memberName}'`);
} else {
workerScript.log("purchaseEquipment", `Failed to purchase '${equipName}' for Gang member '${memberName}'`);
}
return res;
},
ascendMember: function (name: any): any {
helper.updateDynamicRam("ascendMember", getRamCost("gang", "ascendMember"));
checkGangApiAccess("ascendMember");
const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
const member = getGangMember("ascendMember", name);
if (!member.canAscend()) return;
return gang.ascendMember(member, workerScript);
},
setTerritoryWarfare: function (engage: any): void {
helper.updateDynamicRam("setTerritoryWarfare", getRamCost("gang", "setTerritoryWarfare"));
checkGangApiAccess("setTerritoryWarfare");
const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
if (engage) {
gang.territoryWarfareEngaged = true;
workerScript.log("setTerritoryWarfare", "Engaging in Gang Territory Warfare");
} else {
gang.territoryWarfareEngaged = false;
workerScript.log("setTerritoryWarfare", "Disengaging in Gang Territory Warfare");
}
},
getChanceToWinClash: function (otherGang: any): any {
helper.updateDynamicRam("getChanceToWinClash", getRamCost("gang", "getChanceToWinClash"));
checkGangApiAccess("getChanceToWinClash");
const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
if (AllGangs[otherGang] == null) {
throw helper.makeRuntimeErrorMsg(`gang.getChanceToWinClash`, `Invalid gang: ${otherGang}`);
}
const playerPower = AllGangs[gang.facName].power;
const otherPower = AllGangs[otherGang].power;
return playerPower / (otherPower + playerPower);
},
getBonusTime: function (): any {
helper.updateDynamicRam("getBonusTime", getRamCost("gang", "getBonusTime"));
checkGangApiAccess("getBonusTime");
const gang = player.gang;
if (gang === null) throw new Error("Should not be called without Gang");
return Math.round(gang.storedCycles / 5);
},
};
}

@ -0,0 +1,4 @@
export interface INetscriptHelper {
updateDynamicRam(functionName: string, ram: number): void;
makeRuntimeErrorMsg(functionName: string, message: string): void;
}

@ -1,4 +1,5 @@
export interface Options {
theme: string;
insertSpaces: boolean;
fontSize: number;
}

@ -8,6 +8,7 @@ import Typography from "@mui/material/Typography";
import Select from "@mui/material/Select";
import Switch from "@mui/material/Switch";
import MenuItem from "@mui/material/MenuItem";
import TextField from "@mui/material/TextField";
interface IProps {
options: Options;
@ -19,15 +20,23 @@ interface IProps {
export function OptionsModal(props: IProps): React.ReactElement {
const [theme, setTheme] = useState(props.options.theme);
const [insertSpaces, setInsertSpaces] = useState(props.options.insertSpaces);
const [fontSize, setFontSize] = useState(props.options.fontSize);
function save(): void {
props.save({
theme: theme,
insertSpaces: insertSpaces,
fontSize: fontSize,
});
props.onClose();
}
function onFontChange(event: React.ChangeEvent<HTMLInputElement>): void {
const f = parseFloat(event.target.value);
if (isNaN(f)) return;
setFontSize(f);
}
return (
<Modal open={props.open} onClose={props.onClose}>
<Box display="flex" flexDirection="row" alignItems="center">
@ -42,6 +51,9 @@ export function OptionsModal(props: IProps): React.ReactElement {
<Typography>Use whitespace over tabs: </Typography>
<Switch onChange={(event) => setInsertSpaces(event.target.checked)} checked={insertSpaces} />
</Box>
<Box display="flex" flexDirection="row" alignItems="center">
<TextField type="number" label="Font size" value={fontSize} onChange={onFontChange} />
</Box>
<br />
<Button onClick={save}>Save</Button>
</Modal>

@ -31,7 +31,7 @@ import IconButton from "@mui/material/IconButton";
import SettingsIcon from "@mui/icons-material/Settings";
let symbols: string[] = [];
(function () {
export function SetupTextEditor(): void {
const ns = NetscriptFunctions({} as WorkerScript);
function populate(ns: any): string[] {
@ -52,7 +52,7 @@ let symbols: string[] = [];
const exclude = ["heart", "break", "exploit", "bypass", "corporation"];
symbols = symbols.filter((symbol: string) => !exclude.includes(symbol));
})();
}
interface IProps {
filename: string;
@ -87,6 +87,7 @@ export function Root(props: IProps): React.ReactElement {
const [options, setOptions] = useState<Options>({
theme: Settings.MonacoTheme,
insertSpaces: Settings.MonacoInsertSpaces,
fontSize: Settings.MonacoFontSize,
});
// store the last known state in case we need to restart without nano.
@ -329,11 +330,13 @@ export function Root(props: IProps): React.ReactElement {
options={{
theme: Settings.MonacoTheme,
insertSpaces: Settings.MonacoInsertSpaces,
fontSize: Settings.MonacoFontSize,
}}
save={(options: Options) => {
setOptions(options);
Settings.MonacoTheme = options.theme;
Settings.MonacoInsertSpaces = options.insertSpaces;
Settings.MonacoFontSize = options.fontSize;
}}
/>
</>

@ -150,6 +150,8 @@ interface ISettings extends IDefaultSettings {
MonacoTheme: string;
MonacoInsertSpaces: boolean;
MonacoFontSize: number;
}
export const defaultSettings: IDefaultSettings = {
@ -232,6 +234,7 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
SuppressBladeburnerPopup: defaultSettings.SuppressBladeburnerPopup,
MonacoTheme: "vs-dark",
MonacoInsertSpaces: false,
MonacoFontSize: 10,
theme: {
primarylight: defaultSettings.theme.primarylight,

@ -14,6 +14,7 @@ import { CONSTANTS } from "./Constants";
import { Factions, initFactions } from "./Faction/Factions";
import { processPassiveFactionRepGain, inviteToFaction } from "./Faction/FactionHelpers";
import { Router } from "./ui/GameRoot";
import { SetupTextEditor } from "./ScriptEditor/ui/Root";
import {
getHackingWorkRepGain,
@ -422,6 +423,7 @@ const Engine: {
// Start interactive tutorial
iTutorialStart();
}
SetupTextEditor();
},
start: function () {