Merge pull request #1581 from danielyxie/dev

Money tracked more precisely.
This commit is contained in:
hydroflame
2021-10-27 14:19:05 -04:00
committed by GitHub
38 changed files with 94 additions and 103 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1235,8 +1235,7 @@ export class Bladeburner implements IBladeburner {
let moneyGain = 0;
if (!isOperation) {
moneyGain = BladeburnerConstants.ContractBaseMoneyGain * rewardMultiplier * this.skillMultipliers.money;
player.gainMoney(moneyGain);
player.recordMoneySource(moneyGain, "bladeburner");
player.gainMoney(moneyGain, "bladeburner");
}
if (isOperation) {

View File

@ -76,7 +76,7 @@ export class Blackjack extends Game<Props, State> {
// Take money from player right away so that player's dont just "leave" to avoid the loss (I mean they could
// always reload without saving but w.e)
this.props.p.loseMoney(this.state.bet);
this.props.p.loseMoney(this.state.bet, "casino");
const playerHand = new Hand([this.deck.safeDrawCard(), this.deck.safeDrawCard()]);
const dealerHand = new Hand([this.deck.safeDrawCard(), this.deck.safeDrawCard()]);

View File

@ -5,8 +5,7 @@ import { dialogBoxCreate } from "../ui/React/DialogBox";
const gainLimit = 10e9;
export function win(p: IPlayer, n: number): void {
p.gainMoney(n);
p.recordMoneySource(n, "casino");
p.gainMoney(n, "casino");
}
export function reachedLimit(p: IPlayer): boolean {
@ -19,8 +18,7 @@ export function reachedLimit(p: IPlayer): boolean {
export class Game<T, U> extends React.Component<T, U> {
win(p: IPlayer, n: number): void {
p.gainMoney(n);
p.recordMoneySource(n, "casino");
p.gainMoney(n, "casino");
}
reachedLimit(p: IPlayer): boolean {

View File

@ -134,8 +134,7 @@ export class Corporation {
const retainedEarnings = cycleProfit - totalDividends;
const dividendsPerShare = totalDividends / this.totalShares;
const profit = this.numShares * dividendsPerShare * (1 - this.dividendTaxPercentage / 100);
player.gainMoney(profit);
player.recordMoneySource(profit, "corporation");
player.gainMoney(profit, "corporation");
this.addFunds(retainedEarnings);
}
} else {

View File

@ -48,7 +48,7 @@ export function BuybackSharesModal(props: IProps): React.ReactElement {
}
}
corp.issuedShares -= shares;
player.loseMoney(shares * buybackPrice);
player.loseMoney(shares * buybackPrice, "corporation");
props.onClose();
props.rerender();
}

View File

@ -36,7 +36,7 @@ export function CreateCorporationModal(props: IProps): React.ReactElement {
}
player.startCorporation(name);
player.loseMoney(150e9);
player.loseMoney(150e9, "corporation");
props.onClose();
router.toCorporation();

View File

@ -69,8 +69,7 @@ export function SellSharesModal(props: IProps): React.ReactElement {
corp.sharePrice = newSharePrice;
corp.shareSalesUntilPriceUpdate = newSharesUntilUpdate;
corp.shareSaleCooldown = CorporationConstants.SellSharesCooldown;
player.gainMoney(profit);
player.recordMoneySource(profit, "corporation");
player.gainMoney(profit, "corporation");
props.onClose();
dialogBoxCreate(
<>

View File

@ -60,7 +60,7 @@ export function buyDarkwebItem(itemName: string): void {
}
// buy and push
Player.loseMoney(item.price);
Player.loseMoney(item.price, "other");
Player.getHomeComputer().programs.push(item.program);
Terminal.print(
"You have purchased the " + item.program + " program. The new program can be found on your home computer.",

View File

@ -19,7 +19,7 @@ interface IProps {
export function General(props: IProps): React.ReactElement {
function addMoney(n: number) {
return function () {
props.player.gainMoney(n);
props.player.gainMoney(n, "other");
};
}

View File

@ -106,7 +106,7 @@ export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = fal
}
Player.queuedAugmentations.push(queuedAugmentation);
Player.loseMoney(aug.baseCost * factionInfo.augmentationPriceMult);
Player.loseMoney(aug.baseCost * factionInfo.augmentationPriceMult, "augmentations");
// If you just purchased Neuroflux Governor, recalculate the cost
if (aug.name == AugmentationNames.NeuroFluxGovernor) {

View File

@ -52,7 +52,7 @@ export function DonateOption(props: IProps): React.ReactElement {
const amt = donateAmt;
if (amt === null) return;
if (!canDonate()) return;
props.p.loseMoney(amt);
props.p.loseMoney(amt, "other");
const repGain = repFromDonation(amt, props.p);
props.faction.playerReputation += repGain;
dialogBoxCreate(

View File

@ -147,8 +147,7 @@ export class Gang {
this.wanted = newWanted;
if (this.wanted < 1) this.wanted = 1;
}
player.gainMoney(moneyGains * numCycles);
player.recordMoneySource(moneyGains * numCycles, "gang");
player.gainMoney(moneyGains * numCycles, "gang");
}
processTerritoryAndPowerGains(numCycles = 1): void {

View File

@ -317,7 +317,7 @@ export class GangMember {
if (this.augmentations.includes(upg.name) || this.upgrades.includes(upg.name)) return false;
if (player.money.lt(gang.getUpgradeCost(upg))) return false;
player.loseMoney(gang.getUpgradeCost(upg));
player.loseMoney(gang.getUpgradeCost(upg), "gang");
if (upg.type === "g") {
this.augmentations.push(upg.name);
} else {

View File

@ -50,7 +50,7 @@ export function purchaseHacknet(player: IPlayer): number {
if (!player.canAfford(cost)) {
return -1;
}
player.loseMoney(cost);
player.loseMoney(cost, "hacknet");
player.createHacknetServer();
updateHashManagerCapacity(player);
@ -69,7 +69,7 @@ export function purchaseHacknet(player: IPlayer): number {
const name = "hacknet-node-" + numOwned;
const node = new HacknetNode(name, player.hacknet_node_money_mult);
player.loseMoney(cost);
player.loseMoney(cost, "hacknet");
player.hacknetNodes.push(node);
return numOwned;
@ -266,7 +266,7 @@ export function purchaseLevelUpgrade(player: IPlayer, node: HacknetNode | Hackne
return false;
}
player.loseMoney(cost);
player.loseMoney(cost, "hacknet");
node.upgradeLevel(sanitizedLevels, player.hacknet_node_money_mult);
return true;
@ -305,7 +305,7 @@ export function purchaseRamUpgrade(player: IPlayer, node: HacknetNode | HacknetS
return false;
}
player.loseMoney(cost);
player.loseMoney(cost, "hacknet");
node.upgradeRam(sanitizedLevels, player.hacknet_node_money_mult);
return true;
@ -336,7 +336,7 @@ export function purchaseCoreUpgrade(player: IPlayer, node: HacknetNode | Hacknet
return false;
}
player.loseMoney(cost);
player.loseMoney(cost, "hacknet");
node.upgradeCore(sanitizedLevels, player.hacknet_node_money_mult);
return true;
@ -364,7 +364,7 @@ export function purchaseCacheUpgrade(player: IPlayer, node: HacknetServer, level
return false;
}
player.loseMoney(cost);
player.loseMoney(cost, "hacknet");
node.upgradeCache(sanitizedLevels);
return true;
@ -398,8 +398,7 @@ function processAllHacknetNodeEarnings(player: IPlayer, numCycles: number): numb
function processSingleHacknetNodeEarnings(player: IPlayer, numCycles: number, nodeObj: HacknetNode): number {
const totalEarnings = nodeObj.process(numCycles);
player.gainMoney(totalEarnings);
player.recordMoneySource(totalEarnings, "hacknetnode");
player.gainMoney(totalEarnings, "hacknet");
return totalEarnings;
}
@ -472,8 +471,7 @@ export function purchaseHashUpgrade(player: IPlayer, upgName: string, upgTarget:
switch (upgName) {
case "Sell for Money": {
player.gainMoney(upg.value);
player.recordMoneySource(upg.value, "hacknetnode");
player.gainMoney(upg.value, "hacknet");
break;
}
case "Sell for Corporation Funds": {

View File

@ -42,8 +42,7 @@ export function Victory(props: IProps): React.ReactElement {
BitNodeMultipliers.InfiltrationMoney;
function sell(): void {
player.gainMoney(moneyGain);
player.recordMoneySource(moneyGain, "infiltration");
player.gainMoney(moneyGain, "infiltration");
quitInfiltration();
}

View File

@ -23,7 +23,7 @@ export function purchaseTorRouter(p: IPlayer): void {
dialogBoxCreate("You cannot afford to purchase the TOR router!");
return;
}
p.loseMoney(CONSTANTS.TorRouterCost);
p.loseMoney(CONSTANTS.TorRouterCost, "other");
const darkweb = safetlyCreateUniqueServer({
ip: createUniqueRandomIp(),

View File

@ -24,7 +24,7 @@ export function CoresButton(props: IProps): React.ReactElement {
function buy(): void {
if (maxCores) return;
if (!props.p.canAfford(cost)) return;
props.p.loseMoney(cost);
props.p.loseMoney(cost, "servers");
homeComputer.cpuCores++;
props.rerender();
}

View File

@ -57,9 +57,8 @@ export class HospitalLocation extends React.Component<IProps, IState> {
}
const cost = this.getCost();
this.props.p.loseMoney(cost);
this.props.p.loseMoney(cost, "hospitalization");
this.props.p.hp = this.props.p.max_hp;
this.props.p.recordMoneySource(-1 * cost, "hospitalization");
// This just forces a re-render to update the cost
this.setState({

View File

@ -33,7 +33,7 @@ function travel(p: IPlayer, router: IRouter, to: CityName): void {
return;
}
p.loseMoney(cost);
p.loseMoney(cost, "other");
p.travel(to);
dialogBoxCreate(<>You are now in {to}!</>);
router.toCity();

View File

@ -395,10 +395,9 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
const moneyGained = moneyDrained * BitNodeMultipliers.ScriptHackMoneyGain;
Player.gainMoney(moneyGained);
Player.gainMoney(moneyGained, "hacking");
workerScript.scriptRef.onlineMoneyMade += moneyGained;
Player.scriptProdSinceLastAug += moneyGained;
Player.recordMoneySource(moneyGained, "hacking");
workerScript.scriptRef.recordHack(server.hostname, moneyGained, threads);
Player.gainHackingExp(expGainedOnSuccess);
workerScript.scriptRef.onlineExpGained += expGainedOnSuccess;
@ -1550,7 +1549,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
const homeComputer = Player.getHomeComputer();
homeComputer.serversOnNetwork.push(newServ.hostname);
newServ.serversOnNetwork.push(homeComputer.hostname);
Player.loseMoney(cost);
Player.loseMoney(cost, "servers");
workerScript.log(
"purchaseServer",
`Purchased new server with hostname '${newServ.hostname}' for ${numeralWrapper.formatMoney(cost)}`,
@ -2297,7 +2296,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
if (Player.money.lt(CONSTANTS.TravelCost)) {
throw makeRuntimeErrorMsg("travelToCity", "Not enough money to travel.");
}
Player.loseMoney(CONSTANTS.TravelCost);
Player.loseMoney(CONSTANTS.TravelCost, "other");
Player.city = cityname;
workerScript.log("travelToCity", `Traveled to ${cityname}`);
return true;
@ -2320,7 +2319,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
workerScript.log("purchaseTor", "You cannot afford to purchase a Tor router.");
return false;
}
Player.loseMoney(CONSTANTS.TorRouterCost);
Player.loseMoney(CONSTANTS.TorRouterCost, "other");
const darkweb = safetlyCreateUniqueServer({
ip: createUniqueRandomIp(),
@ -2376,7 +2375,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
return true;
}
Player.loseMoney(item.price);
Player.loseMoney(item.price, "other");
Player.getHomeComputer().programs.push(item.program);
workerScript.log(
"purchaseProgram",
@ -2667,7 +2666,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
}
homeComputer.cpuCores += 1;
Player.loseMoney(cost);
Player.loseMoney(cost, "servers");
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
workerScript.log(
@ -2700,7 +2699,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
}
homeComputer.maxRam *= 2;
Player.loseMoney(cost);
Player.loseMoney(cost, "servers");
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
workerScript.log(
@ -3061,7 +3060,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
}
const repGain = (amt / CONSTANTS.DonateMoneyToRepDivisor) * Player.faction_rep_mult;
faction.playerReputation += repGain;
Player.loseMoney(amt);
Player.loseMoney(amt, "other");
workerScript.log(
"donateToFaction",
`${numeralWrapper.formatMoney(amt)} donated to '${name}' for ${numeralWrapper.formatReputation(

View File

@ -350,7 +350,7 @@ export function NetscriptStockMarket(
}
player.has4SData = true;
player.loseMoney(getStockMarket4SDataCost());
player.loseMoney(getStockMarket4SDataCost(), "stock");
workerScript.log("purchase4SMarketData", "Purchased 4S Market Data");
return true;
},
@ -369,7 +369,7 @@ export function NetscriptStockMarket(
}
player.has4SDataTixApi = true;
player.loseMoney(getStockMarket4STixApiCost());
player.loseMoney(getStockMarket4STixApiCost(), "stock");
workerScript.log("purchase4SMarketDataTixApi", "Purchased 4S Market Data TIX API");
return true;
},

View File

@ -56,7 +56,7 @@ export interface IPlayer {
numPeopleKilled: number;
location: LocationName;
max_hp: number;
money: any;
readonly money: any;
moneySourceA: MoneySourceTracker;
moneySourceB: MoneySourceTracker;
playtimeSinceLastAug: number;
@ -184,7 +184,7 @@ export interface IPlayer {
gainAgilityExp(exp: number): void;
gainCharismaExp(exp: number): void;
gainIntelligenceExp(exp: number): void;
gainMoney(money: number): void;
gainMoney(money: number, source: string): void;
getCurrentServer(): BaseServer;
getGangFaction(): Faction;
getGangName(): string;
@ -201,12 +201,11 @@ export interface IPlayer {
inBladeburner(): boolean;
inGang(): boolean;
isQualified(company: Company, position: CompanyPosition): boolean;
loseMoney(money: number): void;
loseMoney(money: number, source: string): void;
process(router: IRouter, numCycles?: number): void;
reapplyAllAugmentations(resetMultipliers?: boolean): void;
reapplyAllSourceFiles(): void;
regenerateHp(amt: number): void;
recordMoneySource(amt: number, source: string): void;
setMoney(amt: number): void;
singularityStopWork(): string;
startBladeburner(p: any): void;

View File

@ -191,7 +191,7 @@ export class PlayerObject implements IPlayer {
gainAgilityExp: (exp: number) => void;
gainCharismaExp: (exp: number) => void;
gainIntelligenceExp: (exp: number) => void;
gainMoney: (money: number) => void;
gainMoney: (money: number, source: string) => void;
getCurrentServer: () => BaseServer;
getGangFaction: () => Faction;
getGangName: () => string;
@ -208,7 +208,7 @@ export class PlayerObject implements IPlayer {
inBladeburner: () => boolean;
inGang: () => boolean;
isQualified: (company: Company, position: CompanyPosition) => boolean;
loseMoney: (money: number) => void;
loseMoney: (money: number, source: string) => void;
reapplyAllAugmentations: (resetMultipliers?: boolean) => void;
reapplyAllSourceFiles: () => void;
regenerateHp: (amt: number) => void;

View File

@ -1,4 +1,5 @@
import { IPlayer } from "../IPlayer";
import { PlayerObject } from "./PlayerObject";
import { Augmentations } from "../../Augmentation/Augmentations";
import { applyAugmentation } from "../../Augmentation/AugmentationHelpers";
import { PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation";
@ -78,7 +79,7 @@ export function init(this: IPlayer): void {
this.getHomeComputer().programs.push(Programs.NukeProgram.name);
}
export function prestigeAugmentation(this: IPlayer): void {
export function prestigeAugmentation(this: PlayerObject): void {
this.currentServer = SpecialServers.Home;
this.numPeopleKilled = 0;
@ -319,7 +320,7 @@ export function hasProgram(this: IPlayer, programName: string): boolean {
return false;
}
export function setMoney(this: IPlayer, money: number): void {
export function setMoney(this: PlayerObject, money: number): void {
if (isNaN(money)) {
console.error("NaN passed into Player.setMoney()");
return;
@ -327,21 +328,23 @@ export function setMoney(this: IPlayer, money: number): void {
this.money = new Decimal(money);
}
export function gainMoney(this: IPlayer, money: number): void {
export function gainMoney(this: PlayerObject, money: number, source: string): void {
if (isNaN(money)) {
console.error("NaN passed into Player.gainMoney()");
return;
}
this.money = this.money.plus(money);
this.recordMoneySource(money, source);
}
export function loseMoney(this: IPlayer, money: number): void {
export function loseMoney(this: PlayerObject, money: number, source: string): void {
if (isNaN(money)) {
console.error("NaN passed into Player.loseMoney()");
return;
}
if (this.money.eq(Infinity) && money === Infinity) return;
this.money = this.money.minus(money);
this.recordMoneySource(-1 * money, source);
}
export function canAfford(this: IPlayer, cost: number): boolean {
@ -352,7 +355,7 @@ export function canAfford(this: IPlayer, cost: number): boolean {
return this.money.gte(cost);
}
export function recordMoneySource(this: IPlayer, amt: number, source: string): void {
export function recordMoneySource(this: PlayerObject, amt: number, source: string): void {
if (!(this.moneySourceA instanceof MoneySourceTracker)) {
console.warn(`Player.moneySourceA was not properly initialized. Resetting`);
this.moneySourceA = new MoneySourceTracker();
@ -539,12 +542,7 @@ export function processWorkEarnings(this: IPlayer, numCycles = 1): void {
this.gainDexterityExp(dexExpGain);
this.gainAgilityExp(agiExpGain);
this.gainCharismaExp(chaExpGain);
this.gainMoney(moneyGain);
if (this.className) {
this.recordMoneySource(moneyGain, "class");
} else {
this.recordMoneySource(moneyGain, "work");
}
this.gainMoney(moneyGain, this.className ? "class" : "work");
this.workHackExpGained += hackExpGain;
this.workStrExpGained += strExpGain;
this.workDefExpGained += defExpGain;
@ -1512,8 +1510,7 @@ export function finishCrime(this: IPlayer, cancelled: boolean): string {
);
return "";
}
this.gainMoney(this.workMoneyGained);
this.recordMoneySource(this.workMoneyGained, "crime");
this.gainMoney(this.workMoneyGained, "crime");
this.karma -= crime.karma;
this.numPeopleKilled += crime.kills;
if (crime.intelligence_exp > 0) {
@ -1702,8 +1699,7 @@ export function hospitalize(this: IPlayer): number {
SnackbarEvents.emit(`You've been Hospitalized for ${numeralWrapper.formatMoney(cost)}`, "warning");
}
this.loseMoney(cost);
this.recordMoneySource(-1 * cost, "hospitalization");
this.loseMoney(cost, "hospitalization");
this.hp = this.max_hp;
return cost;
}
@ -2600,8 +2596,7 @@ export function gainCodingContractReward(this: IPlayer, reward: ICodingContractR
case CodingContractRewardType.Money:
default: {
const moneyGain = CONSTANTS.CodingContractBaseMoneyGain * difficulty * BitNodeMultipliers.CodingContractMoney;
this.gainMoney(moneyGain);
this.recordMoneySource(moneyGain, "codingcontract");
this.gainMoney(moneyGain, "codingcontract");
return `Gained ${numeralWrapper.formatMoney(moneyGain)}`;
}
}

View File

@ -26,7 +26,7 @@ export function purchaseResleeve(r: Resleeve, p: IPlayer): boolean {
if (!p.canAfford(cost)) {
return false;
}
p.loseMoney(cost);
p.loseMoney(cost, "other");
// Set the player's exp
p.hacking_exp = r.hacking_exp;

View File

@ -331,8 +331,7 @@ export class Sleeve extends Person {
const gain: number = task.money * numCycles;
this.earningsForTask.money += gain;
this.earningsForPlayer.money += gain;
p.gainMoney(gain);
p.recordMoneySource(gain, "sleeves");
p.gainMoney(gain, "sleeves");
}
/**
@ -668,7 +667,7 @@ export class Sleeve extends Person {
* Travel to another City. Costs money from player
*/
travel(p: IPlayer, newCity: CityName): boolean {
p.loseMoney(CONSTANTS.TravelCost);
p.loseMoney(CONSTANTS.TravelCost, "sleeves");
this.city = newCity;
return true;
@ -684,7 +683,7 @@ export class Sleeve extends Person {
return false;
}
p.loseMoney(aug.startingCost);
p.loseMoney(aug.startingCost, "sleeves");
this.installAugmentation(aug);
return true;
}

View File

@ -53,7 +53,7 @@ export function CovenantPurchasesRoot(props: IProps): React.ReactElement {
if (player.sleevesFromCovenant >= MaxSleevesFromCovenant) return;
if (player.canAfford(purchaseCost())) {
player.loseMoney(purchaseCost());
player.loseMoney(purchaseCost(), "sleeves");
player.sleevesFromCovenant += 1;
player.sleeves.push(new Sleeve(player));
rerender();

View File

@ -53,7 +53,7 @@ export function CovenantSleeveMemoryUpgrade(props: IProps): React.ReactElement {
const cost = getPurchaseCost();
if (props.p.canAfford(cost)) {
props.sleeve.upgradeMemory(amt);
props.p.loseMoney(cost);
props.p.loseMoney(cost, "sleeves");
props.rerender();
}
}

View File

@ -25,7 +25,7 @@ export function TravelModal(props: IProps): React.ReactElement {
dialogBoxCreate("You cannot afford to have this sleeve travel to another city");
}
props.sleeve.city = city as CityName;
player.loseMoney(CONSTANTS.TravelCost);
player.loseMoney(CONSTANTS.TravelCost, "sleeve");
props.sleeve.resetTaskStatus();
props.rerender();
props.onClose();

View File

@ -94,7 +94,7 @@ export function purchaseServer(hostname: string, ram: number, cost: number, p: I
homeComputer.serversOnNetwork.push(newServ.hostname);
newServ.serversOnNetwork.push(homeComputer.hostname);
p.loseMoney(cost);
p.loseMoney(cost, "servers");
dialogBoxCreate("Server successfully purchased with hostname " + hostname);
}
@ -114,5 +114,5 @@ export function purchaseRamForHomeComputer(p: IPlayer): void {
}
homeComputer.maxRam *= 2;
p.loseMoney(cost);
p.loseMoney(cost, "servers");
}

View File

@ -102,7 +102,7 @@ export function buyStock(
}
const origTotal = stock.playerShares * stock.playerAvgPx;
Player.loseMoney(totalPrice);
Player.loseMoney(totalPrice, "stock");
const newTotal = origTotal + totalPrice - CONSTANTS.StockMarketCommission;
stock.playerShares = Math.round(stock.playerShares + shares);
stock.playerAvgPx = newTotal / stock.playerShares;
@ -171,8 +171,7 @@ export function sellStock(
if (isNaN(netProfit)) {
netProfit = 0;
}
Player.gainMoney(gains);
Player.recordMoneySource(netProfit, "stock");
Player.gainMoney(gains, "stock");
if (workerScript) {
workerScript.scriptRef.onlineMoneyMade += netProfit;
Player.scriptProdSinceLastAug += netProfit;
@ -280,7 +279,7 @@ export function shortStock(
}
const origTotal = stock.playerShortShares * stock.playerAvgShortPx;
Player.loseMoney(totalPrice);
Player.loseMoney(totalPrice, "stock");
const newTotal = origTotal + totalPrice - CONSTANTS.StockMarketCommission;
stock.playerShortShares = Math.round(stock.playerShortShares + shares);
stock.playerAvgShortPx = newTotal / stock.playerShortShares;
@ -364,8 +363,7 @@ export function sellShort(
if (isNaN(profit)) {
profit = 0;
}
Player.gainMoney(totalGain);
Player.recordMoneySource(profit, "stock");
Player.gainMoney(totalGain, "stock");
if (workerScript) {
workerScript.scriptRef.onlineMoneyMade += profit;
Player.scriptProdSinceLastAug += profit;

View File

@ -35,7 +35,7 @@ function Purchase4SMarketDataTixApiAccessButton(props: IProps): React.ReactEleme
return;
}
props.p.has4SDataTixApi = true;
props.p.loseMoney(getStockMarket4STixApiCost());
props.p.loseMoney(getStockMarket4STixApiCost(), "stock");
props.rerender();
}
@ -88,7 +88,7 @@ function PurchaseWseAccountButton(props: IProps): React.ReactElement {
}
props.p.hasWseAccount = true;
props.initStockMarket();
props.p.loseMoney(CONSTANTS.WSEAccountCost);
props.p.loseMoney(CONSTANTS.WSEAccountCost, "stock");
props.rerender();
}
@ -113,7 +113,7 @@ function PurchaseTixApiAccessButton(props: IProps): React.ReactElement {
return;
}
props.p.hasTixApiAccess = true;
props.p.loseMoney(CONSTANTS.TIXAPICost);
props.p.loseMoney(CONSTANTS.TIXAPICost, "stock");
props.rerender();
}
@ -143,7 +143,7 @@ function Purchase4SMarketDataButton(props: IProps): React.ReactElement {
return;
}
props.p.has4SData = true;
props.p.loseMoney(getStockMarket4SDataCost());
props.p.loseMoney(getStockMarket4SDataCost(), "stock");
props.rerender();
}
if (props.p.has4SData) {

View File

@ -196,8 +196,7 @@ export class Terminal implements ITerminal {
} // Safety check
server.moneyAvailable -= moneyGained;
player.gainMoney(moneyGained);
player.recordMoneySource(moneyGained, "hacking");
player.gainMoney(moneyGained, "hacking");
player.gainHackingExp(expGainedOnSuccess);
player.gainIntelligenceExp(expGainedOnSuccess / CONSTANTS.IntelligenceTerminalHackBaseExpGain);

View File

@ -253,7 +253,7 @@ const Engine: {
let offlineReputation = 0;
const offlineHackingIncome = (Player.moneySourceA.hacking / Player.playtimeSinceLastAug) * timeOffline * 0.75;
Player.gainMoney(offlineHackingIncome);
Player.gainMoney(offlineHackingIncome, "hacknet");
// Process offline progress
loadAllRunningScripts(); // This also takes care of offline production for those scripts
if (Player.isWorking) {

View File

@ -167,9 +167,15 @@ function MoneyModal({ open, onClose }: IMoneyModalProps): React.ReactElement {
const player = use.Player();
function convertMoneySourceTrackerToString(src: MoneySourceTracker): React.ReactElement {
const parts: any[][] = [[`Total:`, <Money money={src.total} />]];
if (src.augmentations) {
parts.push([`Augmentations:`, <Money money={src.augmentations} />]);
}
if (src.bladeburner) {
parts.push([`Bladeburner:`, <Money money={src.bladeburner} />]);
}
if (src.casino) {
parts.push([`Casino:`, <Money money={src.casino} />]);
}
if (src.codingcontract) {
parts.push([`Coding Contracts:`, <Money money={src.codingcontract} />]);
}
@ -191,8 +197,8 @@ function MoneyModal({ open, onClose }: IMoneyModalProps): React.ReactElement {
if (src.hacking) {
parts.push([`Hacking:`, <Money money={src.hacking} />]);
}
if (src.hacknetnode) {
parts.push([`Hacknet Nodes:`, <Money money={src.hacknetnode} />]);
if (src.hacknet) {
parts.push([`Hacknet Nodes:`, <Money money={src.hacknet} />]);
}
if (src.hospitalization) {
parts.push([`Hospitalization:`, <Money money={src.hospitalization} />]);
@ -200,15 +206,18 @@ function MoneyModal({ open, onClose }: IMoneyModalProps): React.ReactElement {
if (src.infiltration) {
parts.push([`Infiltration:`, <Money money={src.infiltration} />]);
}
if (src.servers) {
parts.push([`Servers:`, <Money money={src.servers} />]);
}
if (src.stock) {
parts.push([`Stock Market:`, <Money money={src.stock} />]);
}
if (src.casino) {
parts.push([`Casino:`, <Money money={src.casino} />]);
}
if (src.sleeves) {
parts.push([`Sleeves:`, <Money money={src.sleeves} />]);
}
if (src.other) {
parts.push([`Other:`, <Money money={src.other} />]);
}
return <StatsTable rows={parts} wide />;
}

View File

@ -16,13 +16,16 @@ export class MoneySourceTracker {
crime = 0;
gang = 0;
hacking = 0;
hacknetnode = 0;
hacknet = 0;
hospitalization = 0;
infiltration = 0;
sleeves = 0;
stock = 0;
total = 0;
work = 0;
servers = 0;
other = 0;
augmentations = 0;
// Record money earned
record(amt: number, source: string): void {