2019-03-29 08:12:41 +01:00
|
|
|
/**
|
|
|
|
* Root React Component for displaying overall Location UI
|
|
|
|
*/
|
|
|
|
import * as React from "react";
|
|
|
|
|
|
|
|
import { LocationCity } from "./City";
|
2019-04-01 11:23:25 +02:00
|
|
|
import { GenericLocation } from "./GenericLocation";
|
|
|
|
|
|
|
|
import { Cities } from "../Cities";
|
|
|
|
import { Locations } from "../Locations";
|
|
|
|
import { LocationType } from "../LocationTypeEnum";
|
2019-03-29 08:12:41 +01:00
|
|
|
|
|
|
|
import { CityName } from "../data/CityNames";
|
|
|
|
import { LocationName } from "../data/LocationNames";
|
|
|
|
|
2019-04-01 11:23:25 +02:00
|
|
|
import { CONSTANTS } from "../../Constants";
|
|
|
|
import { IEngine } from "../../IEngine";
|
2019-03-29 08:12:41 +01:00
|
|
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
|
|
|
2019-04-01 11:23:25 +02:00
|
|
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
|
|
|
|
2019-03-29 08:12:41 +01:00
|
|
|
type IProps = {
|
2019-04-04 02:08:11 +02:00
|
|
|
initiallyInCity?: boolean;
|
2019-04-01 11:23:25 +02:00
|
|
|
engine: IEngine;
|
2019-03-29 08:12:41 +01:00
|
|
|
p: IPlayer;
|
|
|
|
}
|
|
|
|
|
|
|
|
type IState = {
|
|
|
|
city: CityName;
|
|
|
|
inCity: boolean;
|
|
|
|
location: LocationName;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class LocationRoot extends React.Component<IProps, IState> {
|
|
|
|
constructor(props: IProps) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
city: props.p.city,
|
2019-04-04 02:08:11 +02:00
|
|
|
inCity: props.initiallyInCity == null ? true : props.initiallyInCity,
|
2019-03-29 08:12:41 +01:00
|
|
|
location: props.p.location,
|
|
|
|
}
|
|
|
|
|
2019-04-04 02:08:11 +02:00
|
|
|
this.enterLocation = this.enterLocation.bind(this);
|
2019-03-29 08:12:41 +01:00
|
|
|
this.returnToCity = this.returnToCity.bind(this);
|
2019-04-01 11:23:25 +02:00
|
|
|
this.travel = this.travel.bind(this);
|
2019-03-29 08:12:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
enterLocation(to: LocationName): void {
|
2019-04-04 02:08:11 +02:00
|
|
|
this.props.p.gotoLocation(to);
|
2019-03-29 08:12:41 +01:00
|
|
|
this.setState({
|
|
|
|
inCity: false,
|
|
|
|
location: to,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Click listener for a button that lets the player go from a specific location
|
|
|
|
* back to the city
|
|
|
|
*/
|
|
|
|
returnToCity(): void {
|
|
|
|
this.setState({
|
|
|
|
inCity: true,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Render UI for a city
|
|
|
|
*/
|
|
|
|
renderCity(): React.ReactNode {
|
2019-04-01 11:23:25 +02:00
|
|
|
const city = Cities[this.state.city];
|
|
|
|
if (city == null) {
|
|
|
|
throw new Error(`Invalid city when rendering UI: ${this.state.city}`);
|
|
|
|
}
|
|
|
|
|
2019-03-29 08:12:41 +01:00
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<h2>{this.state.city}</h2>
|
2019-04-01 11:23:25 +02:00
|
|
|
<LocationCity city={city} enterLocation={this.enterLocation} />
|
2019-03-29 08:12:41 +01:00
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Render UI for a specific location
|
|
|
|
*/
|
|
|
|
renderLocation(): React.ReactNode {
|
2019-04-01 11:23:25 +02:00
|
|
|
const loc = Locations[this.state.location];
|
|
|
|
|
|
|
|
if (loc == null) {
|
|
|
|
throw new Error(`Invalid location when rendering UI: ${this.state.location}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (loc.types.includes(LocationType.StockMarket)) {
|
|
|
|
this.props.engine.loadStockMarketContent();
|
|
|
|
}
|
|
|
|
|
2019-03-29 08:12:41 +01:00
|
|
|
return (
|
2019-04-01 11:23:25 +02:00
|
|
|
<GenericLocation
|
|
|
|
engine={this.props.engine}
|
|
|
|
loc={loc}
|
|
|
|
p={this.props.p}
|
|
|
|
returnToCity={this.returnToCity}
|
|
|
|
travel={this.travel}
|
|
|
|
/>
|
2019-03-29 08:12:41 +01:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2019-04-01 11:23:25 +02:00
|
|
|
/**
|
|
|
|
* Travel to a different city
|
|
|
|
* @param {CityName} to - Destination city
|
|
|
|
*/
|
|
|
|
travel(to: CityName): void {
|
|
|
|
const p = this.props.p;
|
|
|
|
const cost = CONSTANTS.TravelCost;
|
|
|
|
if (!p.canAfford(cost)) {
|
|
|
|
dialogBoxCreate(`You cannot afford to travel to ${to}`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
p.loseMoney(cost);
|
|
|
|
p.travel(to);
|
|
|
|
dialogBoxCreate(`You are now in ${to}!`);
|
|
|
|
|
|
|
|
// Dynamically update main menu
|
|
|
|
if (p.firstTimeTraveled === false) {
|
|
|
|
p.firstTimeTraveled = true;
|
|
|
|
const travelTab = document.getElementById("travel-tab");
|
|
|
|
const worldHeader = document.getElementById("world-menu-header");
|
|
|
|
if (travelTab != null && worldHeader !== null) {
|
|
|
|
travelTab.style.display = "list-item";
|
|
|
|
worldHeader.click(); worldHeader.click();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.props.p.travel(to)) {
|
|
|
|
this.setState({
|
2019-04-04 02:08:11 +02:00
|
|
|
inCity: true,
|
2019-04-01 11:23:25 +02:00
|
|
|
city: to
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-29 08:12:41 +01:00
|
|
|
render() {
|
|
|
|
if (this.state.inCity) {
|
|
|
|
return this.renderCity();
|
|
|
|
} else {
|
|
|
|
return this.renderLocation();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|