From 8d474a7610febe574478a1739d68590b04f260d7 Mon Sep 17 00:00:00 2001 From: Staszek Welsh <stalefishies@gmail.com> Date: Mon, 30 May 2022 21:45:36 +0100 Subject: [PATCH 1/7] Change corporation.dividendPercentage to corporation.dividendRate --- src/Corporation/Actions.ts | 8 +++---- src/Corporation/Corporation.tsx | 22 +++++++++---------- src/Corporation/ICorporation.ts | 2 +- src/Corporation/data/Constants.ts | 4 ++-- src/Corporation/ui/Overview.tsx | 6 ++--- .../ui/modals/IssueDividendsModal.tsx | 2 +- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Corporation/Actions.ts b/src/Corporation/Actions.ts index 1ec820037..acd211467 100644 --- a/src/Corporation/Actions.ts +++ b/src/Corporation/Actions.ts @@ -84,12 +84,12 @@ export function LevelUpgrade(corporation: ICorporation, upgrade: CorporationUpgr } } -export function IssueDividends(corporation: ICorporation, percent: number): void { - if (isNaN(percent) || percent < 0 || percent > CorporationConstants.DividendMaxPercentage) { - throw new Error(`Invalid value. Must be an integer between 0 and ${CorporationConstants.DividendMaxPercentage}`); +export function IssueDividends(corporation: ICorporation, rate: number): void { + if (isNaN(rate) || rate < 0 || rate > CorporationConstants.DividendMaxRate) { + throw new Error(`Invalid value. Must be an number between 0 and ${CorporationConstants.DividendMaxRate}`); } - corporation.dividendPercentage = percent * 100; + corporation.dividendRate = rate; } export function SellMaterial(mat: Material, amt: string, price: string): void { diff --git a/src/Corporation/Corporation.tsx b/src/Corporation/Corporation.tsx index ace40ae72..787e22569 100644 --- a/src/Corporation/Corporation.tsx +++ b/src/Corporation/Corporation.tsx @@ -35,8 +35,8 @@ export class Corporation { shareSalesUntilPriceUpdate = CorporationConstants.SHARESPERPRICEUPDATE; shareSaleCooldown = 0; // Game cycles until player can sell shares again issueNewSharesCooldown = 0; // Game cycles until player can issue shares again - dividendPercentage = 0; - dividendTaxPercentage = 50; + dividendRate = 0; + dividendTaxPercentage = 100 - 100 * BitNodeMultipliers.CorporationSoftcap; issuedShares = 0; sharePrice = 0; storedCycles = 0; @@ -121,16 +121,16 @@ export class Corporation { } // Process dividends - if (this.dividendPercentage > 0 && cycleProfit > 0) { + if (this.dividendRate > 0 && cycleProfit > 0) { // Validate input again, just to be safe if ( - isNaN(this.dividendPercentage) || - this.dividendPercentage < 0 || - this.dividendPercentage > CorporationConstants.DividendMaxPercentage * 100 + isNaN(this.dividendRate) || + this.dividendRate < 0 || + this.dividendRate > CorporationConstants.DividendMaxRate ) { - console.error(`Invalid Corporation dividend percentage: ${this.dividendPercentage}`); + console.error(`Invalid Corporation dividend rate: ${this.dividendRate}`); } else { - const totalDividends = (this.dividendPercentage / 100) * cycleProfit; + const totalDividends = this.dividendRate * cycleProfit; const retainedEarnings = cycleProfit - totalDividends; player.gainMoney(this.getDividends(), "corporation"); this.addFunds(retainedEarnings); @@ -149,7 +149,7 @@ export class Corporation { getDividends(): number { const profit = this.revenue - this.expenses; const cycleProfit = profit * CorporationConstants.SecsPerMarketCycle; - const totalDividends = (this.dividendPercentage / 100) * cycleProfit; + const totalDividends = this.dividendRate * cycleProfit; const dividendsPerShare = totalDividends / this.totalShares; const dividends = this.numShares * dividendsPerShare; let upgrades = -0.15; @@ -167,8 +167,8 @@ export class Corporation { profit = this.avgProfit; if (this.public) { // Account for dividends - if (this.dividendPercentage > 0) { - profit *= (100 - this.dividendPercentage) / 100; + if (this.dividendRate > 0) { + profit *= 1 - this.dividendRate; } val = this.funds + profit * 85e3; diff --git a/src/Corporation/ICorporation.ts b/src/Corporation/ICorporation.ts index 609204fee..ebb51cad6 100644 --- a/src/Corporation/ICorporation.ts +++ b/src/Corporation/ICorporation.ts @@ -19,7 +19,7 @@ export interface ICorporation { shareSalesUntilPriceUpdate: number; shareSaleCooldown: number; issueNewSharesCooldown: number; - dividendPercentage: number; + dividendRate: number; dividendTaxPercentage: number; issuedShares: number; sharePrice: number; diff --git a/src/Corporation/data/Constants.ts b/src/Corporation/data/Constants.ts index d6b53f3d1..c83e3e0d7 100644 --- a/src/Corporation/data/Constants.ts +++ b/src/Corporation/data/Constants.ts @@ -19,7 +19,7 @@ export const CorporationConstants: { BribeThreshold: number; BribeToRepRatio: number; ProductProductionCostRatio: number; - DividendMaxPercentage: number; + DividendMaxRate: number; EmployeeSalaryMultiplier: number; CyclesPerEmployeeRaise: number; EmployeeRaiseAmount: number; @@ -61,7 +61,7 @@ export const CorporationConstants: { ProductProductionCostRatio: 5, //Ratio of material cost of a product to its production cost - DividendMaxPercentage: 1, + DividendMaxRate: 1, EmployeeSalaryMultiplier: 3, // Employee stats multiplied by this to determine initial salary CyclesPerEmployeeRaise: 400, // All employees get a raise every X market cycles diff --git a/src/Corporation/ui/Overview.tsx b/src/Corporation/ui/Overview.tsx index e2856867a..a873f9a92 100644 --- a/src/Corporation/ui/Overview.tsx +++ b/src/Corporation/ui/Overview.tsx @@ -275,15 +275,15 @@ interface IDividendsStatsProps { } function DividendsStats({ profit }: IDividendsStatsProps): React.ReactElement { const corp = useCorporation(); - if (corp.dividendPercentage <= 0 || profit <= 0) return <></>; - const totalDividends = (corp.dividendPercentage / 100) * profit; + if (corp.dividendRate <= 0 || profit <= 0) return <></>; + const totalDividends = corp.dividendRate * profit; const retainedEarnings = profit - totalDividends; const dividendsPerShare = totalDividends / corp.totalShares; return ( <StatsTable rows={[ ["Retained Profits (after dividends):", <MoneyRate money={retainedEarnings} />], - ["Dividend Percentage:", numeralWrapper.format(corp.dividendPercentage / 100, "0%")], + ["Dividend Percentage:", numeralWrapper.format(corp.dividendRate, "0%")], ["Dividends per share:", <MoneyRate money={dividendsPerShare} />], ["Your earnings as a shareholder:", <MoneyRate money={corp.getDividends()} />], ]} diff --git a/src/Corporation/ui/modals/IssueDividendsModal.tsx b/src/Corporation/ui/modals/IssueDividendsModal.tsx index 4531faedf..110e21cc5 100644 --- a/src/Corporation/ui/modals/IssueDividendsModal.tsx +++ b/src/Corporation/ui/modals/IssueDividendsModal.tsx @@ -19,7 +19,7 @@ export function IssueDividendsModal(props: IProps): React.ReactElement { const corp = useCorporation(); const [percent, setPercent] = useState(0); - const canIssue = !isNaN(percent) && percent >= 0 && percent <= CorporationConstants.DividendMaxPercentage * 100; + const canIssue = !isNaN(percent) && percent >= 0 && percent <= CorporationConstants.DividendMaxRate * 100; function issueDividends(): void { if (!canIssue) return; if (percent === null) return; From e28fe3e31d07d7a4b410c30760a4d40fb017c20c Mon Sep 17 00:00:00 2001 From: Staszek Welsh <stalefishies@gmail.com> Date: Mon, 30 May 2022 22:05:05 +0100 Subject: [PATCH 2/7] Use stored corporation.dividendTax in the dividend tax calculation --- src/Corporation/Corporation.tsx | 28 +++++++++++++++------------- src/Corporation/ICorporation.ts | 5 +++-- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/Corporation/Corporation.tsx b/src/Corporation/Corporation.tsx index 787e22569..a41185372 100644 --- a/src/Corporation/Corporation.tsx +++ b/src/Corporation/Corporation.tsx @@ -36,7 +36,7 @@ export class Corporation { shareSaleCooldown = 0; // Game cycles until player can sell shares again issueNewSharesCooldown = 0; // Game cycles until player can issue shares again dividendRate = 0; - dividendTaxPercentage = 100 - 100 * BitNodeMultipliers.CorporationSoftcap; + dividendTax = 1 - BitNodeMultipliers.CorporationSoftcap + 0.15; issuedShares = 0; sharePrice = 0; storedCycles = 0; @@ -121,6 +121,7 @@ export class Corporation { } // Process dividends + this.updateDividendTax(); if (this.dividendRate > 0 && cycleProfit > 0) { // Validate input again, just to be safe if ( @@ -146,20 +147,23 @@ export class Corporation { } } + updateDividendTax(): void { + this.dividendTax = 1 - BitNodeMultipliers.CorporationSoftcap + 0.15; + if (this.unlockUpgrades[5] === 1) { + this.dividendTax -= 0.05; + } + if (this.unlockUpgrades[6] === 1) { + this.dividendTax -= 0.1; + } + } + getDividends(): number { const profit = this.revenue - this.expenses; const cycleProfit = profit * CorporationConstants.SecsPerMarketCycle; const totalDividends = this.dividendRate * cycleProfit; const dividendsPerShare = totalDividends / this.totalShares; const dividends = this.numShares * dividendsPerShare; - let upgrades = -0.15; - if (this.unlockUpgrades[5] === 1) { - upgrades += 0.05; - } - if (this.unlockUpgrades[6] === 1) { - upgrades += 0.1; - } - return Math.pow(dividends, BitNodeMultipliers.CorporationSoftcap + upgrades); + return Math.pow(dividends, 1 - this.dividendTax); } determineValuation(): number { @@ -277,10 +281,8 @@ export class Corporation { this.funds = this.funds - price; // Apply effects for one-time upgrades - if (upgN === 5) { - this.dividendTaxPercentage -= 5; - } else if (upgN === 6) { - this.dividendTaxPercentage -= 10; + if (upgN === 5 || upgN === 6) { + this.updateDividendTax(); } } diff --git a/src/Corporation/ICorporation.ts b/src/Corporation/ICorporation.ts index ebb51cad6..457f09061 100644 --- a/src/Corporation/ICorporation.ts +++ b/src/Corporation/ICorporation.ts @@ -20,7 +20,7 @@ export interface ICorporation { shareSaleCooldown: number; issueNewSharesCooldown: number; dividendRate: number; - dividendTaxPercentage: number; + dividendTax: number; issuedShares: number; sharePrice: number; storedCycles: number; @@ -54,6 +54,7 @@ export interface ICorporation { getSalesMultiplier(): number; getScientificResearchMultiplier(): number; getStarterGuide(player: IPlayer): void; - toJSON(): any; + updateDividendTax(): void; getDividends(): number; + toJSON(): any; } From c117b55df902f948770426efec9cb7eb3971ef56 Mon Sep 17 00:00:00 2001 From: Staszek Welsh <stalefishies@gmail.com> Date: Mon, 30 May 2022 22:21:27 +0100 Subject: [PATCH 3/7] Expose dividend info through ns.corporation.getCorporation() --- src/NetscriptFunctions/Corporation.ts | 3 +++ src/ScriptEditor/NetscriptDefinitions.d.ts | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/NetscriptFunctions/Corporation.ts b/src/NetscriptFunctions/Corporation.ts index 9ed771625..1303151cc 100644 --- a/src/NetscriptFunctions/Corporation.ts +++ b/src/NetscriptFunctions/Corporation.ts @@ -952,6 +952,9 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript shareSaleCooldown: corporation.shareSaleCooldown, issuedShares: corporation.issuedShares, sharePrice: corporation.sharePrice, + dividendRate: corporation.dividendRate, + dividendTax: corporation.dividendTax, + dividendEarnings: corporation.getDividends() / CorporationConstants.SecsPerMarketCycle, state: corporation.state.getState(), divisions: corporation.divisions.map((division): NSDivision => getSafeDivision(division)), }; diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index 01432f441..b9bda8ce9 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -7100,6 +7100,12 @@ interface CorporationInfo { issuedShares: number; /** Price of the shares */ sharePrice: number; + /** Fraction of profits issued as dividends */ + dividendRate: number; + /** Tax applied on your earnings as a shareholder */ + dividendTax: number; + /** Your earnings as a shareholder per second this cycle */ + dividendEarnings: number; /** State of the corporation. Possible states are START, PURCHASE, PRODUCTION, SALE, EXPORT. */ state: string; /** Array of all divisions */ From 74e4a32f1396b248b06d3635292939b4d9b6bd99 Mon Sep 17 00:00:00 2001 From: Staszek Welsh <stalefishies@gmail.com> Date: Mon, 30 May 2022 22:24:52 +0100 Subject: [PATCH 4/7] Fix shareholder earnings in UI being per cycle instead of per sec --- src/Corporation/ui/Overview.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Corporation/ui/Overview.tsx b/src/Corporation/ui/Overview.tsx index a873f9a92..126408257 100644 --- a/src/Corporation/ui/Overview.tsx +++ b/src/Corporation/ui/Overview.tsx @@ -279,13 +279,14 @@ function DividendsStats({ profit }: IDividendsStatsProps): React.ReactElement { const totalDividends = corp.dividendRate * profit; const retainedEarnings = profit - totalDividends; const dividendsPerShare = totalDividends / corp.totalShares; + const playerEarnings = corp.getDividends() / CorporationConstants.SecsPerMarketCycle; return ( <StatsTable rows={[ ["Retained Profits (after dividends):", <MoneyRate money={retainedEarnings} />], ["Dividend Percentage:", numeralWrapper.format(corp.dividendRate, "0%")], ["Dividends per share:", <MoneyRate money={dividendsPerShare} />], - ["Your earnings as a shareholder:", <MoneyRate money={corp.getDividends()} />], + ["Your earnings as a shareholder:", <MoneyRate money={playerEarnings} />], ]} /> ); From 4a3558098ce26b8c6fd95051eddc59d874d184e4 Mon Sep 17 00:00:00 2001 From: Staszek Welsh <stalefishies@gmail.com> Date: Mon, 30 May 2022 22:31:51 +0100 Subject: [PATCH 5/7] Fix error check in issueDividends expecting 0-100 when it actually takes 0-1 --- src/NetscriptFunctions/Corporation.ts | 11 ++++++----- src/ScriptEditor/NetscriptDefinitions.d.ts | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/NetscriptFunctions/Corporation.ts b/src/NetscriptFunctions/Corporation.ts index 1303151cc..18bab912b 100644 --- a/src/NetscriptFunctions/Corporation.ts +++ b/src/NetscriptFunctions/Corporation.ts @@ -918,14 +918,15 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript }, issueDividends: (ctx: NetscriptContext) => - (_percent: unknown): void => { + (_rate: unknown): void => { checkAccess(ctx); - const percent = ctx.helper.number("percent", _percent); - if (percent < 0 || percent > 100) - throw new Error("Invalid value for percent field! Must be numeric, greater than 0, and less than 100"); + const rate = ctx.helper.number("rate", _rate); + const max = CorporationConstants.DividendMaxRate; + if (rate < 0 || rate > max) + throw new Error(`Invalid value for rate field! Must be numeric, greater than 0, and less than ${max}`); const corporation = getCorporation(); if (!corporation.public) throw ctx.makeRuntimeErrorMsg(`Your company has not gone public!`); - IssueDividends(corporation, percent); + IssueDividends(corporation, rate); }, // If you modify these objects you will affect them for real, it's not diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index b9bda8ce9..a1b01a9ca 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -7048,9 +7048,9 @@ export interface Corporation extends WarehouseAPI, OfficeAPI { levelUpgrade(upgradeName: string): void; /** * Issue dividends - * @param percent - Percent of profit to issue as dividends. + * @param rate - Fraction of profit to issue as dividends. */ - issueDividends(percent: number): void; + issueDividends(rate: number): void; /** * Buyback Shares * @param amount - Amount of shares to buy back. From eb46e4d15695d70ae5818ec9901a5e95f88071bd Mon Sep 17 00:00:00 2001 From: Staszek Welsh <stalefishies@gmail.com> Date: Wed, 1 Jun 2022 12:59:45 +0100 Subject: [PATCH 6/7] Rename getDividends to getCycleDividends for clarity --- src/Corporation/Corporation.tsx | 4 ++-- src/Corporation/ICorporation.ts | 2 +- src/Corporation/ui/Overview.tsx | 2 +- src/NetscriptFunctions/Corporation.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Corporation/Corporation.tsx b/src/Corporation/Corporation.tsx index a41185372..eae2692a5 100644 --- a/src/Corporation/Corporation.tsx +++ b/src/Corporation/Corporation.tsx @@ -133,7 +133,7 @@ export class Corporation { } else { const totalDividends = this.dividendRate * cycleProfit; const retainedEarnings = cycleProfit - totalDividends; - player.gainMoney(this.getDividends(), "corporation"); + player.gainMoney(this.getCycleDividends(), "corporation"); this.addFunds(retainedEarnings); } } else { @@ -157,7 +157,7 @@ export class Corporation { } } - getDividends(): number { + getCycleDividends(): number { const profit = this.revenue - this.expenses; const cycleProfit = profit * CorporationConstants.SecsPerMarketCycle; const totalDividends = this.dividendRate * cycleProfit; diff --git a/src/Corporation/ICorporation.ts b/src/Corporation/ICorporation.ts index 457f09061..b2ea08648 100644 --- a/src/Corporation/ICorporation.ts +++ b/src/Corporation/ICorporation.ts @@ -55,6 +55,6 @@ export interface ICorporation { getScientificResearchMultiplier(): number; getStarterGuide(player: IPlayer): void; updateDividendTax(): void; - getDividends(): number; + getCycleDividends(): number; toJSON(): any; } diff --git a/src/Corporation/ui/Overview.tsx b/src/Corporation/ui/Overview.tsx index 126408257..b6390aad3 100644 --- a/src/Corporation/ui/Overview.tsx +++ b/src/Corporation/ui/Overview.tsx @@ -279,7 +279,7 @@ function DividendsStats({ profit }: IDividendsStatsProps): React.ReactElement { const totalDividends = corp.dividendRate * profit; const retainedEarnings = profit - totalDividends; const dividendsPerShare = totalDividends / corp.totalShares; - const playerEarnings = corp.getDividends() / CorporationConstants.SecsPerMarketCycle; + const playerEarnings = corp.getCycleDividends() / CorporationConstants.SecsPerMarketCycle; return ( <StatsTable rows={[ diff --git a/src/NetscriptFunctions/Corporation.ts b/src/NetscriptFunctions/Corporation.ts index 18bab912b..6a8b55ec2 100644 --- a/src/NetscriptFunctions/Corporation.ts +++ b/src/NetscriptFunctions/Corporation.ts @@ -955,7 +955,7 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript sharePrice: corporation.sharePrice, dividendRate: corporation.dividendRate, dividendTax: corporation.dividendTax, - dividendEarnings: corporation.getDividends() / CorporationConstants.SecsPerMarketCycle, + dividendEarnings: corporation.getCycleDividends() / CorporationConstants.SecsPerMarketCycle, state: corporation.state.getState(), divisions: corporation.divisions.map((division): NSDivision => getSafeDivision(division)), }; From df98bcc748ffe77784a4c1a3f3780ebc69af15ca Mon Sep 17 00:00:00 2001 From: Staszek Welsh <stalefishies@gmail.com> Date: Wed, 1 Jun 2022 13:03:32 +0100 Subject: [PATCH 7/7] Remove unnecessary check in corporation.unlock --- src/Corporation/Corporation.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Corporation/Corporation.tsx b/src/Corporation/Corporation.tsx index eae2692a5..e493ccf31 100644 --- a/src/Corporation/Corporation.tsx +++ b/src/Corporation/Corporation.tsx @@ -281,9 +281,7 @@ export class Corporation { this.funds = this.funds - price; // Apply effects for one-time upgrades - if (upgN === 5 || upgN === 6) { - this.updateDividendTax(); - } + this.updateDividendTax(); } //Levelable upgrades