bitburner-src/src/Locations/ui/City.tsx
2021-09-08 23:47:34 -04:00

120 lines
2.9 KiB
TypeScript

/**
* React Component for displaying a City's UI.
* This UI shows all of the available locations in the city, and lets the player
* visit those locations
*/
import * as React from "react";
import { City } from "../City";
import { LocationName } from "../data/LocationNames";
import { Settings } from "../../Settings/Settings";
import { StdButton } from "../../ui/React/StdButton";
type IProps = {
city: City;
enterLocation: (to: LocationName) => void;
};
export class LocationCity extends React.Component<IProps, any> {
asciiCity(): React.ReactNode {
const LocationLetter = (location: LocationName): JSX.Element => {
if (location)
return (
<span
key={location}
className="tooltip"
style={{
color: "white",
whiteSpace: "nowrap",
margin: "0px",
padding: "0px",
cursor: "pointer",
}}
onClick={this.props.enterLocation.bind(this, location)}
>
<b>X</b>
</span>
);
return <span>*</span>;
};
const locationLettersRegex = /[A-Z]/g;
const letterMap: any = {
A: 0,
B: 1,
C: 2,
D: 3,
E: 4,
F: 5,
G: 6,
H: 7,
I: 8,
J: 9,
K: 10,
L: 11,
M: 12,
N: 13,
O: 14,
P: 15,
Q: 16,
R: 17,
S: 18,
T: 19,
U: 20,
V: 21,
W: 22,
X: 23,
Y: 24,
Z: 25,
};
const lineElems = (s: string): JSX.Element[] => {
const elems: any[] = [];
const matches: any[] = [];
let match: any;
while ((match = locationLettersRegex.exec(s)) !== null) {
matches.push(match);
}
if (matches.length === 0) {
elems.push(s);
return elems;
}
for (let i = 0; i < matches.length; i++) {
const startI = i === 0 ? 0 : matches[i - 1].index + 1;
const endI = matches[i].index;
elems.push(s.slice(startI, endI));
const locationI = letterMap[s[matches[i].index]];
elems.push(LocationLetter(this.props.city.locations[locationI]));
}
elems.push(s.slice(matches[matches.length - 1].index + 1));
return elems;
};
const elems: JSX.Element[] = [];
const lines = this.props.city.asciiArt.split("\n");
for (const i in lines) {
elems.push(<pre key={i}>{lineElems(lines[i])}</pre>);
}
return <div className="noselect">{elems}</div>;
}
listCity(): React.ReactNode {
const locationButtons = this.props.city.locations.map((locName) => {
return (
<li key={locName}>
<StdButton onClick={this.props.enterLocation.bind(this, locName)} text={locName} />
</li>
);
});
return <ul>{locationButtons}</ul>;
}
render(): React.ReactNode {
return <>{Settings.DisableASCIIArt ? this.listCity() : this.asciiCity()}</>;
}
}