mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-21 16:52:55 +02:00
NETSCRIPT: ns.sleeve.getSleeve added. getPlayer and getSleeve can both be used for formulas. (#200)
* BREAKING CHANGE: Removed getSleeveStats and getSleeveInformation because this info is provided by getSleeve in a more usable form. * BREAKING CHANGE: Removed tor, inBladeburner, and hasCorporation fields from ns.getPlayer. Functionality still exists via added functions ns.hasTorRouter, ns.corporation.hasCorporation, and ns.bladeburner.inBladeburner. * Separated ns definitions for Person, Sleeve, and Player interfaces with both Player and Sleeve just extending Person. Added getSleeve, which provides a Sleeve object similar to getPlayer. * Renamed the sleeve ns layer's interface as sleeve lowercase because of name conflict. todo: May move all the ns layers interface names to lowercase for consistency * Added ns.formulas.work.crimeSuccessChance and reworked to allow both sleeve and player calculations. * Removed internal Person.getIntelligenceBonus function which was just a wrapper for calculateIntelligenceBonus. Any use of the former in formulas creates a conflict where ns-provided Person objects throw an error. * Renamed helpers.player to helpers.person for netscript person validation. Reduced number of fields validated due to Person being a smaller interface. * Fixed bug in bladeburner where Player multipliers and int were being used no matter which person was performing the task * Fixed leak of Player.jobs at ns.getPlayer * Person / Player / Sleeve classes now implement the netscript equivalent interfaces. Netscript helper for person no longer asserts that it's a real Person class member, only that it's a Person interface. Functions that use netscript persons have been changed to expect just a person interface to prevent needing this incorrect type assertion.
This commit is contained in:
@@ -47,6 +47,7 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
|
||||
};
|
||||
|
||||
return {
|
||||
inBladeburner: () => () => !!Player.bladeburner,
|
||||
getContractNames: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return bladeburner.getContractNamesNetscriptFn();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Player as player } from "../Player";
|
||||
import { Player, Player as player } from "../Player";
|
||||
|
||||
import { OfficeSpace } from "../Corporation/OfficeSpace";
|
||||
import { Product } from "../Corporation/Product";
|
||||
@@ -63,7 +63,7 @@ import { CityName } from "../Locations/data/CityNames";
|
||||
|
||||
export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
||||
function createCorporation(corporationName: string, selfFund = true): boolean {
|
||||
if (!player.canAccessCorporation() || player.hasCorporation()) return false;
|
||||
if (!player.canAccessCorporation() || player.corporation) return false;
|
||||
if (!corporationName) return false;
|
||||
if (player.bitNodeN !== 3 && !selfFund) throw new Error("cannot use seed funds outside of BitNode 3");
|
||||
if (BitNodeMultipliers.CorporationSoftcap < 0.15)
|
||||
@@ -705,6 +705,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
||||
return {
|
||||
...warehouseAPI,
|
||||
...officeAPI,
|
||||
hasCorporation: () => () => !!Player.corporation,
|
||||
// Todo: Just remove these functions and provide enums?
|
||||
getMaterialNames: (ctx) => () => {
|
||||
checkAccess(ctx);
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
calculateWeakenTime,
|
||||
} from "../Hacking";
|
||||
import { Programs } from "../Programs/Programs";
|
||||
import { Formulas as IFormulas } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { Formulas as IFormulas, Player as IPlayer, Person as IPerson } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import {
|
||||
calculateRespectGain,
|
||||
calculateWantedLevelGain,
|
||||
@@ -87,26 +87,10 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
requiredHackingSkill: 0,
|
||||
serverGrowth: 0,
|
||||
}),
|
||||
mockPlayer: () => () => ({
|
||||
mockPlayer: () => (): IPlayer => ({
|
||||
hp: { current: 0, max: 0 },
|
||||
skills: {
|
||||
hacking: 0,
|
||||
strength: 0,
|
||||
defense: 0,
|
||||
dexterity: 0,
|
||||
agility: 0,
|
||||
charisma: 0,
|
||||
intelligence: 0,
|
||||
},
|
||||
exp: {
|
||||
hacking: 0,
|
||||
strength: 0,
|
||||
defense: 0,
|
||||
dexterity: 0,
|
||||
agility: 0,
|
||||
charisma: 0,
|
||||
intelligence: 0,
|
||||
},
|
||||
skills: { hacking: 0, strength: 0, defense: 0, dexterity: 0, agility: 0, charisma: 0, intelligence: 0 },
|
||||
exp: { hacking: 0, strength: 0, defense: 0, dexterity: 0, agility: 0, charisma: 0, intelligence: 0 },
|
||||
mults: defaultMultipliers(),
|
||||
numPeopleKilled: 0,
|
||||
money: 0,
|
||||
@@ -118,11 +102,15 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
playtimeSinceLastBitnode: 0,
|
||||
jobs: {},
|
||||
factions: [],
|
||||
tor: false,
|
||||
hasCorporation: false,
|
||||
inBladeburner: false,
|
||||
entropy: 0,
|
||||
}),
|
||||
mockPerson: () => (): IPerson => ({
|
||||
hp: { current: 0, max: 0 },
|
||||
skills: { hacking: 0, strength: 0, defense: 0, dexterity: 0, agility: 0, charisma: 0, intelligence: 0 },
|
||||
exp: { hacking: 0, strength: 0, defense: 0, dexterity: 0, agility: 0, charisma: 0, intelligence: 0 },
|
||||
mults: defaultMultipliers(),
|
||||
city: "",
|
||||
}),
|
||||
reputation: {
|
||||
calculateFavorToRep: (ctx) => (_favor) => {
|
||||
const favor = helpers.number(ctx, "favor", _favor);
|
||||
@@ -136,9 +124,9 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
},
|
||||
repFromDonation: (ctx) => (_amount, _player) => {
|
||||
const amount = helpers.number(ctx, "amount", _amount);
|
||||
const player = helpers.player(ctx, _player);
|
||||
const person = helpers.person(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return repFromDonation(amount, player);
|
||||
return repFromDonation(amount, person);
|
||||
},
|
||||
},
|
||||
skills: {
|
||||
@@ -162,49 +150,49 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
hacking: {
|
||||
hackChance: (ctx) => (_server, _player) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
const person = helpers.person(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateHackingChance(server, player);
|
||||
return calculateHackingChance(server, person);
|
||||
},
|
||||
hackExp: (ctx) => (_server, _player) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
const person = helpers.person(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateHackingExpGain(server, player);
|
||||
return calculateHackingExpGain(server, person);
|
||||
},
|
||||
hackPercent: (ctx) => (_server, _player) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
const person = helpers.person(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculatePercentMoneyHacked(server, player);
|
||||
return calculatePercentMoneyHacked(server, person);
|
||||
},
|
||||
growPercent:
|
||||
(ctx) =>
|
||||
(_server, _threads, _player, _cores = 1) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
const person = helpers.person(ctx, _player);
|
||||
const threads = helpers.number(ctx, "threads", _threads);
|
||||
const cores = helpers.number(ctx, "cores", _cores);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateServerGrowth(server, threads, player, cores);
|
||||
return calculateServerGrowth(server, threads, person, cores);
|
||||
},
|
||||
hackTime: (ctx) => (_server, _player) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
const person = helpers.person(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateHackingTime(server, player) * 1000;
|
||||
return calculateHackingTime(server, person) * 1000;
|
||||
},
|
||||
growTime: (ctx) => (_server, _player) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
const person = helpers.person(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateGrowTime(server, player) * 1000;
|
||||
return calculateGrowTime(server, person) * 1000;
|
||||
},
|
||||
weakenTime: (ctx) => (_server, _player) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
const person = helpers.person(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateWeakenTime(server, player) * 1000;
|
||||
return calculateWeakenTime(server, person) * 1000;
|
||||
},
|
||||
},
|
||||
hacknetNodes: {
|
||||
@@ -365,20 +353,26 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
},
|
||||
},
|
||||
work: {
|
||||
crimeSuccessChance: (ctx) => (_person, _crimeType) => {
|
||||
const person = helpers.person(ctx, _person);
|
||||
const crimeType = helpers.string(ctx, "crimeType", _crimeType);
|
||||
if (!checkEnum(CrimeType, crimeType)) throw new Error(`Invalid crime type: ${crimeType}`);
|
||||
return Crimes[crimeType].successRate(person);
|
||||
},
|
||||
crimeGains: (ctx) => (_person, _crimeType) => {
|
||||
const person = helpers.player(ctx, _person);
|
||||
const person = helpers.person(ctx, _person);
|
||||
const crimeType = helpers.string(ctx, "crimeType", _crimeType);
|
||||
if (!checkEnum(CrimeType, crimeType)) throw new Error(`Invalid crime type: ${crimeType}`);
|
||||
return calculateCrimeWorkStats(person, Crimes[crimeType]);
|
||||
},
|
||||
classGains: (ctx) => (_person, _classType, _locationName) => {
|
||||
const person = helpers.player(ctx, _person);
|
||||
const person = helpers.person(ctx, _person);
|
||||
const classType = helpers.string(ctx, "classType", _classType);
|
||||
const locationName = helpers.string(ctx, "locationName", _locationName);
|
||||
return calculateClassEarnings(person, classType as ClassType, locationName as LocationName);
|
||||
},
|
||||
factionGains: (ctx) => (_player, _workType, _favor) => {
|
||||
const player = helpers.player(ctx, _player);
|
||||
const player = helpers.person(ctx, _player);
|
||||
const workType = helpers.string(ctx, "_workType", _workType) as FactionWorkType;
|
||||
const favor = helpers.number(ctx, "favor", _favor);
|
||||
const exp = calculateFactionExp(player, workType);
|
||||
@@ -386,9 +380,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
exp.reputation = rep;
|
||||
return exp;
|
||||
},
|
||||
|
||||
companyGains: (ctx) => (_player, _companyName, _positionName, _favor) => {
|
||||
const player = helpers.player(ctx, _player);
|
||||
const player = helpers.person(ctx, _player);
|
||||
CompanyPositions;
|
||||
const positionName = helpers.string(ctx, "_positionName", _positionName);
|
||||
const position = Object.values(CompanyPositions).find((c) => c.name === positionName);
|
||||
|
||||
@@ -1234,7 +1234,6 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
return true;
|
||||
};
|
||||
const bladeburnerRequirements = () => {
|
||||
if (!Player.inBladeburner()) return false;
|
||||
if (!Player.bladeburner) return false;
|
||||
return Player.bladeburner.blackops[BlackOperationNames.OperationDaedalus];
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ import { CityName } from "../Locations/data/CityNames";
|
||||
import { findCrime } from "../Crime/CrimeHelpers";
|
||||
import { Augmentation } from "../Augmentation/Augmentation";
|
||||
|
||||
import { Sleeve as ISleeve, SleeveSkills } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { sleeve } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { checkEnum } from "../utils/helpers/checkEnum";
|
||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||
import { isSleeveBladeburnerWork } from "../PersonObjects/Sleeve/Work/SleeveBladeburnerWork";
|
||||
@@ -15,7 +15,7 @@ import { Crimes } from "../Crime/Crimes";
|
||||
import { CrimeType } from "../utils/WorkType";
|
||||
import { cloneDeep } from "lodash";
|
||||
|
||||
export function NetscriptSleeve(): InternalAPI<ISleeve> {
|
||||
export function NetscriptSleeve(): InternalAPI<sleeve> {
|
||||
const checkSleeveAPIAccess = function (ctx: NetscriptContext) {
|
||||
if (Player.bitNodeN !== 10 && !Player.sourceFileLvl(10)) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
@@ -33,21 +33,6 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
|
||||
}
|
||||
};
|
||||
|
||||
const getSleeveStats = function (sleeveNumber: number): SleeveSkills {
|
||||
const sl = Player.sleeves[sleeveNumber];
|
||||
return {
|
||||
shock: 100 - sl.shock,
|
||||
sync: sl.sync,
|
||||
memory: sl.memory,
|
||||
hacking: sl.skills.hacking,
|
||||
strength: sl.skills.strength,
|
||||
defense: sl.skills.defense,
|
||||
dexterity: sl.skills.dexterity,
|
||||
agility: sl.skills.agility,
|
||||
charisma: sl.skills.charisma,
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
getNumSleeves: (ctx) => () => {
|
||||
checkSleeveAPIAccess(ctx);
|
||||
@@ -154,12 +139,6 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
|
||||
|
||||
return Player.sleeves[sleeveNumber].workoutAtGym(gymName, stat);
|
||||
},
|
||||
getSleeveStats: (ctx) => (_sleeveNumber) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
return getSleeveStats(sleeveNumber);
|
||||
},
|
||||
getTask: (ctx) => (_sleeveNumber) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
@@ -169,40 +148,25 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
|
||||
if (sl.currentWork === null) return null;
|
||||
return sl.currentWork.APICopy();
|
||||
},
|
||||
getInformation: (ctx) => (_sleeveNumber) => {
|
||||
getSleeve: (ctx) => (_sleeveNumber) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
const sl = Player.sleeves[sleeveNumber];
|
||||
return {
|
||||
tor: false,
|
||||
city: sl.city,
|
||||
hp: sl.hp,
|
||||
jobs: Object.keys(Player.jobs), // technically sleeves have the same jobs as the player.
|
||||
jobTitle: Object.values(Player.jobs),
|
||||
|
||||
mult: {
|
||||
agility: sl.mults.agility,
|
||||
agilityExp: sl.mults.agility_exp,
|
||||
charisma: sl.mults.charisma,
|
||||
charismaExp: sl.mults.charisma_exp,
|
||||
companyRep: sl.mults.company_rep,
|
||||
crimeMoney: sl.mults.crime_money,
|
||||
crimeSuccess: sl.mults.crime_success,
|
||||
defense: sl.mults.defense,
|
||||
defenseExp: sl.mults.defense_exp,
|
||||
dexterity: sl.mults.dexterity,
|
||||
dexterityExp: sl.mults.dexterity_exp,
|
||||
factionRep: sl.mults.faction_rep,
|
||||
hacking: sl.mults.hacking,
|
||||
hackingExp: sl.mults.hacking_exp,
|
||||
strength: sl.mults.strength,
|
||||
strengthExp: sl.mults.strength_exp,
|
||||
workMoney: sl.mults.work_money,
|
||||
},
|
||||
const data = {
|
||||
hp: cloneDeep(sl.hp),
|
||||
skills: cloneDeep(sl.skills),
|
||||
exp: cloneDeep(sl.exp),
|
||||
mults: cloneDeep(sl.mults),
|
||||
city: sl.city,
|
||||
shock: sl.shock,
|
||||
sync: sl.sync,
|
||||
memory: sl.memory,
|
||||
};
|
||||
|
||||
return data;
|
||||
},
|
||||
getSleeveAugmentations: (ctx) => (_sleeveNumber) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
@@ -238,7 +202,7 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
if (getSleeveStats(sleeveNumber).shock > 0) {
|
||||
if (Player.sleeves[sleeveNumber].shock > 0) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Sleeve shock too high: Sleeve ${sleeveNumber}`);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user