mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-22 15:43:49 +01:00
Merge pull request #1226 from threehams/corp-overview-perf
Stop remounting components on every render on corp overview
This commit is contained in:
commit
38cf4bd3cd
@ -63,7 +63,6 @@ module.exports = {
|
|||||||
"id-blacklist": ["error"],
|
"id-blacklist": ["error"],
|
||||||
"id-length": ["off"],
|
"id-length": ["off"],
|
||||||
"id-match": ["error"],
|
"id-match": ["error"],
|
||||||
"implicit-arrow-linebreak": ["error", "beside"],
|
|
||||||
indent: ["off"],
|
indent: ["off"],
|
||||||
"indent-legacy": ["off"],
|
"indent-legacy": ["off"],
|
||||||
"init-declarations": ["off"],
|
"init-declarations": ["off"],
|
||||||
|
@ -133,6 +133,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cmpy-mgmt-upgrade-div {
|
.cmpy-mgmt-upgrade-div {
|
||||||
|
text-align: left;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border: 1px solid #fff;
|
border: 1px solid #fff;
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
|
@ -40,9 +40,9 @@ export function LevelableUpgrade(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"cmpy-mgmt-upgrade-div tooltip"} style={{ width: "45%" }} onClick={onClick}>
|
<button className={"cmpy-mgmt-upgrade-div tooltip"} style={{ width: "45%" }} onClick={onClick}>
|
||||||
{text}
|
{text}
|
||||||
<span className={"tooltiptext"}>{tooltip}</span>
|
<span className={"tooltiptext"}>{tooltip}</span>
|
||||||
</div>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -27,330 +27,52 @@ interface IProps {
|
|||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
rerender: () => void;
|
rerender: () => void;
|
||||||
}
|
}
|
||||||
|
export function Overview({ corp, player, rerender }: IProps): React.ReactElement {
|
||||||
export function Overview(props: IProps): React.ReactElement {
|
const profit: number = corp.revenue.minus(corp.expenses).toNumber();
|
||||||
// Generic Function for Creating a button
|
|
||||||
interface ICreateButtonProps {
|
|
||||||
text: string;
|
|
||||||
class?: string;
|
|
||||||
className?: string;
|
|
||||||
display?: string;
|
|
||||||
tooltip?: string;
|
|
||||||
onClick?: (event: React.MouseEvent) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Button(props: ICreateButtonProps): React.ReactElement {
|
|
||||||
let className = props.className ? props.className : "std-button";
|
|
||||||
const hasTooltip = props.tooltip != null;
|
|
||||||
if (hasTooltip) className += " tooltip";
|
|
||||||
return (
|
|
||||||
<a className={className} onClick={props.onClick} style={{ display: props.display ? props.display : "block" }}>
|
|
||||||
{props.text}
|
|
||||||
{hasTooltip && <span className={"tooltiptext"}>{props.tooltip}</span>}
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function openBribeFactionPopup(): void {
|
|
||||||
const popupId = "corp-bribe-popup";
|
|
||||||
createPopup(popupId, BribeFactionPopup, {
|
|
||||||
player: props.player,
|
|
||||||
popupId: popupId,
|
|
||||||
corp: props.corp,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const profit: number = props.corp.revenue.minus(props.corp.expenses).toNumber();
|
|
||||||
|
|
||||||
function DividendsStats(): React.ReactElement {
|
|
||||||
if (props.corp.dividendPercentage <= 0 || profit <= 0) return <></>;
|
|
||||||
const totalDividends = (props.corp.dividendPercentage / 100) * profit;
|
|
||||||
const retainedEarnings = profit - totalDividends;
|
|
||||||
const dividendsPerShare = totalDividends / props.corp.totalShares;
|
|
||||||
const playerEarnings = props.corp.numShares * dividendsPerShare;
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
Retained Profits (after dividends): <Money money={retainedEarnings} /> / s<br />
|
|
||||||
<br />
|
|
||||||
Dividend Percentage: {numeralWrapper.format(props.corp.dividendPercentage / 100, "0%")}
|
|
||||||
<br />
|
|
||||||
Dividends per share: <Money money={dividendsPerShare} /> / s<br />
|
|
||||||
Your earnings as a shareholder (Pre-Tax): <Money money={playerEarnings} /> / s<br />
|
|
||||||
Dividend Tax Rate: {props.corp.dividendTaxPercentage}%<br />
|
|
||||||
Your earnings as a shareholder (Post-Tax):{" "}
|
|
||||||
<Money money={playerEarnings * (1 - props.corp.dividendTaxPercentage / 100)} /> / s<br />
|
|
||||||
<br />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Mult(props: { name: string; mult: number }): React.ReactElement {
|
|
||||||
if (props.mult <= 1) return <></>;
|
|
||||||
return (
|
|
||||||
<p>
|
|
||||||
{props.name}
|
|
||||||
{numeralWrapper.format(props.mult, "0.000")}
|
|
||||||
<br />
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a string with general information about Corporation
|
|
||||||
function BonusTime(): React.ReactElement {
|
|
||||||
const storedTime = props.corp.storedCycles * CONSTANTS.MilliPerCycle;
|
|
||||||
if (storedTime <= 15000) return <></>;
|
|
||||||
return (
|
|
||||||
<p>
|
|
||||||
Bonus time: {convertTimeMsToTimeElapsedString(storedTime)}
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function BribeButton(): React.ReactElement {
|
|
||||||
const canBribe = props.corp.determineValuation() >= CorporationConstants.BribeThreshold || true;
|
|
||||||
const bribeFactionsClass = canBribe ? "a-link-button" : "a-link-button-inactive";
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
className={bribeFactionsClass}
|
|
||||||
display="inline-block"
|
|
||||||
onClick={openBribeFactionPopup}
|
|
||||||
text="Bribe Factions"
|
|
||||||
tooltip={
|
|
||||||
canBribe
|
|
||||||
? "Use your Corporations power and influence to bribe Faction leaders in exchange for reputation"
|
|
||||||
: "Your Corporation is not powerful enough to bribe Faction leaders"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function openFindInvestorsPopup(): void {
|
|
||||||
const popupId = "cmpy-mgmt-find-investors-popup";
|
|
||||||
createPopup(popupId, FindInvestorsPopup, {
|
|
||||||
rerender: props.rerender,
|
|
||||||
player: props.player,
|
|
||||||
popupId: popupId,
|
|
||||||
corp: props.corp,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function openGoPublicPopup(): void {
|
|
||||||
const popupId = "cmpy-mgmt-go-public-popup";
|
|
||||||
createPopup(popupId, GoPublicPopup, {
|
|
||||||
rerender: props.rerender,
|
|
||||||
player: props.player,
|
|
||||||
popupId: popupId,
|
|
||||||
corp: props.corp,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render the buttons for when your Corporation is still private
|
|
||||||
function PrivateButtons(): React.ReactElement {
|
|
||||||
const fundingAvailable = props.corp.fundingRound < 4;
|
|
||||||
const findInvestorsClassName = fundingAvailable ? "std-button" : "a-link-button-inactive";
|
|
||||||
const findInvestorsTooltip = fundingAvailable
|
|
||||||
? "Search for private investors who will give you startup funding in exchangefor equity (stock shares) in your company"
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Button
|
|
||||||
className={findInvestorsClassName}
|
|
||||||
onClick={openFindInvestorsPopup}
|
|
||||||
text="Find Investors"
|
|
||||||
tooltip={findInvestorsTooltip}
|
|
||||||
display="inline-block"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
className="std-button"
|
|
||||||
onClick={openGoPublicPopup}
|
|
||||||
display="inline-block"
|
|
||||||
text="Go Public"
|
|
||||||
tooltip={
|
|
||||||
"Become a publicly traded and owned entity. Going public " +
|
|
||||||
"involves issuing shares for an IPO. Once you are a public " +
|
|
||||||
"company, your shares will be traded on the stock market."
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function openSellSharesPopup(): void {
|
|
||||||
const popupId = "cmpy-mgmt-sell-shares-popup";
|
|
||||||
createPopup(popupId, SellSharesPopup, {
|
|
||||||
corp: props.corp,
|
|
||||||
player: props.player,
|
|
||||||
popupId: popupId,
|
|
||||||
rerender: props.rerender,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function openBuybackSharesPopup(): void {
|
|
||||||
const popupId = "corp-buyback-shares-popup";
|
|
||||||
createPopup(popupId, BuybackSharesPopup, {
|
|
||||||
rerender: props.rerender,
|
|
||||||
player: props.player,
|
|
||||||
popupId: popupId,
|
|
||||||
corp: props.corp,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function openIssueNewSharesPopup(): void {
|
|
||||||
const popupId = "cmpy-mgmt-issue-new-shares-popup";
|
|
||||||
createPopup(popupId, IssueNewSharesPopup, {
|
|
||||||
popupId: popupId,
|
|
||||||
corp: props.corp,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function openIssueDividendsPopup(): void {
|
|
||||||
const popupId = "cmpy-mgmt-issue-dividends-popup";
|
|
||||||
createPopup(popupId, IssueDividendsPopup, {
|
|
||||||
popupId: popupId,
|
|
||||||
corp: props.corp,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render the buttons for when your Corporation has gone public
|
|
||||||
function PublicButtons(): React.ReactElement {
|
|
||||||
const corp = props.corp;
|
|
||||||
|
|
||||||
const sellSharesOnCd = corp.shareSaleCooldown > 0;
|
|
||||||
const sellSharesClass = sellSharesOnCd ? "a-link-button-inactive" : "std-button";
|
|
||||||
const sellSharesTooltip = sellSharesOnCd
|
|
||||||
? "Cannot sell shares for " + corp.convertCooldownToString(corp.shareSaleCooldown)
|
|
||||||
: "Sell your shares in the company. The money earned from selling your " +
|
|
||||||
"shares goes into your personal account, not the Corporation's. " +
|
|
||||||
"This is one of the only ways to profit from your business venture.";
|
|
||||||
|
|
||||||
const issueNewSharesOnCd = corp.issueNewSharesCooldown > 0;
|
|
||||||
const issueNewSharesClass = issueNewSharesOnCd ? "a-link-button-inactive" : "std-button";
|
|
||||||
const issueNewSharesTooltip = issueNewSharesOnCd
|
|
||||||
? "Cannot issue new shares for " + corp.convertCooldownToString(corp.issueNewSharesCooldown)
|
|
||||||
: "Issue new equity shares to raise capital.";
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Button
|
|
||||||
className={sellSharesClass}
|
|
||||||
display="inline-block"
|
|
||||||
onClick={openSellSharesPopup}
|
|
||||||
text="Sell Shares"
|
|
||||||
tooltip={sellSharesTooltip}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
className="std-button"
|
|
||||||
display="inline-block"
|
|
||||||
onClick={openBuybackSharesPopup}
|
|
||||||
text="Buyback shares"
|
|
||||||
tooltip="Buy back shares you that previously issued or sold at market price."
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<Button
|
|
||||||
className={issueNewSharesClass}
|
|
||||||
display="inline-block"
|
|
||||||
onClick={openIssueNewSharesPopup}
|
|
||||||
text="Issue New Shares"
|
|
||||||
tooltip={issueNewSharesTooltip}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
className="std-button"
|
|
||||||
display="inline-block"
|
|
||||||
onClick={openIssueDividendsPopup}
|
|
||||||
text="Issue Dividends"
|
|
||||||
tooltip="Manage the dividends that are paid out to shareholders (including yourself)"
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render the UI for Corporation upgrades
|
|
||||||
function Upgrades(): React.ReactElement {
|
|
||||||
// Don't show upgrades
|
|
||||||
if (props.corp.divisions.length <= 0) {
|
|
||||||
return <h1>Unlock upgrades after creating your first division</h1>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={"cmpy-mgmt-upgrade-container"}>
|
|
||||||
<h1 className={"cmpy-mgmt-upgrade-header"}> Unlocks </h1>
|
|
||||||
{Object.values(CorporationUnlockUpgrades)
|
|
||||||
.filter((upgrade: CorporationUnlockUpgrade) => props.corp.unlockUpgrades[upgrade[0]] === 0)
|
|
||||||
.map((upgrade: CorporationUnlockUpgrade) => (
|
|
||||||
<UnlockUpgrade
|
|
||||||
rerender={props.rerender}
|
|
||||||
player={props.player}
|
|
||||||
corp={props.corp}
|
|
||||||
upgradeData={upgrade}
|
|
||||||
key={upgrade[0]}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
|
|
||||||
<h1 className={"cmpy-mgmt-upgrade-header"}> Upgrades </h1>
|
|
||||||
{props.corp.upgrades
|
|
||||||
.map((level: number, i: number) => CorporationUpgrades[i])
|
|
||||||
.map((upgrade: CorporationUpgrade) => (
|
|
||||||
<LevelableUpgrade
|
|
||||||
rerender={props.rerender}
|
|
||||||
player={props.player}
|
|
||||||
corp={props.corp}
|
|
||||||
upgrade={upgrade}
|
|
||||||
key={upgrade[0]}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
Total Funds: <Money money={props.corp.funds.toNumber()} />
|
Total Funds: <Money money={corp.funds.toNumber()} />
|
||||||
<br />
|
<br />
|
||||||
Total Revenue: <Money money={props.corp.revenue.toNumber()} /> / s<br />
|
Total Revenue: <Money money={corp.revenue.toNumber()} /> / s<br />
|
||||||
Total Expenses: <Money money={props.corp.expenses.toNumber()} /> / s
|
Total Expenses: <Money money={corp.expenses.toNumber()} /> / s
|
||||||
<br />
|
<br />
|
||||||
Total Profits: <Money money={profit} /> / s<br />
|
Total Profits: <Money money={profit} /> / s<br />
|
||||||
<DividendsStats />
|
<DividendsStats corp={corp} profit={profit} />
|
||||||
Publicly Traded: {props.corp.public ? "Yes" : "No"}
|
Publicly Traded: {corp.public ? "Yes" : "No"}
|
||||||
<br />
|
<br />
|
||||||
Owned Stock Shares: {numeralWrapper.format(props.corp.numShares, "0.000a")}
|
Owned Stock Shares: {numeralWrapper.format(corp.numShares, "0.000a")}
|
||||||
<br />
|
<br />
|
||||||
Stock Price: {props.corp.public ? <Money money={props.corp.sharePrice} /> : "N/A"}
|
Stock Price: {corp.public ? <Money money={corp.sharePrice} /> : "N/A"}
|
||||||
<br />
|
<br />
|
||||||
</p>
|
</p>
|
||||||
<p className="tooltip">
|
<p className="tooltip">
|
||||||
Total Stock Shares: {numeralWrapper.format(props.corp.totalShares, "0.000a")}
|
Total Stock Shares: {numeralWrapper.format(corp.totalShares, "0.000a")}
|
||||||
<span className="tooltiptext">
|
<span className="tooltiptext">
|
||||||
Outstanding Shares: {numeralWrapper.format(props.corp.issuedShares, "0.000a")}
|
Outstanding Shares: {numeralWrapper.format(corp.issuedShares, "0.000a")}
|
||||||
<br />
|
<br />
|
||||||
Private Shares:{" "}
|
Private Shares: {numeralWrapper.format(corp.totalShares - corp.issuedShares - corp.numShares, "0.000a")}
|
||||||
{numeralWrapper.format(props.corp.totalShares - props.corp.issuedShares - props.corp.numShares, "0.000a")}
|
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<Mult name="Production Multiplier: " mult={props.corp.getProductionMultiplier()} />
|
<Mult name="Production Multiplier: " mult={corp.getProductionMultiplier()} />
|
||||||
<Mult name="Storage Multiplier: " mult={props.corp.getStorageMultiplier()} />
|
<Mult name="Storage Multiplier: " mult={corp.getStorageMultiplier()} />
|
||||||
<Mult name="Advertising Multiplier: " mult={props.corp.getAdvertisingMultiplier()} />
|
<Mult name="Advertising Multiplier: " mult={corp.getAdvertisingMultiplier()} />
|
||||||
<Mult name="Empl. Creativity Multiplier: " mult={props.corp.getEmployeeCreMultiplier()} />
|
<Mult name="Empl. Creativity Multiplier: " mult={corp.getEmployeeCreMultiplier()} />
|
||||||
<Mult name="Empl. Charisma Multiplier: " mult={props.corp.getEmployeeChaMultiplier()} />
|
<Mult name="Empl. Charisma Multiplier: " mult={corp.getEmployeeChaMultiplier()} />
|
||||||
<Mult name="Empl. Intelligence Multiplier: " mult={props.corp.getEmployeeIntMultiplier()} />
|
<Mult name="Empl. Intelligence Multiplier: " mult={corp.getEmployeeIntMultiplier()} />
|
||||||
<Mult name="Empl. Efficiency Multiplier: " mult={props.corp.getEmployeeEffMultiplier()} />
|
<Mult name="Empl. Efficiency Multiplier: " mult={corp.getEmployeeEffMultiplier()} />
|
||||||
<Mult name="Sales Multiplier: " mult={props.corp.getSalesMultiplier()} />
|
<Mult name="Sales Multiplier: " mult={corp.getSalesMultiplier()} />
|
||||||
<Mult name="Scientific Research Multiplier: " mult={props.corp.getScientificResearchMultiplier()} />
|
<Mult name="Scientific Research Multiplier: " mult={corp.getScientificResearchMultiplier()} />
|
||||||
<br />
|
<br />
|
||||||
<BonusTime />
|
<BonusTime corp={corp} />
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
className="a-link-button"
|
className="a-link-button"
|
||||||
display="inline-block"
|
display="inline-block"
|
||||||
onClick={() => props.corp.getStarterGuide(props.player)}
|
onClick={() => corp.getStarterGuide(player)}
|
||||||
text="Getting Started Guide"
|
text="Getting Started Guide"
|
||||||
tooltip={
|
tooltip={
|
||||||
"Get a copy of and read 'The Complete Handbook for Creating a Successful Corporation.' " +
|
"Get a copy of and read 'The Complete Handbook for Creating a Successful Corporation.' " +
|
||||||
@ -358,11 +80,307 @@ export function Overview(props: IProps): React.ReactElement {
|
|||||||
"provides some tips/pointers for helping you get started with managing it."
|
"provides some tips/pointers for helping you get started with managing it."
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{props.corp.public ? <PublicButtons /> : <PrivateButtons />}
|
{corp.public ? (
|
||||||
<BribeButton />
|
<PublicButtons corp={corp} player={player} rerender={rerender} />
|
||||||
|
) : (
|
||||||
|
<PrivateButtons corp={corp} player={player} rerender={rerender} />
|
||||||
|
)}
|
||||||
|
<BribeButton corp={corp} player={player} />
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<Upgrades />
|
<Upgrades corp={corp} player={player} rerender={rerender} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IPrivateButtonsProps {
|
||||||
|
corp: ICorporation;
|
||||||
|
player: IPlayer;
|
||||||
|
rerender: () => void;
|
||||||
|
}
|
||||||
|
// Render the buttons for when your Corporation is still private
|
||||||
|
function PrivateButtons({ corp, player, rerender }: IPrivateButtonsProps): React.ReactElement {
|
||||||
|
function openFindInvestorsPopup(): void {
|
||||||
|
const popupId = "cmpy-mgmt-find-investors-popup";
|
||||||
|
createPopup(popupId, FindInvestorsPopup, {
|
||||||
|
rerender,
|
||||||
|
player,
|
||||||
|
popupId,
|
||||||
|
corp: corp,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function openGoPublicPopup(): void {
|
||||||
|
const popupId = "cmpy-mgmt-go-public-popup";
|
||||||
|
createPopup(popupId, GoPublicPopup, {
|
||||||
|
rerender,
|
||||||
|
player,
|
||||||
|
popupId,
|
||||||
|
corp: corp,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const fundingAvailable = corp.fundingRound < 4;
|
||||||
|
const findInvestorsClassName = fundingAvailable ? "std-button" : "a-link-button-inactive";
|
||||||
|
const findInvestorsTooltip = fundingAvailable
|
||||||
|
? "Search for private investors who will give you startup funding in exchangefor equity (stock shares) in your company"
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
className={findInvestorsClassName}
|
||||||
|
onClick={openFindInvestorsPopup}
|
||||||
|
text="Find Investors"
|
||||||
|
tooltip={findInvestorsTooltip}
|
||||||
|
display="inline-block"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className="std-button"
|
||||||
|
onClick={openGoPublicPopup}
|
||||||
|
display="inline-block"
|
||||||
|
text="Go Public"
|
||||||
|
tooltip={
|
||||||
|
"Become a publicly traded and owned entity. Going public " +
|
||||||
|
"involves issuing shares for an IPO. Once you are a public " +
|
||||||
|
"company, your shares will be traded on the stock market."
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IUpgradeProps {
|
||||||
|
corp: ICorporation;
|
||||||
|
player: IPlayer;
|
||||||
|
rerender: () => void;
|
||||||
|
}
|
||||||
|
// Render the UI for Corporation upgrades
|
||||||
|
function Upgrades({ corp, player, rerender }: IUpgradeProps): React.ReactElement {
|
||||||
|
// Don't show upgrades
|
||||||
|
if (corp.divisions.length <= 0) {
|
||||||
|
return <h1>Unlock upgrades after creating your first division</h1>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={"cmpy-mgmt-upgrade-container"}>
|
||||||
|
<h1 className={"cmpy-mgmt-upgrade-header"}> Unlocks </h1>
|
||||||
|
{Object.values(CorporationUnlockUpgrades)
|
||||||
|
.filter((upgrade: CorporationUnlockUpgrade) => corp.unlockUpgrades[upgrade[0]] === 0)
|
||||||
|
.map((upgrade: CorporationUnlockUpgrade) => (
|
||||||
|
<UnlockUpgrade rerender={rerender} player={player} corp={corp} upgradeData={upgrade} key={upgrade[0]} />
|
||||||
|
))}
|
||||||
|
|
||||||
|
<h1 className={"cmpy-mgmt-upgrade-header"}> Upgrades </h1>
|
||||||
|
{corp.upgrades
|
||||||
|
.map((level: number, i: number) => CorporationUpgrades[i])
|
||||||
|
.map((upgrade: CorporationUpgrade) => (
|
||||||
|
<LevelableUpgrade rerender={rerender} player={player} corp={corp} upgrade={upgrade} key={upgrade[0]} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IPublicButtonsProps {
|
||||||
|
corp: ICorporation;
|
||||||
|
player: IPlayer;
|
||||||
|
rerender: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the buttons for when your Corporation has gone public
|
||||||
|
function PublicButtons({ corp, player, rerender }: IPublicButtonsProps): React.ReactElement {
|
||||||
|
const sellSharesOnCd = corp.shareSaleCooldown > 0;
|
||||||
|
const sellSharesClass = sellSharesOnCd ? "a-link-button-inactive" : "std-button";
|
||||||
|
const sellSharesTooltip = sellSharesOnCd
|
||||||
|
? "Cannot sell shares for " + corp.convertCooldownToString(corp.shareSaleCooldown)
|
||||||
|
: "Sell your shares in the company. The money earned from selling your " +
|
||||||
|
"shares goes into your personal account, not the Corporation's. " +
|
||||||
|
"This is one of the only ways to profit from your business venture.";
|
||||||
|
|
||||||
|
const issueNewSharesOnCd = corp.issueNewSharesCooldown > 0;
|
||||||
|
const issueNewSharesClass = issueNewSharesOnCd ? "a-link-button-inactive" : "std-button";
|
||||||
|
const issueNewSharesTooltip = issueNewSharesOnCd
|
||||||
|
? "Cannot issue new shares for " + corp.convertCooldownToString(corp.issueNewSharesCooldown)
|
||||||
|
: "Issue new equity shares to raise capital.";
|
||||||
|
|
||||||
|
function openSellSharesPopup(): void {
|
||||||
|
const popupId = "cmpy-mgmt-sell-shares-popup";
|
||||||
|
createPopup(popupId, SellSharesPopup, {
|
||||||
|
corp: corp,
|
||||||
|
player,
|
||||||
|
popupId,
|
||||||
|
rerender,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function openBuybackSharesPopup(): void {
|
||||||
|
const popupId = "corp-buyback-shares-popup";
|
||||||
|
createPopup(popupId, BuybackSharesPopup, {
|
||||||
|
rerender,
|
||||||
|
player,
|
||||||
|
popupId,
|
||||||
|
corp: corp,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function openIssueNewSharesPopup(): void {
|
||||||
|
const popupId = "cmpy-mgmt-issue-new-shares-popup";
|
||||||
|
createPopup(popupId, IssueNewSharesPopup, {
|
||||||
|
popupId,
|
||||||
|
corp: corp,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function openIssueDividendsPopup(): void {
|
||||||
|
const popupId = "cmpy-mgmt-issue-dividends-popup";
|
||||||
|
createPopup(popupId, IssueDividendsPopup, {
|
||||||
|
popupId,
|
||||||
|
corp: corp,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
className={sellSharesClass}
|
||||||
|
display="inline-block"
|
||||||
|
onClick={openSellSharesPopup}
|
||||||
|
text="Sell Shares"
|
||||||
|
tooltip={sellSharesTooltip}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className="std-button"
|
||||||
|
display="inline-block"
|
||||||
|
onClick={openBuybackSharesPopup}
|
||||||
|
text="Buyback shares"
|
||||||
|
tooltip="Buy back shares you that previously issued or sold at market price."
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<Button
|
||||||
|
className={issueNewSharesClass}
|
||||||
|
display="inline-block"
|
||||||
|
onClick={openIssueNewSharesPopup}
|
||||||
|
text="Issue New Shares"
|
||||||
|
tooltip={issueNewSharesTooltip}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className="std-button"
|
||||||
|
display="inline-block"
|
||||||
|
onClick={openIssueDividendsPopup}
|
||||||
|
text="Issue Dividends"
|
||||||
|
tooltip="Manage the dividends that are paid out to shareholders (including yourself)"
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic Function for Creating a button
|
||||||
|
interface ICreateButtonProps {
|
||||||
|
text: string;
|
||||||
|
className?: string;
|
||||||
|
display?: string;
|
||||||
|
tooltip?: string;
|
||||||
|
onClick?: (event: React.MouseEvent) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Button({ className = "std-button", text, display, tooltip, onClick }: ICreateButtonProps): React.ReactElement {
|
||||||
|
const hasTooltip = tooltip != null;
|
||||||
|
if (hasTooltip) className += " tooltip";
|
||||||
|
return (
|
||||||
|
<button className={className} onClick={onClick} style={{ display: display ? display : "block" }}>
|
||||||
|
{text}
|
||||||
|
{hasTooltip && <span className={"tooltiptext"}>{tooltip}</span>}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IBribeButtonProps {
|
||||||
|
player: IPlayer;
|
||||||
|
corp: ICorporation;
|
||||||
|
}
|
||||||
|
function BribeButton({ player, corp }: IBribeButtonProps): React.ReactElement {
|
||||||
|
function openBribeFactionPopup(): void {
|
||||||
|
const popupId = "corp-bribe-popup";
|
||||||
|
createPopup(popupId, BribeFactionPopup, {
|
||||||
|
player,
|
||||||
|
popupId,
|
||||||
|
corp: corp,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const canBribe = corp.determineValuation() >= CorporationConstants.BribeThreshold || true;
|
||||||
|
const bribeFactionsClass = canBribe ? "a-link-button" : "a-link-button-inactive";
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className={bribeFactionsClass}
|
||||||
|
display="inline-block"
|
||||||
|
onClick={openBribeFactionPopup}
|
||||||
|
text="Bribe Factions"
|
||||||
|
tooltip={
|
||||||
|
canBribe
|
||||||
|
? "Use your Corporations power and influence to bribe Faction leaders in exchange for reputation"
|
||||||
|
: "Your Corporation is not powerful enough to bribe Faction leaders"
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IDividendsStatsProps {
|
||||||
|
corp: ICorporation;
|
||||||
|
profit: number;
|
||||||
|
}
|
||||||
|
function DividendsStats({ corp, profit }: IDividendsStatsProps): React.ReactElement {
|
||||||
|
if (corp.dividendPercentage <= 0 || profit <= 0) return <></>;
|
||||||
|
const totalDividends = (corp.dividendPercentage / 100) * profit;
|
||||||
|
const retainedEarnings = profit - totalDividends;
|
||||||
|
const dividendsPerShare = totalDividends / corp.totalShares;
|
||||||
|
const playerEarnings = corp.numShares * dividendsPerShare;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
Retained Profits (after dividends): <Money money={retainedEarnings} /> / s
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Dividend Percentage: {numeralWrapper.format(corp.dividendPercentage / 100, "0%")}
|
||||||
|
<br />
|
||||||
|
Dividends per share: <Money money={dividendsPerShare} /> / s<br />
|
||||||
|
Your earnings as a shareholder (Pre-Tax): <Money money={playerEarnings} /> / s<br />
|
||||||
|
Dividend Tax Rate: {corp.dividendTaxPercentage}%<br />
|
||||||
|
Your earnings as a shareholder (Post-Tax):{" "}
|
||||||
|
<Money money={playerEarnings * (1 - corp.dividendTaxPercentage / 100)} /> / s<br />
|
||||||
|
<br />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IMultProps {
|
||||||
|
name: string;
|
||||||
|
mult: number;
|
||||||
|
}
|
||||||
|
function Mult({ name, mult }: IMultProps): React.ReactElement {
|
||||||
|
if (mult <= 1) return <></>;
|
||||||
|
return (
|
||||||
|
<p>
|
||||||
|
{name}
|
||||||
|
{numeralWrapper.format(mult, "0.000")}
|
||||||
|
<br />
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IBonusTimeProps {
|
||||||
|
corp: ICorporation;
|
||||||
|
}
|
||||||
|
// Returns a string with general information about Corporation
|
||||||
|
function BonusTime({ corp }: IBonusTimeProps): React.ReactElement {
|
||||||
|
const storedTime = corp.storedCycles * CONSTANTS.MilliPerCycle;
|
||||||
|
if (storedTime <= 15000) return <></>;
|
||||||
|
return (
|
||||||
|
<p>
|
||||||
|
Bonus time: {convertTimeMsToTimeElapsedString(storedTime)}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -34,9 +34,9 @@ export function UnlockUpgrade(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"cmpy-mgmt-upgrade-div tooltip"} style={{ width: "45%" }} onClick={onClick}>
|
<button className={"cmpy-mgmt-upgrade-div tooltip"} style={{ width: "45%" }} onClick={onClick}>
|
||||||
{text}
|
{text}
|
||||||
<span className={"tooltiptext"}>{tooltip}</span>
|
<span className={"tooltiptext"}>{tooltip}</span>
|
||||||
</div>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user