mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-17 06:48:42 +02:00
build
This commit is contained in:
@@ -27,12 +27,12 @@ export function NewIndustry(corporation: ICorporation, industry: string, name: s
|
||||
if (cost === undefined) {
|
||||
throw new Error(`Invalid industry: '${industry}'`);
|
||||
}
|
||||
if (corporation.funds < cost) {
|
||||
if (corporation.funds.lt(cost)) {
|
||||
throw new Error("Not enough money to create a new division in this industry");
|
||||
} else if (name === "") {
|
||||
throw new Error("New division must have a name!");
|
||||
} else {
|
||||
corporation.funds = corporation.funds - cost;
|
||||
corporation.funds = corporation.funds.minus(cost);
|
||||
corporation.divisions.push(
|
||||
new Industry({
|
||||
corp: corporation,
|
||||
@@ -44,10 +44,10 @@ export function NewIndustry(corporation: ICorporation, industry: string, name: s
|
||||
}
|
||||
|
||||
export function NewCity(corporation: ICorporation, division: IIndustry, city: string): void {
|
||||
if (corporation.funds < CorporationConstants.OfficeInitialCost) {
|
||||
if (corporation.funds.lt(CorporationConstants.OfficeInitialCost)) {
|
||||
throw new Error("You don't have enough company funds to open a new office!");
|
||||
} else {
|
||||
corporation.funds = corporation.funds - CorporationConstants.OfficeInitialCost;
|
||||
corporation.funds = corporation.funds.minus(CorporationConstants.OfficeInitialCost);
|
||||
division.offices[city] = new OfficeSpace({
|
||||
loc: city,
|
||||
size: CorporationConstants.OfficeInitialSize,
|
||||
@@ -56,7 +56,7 @@ export function NewCity(corporation: ICorporation, division: IIndustry, city: st
|
||||
}
|
||||
|
||||
export function UnlockUpgrade(corporation: ICorporation, upgrade: CorporationUnlockUpgrade): void {
|
||||
if (corporation.funds < upgrade[1]) {
|
||||
if (corporation.funds.lt(upgrade[1])) {
|
||||
throw new Error("Insufficient funds");
|
||||
}
|
||||
corporation.unlock(upgrade);
|
||||
@@ -67,7 +67,7 @@ export function LevelUpgrade(corporation: ICorporation, upgrade: CorporationUpgr
|
||||
const priceMult = upgrade[2];
|
||||
const level = corporation.upgrades[upgrade[0]];
|
||||
const cost = baseCost * Math.pow(priceMult, level);
|
||||
if (corporation.funds < cost) {
|
||||
if (corporation.funds.lt(cost)) {
|
||||
throw new Error("Insufficient funds");
|
||||
} else {
|
||||
corporation.upgrade(upgrade);
|
||||
@@ -259,15 +259,15 @@ export function UpgradeOfficeSize(corp: ICorporation, office: OfficeSpace, size:
|
||||
mult += Math.pow(costMultiplier, initialPriceMult + i);
|
||||
}
|
||||
const cost = CorporationConstants.OfficeInitialCost * mult;
|
||||
if (corp.funds < cost) return;
|
||||
if (corp.funds.lt(cost)) return;
|
||||
office.size += size;
|
||||
corp.funds = corp.funds - cost;
|
||||
corp.funds = corp.funds.minus(cost);
|
||||
}
|
||||
|
||||
export function ThrowParty(corp: ICorporation, office: OfficeSpace, costPerEmployee: number): number {
|
||||
const totalCost = costPerEmployee * office.employees.length;
|
||||
if (corp.funds < totalCost) return 0;
|
||||
corp.funds = corp.funds - totalCost;
|
||||
if (corp.funds.lt(totalCost)) return 0;
|
||||
corp.funds = corp.funds.minus(totalCost);
|
||||
let mult = 0;
|
||||
for (let i = 0; i < office.employees.length; ++i) {
|
||||
mult = office.employees[i].throwParty(costPerEmployee);
|
||||
@@ -277,7 +277,7 @@ export function ThrowParty(corp: ICorporation, office: OfficeSpace, costPerEmplo
|
||||
}
|
||||
|
||||
export function PurchaseWarehouse(corp: ICorporation, division: IIndustry, city: string): void {
|
||||
if (corp.funds < CorporationConstants.WarehouseInitialCost) return;
|
||||
if (corp.funds.lt(CorporationConstants.WarehouseInitialCost)) return;
|
||||
if (division.warehouses[city] instanceof Warehouse) return;
|
||||
division.warehouses[city] = new Warehouse({
|
||||
corp: corp,
|
||||
@@ -285,21 +285,21 @@ export function PurchaseWarehouse(corp: ICorporation, division: IIndustry, city:
|
||||
loc: city,
|
||||
size: CorporationConstants.WarehouseInitialSize,
|
||||
});
|
||||
corp.funds = corp.funds - CorporationConstants.WarehouseInitialCost;
|
||||
corp.funds = corp.funds.minus(CorporationConstants.WarehouseInitialCost);
|
||||
}
|
||||
|
||||
export function UpgradeWarehouse(corp: ICorporation, division: IIndustry, warehouse: Warehouse): void {
|
||||
const sizeUpgradeCost = CorporationConstants.WarehouseUpgradeBaseCost * Math.pow(1.07, warehouse.level + 1);
|
||||
++warehouse.level;
|
||||
warehouse.updateSize(corp, division);
|
||||
corp.funds = corp.funds - sizeUpgradeCost;
|
||||
corp.funds = corp.funds.minus(sizeUpgradeCost);
|
||||
}
|
||||
|
||||
export function BuyCoffee(corp: ICorporation, division: IIndustry, office: OfficeSpace): void {
|
||||
const upgrade = IndustryUpgrades[0];
|
||||
const cost = office.employees.length * upgrade[1];
|
||||
if (corp.funds < cost) return;
|
||||
corp.funds = corp.funds - cost;
|
||||
if (corp.funds.lt(cost)) return;
|
||||
corp.funds = corp.funds.minus(cost);
|
||||
division.upgrade(upgrade, {
|
||||
corporation: corp,
|
||||
office: office,
|
||||
@@ -309,8 +309,8 @@ export function BuyCoffee(corp: ICorporation, division: IIndustry, office: Offic
|
||||
export function HireAdVert(corp: ICorporation, division: IIndustry, office: OfficeSpace): void {
|
||||
const upgrade = IndustryUpgrades[1];
|
||||
const cost = upgrade[1] * Math.pow(upgrade[2], division.upgrades[1]);
|
||||
if (corp.funds < cost) return;
|
||||
corp.funds = corp.funds - cost;
|
||||
if (corp.funds.lt(cost)) return;
|
||||
corp.funds = corp.funds.minus(cost);
|
||||
division.upgrade(upgrade, {
|
||||
corporation: corp,
|
||||
office: office,
|
||||
@@ -340,7 +340,7 @@ export function MakeProduct(
|
||||
if (isNaN(marketingInvest)) {
|
||||
throw new Error("Invalid value for marketing investment");
|
||||
}
|
||||
if (corp.funds < designInvest + marketingInvest) {
|
||||
if (corp.funds.lt(designInvest + marketingInvest)) {
|
||||
throw new Error("You don't have enough company funds to make this large of an investment");
|
||||
}
|
||||
const product = new Product({
|
||||
@@ -352,7 +352,7 @@ export function MakeProduct(
|
||||
if (division.products[product.name] instanceof Product) {
|
||||
throw new Error(`You already have a product with this name!`);
|
||||
}
|
||||
corp.funds = corp.funds - (designInvest + marketingInvest);
|
||||
corp.funds = corp.funds.minus(designInvest + marketingInvest);
|
||||
division.products[product.name] = product;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@ import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { Reviver, Generic_toJSON, Generic_fromJSON } from "../utils/JSONReviver";
|
||||
import { isString } from "../utils/helpers/isString";
|
||||
|
||||
// UI Related Imports
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
|
||||
interface IParams {
|
||||
name?: string;
|
||||
}
|
||||
@@ -25,9 +29,9 @@ export class Corporation {
|
||||
divisions: Industry[] = [];
|
||||
|
||||
//Financial stats
|
||||
funds = 150e9;
|
||||
revenue = 0;
|
||||
expenses = 0;
|
||||
funds = new Decimal(150e9);
|
||||
revenue = new Decimal(0);
|
||||
expenses = new Decimal(0);
|
||||
fundingRound = 0;
|
||||
public = false; //Publicly traded
|
||||
totalShares = CorporationConstants.INITIALSHARES; // Total existing shares
|
||||
@@ -61,7 +65,7 @@ export class Corporation {
|
||||
console.error("Trying to add invalid amount of funds. Report to a developper.");
|
||||
return;
|
||||
}
|
||||
this.funds = this.funds + amt;
|
||||
this.funds = this.funds.plus(amt);
|
||||
}
|
||||
|
||||
getState(): string {
|
||||
@@ -93,8 +97,8 @@ export class Corporation {
|
||||
|
||||
//At the start of a new cycle, calculate profits from previous cycle
|
||||
if (state === "START") {
|
||||
this.revenue = 0;
|
||||
this.expenses = 0;
|
||||
this.revenue = new Decimal(0);
|
||||
this.expenses = new Decimal(0);
|
||||
this.divisions.forEach((ind) => {
|
||||
if (ind.lastCycleRevenue === -Infinity || ind.lastCycleRevenue === Infinity) {
|
||||
return;
|
||||
@@ -102,18 +106,18 @@ export class Corporation {
|
||||
if (ind.lastCycleExpenses === -Infinity || ind.lastCycleExpenses === Infinity) {
|
||||
return;
|
||||
}
|
||||
this.revenue = this.revenue + ind.lastCycleRevenue;
|
||||
this.expenses = this.expenses + ind.lastCycleExpenses;
|
||||
this.revenue = this.revenue.plus(ind.lastCycleRevenue);
|
||||
this.expenses = this.expenses.plus(ind.lastCycleExpenses);
|
||||
});
|
||||
const profit = this.revenue - this.expenses;
|
||||
const cycleProfit = profit * (marketCycles * CorporationConstants.SecsPerMarketCycle);
|
||||
const profit = this.revenue.minus(this.expenses);
|
||||
const cycleProfit = profit.times(marketCycles * CorporationConstants.SecsPerMarketCycle);
|
||||
if (isNaN(this.funds) || this.funds === Infinity || this.funds === -Infinity) {
|
||||
dialogBoxCreate(
|
||||
"There was an error calculating your Corporations funds and they got reset to 0. " +
|
||||
"This is a bug. Please report to game developer.<br><br>" +
|
||||
"(Your funds have been set to $150b for the inconvenience)",
|
||||
);
|
||||
this.funds = 150e9;
|
||||
this.funds = new Decimal(150e9);
|
||||
}
|
||||
|
||||
// Process dividends
|
||||
@@ -143,8 +147,8 @@ export class Corporation {
|
||||
}
|
||||
|
||||
getDividends(): number {
|
||||
const profit = this.revenue - this.expenses;
|
||||
const cycleProfit = profit * CorporationConstants.SecsPerMarketCycle;
|
||||
const profit = this.revenue.minus(this.expenses);
|
||||
const cycleProfit = profit.times(CorporationConstants.SecsPerMarketCycle);
|
||||
const totalDividends = (this.dividendPercentage / 100) * cycleProfit;
|
||||
const dividendsPerShare = totalDividends / this.totalShares;
|
||||
const dividends = this.numShares * dividendsPerShare * (1 - this.dividendTaxPercentage / 100);
|
||||
@@ -161,18 +165,18 @@ export class Corporation {
|
||||
|
||||
determineValuation(): number {
|
||||
let val,
|
||||
profit = this.revenue - this.expenses;
|
||||
profit = this.revenue.minus(this.expenses).toNumber();
|
||||
if (this.public) {
|
||||
// Account for dividends
|
||||
if (this.dividendPercentage > 0) {
|
||||
profit *= (100 - this.dividendPercentage) / 100;
|
||||
}
|
||||
|
||||
val = this.funds + profit * 85e3;
|
||||
val = this.funds.toNumber() + profit * 85e3;
|
||||
val *= Math.pow(1.1, this.divisions.length);
|
||||
val = Math.max(val, 0);
|
||||
} else {
|
||||
val = 10e9 + Math.max(this.funds, 0) / 3; //Base valuation
|
||||
val = 10e9 + Math.max(this.funds.toNumber(), 0) / 3; //Base valuation
|
||||
if (profit > 0) {
|
||||
val += profit * 315e3;
|
||||
val *= Math.pow(1.1, this.divisions.length);
|
||||
@@ -266,12 +270,12 @@ export class Corporation {
|
||||
while (this.unlockUpgrades.length <= upgN) {
|
||||
this.unlockUpgrades.push(0);
|
||||
}
|
||||
if (this.funds < price) {
|
||||
if (this.funds.lt(price)) {
|
||||
dialogBoxCreate("You don't have enough funds to unlock this!");
|
||||
return;
|
||||
}
|
||||
this.unlockUpgrades[upgN] = 1;
|
||||
this.funds = this.funds - price;
|
||||
this.funds = this.funds.minus(price);
|
||||
|
||||
// Apply effects for one-time upgrades
|
||||
if (upgN === 5) {
|
||||
@@ -294,12 +298,12 @@ export class Corporation {
|
||||
this.upgradeMultipliers.push(1);
|
||||
}
|
||||
const totalCost = basePrice * Math.pow(priceMult, this.upgrades[upgN]);
|
||||
if (this.funds < totalCost) {
|
||||
if (this.funds.lt(totalCost)) {
|
||||
dialogBoxCreate("You don't have enough funds to purchase this!");
|
||||
return;
|
||||
}
|
||||
++this.upgrades[upgN];
|
||||
this.funds = this.funds - totalCost;
|
||||
this.funds = this.funds.minus(totalCost);
|
||||
|
||||
//Increase upgrade multiplier
|
||||
this.upgradeMultipliers[upgN] = 1 + this.upgrades[upgN] * upgradeAmt;
|
||||
|
||||
@@ -9,9 +9,9 @@ export interface ICorporation {
|
||||
|
||||
divisions: Industry[];
|
||||
|
||||
funds: number;
|
||||
revenue: number;
|
||||
expenses: number;
|
||||
funds: any;
|
||||
revenue: any;
|
||||
expenses: any;
|
||||
fundingRound: number;
|
||||
public: boolean;
|
||||
totalShares: number;
|
||||
|
||||
@@ -31,10 +31,10 @@ export interface IIndustry {
|
||||
prodMult: number;
|
||||
|
||||
// Decimal
|
||||
lastCycleRevenue: number;
|
||||
lastCycleExpenses: number;
|
||||
thisCycleRevenue: number;
|
||||
thisCycleExpenses: number;
|
||||
lastCycleRevenue: any;
|
||||
lastCycleExpenses: any;
|
||||
thisCycleRevenue: any;
|
||||
thisCycleExpenses: any;
|
||||
|
||||
upgrades: number[];
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Reviver, Generic_toJSON, Generic_fromJSON } from "../utils/JSONReviver";
|
||||
import { CityName } from "../Locations/data/CityNames";
|
||||
import Decimal from "decimal.js";
|
||||
import { Industries, IndustryStartingCosts, IndustryResearchTrees } from "./IndustryData";
|
||||
import { CorporationConstants } from "./data/Constants";
|
||||
import { EmployeePositions } from "./EmployeePositions";
|
||||
@@ -54,10 +55,10 @@ export class Industry implements IIndustry {
|
||||
prodMult = 0; //Production multiplier
|
||||
|
||||
//Financials
|
||||
lastCycleRevenue: number;
|
||||
lastCycleExpenses: number;
|
||||
thisCycleRevenue: number;
|
||||
thisCycleExpenses: number;
|
||||
lastCycleRevenue: any;
|
||||
lastCycleExpenses: any;
|
||||
thisCycleRevenue: any;
|
||||
thisCycleExpenses: any;
|
||||
|
||||
//Upgrades
|
||||
upgrades: number[] = Array(Object.keys(IndustryUpgrades).length).fill(0);
|
||||
@@ -86,10 +87,10 @@ export class Industry implements IIndustry {
|
||||
this.type = params.type ? params.type : Industries.Agriculture;
|
||||
|
||||
//Financials
|
||||
this.lastCycleRevenue = 0;
|
||||
this.lastCycleExpenses = 0;
|
||||
this.thisCycleRevenue = 0;
|
||||
this.thisCycleExpenses = 0;
|
||||
this.lastCycleRevenue = new Decimal(0);
|
||||
this.lastCycleExpenses = new Decimal(0);
|
||||
this.thisCycleRevenue = new Decimal(0);
|
||||
this.thisCycleExpenses = new Decimal(0);
|
||||
|
||||
this.warehouses = {
|
||||
[CityName.Aevum]: 0,
|
||||
@@ -398,17 +399,17 @@ export class Industry implements IIndustry {
|
||||
dialogBoxCreate(
|
||||
"Something went wrong when compting Corporation's revenue/expenses. This is a bug. Please report to game developer",
|
||||
);
|
||||
this.thisCycleRevenue = 0;
|
||||
this.thisCycleExpenses = 0;
|
||||
this.thisCycleRevenue = new Decimal(0);
|
||||
this.thisCycleExpenses = new Decimal(0);
|
||||
}
|
||||
this.lastCycleRevenue = this.thisCycleRevenue / (marketCycles * CorporationConstants.SecsPerMarketCycle);
|
||||
this.lastCycleExpenses = this.thisCycleExpenses / (marketCycles * CorporationConstants.SecsPerMarketCycle);
|
||||
this.thisCycleRevenue = 0;
|
||||
this.thisCycleExpenses = 0;
|
||||
this.lastCycleRevenue = this.thisCycleRevenue.dividedBy(marketCycles * CorporationConstants.SecsPerMarketCycle);
|
||||
this.lastCycleExpenses = this.thisCycleExpenses.dividedBy(marketCycles * CorporationConstants.SecsPerMarketCycle);
|
||||
this.thisCycleRevenue = new Decimal(0);
|
||||
this.thisCycleExpenses = new Decimal(0);
|
||||
|
||||
// Once you start making revenue, the player should no longer be
|
||||
// considered new, and therefore no longer needs the 'tutorial' UI elements
|
||||
if (this.lastCycleRevenue > 0) {
|
||||
if (this.lastCycleRevenue.gt(0)) {
|
||||
this.newInd = false;
|
||||
}
|
||||
|
||||
@@ -421,7 +422,7 @@ export class Industry implements IIndustry {
|
||||
employeeSalary += office.process(marketCycles, corporation, this);
|
||||
}
|
||||
}
|
||||
this.thisCycleExpenses = this.thisCycleExpenses + employeeSalary;
|
||||
this.thisCycleExpenses = this.thisCycleExpenses.plus(employeeSalary);
|
||||
|
||||
// Process change in demand/competition of materials/products
|
||||
this.processMaterialMarket();
|
||||
@@ -445,15 +446,15 @@ export class Industry implements IIndustry {
|
||||
// Process production, purchase, and import/export of materials
|
||||
let res = this.processMaterials(marketCycles, corporation);
|
||||
if (Array.isArray(res)) {
|
||||
this.thisCycleRevenue = this.thisCycleRevenue + res[0];
|
||||
this.thisCycleExpenses = this.thisCycleExpenses + res[1];
|
||||
this.thisCycleRevenue = this.thisCycleRevenue.plus(res[0]);
|
||||
this.thisCycleExpenses = this.thisCycleExpenses.plus(res[1]);
|
||||
}
|
||||
|
||||
// Process creation, production & sale of products
|
||||
res = this.processProducts(marketCycles, corporation);
|
||||
if (Array.isArray(res)) {
|
||||
this.thisCycleRevenue = this.thisCycleRevenue + res[0];
|
||||
this.thisCycleExpenses = this.thisCycleExpenses + res[1];
|
||||
this.thisCycleRevenue = this.thisCycleRevenue.plus(res[0]);
|
||||
this.thisCycleExpenses = this.thisCycleExpenses.plus(res[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1475,10 +1476,10 @@ export class Industry implements IIndustry {
|
||||
division.prodMult = this.prodMult;
|
||||
division.state = this.state;
|
||||
division.newInd = this.newInd;
|
||||
division.lastCycleRevenue = this.lastCycleRevenue + 0;
|
||||
division.lastCycleExpenses = this.lastCycleExpenses + 0;
|
||||
division.thisCycleRevenue = this.thisCycleRevenue + 0;
|
||||
division.thisCycleExpenses = this.thisCycleExpenses + 0;
|
||||
division.lastCycleRevenue = this.lastCycleRevenue.plus(0);
|
||||
division.lastCycleExpenses = this.lastCycleExpenses.plus(0);
|
||||
division.thisCycleRevenue = this.thisCycleRevenue.plus(0);
|
||||
division.thisCycleExpenses = this.thisCycleExpenses.plus(0);
|
||||
division.upgrades = this.upgrades.slice();
|
||||
division.prodMats = this.prodMats.slice();
|
||||
return division;
|
||||
|
||||
@@ -38,7 +38,7 @@ export function BribeFactionModal(props: IProps): React.ReactElement {
|
||||
isNaN(stock) ||
|
||||
money < 0 ||
|
||||
stock < 0 ||
|
||||
corp.funds < money ||
|
||||
corp.funds.lt(money) ||
|
||||
stock > corp.numShares;
|
||||
|
||||
function onMoneyChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
@@ -61,7 +61,7 @@ export function BribeFactionModal(props: IProps): React.ReactElement {
|
||||
if (money === 0 && stock === 0) return "";
|
||||
if (isNaN(money) || isNaN(stock) || money < 0 || stock < 0) {
|
||||
return "ERROR: Invalid value(s) entered";
|
||||
} else if (corp.funds < money) {
|
||||
} else if (corp.funds.lt(money)) {
|
||||
return "ERROR: You do not have this much money to bribe with";
|
||||
} else if (stock > corp.numShares) {
|
||||
return "ERROR: You do not have this many shares to bribe with";
|
||||
@@ -84,7 +84,7 @@ export function BribeFactionModal(props: IProps): React.ReactElement {
|
||||
"You gained " + numeralWrapper.formatReputation(rep) + " reputation with " + fac.name + " by bribing them.",
|
||||
);
|
||||
fac.playerReputation += rep;
|
||||
corp.funds = corp.funds - money;
|
||||
corp.funds = corp.funds.minus(money);
|
||||
corp.numShares -= stock;
|
||||
props.onClose();
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ export function ExpandIndustryTab(props: IProps): React.ReactElement {
|
||||
if (cost === undefined) {
|
||||
throw new Error(`Invalid industry: '${industry}'`);
|
||||
}
|
||||
const disabled = corp.funds < cost || name === "";
|
||||
const disabled = corp.funds.lt(cost) || name === "";
|
||||
|
||||
function newIndustry(): void {
|
||||
if (disabled) return;
|
||||
|
||||
@@ -19,7 +19,7 @@ export function ExpandNewCity(props: IProps): React.ReactElement {
|
||||
const possibleCities = Object.keys(division.offices).filter((cityName: string) => division.offices[cityName] === 0);
|
||||
const [city, setCity] = useState(possibleCities[0]);
|
||||
|
||||
const disabled = corp.funds < CorporationConstants.OfficeInitialCost;
|
||||
const disabled = corp.funds.lt(CorporationConstants.OfficeInitialCost);
|
||||
|
||||
function onCityChange(event: SelectChangeEvent<string>): void {
|
||||
setCity(event.target.value);
|
||||
|
||||
@@ -440,7 +440,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
<br />
|
||||
<Tooltip title={<Typography>Upgrade the office's size so that it can hold more employees!</Typography>}>
|
||||
<span>
|
||||
<Button disabled={corp.funds < 0} onClick={() => setUpgradeOfficeSizeOpen(true)}>
|
||||
<Button disabled={corp.funds.lt(0)} onClick={() => setUpgradeOfficeSizeOpen(true)}>
|
||||
Upgrade size
|
||||
</Button>
|
||||
</span>
|
||||
@@ -458,7 +458,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
title={<Typography>Throw an office party to increase your employee's morale and happiness</Typography>}
|
||||
>
|
||||
<span>
|
||||
<Button disabled={corp.funds < 0} onClick={() => setThrowPartyOpen(true)}>
|
||||
<Button disabled={corp.funds.lt(0)} onClick={() => setThrowPartyOpen(true)}>
|
||||
Throw Party
|
||||
</Button>
|
||||
</span>
|
||||
|
||||
@@ -79,7 +79,11 @@ function MakeProductButton(): React.ReactElement {
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button color={shouldFlash() ? "error" : "primary"} onClick={() => setMakeOpen(true)} disabled={corp.funds < 0}>
|
||||
<Button
|
||||
color={shouldFlash() ? "error" : "primary"}
|
||||
onClick={() => setMakeOpen(true)}
|
||||
disabled={corp.funds.lt(0)}
|
||||
>
|
||||
{createProductButtonText}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
@@ -93,7 +97,7 @@ function Text(): React.ReactElement {
|
||||
const [helpOpen, setHelpOpen] = useState(false);
|
||||
const [researchOpen, setResearchOpen] = useState(false);
|
||||
const vechain = corp.unlockUpgrades[4] === 1;
|
||||
const profit = division.lastCycleRevenue - division.lastCycleExpenses;
|
||||
const profit = division.lastCycleRevenue.minus(division.lastCycleExpenses).toNumber();
|
||||
|
||||
let advertisingInfo = false;
|
||||
const advertisingFactors = division.getAdvertisingFactors();
|
||||
@@ -115,7 +119,7 @@ function Text(): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<Typography>
|
||||
Industry: {division.type} (Corp Funds: <Money money={corp.funds} />)
|
||||
Industry: {division.type} (Corp Funds: <Money money={corp.funds.toNumber()} />)
|
||||
</Typography>
|
||||
<br />
|
||||
<StatsTable
|
||||
@@ -145,8 +149,8 @@ function Text(): React.ReactElement {
|
||||
<br />
|
||||
<StatsTable
|
||||
rows={[
|
||||
["Revenue:", <MoneyRate money={division.lastCycleRevenue} />],
|
||||
["Expenses:", <MoneyRate money={division.lastCycleExpenses} />],
|
||||
["Revenue:", <MoneyRate money={division.lastCycleRevenue.toNumber()} />],
|
||||
["Expenses:", <MoneyRate money={division.lastCycleExpenses.toNumber()} />],
|
||||
["Profit:", <MoneyRate money={profit} />],
|
||||
]}
|
||||
/>
|
||||
@@ -237,8 +241,8 @@ function Upgrades(props: { office: OfficeSpace; rerender: () => void }): React.R
|
||||
}
|
||||
|
||||
function onClick(): void {
|
||||
if (corp.funds < cost) return;
|
||||
corp.funds = corp.funds - cost;
|
||||
if (corp.funds.lt(cost)) return;
|
||||
corp.funds = corp.funds.minus(cost);
|
||||
division.upgrade(upgrade, {
|
||||
corporation: corp,
|
||||
office: props.office,
|
||||
@@ -249,7 +253,7 @@ function Upgrades(props: { office: OfficeSpace; rerender: () => void }): React.R
|
||||
upgrades.push(
|
||||
<Tooltip key={index} title={upgrade[5]}>
|
||||
<span>
|
||||
<Button disabled={corp.funds < cost} onClick={onClick}>
|
||||
<Button disabled={corp.funds.lt(cost)} onClick={onClick}>
|
||||
{upgrade[4]} -
|
||||
<MoneyCost money={cost} corp={corp} />
|
||||
</Button>
|
||||
|
||||
@@ -45,14 +45,14 @@ function WarehouseRoot(props: IProps): React.ReactElement {
|
||||
|
||||
// Upgrade Warehouse size button
|
||||
const sizeUpgradeCost = CorporationConstants.WarehouseUpgradeBaseCost * Math.pow(1.07, props.warehouse.level + 1);
|
||||
const canAffordUpgrade = corp.funds > sizeUpgradeCost;
|
||||
const canAffordUpgrade = corp.funds.gt(sizeUpgradeCost);
|
||||
function upgradeWarehouseOnClick(): void {
|
||||
if (division === null) return;
|
||||
if (props.warehouse === 0) return;
|
||||
if (!canAffordUpgrade) return;
|
||||
++props.warehouse.level;
|
||||
props.warehouse.updateSize(corp, division);
|
||||
corp.funds = corp.funds - sizeUpgradeCost;
|
||||
corp.funds = corp.funds.minus(sizeUpgradeCost);
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ interface IEmptyProps {
|
||||
function EmptyWarehouse(props: IEmptyProps): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const division = useDivision();
|
||||
const disabled = corp.funds < CorporationConstants.WarehouseInitialCost;
|
||||
const disabled = corp.funds.lt(CorporationConstants.WarehouseInitialCost);
|
||||
function purchaseWarehouse(): void {
|
||||
if (disabled) return;
|
||||
PurchaseWarehouse(corp, division, props.city);
|
||||
|
||||
@@ -81,7 +81,7 @@ export function IssueNewSharesModal(props: IProps): React.ReactElement {
|
||||
privateShares = Math.round(privateShares / 1e6) * 1e6;
|
||||
|
||||
corp.issuedShares += newShares - privateShares;
|
||||
corp.funds = corp.funds + profit;
|
||||
corp.funds = corp.funds.plus(profit);
|
||||
corp.immediatelyUpdateSharePrice();
|
||||
props.onClose();
|
||||
dialogBoxCreate(
|
||||
|
||||
@@ -28,7 +28,7 @@ export function LevelableUpgrade(props: IProps): React.ReactElement {
|
||||
|
||||
const tooltip = data[5];
|
||||
function onClick(): void {
|
||||
if (corp.funds < cost) return;
|
||||
if (corp.funds.lt(cost)) return;
|
||||
try {
|
||||
LevelUpgrade(corp, props.upgrade);
|
||||
} catch (err) {
|
||||
@@ -40,13 +40,11 @@ export function LevelableUpgrade(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<Grid item xs={4}>
|
||||
<Box display="flex" alignItems="center" flexDirection="row-reverse">
|
||||
<Button disabled={corp.funds < cost} sx={{ mx: 1 }} onClick={onClick}>
|
||||
<Button disabled={corp.funds.lt(cost)} sx={{ mx: 1 }} onClick={onClick}>
|
||||
<MoneyCost money={cost} corp={corp} />
|
||||
</Button>
|
||||
<Tooltip title={tooltip}>
|
||||
<Typography>
|
||||
{data[4]} - lvl {level}
|
||||
</Typography>
|
||||
<Typography>{data[4]} - lvl {level}</Typography>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</Grid>
|
||||
|
||||
@@ -23,7 +23,7 @@ interface IProps {
|
||||
|
||||
export function MoneyCost(props: IProps): React.ReactElement {
|
||||
const classes = useStyles();
|
||||
if (props.corp.funds <= props.money)
|
||||
if (!props.corp.funds.gt(props.money))
|
||||
return <span className={classes.unbuyable}>{numeralWrapper.formatMoney(props.money)}</span>;
|
||||
|
||||
return <span className={classes.money}>{numeralWrapper.formatMoney(props.money)}</span>;
|
||||
|
||||
@@ -36,7 +36,7 @@ interface IProps {
|
||||
export function Overview({ rerender }: IProps): React.ReactElement {
|
||||
const player = use.Player();
|
||||
const corp = useCorporation();
|
||||
const profit: number = corp.revenue - corp.expenses;
|
||||
const profit: number = corp.revenue.minus(corp.expenses).toNumber();
|
||||
|
||||
const multRows: any[][] = [];
|
||||
function appendMult(name: string, value: number): void {
|
||||
@@ -57,9 +57,9 @@ export function Overview({ rerender }: IProps): React.ReactElement {
|
||||
<>
|
||||
<StatsTable
|
||||
rows={[
|
||||
["Total Funds:", <Money money={corp.funds} />],
|
||||
["Total Revenue:", <MoneyRate money={corp.revenue} />],
|
||||
["Total Expenses:", <MoneyRate money={corp.expenses} />],
|
||||
["Total Funds:", <Money money={corp.funds.toNumber()} />],
|
||||
["Total Revenue:", <MoneyRate money={corp.revenue.toNumber()} />],
|
||||
["Total Expenses:", <MoneyRate money={corp.expenses.toNumber()} />],
|
||||
["Publicly Traded:", corp.public ? "Yes" : "No"],
|
||||
["Owned Stock Shares:", numeralWrapper.format(corp.numShares, "0.000a")],
|
||||
["Stock Price:", corp.public ? <Money money={corp.sharePrice} /> : "N/A"],
|
||||
|
||||
@@ -25,25 +25,15 @@ function BulkPurchaseText(props: IBulkPurchaseTextProps): React.ReactElement {
|
||||
const maxAmount = (props.warehouse.size - props.warehouse.sizeUsed) / matSize;
|
||||
|
||||
if (parsedAmt * matSize > maxAmount) {
|
||||
return (
|
||||
<>
|
||||
<Typography color={"error"}>Not enough warehouse space to purchase this amount</Typography>
|
||||
</>
|
||||
);
|
||||
return <><Typography color={"error"}>Not enough warehouse space to purchase this amount</Typography></>;
|
||||
} else if (isNaN(cost)) {
|
||||
return (
|
||||
<>
|
||||
<Typography color={"error"}>Invalid put for Bulk Purchase amount</Typography>
|
||||
</>
|
||||
);
|
||||
return <><Typography color={"error"}>Invalid put for Bulk Purchase amount</Typography></>;
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
<Typography>
|
||||
Purchasing {numeralWrapper.format(parsedAmt, "0,0.00")} of {props.mat.name} will cost{" "}
|
||||
{numeralWrapper.formatMoney(cost)}
|
||||
</Typography>
|
||||
</>
|
||||
<><Typography>
|
||||
Purchasing {numeralWrapper.format(parsedAmt, "0,0.00")} of {props.mat.name} will cost{" "}
|
||||
{numeralWrapper.formatMoney(cost)}</Typography>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -72,8 +62,8 @@ function BulkPurchase(props: IBPProps): React.ReactElement {
|
||||
dialogBoxCreate("Invalid input amount");
|
||||
} else {
|
||||
const cost = amount * props.mat.bCost;
|
||||
if (corp.funds > cost) {
|
||||
corp.funds = corp.funds - cost;
|
||||
if (corp.funds.gt(cost)) {
|
||||
corp.funds = corp.funds.minus(cost);
|
||||
props.mat.qty += amount;
|
||||
} else {
|
||||
dialogBoxCreate(`You cannot afford this purchase.`);
|
||||
|
||||
@@ -23,7 +23,7 @@ export function ThrowPartyModal(props: IProps): React.ReactElement {
|
||||
const [cost, setCost] = useState(0);
|
||||
|
||||
const totalCost = cost * props.office.employees.length;
|
||||
const canParty = corp.funds >= totalCost;
|
||||
const canParty = corp.funds.gte(totalCost);
|
||||
function changeCost(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
let x = parseFloat(event.target.value);
|
||||
if (isNaN(x)) x = 0;
|
||||
|
||||
@@ -22,7 +22,7 @@ export function UnlockUpgrade(props: IProps): React.ReactElement {
|
||||
const data = props.upgradeData;
|
||||
const tooltip = data[3];
|
||||
function onClick(): void {
|
||||
if (corp.funds < data[1]) return;
|
||||
if (corp.funds.lt(data[1])) return;
|
||||
try {
|
||||
UU(corp, props.upgradeData);
|
||||
} catch (err) {
|
||||
@@ -34,7 +34,7 @@ export function UnlockUpgrade(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<Grid item xs={4}>
|
||||
<Box display="flex" alignItems="center" flexDirection="row-reverse">
|
||||
<Button disabled={corp.funds < data[1]} sx={{ mx: 1 }} onClick={onClick}>
|
||||
<Button disabled={corp.funds.lt(data[1])} sx={{ mx: 1 }} onClick={onClick}>
|
||||
<MoneyCost money={data[1]} corp={corp} />
|
||||
</Button>
|
||||
<Tooltip title={tooltip}>
|
||||
|
||||
@@ -23,7 +23,7 @@ interface IUpgradeButton {
|
||||
function UpgradeSizeButton(props: IUpgradeButton): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
function upgradeSize(cost: number, size: number): void {
|
||||
if (corp.funds < cost) {
|
||||
if (corp.funds.lt(cost)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ function UpgradeSizeButton(props: IUpgradeButton): React.ReactElement {
|
||||
return (
|
||||
<Tooltip title={numeralWrapper.formatMoney(props.cost)}>
|
||||
<span>
|
||||
<Button disabled={corp.funds < props.cost} onClick={() => upgradeSize(props.cost, props.size)}>
|
||||
<Button disabled={corp.funds.lt(props.cost)} onClick={() => upgradeSize(props.cost, props.size)}>
|
||||
+{props.size}
|
||||
</Button>
|
||||
</span>
|
||||
@@ -63,7 +63,7 @@ export function UpgradeOfficeSizeModal(props: IProps): React.ReactElement {
|
||||
const upgradeCost15 = CorporationConstants.OfficeInitialCost * mult;
|
||||
|
||||
//Calculate max upgrade size and cost
|
||||
const maxMult = corp.funds / CorporationConstants.OfficeInitialCost;
|
||||
const maxMult = corp.funds.dividedBy(CorporationConstants.OfficeInitialCost).toNumber();
|
||||
let maxNum = 1;
|
||||
mult = Math.pow(costMultiplier, initialPriceMult);
|
||||
while (maxNum < 50) {
|
||||
|
||||
@@ -19,13 +19,13 @@ interface IProps {
|
||||
export function Corporation(props: IProps): React.ReactElement {
|
||||
function addTonsCorporationFunds(): void {
|
||||
if (props.player.corporation) {
|
||||
props.player.corporation.funds = props.player.corporation.funds + 1e99;
|
||||
props.player.corporation.funds = props.player.corporation.funds.plus(1e99);
|
||||
}
|
||||
}
|
||||
|
||||
function resetCorporationFunds(): void {
|
||||
if (props.player.corporation) {
|
||||
props.player.corporation.funds = props.player.corporation.funds - props.player.corporation.funds;
|
||||
props.player.corporation.funds = props.player.corporation.funds.minus(props.player.corporation.funds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,8 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
||||
const repCost = aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult;
|
||||
const hasReq = props.faction.playerReputation >= repCost;
|
||||
const hasRep = hasAugmentationPrereqs(aug);
|
||||
const hasCost = aug.baseCost !== 0 && player.money > aug.baseCost * props.faction.getInfo().augmentationPriceMult;
|
||||
const hasCost =
|
||||
aug.baseCost !== 0 && player.money.gt(aug.baseCost * props.faction.getInfo().augmentationPriceMult);
|
||||
return hasCost && hasReq && hasRep;
|
||||
}
|
||||
const buy = augs.filter(canBuy).sort((augName1, augName2) => {
|
||||
|
||||
@@ -37,7 +37,7 @@ export function DonateOption(props: IProps): React.ReactElement {
|
||||
function canDonate(): boolean {
|
||||
if (donateAmt === null) return false;
|
||||
if (isNaN(donateAmt) || donateAmt <= 0) return false;
|
||||
if (props.p.money < donateAmt) return false;
|
||||
if (props.p.money.lt(donateAmt)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ export function DonateOption(props: IProps): React.ReactElement {
|
||||
function Status(): React.ReactElement {
|
||||
if (donateAmt === null) return <></>;
|
||||
if (!canDonate()) {
|
||||
if (props.p.money < donateAmt) return <Typography>Insufficient funds</Typography>;
|
||||
if (props.p.money.lt(donateAmt)) return <Typography>Insufficient funds</Typography>;
|
||||
return <Typography>Invalid donate amount entered!</Typography>;
|
||||
}
|
||||
return (
|
||||
|
||||
@@ -88,7 +88,7 @@ export function PurchaseableAugmentation(props: IProps): React.ReactElement {
|
||||
const repCost = aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult;
|
||||
const hasReq = hasAugmentationPrereqs(aug);
|
||||
const hasRep = props.faction.playerReputation >= repCost;
|
||||
const hasCost = aug.baseCost === 0 || props.p.money > aug.baseCost * props.faction.getInfo().augmentationPriceMult;
|
||||
const hasCost = aug.baseCost === 0 || props.p.money.gt(aug.baseCost * props.faction.getInfo().augmentationPriceMult);
|
||||
|
||||
// Determine UI properties
|
||||
const color: "error" | "primary" = !hasReq || !hasRep || !hasCost ? "error" : "primary";
|
||||
|
||||
@@ -316,7 +316,7 @@ export class GangMember {
|
||||
// Prevent purchasing of already-owned upgrades
|
||||
if (this.augmentations.includes(upg.name) || this.upgrades.includes(upg.name)) return false;
|
||||
|
||||
if (player.money < gang.getUpgradeCost(upg)) return false;
|
||||
if (player.money.lt(gang.getUpgradeCost(upg))) return false;
|
||||
player.loseMoney(gang.getUpgradeCost(upg), "gang");
|
||||
if (upg.type === "g") {
|
||||
this.augmentations.push(upg.name);
|
||||
|
||||
@@ -28,7 +28,7 @@ function NextReveal(props: INextRevealProps): React.ReactElement {
|
||||
const upgrades = Object.keys(GangMemberUpgrades)
|
||||
.filter((upgName: string) => {
|
||||
const upg = GangMemberUpgrades[upgName];
|
||||
if (player.money > gang.getUpgradeCost(upg)) return false;
|
||||
if (player.money.gt(gang.getUpgradeCost(upg))) return false;
|
||||
if (upg.type !== props.type) return false;
|
||||
if (props.upgrades.includes(upgName)) return false;
|
||||
return true;
|
||||
@@ -96,7 +96,7 @@ function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement {
|
||||
return Object.keys(GangMemberUpgrades)
|
||||
.filter((upgName: string) => {
|
||||
const upg = GangMemberUpgrades[upgName];
|
||||
if (player.money < gang.getUpgradeCost(upg)) return false;
|
||||
if (player.money.lt(gang.getUpgradeCost(upg))) return false;
|
||||
if (upg.type !== type) return false;
|
||||
if (list.includes(upgName)) return false;
|
||||
return true;
|
||||
|
||||
@@ -98,14 +98,14 @@ export function getMaxNumberLevelUpgrades(
|
||||
throw new Error(`getMaxNumberLevelUpgrades() called without maxLevel arg`);
|
||||
}
|
||||
|
||||
if (player.money < nodeObj.calculateLevelUpgradeCost(1, player.hacknet_node_level_cost_mult)) {
|
||||
if (player.money.lt(nodeObj.calculateLevelUpgradeCost(1, player.hacknet_node_level_cost_mult))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let min = 1;
|
||||
let max = maxLevel - 1;
|
||||
const levelsToMax = maxLevel - nodeObj.level;
|
||||
if (player.money > nodeObj.calculateLevelUpgradeCost(levelsToMax, player.hacknet_node_level_cost_mult)) {
|
||||
if (player.money.gt(nodeObj.calculateLevelUpgradeCost(levelsToMax, player.hacknet_node_level_cost_mult))) {
|
||||
return levelsToMax;
|
||||
}
|
||||
|
||||
@@ -113,13 +113,13 @@ export function getMaxNumberLevelUpgrades(
|
||||
const curr = ((min + max) / 2) | 0;
|
||||
if (
|
||||
curr !== maxLevel &&
|
||||
player.money > nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult) &&
|
||||
player.money < nodeObj.calculateLevelUpgradeCost(curr + 1, player.hacknet_node_level_cost_mult)
|
||||
player.money.gt(nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult)) &&
|
||||
player.money.lt(nodeObj.calculateLevelUpgradeCost(curr + 1, player.hacknet_node_level_cost_mult))
|
||||
) {
|
||||
return Math.min(levelsToMax, curr);
|
||||
} else if (player.money < nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult)) {
|
||||
} else if (player.money.lt(nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult))) {
|
||||
max = curr - 1;
|
||||
} else if (player.money > nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult)) {
|
||||
} else if (player.money.gt(nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult))) {
|
||||
min = curr + 1;
|
||||
} else {
|
||||
return Math.min(levelsToMax, curr);
|
||||
@@ -138,7 +138,7 @@ export function getMaxNumberRamUpgrades(
|
||||
throw new Error(`getMaxNumberRamUpgrades() called without maxLevel arg`);
|
||||
}
|
||||
|
||||
if (player.money < nodeObj.calculateRamUpgradeCost(1, player.hacknet_node_ram_cost_mult)) {
|
||||
if (player.money.lt(nodeObj.calculateRamUpgradeCost(1, player.hacknet_node_ram_cost_mult))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -148,13 +148,13 @@ export function getMaxNumberRamUpgrades(
|
||||
} else {
|
||||
levelsToMax = Math.round(Math.log2(maxLevel / nodeObj.ram));
|
||||
}
|
||||
if (player.money > nodeObj.calculateRamUpgradeCost(levelsToMax, player.hacknet_node_ram_cost_mult)) {
|
||||
if (player.money.gt(nodeObj.calculateRamUpgradeCost(levelsToMax, player.hacknet_node_ram_cost_mult))) {
|
||||
return levelsToMax;
|
||||
}
|
||||
|
||||
//We'll just loop until we find the max
|
||||
for (let i = levelsToMax - 1; i >= 0; --i) {
|
||||
if (player.money > nodeObj.calculateRamUpgradeCost(i, player.hacknet_node_ram_cost_mult)) {
|
||||
if (player.money.gt(nodeObj.calculateRamUpgradeCost(i, player.hacknet_node_ram_cost_mult))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -171,14 +171,14 @@ export function getMaxNumberCoreUpgrades(
|
||||
throw new Error(`getMaxNumberCoreUpgrades() called without maxLevel arg`);
|
||||
}
|
||||
|
||||
if (player.money < nodeObj.calculateCoreUpgradeCost(1, player.hacknet_node_core_cost_mult)) {
|
||||
if (player.money.lt(nodeObj.calculateCoreUpgradeCost(1, player.hacknet_node_core_cost_mult))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let min = 1;
|
||||
let max = maxLevel - 1;
|
||||
const levelsToMax = maxLevel - nodeObj.cores;
|
||||
if (player.money > nodeObj.calculateCoreUpgradeCost(levelsToMax, player.hacknet_node_core_cost_mult)) {
|
||||
if (player.money.gt(nodeObj.calculateCoreUpgradeCost(levelsToMax, player.hacknet_node_core_cost_mult))) {
|
||||
return levelsToMax;
|
||||
}
|
||||
|
||||
@@ -187,13 +187,13 @@ export function getMaxNumberCoreUpgrades(
|
||||
const curr = ((min + max) / 2) | 0;
|
||||
if (
|
||||
curr != maxLevel &&
|
||||
player.money > nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult) &&
|
||||
player.money < nodeObj.calculateCoreUpgradeCost(curr + 1, player.hacknet_node_core_cost_mult)
|
||||
player.money.gt(nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult)) &&
|
||||
player.money.lt(nodeObj.calculateCoreUpgradeCost(curr + 1, player.hacknet_node_core_cost_mult))
|
||||
) {
|
||||
return Math.min(levelsToMax, curr);
|
||||
} else if (player.money < nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult)) {
|
||||
} else if (player.money.lt(nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult))) {
|
||||
max = curr - 1;
|
||||
} else if (player.money > nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult)) {
|
||||
} else if (player.money.gt(nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult))) {
|
||||
min = curr + 1;
|
||||
} else {
|
||||
return Math.min(levelsToMax, curr);
|
||||
@@ -480,7 +480,7 @@ export function purchaseHashUpgrade(player: IPlayer, upgName: string, upgTarget:
|
||||
player.hashManager.refundUpgrade(upgName);
|
||||
return false;
|
||||
}
|
||||
corp.funds = corp.funds + upg.value;
|
||||
corp.funds = corp.funds.plus(upg.value);
|
||||
break;
|
||||
}
|
||||
case "Reduce Minimum Security": {
|
||||
|
||||
@@ -155,7 +155,7 @@ export function HacknetServerElem(props: IProps): React.ReactElement {
|
||||
<Money money={upgradeCacheCost} player={props.player} />
|
||||
</>
|
||||
);
|
||||
if (props.player.money < upgradeCacheCost) {
|
||||
if (props.player.money.lt(upgradeCacheCost)) {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export function PlayerInfo(props: IProps): React.ReactElement {
|
||||
<>
|
||||
<Typography>
|
||||
Money:
|
||||
<Money money={props.player.money} />
|
||||
<Money money={props.player.money.toNumber()} />
|
||||
</Typography>
|
||||
|
||||
{hasServers && (
|
||||
|
||||
@@ -2,11 +2,18 @@ import { CONSTANTS } from "../Constants";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
|
||||
export function getHospitalizationCost(p: IPlayer): number {
|
||||
if (p.money < 0) {
|
||||
let money;
|
||||
if (typeof p.money === "number") {
|
||||
money = p.money;
|
||||
} else {
|
||||
money = p.money.toNumber();
|
||||
}
|
||||
|
||||
if (money < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.min(p.money * 0.1, (p.max_hp - p.hp) * CONSTANTS.HospitalCostPerHp);
|
||||
return Math.min(money * 0.1, (p.max_hp - p.hp) * CONSTANTS.HospitalCostPerHp);
|
||||
}
|
||||
|
||||
export function calculateHospitalizationCost(p: IPlayer, damage: number): number {
|
||||
|
||||
@@ -136,7 +136,7 @@ function iTutorialPrevStep(): void {
|
||||
|
||||
function iTutorialEnd(): void {
|
||||
ITutorial.isRunning = false;
|
||||
ITutorial.currStep = iTutorialSteps.End;
|
||||
|
||||
Player.getHomeComputer().messages.push(LiteratureNames.HackersStartingHandbook);
|
||||
ITutorialEvents.emit();
|
||||
}
|
||||
|
||||
@@ -450,7 +450,7 @@ export function NetscriptSingularity(
|
||||
case CityName.NewTokyo:
|
||||
case CityName.Ishima:
|
||||
case CityName.Volhaven:
|
||||
if (player.money < CONSTANTS.TravelCost) {
|
||||
if (player.money.lt(CONSTANTS.TravelCost)) {
|
||||
throw helper.makeRuntimeErrorMsg("travelToCity", "Not enough money to travel.");
|
||||
}
|
||||
player.loseMoney(CONSTANTS.TravelCost, "other");
|
||||
@@ -473,7 +473,7 @@ export function NetscriptSingularity(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player.money < CONSTANTS.TorRouterCost) {
|
||||
if (player.money.lt(CONSTANTS.TorRouterCost)) {
|
||||
workerScript.log("purchaseTor", "You cannot afford to purchase a Tor router.");
|
||||
return false;
|
||||
}
|
||||
@@ -520,7 +520,7 @@ export function NetscriptSingularity(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player.money < item.price) {
|
||||
if (player.money.lt(item.price)) {
|
||||
workerScript.log(
|
||||
"purchaseProgram",
|
||||
`Not enough money to purchase '${item.program}'. Need ${numeralWrapper.formatMoney(item.price)}`,
|
||||
@@ -724,7 +724,7 @@ export function NetscriptSingularity(
|
||||
}
|
||||
|
||||
const cost = player.getUpgradeHomeCoresCost();
|
||||
if (player.money < cost) {
|
||||
if (player.money.lt(cost)) {
|
||||
workerScript.log("upgradeHomeCores", `You don't have enough money. Need ${numeralWrapper.formatMoney(cost)}`);
|
||||
return false;
|
||||
}
|
||||
@@ -757,7 +757,7 @@ export function NetscriptSingularity(
|
||||
}
|
||||
|
||||
const cost = player.getUpgradeHomeRamCost();
|
||||
if (player.money < cost) {
|
||||
if (player.money.lt(cost)) {
|
||||
workerScript.log("upgradeHomeRam", `You don't have enough money. Need ${numeralWrapper.formatMoney(cost)}`);
|
||||
return false;
|
||||
}
|
||||
@@ -1107,7 +1107,7 @@ export function NetscriptSingularity(
|
||||
workerScript.log("donateToFaction", `Invalid donation amount: '${amt}'.`);
|
||||
return false;
|
||||
}
|
||||
if (player.money < amt) {
|
||||
if (player.money.lt(amt)) {
|
||||
workerScript.log(
|
||||
"donateToFaction",
|
||||
`You do not have enough money to donate ${numeralWrapper.formatMoney(amt)} to '${name}'`,
|
||||
|
||||
@@ -319,7 +319,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player.money < getStockMarket4SDataCost()) {
|
||||
if (player.money.lt(getStockMarket4SDataCost())) {
|
||||
workerScript.log("purchase4SMarketData", "Not enough money to purchase 4S Market Data.");
|
||||
return false;
|
||||
}
|
||||
@@ -338,7 +338,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player.money < getStockMarket4STixApiCost()) {
|
||||
if (player.money.lt(getStockMarket4STixApiCost())) {
|
||||
workerScript.log("purchase4SMarketDataTixApi", "Not enough money to purchase 4S Market Data TIX API");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ export interface IPlayer {
|
||||
numPeopleKilled: number;
|
||||
location: LocationName;
|
||||
max_hp: number;
|
||||
readonly money: number;
|
||||
readonly money: any;
|
||||
moneySourceA: MoneySourceTracker;
|
||||
moneySourceB: MoneySourceTracker;
|
||||
playtimeSinceLastAug: number;
|
||||
@@ -134,8 +134,6 @@ export interface IPlayer {
|
||||
className: string;
|
||||
currentWorkFactionName: string;
|
||||
workType: string;
|
||||
workCostMult: number;
|
||||
workExpMult: number;
|
||||
currentWorkFactionDescription: string;
|
||||
timeWorked: number;
|
||||
workMoneyGained: number;
|
||||
|
||||
@@ -35,6 +35,8 @@ import { CityName } from "../../Locations/data/CityNames";
|
||||
import { MoneySourceTracker } from "../../utils/MoneySourceTracker";
|
||||
import { Reviver, Generic_toJSON, Generic_fromJSON } from "../../utils/JSONReviver";
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
|
||||
export class PlayerObject implements IPlayer {
|
||||
// Class members
|
||||
augmentations: IPlayerOwnedAugmentation[];
|
||||
@@ -139,8 +141,6 @@ export class PlayerObject implements IPlayer {
|
||||
className: string;
|
||||
currentWorkFactionName: string;
|
||||
workType: string;
|
||||
workCostMult: number;
|
||||
workExpMult: number;
|
||||
currentWorkFactionDescription: string;
|
||||
timeWorked: number;
|
||||
workMoneyGained: number;
|
||||
@@ -336,7 +336,7 @@ export class PlayerObject implements IPlayer {
|
||||
this.faction_rep_mult = 1;
|
||||
|
||||
//Money
|
||||
this.money = 1000;
|
||||
this.money = new Decimal(1000);
|
||||
|
||||
//Location information
|
||||
this.city = CityName.Sector12;
|
||||
@@ -379,8 +379,6 @@ export class PlayerObject implements IPlayer {
|
||||
this.isWorking = false;
|
||||
this.focus = false;
|
||||
this.workType = "";
|
||||
this.workCostMult = 1;
|
||||
this.workExpMult = 1;
|
||||
|
||||
this.currentWorkFactionName = "";
|
||||
this.currentWorkFactionDescription = "";
|
||||
|
||||
@@ -36,6 +36,7 @@ import {
|
||||
import { GetServer, AddToAllServers, createUniqueRandomIp } from "../../Server/AllServers";
|
||||
import { Server } from "../../Server/Server";
|
||||
import { safetlyCreateUniqueServer } from "../../Server/ServerHelpers";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { SpecialServers } from "../../Server/data/SpecialServers";
|
||||
import { applySourceFile } from "../../SourceFile/applySourceFile";
|
||||
import { applyExploit } from "../../Exploits/applyExploits";
|
||||
@@ -46,6 +47,8 @@ import { getHospitalizationCost } from "../../Hospital/Hospital";
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
import { HacknetServer } from "../../Hacknet/HacknetServer";
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { IRouter } from "../../ui/Router";
|
||||
import { MoneySourceTracker } from "../../utils/MoneySourceTracker";
|
||||
@@ -58,7 +61,6 @@ import { Money } from "../../ui/React/Money";
|
||||
import React from "react";
|
||||
import { serverMetadata } from "../../Server/data/servers";
|
||||
import { SnackbarEvents } from "../../ui/React/Snackbar";
|
||||
import { calculateClassEarnings } from "../formulas/work";
|
||||
|
||||
export function init(this: IPlayer): void {
|
||||
/* Initialize Player's home computer */
|
||||
@@ -100,7 +102,7 @@ export function prestigeAugmentation(this: PlayerObject): void {
|
||||
this.agility_exp = 0;
|
||||
this.charisma_exp = 0;
|
||||
|
||||
this.money = 1000;
|
||||
this.money = new Decimal(1000);
|
||||
|
||||
this.city = CityName.Sector12;
|
||||
this.location = LocationName.TravelAgency;
|
||||
@@ -323,7 +325,7 @@ export function setMoney(this: PlayerObject, money: number): void {
|
||||
console.error("NaN passed into Player.setMoney()");
|
||||
return;
|
||||
}
|
||||
this.money = money;
|
||||
this.money = new Decimal(money);
|
||||
}
|
||||
|
||||
export function gainMoney(this: PlayerObject, money: number, source: string): void {
|
||||
@@ -331,7 +333,7 @@ export function gainMoney(this: PlayerObject, money: number, source: string): vo
|
||||
console.error("NaN passed into Player.gainMoney()");
|
||||
return;
|
||||
}
|
||||
this.money = this.money + money;
|
||||
this.money = this.money.plus(money);
|
||||
this.recordMoneySource(money, source);
|
||||
}
|
||||
|
||||
@@ -340,8 +342,8 @@ export function loseMoney(this: PlayerObject, money: number, source: string): vo
|
||||
console.error("NaN passed into Player.loseMoney()");
|
||||
return;
|
||||
}
|
||||
if (this.money == Infinity && money === Infinity) return;
|
||||
this.money = this.money - money;
|
||||
if (this.money.eq(Infinity) && money === Infinity) return;
|
||||
this.money = this.money.minus(money);
|
||||
this.recordMoneySource(-1 * money, source);
|
||||
}
|
||||
|
||||
@@ -350,7 +352,7 @@ export function canAfford(this: IPlayer, cost: number): boolean {
|
||||
console.error(`NaN passed into Player.canAfford()`);
|
||||
return false;
|
||||
}
|
||||
return this.money >= cost;
|
||||
return this.money.gte(cost);
|
||||
}
|
||||
|
||||
export function recordMoneySource(this: PlayerObject, amt: number, source: string): void {
|
||||
@@ -1303,30 +1305,77 @@ export function startClass(this: IPlayer, router: IRouter, costMult: number, exp
|
||||
this.isWorking = true;
|
||||
this.focus = true;
|
||||
this.workType = CONSTANTS.WorkTypeStudyClass;
|
||||
this.workCostMult = costMult;
|
||||
this.workExpMult = expMult;
|
||||
|
||||
this.className = className;
|
||||
const earnings = calculateClassEarnings(this);
|
||||
this.workMoneyLossRate = earnings.workMoneyLossRate;
|
||||
this.workHackExpGainRate = earnings.workHackExpGainRate;
|
||||
this.workStrExpGainRate = earnings.workStrExpGainRate;
|
||||
this.workDefExpGainRate = earnings.workDefExpGainRate;
|
||||
this.workDexExpGainRate = earnings.workDexExpGainRate;
|
||||
this.workAgiExpGainRate = earnings.workAgiExpGainRate;
|
||||
this.workChaExpGainRate = earnings.workChaExpGainRate;
|
||||
|
||||
const gameCPS = 1000 / CONSTANTS._idleSpeed;
|
||||
|
||||
//Find cost and exp gain per game cycle
|
||||
let cost = 0;
|
||||
let hackExp = 0,
|
||||
strExp = 0,
|
||||
defExp = 0,
|
||||
dexExp = 0,
|
||||
agiExp = 0,
|
||||
chaExp = 0;
|
||||
const hashManager = this.hashManager;
|
||||
switch (className) {
|
||||
case CONSTANTS.ClassStudyComputerScience:
|
||||
hackExp = ((CONSTANTS.ClassStudyComputerScienceBaseExp * expMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassDataStructures:
|
||||
cost = (CONSTANTS.ClassDataStructuresBaseCost * costMult) / gameCPS;
|
||||
hackExp = ((CONSTANTS.ClassDataStructuresBaseExp * expMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassNetworks:
|
||||
cost = (CONSTANTS.ClassNetworksBaseCost * costMult) / gameCPS;
|
||||
hackExp = ((CONSTANTS.ClassNetworksBaseExp * expMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassAlgorithms:
|
||||
cost = (CONSTANTS.ClassAlgorithmsBaseCost * costMult) / gameCPS;
|
||||
hackExp = ((CONSTANTS.ClassAlgorithmsBaseExp * expMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassManagement:
|
||||
cost = (CONSTANTS.ClassManagementBaseCost * costMult) / gameCPS;
|
||||
chaExp = ((CONSTANTS.ClassManagementBaseExp * expMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassLeadership:
|
||||
cost = (CONSTANTS.ClassLeadershipBaseCost * costMult) / gameCPS;
|
||||
chaExp = ((CONSTANTS.ClassLeadershipBaseExp * expMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymStrength:
|
||||
cost = (CONSTANTS.ClassGymBaseCost * costMult) / gameCPS;
|
||||
strExp = (expMult / gameCPS) * hashManager.getTrainingMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymDefense:
|
||||
cost = (CONSTANTS.ClassGymBaseCost * costMult) / gameCPS;
|
||||
defExp = (expMult / gameCPS) * hashManager.getTrainingMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymDexterity:
|
||||
cost = (CONSTANTS.ClassGymBaseCost * costMult) / gameCPS;
|
||||
dexExp = (expMult / gameCPS) * hashManager.getTrainingMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymAgility:
|
||||
cost = (CONSTANTS.ClassGymBaseCost * costMult) / gameCPS;
|
||||
agiExp = (expMult / gameCPS) * hashManager.getTrainingMult();
|
||||
break;
|
||||
default:
|
||||
throw new Error("ERR: Invalid/unrecognized class name");
|
||||
return;
|
||||
}
|
||||
|
||||
this.workMoneyLossRate = cost;
|
||||
this.workHackExpGainRate = hackExp * this.hacking_exp_mult * BitNodeMultipliers.ClassGymExpGain;
|
||||
this.workStrExpGainRate = strExp * this.strength_exp_mult * BitNodeMultipliers.ClassGymExpGain;
|
||||
this.workDefExpGainRate = defExp * this.defense_exp_mult * BitNodeMultipliers.ClassGymExpGain;
|
||||
this.workDexExpGainRate = dexExp * this.dexterity_exp_mult * BitNodeMultipliers.ClassGymExpGain;
|
||||
this.workAgiExpGainRate = agiExp * this.agility_exp_mult * BitNodeMultipliers.ClassGymExpGain;
|
||||
this.workChaExpGainRate = chaExp * this.charisma_exp_mult * BitNodeMultipliers.ClassGymExpGain;
|
||||
router.toWork();
|
||||
}
|
||||
|
||||
export function takeClass(this: IPlayer, numCycles: number): boolean {
|
||||
this.timeWorked += CONSTANTS._idleSpeed * numCycles;
|
||||
const earnings = calculateClassEarnings(this);
|
||||
this.workMoneyLossRate = earnings.workMoneyLossRate;
|
||||
this.workHackExpGainRate = earnings.workHackExpGainRate;
|
||||
this.workStrExpGainRate = earnings.workStrExpGainRate;
|
||||
this.workDefExpGainRate = earnings.workDefExpGainRate;
|
||||
this.workDexExpGainRate = earnings.workDexExpGainRate;
|
||||
this.workAgiExpGainRate = earnings.workAgiExpGainRate;
|
||||
this.workChaExpGainRate = earnings.workChaExpGainRate;
|
||||
this.processWorkEarnings(numCycles);
|
||||
return false;
|
||||
}
|
||||
@@ -2021,7 +2070,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
!illuminatiFac.isMember &&
|
||||
!illuminatiFac.alreadyInvited &&
|
||||
numAugmentations >= 30 &&
|
||||
this.money >= 150000000000 &&
|
||||
this.money.gte(150000000000) &&
|
||||
this.hacking >= 1500 &&
|
||||
this.strength >= 1200 &&
|
||||
this.defense >= 1200 &&
|
||||
@@ -2038,7 +2087,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
!daedalusFac.isMember &&
|
||||
!daedalusFac.alreadyInvited &&
|
||||
numAugmentations >= Math.round(30 * BitNodeMultipliers.DaedalusAugsRequirement) &&
|
||||
this.money >= 100000000000 &&
|
||||
this.money.gte(100000000000) &&
|
||||
(this.hacking >= 2500 ||
|
||||
(this.strength >= 1500 && this.defense >= 1500 && this.dexterity >= 1500 && this.agility >= 1500))
|
||||
) {
|
||||
@@ -2052,7 +2101,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
!covenantFac.isMember &&
|
||||
!covenantFac.alreadyInvited &&
|
||||
numAugmentations >= 20 &&
|
||||
this.money >= 75000000000 &&
|
||||
this.money.gte(75000000000) &&
|
||||
this.hacking >= 850 &&
|
||||
this.strength >= 850 &&
|
||||
this.defense >= 850 &&
|
||||
@@ -2231,7 +2280,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
!chongqingFac.isBanned &&
|
||||
!chongqingFac.isMember &&
|
||||
!chongqingFac.alreadyInvited &&
|
||||
this.money >= 20000000 &&
|
||||
this.money.gte(20000000) &&
|
||||
this.city == CityName.Chongqing
|
||||
) {
|
||||
invitedFactions.push(chongqingFac);
|
||||
@@ -2243,7 +2292,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
!sector12Fac.isBanned &&
|
||||
!sector12Fac.isMember &&
|
||||
!sector12Fac.alreadyInvited &&
|
||||
this.money >= 15000000 &&
|
||||
this.money.gte(15000000) &&
|
||||
this.city == CityName.Sector12
|
||||
) {
|
||||
invitedFactions.push(sector12Fac);
|
||||
@@ -2255,7 +2304,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
!newtokyoFac.isBanned &&
|
||||
!newtokyoFac.isMember &&
|
||||
!newtokyoFac.alreadyInvited &&
|
||||
this.money >= 20000000 &&
|
||||
this.money.gte(20000000) &&
|
||||
this.city == CityName.NewTokyo
|
||||
) {
|
||||
invitedFactions.push(newtokyoFac);
|
||||
@@ -2267,7 +2316,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
!aevumFac.isBanned &&
|
||||
!aevumFac.isMember &&
|
||||
!aevumFac.alreadyInvited &&
|
||||
this.money >= 40000000 &&
|
||||
this.money.gte(40000000) &&
|
||||
this.city == CityName.Aevum
|
||||
) {
|
||||
invitedFactions.push(aevumFac);
|
||||
@@ -2279,7 +2328,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
!ishimaFac.isBanned &&
|
||||
!ishimaFac.isMember &&
|
||||
!ishimaFac.alreadyInvited &&
|
||||
this.money >= 30000000 &&
|
||||
this.money.gte(30000000) &&
|
||||
this.city == CityName.Ishima
|
||||
) {
|
||||
invitedFactions.push(ishimaFac);
|
||||
@@ -2291,7 +2340,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
!volhavenFac.isBanned &&
|
||||
!volhavenFac.isMember &&
|
||||
!volhavenFac.alreadyInvited &&
|
||||
this.money >= 50000000 &&
|
||||
this.money.gte(50000000) &&
|
||||
this.city == CityName.Volhaven
|
||||
) {
|
||||
invitedFactions.push(volhavenFac);
|
||||
@@ -2348,7 +2397,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
this.dexterity >= 200 &&
|
||||
this.agility >= 200 &&
|
||||
(this.city == CityName.Aevum || this.city == CityName.Sector12) &&
|
||||
this.money >= 10000000 &&
|
||||
this.money.gte(10000000) &&
|
||||
this.karma <= -90 &&
|
||||
!allCompanies.includes(LocationName.Sector12CIA) &&
|
||||
!allCompanies.includes(LocationName.Sector12NSA)
|
||||
@@ -2365,7 +2414,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
(allPositions.includes("Chief Technology Officer") ||
|
||||
allPositions.includes("Chief Financial Officer") ||
|
||||
allPositions.includes("Chief Executive Officer")) &&
|
||||
this.money >= 15000000 &&
|
||||
this.money.gte(15000000) &&
|
||||
this.karma <= -22
|
||||
) {
|
||||
invitedFactions.push(silhouetteFac);
|
||||
@@ -2398,7 +2447,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
this.dexterity >= 30 &&
|
||||
this.agility >= 30 &&
|
||||
this.karma <= -9 &&
|
||||
this.money >= 1000000
|
||||
this.money.gte(1000000)
|
||||
) {
|
||||
invitedFactions.push(slumsnakesFac);
|
||||
}
|
||||
@@ -2441,7 +2490,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
!tiandihuiFac.isBanned &&
|
||||
!tiandihuiFac.isMember &&
|
||||
!tiandihuiFac.alreadyInvited &&
|
||||
this.money >= 1000000 &&
|
||||
this.money.gte(1000000) &&
|
||||
this.hacking >= 50 &&
|
||||
(this.city == CityName.Chongqing || this.city == CityName.NewTokyo || this.city == CityName.Ishima)
|
||||
) {
|
||||
|
||||
@@ -64,7 +64,7 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<TableRow key={aug.name}>
|
||||
<TableCell>
|
||||
<Button onClick={() => purchaseAugmentation(aug)} disabled={player.money < aug.startingCost}>
|
||||
<Button onClick={() => purchaseAugmentation(aug)} disabled={player.money.lt(aug.startingCost)}>
|
||||
Buy
|
||||
</Button>
|
||||
</TableCell>
|
||||
|
||||
@@ -174,9 +174,9 @@ export function SleeveElem(props: IProps): React.ReactElement {
|
||||
<Grid item xs={3}>
|
||||
<StatsElement sleeve={props.sleeve} />
|
||||
<Button onClick={() => setStatsOpen(true)}>More Stats</Button>
|
||||
<Tooltip title={player.money < CONSTANTS.TravelCost ? <Typography>Insufficient funds</Typography> : ""}>
|
||||
<Tooltip title={player.money.lt(CONSTANTS.TravelCost) ? <Typography>Insufficient funds</Typography> : ""}>
|
||||
<span>
|
||||
<Button onClick={() => setTravelOpen(true)} disabled={player.money < CONSTANTS.TravelCost}>
|
||||
<Button onClick={() => setTravelOpen(true)} disabled={player.money.lt(CONSTANTS.TravelCost)}>
|
||||
Travel
|
||||
</Button>
|
||||
</span>
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
export interface WorkEarnings {
|
||||
workMoneyLossRate: number;
|
||||
workHackExpGainRate: number;
|
||||
workStrExpGainRate: number;
|
||||
workDefExpGainRate: number;
|
||||
workDexExpGainRate: number;
|
||||
workAgiExpGainRate: number;
|
||||
workChaExpGainRate: number;
|
||||
}
|
||||
|
||||
export function calculateClassEarnings(player: IPlayer): WorkEarnings {
|
||||
const gameCPS = 1000 / CONSTANTS._idleSpeed;
|
||||
|
||||
//Find cost and exp gain per game cycle
|
||||
let cost = 0;
|
||||
let hackExp = 0,
|
||||
strExp = 0,
|
||||
defExp = 0,
|
||||
dexExp = 0,
|
||||
agiExp = 0,
|
||||
chaExp = 0;
|
||||
const hashManager = player.hashManager;
|
||||
switch (player.className) {
|
||||
case CONSTANTS.ClassStudyComputerScience:
|
||||
hackExp =
|
||||
((CONSTANTS.ClassStudyComputerScienceBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassDataStructures:
|
||||
cost = (CONSTANTS.ClassDataStructuresBaseCost * player.workCostMult) / gameCPS;
|
||||
hackExp = ((CONSTANTS.ClassDataStructuresBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassNetworks:
|
||||
cost = (CONSTANTS.ClassNetworksBaseCost * player.workCostMult) / gameCPS;
|
||||
hackExp = ((CONSTANTS.ClassNetworksBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassAlgorithms:
|
||||
cost = (CONSTANTS.ClassAlgorithmsBaseCost * player.workCostMult) / gameCPS;
|
||||
hackExp = ((CONSTANTS.ClassAlgorithmsBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassManagement:
|
||||
cost = (CONSTANTS.ClassManagementBaseCost * player.workCostMult) / gameCPS;
|
||||
chaExp = ((CONSTANTS.ClassManagementBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassLeadership:
|
||||
cost = (CONSTANTS.ClassLeadershipBaseCost * player.workCostMult) / gameCPS;
|
||||
chaExp = ((CONSTANTS.ClassLeadershipBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymStrength:
|
||||
cost = (CONSTANTS.ClassGymBaseCost * player.workCostMult) / gameCPS;
|
||||
strExp = (player.workExpMult / gameCPS) * hashManager.getTrainingMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymDefense:
|
||||
cost = (CONSTANTS.ClassGymBaseCost * player.workCostMult) / gameCPS;
|
||||
defExp = (player.workExpMult / gameCPS) * hashManager.getTrainingMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymDexterity:
|
||||
cost = (CONSTANTS.ClassGymBaseCost * player.workCostMult) / gameCPS;
|
||||
dexExp = (player.workExpMult / gameCPS) * hashManager.getTrainingMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymAgility:
|
||||
cost = (CONSTANTS.ClassGymBaseCost * player.workCostMult) / gameCPS;
|
||||
agiExp = (player.workExpMult / gameCPS) * hashManager.getTrainingMult();
|
||||
break;
|
||||
default:
|
||||
throw new Error("ERR: Invalid/unrecognized class name");
|
||||
}
|
||||
return {
|
||||
workMoneyLossRate: cost,
|
||||
workHackExpGainRate: hackExp * player.hacking_exp_mult * BitNodeMultipliers.ClassGymExpGain,
|
||||
workStrExpGainRate: strExp * player.strength_exp_mult * BitNodeMultipliers.ClassGymExpGain,
|
||||
workDefExpGainRate: defExp * player.defense_exp_mult * BitNodeMultipliers.ClassGymExpGain,
|
||||
workDexExpGainRate: dexExp * player.dexterity_exp_mult * BitNodeMultipliers.ClassGymExpGain,
|
||||
workAgiExpGainRate: agiExp * player.agility_exp_mult * BitNodeMultipliers.ClassGymExpGain,
|
||||
workChaExpGainRate: chaExp * player.charisma_exp_mult * BitNodeMultipliers.ClassGymExpGain,
|
||||
};
|
||||
}
|
||||
@@ -3,11 +3,29 @@ import { PlayerObject } from "./PersonObjects/Player/PlayerObject";
|
||||
import { sanitizeExploits } from "./Exploits/Exploit";
|
||||
|
||||
import { Reviver } from "./utils/JSONReviver";
|
||||
import Decimal from "decimal.js";
|
||||
|
||||
export let Player = new PlayerObject();
|
||||
|
||||
export function loadPlayer(saveString: string): void {
|
||||
Player = JSON.parse(saveString, Reviver);
|
||||
|
||||
// Parse Decimal.js objects
|
||||
Player.money = new Decimal(Player.money);
|
||||
|
||||
if (Player.corporation instanceof Corporation) {
|
||||
Player.corporation.funds = new Decimal(Player.corporation.funds);
|
||||
Player.corporation.revenue = new Decimal(Player.corporation.revenue);
|
||||
Player.corporation.expenses = new Decimal(Player.corporation.expenses);
|
||||
|
||||
for (let i = 0; i < Player.corporation.divisions.length; ++i) {
|
||||
const ind = Player.corporation.divisions[i];
|
||||
ind.lastCycleRevenue = new Decimal(ind.lastCycleRevenue);
|
||||
ind.lastCycleExpenses = new Decimal(ind.lastCycleExpenses);
|
||||
ind.thisCycleRevenue = new Decimal(ind.thisCycleRevenue);
|
||||
ind.thisCycleExpenses = new Decimal(ind.thisCycleExpenses);
|
||||
}
|
||||
}
|
||||
|
||||
Player.exploits = sanitizeExploits(Player.exploits);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import { Terminal } from "./Terminal";
|
||||
|
||||
import { dialogBoxCreate } from "./ui/React/DialogBox";
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import { ProgramsSeen } from "./Programs/ui/ProgramsRoot";
|
||||
import { InvitationsSeen } from "./Faction/ui/FactionsRoot";
|
||||
|
||||
@@ -119,7 +120,7 @@ export function prestigeAugmentation(): void {
|
||||
|
||||
// BitNode 8: Ghost of Wall Street
|
||||
if (Player.bitNodeN === 8) {
|
||||
Player.money = BitNode8StartingMoney;
|
||||
Player.money = new Decimal(BitNode8StartingMoney);
|
||||
}
|
||||
if (Player.bitNodeN === 8 || SourceFileFlags[8] > 0) {
|
||||
Player.hasWseAccount = true;
|
||||
@@ -234,7 +235,7 @@ export function prestigeSourceFile(flume: boolean): void {
|
||||
|
||||
// BitNode 8: Ghost of Wall Street
|
||||
if (Player.bitNodeN === 8) {
|
||||
Player.money = BitNode8StartingMoney;
|
||||
Player.money = new Decimal(BitNode8StartingMoney);
|
||||
}
|
||||
if (Player.bitNodeN === 8 || SourceFileFlags[8] > 0) {
|
||||
Player.hasWseAccount = true;
|
||||
|
||||
@@ -306,10 +306,10 @@ export const programsMetadata: IProgramCreationParams[] = [
|
||||
create: null,
|
||||
run: (router: IRouter, terminal: ITerminal, player: IPlayer): void => {
|
||||
const numAugReq = Math.round(BitNodeMultipliers.DaedalusAugsRequirement * 30);
|
||||
const fulfilled = player.augmentations.length >= numAugReq && player.money > 1e11 && player.hacking >= 2500;
|
||||
const fulfilled = player.augmentations.length >= numAugReq && player.money.gt(1e11) && player.hacking >= 2500;
|
||||
if (!fulfilled) {
|
||||
terminal.print(`Augmentations: ${player.augmentations.length} / ${numAugReq}`);
|
||||
terminal.print(`Money: ${numeralWrapper.formatMoney(player.money)} / $100b`);
|
||||
terminal.print(`Money: ${numeralWrapper.formatMoney(player.money.toNumber())} / $100b`);
|
||||
terminal.print(`Hacking skill: ${player.hacking} / 2500`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -282,5 +282,6 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
|
||||
Object.assign(Settings.theme, save.theme);
|
||||
delete save.theme;
|
||||
Object.assign(Settings, save);
|
||||
console.log(Settings.TimestampsFormat);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -173,7 +173,7 @@ export function StockTicker(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
function handleBuyMaxButtonClick(): void {
|
||||
const playerMoney: number = props.p.money;
|
||||
const playerMoney: number = props.p.money.toNumber();
|
||||
|
||||
const stock = props.stock;
|
||||
let maxShares = calculateBuyMaxAmount(stock, position, playerMoney);
|
||||
|
||||
1
src/ThirdParty/decimal.js.d.ts
vendored
Normal file
1
src/ThirdParty/decimal.js.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare module "decimal.js";
|
||||
@@ -251,22 +251,6 @@ const Engine: {
|
||||
const timeOffline = Engine._lastUpdate - lastUpdate;
|
||||
const numCyclesOffline = Math.floor(timeOffline / CONSTANTS._idleSpeed);
|
||||
|
||||
// Generate coding contracts
|
||||
let numContracts = 0;
|
||||
if (numCyclesOffline < 3000 * 100) {
|
||||
// if we have less than 100 rolls, just roll them exactly.
|
||||
for (let i = 0; i < numCyclesOffline / 3000; i++) {
|
||||
if (Math.random() < 0.25) numContracts++;
|
||||
}
|
||||
} else {
|
||||
// just average it.
|
||||
numContracts = (numCyclesOffline / 3000) * 0.25;
|
||||
}
|
||||
console.log(`${numCyclesOffline} ${numContracts}`);
|
||||
for (let i = 0; i < numContracts; i++) {
|
||||
generateRandomContract();
|
||||
}
|
||||
|
||||
let offlineReputation = 0;
|
||||
const offlineHackingIncome = (Player.moneySourceA.hacking / Player.playtimeSinceLastAug) * timeOffline * 0.75;
|
||||
Player.gainMoney(offlineHackingIncome, "hacking");
|
||||
|
||||
@@ -290,7 +290,7 @@ export function CharacterStats(): React.ReactElement {
|
||||
<Employers />
|
||||
|
||||
<Typography>
|
||||
Money: <Money money={player.money} />
|
||||
Money: <Money money={player.money.toNumber()} />
|
||||
<IconButton onClick={() => setMoneyOpen(true)}>
|
||||
<MoreHorizIcon color="info" />
|
||||
</IconButton>
|
||||
|
||||
@@ -176,7 +176,9 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle
|
||||
<Typography classes={{ root: classes.money }}>Money </Typography>
|
||||
</TableCell>
|
||||
<TableCell align="right" classes={{ root: classes.cellNone }}>
|
||||
<Typography classes={{ root: classes.money }}>{numeralWrapper.formatMoney(player.money)}</Typography>
|
||||
<Typography classes={{ root: classes.money }}>
|
||||
{numeralWrapper.formatMoney(player.money.toNumber())}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="right" classes={{ root: classes.cellNone }}>
|
||||
<Typography id="overview-money-hook" classes={{ root: classes.money }}>
|
||||
|
||||
@@ -480,13 +480,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
|
||||
<TextField
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<Typography
|
||||
color={
|
||||
formatTime(timestampFormat) === "format error" && timestampFormat !== ""
|
||||
? "error"
|
||||
: "success"
|
||||
}
|
||||
>
|
||||
<Typography color={formatTime(timestampFormat) === "format error" ? "error" : "success"}>
|
||||
Timestamp format:
|
||||
</Typography>
|
||||
),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { format } from "date-fns";
|
||||
|
||||
export function formatTime(fmt: string): string {
|
||||
if (fmt === "") return "format error";
|
||||
try {
|
||||
return format(new Date(), fmt);
|
||||
} catch (err: any) {
|
||||
|
||||
Reference in New Issue
Block a user