mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-26 01:23:49 +01:00
NETSCRIPT: Added ns.corporation.issueNewShares function (#261)
This commit is contained in:
parent
556fe8dd33
commit
5c80655d62
@ -16,6 +16,7 @@ import { ResearchMap } from "./ResearchMap";
|
||||
import { isRelevantMaterial } from "./ui/Helpers";
|
||||
import { checkEnum } from "../utils/helpers/enum";
|
||||
import { CityName } from "../Locations/data/CityNames";
|
||||
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
||||
|
||||
export function NewIndustry(corporation: Corporation, industry: IndustryType, name: string): void {
|
||||
if (corporation.divisions.find(({ type }) => industry == type))
|
||||
@ -90,6 +91,33 @@ export function IssueDividends(corporation: Corporation, rate: number): void {
|
||||
corporation.dividendRate = rate;
|
||||
}
|
||||
|
||||
export function IssueNewShares(corporation: Corporation, amount: number): [number, number, number] {
|
||||
const max = corporation.calculateMaxNewShares();
|
||||
|
||||
// Round to nearest ten-millionth
|
||||
amount = Math.round(amount / 10e6) * 10e6;
|
||||
|
||||
if (isNaN(amount) || amount < 10e6 || amount > max) {
|
||||
throw new Error(`Invalid value. Must be an number between 10m and ${max} (20% of total shares)`);
|
||||
}
|
||||
|
||||
const newSharePrice = Math.round(corporation.sharePrice * 0.9);
|
||||
|
||||
const profit = amount * newSharePrice;
|
||||
corporation.issueNewSharesCooldown = CorporationConstants.IssueNewSharesCooldown;
|
||||
|
||||
const privateOwnedRatio = 1 - (corporation.numShares + corporation.issuedShares) / corporation.totalShares;
|
||||
const maxPrivateShares = Math.round((amount / 2) * privateOwnedRatio);
|
||||
const privateShares = Math.round(getRandomInt(0, maxPrivateShares) / 10e6) * 10e6;
|
||||
|
||||
corporation.issuedShares += amount - privateShares;
|
||||
corporation.totalShares += amount;
|
||||
corporation.funds = corporation.funds + profit;
|
||||
corporation.immediatelyUpdateSharePrice();
|
||||
|
||||
return [profit, amount, privateShares];
|
||||
}
|
||||
|
||||
export function SellMaterial(mat: Material, amt: string, price: string): void {
|
||||
if (price === "") price = "0";
|
||||
if (amt === "") amt = "0";
|
||||
|
@ -225,6 +225,12 @@ export class Corporation {
|
||||
this.sharePrice = this.getTargetSharePrice();
|
||||
}
|
||||
|
||||
calculateMaxNewShares(): number {
|
||||
const maxNewSharesUnrounded = Math.round(this.totalShares * 0.2);
|
||||
const maxNewShares = maxNewSharesUnrounded - (maxNewSharesUnrounded % 10e6);
|
||||
return maxNewShares;
|
||||
}
|
||||
|
||||
// Calculates how much money will be made and what the resulting stock price
|
||||
// will be when the player sells his/her shares
|
||||
// @return - [Player profit, final stock price, end shareSalesUntilPriceUpdate property]
|
||||
|
@ -2,13 +2,12 @@ import React, { useState } from "react";
|
||||
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||
import { dialogBoxCreate } from "../../../ui/React/DialogBox";
|
||||
import { Modal } from "../../../ui/React/Modal";
|
||||
import { getRandomInt } from "../../../utils/helpers/getRandomInt";
|
||||
import { CorporationConstants } from "../../data/Constants";
|
||||
import { useCorporation } from "../Context";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { NumberInput } from "../../../ui/React/NumberInput";
|
||||
import Button from "@mui/material/Button";
|
||||
import { KEY } from "../../../utils/helpers/keyCodes";
|
||||
import { IssueNewShares } from "../../Actions";
|
||||
|
||||
interface IEffectTextProps {
|
||||
shares: number | null;
|
||||
@ -18,8 +17,7 @@ function EffectText(props: IEffectTextProps): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
if (props.shares === null) return <></>;
|
||||
const newSharePrice = Math.round(corp.sharePrice * 0.9);
|
||||
const maxNewSharesUnrounded = Math.round(corp.totalShares * 0.2);
|
||||
const maxNewShares = maxNewSharesUnrounded - (maxNewSharesUnrounded % 1e6);
|
||||
const maxNewShares = corp.calculateMaxNewShares();
|
||||
let newShares = props.shares;
|
||||
if (isNaN(newShares)) {
|
||||
return <Typography>Invalid input</Typography>;
|
||||
@ -55,8 +53,7 @@ interface IProps {
|
||||
export function IssueNewSharesModal(props: IProps): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const [shares, setShares] = useState<number>(NaN);
|
||||
const maxNewSharesUnrounded = Math.round(corp.totalShares * 0.2);
|
||||
const maxNewShares = maxNewSharesUnrounded - (maxNewSharesUnrounded % 1e6);
|
||||
const maxNewShares = corp.calculateMaxNewShares();
|
||||
|
||||
const newShares = Math.round((shares || 0) / 10e6) * 10e6;
|
||||
const disabled = isNaN(shares) || isNaN(newShares) || newShares < 10e6 || newShares > maxNewShares;
|
||||
@ -64,27 +61,8 @@ export function IssueNewSharesModal(props: IProps): React.ReactElement {
|
||||
function issueNewShares(): void {
|
||||
if (isNaN(shares)) return;
|
||||
if (disabled) return;
|
||||
const [profit, newShares, privateShares] = IssueNewShares(corp, shares);
|
||||
|
||||
const newSharePrice = Math.round(corp.sharePrice * 0.9);
|
||||
let newShares = shares;
|
||||
|
||||
// Round to nearest ten-millionth
|
||||
newShares = Math.round(newShares / 10e6) * 10e6;
|
||||
|
||||
const profit = newShares * newSharePrice;
|
||||
corp.issueNewSharesCooldown = CorporationConstants.IssueNewSharesCooldown;
|
||||
|
||||
// Determine how many are bought by private investors
|
||||
// If private investors own n% of the company, private investors get up to 0.5n% at most
|
||||
// Round # of private shares to the nearest million
|
||||
const privateOwnedRatio = 1 - (corp.numShares + corp.issuedShares) / corp.totalShares;
|
||||
const maxPrivateShares = Math.round((newShares / 2) * privateOwnedRatio);
|
||||
const privateShares = Math.round(getRandomInt(0, maxPrivateShares) / 1e6) * 1e6;
|
||||
|
||||
corp.issuedShares += newShares - privateShares;
|
||||
corp.totalShares += newShares;
|
||||
corp.funds = corp.funds + profit;
|
||||
corp.immediatelyUpdateSharePrice();
|
||||
props.onClose();
|
||||
|
||||
let dialogContents =
|
||||
|
@ -373,6 +373,7 @@ const corporation = {
|
||||
unlockUpgrade: 0,
|
||||
levelUpgrade: 0,
|
||||
issueDividends: 0,
|
||||
issueNewShares: 0,
|
||||
buyBackShares: 0,
|
||||
sellShares: 0,
|
||||
getBonusTime: 0,
|
||||
|
@ -24,6 +24,7 @@ import {
|
||||
UnlockUpgrade,
|
||||
LevelUpgrade,
|
||||
IssueDividends,
|
||||
IssueNewShares,
|
||||
SellMaterial,
|
||||
SellProduct,
|
||||
SetSmartSupply,
|
||||
@ -820,6 +821,21 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
||||
if (!corporation.public) throw helpers.makeRuntimeErrorMsg(ctx, `Your company has not gone public!`);
|
||||
IssueDividends(corporation, rate);
|
||||
},
|
||||
issueNewShares: (ctx) => (_amount) => {
|
||||
checkAccess(ctx);
|
||||
const corporation = getCorporation();
|
||||
const maxNewShares = corporation.calculateMaxNewShares();
|
||||
if (_amount == undefined) _amount = maxNewShares;
|
||||
const amount = helpers.number(ctx, "amount", _amount);
|
||||
if (corporation.issueNewSharesCooldown > 0) throw new Error(`Can't issue new shares, action on cooldown.`);
|
||||
if (amount < 10e6 || amount > maxNewShares)
|
||||
throw new Error(
|
||||
`Invalid value for amount field! Must be numeric, greater than 10m, and less than ${maxNewShares} (20% of total shares)`,
|
||||
);
|
||||
if (!corporation.public) throw helpers.makeRuntimeErrorMsg(ctx, `Your company has not gone public!`);
|
||||
const [funds] = IssueNewShares(corporation, amount);
|
||||
return funds;
|
||||
},
|
||||
getDivision: (ctx) => (_divisionName) => {
|
||||
checkAccess(ctx);
|
||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||
|
5
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
5
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -7545,6 +7545,11 @@ export interface Corporation extends WarehouseAPI, OfficeAPI {
|
||||
* @param rate - Fraction of profit to issue as dividends. */
|
||||
issueDividends(rate: number): void;
|
||||
|
||||
/** Issue new shares
|
||||
* @param amount - Number of new shares to issue, will be rounded to nearest 10m. Defaults to max amount.
|
||||
* @returns Amount of funds generated for the corporation. */
|
||||
issueNewShares(amount?: number): number;
|
||||
|
||||
/** Buyback Shares
|
||||
* @param amount - Amount of shares to buy back. */
|
||||
buyBackShares(amount: number): void;
|
||||
|
Loading…
Reference in New Issue
Block a user