fix decimal

This commit is contained in:
Olivier Gagnon 2021-11-11 21:35:26 -05:00
commit 0114c92829
65 changed files with 340 additions and 309 deletions

46
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

@ -10,7 +10,7 @@ getPlayer() Netscript Function
Returns an object with the Player's stats. The object has the following properties::
{
hacking_skill: Current Hacking skill level
hacking: Current Hacking skill level
hp: Current health points
max_hp: Maximum health points
strength: Current Strength skill level

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

22
package-lock.json generated

@ -1,11 +1,11 @@
{
"name": "bitburner",
"version": "0.58.0",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "0.58.0",
"version": "1.0.0",
"hasInstallScript": true,
"license": "SEE LICENSE IN license.txt",
"dependencies": {
@ -28,6 +28,7 @@
"arg": "^5.0.0",
"better-react-mathjax": "^1.0.3",
"clsx": "^1.1.1",
"date-fns": "^2.25.0",
"decimal.js": "7.2.3",
"escodegen": "^1.11.0",
"file-saver": "^1.3.8",
@ -6963,6 +6964,18 @@
"whatwg-url": "^7.0.0"
}
},
"node_modules/date-fns": {
"version": "2.25.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz",
"integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w==",
"engines": {
"node": ">=0.11"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/date-fns"
}
},
"node_modules/date-now": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
@ -26992,6 +27005,11 @@
"whatwg-url": "^7.0.0"
}
},
"date-fns": {
"version": "2.25.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz",
"integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w=="
},
"date-now": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",

@ -29,7 +29,7 @@
"arg": "^5.0.0",
"better-react-mathjax": "^1.0.3",
"clsx": "^1.1.1",
"decimal.js": "7.2.3",
"date-fns": "^2.25.0",
"escodegen": "^1.11.0",
"file-saver": "^1.3.8",
"jquery": "^3.5.0",

@ -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.lt(cost)) {
if (corporation.funds < 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.minus(cost);
corporation.funds = corporation.funds - 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.lt(CorporationConstants.OfficeInitialCost)) {
if (corporation.funds < CorporationConstants.OfficeInitialCost) {
throw new Error("You don't have enough company funds to open a new office!");
} else {
corporation.funds = corporation.funds.minus(CorporationConstants.OfficeInitialCost);
corporation.funds = corporation.funds - 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.lt(upgrade[1])) {
if (corporation.funds < 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.lt(cost)) {
if (corporation.funds < 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.lt(cost)) return;
if (corp.funds < cost) return;
office.size += size;
corp.funds = corp.funds.minus(cost);
corp.funds = corp.funds - cost;
}
export function ThrowParty(corp: ICorporation, office: OfficeSpace, costPerEmployee: number): number {
const totalCost = costPerEmployee * office.employees.length;
if (corp.funds.lt(totalCost)) return 0;
corp.funds = corp.funds.minus(totalCost);
if (corp.funds < totalCost) return 0;
corp.funds = corp.funds - 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.lt(CorporationConstants.WarehouseInitialCost)) return;
if (corp.funds < 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.minus(CorporationConstants.WarehouseInitialCost);
corp.funds = corp.funds - 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.minus(sizeUpgradeCost);
corp.funds = corp.funds - 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.lt(cost)) return;
corp.funds = corp.funds.minus(cost);
if (corp.funds < cost) return;
corp.funds = corp.funds - 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.lt(cost)) return;
corp.funds = corp.funds.minus(cost);
if (corp.funds < cost) return;
corp.funds = corp.funds - 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.lt(designInvest + marketingInvest)) {
if (corp.funds < 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.minus(designInvest + marketingInvest);
corp.funds = corp.funds - (designInvest + marketingInvest);
division.products[product.name] = product;
}

@ -14,10 +14,6 @@ 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;
}
@ -29,9 +25,9 @@ export class Corporation {
divisions: Industry[] = [];
//Financial stats
funds = new Decimal(150e9);
revenue = new Decimal(0);
expenses = new Decimal(0);
funds = 150e9;
revenue = 0;
expenses = 0;
fundingRound = 0;
public = false; //Publicly traded
totalShares = CorporationConstants.INITIALSHARES; // Total existing shares
@ -65,7 +61,7 @@ export class Corporation {
console.error("Trying to add invalid amount of funds. Report to a developper.");
return;
}
this.funds = this.funds.plus(amt);
this.funds = this.funds + amt;
}
getState(): string {
@ -97,8 +93,8 @@ export class Corporation {
//At the start of a new cycle, calculate profits from previous cycle
if (state === "START") {
this.revenue = new Decimal(0);
this.expenses = new Decimal(0);
this.revenue = 0;
this.expenses = 0;
this.divisions.forEach((ind) => {
if (ind.lastCycleRevenue === -Infinity || ind.lastCycleRevenue === Infinity) {
return;
@ -106,18 +102,18 @@ export class Corporation {
if (ind.lastCycleExpenses === -Infinity || ind.lastCycleExpenses === Infinity) {
return;
}
this.revenue = this.revenue.plus(ind.lastCycleRevenue);
this.expenses = this.expenses.plus(ind.lastCycleExpenses);
this.revenue = this.revenue + ind.lastCycleRevenue;
this.expenses = this.expenses + ind.lastCycleExpenses;
});
const profit = this.revenue.minus(this.expenses);
const cycleProfit = profit.times(marketCycles * CorporationConstants.SecsPerMarketCycle);
const profit = this.revenue - this.expenses;
const cycleProfit = profit * (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 = new Decimal(150e9);
this.funds = 150e9;
}
// Process dividends
@ -147,28 +143,36 @@ export class Corporation {
}
getDividends(): number {
const profit = this.revenue.minus(this.expenses);
const cycleProfit = profit.times(CorporationConstants.SecsPerMarketCycle);
const profit = this.revenue - this.expenses;
const cycleProfit = profit * CorporationConstants.SecsPerMarketCycle;
const totalDividends = (this.dividendPercentage / 100) * cycleProfit;
const dividendsPerShare = totalDividends / this.totalShares;
const dividends = this.numShares * dividendsPerShare * (1 - this.dividendTaxPercentage / 100);
return Math.pow(dividends, BitNodeMultipliers.CorporationSoftCap);
let upgrades = -0.15;
if (this.unlockUpgrades[5] === 1) {
upgrades += 0.05;
}
if (this.unlockUpgrades[6] === 1) {
upgrades += 0.1;
}
console.log(upgrades);
return Math.pow(dividends, BitNodeMultipliers.CorporationSoftCap + upgrades);
}
determineValuation(): number {
let val,
profit = this.revenue.minus(this.expenses).toNumber();
profit = this.revenue - this.expenses;
if (this.public) {
// Account for dividends
if (this.dividendPercentage > 0) {
profit *= (100 - this.dividendPercentage) / 100;
}
val = this.funds.toNumber() + profit * 85e3;
val = this.funds + profit * 85e3;
val *= Math.pow(1.1, this.divisions.length);
val = Math.max(val, 0);
} else {
val = 10e9 + Math.max(this.funds.toNumber(), 0) / 3; //Base valuation
val = 10e9 + Math.max(this.funds, 0) / 3; //Base valuation
if (profit > 0) {
val += profit * 315e3;
val *= Math.pow(1.1, this.divisions.length);
@ -262,12 +266,12 @@ export class Corporation {
while (this.unlockUpgrades.length <= upgN) {
this.unlockUpgrades.push(0);
}
if (this.funds.lt(price)) {
if (this.funds < price) {
dialogBoxCreate("You don't have enough funds to unlock this!");
return;
}
this.unlockUpgrades[upgN] = 1;
this.funds = this.funds.minus(price);
this.funds = this.funds - price;
// Apply effects for one-time upgrades
if (upgN === 5) {
@ -290,12 +294,12 @@ export class Corporation {
this.upgradeMultipliers.push(1);
}
const totalCost = basePrice * Math.pow(priceMult, this.upgrades[upgN]);
if (this.funds.lt(totalCost)) {
if (this.funds < totalCost) {
dialogBoxCreate("You don't have enough funds to purchase this!");
return;
}
++this.upgrades[upgN];
this.funds = this.funds.minus(totalCost);
this.funds = this.funds - totalCost;
//Increase upgrade multiplier
this.upgradeMultipliers[upgN] = 1 + this.upgrades[upgN] * upgradeAmt;

@ -9,9 +9,9 @@ export interface ICorporation {
divisions: Industry[];
funds: any;
revenue: any;
expenses: any;
funds: number;
revenue: number;
expenses: number;
fundingRound: number;
public: boolean;
totalShares: number;

@ -31,10 +31,10 @@ export interface IIndustry {
prodMult: number;
// Decimal
lastCycleRevenue: any;
lastCycleExpenses: any;
thisCycleRevenue: any;
thisCycleExpenses: any;
lastCycleRevenue: number;
lastCycleExpenses: number;
thisCycleRevenue: number;
thisCycleExpenses: number;
upgrades: number[];

@ -1,6 +1,5 @@
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";
@ -55,10 +54,10 @@ export class Industry implements IIndustry {
prodMult = 0; //Production multiplier
//Financials
lastCycleRevenue: any;
lastCycleExpenses: any;
thisCycleRevenue: any;
thisCycleExpenses: any;
lastCycleRevenue: number;
lastCycleExpenses: number;
thisCycleRevenue: number;
thisCycleExpenses: number;
//Upgrades
upgrades: number[] = Array(Object.keys(IndustryUpgrades).length).fill(0);
@ -87,10 +86,10 @@ export class Industry implements IIndustry {
this.type = params.type ? params.type : Industries.Agriculture;
//Financials
this.lastCycleRevenue = new Decimal(0);
this.lastCycleExpenses = new Decimal(0);
this.thisCycleRevenue = new Decimal(0);
this.thisCycleExpenses = new Decimal(0);
this.lastCycleRevenue = 0;
this.lastCycleExpenses = 0;
this.thisCycleRevenue = 0;
this.thisCycleExpenses = 0;
this.warehouses = {
[CityName.Aevum]: 0,
@ -399,17 +398,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 = new Decimal(0);
this.thisCycleExpenses = new Decimal(0);
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);
this.lastCycleRevenue = this.thisCycleRevenue / (marketCycles * CorporationConstants.SecsPerMarketCycle);
this.lastCycleExpenses = this.thisCycleExpenses / (marketCycles * CorporationConstants.SecsPerMarketCycle);
this.thisCycleRevenue = 0;
this.thisCycleExpenses = 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.gt(0)) {
if (this.lastCycleRevenue > 0) {
this.newInd = false;
}
@ -422,7 +421,7 @@ export class Industry implements IIndustry {
employeeSalary += office.process(marketCycles, corporation, this);
}
}
this.thisCycleExpenses = this.thisCycleExpenses.plus(employeeSalary);
this.thisCycleExpenses = this.thisCycleExpenses + employeeSalary;
// Process change in demand/competition of materials/products
this.processMaterialMarket();
@ -446,15 +445,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.plus(res[0]);
this.thisCycleExpenses = this.thisCycleExpenses.plus(res[1]);
this.thisCycleRevenue = this.thisCycleRevenue + res[0];
this.thisCycleExpenses = this.thisCycleExpenses + res[1];
}
// Process creation, production & sale of products
res = this.processProducts(marketCycles, corporation);
if (Array.isArray(res)) {
this.thisCycleRevenue = this.thisCycleRevenue.plus(res[0]);
this.thisCycleExpenses = this.thisCycleExpenses.plus(res[1]);
this.thisCycleRevenue = this.thisCycleRevenue + res[0];
this.thisCycleExpenses = this.thisCycleExpenses + res[1];
}
}
@ -1476,10 +1475,10 @@ export class Industry implements IIndustry {
division.prodMult = this.prodMult;
division.state = this.state;
division.newInd = this.newInd;
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.lastCycleRevenue = this.lastCycleRevenue + 0;
division.lastCycleExpenses = this.lastCycleExpenses + 0;
division.thisCycleRevenue = this.thisCycleRevenue + 0;
division.thisCycleExpenses = this.thisCycleExpenses + 0;
division.upgrades = this.upgrades.slice();
division.prodMats = this.prodMats.slice();
return division;

@ -53,14 +53,14 @@ export const CorporationUnlockUpgrades: IMap<CorporationUnlockUpgrade> = {
],
"5": [
5,
500e9,
500e12,
"Shady Accounting",
"Utilize unscrupulous accounting practices and pay off government officials to save money " +
"on taxes. This reduces the dividend tax rate by 5%.",
],
"6": [
6,
2e12,
2e15,
"Government Partnership",
"Help national governments further their agendas in exchange for lowered taxes. " +
"This reduces the dividend tax rate by 10%",

@ -38,7 +38,7 @@ export function BribeFactionModal(props: IProps): React.ReactElement {
isNaN(stock) ||
money < 0 ||
stock < 0 ||
corp.funds.lt(money) ||
corp.funds < 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.lt(money)) {
} else if (corp.funds < 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.minus(money);
corp.funds = corp.funds - 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.lt(cost) || name === "";
const disabled = corp.funds < 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.lt(CorporationConstants.OfficeInitialCost);
const disabled = corp.funds < 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.lt(0)} onClick={() => setUpgradeOfficeSizeOpen(true)}>
<Button disabled={corp.funds < 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.lt(0)} onClick={() => setThrowPartyOpen(true)}>
<Button disabled={corp.funds < 0} onClick={() => setThrowPartyOpen(true)}>
Throw Party
</Button>
</span>

@ -79,11 +79,7 @@ function MakeProductButton(): React.ReactElement {
)
}
>
<Button
color={shouldFlash() ? "error" : "primary"}
onClick={() => setMakeOpen(true)}
disabled={corp.funds.lt(0)}
>
<Button color={shouldFlash() ? "error" : "primary"} onClick={() => setMakeOpen(true)} disabled={corp.funds < 0}>
{createProductButtonText}
</Button>
</Tooltip>
@ -97,7 +93,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.minus(division.lastCycleExpenses).toNumber();
const profit = division.lastCycleRevenue - division.lastCycleExpenses;
let advertisingInfo = false;
const advertisingFactors = division.getAdvertisingFactors();
@ -119,7 +115,7 @@ function Text(): React.ReactElement {
return (
<>
<Typography>
Industry: {division.type} (Corp Funds: <Money money={corp.funds.toNumber()} />)
Industry: {division.type} (Corp Funds: <Money money={corp.funds} />)
</Typography>
<br />
<StatsTable
@ -149,8 +145,8 @@ function Text(): React.ReactElement {
<br />
<StatsTable
rows={[
["Revenue:", <MoneyRate money={division.lastCycleRevenue.toNumber()} />],
["Expenses:", <MoneyRate money={division.lastCycleExpenses.toNumber()} />],
["Revenue:", <MoneyRate money={division.lastCycleRevenue} />],
["Expenses:", <MoneyRate money={division.lastCycleExpenses} />],
["Profit:", <MoneyRate money={profit} />],
]}
/>
@ -241,8 +237,8 @@ function Upgrades(props: { office: OfficeSpace; rerender: () => void }): React.R
}
function onClick(): void {
if (corp.funds.lt(cost)) return;
corp.funds = corp.funds.minus(cost);
if (corp.funds < cost) return;
corp.funds = corp.funds - cost;
division.upgrade(upgrade, {
corporation: corp,
office: props.office,
@ -253,7 +249,7 @@ function Upgrades(props: { office: OfficeSpace; rerender: () => void }): React.R
upgrades.push(
<Tooltip key={index} title={upgrade[5]}>
<span>
<Button disabled={corp.funds.lt(cost)} onClick={onClick}>
<Button disabled={corp.funds < cost} onClick={onClick}>
{upgrade[4]} -&nbsp;
<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.gt(sizeUpgradeCost);
const canAffordUpgrade = corp.funds > 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.minus(sizeUpgradeCost);
corp.funds = corp.funds - 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.lt(CorporationConstants.WarehouseInitialCost);
const disabled = corp.funds < 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.plus(profit);
corp.funds = corp.funds + 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.lt(cost)) return;
if (corp.funds < cost) return;
try {
LevelUpgrade(corp, props.upgrade);
} catch (err) {
@ -40,11 +40,13 @@ export function LevelableUpgrade(props: IProps): React.ReactElement {
return (
<Grid item xs={4}>
<Box display="flex" alignItems="center" flexDirection="row-reverse">
<Button disabled={corp.funds.lt(cost)} sx={{ mx: 1 }} onClick={onClick}>
<Button disabled={corp.funds < 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.gt(props.money))
if (!(props.corp.funds > 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.minus(corp.expenses).toNumber();
const profit: number = corp.revenue - corp.expenses;
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.toNumber()} />],
["Total Revenue:", <MoneyRate money={corp.revenue.toNumber()} />],
["Total Expenses:", <MoneyRate money={corp.expenses.toNumber()} />],
["Total Funds:", <Money money={corp.funds} />],
["Total Revenue:", <MoneyRate money={corp.revenue} />],
["Total Expenses:", <MoneyRate money={corp.expenses} />],
["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,15 +25,25 @@ 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>
</>
);
}
}
@ -62,8 +72,8 @@ function BulkPurchase(props: IBPProps): React.ReactElement {
dialogBoxCreate("Invalid input amount");
} else {
const cost = amount * props.mat.bCost;
if (corp.funds.gt(cost)) {
corp.funds = corp.funds.minus(cost);
if (corp.funds >= cost) {
corp.funds = corp.funds - 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.gte(totalCost);
const canParty = corp.funds >= 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.lt(data[1])) return;
if (corp.funds < 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.lt(data[1])} sx={{ mx: 1 }} onClick={onClick}>
<Button disabled={corp.funds < 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.lt(cost)) {
if (corp.funds < cost) {
return;
}
@ -34,7 +34,7 @@ function UpgradeSizeButton(props: IUpgradeButton): React.ReactElement {
return (
<Tooltip title={numeralWrapper.formatMoney(props.cost)}>
<span>
<Button disabled={corp.funds.lt(props.cost)} onClick={() => upgradeSize(props.cost, props.size)}>
<Button disabled={corp.funds < 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.dividedBy(CorporationConstants.OfficeInitialCost).toNumber();
const maxMult = corp.funds / CorporationConstants.OfficeInitialCost;
let maxNum = 1;
mult = Math.pow(costMultiplier, initialPriceMult);
while (maxNum < 50) {

@ -54,7 +54,7 @@ export function buyDarkwebItem(itemName: string): void {
}
// return if the player doesn't have enough money
if (Player.money.lt(item.price)) {
if (Player.money < item.price) {
Terminal.error("Not enough money to purchase " + item.program);
return;
}

@ -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.plus(1e99);
props.player.corporation.funds = props.player.corporation.funds + 1e99;
}
}
function resetCorporationFunds(): void {
if (props.player.corporation) {
props.player.corporation.funds = props.player.corporation.funds.minus(props.player.corporation.funds);
props.player.corporation.funds = props.player.corporation.funds - props.player.corporation.funds;
}
}

@ -87,7 +87,7 @@ export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = fal
} else {
dialogBoxCreate(txt);
}
} else if (aug.baseCost !== 0 && Player.money.lt(aug.baseCost * factionInfo.augmentationPriceMult)) {
} else if (aug.baseCost !== 0 && Player.money < aug.baseCost * factionInfo.augmentationPriceMult) {
const txt = "You don't have enough money to purchase " + aug.name;
if (sing) {
return txt;
@ -99,7 +99,7 @@ export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = fal
return txt;
}
dialogBoxCreate(txt);
} else if (aug.baseCost === 0 || Player.money.gte(aug.baseCost * factionInfo.augmentationPriceMult)) {
} else if (aug.baseCost === 0 || Player.money >= aug.baseCost * factionInfo.augmentationPriceMult) {
const queuedAugmentation = new PlayerOwnedAugmentation(aug.name);
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
queuedAugmentation.level = getNextNeurofluxLevel();

@ -93,8 +93,7 @@ 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.gt(aug.baseCost * props.faction.getInfo().augmentationPriceMult);
const hasCost = aug.baseCost !== 0 && player.money > 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.lt(donateAmt)) return false;
if (props.p.money < 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.lt(donateAmt)) return <Typography>Insufficient funds</Typography>;
if (props.p.money < 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.gt(aug.baseCost * props.faction.getInfo().augmentationPriceMult);
const hasCost = aug.baseCost === 0 || props.p.money > 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.lt(gang.getUpgradeCost(upg))) return false;
if (player.money < 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.gt(gang.getUpgradeCost(upg))) return false;
if (player.money > 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.lt(gang.getUpgradeCost(upg))) return false;
if (player.money < 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.lt(nodeObj.calculateLevelUpgradeCost(1, player.hacknet_node_level_cost_mult))) {
if (player.money < 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.gt(nodeObj.calculateLevelUpgradeCost(levelsToMax, player.hacknet_node_level_cost_mult))) {
if (player.money > 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.gt(nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult)) &&
player.money.lt(nodeObj.calculateLevelUpgradeCost(curr + 1, player.hacknet_node_level_cost_mult))
player.money > nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult) &&
player.money < nodeObj.calculateLevelUpgradeCost(curr + 1, player.hacknet_node_level_cost_mult)
) {
return Math.min(levelsToMax, curr);
} else if (player.money.lt(nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult))) {
} else if (player.money < nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult)) {
max = curr - 1;
} else if (player.money.gt(nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult))) {
} else if (player.money > 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.lt(nodeObj.calculateRamUpgradeCost(1, player.hacknet_node_ram_cost_mult))) {
if (player.money < 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.gt(nodeObj.calculateRamUpgradeCost(levelsToMax, player.hacknet_node_ram_cost_mult))) {
if (player.money > 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.gt(nodeObj.calculateRamUpgradeCost(i, player.hacknet_node_ram_cost_mult))) {
if (player.money > 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.lt(nodeObj.calculateCoreUpgradeCost(1, player.hacknet_node_core_cost_mult))) {
if (player.money < 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.gt(nodeObj.calculateCoreUpgradeCost(levelsToMax, player.hacknet_node_core_cost_mult))) {
if (player.money > 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.gt(nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult)) &&
player.money.lt(nodeObj.calculateCoreUpgradeCost(curr + 1, player.hacknet_node_core_cost_mult))
player.money > nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult) &&
player.money < nodeObj.calculateCoreUpgradeCost(curr + 1, player.hacknet_node_core_cost_mult)
) {
return Math.min(levelsToMax, curr);
} else if (player.money.lt(nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult))) {
} else if (player.money < nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult)) {
max = curr - 1;
} else if (player.money.gt(nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult))) {
} else if (player.money > 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.plus(upg.value);
corp.funds = corp.funds + upg.value;
break;
}
case "Reduce Minimum Security": {

@ -20,8 +20,6 @@ import { createRandomIp } from "../utils/IPAddress";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
interface IConstructorParams {
adminRights?: boolean;
hostname: string;
@ -37,7 +35,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
// Number of cores. Improves hash production
cores = 1;
// Number of hashes that can be stored by this Hacknet Server
hashCapacity = 0;
@ -53,6 +51,9 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
// Total number of hashes earned by this server
totalHashesGenerated = 0;
// Flag indicating wehther this is a purchased server
purchasedByPlayer = true;
constructor(params: IConstructorParams = { hostname: "", ip: createRandomIp() }) {
super(params);
@ -95,7 +96,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
upgradeCore(levels: number, prodMult: number): void {
this.cores = Math.min(HacknetServerConstants.MaxCores, Math.round(this.cores + levels));
this.updateHashRate(prodMult);
this.cpuCores=this.cores;
this.cpuCores = this.cores;
}
upgradeLevel(levels: number, prodMult: number): void {

@ -155,7 +155,7 @@ export function HacknetServerElem(props: IProps): React.ReactElement {
<Money money={upgradeCacheCost} player={props.player} />
</>
);
if (props.player.money.lt(upgradeCacheCost)) {
if (props.player.money < upgradeCacheCost) {
} else {
}
}

@ -33,7 +33,7 @@ export function PlayerInfo(props: IProps): React.ReactElement {
<>
<Typography>
Money:
<Money money={props.player.money.toNumber()} />
<Money money={props.player.money} />
</Typography>
{hasServers && (

@ -2,18 +2,11 @@ import { CONSTANTS } from "../Constants";
import { IPlayer } from "../PersonObjects/IPlayer";
export function getHospitalizationCost(p: IPlayer): number {
let money;
if (typeof p.money === "number") {
money = p.money;
} else {
money = p.money.toNumber();
}
if (money < 0) {
if (p.money < 0) {
return 0;
}
return Math.min(money * 0.1, (p.max_hp - p.hp) * CONSTANTS.HospitalCostPerHp);
return Math.min(p.money * 0.1, (p.max_hp - p.hp) * CONSTANTS.HospitalCostPerHp);
}
export function calculateHospitalizationCost(p: IPlayer, damage: number): number {

@ -1294,9 +1294,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
// Return player's money
workerScript.log(
"getServerMoneyAvailable",
`returned player's money: ${numeralWrapper.formatMoney(Player.money.toNumber())}`,
`returned player's money: ${numeralWrapper.formatMoney(Player.money)}`,
);
return Player.money.toNumber();
return Player.money;
}
workerScript.log(
"getServerMoneyAvailable",
@ -1522,7 +1522,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
return "";
}
if (Player.money.lt(cost)) {
if (Player.money < cost) {
workerScript.log(
"purchaseServer",
`Not enough money to purchase server. Need ${numeralWrapper.formatMoney(cost)}`,
@ -2126,7 +2126,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
company_rep_mult: Player.company_rep_mult,
faction_rep_mult: Player.faction_rep_mult,
numPeopleKilled: Player.numPeopleKilled,
money: Player.money.toNumber(),
money: Player.money,
city: Player.city,
location: Player.location,
companyName: Player.companyName,

@ -450,7 +450,7 @@ export function NetscriptSingularity(
case CityName.NewTokyo:
case CityName.Ishima:
case CityName.Volhaven:
if (player.money.lt(CONSTANTS.TravelCost)) {
if (player.money < 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.lt(CONSTANTS.TorRouterCost)) {
if (player.money < 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.lt(item.price)) {
if (player.money < 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.lt(cost)) {
if (player.money < 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.lt(cost)) {
if (player.money < 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.lt(amt)) {
if (player.money < 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.lt(getStockMarket4SDataCost())) {
if (player.money < 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.lt(getStockMarket4STixApiCost())) {
if (player.money < 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: any;
readonly money: number;
moneySourceA: MoneySourceTracker;
moneySourceB: MoneySourceTracker;
playtimeSinceLastAug: number;

@ -35,8 +35,6 @@ 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[];
@ -63,7 +61,7 @@ export class PlayerObject implements IPlayer {
numPeopleKilled: number;
location: LocationName;
max_hp: number;
money: any;
money: number;
moneySourceA: MoneySourceTracker;
moneySourceB: MoneySourceTracker;
playtimeSinceLastAug: number;
@ -336,7 +334,7 @@ export class PlayerObject implements IPlayer {
this.faction_rep_mult = 1;
//Money
this.money = new Decimal(1000);
this.money = 1000;
//Location information
this.city = CityName.Sector12;

@ -36,7 +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";
@ -47,8 +47,6 @@ 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";
@ -102,7 +100,7 @@ export function prestigeAugmentation(this: PlayerObject): void {
this.agility_exp = 0;
this.charisma_exp = 0;
this.money = new Decimal(1000);
this.money = 1000;
this.city = CityName.Sector12;
this.location = LocationName.TravelAgency;
@ -325,7 +323,7 @@ export function setMoney(this: PlayerObject, money: number): void {
console.error("NaN passed into Player.setMoney()");
return;
}
this.money = new Decimal(money);
this.money = money;
}
export function gainMoney(this: PlayerObject, money: number, source: string): void {
@ -333,7 +331,8 @@ export function gainMoney(this: PlayerObject, money: number, source: string): vo
console.error("NaN passed into Player.gainMoney()");
return;
}
this.money = this.money.plus(money);
this.money = this.money + money;
this.recordMoneySource(money, source);
}
@ -342,8 +341,8 @@ export function loseMoney(this: PlayerObject, money: number, source: string): vo
console.error("NaN passed into Player.loseMoney()");
return;
}
if (this.money.eq(Infinity) && money === Infinity) return;
this.money = this.money.minus(money);
if (this.money === Infinity && money === Infinity) return;
this.money = this.money - money;
this.recordMoneySource(-1 * money, source);
}
@ -352,7 +351,7 @@ export function canAfford(this: IPlayer, cost: number): boolean {
console.error(`NaN passed into Player.canAfford()`);
return false;
}
return this.money.gte(cost);
return this.money >= cost;
}
export function recordMoneySource(this: PlayerObject, amt: number, source: string): void {
@ -535,7 +534,6 @@ export function processWorkEarnings(this: IPlayer, numCycles = 1): void {
const agiExpGain = focusBonus * this.workAgiExpGainRate * numCycles;
const chaExpGain = focusBonus * this.workChaExpGainRate * numCycles;
const moneyGain = (this.workMoneyGainRate - this.workMoneyLossRate) * numCycles;
this.gainHackingExp(hackExpGain);
this.gainStrengthExp(strExpGain);
this.gainDefenseExp(defExpGain);
@ -2070,7 +2068,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
!illuminatiFac.isMember &&
!illuminatiFac.alreadyInvited &&
numAugmentations >= 30 &&
this.money.gte(150000000000) &&
this.money >= 150000000000 &&
this.hacking >= 1500 &&
this.strength >= 1200 &&
this.defense >= 1200 &&
@ -2087,7 +2085,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
!daedalusFac.isMember &&
!daedalusFac.alreadyInvited &&
numAugmentations >= Math.round(30 * BitNodeMultipliers.DaedalusAugsRequirement) &&
this.money.gte(100000000000) &&
this.money >= 100000000000 &&
(this.hacking >= 2500 ||
(this.strength >= 1500 && this.defense >= 1500 && this.dexterity >= 1500 && this.agility >= 1500))
) {
@ -2101,7 +2099,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
!covenantFac.isMember &&
!covenantFac.alreadyInvited &&
numAugmentations >= 20 &&
this.money.gte(75000000000) &&
this.money >= 75000000000 &&
this.hacking >= 850 &&
this.strength >= 850 &&
this.defense >= 850 &&
@ -2280,7 +2278,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
!chongqingFac.isBanned &&
!chongqingFac.isMember &&
!chongqingFac.alreadyInvited &&
this.money.gte(20000000) &&
this.money >= 20000000 &&
this.city == CityName.Chongqing
) {
invitedFactions.push(chongqingFac);
@ -2292,7 +2290,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
!sector12Fac.isBanned &&
!sector12Fac.isMember &&
!sector12Fac.alreadyInvited &&
this.money.gte(15000000) &&
this.money >= 15000000 &&
this.city == CityName.Sector12
) {
invitedFactions.push(sector12Fac);
@ -2304,7 +2302,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
!newtokyoFac.isBanned &&
!newtokyoFac.isMember &&
!newtokyoFac.alreadyInvited &&
this.money.gte(20000000) &&
this.money >= 20000000 &&
this.city == CityName.NewTokyo
) {
invitedFactions.push(newtokyoFac);
@ -2316,7 +2314,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
!aevumFac.isBanned &&
!aevumFac.isMember &&
!aevumFac.alreadyInvited &&
this.money.gte(40000000) &&
this.money >= 40000000 &&
this.city == CityName.Aevum
) {
invitedFactions.push(aevumFac);
@ -2328,7 +2326,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
!ishimaFac.isBanned &&
!ishimaFac.isMember &&
!ishimaFac.alreadyInvited &&
this.money.gte(30000000) &&
this.money >= 30000000 &&
this.city == CityName.Ishima
) {
invitedFactions.push(ishimaFac);
@ -2340,7 +2338,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
!volhavenFac.isBanned &&
!volhavenFac.isMember &&
!volhavenFac.alreadyInvited &&
this.money.gte(50000000) &&
this.money >= 50000000 &&
this.city == CityName.Volhaven
) {
invitedFactions.push(volhavenFac);
@ -2397,7 +2395,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
this.dexterity >= 200 &&
this.agility >= 200 &&
(this.city == CityName.Aevum || this.city == CityName.Sector12) &&
this.money.gte(10000000) &&
this.money >= 10000000 &&
this.karma <= -90 &&
!allCompanies.includes(LocationName.Sector12CIA) &&
!allCompanies.includes(LocationName.Sector12NSA)
@ -2414,7 +2412,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
(allPositions.includes("Chief Technology Officer") ||
allPositions.includes("Chief Financial Officer") ||
allPositions.includes("Chief Executive Officer")) &&
this.money.gte(15000000) &&
this.money >= 15000000 &&
this.karma <= -22
) {
invitedFactions.push(silhouetteFac);
@ -2447,7 +2445,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
this.dexterity >= 30 &&
this.agility >= 30 &&
this.karma <= -9 &&
this.money.gte(1000000)
this.money >= 1000000
) {
invitedFactions.push(slumsnakesFac);
}
@ -2490,7 +2488,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
!tiandihuiFac.isBanned &&
!tiandihuiFac.isMember &&
!tiandihuiFac.alreadyInvited &&
this.money.gte(1000000) &&
this.money >= 1000000 &&
this.hacking >= 50 &&
(this.city == CityName.Chongqing || this.city == CityName.NewTokyo || this.city == CityName.Ishima)
) {

@ -18,7 +18,7 @@ export function hasTorRouter(this: IPlayer): boolean {
export function getCurrentServer(this: IPlayer): BaseServer {
const server = GetServer(this.currentServer);
if (server === null) throw new Error("somehow connected to a server that does not exist.");
if (server === null) throw new Error(`somehow connected to a server that does not exist. ${this.currentServer}`);
return server;
}

@ -64,7 +64,7 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement {
return (
<TableRow key={aug.name}>
<TableCell>
<Button onClick={() => purchaseAugmentation(aug)} disabled={player.money.lt(aug.startingCost)}>
<Button onClick={() => purchaseAugmentation(aug)} disabled={player.money < 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.lt(CONSTANTS.TravelCost) ? <Typography>Insufficient funds</Typography> : ""}>
<Tooltip title={player.money < CONSTANTS.TravelCost ? <Typography>Insufficient funds</Typography> : ""}>
<span>
<Button onClick={() => setTravelOpen(true)} disabled={player.money.lt(CONSTANTS.TravelCost)}>
<Button onClick={() => setTravelOpen(true)} disabled={player.money < CONSTANTS.TravelCost}>
Travel
</Button>
</span>

@ -3,29 +3,11 @@ 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.money = parseFloat(Player.money as any);
Player.exploits = sanitizeExploits(Player.exploits);
}

@ -26,7 +26,6 @@ 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";
@ -120,7 +119,7 @@ export function prestigeAugmentation(): void {
// BitNode 8: Ghost of Wall Street
if (Player.bitNodeN === 8) {
Player.money = new Decimal(BitNode8StartingMoney);
Player.money = BitNode8StartingMoney;
}
if (Player.bitNodeN === 8 || SourceFileFlags[8] > 0) {
Player.hasWseAccount = true;
@ -235,7 +234,7 @@ export function prestigeSourceFile(flume: boolean): void {
// BitNode 8: Ghost of Wall Street
if (Player.bitNodeN === 8) {
Player.money = new Decimal(BitNode8StartingMoney);
Player.money = 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.gt(1e11) && player.hacking >= 2500;
const fulfilled = player.augmentations.length >= numAugReq && player.money > 1e11 && player.hacking >= 2500;
if (!fulfilled) {
terminal.print(`Augmentations: ${player.augmentations.length} / ${numAugReq}`);
terminal.print(`Money: ${numeralWrapper.formatMoney(player.money.toNumber())} / $100b`);
terminal.print(`Money: ${numeralWrapper.formatMoney(player.money)} / $100b`);
terminal.print(`Hacking skill: ${player.hacking} / 2500`);
return;
}

@ -354,8 +354,7 @@ export function Root(props: IProps): React.ReactElement {
.find((l: any) => l.id === "javascript")
.loader();
l.language.tokenizer.root.unshift(["ns", { token: "ns" }]);
for (const symbol of symbols)
l.language.tokenizer.root.unshift(["[^a-zA-Z0-9]" + symbol + "[^a-zA-Z0-9]", { token: "netscriptfunction" }]);
for (const symbol of symbols) l.language.tokenizer.root.unshift([symbol, { token: "netscriptfunction" }]);
const otherKeywords = ["let", "const", "var", "function"];
const otherKeyvars = ["true", "false", "null", "undefined"];
otherKeywords.forEach((k) => l.language.tokenizer.root.unshift([k, { token: "otherkeywords" }]));

@ -94,6 +94,9 @@ export class BaseServer {
// Text files on this server
textFiles: TextFile[] = [];
// Flag indicating wehther this is a purchased server
purchasedByPlayer = false;
constructor(params: IConstructorParams = { hostname: "", ip: createRandomIp() }) {
this.ip = params.ip ? params.ip : createRandomIp();

@ -48,9 +48,6 @@ export class Server extends BaseServer {
// How many ports are currently opened on the server
openPortCount = 0;
// Flag indicating wehther this is a purchased server
purchasedByPlayer = false;
// Hacking level required to hack this server
requiredHackingSkill = 1;

@ -166,7 +166,7 @@ export const defaultSettings: IDefaultSettings = {
DisableHotkeys: false,
DisableTextEffects: false,
EnableBashHotkeys: false,
TimestampsFormat: "YYYY-MM-DD HH:MM:SS",
TimestampsFormat: "",
Locale: "en",
MaxLogCapacity: 50,
MaxPortCapacity: 50,

@ -64,7 +64,7 @@ export function buyStock(
if (totalPrice == null) {
return false;
}
if (Player.money.lt(totalPrice)) {
if (Player.money < totalPrice) {
if (workerScript) {
workerScript.log(
"buyStock",
@ -241,7 +241,7 @@ export function shortStock(
if (totalPrice == null) {
return false;
}
if (Player.money.lt(totalPrice)) {
if (Player.money < totalPrice) {
if (workerScript) {
workerScript.log(
"shortStock",

@ -173,7 +173,7 @@ export function StockTicker(props: IProps): React.ReactElement {
}
function handleBuyMaxButtonClick(): void {
const playerMoney: number = props.p.money.toNumber();
const playerMoney: number = props.p.money;
const stock = props.stock;
let maxShares = calculateBuyMaxAmount(stock, position, playerMoney);

@ -27,7 +27,11 @@ export function download(
const file = new Blob([server.scripts[i].code], {
type: "text/plain",
});
zip.file(server.scripts[i].filename + ".js", file);
let name = server.scripts[i].filename;
if (name.startsWith("/")) {
name = name.slice(1);
}
zip.file(name + ".js", file);
}
}
if (fn === "*" || fn === "*.txt") {

@ -1 +0,0 @@
declare module "decimal.js";

@ -251,9 +251,25 @@ 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, "hacknet");
Player.gainMoney(offlineHackingIncome, "hacking");
// Process offline progress
loadAllRunningScripts(); // This also takes care of offline production for those scripts
if (Player.isWorking) {

@ -290,7 +290,7 @@ export function CharacterStats(): React.ReactElement {
<Employers />
<Typography>
Money: <Money money={player.money.toNumber()} />
Money: <Money money={player.money} />
<IconButton onClick={() => setMoneyOpen(true)}>
<MoreHorizIcon color="info" />
</IconButton>

@ -176,9 +176,7 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle
<Typography classes={{ root: classes.money }}>Money&nbsp;</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.money }}>
{numeralWrapper.formatMoney(player.money.toNumber())}
</Typography>
<Typography classes={{ root: classes.money }}>{numeralWrapper.formatMoney(player.money)}</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography id="overview-money-hook" classes={{ root: classes.money }}>

@ -19,6 +19,7 @@ import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem";
import Link from "@mui/material/Link";
import Tooltip from "@mui/material/Tooltip";
import TextField from "@mui/material/TextField";
import DownloadIcon from "@mui/icons-material/Download";
import UploadIcon from "@mui/icons-material/Upload";
@ -30,6 +31,7 @@ import { ThemeEditorModal } from "./ThemeEditorModal";
import { Settings } from "../../Settings/Settings";
import { save, deleteGame } from "../../db";
import { formatTime } from "../../utils/helpers/formatTime";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
@ -73,7 +75,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
const [disableASCIIArt, setDisableASCIIArt] = useState(Settings.DisableASCIIArt);
const [disableTextEffects, setDisableTextEffects] = useState(Settings.DisableTextEffects);
const [enableBashHotkeys, setEnableBashHotkeys] = useState(Settings.EnableBashHotkeys);
const [enableTimestamps, setEnableTimestamps] = useState(!!Settings.TimestampsFormat);
const [timestampFormat, setTimestampFormat] = useState(Settings.TimestampsFormat);
const [saveGameOnFileSave, setSaveGameOnFileSave] = useState(Settings.SaveGameOnFileSave);
const [locale, setLocale] = useState(Settings.Locale);
@ -154,9 +156,9 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
setEnableBashHotkeys(event.target.checked);
Settings.EnableBashHotkeys = event.target.checked;
}
function handleEnableTimestampsChange(event: React.ChangeEvent<HTMLInputElement>): void {
setEnableTimestamps(event.target.checked);
Settings.TimestampsFormat = event.target.checked ? "YYYY-MM-DD HH:MM:SS" : "";
function handleTimestampFormatChange(event: React.ChangeEvent<HTMLInputElement>): void {
setTimestampFormat(event.target.value);
Settings.TimestampsFormat = event.target.value;
}
function handleSaveGameOnFile(event: React.ChangeEvent<HTMLInputElement>): void {
setSaveGameOnFileSave(event.target.checked);
@ -466,21 +468,28 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
/>
</ListItem>
<ListItem>
<FormControlLabel
control={<Switch checked={enableTimestamps} onChange={handleEnableTimestampsChange} />}
label={
<Tooltip
title={
<Typography>
Terminal commands and log entries will be timestamped. The timestamp will have the format: M/D
h:m
</Typography>
}
>
<Typography>Enable timestamps</Typography>
</Tooltip>
<Tooltip
title={
<Typography>
Terminal commands and log entries will be timestamped. See
https://date-fns.org/docs/Getting-Started/
</Typography>
}
/>
>
<span>
<TextField
InputProps={{
startAdornment: (
<Typography color={formatTime(timestampFormat) === "format error" ? "error" : "success"}>
Timestamp&nbsp;format:&nbsp;
</Typography>
),
}}
value={timestampFormat}
onChange={handleTimestampFormatChange}
/>
</span>
</Tooltip>
</ListItem>
<ListItem>

@ -1,3 +1,10 @@
export function formatTime(format: string): string {
return "";
import { format } from "date-fns";
export function formatTime(fmt: string): string {
try {
return format(new Date(), fmt);
} catch (err: any) {
console.error(err);
return "format error";
}
}

@ -856,7 +856,7 @@ describe("Stock Market Tests", function () {
expect(buyStock(stock, shares, null, suppressDialogOpt)).equal(true);
expect(stock.playerShares).equal(shares);
expect(stock.playerAvgPx).greaterThan(0);
expect(Player.money.toNumber()).equal(0);
expect(Player.money).equal(0);
});
});
@ -888,7 +888,7 @@ describe("Stock Market Tests", function () {
expect(sellStock(stock, shares, null, suppressDialogOpt)).equal(true);
expect(stock.playerShares).equal(0);
expect(stock.playerAvgPx).equal(0);
expect(Player.money.toNumber()).equal(gain);
expect(Player.money).equal(gain);
});
it("should cap the number of sharse sold to however many the player owns", function () {
@ -902,7 +902,7 @@ describe("Stock Market Tests", function () {
expect(sellStock(stock, attemptedShares, null, suppressDialogOpt)).equal(true);
expect(stock.playerShares).equal(0);
expect(stock.playerAvgPx).equal(0);
expect(Player.money.toNumber()).equal(gain);
expect(Player.money).equal(gain);
});
it("should properly update stock properties for partial transactions", function () {
@ -916,7 +916,7 @@ describe("Stock Market Tests", function () {
expect(sellStock(stock, shares, null, suppressDialogOpt)).equal(true);
expect(stock.playerShares).equal(shares);
expect(stock.playerAvgPx).equal(origPrice);
expect(Player.money.toNumber()).equal(gain);
expect(Player.money).equal(gain);
});
});
@ -950,7 +950,7 @@ describe("Stock Market Tests", function () {
expect(shortStock(stock, shares, null, suppressDialogOpt)).equal(true);
expect(stock.playerShortShares).equal(shares);
expect(stock.playerAvgShortPx).greaterThan(0);
expect(Player.money.toNumber()).equal(0);
expect(Player.money).equal(0);
});
});
@ -982,7 +982,7 @@ describe("Stock Market Tests", function () {
expect(sellShort(stock, shares, null, suppressDialogOpt)).equal(true);
expect(stock.playerShortShares).equal(0);
expect(stock.playerAvgShortPx).equal(0);
expect(Player.money.toNumber()).equal(gain);
expect(Player.money).equal(gain);
});
it("should cap the number of sharse sold to however many the player owns", function () {
@ -996,7 +996,7 @@ describe("Stock Market Tests", function () {
expect(sellShort(stock, attemptedShares, null, suppressDialogOpt)).equal(true);
expect(stock.playerShortShares).equal(0);
expect(stock.playerAvgShortPx).equal(0);
expect(Player.money.toNumber()).equal(gain);
expect(Player.money).equal(gain);
});
it("should properly update stock properties for partial transactions", function () {
@ -1010,7 +1010,7 @@ describe("Stock Market Tests", function () {
expect(sellShort(stock, shares, null, suppressDialogOpt)).equal(true);
expect(stock.playerShortShares).equal(shares);
expect(stock.playerAvgShortPx).equal(origPrice);
expect(Player.money.toNumber()).equal(gain);
expect(Player.money).equal(gain);
});
});
});