Rework faction augs menu

This commit is contained in:
Olivier Gagnon
2021-09-20 20:42:13 -04:00
parent 74906cc9e6
commit 9e62438b43
10 changed files with 764 additions and 578 deletions

View File

@ -1,360 +0,0 @@
import { IMap } from "../types";
/**
* Contains the "information" property for all the Factions, which is just a description of each faction
*/
export class FactionInfo {
/**
* The multiplier to apply to augmentation base purchase price.
*/
augmentationPriceMult: number;
/**
* The multiplier to apply to augmentation reputation base requirement.
*/
augmentationRepRequirementMult: number;
/**
* The names of all other factions considered to be enemies to this faction.
*/
enemies: string[];
/**
* The descriptive text to show on the faction's page.
*/
infoText: string;
/**
* A flag indicating if the faction supports field work to earn reputation.
*/
offerFieldWork: boolean;
/**
* A flag indicating if the faction supports hacking missions to earn reputation.
*/
offerHackingMission: boolean;
/**
* A flag indicating if the faction supports hacking work to earn reputation.
*/
offerHackingWork: boolean;
/**
* A flag indicating if the faction supports security work to earn reputation.
*/
offerSecurityWork: boolean;
constructor(
infoText: string,
enemies: string[],
offerHackingMission: boolean,
offerHackingWork: boolean,
offerFieldWork: boolean,
offerSecurityWork: boolean,
) {
this.infoText = infoText;
this.enemies = enemies;
this.offerHackingMission = offerHackingMission;
this.offerHackingWork = offerHackingWork;
this.offerFieldWork = offerFieldWork;
this.offerSecurityWork = offerSecurityWork;
// These are always all 1 for now.
this.augmentationPriceMult = 1;
this.augmentationRepRequirementMult = 1;
}
offersWork(): boolean {
return this.offerFieldWork || this.offerHackingMission || this.offerHackingWork || this.offerSecurityWork;
}
}
/**
* A map of all factions and associated info to them.
*/
// tslint:disable-next-line:variable-name
export const FactionInfos: IMap<FactionInfo> = {
// Endgame
Illuminati: new FactionInfo(
"Humanity never changes. No matter how civilized society becomes, it will eventually fall back into chaos. " +
"And from this chaos, we are the invisible hand that guides them to order. ",
[],
true,
true,
true,
false,
),
Daedalus: new FactionInfo(
"Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.",
[],
true,
true,
true,
false,
),
"The Covenant": new FactionInfo(
"Surrender yourself. Give up your empty individuality to become part of something great, something eternal. " +
"Become a slave. Submit your mind, body, and soul. Only then can you set yourself free.<br>" +
"<br>" +
"Only then can you discover immortality.",
[],
true,
true,
true,
false,
),
// Megacorporations, each forms its own faction
ECorp: new FactionInfo(
"ECorp's mission is simple: to connect the world of today with the technology of tomorrow. With our wide " +
"range of Internet-related software and commercial hardware, ECorp makes the world's information " +
"universally accessible.",
[],
true,
true,
true,
true,
),
MegaCorp: new FactionInfo(
"MegaCorp does what no other dares to do. We imagine. We create. We invent. We create what others have " +
"never even dreamed of. Our work fills the world's needs for food, water, power, and transporation on an " +
"unprecendented scale, in ways that no other company can.<br>" +
"<br>" +
"In our labs and factories and on the ground with customers, MegaCorp is ushering in a new era for the world.",
[],
true,
true,
true,
true,
),
"Bachman & Associates": new FactionInfo(
"Where Law and Business meet - thats where we are.<br>" +
"<br>" +
"Legal Insight - Business Instinct - Innovative Experience.",
[],
true,
true,
true,
true,
),
"Blade Industries": new FactionInfo("Augmentation is Salvation.", [], true, true, true, true),
NWO: new FactionInfo(
"Humans don't truly desire freedom. They want to be observed, understood, and judged. They want to " +
"be given purpose and direction in life. That is why they created God. And that is why they created " +
"civilization - not because of willingness, but because of a need to be incorporated into higher orders of " +
"structure and meaning.",
[],
true,
true,
true,
true,
),
"Clarke Incorporated": new FactionInfo("The Power of the Genome - Unlocked.", [], true, true, true, true),
"OmniTek Incorporated": new FactionInfo(
"Simply put, our mission is to design and build robots that make a difference.",
[],
true,
true,
true,
true,
),
"Four Sigma": new FactionInfo(
"The scientific method is the best way to approach investing. Big strategies backed up with big data. Driven " +
"by deep learning and innovative ideas. And improved by iteration. That's Four Sigma.",
[],
true,
true,
true,
true,
),
"KuaiGong International": new FactionInfo("Dream big. Work hard. Make history.", [], true, true, true, true),
// Other Corporations
"Fulcrum Secret Technologies": new FactionInfo(
"The human organism has an innate desire to worship. That is why they created gods. If there were no gods, it " +
"would be necessary to create them. And now we can.",
[],
true,
true,
false,
true,
),
// Hacker groups
BitRunners: new FactionInfo(
"Our entire lives are controlled by bits. All of our actions, our thoughts, our personal information. It's " +
"all transformed into bits, stored in bits, communicated through bits. Its impossible for any person to move, " +
"to live, to operate at any level without the use of bits. And when a person moves, lives, and operates, they " +
"leave behind their bits, mere traces of seemingly meaningless fragments of information. But these bits can be " +
"reconstructed. Transformed. Used.<br>" +
"<br>" +
"Those who run the bits, run the world.",
[],
true,
true,
false,
false,
),
"The Black Hand": new FactionInfo(
"The world, so afraid of strong government, now has no government. Only power - Digital power. Financial " +
"power. Technological power. And those at the top rule with an invisible hand. They built a society where the " +
"rich get richer, and everyone else suffers.<br>" +
"<br>" +
"So much pain. So many lives. Their darkness must end.",
[],
true,
true,
true,
false,
),
NiteSec: new FactionInfo(
" __..__ <br>" +
" _.nITESECNIt. <br>" +
" .-'NITESECNITESEc. <br>" +
" .' NITESECNITESECn <br>" +
" / NITESECNITESEC; <br>" +
" : :NITESECNITESEC; <br>" +
" ; $ NITESECNITESECN <br>" +
" : _, ,N'ITESECNITESEC <br>" +
" : .+^^`, : `NITESECNIT <br>" +
" ) /), `-,-=,NITESECNI <br>" +
" / ^ ,-;|NITESECN; <br>" +
" / _.' '-';NITESECN <br>" +
" ( , ,-''`^NITE' <br>" +
" )` :`. .' <br>" +
" )-- ; `- / <br>" +
" ' _.-' : <br>" +
" ( _.-' . <br>" +
" ------. <br>" +
" . <br>" +
" _.nIt <br>" +
" _.nITESECNi <br>" +
" nITESECNIT^' <br>" +
" NITE^' ___ <br>" +
" / .gP''''Tp. <br>" +
" : d' . `b <br>" +
" ; d' o `b ; <br>" +
" / d; `b| <br>" +
" /, $; @ `: <br>" +
" /' $$ ; <br>" +
" .' $$b o | <br>" +
" .' d$$$; : <br>" +
" / .d$$$$; , ; <br>" +
" d .dNITESEC $ | <br>" +
" :bp.__.gNITESEC$$ :$ ; <br>" +
" NITESECNITESECNIT $$b : <br>",
[],
true,
true,
false,
false,
),
// City factions, essentially governments
Aevum: new FactionInfo("The Silicon City.", ["Chongqing", "New Tokyo", "Ishima", "Volhaven"], true, true, true, true),
Chongqing: new FactionInfo("Serve the People.", ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
Ishima: new FactionInfo(
"The East Asian Order of the Future.",
["Sector-12", "Aevum", "Volhaven"],
true,
true,
true,
true,
),
"New Tokyo": new FactionInfo("Asia's World City.", ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
"Sector-12": new FactionInfo(
"The City of the Future.",
["Chongqing", "New Tokyo", "Ishima", "Volhaven"],
true,
true,
true,
true,
),
Volhaven: new FactionInfo(
"Benefit, Honor, and Glory.",
["Chongqing", "Sector-12", "New Tokyo", "Aevum", "Ishima"],
true,
true,
true,
true,
),
// Criminal Organizations/Gangs
"Speakers for the Dead": new FactionInfo(
"It is better to reign in Hell than to serve in Heaven.",
[],
true,
true,
true,
true,
),
"The Dark Army": new FactionInfo(
"The World doesn't care about right or wrong. It only cares about power.",
[],
true,
true,
true,
false,
),
"The Syndicate": new FactionInfo("Honor holds you back.", [], true, true, true, true),
Silhouette: new FactionInfo(
"Corporations have filled the void of power left behind by the collapse of Western government. The issue is " +
"they've become so big that you don't know who they're working for. And if you're employed at one of these " +
"corporations, you don't even know who you're working for.<br>" +
"<br>" +
"That's terror. Terror, fear, and corruption. All born into the system, all propagated by the system.",
[],
true,
true,
true,
false,
),
Tetrads: new FactionInfo("Following the mandate of Heaven and carrying out the way.", [], false, false, true, true),
"Slum Snakes": new FactionInfo("Slum Snakes rule!", [], false, false, true, true),
// Earlygame factions - factions the player will prestige with early on that don't belong in other categories.
Netburners: new FactionInfo("~~//*>H4CK||3T 8URN3R5**>?>\\~~", [], true, true, false, false),
"Tian Di Hui": new FactionInfo("Obey Heaven and work righteously.", [], true, true, false, true),
CyberSec: new FactionInfo(
"The Internet is the first thing that was built that we don't fully understand, the largest " +
"experiment in anarchy that we have ever had. And as the world becomes increasingly dominated by it, " +
"society approaches the brink of total chaos. We serve only to protect society, to protect humanity, to " +
"protect the world from imminent collapse.",
[],
true,
true,
false,
false,
),
// Special Factions
Bladeburners: new FactionInfo(
"It's too bad they won't live. But then again, who does?<br><br>Note that for this faction, reputation can " +
"only be gained through Bladeburner actions. Completing Bladeburner contracts/operations will increase your " +
"reputation.",
[],
false,
false,
false,
false,
),
};

433
src/Faction/FactionInfo.tsx Normal file
View File

@ -0,0 +1,433 @@
import React from "react";
import { IMap } from "../types";
/**
* Contains the "information" property for all the Factions, which is just a description of each faction
*/
export class FactionInfo {
/**
* The multiplier to apply to augmentation base purchase price.
*/
augmentationPriceMult: number;
/**
* The multiplier to apply to augmentation reputation base requirement.
*/
augmentationRepRequirementMult: number;
/**
* The names of all other factions considered to be enemies to this faction.
*/
enemies: string[];
/**
* The descriptive text to show on the faction's page.
*/
infoText: JSX.Element;
/**
* A flag indicating if the faction supports field work to earn reputation.
*/
offerFieldWork: boolean;
/**
* A flag indicating if the faction supports hacking missions to earn reputation.
*/
offerHackingMission: boolean;
/**
* A flag indicating if the faction supports hacking work to earn reputation.
*/
offerHackingWork: boolean;
/**
* A flag indicating if the faction supports security work to earn reputation.
*/
offerSecurityWork: boolean;
constructor(
infoText: JSX.Element,
enemies: string[],
offerHackingMission: boolean,
offerHackingWork: boolean,
offerFieldWork: boolean,
offerSecurityWork: boolean,
) {
this.infoText = infoText;
this.enemies = enemies;
this.offerHackingMission = offerHackingMission;
this.offerHackingWork = offerHackingWork;
this.offerFieldWork = offerFieldWork;
this.offerSecurityWork = offerSecurityWork;
// These are always all 1 for now.
this.augmentationPriceMult = 1;
this.augmentationRepRequirementMult = 1;
}
offersWork(): boolean {
return this.offerFieldWork || this.offerHackingMission || this.offerHackingWork || this.offerSecurityWork;
}
}
/**
* A map of all factions and associated info to them.
*/
// tslint:disable-next-line:variable-name
export const FactionInfos: IMap<FactionInfo> = {
// Endgame
Illuminati: new FactionInfo(
(
<>
Humanity never changes. No matter how civilized society becomes, it will eventually fall back into chaos. And
from this chaos, we are the invisible hand that guides them to order.{" "}
</>
),
[],
true,
true,
true,
false,
),
Daedalus: new FactionInfo(
<>Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.</>,
[],
true,
true,
true,
false,
),
"The Covenant": new FactionInfo(
(
<>
Surrender yourself. Give up your empty individuality to become part of something great, something eternal.
Become a slave. Submit your mind, body, and soul. Only then can you set yourself free.
<br />
<br />
Only then can you discover immortality.
</>
),
[],
true,
true,
true,
false,
),
// Megacorporations, each forms its own faction
ECorp: new FactionInfo(
(
<>
ECorp's mission is simple: to connect the world of today with the technology of tomorrow. With our wide range of
Internet-related software and commercial hardware, ECorp makes the world's information universally accessible.
</>
),
[],
true,
true,
true,
true,
),
MegaCorp: new FactionInfo(
(
<>
MegaCorp does what no other dares to do. We imagine. We create. We invent. We create what others have never even
dreamed of. Our work fills the world's needs for food, water, power, and transporation on an unprecendented
scale, in ways that no other company can.
<br />
<br />
In our labs and factories and on the ground with customers, MegaCorp is ushering in a new era for the world.
</>
),
[],
true,
true,
true,
true,
),
"Bachman & Associates": new FactionInfo(
(
<>
Where Law and Business meet - thats where we are.
<br />
<br />
Legal Insight - Business Instinct - Innovative Experience.
</>
),
[],
true,
true,
true,
true,
),
"Blade Industries": new FactionInfo(<>Augmentation is Salvation.</>, [], true, true, true, true),
NWO: new FactionInfo(
(
<>
Humans don't truly desire freedom. They want to be observed, understood, and judged. They want to be given
purpose and direction in life. That is why they created God. And that is why they created civilization - not
because of willingness, but because of a need to be incorporated into higher orders of structure and meaning.
</>
),
[],
true,
true,
true,
true,
),
"Clarke Incorporated": new FactionInfo(<>The Power of the Genome - Unlocked.</>, [], true, true, true, true),
"OmniTek Incorporated": new FactionInfo(
<>Simply put, our mission is to design and build robots that make a difference.</>,
[],
true,
true,
true,
true,
),
"Four Sigma": new FactionInfo(
(
<>
The scientific method is the best way to approach investing. Big strategies backed up with big data. Driven by
deep learning and innovative ideas. And improved by iteration. That's Four Sigma.
</>
),
[],
true,
true,
true,
true,
),
"KuaiGong International": new FactionInfo(<>Dream big. Work hard. Make history.</>, [], true, true, true, true),
// Other Corporations
"Fulcrum Secret Technologies": new FactionInfo(
(
<>
The human organism has an innate desire to worship. That is why they created gods. If there were no gods, it
would be necessary to create them. And now we can.
</>
),
[],
true,
true,
false,
true,
),
// Hacker groups
BitRunners: new FactionInfo(
(
<>
Our entire lives are controlled by bits. All of our actions, our thoughts, our personal information. It's all
transformed into bits, stored in bits, communicated through bits. Its impossible for any person to move, to
live, to operate at any level without the use of bits. And when a person moves, lives, and operates, they leave
behind their bits, mere traces of seemingly meaningless fragments of information. But these bits can be
reconstructed. Transformed. Used.
<br />
<br />
Those who run the bits, run the world.
</>
),
[],
true,
true,
false,
false,
),
"The Black Hand": new FactionInfo(
(
<>
The world, so afraid of strong government, now has no government. Only power - Digital power. Financial power.
Technological power. And those at the top rule with an invisible hand. They built a society where the rich get
richer, and everyone else suffers.
<br />
<br />
So much pain. So many lives. Their darkness must end.
</>
),
[],
true,
true,
true,
false,
),
// prettier-ignore
NiteSec: new FactionInfo(<>
{" __..__ "}<br />
{" _.nITESECNIt. "}<br />
{" .-'NITESECNITESEc. "}<br />
{" .' NITESECNITESECn "}<br />
{" / NITESECNITESEC; "}<br />
{" : :NITESECNITESEC; "}<br />
{" ; $ NITESECNITESECN "}<br />
{" : _, ,N'ITESECNITESEC "}<br />
{" : .+^^`, : `NITESECNIT "}<br />
{" ) /), `-,-=,NITESECNI "}<br />
{" / ^ ,-;|NITESECN; "}<br />
{" / _.' '-';NITESECN "}<br />
{" ( , ,-''`^NITE' "}<br />
{" )` :`. .' "}<br />
{" )-- ; `- / "}<br />
{" ' _.-' : "}<br />
{" ( _.-' . "}<br />
{" ------. "}<br />
{" . "}<br />
{" _.nIt "}<br />
{" _.nITESECNi "}<br />
{" nITESECNIT^' "}<br />
{" NITE^' ___ "}<br />
{" / .gP''''Tp. "}<br />
{" : d' . `b "}<br />
{" ; d' o `b ; "}<br />
{" / d; `b| "}<br />
{" /, $; @ `: "}<br />
{" /' $$ ; "}<br />
{" .' $$b o | "}<br />
{" .' d$$$; : "}<br />
{" / .d$$$$; , ; "}<br />
{" d .dNITESEC $ | "}<br />
{" :bp.__.gNITESEC$$ :$ ; "}<br />
{" NITESECNITESECNIT $$b : "}<br /></>,
[],
true,
true,
false,
false,
),
// City factions, essentially governments
Aevum: new FactionInfo(
<>The Silicon City.</>,
["Chongqing", "New Tokyo", "Ishima", "Volhaven"],
true,
true,
true,
true,
),
Chongqing: new FactionInfo(<>Serve the People.</>, ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
Ishima: new FactionInfo(
<>The East Asian Order of the Future.</>,
["Sector-12", "Aevum", "Volhaven"],
true,
true,
true,
true,
),
"New Tokyo": new FactionInfo(<>Asia's World City.</>, ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
"Sector-12": new FactionInfo(
<>The City of the Future.</>,
["Chongqing", "New Tokyo", "Ishima", "Volhaven"],
true,
true,
true,
true,
),
Volhaven: new FactionInfo(
<>Benefit, Honor, and Glory.</>,
["Chongqing", "Sector-12", "New Tokyo", "Aevum", "Ishima"],
true,
true,
true,
true,
),
// Criminal Organizations/Gangs
"Speakers for the Dead": new FactionInfo(
<>It is better to reign in Hell than to serve in Heaven.</>,
[],
true,
true,
true,
true,
),
"The Dark Army": new FactionInfo(
<>The World doesn't care about right or wrong. It only cares about power.</>,
[],
true,
true,
true,
false,
),
"The Syndicate": new FactionInfo(<>Honor holds you back.</>, [], true, true, true, true),
Silhouette: new FactionInfo(
(
<>
Corporations have filled the void of power left behind by the collapse of Western government. The issue is
they've become so big that you don't know who they're working for. And if you're employed at one of these
corporations, you don't even know who you're working for.
<br />
<br />
That's terror. Terror, fear, and corruption. All born into the system, all propagated by the system.
</>
),
[],
true,
true,
true,
false,
),
Tetrads: new FactionInfo(
<>Following the mandate of Heaven and carrying out the way.</>,
[],
false,
false,
true,
true,
),
"Slum Snakes": new FactionInfo(<>Slum Snakes rule!</>, [], false, false, true, true),
// Earlygame factions - factions the player will prestige with early on that don't belong in other categories.
Netburners: new FactionInfo(<>{"~~//*>H4CK||3T 8URN3R5**>?>\\~~"}</>, [], true, true, false, false),
"Tian Di Hui": new FactionInfo(<>Obey Heaven and work righteously.</>, [], true, true, false, true),
CyberSec: new FactionInfo(
(
<>
The Internet is the first thing that was built that we don't fully understand, the largest experiment in anarchy
that we have ever had. And as the world becomes increasingly dominated by it, society approaches the brink of
total chaos. We serve only to protect society, to protect humanity, to protect the world from imminent collapse.
</>
),
[],
true,
true,
false,
false,
),
// Special Factions
Bladeburners: new FactionInfo(
(
<>
It's too bad they won't live. But then again, who does?
<br />
<br />
Note that for this faction, reputation can only be gained through Bladeburner actions. Completing Bladeburner
contracts/operations will increase your reputation.
</>
),
[],
false,
false,
false,
false,
),
};

View File

@ -14,6 +14,11 @@ import { Settings } from "../../Settings/Settings";
import { StdButton } from "../../ui/React/StdButton";
import { use } from "../../ui/Context";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import TableBody from "@mui/material/TableBody";
import Table from "@mui/material/Table";
type IProps = {
faction: Faction;
routeToMainPage: () => void;
@ -31,6 +36,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
}
function getAugs(): string[] {
console.log(props.faction.augmentations);
if (isPlayersGang) {
const augs: string[] = [];
for (const augName in Augmentations) {
@ -104,8 +110,17 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
(!player.augmentations.some((a) => a.name === aug) && !player.queuedAugmentations.some((a) => a.name === aug)),
);
const purchaseableAugmentation = (aug: string): React.ReactNode => {
return <PurchaseableAugmentation augName={aug} faction={props.faction} key={aug} p={player} rerender={rerender} />;
const purchaseableAugmentation = (aug: string, owned = false): React.ReactNode => {
return (
<PurchaseableAugmentation
augName={aug}
faction={props.faction}
key={aug}
p={player}
rerender={rerender}
owned={owned}
/>
);
};
const augListElems = purchasable.map((aug) => purchaseableAugmentation(aug));
@ -116,42 +131,33 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
ownedElem = (
<>
<br />
<h2>Purchased Augmentations</h2>
<p>This factions also offers these augmentations but you already own them.</p>
{owned.map((aug) => purchaseableAugmentation(aug))}
<Typography variant="h4">Purchased Augmentations</Typography>
<Typography>This factions also offers these augmentations but you already own them.</Typography>
{owned.map((aug) => purchaseableAugmentation(aug, true))}
</>
);
}
return (
<div>
<StdButton onClick={props.routeToMainPage} text={"Back"} />
<h1>Faction Augmentations</h1>
<p>
<Button onClick={props.routeToMainPage}>Back</Button>
<Typography variant="h4">Faction Augmentations</Typography>
<Typography>
These are all of the Augmentations that are available to purchase from {props.faction.name}. Augmentations are
powerful upgrades that will enhance your abilities.
</p>
<StdButton onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Cost)} text={"Sort by Cost"} />
<StdButton
onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Reputation)}
text={"Sort by Reputation"}
/>
<StdButton
onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Default)}
text={"Sort by Default Order"}
/>
<br />
{augListElems}
{ownedElem}
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
</Typography>
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Cost)}>Sort by Cost</Button>
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Reputation)}>Sort by Reputation</Button>
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Default)}>Sort by Default Order</Button>
<br />
<Table size="small" padding="none">
<TableBody>{augListElems}</TableBody>
</Table>
<Table size="small" padding="none">
<TableBody>{ownedElem}</TableBody>
</Table>
</div>
);
}

View File

@ -7,6 +7,7 @@ import { CONSTANTS } from "../../Constants";
import { Faction } from "../../Faction/Faction";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { repFromDonation } from "../formulas/donation";
import { Favor } from "../../ui/React/Favor";
import { Money } from "../../ui/React/Money";
import { Reputation } from "../../ui/React/Reputation";
@ -18,6 +19,11 @@ import { numeralWrapper } from "../../ui/numeralFormat";
import { dialogBoxCreate } from "../../../utils/DialogBox";
import { MathComponent } from "mathjax-react";
import Typography from "@mui/material/Typography";
import Paper from "@mui/material/Paper";
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";
type IProps = {
faction: Faction;
disabled: boolean;
@ -67,36 +73,45 @@ export function DonateOption(props: IProps): React.ReactElement {
function Status(): React.ReactElement {
if (donateAmt === null) return <></>;
if (!canDonate()) {
if (props.p.money.lt(donateAmt)) return <p>Insufficient funds</p>;
return <p>Invalid donate amount entered!</p>;
if (props.p.money.lt(donateAmt)) return <Typography>Insufficient funds</Typography>;
return <Typography>Invalid donate amount entered!</Typography>;
}
return <p>This donation will result in {Reputation(repFromDonation(donateAmt, props.p))} reputation gain</p>;
return (
<Typography>
This donation will result in {Reputation(repFromDonation(donateAmt, props.p))} reputation gain
</Typography>
);
}
return (
<div className={"faction-work-div"}>
<div className={"faction-work-div-wrapper"}>
<input
className="text-input"
onChange={onChange}
placeholder={"Donation amount"}
style={inputStyleMarkup}
disabled={props.disabled}
/>
<StdButton onClick={donate} text={"Donate Money"} disabled={props.disabled || !canDonate()} />
<Status />
{props.disabled ? (
<p>
Unlocked at {props.favorToDonate} favor with {props.faction.name}
</p>
) : (
<div className="text">
<Paper sx={{ my: 1, p: 1, width: "100%" }}>
<Status />
{props.disabled ? (
<Typography>
Unlock donations at {Favor(props.favorToDonate)} favor with {props.faction.name}
</Typography>
) : (
<>
<TextField
variant="standard"
onChange={onChange}
placeholder={"Donation amount"}
disabled={props.disabled}
InputProps={{
endAdornment: (
<Button onClick={donate} disabled={props.disabled || !canDonate()}>
donate
</Button>
),
}}
/>
<Typography>
<MathComponent
tex={String.raw`reputation = \frac{\text{donation amount} \times \text{reputation multiplier}}{10^{${digits}}}`}
/>
</div>
)}
</div>
</div>
</Typography>
</>
)}
</Paper>
);
}

View File

@ -21,6 +21,8 @@ import { createPopup } from "../../ui/React/createPopup";
import { use } from "../../ui/Context";
import { CreateGangPopup } from "./CreateGangPopup";
import Typography from "@mui/material/Typography";
type IProps = {
faction: Faction;
};
@ -145,8 +147,10 @@ export function FactionRoot(props: IProps): React.ReactElement {
}
return (
<div className="faction-container">
<h1>{faction.name}</h1>
<>
<Typography variant="h4" color="primary">
{faction.name}
</Typography>
<Info faction={faction} factionInfo={factionInfo} />
{canAccessGang && <Option buttonText={"Manage Gang"} infoText={gangInfo} onClick={() => manageGang(faction)} />}
{!isPlayersGang && factionInfo.offerHackingMission && (
@ -186,7 +190,7 @@ export function FactionRoot(props: IProps): React.ReactElement {
onClick={sleevePurchases}
/>
)}
</div>
</>
);
}

View File

@ -13,85 +13,75 @@ import { Reputation } from "../../ui/React/Reputation";
import { Favor } from "../../ui/React/Favor";
import { MathComponent } from "mathjax-react";
import { Theme } from "@mui/material/styles";
import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip";
import Box from "@mui/material/Box";
type IProps = {
faction: Faction;
factionInfo: FactionInfo;
};
type IInnerHTMLMarkup = {
__html: string;
};
const useStyles = makeStyles((theme: Theme) =>
createStyles({
noformat: {
whiteSpace: "pre",
},
}),
);
const blockStyleMarkup = {
display: "block",
};
export function Info(props: IProps): React.ReactElement {
const classes = useStyles();
const infoStyleMarkup = {
display: "block",
width: "70%",
};
const favorGain = props.faction.getFavorGain()[0];
return (
<>
<Typography classes={{ root: classes.noformat }}>{props.factionInfo.infoText}</Typography>
<Typography>-------------------------</Typography>
<Box display="flex">
<Tooltip
title={
<Typography>
You will have {Favor(props.faction.favor + favorGain)} faction favor after installing an Augmentation.
<MathComponent tex={String.raw`\large{r = \text{total faction reputation}}`} />
<MathComponent
tex={String.raw`\large{favor=\left\lfloor\log_{1.02}\left(\frac{r+25000}{25500}\right)\right\rfloor}`}
/>
</Typography>
}
>
<Typography>Reputation: {Reputation(props.faction.playerReputation)}</Typography>
</Tooltip>
</Box>
export class Info extends React.Component<IProps, any> {
constructor(props: IProps) {
super(props);
<Typography>-------------------------</Typography>
this.getFavorGainContent = this.getFavorGainContent.bind(this);
this.getReputationContent = this.getReputationContent.bind(this);
}
<Box display="flex">
<Tooltip
title={
<Typography>
Faction favor increases the rate at which you earn reputation for this faction by 1% per favor. Faction
favor is gained whenever you install an Augmentation. The amount of favor you gain depends on the total
amount of reputation you earned with this faction. Across all resets.
<MathComponent tex={String.raw`\large{r = reputation}`} />
<MathComponent tex={String.raw`\large{\Delta r = \Delta r \times \frac{100+favor}{100}}`} />
</Typography>
}
>
<Typography>Faction Favor: {Favor(props.faction.favor)}</Typography>
</Tooltip>
</Box>
getFavorGainContent(): JSX.Element {
const favorGain = this.props.faction.getFavorGain()[0];
return (
<>
You will have {Favor(this.props.faction.favor + favorGain)} faction favor after installing an Augmentation.
<MathComponent tex={String.raw`\large{r = \text{total faction reputation}}`} />
<MathComponent
tex={String.raw`\large{favor=\left\lfloor\log_{1.02}\left(\frac{r+25000}{25500}\right)\right\rfloor}`}
/>
</>
);
}
getReputationContent(): JSX.Element {
return <>Reputation: {Reputation(this.props.faction.playerReputation)}</>;
}
render(): React.ReactNode {
const favorTooltip = (
<>
Faction favor increases the rate at which you earn reputation for this faction by 1% per favor. Faction favor is
gained whenever you install an Augmentation. The amount of favor you gain depends on the total amount of
reputation you earned with this faction. Across all resets.
<MathComponent tex={String.raw`\large{r = reputation}`} />
<MathComponent tex={String.raw`\large{\Delta r = \Delta r \times \frac{100+favor}{100}}`} />
</>
);
const infoText: IInnerHTMLMarkup = {
__html: this.props.factionInfo.infoText,
};
return (
<div>
<pre>
<i className={"text"} dangerouslySetInnerHTML={infoText}></i>
</pre>
<p style={blockStyleMarkup}>-------------------------</p>
<AutoupdatingParagraph
intervalTime={5e3}
getContent={this.getReputationContent}
getTooltip={this.getFavorGainContent}
/>
<p style={blockStyleMarkup}>-------------------------</p>
<ParagraphWithTooltip content={<>Faction Favor: {Favor(this.props.faction.favor)}</>} tooltip={favorTooltip} />
<p style={blockStyleMarkup}>-------------------------</p>
<p style={infoStyleMarkup}>
Perform work/carry out assignments for your faction to help further its cause! By doing so you will earn
reputation for your faction. You will also gain reputation passively over time, although at a very slow rate.
Earning reputation will allow you to purchase Augmentations through this faction, which are powerful upgrades
that enhance your abilities.
</p>
</div>
);
}
<Typography>-------------------------</Typography>
<Typography>
Perform work/carry out assignments for your faction to help further its cause! By doing so you will earn
reputation for your faction. You will also gain reputation passively over time, although at a very slow rate.
Earning reputation will allow you to purchase Augmentations through this faction, which are powerful upgrades
that enhance your abilities.
</Typography>
</>
);
}

View File

@ -7,21 +7,24 @@ import * as React from "react";
import { StdButton } from "../../ui/React/StdButton";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Paper from "@mui/material/Paper";
import Box from "@mui/material/Box";
type IProps = {
buttonText: string;
infoText: string;
onClick: (e: React.MouseEvent<HTMLElement>) => void;
};
export class Option extends React.Component<IProps, any> {
render(): React.ReactNode {
return (
<div className={"faction-work-div"}>
<div className={"faction-work-div-wrapper"}>
<StdButton onClick={this.props.onClick} text={this.props.buttonText} />
<p>{this.props.infoText}</p>
</div>
</div>
);
}
export function Option(props: IProps): React.ReactElement {
return (
<Box>
<Paper sx={{ my: 1, p: 1, width: "100%" }}>
<Button onClick={props.onClick}>{props.buttonText}</Button>
<Typography>{props.infoText}</Typography>
</Paper>
</Box>
);
}

View File

@ -19,13 +19,55 @@ import { IMap } from "../../types";
import { StdButton } from "../../ui/React/StdButton";
import { Augmentation as AugFormat } from "../../ui/React/Augmentation";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip";
import Box from "@mui/material/Box";
import { TableCell } from "../../ui/React/Table";
import TableRow from "@mui/material/TableRow";
type IProps = {
interface IReqProps {
augName: string;
p: IPlayer;
hasReq: boolean;
rep: number;
hasRep: boolean;
cost: number;
hasCost: boolean;
}
function Requirements(props: IReqProps): React.ReactElement {
const aug = Augmentations[props.augName];
if (!props.hasReq) {
return (
<TableCell colSpan={2}>
<Typography color="error">Requires {aug.prereqs.map((aug) => AugFormat(aug))}</Typography>
</TableCell>
);
}
let color = !props.hasRep && !props.hasCost ? "error" : "primary";
return (
<>
<TableCell>
<Typography color={color}>
<Money money={props.cost} player={props.p} />
</Typography>
</TableCell>
<TableCell>
<Typography color={color}>Requires {Reputation(props.rep)} faction reputation</Typography>
</TableCell>
</>
);
}
interface IProps {
augName: string;
faction: Faction;
p: IPlayer;
rerender: () => void;
};
owned?: boolean;
}
export function PurchaseableAugmentation(props: IProps): React.ReactElement {
const aug = Augmentations[props.augName];
@ -39,22 +81,6 @@ export function PurchaseableAugmentation(props: IProps): React.ReactElement {
return aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult;
}
function handleClick(): void {
if (!Settings.SuppressBuyAugmentationConfirmation) {
const popupId = "purchase-augmentation-popup";
createPopup(popupId, PurchaseAugmentationPopup, {
aug: aug,
faction: props.faction,
player: props.p,
rerender: props.rerender,
popupId: popupId,
});
} else {
purchaseAugmentation(aug, props.faction);
props.rerender();
}
}
// Whether the player has the prerequisite Augmentations
function hasPrereqs(): boolean {
return hasAugmentationPrereqs(aug);
@ -94,18 +120,21 @@ export function PurchaseableAugmentation(props: IProps): React.ReactElement {
const moneyCost = getMoneyCost();
const repCost = getRepCost();
const hasReq = hasPrereqs();
const hasRep = hasReputation();
const hasCost = aug.baseCost !== 0 && props.p.money.lt(aug.baseCost * props.faction.getInfo().augmentationPriceMult);
// Determine UI properties
let disabled = false;
let status: JSX.Element = <></>;
let color = "";
if (!hasPrereqs()) {
let status: JSX.Element | null = null;
let color: "primary" | "error" = "primary";
if (!hasReq) {
disabled = true;
status = <>LOCKED (Requires {aug.prereqs.map((aug) => AugFormat(aug))} as prerequisite)</>;
color = "red";
color = "error";
} else if (aug.name !== AugmentationNames.NeuroFluxGovernor && (aug.owned || owned())) {
disabled = true;
} else if (hasReputation()) {
} else if (hasRep) {
status = (
<>
UNLOCKED (at {Reputation(repCost)} faction reputation) - <Money money={moneyCost} player={props.p} />
@ -118,14 +147,12 @@ export function PurchaseableAugmentation(props: IProps): React.ReactElement {
LOCKED (Requires {Reputation(repCost)} faction reputation - <Money money={moneyCost} player={props.p} />)
</>
);
color = "red";
color = "error";
}
const txtStyle: IMap<string> = {
display: "inline-block",
};
if (color !== "") {
txtStyle.color = color;
if (hasCost) {
disabled = true;
color = "error";
}
// Determine button txt
@ -154,25 +181,59 @@ export function PurchaseableAugmentation(props: IProps): React.ReactElement {
</>
);
function handleClick(): void {
if (disabled) return;
if (!Settings.SuppressBuyAugmentationConfirmation) {
const popupId = "purchase-augmentation-popup";
createPopup(popupId, PurchaseAugmentationPopup, {
aug: aug,
faction: props.faction,
player: props.p,
rerender: props.rerender,
popupId: popupId,
});
} else {
purchaseAugmentation(aug, props.faction);
props.rerender();
}
}
return (
<li key={aug.name}>
<span
style={{
margin: "4px",
padding: "4px",
}}
>
<StdButton
disabled={disabled}
onClick={handleClick}
style={{
display: "inline-block",
}}
text={btnTxt}
tooltip={tooltip}
<TableRow>
{!props.owned && (
<TableCell>
{status && (
<Button onClick={handleClick} color={color}>
Buy
</Button>
)}
</TableCell>
)}
<TableCell>
<Box display="flex">
<Tooltip
title={<Typography>{tooltip}</Typography>}
placement="top"
disableFocusListener
disableTouchListener
enterDelay={500}
leaveDelay={0}
>
<Typography>{btnTxt}</Typography>
</Tooltip>
</Box>
</TableCell>
{!props.owned && (
<Requirements
augName={props.augName}
p={props.p}
cost={moneyCost}
rep={repCost}
hasReq={hasReq}
hasRep={hasRep}
hasCost={hasCost}
/>
<p style={txtStyle}>{status}</p>
</span>
</li>
)}
</TableRow>
);
}

View File

@ -1,7 +1,9 @@
// Root React Component for the Corporation UI
import React, { useState, useEffect } from "react";
import { Theme } from "@mui/material/styles";
import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
import { numeralWrapper } from "../../ui/numeralFormat";
import { Reputation } from "./Reputation";
@ -78,35 +80,37 @@ function Work(): React.ReactElement {
);
}
const useStyles = makeStyles({
cellNone: {
borderBottom: "none",
padding: 0,
margin: 0,
},
cell: {
padding: 0,
margin: 0,
},
hp: {
color: colors.hp,
},
money: {
color: colors.money,
},
hack: {
color: colors.hack,
},
combat: {
color: colors.combat,
},
cha: {
color: colors.cha,
},
int: {
color: colors.int,
},
});
const useStyles = makeStyles((theme: Theme) =>
createStyles({
cellNone: {
borderBottom: "none",
padding: 0,
margin: 0,
},
cell: {
padding: 0,
margin: 0,
},
hp: {
color: theme.colors.hp,
},
money: {
color: theme.colors.money,
},
hack: {
color: theme.colors.hack,
},
combat: {
color: theme.colors.combat,
},
cha: {
color: theme.colors.cha,
},
int: {
color: theme.colors.int,
},
}),
);
export function CharacterOverview({ save }: IProps): React.ReactElement {
const player = use.Player();

View File

@ -1,11 +1,30 @@
import React from "react";
import { createTheme, ThemeProvider, Theme, StyledEngineProvider } from "@mui/material/styles";
declare module "@mui/styles/defaultTheme" {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface DefaultTheme extends Theme {}
declare module "@mui/material/styles" {
interface Theme {
colors: {
hp: React.CSSProperties["color"];
money: React.CSSProperties["color"];
hack: React.CSSProperties["color"];
combat: React.CSSProperties["color"];
cha: React.CSSProperties["color"];
int: React.CSSProperties["color"];
rep: React.CSSProperties["color"];
};
}
interface ThemeOptions {
colors: {
hp: React.CSSProperties["color"];
money: React.CSSProperties["color"];
hack: React.CSSProperties["color"];
combat: React.CSSProperties["color"];
cha: React.CSSProperties["color"];
int: React.CSSProperties["color"];
rep: React.CSSProperties["color"];
};
}
}
export const colors = {
primarylight: "#0f0",
primary: "#0c0",
@ -38,9 +57,19 @@ export const colors = {
combat: "#faffdf",
cha: "#a671d1",
int: "#6495ed",
rep: "#faffdf",
};
export const theme = createTheme({
colors: {
hp: "#dd3434",
money: "#ffd700",
hack: "#adff2f",
combat: "#faffdf",
cha: "#a671d1",
int: "#6495ed",
rep: "#faffdf",
},
palette: {
primary: {
light: colors.primarylight,
@ -191,6 +220,7 @@ export const theme = createTheme({
backgroundColor: colors.well,
borderRadius: 0,
border: "2px solid white",
maxWidth: "100vh",
},
},
},