diff --git a/src/Locations/ui/CompanyLocation.tsx b/src/Locations/ui/CompanyLocation.tsx index 1d69b3ff7..ca8a0b442 100644 --- a/src/Locations/ui/CompanyLocation.tsx +++ b/src/Locations/ui/CompanyLocation.tsx @@ -57,7 +57,7 @@ export function CompanyLocation(props: IProps): React.ReactElement { */ const currentPosition = jobTitle ? CompanyPositions[jobTitle] : null; - Player.location = companyNameAsLocationName(props.companyName); + Player.gotoLocation(companyNameAsLocationName(props.companyName)); function startInfiltration(e: React.MouseEvent): void { if (!e.isTrusted) { diff --git a/src/Locations/ui/TravelAgencyRoot.tsx b/src/Locations/ui/TravelAgencyRoot.tsx index 97389b778..b2784559d 100644 --- a/src/Locations/ui/TravelAgencyRoot.tsx +++ b/src/Locations/ui/TravelAgencyRoot.tsx @@ -24,14 +24,12 @@ import Button from "@mui/material/Button"; import { useRerender } from "../../ui/React/hooks"; function travel(to: CityName): void { - const cost = CONSTANTS.TravelCost; - if (!Player.canAfford(cost)) { + if (!Player.travel(to)) { return; } - - Player.loseMoney(cost, "other"); - Player.travel(to); - if (!Settings.SuppressTravelConfirmation) dialogBoxCreate(`You are now in ${to}!`); + if (!Settings.SuppressTravelConfirmation) { + dialogBoxCreate(`You are now in ${to}!`); + } Router.toPage(Page.City); } @@ -41,8 +39,7 @@ export function TravelAgencyRoot(): React.ReactElement { useRerender(1000); function startTravel(city: CityName): void { - const cost = CONSTANTS.TravelCost; - if (!Player.canAfford(cost)) { + if (!Player.canAfford(CONSTANTS.TravelCost)) { return; } if (Settings.SuppressTravelConfirmation) { diff --git a/src/Locations/ui/TravelConfirmationModal.tsx b/src/Locations/ui/TravelConfirmationModal.tsx index 5a16822d0..ee8bdd04d 100644 --- a/src/Locations/ui/TravelConfirmationModal.tsx +++ b/src/Locations/ui/TravelConfirmationModal.tsx @@ -14,7 +14,6 @@ interface IProps { } export function TravelConfirmationModal(props: IProps): React.ReactElement { - const cost = CONSTANTS.TravelCost; function travel(): void { props.travel(); } @@ -22,7 +21,8 @@ export function TravelConfirmationModal(props: IProps): React.ReactElement { return ( - Would you like to travel to {props.city}? The trip will cost . + Would you like to travel to {props.city}? The trip will cost{" "} + .

diff --git a/src/NetscriptFunctions/Singularity.ts b/src/NetscriptFunctions/Singularity.ts index e0628ceae..cde24fea3 100644 --- a/src/NetscriptFunctions/Singularity.ts +++ b/src/NetscriptFunctions/Singularity.ts @@ -269,7 +269,7 @@ export function NetscriptSingularity(): InternalAPI { ); return false; } - Player.location = LocationName.Sector12RothmanUniversity; + Player.gotoLocation(LocationName.Sector12RothmanUniversity); break; case LocationName.VolhavenZBInstituteOfTechnology.toLowerCase(): if (Player.city != CityName.Volhaven) { @@ -279,7 +279,7 @@ export function NetscriptSingularity(): InternalAPI { ); return false; } - Player.location = LocationName.VolhavenZBInstituteOfTechnology; + Player.gotoLocation(LocationName.VolhavenZBInstituteOfTechnology); break; default: helpers.log(ctx, () => `Invalid university name: '${universityName}'.`); @@ -327,7 +327,7 @@ export function NetscriptSingularity(): InternalAPI { ); return false; } - Player.location = LocationName.AevumCrushFitnessGym; + Player.gotoLocation(LocationName.AevumCrushFitnessGym); break; case LocationName.AevumSnapFitnessGym.toLowerCase(): if (Player.city != CityName.Aevum) { @@ -338,7 +338,7 @@ export function NetscriptSingularity(): InternalAPI { ); return false; } - Player.location = LocationName.AevumSnapFitnessGym; + Player.gotoLocation(LocationName.AevumSnapFitnessGym); break; case LocationName.Sector12IronGym.toLowerCase(): if (Player.city != CityName.Sector12) { @@ -349,7 +349,7 @@ export function NetscriptSingularity(): InternalAPI { ); return false; } - Player.location = LocationName.Sector12IronGym; + Player.gotoLocation(LocationName.Sector12IronGym); break; case LocationName.Sector12PowerhouseGym.toLowerCase(): if (Player.city != CityName.Sector12) { @@ -360,7 +360,7 @@ export function NetscriptSingularity(): InternalAPI { ); return false; } - Player.location = LocationName.Sector12PowerhouseGym; + Player.gotoLocation(LocationName.Sector12PowerhouseGym); break; case LocationName.VolhavenMilleniumFitnessGym.toLowerCase(): if (Player.city != CityName.Volhaven) { @@ -371,7 +371,7 @@ export function NetscriptSingularity(): InternalAPI { ); return false; } - Player.location = LocationName.VolhavenMilleniumFitnessGym; + Player.gotoLocation(LocationName.VolhavenMilleniumFitnessGym); break; default: helpers.log(ctx, () => `Invalid gym name: ${gymName}. gymWorkout() failed`); @@ -401,12 +401,10 @@ export function NetscriptSingularity(): InternalAPI { case CityName.NewTokyo: case CityName.Ishima: case CityName.Volhaven: - if (Player.money < CONSTANTS.TravelCost) { + if (!Player.travel(cityName)) { helpers.log(ctx, () => "Not enough money to travel."); return false; } - Player.loseMoney(CONSTANTS.TravelCost, "other"); - Player.city = cityName; helpers.log(ctx, () => `Traveled to ${cityName}`); Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50000); return true; diff --git a/src/NetscriptFunctions/Sleeve.ts b/src/NetscriptFunctions/Sleeve.ts index 253a09d3b..24113c9e4 100644 --- a/src/NetscriptFunctions/Sleeve.ts +++ b/src/NetscriptFunctions/Sleeve.ts @@ -79,7 +79,11 @@ export function NetscriptSleeve(): InternalAPI { const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName); checkSleeveAPIAccess(ctx); checkSleeveNumber(ctx, sleeveNumber); - return Player.sleeves[sleeveNumber].travel(cityName); + if (!Player.sleeves[sleeveNumber].travel(cityName)) { + helpers.log(ctx, () => "Not enough money to travel."); + return false; + } + return true; }, setToCompanyWork: (ctx) => (_sleeveNumber, _companyName) => { const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts index 62e45e4f9..ac00f6532 100644 --- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts +++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts @@ -531,20 +531,23 @@ export function gainCodingContractReward( } } -export function travel(this: PlayerObject, to: CityName): boolean { - if (Cities[to] == null) { - console.warn(`Player.travel() called with invalid city: ${to}`); +export function travel(this: PlayerObject, cityName: CityName): boolean { + if (Cities[cityName] == null) { + throw new Error(`Player.travel() was called with an invalid city: ${cityName}`); + } + if (!this.canAfford(CONSTANTS.TravelCost)) { return false; } - this.city = to; + + this.loseMoney(CONSTANTS.TravelCost, "other"); + this.city = cityName; return true; } export function gotoLocation(this: PlayerObject, to: LocationName): boolean { if (Locations[to] == null) { - console.warn(`Player.gotoLocation() called with invalid location: ${to}`); - return false; + throw new Error(`Player.gotoLocation() was called with an invalid location: ${to}`); } this.location = to; diff --git a/src/PersonObjects/Sleeve/Sleeve.ts b/src/PersonObjects/Sleeve/Sleeve.ts index 9b48ab889..69a4d37c3 100644 --- a/src/PersonObjects/Sleeve/Sleeve.ts +++ b/src/PersonObjects/Sleeve/Sleeve.ts @@ -44,6 +44,7 @@ import { SleeveCrimeWork } from "./Work/SleeveCrimeWork"; import * as sleeveMethods from "./SleeveMethods"; import { calculateIntelligenceBonus } from "../formulas/intelligence"; import { getEnumHelper } from "../../utils/EnumHelper"; +import { Cities } from "../../Locations/Cities"; export class Sleeve extends Person implements SleevePerson { currentWork: SleeveWork | null = null; @@ -255,13 +256,16 @@ export class Sleeve extends Person implements SleevePerson { } /** Travel to another City. Costs money from player */ - travel(newCity: CityName): boolean { + travel(cityName: CityName): boolean { + if (Cities[cityName] == null) { + throw new Error(`Sleeve.travel() was called with an invalid city: ${cityName}`); + } if (!Player.canAfford(CONSTANTS.TravelCost)) { return false; } Player.loseMoney(CONSTANTS.TravelCost, "sleeves"); - this.city = newCity; + this.city = cityName; return true; } diff --git a/src/PersonObjects/Sleeve/ui/TravelModal.tsx b/src/PersonObjects/Sleeve/ui/TravelModal.tsx index 76cec4276..2c7e78f1d 100644 --- a/src/PersonObjects/Sleeve/ui/TravelModal.tsx +++ b/src/PersonObjects/Sleeve/ui/TravelModal.tsx @@ -1,6 +1,5 @@ import React from "react"; import { Button, Typography } from "@mui/material"; -import { Player } from "@player"; import { CityName } from "@enums"; import { Sleeve } from "../Sleeve"; import { CONSTANTS } from "../../../Constants"; @@ -19,11 +18,10 @@ interface IProps { export function TravelModal(props: IProps): React.ReactElement { function travel(city: string): void { - if (!Player.canAfford(CONSTANTS.TravelCost)) { + if (!props.sleeve.travel(city as CityName)) { dialogBoxCreate("You cannot afford to have this sleeve travel to another city"); + return; } - props.sleeve.city = city as CityName; - Player.loseMoney(CONSTANTS.TravelCost, "sleeves"); props.sleeve.stopWork(); props.rerender(); props.onClose();