Address review

Add ns function setToBladeburnerAction
Formatting updates
fix sleeves using player stamina
Correct supporting sleeve causing error
This commit is contained in:
rderfler 2022-04-30 15:25:36 -04:00
parent 47ce4f4927
commit 7cf21629a7
9 changed files with 97 additions and 23 deletions

@ -1264,7 +1264,7 @@ export class Bladeburner implements IBladeburner {
}
}
completeAction(player: IPlayer, person: IPerson, actionIdent: IActionIdentifier): ITaskTracker {
completeAction(player: IPlayer, person: IPerson, actionIdent: IActionIdentifier, isPlayer = true): ITaskTracker {
let retValue = createTaskTracker();
switch (actionIdent.type) {
case ActionTypes["Contract"]:
@ -1281,10 +1281,12 @@ export class Bladeburner implements IBladeburner {
difficulty / BladeburnerConstants.DiffMultLinearFactor;
const rewardMultiplier = Math.pow(action.rewardFac, action.level - 1);
// Stamina loss is based on difficulty
this.stamina -= BladeburnerConstants.BaseStaminaLoss * difficultyMultiplier;
if (this.stamina < 0) {
this.stamina = 0;
if (isPlayer) {
// Stamina loss is based on difficulty
this.stamina -= BladeburnerConstants.BaseStaminaLoss * difficultyMultiplier;
if (this.stamina < 0) {
this.stamina = 0;
}
}
// Process Contract/Operation success/failure

@ -100,7 +100,7 @@ export interface IBladeburner {
completeOperation(success: boolean, player: IPlayer): void;
getActionObject(actionId: IActionIdentifier): IAction | null;
completeContract(success: boolean, actionIdent: IActionIdentifier): void;
completeAction(player: IPlayer, person: IPerson, actionIdent: IActionIdentifier): ITaskTracker;
completeAction(player: IPlayer, person: IPerson, actionIdent: IActionIdentifier, isPlayer?: boolean): ITaskTracker;
infiltrateSynthoidCommunities(): void;
changeRank(player: IPlayer, change: number): void;
processAction(router: IRouter, player: IPlayer, seconds: number): void;

@ -282,6 +282,7 @@ const sleeve: IMap<any> = {
getSleeveAugmentations: RamCostConstants.ScriptSleeveBaseRamCost,
getSleevePurchasableAugs: RamCostConstants.ScriptSleeveBaseRamCost,
purchaseSleeveAug: RamCostConstants.ScriptSleeveBaseRamCost,
setToBladeburnerAction: RamCostConstants.ScriptSleeveBaseRamCost,
};
// Stanek API

@ -310,5 +310,36 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
return player.sleeves[sleeveNumber].tryBuyAugmentation(player, aug);
},
setToBladeburnerAction: function (_sleeveNumber: unknown, _action: unknown, _contract?: unknown): boolean {
updateRam("setToBladeburnerAction");
const sleeveNumber = helper.number("setToBladeburnerAction", "sleeveNumber", _sleeveNumber);
const action = helper.string("setToBladeburnerAction", "action", _action);
let contract: string;
if (typeof _contract === "undefined") {
contract = "------";
} else {
contract = helper.string("setToBladeburnerAction", "contract", _contract);
}
checkSleeveAPIAccess("setToBladeburnerAction");
checkSleeveNumber("setToBladeburnerAction", sleeveNumber);
// Cannot Take on Contracts if another sleeve is performing that action
if (action === "Take on contracts") {
for (let i = 0; i < player.sleeves.length; ++i) {
if (i === sleeveNumber) {
continue;
}
const other = player.sleeves[i];
if (other.currentTask === SleeveTaskType.Bladeburner && other.bbAction === action) {
throw helper.makeRuntimeErrorMsg(
"sleeve.setToBladeburnerAction",
`Sleeve ${sleeveNumber} cannot take of contracts because Sleeve ${i} is already performing that action.`,
);
}
}
}
return player.sleeves[sleeveNumber].bladeburner(player, action, contract);
},
};
}

@ -35,6 +35,8 @@ import { LocationName } from "../../Locations/data/LocationNames";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
import { BladeburnerConstants } from "../../Bladeburner/data/Constants";
import { numeralWrapper } from "../../ui/numeralFormat";
import { capitalizeFirstLetter, capitalizeEachWord } from "../../utils/StringHelperFunctions";
export class Sleeve extends Person {
/**
@ -221,6 +223,10 @@ export class Sleeve extends Person {
return retValue;
}
} else if (this.currentTask === SleeveTaskType.Bladeburner) {
if (this.currentTaskMaxTime === 0) {
this.currentTaskTime = 0;
return retValue;
}
// For bladeburner, all experience and money is gained at the end
const bb = p.bladeburner;
if (bb === null) {
@ -236,10 +242,9 @@ export class Sleeve extends Person {
this.currentTaskTime = 0;
return retValue;
}
let type: string;
let name: string;
if (this.bbAction === "Take on Contracts") {
if (this.bbAction === "Take on contracts") {
type = "Contracts";
name = this.bbContract;
} else {
@ -257,7 +262,7 @@ export class Sleeve extends Person {
const action = bb.getActionObject(actionIdent);
if ((action?.count ?? 0) > 0) {
const bbRetValue = bb.completeAction(p, this, actionIdent);
const bbRetValue = bb.completeAction(p, this, actionIdent, false);
if (bbRetValue) {
retValue = this.gainExperience(p, bbRetValue);
this.gainMoney(p, bbRetValue);
@ -647,7 +652,8 @@ export class Sleeve extends Person {
if (this.currentTask == SleeveTaskType.Class) {
const retVal = createTaskTracker();
retVal.int = CONSTANTS.IntelligenceClassBaseExpGain * Math.round(this.currentTaskTime / 1000);
this.gainExperience(p, retVal); //Wont be shared with other sleeves
const r = this.gainExperience(p, retVal);
p.sleeves.filter((s) => s != this).forEach((s) => s.gainExperience(p, r, 1, true));
}
this.earningsForTask = createTaskTracker();
this.gainRatesForTask = createTaskTracker();
@ -660,7 +666,7 @@ export class Sleeve extends Person {
this.gymStatType = "";
this.className = "";
this.bbAction = "";
this.bbContract = "";
this.bbContract = "------";
}
shockRecovery(p: IPlayer): boolean {
@ -1091,8 +1097,10 @@ export class Sleeve extends Person {
this.currentTaskLocation = "";
let time = 0;
this.bbContract = "------";
switch (action) {
case "Field Analysis":
case "Field analysis":
time = this.getBladeburnerActionTime(p, "General", action);
this.gainRatesForTask.hack = 20 * this.hacking_exp_mult;
this.gainRatesForTask.cha = 20 * this.charisma_exp_mult;
@ -1101,7 +1109,9 @@ export class Sleeve extends Person {
time = this.getBladeburnerActionTime(p, "General", action);
this.gainRatesForTask.cha =
2 * BladeburnerConstants.BaseStatGain * (p.bladeburner?.getRecruitmentTime(this) ?? 0) * 1000;
this.currentTaskLocation = (p.bladeburner?.getRecruitmentSuccessChance(this) ?? 0).toString() + "%";
this.currentTaskLocation = `(Success Rate: ${numeralWrapper.formatPercentage(
this.recrutmentSuccessChance(p),
)})`;
break;
case "Diplomacy":
time = this.getBladeburnerActionTime(p, "General", action);
@ -1114,20 +1124,24 @@ export class Sleeve extends Person {
p.bladeburner?.sleeveSupport(true);
time = 0;
break;
case "Take on Contracts":
case "Take on contracts":
time = this.getBladeburnerActionTime(p, "Contracts", contract);
this.contractGainRates(p, "Contracts", contract);
this.currentTaskLocation = this.contractSuccessChance(p, "Contracts", contract);
this.bbContract = capitalizeEachWord(contract.toLowerCase());
break;
}
this.bbAction = action;
this.bbContract = contract;
this.bbAction = capitalizeFirstLetter(action.toLowerCase());
this.currentTaskMaxTime = time;
this.currentTask = SleeveTaskType.Bladeburner;
return true;
}
recrutmentSuccessChance(p: IPlayer): number {
return Math.max(0, Math.min(1, p.bladeburner?.getRecruitmentSuccessChance(this) ?? 0));
}
contractSuccessChance(p: IPlayer, type: string, name: string): string {
const bb = p.bladeburner;
if (bb === null) {
@ -1143,7 +1157,7 @@ export class Sleeve extends Person {
if (chances[0] >= 1) {
return "100%";
} else {
return `${chances[0] * 100}% - ${chances[1] * 100}%`;
return `${numeralWrapper.formatPercentage(chances[0])} - ${numeralWrapper.formatPercentage(chances[1])}`;
}
}

@ -122,8 +122,7 @@ export function SleeveElem(props: IProps): React.ReactElement {
}
desc = (
<>
This sleeve is currently attempting to {props.sleeve.bbAction}
{message}
This sleeve is currently attempting to {props.sleeve.bbAction}. {message}
</>
);
break;

@ -23,12 +23,12 @@ const universitySelectorOptions: string[] = [
const gymSelectorOptions: string[] = ["Train Strength", "Train Defense", "Train Dexterity", "Train Agility"];
const bladeburnerSelectorOptions: string[] = [
"Field Analysis",
"Field analysis",
"Recruitment",
"Diplomacy",
"Infiltrate synthoids",
"Support main sleeve",
"Take on Contracts",
"Take on contracts",
];
interface IProps {
@ -101,7 +101,7 @@ function possibleContracts(player: IPlayer, sleeve: Sleeve): string[] {
if (sleeve === otherSleeve) {
continue;
}
if (otherSleeve.currentTask === SleeveTaskType.Bladeburner && otherSleeve.bbAction == "Take on Contracts") {
if (otherSleeve.currentTask === SleeveTaskType.Bladeburner && otherSleeve.bbAction == "Take on contracts") {
contracts = contracts.filter((x) => x != otherSleeve.bbContract);
}
}
@ -202,7 +202,7 @@ const tasks: {
return {
first: bladeburnerSelectorOptions,
second: (s1: string) => {
if (s1 === "Take on Contracts") {
if (s1 === "Take on contracts") {
return possibleContracts(player, sleeve);
} else {
return ["------"];

@ -3777,6 +3777,20 @@ export interface Sleeve {
* @returns True if the aug was purchased and installed on the sleeve, false otherwise.
*/
purchaseSleeveAug(sleeveNumber: number, augName: string): boolean;
/**
* Set a sleeve to perform bladeburner actions.
* @remarks
* RAM cost: 4 GB
*
* Return a boolean indicating whether or not the sleeve started working out.
*
* @param sleeveNumber - Index of the sleeve to workout at the gym.
* @param action - Name of the action to be performed.
* @param contract - Name of the contract if applicable.
* @returns True if the sleeve started working out, false otherwise.
*/
setToBladeburnerAction(sleeveNumber: number, action: string, contract?: string): boolean;
}
/**

@ -117,6 +117,17 @@ function cyrb53(str: string, seed = 0): string {
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(16);
}
function capitalizeFirstLetter(s: string): string {
return s.charAt(0).toUpperCase() + s.slice(1);
}
function capitalizeEachWord(s: string): string {
return s
.split(" ")
.map((word) => capitalizeFirstLetter(word))
.join(" ");
}
export {
convertTimeMsToTimeElapsedString,
longestCommonStart,
@ -124,4 +135,6 @@ export {
formatNumber,
generateRandomString,
cyrb53,
capitalizeFirstLetter,
capitalizeEachWord,
};