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..e493ccf31 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; + dividendTax = 1 - BitNodeMultipliers.CorporationSoftcap + 0.15; issuedShares = 0; sharePrice = 0; storedCycles = 0; @@ -121,18 +121,19 @@ export class Corporation { } // Process dividends - if (this.dividendPercentage > 0 && cycleProfit > 0) { + this.updateDividendTax(); + 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"); + player.gainMoney(this.getCycleDividends(), "corporation"); this.addFunds(retainedEarnings); } } else { @@ -146,20 +147,23 @@ export class Corporation { } } - getDividends(): number { - 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; - let upgrades = -0.15; + updateDividendTax(): void { + this.dividendTax = 1 - BitNodeMultipliers.CorporationSoftcap + 0.15; if (this.unlockUpgrades[5] === 1) { - upgrades += 0.05; + this.dividendTax -= 0.05; } if (this.unlockUpgrades[6] === 1) { - upgrades += 0.1; + this.dividendTax -= 0.1; } - return Math.pow(dividends, BitNodeMultipliers.CorporationSoftcap + upgrades); + } + + getCycleDividends(): 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; + return Math.pow(dividends, 1 - this.dividendTax); } determineValuation(): number { @@ -167,8 +171,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; @@ -277,11 +281,7 @@ 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; - } + this.updateDividendTax(); } //Levelable upgrades diff --git a/src/Corporation/ICorporation.ts b/src/Corporation/ICorporation.ts index 609204fee..b2ea08648 100644 --- a/src/Corporation/ICorporation.ts +++ b/src/Corporation/ICorporation.ts @@ -19,8 +19,8 @@ export interface ICorporation { shareSalesUntilPriceUpdate: number; shareSaleCooldown: number; issueNewSharesCooldown: number; - dividendPercentage: number; - dividendTaxPercentage: number; + dividendRate: number; + dividendTax: number; issuedShares: number; sharePrice: number; storedCycles: number; @@ -54,6 +54,7 @@ export interface ICorporation { getSalesMultiplier(): number; getScientificResearchMultiplier(): number; getStarterGuide(player: IPlayer): void; + updateDividendTax(): void; + getCycleDividends(): number; toJSON(): any; - getDividends(): 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..b6390aad3 100644 --- a/src/Corporation/ui/Overview.tsx +++ b/src/Corporation/ui/Overview.tsx @@ -275,17 +275,18 @@ 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; + const playerEarnings = corp.getCycleDividends() / CorporationConstants.SecsPerMarketCycle; return ( ], - ["Dividend Percentage:", numeralWrapper.format(corp.dividendPercentage / 100, "0%")], + ["Dividend Percentage:", numeralWrapper.format(corp.dividendRate, "0%")], ["Dividends per share:", ], - ["Your earnings as a shareholder:", ], + ["Your earnings as a shareholder:", ], ]} /> ); 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; diff --git a/src/NetscriptFunctions/Corporation.ts b/src/NetscriptFunctions/Corporation.ts index b6abb18e0..139bf8bfd 100644 --- a/src/NetscriptFunctions/Corporation.ts +++ b/src/NetscriptFunctions/Corporation.ts @@ -920,14 +920,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 @@ -954,6 +955,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.getCycleDividends() / 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 bfed1d166..4d35dacef 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -7053,9 +7053,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. @@ -7105,6 +7105,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 */