Merge branch 'dev' into improvement/work-in-progress-ui

This commit is contained in:
nickofolas
2022-05-04 12:28:33 -05:00
72 changed files with 1325 additions and 820 deletions
@@ -18,7 +18,7 @@ export class GraftableAugmentation {
}
get cost(): number {
return this.augmentation.startingCost * CONSTANTS.AugmentationGraftingCostMult;
return this.augmentation.baseCost * CONSTANTS.AugmentationGraftingCostMult;
}
get time(): number {
@@ -1,11 +1,11 @@
import { Augmentations } from "../../Augmentation/Augmentations";
import { StaticAugmentations } from "../../Augmentation/StaticAugmentations";
import { GraftableAugmentation } from "./GraftableAugmentation";
import { IPlayer } from "../IPlayer";
export const getGraftingAvailableAugs = (player: IPlayer): string[] => {
const augs: string[] = [];
for (const [augName, aug] of Object.entries(Augmentations)) {
for (const [augName, aug] of Object.entries(StaticAugmentations)) {
if (aug.isSpecial) continue;
augs.push(augName);
}
+13 -8
View File
@@ -2,7 +2,7 @@ import { Construction, CheckBox, CheckBoxOutlineBlank } from "@mui/icons-materia
import { Box, Button, Container, List, ListItemButton, Paper, Typography } from "@mui/material";
import React, { useState, useEffect } from "react";
import { Augmentation } from "../../../Augmentation/Augmentation";
import { Augmentations } from "../../../Augmentation/Augmentations";
import { StaticAugmentations } from "../../../Augmentation/StaticAugmentations";
import { AugmentationNames } from "../../../Augmentation/data/AugmentationNames";
import { CONSTANTS } from "../../../Constants";
import { hasAugmentationPrereqs } from "../../../Faction/FactionHelpers";
@@ -54,7 +54,7 @@ export const GraftingRoot = (): React.ReactElement => {
const player = use.Player();
const router = use.Router();
for (const aug of Object.values(Augmentations)) {
for (const aug of Object.values(StaticAugmentations)) {
const name = aug.name;
const graftableAug = new GraftableAugmentation(aug);
GraftableAugmentations[name] = graftableAug;
@@ -62,6 +62,7 @@ export const GraftingRoot = (): React.ReactElement => {
const [selectedAug, setSelectedAug] = useState(getGraftingAvailableAugs(player)[0]);
const [graftOpen, setGraftOpen] = useState(false);
const selectedAugmentation = StaticAugmentations[selectedAug];
const setRerender = useState(false)[1];
function rerender(): void {
@@ -148,22 +149,26 @@ export const GraftingRoot = (): React.ReactElement => {
{/* Use formula so the displayed creation time is accurate to player bonus */}
</Typography>
{Augmentations[selectedAug].prereqs.length > 0 && (
<AugPreReqsChecklist player={player} aug={Augmentations[selectedAug]} />
{selectedAugmentation.prereqs.length > 0 && (
<AugPreReqsChecklist player={player} aug={selectedAugmentation} />
)}
<br />
<Typography>
{(() => {
const aug = Augmentations[selectedAug];
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
const info =
typeof selectedAugmentation.info === "string" ? (
<span>{selectedAugmentation.info}</span>
) : (
selectedAugmentation.info
);
const tooltip = (
<>
{info}
<br />
<br />
{aug.stats}
{selectedAugmentation.stats}
</>
);
return tooltip;
+2 -2
View File
@@ -248,7 +248,7 @@ export interface IPlayer {
queryStatFromString(str: string): number;
getIntelligenceBonus(weight: number): number;
getCasinoWinnings(): number;
quitJob(company: string): void;
quitJob(company: string, sing?: boolean): void;
hasJob(): boolean;
createHacknetServer(): HacknetServer;
startCreateProgramWork(programName: string, time: number, reqLevel: number): void;
@@ -291,6 +291,6 @@ export interface IPlayer {
sourceFileLvl(n: number): number;
startGraftAugmentationWork(augmentationName: string, time: number): void;
graftAugmentationWork(numCycles: number): boolean;
finishGraftAugmentationWork(cancelled: boolean): string;
finishGraftAugmentationWork(cancelled: boolean, singularity?: boolean): string;
applyEntropy(stacks?: number): void;
}
+6 -6
View File
@@ -258,7 +258,7 @@ export class PlayerObject implements IPlayer {
queryStatFromString: (str: string) => number;
getIntelligenceBonus: (weight: number) => number;
getCasinoWinnings: () => number;
quitJob: (company: string) => void;
quitJob: (company: string, sing?: boolean) => void;
hasJob: () => boolean;
process: (router: IRouter, numCycles?: number) => void;
createHacknetServer: () => HacknetServer;
@@ -302,7 +302,7 @@ export class PlayerObject implements IPlayer {
sourceFileLvl: (n: number) => number;
startGraftAugmentationWork: (augmentationName: string, time: number) => void;
graftAugmentationWork: (numCycles: number) => boolean;
finishGraftAugmentationWork: (cancelled: boolean) => string;
finishGraftAugmentationWork: (cancelled: boolean, singularity?: boolean) => string;
applyEntropy: (stacks?: number) => void;
constructor() {
@@ -463,12 +463,12 @@ export class PlayerObject implements IPlayer {
this.bladeburner = null;
this.bladeburner_max_stamina_mult = 1;
this.bladeburner_stamina_gain_mult = 1;
this.bladeburner_analysis_mult = 1; //Field Analysis Onl;
this.bladeburner_analysis_mult = 1; //Field Analysis Only
this.bladeburner_success_chance_mult = 1;
// Sleeves & Re-sleeving
this.sleeves = [];
this.sleevesFromCovenant = 0; // # of Duplicate sleeves purchased from the covenan;
this.sleevesFromCovenant = 0; // # of Duplicate sleeves purchased from the covenant
//bitnode
this.bitNodeN = 1;
@@ -483,8 +483,8 @@ export class PlayerObject implements IPlayer {
this.playtimeSinceLastBitnode = 0;
// Keep track of where money comes from
this.moneySourceA = new MoneySourceTracker(); // Where money comes from since last-installed Augmentatio;
this.moneySourceB = new MoneySourceTracker(); // Where money comes from for this entire BitNode ru;
this.moneySourceA = new MoneySourceTracker(); // Where money comes from since last-installed Augmentation
this.moneySourceB = new MoneySourceTracker(); // Where money comes from for this entire BitNode run
// Production since last Augmentation installation
this.scriptProdSinceLastAug = 0;
@@ -1,6 +1,5 @@
import { IPlayer } from "../IPlayer";
import { PlayerObject } from "./PlayerObject";
import { Augmentations } from "../../Augmentation/Augmentations";
import { applyAugmentation } from "../../Augmentation/AugmentationHelpers";
import { PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
@@ -1364,10 +1363,10 @@ export function craftAugmentationWork(this: IPlayer, numCycles: number): boolean
return false;
}
export function finishGraftAugmentationWork(this: IPlayer, cancelled: boolean): string {
export function finishGraftAugmentationWork(this: IPlayer, cancelled: boolean, singularity = false): string {
const augName = this.graftAugmentationName;
if (cancelled === false) {
applyAugmentation(Augmentations[augName]);
applyAugmentation({ name: augName, level: 1 });
if (!this.hasAugmentation(AugmentationNames.CongruityImplant)) {
this.entropy += 1;
@@ -1378,7 +1377,7 @@ export function finishGraftAugmentationWork(this: IPlayer, cancelled: boolean):
`You've finished grafting ${augName}.<br>The augmentation has been applied to your body` +
(this.hasAugmentation(AugmentationNames.CongruityImplant) ? "." : ", but you feel a bit off."),
);
} else {
} else if (cancelled && singularity === false) {
dialogBoxCreate(`You cancelled the grafting of ${augName}.<br>Your money was not returned to you.`);
}
@@ -1700,6 +1699,9 @@ export function singularityStopWork(this: IPlayer): string {
case CONSTANTS.WorkTypeCrime:
res = this.finishCrime(true);
break;
case CONSTANTS.WorkTypeGraftAugmentation:
res = this.finishGraftAugmentationWork(true, true);
break;
default:
console.error(`Unrecognized work type (${this.workType})`);
return "";
@@ -1748,14 +1750,6 @@ export function hospitalize(this: IPlayer): number {
//The 'sing' argument designates whether or not this is being called from
//the applyToCompany() Netscript Singularity function
export function applyForJob(this: IPlayer, entryPosType: CompanyPosition, sing = false): boolean {
// Get current company and job
let currCompany = null;
if (this.companyName !== "") {
currCompany = Companies[this.companyName];
}
const currPositionName = this.jobs[this.companyName];
// Get company that's being applied to
const company = Companies[this.location]; //Company being applied to
if (!(company instanceof Company)) {
console.error(`Could not find company that matches the location: ${this.location}. Player.applyToCompany() failed`);
@@ -1765,66 +1759,44 @@ export function applyForJob(this: IPlayer, entryPosType: CompanyPosition, sing =
let pos = entryPosType;
if (!this.isQualified(company, pos)) {
const reqText = getJobRequirementText(company, pos);
if (!sing) {
dialogBoxCreate("Unfortunately, you do not qualify for this position<br>" + reqText);
dialogBoxCreate("Unfortunately, you do not qualify for this position<br>" + getJobRequirementText(company, pos));
}
return false;
}
// Check if this company has the position
if (!company.hasPosition(pos)) {
console.error(`Company ${company.name} does not have position ${pos}. Player.applyToCompany() failed`);
return false;
}
while (true) {
const newPos = getNextCompanyPositionHelper(pos);
if (newPos == null) {
break;
}
//Check if this company has this position
if (company.hasPosition(newPos)) {
if (!this.isQualified(company, newPos)) {
//If player not qualified for next job, break loop so player will be given current job
break;
}
pos = newPos;
} else {
break;
}
const nextPos = getNextCompanyPositionHelper(pos);
if (nextPos == null) break;
if (company.hasPosition(nextPos) && this.isQualified(company, nextPos)) {
pos = nextPos;
} else break;
}
//Check if the determined job is the same as the player's current job
if (currCompany != null) {
if (currCompany.name == company.name && pos.name == currPositionName) {
//Check if player already has the assigned job
if (this.jobs[company.name] === pos.name) {
if (!sing) {
const nextPos = getNextCompanyPositionHelper(pos);
if (nextPos == null) {
if (!sing) {
dialogBoxCreate("You are already at the highest position for your field! No promotion available");
}
return false;
} else if (company.hasPosition(nextPos)) {
if (!sing) {
const reqText = getJobRequirementText(company, nextPos);
dialogBoxCreate("Unfortunately, you do not qualify for a promotion<br>" + reqText);
}
return false;
if (nextPos == null || !company.hasPosition(nextPos)) {
dialogBoxCreate("You are already at the highest position for your field! No promotion available");
} else {
if (!sing) {
dialogBoxCreate("You are already at the highest position for your field! No promotion available");
}
return false;
const reqText = getJobRequirementText(company, nextPos);
dialogBoxCreate("Unfortunately, you do not qualify for a promotion<br>" + reqText);
}
}
return false;
}
this.jobs[company.name] = pos.name;
if (!this.focus && this.isWorking && this.companyName !== this.location) this.resetWorkStatus();
this.companyName = this.location;
if (!this.isWorking || !this.workType.includes("Working for Company")) this.companyName = company.name;
if (!sing) {
dialogBoxCreate("Congratulations! You were offered a new job at " + this.companyName + " as a " + pos.name + "!");
dialogBoxCreate("Congratulations! You were offered a new job at " + company.name + " as a " + pos.name + "!");
}
return true;
}
@@ -1869,7 +1841,7 @@ export function getNextCompanyPosition(
return entryPosType;
}
export function quitJob(this: IPlayer, company: string): void {
export function quitJob(this: IPlayer, company: string, _sing = false): void {
if (this.isWorking == true && this.workType.includes("Working for Company") && this.companyName == company) {
this.finishWork(true);
}
+2 -2
View File
@@ -686,7 +686,7 @@ export class Sleeve extends Person {
}
tryBuyAugmentation(p: IPlayer, aug: Augmentation): boolean {
if (!p.canAfford(aug.startingCost)) {
if (!p.canAfford(aug.baseCost)) {
return false;
}
@@ -695,7 +695,7 @@ export class Sleeve extends Person {
return false;
}
p.loseMoney(aug.startingCost, "sleeves");
p.loseMoney(aug.baseCost, "sleeves");
this.installAugmentation(aug);
return true;
}
+6 -6
View File
@@ -4,7 +4,7 @@ import { Sleeve } from "./Sleeve";
import { IPlayer } from "../IPlayer";
import { Augmentation } from "../../Augmentation/Augmentation";
import { Augmentations } from "../../Augmentation/Augmentations";
import { StaticAugmentations } from "../../Augmentation/StaticAugmentations";
import { Faction } from "../../Faction/Faction";
import { Factions } from "../../Faction/Factions";
@@ -64,13 +64,13 @@ export function findSleevePurchasableAugs(sleeve: Sleeve, p: IPlayer): Augmentat
if (p.inGang()) {
const fac = p.getGangFaction();
for (const augName of Object.keys(Augmentations)) {
const aug = Augmentations[augName];
for (const augName of Object.keys(StaticAugmentations)) {
const aug = StaticAugmentations[augName];
if (!isAvailableForSleeve(aug)) {
continue;
}
if (fac.playerReputation > aug.baseRepRequirement) {
if (fac.playerReputation > aug.getCost(p).repCost) {
availableAugs.push(aug);
}
}
@@ -89,12 +89,12 @@ export function findSleevePurchasableAugs(sleeve: Sleeve, p: IPlayer): Augmentat
}
for (const augName of fac.augmentations) {
const aug: Augmentation = Augmentations[augName];
const aug: Augmentation = StaticAugmentations[augName];
if (!isAvailableForSleeve(aug)) {
continue;
}
if (fac.playerReputation > aug.baseRepRequirement) {
if (fac.playerReputation > aug.getCost(p).repCost) {
availableAugs.push(aug);
}
}
@@ -52,7 +52,7 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement {
ownedAugNames={ownedAugNames}
player={player}
canPurchase={(player, aug) => {
return player.money > aug.startingCost;
return player.money > aug.baseCost;
}}
purchaseAugmentation={(player, aug, _showModal) => {
props.sleeve.tryBuyAugmentation(player, aug);
+3 -1
View File
@@ -77,7 +77,9 @@ function possibleFactions(player: IPlayer, sleeve: Sleeve): string[] {
}
return factions.filter((faction) => {
const facInfo = Factions[faction].getInfo();
const factionObj = Factions[faction];
if (!factionObj) return false;
const facInfo = factionObj.getInfo();
return facInfo.offerHackingWork || facInfo.offerFieldWork || facInfo.offerSecurityWork;
});
}