rewrite travel popup

This commit is contained in:
Olivier Gagnon 2021-09-11 03:19:52 -04:00
parent 609ba34804
commit 1edcbe88ee
5 changed files with 176 additions and 254 deletions

@ -0,0 +1,79 @@
import React, { useState } from "react";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { removePopup } from "../../ui/React/createPopup";
import { Money } from "../../ui/React/Money";
import { dialogBoxCreate } from "../../../utils/DialogBox";
interface IProps {
player: IPlayer;
popupId: string;
}
export function CreateCorporationPopup(props: IProps): React.ReactElement {
if (!props.player.canAccessCorporation() || props.player.hasCorporation()) {
removePopup(props.popupId);
return <></>;
}
const [name, setName] = useState("");
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
setName(event.target.value);
}
function selfFund(): void {
if (!props.player.canAfford(150e9)) {
dialogBoxCreate("You don't have enough money to create a corporation! You need $150b.");
return;
}
if (name == "") {
dialogBoxCreate("Invalid company name!");
return;
}
props.player.startCorporation(name);
props.player.loseMoney(150e9);
dialogBoxCreate(
"Congratulations! You just self-funded your own corporation. You can visit " +
"and manage your company in the City.",
);
removePopup(props.popupId);
}
function seed(): void {
if (name == "") {
dialogBoxCreate("Invalid company name!");
return;
}
props.player.startCorporation(name, 500e6);
dialogBoxCreate(
"Congratulations! You just started your own corporation with government seed money. " +
"You can visit and manage your company in the City.",
);
removePopup(props.popupId);
}
return (
<>
<p>
Would you like to start a corporation? This will require $150b for registration and initial funding. This $150b
can either be self-funded, or you can obtain the seed money from the government in exchange for 500 million
shares
<br />
<br />
If you would like to start one, please enter a name for your corporation below:
</p>
<input autoFocus={true} className="text-input" placeholder="Corporation Name" onChange={onChange} value={name} />
<button className="std-button" onClick={seed} disabled={name == ""}>
Use seed money
</button>
<button className="std-button" onClick={selfFund} disabled={name == "" || !props.player.canAfford(150e9)}>
Self-Fund (<Money money={150e9} player={props.player} />)
</button>
</>
);
}

@ -15,12 +15,7 @@ import { Settings } from "../Settings/Settings";
import { Money } from "../ui/React/Money";
import { dialogBoxCreate } from "../../utils/DialogBox";
import {
yesNoBoxGetYesButton,
yesNoBoxGetNoButton,
yesNoBoxClose,
yesNoBoxCreate,
} from "../../utils/YesNoBox";
import { yesNoBoxGetYesButton, yesNoBoxGetNoButton, yesNoBoxClose, yesNoBoxCreate } from "../../utils/YesNoBox";
import { createElement } from "../../utils/uiHelpers/createElement";
import { createPopup } from "../../utils/uiHelpers/createPopup";
@ -28,193 +23,6 @@ import { createPopupCloseButton } from "../../utils/uiHelpers/createPopupCloseBu
import { removeElementById } from "../../utils/uiHelpers/removeElementById";
import * as React from "react";
/**
* Create a pop-up box that lets the player confirm traveling to a different city.
* If settings are configured to suppress this popup, just instantly travel.
* The actual "Travel" implementation is implemented in the UI, and is passed in
* as an argument.
* @param {CityName} destination - City that the player is traveling to
* @param {Function} travelFn - Function that changes the player's state for traveling
*/
type TravelFunction = (to: CityName) => void;
export function createTravelPopup(destination: CityName, travelFn: TravelFunction): void {
const cost: number = CONSTANTS.TravelCost;
if (Settings.SuppressTravelConfirmation) {
travelFn(destination);
return;
}
const yesBtn = yesNoBoxGetYesButton();
const noBtn = yesNoBoxGetNoButton();
if (yesBtn == null || noBtn == null) {
console.warn(`Could not find YesNo pop-up box buttons`);
return;
}
yesBtn.innerHTML = "Yes";
yesBtn.addEventListener("click", () => {
yesNoBoxClose();
travelFn(destination);
return false;
});
noBtn.innerHTML = "No";
noBtn.addEventListener("click", () => {
yesNoBoxClose();
return false;
});
yesNoBoxCreate(
<span>
Would you like to travel to {destination}? The trip will cost <Money money={cost} />.
</span>,
);
}
/**
* Create a popup that lets the player start a Corporation
* @param {IPlayer} p - Player object
*/
export function createStartCorporationPopup(p: IPlayer): void {
if (!p.canAccessCorporation() || p.hasCorporation()) {
return;
}
const popupId = "create-corporation-popup";
const txt = createElement("p", {
innerHTML:
"Would you like to start a corporation? This will require $150b for registration " +
"and initial funding. This $150b can either be self-funded, or you can obtain " +
"the seed money from the government in exchange for 500 million shares<br><br>" +
"If you would like to start one, please enter a name for your corporation below:",
});
const nameInput = createElement("input", {
class: "text-input",
placeholder: "Corporation Name",
}) as HTMLInputElement;
const selfFundedButton = createElement("button", {
class: "popup-box-button",
innerText: "Self-Fund",
clickListener: () => {
if (!p.canAfford(150e9)) {
dialogBoxCreate("You don't have enough money to create a corporation! You need $150b.");
return false;
}
const companyName = nameInput.value;
if (companyName == null || companyName == "") {
dialogBoxCreate("Invalid company name!");
return false;
}
p.startCorporation(companyName);
p.loseMoney(150e9);
const worldHeader = document.getElementById("world-menu-header");
if (worldHeader instanceof HTMLElement) {
worldHeader.click();
worldHeader.click();
}
dialogBoxCreate(
"Congratulations! You just self-funded your own corporation. You can visit " +
"and manage your company in the City.",
);
removeElementById(popupId);
return false;
},
});
const seedMoneyButton = createElement("button", {
class: "popup-box-button",
innerText: "Use Seed Money",
clickListener: () => {
const companyName = nameInput.value;
if (companyName == null || companyName == "") {
dialogBoxCreate("Invalid company name!");
return false;
}
p.startCorporation(companyName, 500e6);
const worldHeader = document.getElementById("world-menu-header");
if (worldHeader instanceof HTMLElement) {
worldHeader.click();
worldHeader.click();
}
dialogBoxCreate(
"Congratulations! You just started your own corporation with government seed money. " +
"You can visit and manage your company in the City.",
);
removeElementById(popupId);
return false;
},
});
const cancelBtn = createPopupCloseButton(popupId, {
class: "popup-box-button",
});
createPopup(popupId, [txt, nameInput, cancelBtn, selfFundedButton, seedMoneyButton]);
nameInput.focus();
}
/**
* Create a popup that lets the player upgrade the cores on his/her home computer
* @param {IPlayer} p - Player object
*/
export function createUpgradeHomeCoresPopup(p: IPlayer): void {
const currentCores = p.getHomeComputer().cpuCores;
if (currentCores >= 8) {
dialogBoxCreate(<>You have the maximum amount of CPU cores on your home computer.</>);
return;
}
// Cost of purchasing another cost is found by indexing this array with number of current cores
const allCosts = [0, 10e9, 250e9, 5e12, 100e12, 1e15, 20e15, 200e15];
const cost: number = allCosts[currentCores];
const yesBtn = yesNoBoxGetYesButton();
const noBtn = yesNoBoxGetNoButton();
if (yesBtn == null || noBtn == null) {
return;
}
yesBtn.innerHTML = "Purchase";
yesBtn.addEventListener("click", () => {
if (!p.canAfford(cost)) {
dialogBoxCreate("You do not have enough money to purchase an additional CPU Core for your home computer!");
} else {
p.loseMoney(cost);
p.getHomeComputer().cpuCores++;
dialogBoxCreate(
"You purchased an additional CPU Core for your home computer! It now has " +
p.getHomeComputer().cpuCores +
" cores.",
);
}
yesNoBoxClose();
});
noBtn.innerHTML = "Cancel";
noBtn.addEventListener("click", () => {
yesNoBoxClose();
});
yesNoBoxCreate(
<>
Would you like to purchase an additional CPU Core for your home computer? Each CPU Core lets you start with an
additional Core Node in Hacking Missions.
<br />
<br />
Purchasing an additional core (for a total of {p.getHomeComputer().cpuCores + 1}) will cost{" "}
<Money money={cost} player={p} />
</>,
);
}
/**
* Attempt to purchase a TOR router
* @param {IPlayer} p - Player object

@ -13,7 +13,8 @@
import * as React from "react";
import { Location } from "../Location";
import { createStartCorporationPopup } from "../LocationsHelpers";
import { CreateCorporationPopup } from "../../Corporation/ui/CreateCorporationPopup";
import { createPopup } from "../../ui/React/createPopup";
import { LocationName } from "../data/LocationNames";
import { IEngine } from "../../IEngine";
@ -59,7 +60,11 @@ export class SpecialLocation extends React.Component<IProps, IState> {
* Click handler for "Create Corporation" button at Sector-12 City Hall
*/
createCorporationPopup(): void {
createStartCorporationPopup(this.props.p);
const popupId = `create-start-corporation-popup`;
createPopup(popupId, CreateCorporationPopup, {
player: this.props.p,
popupId: popupId,
});
}
/**

@ -6,13 +6,14 @@
import * as React from "react";
import { CityName } from "../data/CityNames";
import { createTravelPopup } from "../LocationsHelpers";
import { TravelConfirmationPopup } from "./TravelConfirmationPopup";
import { CONSTANTS } from "../../Constants";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { Settings } from "../../Settings/Settings";
import { StdButton } from "../../ui/React/StdButton";
import { createPopup } from "../../ui/React/createPopup";
import { Money } from "../../ui/React/Money";
import { WorldMap } from "../../ui/React/WorldMap";
@ -21,67 +22,63 @@ type IProps = {
travel: (to: CityName) => void;
};
export class TravelAgencyLocation extends React.Component<IProps, any> {
/**
* Stores button styling that sets them all to block display
*/
btnStyle: any;
constructor(props: IProps) {
super(props);
this.btnStyle = { display: "block" };
function createTravelPopup(p: IPlayer, city: string, travel: () => void): void {
if (Settings.SuppressTravelConfirmation) {
travel();
return;
}
const popupId = `travel-confirmation`;
createPopup(popupId, TravelConfirmationPopup, {
player: p,
city: city,
travel: travel,
popupId: popupId,
});
}
asciiWorldMap(): React.ReactNode {
// map needs all this whitespace!
// prettier-ignore
return (
<div className="noselect">
<p>
From here, you can travel to any other city! A ticket costs{" "}
<Money money={CONSTANTS.TravelCost} player={this.props.p} />.
</p>
<WorldMap currentCity={this.props.p.city} onTravel={(city: CityName) => createTravelPopup(city, this.props.travel)} />
</div>
);
}
function ASCIIWorldMap(props: IProps): React.ReactElement {
return (
<div className="noselect">
<p>
From here, you can travel to any other city! A ticket costs{" "}
<Money money={CONSTANTS.TravelCost} player={props.p} />.
</p>
<WorldMap
currentCity={props.p.city}
onTravel={(city: CityName) => createTravelPopup(props.p, city, () => props.travel(city))}
/>
</div>
);
}
listWorldMap(): React.ReactNode {
const travelBtns: React.ReactNode[] = [];
for (const key in CityName) {
const city: CityName = (CityName as any)[key];
function ListWorldMap(props: IProps): React.ReactElement {
return (
<div>
<p>
From here, you can travel to any other city! A ticket costs{" "}
<Money money={CONSTANTS.TravelCost} player={props.p} />.
</p>
{Object.values(CityName)
.filter((city: string) => city != props.p.city)
.map((city: string) => (
<StdButton
key={city}
onClick={() =>
createTravelPopup(props.p, city, () => props.travel(CityName[city as keyof typeof CityName]))
}
style={{ display: "block" }}
text={`Travel to ${city}`}
/>
))}
</div>
);
}
// Skip current city
if (city === this.props.p.city) {
continue;
}
travelBtns.push(
<StdButton
key={city}
onClick={createTravelPopup.bind(null, city, this.props.travel)}
style={this.btnStyle}
text={`Travel to ${city}`}
/>,
);
}
return (
<div>
<p>
From here, you can travel to any other city! A ticket costs <Money money={CONSTANTS.TravelCost} />.
</p>
{travelBtns}
</div>
);
}
render(): React.ReactNode {
if (Settings.DisableASCIIArt) {
return this.listWorldMap();
} else {
return this.asciiWorldMap();
}
export function TravelAgencyLocation(props: IProps): React.ReactElement {
console.log(Settings.DisableASCIIArt);
if (Settings.DisableASCIIArt) {
return <ListWorldMap p={props.p} travel={props.travel} />;
} else {
return <ASCIIWorldMap p={props.p} travel={props.travel} />;
}
}

@ -0,0 +1,33 @@
import React from "react";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { CONSTANTS } from "../../Constants";
import { Money } from "../../ui/React/Money";
import { removePopup } from "../../ui/React/createPopup";
interface IProps {
player: IPlayer;
city: string;
travel: () => void;
popupId: string;
}
export function TravelConfirmationPopup(props: IProps): React.ReactElement {
const cost = CONSTANTS.TravelCost;
function travel(): void {
props.travel();
removePopup(props.popupId);
}
return (
<>
<span>
Would you like to travel to {props.city}? The trip will cost <Money money={cost} player={props.player} />.
</span>
<br />
<br />
<button className="std-button" onClick={travel}>
Travel
</button>
</>
);
}