Remove industry upgrades

There are only two industry upgrades, one of which is buying coffee
which is not an upgrade, and for the office not the industry. Moving
that to the office leaves just hiring AdVerts, which is better as an
explicitly named set of methods.
This commit is contained in:
Staszek Welsh 2022-06-02 02:43:22 +01:00
parent 18a80d3fe9
commit ba7b76369b
7 changed files with 59 additions and 139 deletions

@ -14,7 +14,6 @@ import { CorporationUpgrade } from "./data/CorporationUpgrades";
import { Cities } from "../Locations/Cities"; import { Cities } from "../Locations/Cities";
import { EmployeePositions } from "./EmployeePositions"; import { EmployeePositions } from "./EmployeePositions";
import { Employee } from "./Employee"; import { Employee } from "./Employee";
import { IndustryUpgrades } from "./IndustryUpgrades";
import { ResearchMap } from "./ResearchMap"; import { ResearchMap } from "./ResearchMap";
import { isRelevantMaterial } from "./ui/Helpers"; import { isRelevantMaterial } from "./ui/Helpers";
@ -334,7 +333,7 @@ export function UpgradeOfficeSize(corp: ICorporation, office: OfficeSpace, size:
} }
export function BuyCoffee(corp: ICorporation, office: OfficeSpace): boolean { export function BuyCoffee(corp: ICorporation, office: OfficeSpace): boolean {
const cost = 500e3 * office.employees.length; const cost = office.getCoffeeCost();
if (corp.funds < cost) { return false; } if (corp.funds < cost) { return false; }
if (!office.setCoffee()) { return false; } if (!office.setCoffee()) { return false; }
@ -381,15 +380,11 @@ export function UpgradeWarehouse(corp: ICorporation, division: IIndustry, wareho
corp.funds = corp.funds - sizeUpgradeCost; corp.funds = corp.funds - sizeUpgradeCost;
} }
export function HireAdVert(corp: ICorporation, division: IIndustry, office: OfficeSpace): void { export function HireAdVert(corp: ICorporation, division: IIndustry): void {
const upgrade = IndustryUpgrades[1]; const cost = division.getAdVertCost();
const cost = upgrade[1] * Math.pow(upgrade[2], division.upgrades[1]);
if (corp.funds < cost) return; if (corp.funds < cost) return;
corp.funds = corp.funds - cost; corp.funds = corp.funds - cost;
division.upgrade(upgrade, { division.applyAdVert(corp);
corporation: corp,
office: office,
});
} }
export function MakeProduct( export function MakeProduct(

@ -3,7 +3,6 @@ import { Warehouse } from "./Warehouse";
import { ICorporation } from "./ICorporation"; import { ICorporation } from "./ICorporation";
import { OfficeSpace } from "./OfficeSpace"; import { OfficeSpace } from "./OfficeSpace";
import { Product } from "./Product"; import { Product } from "./Product";
import { IndustryUpgrade } from "./IndustryUpgrades";
export interface IIndustry { export interface IIndustry {
name: string; name: string;
@ -36,12 +35,11 @@ export interface IIndustry {
thisCycleRevenue: number; thisCycleRevenue: number;
thisCycleExpenses: number; thisCycleExpenses: number;
upgrades: number[];
state: string; state: string;
newInd: boolean; newInd: boolean;
warehouses: { [key: string]: Warehouse | 0 }; warehouses: { [key: string]: Warehouse | 0 };
offices: { [key: string]: OfficeSpace | 0 }; offices: { [key: string]: OfficeSpace | 0 };
numAdVerts: number;
init(): void; init(): void;
getProductDescriptionText(): string; getProductDescriptionText(): string;
@ -56,7 +54,8 @@ export interface IIndustry {
processProducts(marketCycles: number, corporation: ICorporation): [number, number]; processProducts(marketCycles: number, corporation: ICorporation): [number, number];
processProduct(marketCycles: number, product: Product, corporation: ICorporation): number; processProduct(marketCycles: number, product: Product, corporation: ICorporation): number;
discontinueProduct(product: Product): void; discontinueProduct(product: Product): void;
upgrade(upgrade: IndustryUpgrade, refs: { corporation: ICorporation; office: OfficeSpace }): void; getAdVertCost(): number;
applyAdVert(corporation: ICorporation): void;
getOfficeProductivity(office: OfficeSpace, params?: { forProduct?: boolean }): number; getOfficeProductivity(office: OfficeSpace, params?: { forProduct?: boolean }): number;
getBusinessFactor(office: OfficeSpace): number; getBusinessFactor(office: OfficeSpace): number;
getAdvertisingFactors(): [number, number, number, number]; getAdvertisingFactors(): [number, number, number, number];

@ -14,7 +14,6 @@ import { MaterialSizes } from "./MaterialSizes";
import { Warehouse } from "./Warehouse"; import { Warehouse } from "./Warehouse";
import { ICorporation } from "./ICorporation"; import { ICorporation } from "./ICorporation";
import { IIndustry } from "./IIndustry"; import { IIndustry } from "./IIndustry";
import { IndustryUpgrade, IndustryUpgrades } from "./IndustryUpgrades";
interface IParams { interface IParams {
name?: string; name?: string;
@ -59,9 +58,6 @@ export class Industry implements IIndustry {
thisCycleRevenue: number; thisCycleRevenue: number;
thisCycleExpenses: number; thisCycleExpenses: number;
//Upgrades
upgrades: number[] = Array(Object.keys(IndustryUpgrades).length).fill(0);
state = "START"; state = "START";
newInd = true; newInd = true;
@ -81,6 +77,8 @@ export class Industry implements IIndustry {
[CityName.Volhaven]: 0, [CityName.Volhaven]: 0,
}; };
numAdVerts = 0;
constructor(params: IParams = {}) { constructor(params: IParams = {}) {
this.name = params.name ? params.name : ""; this.name = params.name ? params.name : "";
this.type = params.type ? params.type : Industries.Agriculture; this.type = params.type ? params.type : Industries.Agriculture;
@ -1262,38 +1260,19 @@ export class Industry implements IIndustry {
} }
} }
upgrade(upgrade: IndustryUpgrade, refs: { corporation: ICorporation; office: OfficeSpace }): void { getAdVertCost(): number {
const corporation = refs.corporation; return 1e9 * Math.pow(1.06, this.numAdVerts);
const office = refs.office;
const upgN = upgrade[0];
while (this.upgrades.length <= upgN) {
this.upgrades.push(0);
} }
++this.upgrades[upgN];
switch (upgN) { applyAdVert(corporation: ICorporation): void {
case 0: {
//Coffee, 5% energy per employee
for (let i = 0; i < office.employees.length; ++i) {
office.employees[i].ene = Math.min(office.employees[i].ene * 1.05, office.maxEne);
}
break;
}
case 1: {
//AdVert.Inc,
const advMult = corporation.getAdvertisingMultiplier() * this.getAdvertisingMultiplier(); const advMult = corporation.getAdvertisingMultiplier() * this.getAdvertisingMultiplier();
const awareness = (this.awareness + 3 * advMult) * (1.01 * advMult); const awareness = (this.awareness + 3 * advMult) * (1.01 * advMult);
this.awareness = Math.min(awareness, Number.MAX_VALUE); this.awareness = Math.min(awareness, Number.MAX_VALUE);
const popularity = (this.popularity + 1 * advMult) * ((1 + getRandomInt(1, 3) / 100) * advMult); const popularity = (this.popularity + 1 * advMult) * ((1 + getRandomInt(1, 3) / 100) * advMult);
this.popularity = Math.min(popularity, Number.MAX_VALUE); this.popularity = Math.min(popularity, Number.MAX_VALUE);
break;
} ++this.numAdVerts;
default: {
console.error(`Un-implemented function index: ${upgN}`);
break;
}
}
} }
// Returns how much of a material can be produced based of office productivity (employee stats) // Returns how much of a material can be produced based of office productivity (employee stats)

@ -1,22 +0,0 @@
import { IMap } from "../types";
export type IndustryUpgrade = [number, number, number, number, string, string];
// Industry upgrades
// The data structure is an array with the following format:
// [index in array, base price, price mult, benefit mult (if applicable), name, desc]
export const IndustryUpgrades: IMap<IndustryUpgrade> = {
"0": [0, 500e3, 1, 1.05, "Coffee", "Provide your employees with coffee, increasing their energy by 5%."],
"1": [
1,
1e9,
1.06,
1.03,
"AdVert.Inc",
"Hire AdVert.Inc to advertise your company. Each level of " +
"this upgrade grants your company a static increase of 3 and 1 to its awareness and " +
"popularity, respectively. It will then increase your company's awareness by 1%, and its popularity " +
"by a random percentage between 1% and 3%. These effects are increased by other upgrades " +
"that increase the power of your advertising.",
],
};

@ -251,6 +251,10 @@ export class OfficeSpace {
return count === target; return count === target;
} }
getCoffeeCost(): number {
return 500e3 * this.employees.length;
}
setCoffee(mult = 1.05): boolean { setCoffee(mult = 1.05): boolean {
if (mult > 1 && this.coffeeMult === 0 && !this.autoCoffee && this.employees.length > 0) { if (mult > 1 && this.coffeeMult === 0 && !this.autoCoffee && this.employees.length > 0) {
this.coffeeMult = mult; this.coffeeMult = mult;

@ -2,11 +2,9 @@
// (top-left panel in the Industry UI) // (top-left panel in the Industry UI)
import React, { useState } from "react"; import React, { useState } from "react";
import { BuyCoffee } from "../Actions";
import { OfficeSpace } from "../OfficeSpace"; import { OfficeSpace } from "../OfficeSpace";
import { Industries } from "../IndustryData"; import { Industries } from "../IndustryData";
import { IndustryUpgrades } from "../IndustryUpgrades"; import { BuyCoffee, HireAdVert } from "../Actions";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { createProgressBarText } from "../../utils/helpers/createProgressBarText"; import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
import { MakeProductModal } from "./modals/MakeProductModal"; import { MakeProductModal } from "./modals/MakeProductModal";
@ -209,69 +207,40 @@ function Text(): React.ReactElement {
</Button> </Button>
<ResearchModal open={researchOpen} onClose={() => setResearchOpen(false)} industry={division} /> <ResearchModal open={researchOpen} onClose={() => setResearchOpen(false)} industry={division} />
</Box> </Box>
</>
);
}
function Upgrades(props: { office: OfficeSpace; rerender: () => void }): React.ReactElement { <Typography>Purchases & Upgrades</Typography>
const corp = useCorporation();
const division = useDivision();
const upgrades = [];
for (const index of Object.keys(IndustryUpgrades)) {
const upgrade = IndustryUpgrades[index];
// AutoBrew research disables the Coffee upgrade <Box display="flex" alignItems="center">
if (division.hasResearch("AutoBrew") && upgrade[4] === "Coffee") { <Tooltip title={"Provide your employees with coffee, increasing their energy by 5%."}>
continue;
}
const i = upgrade[0];
const baseCost = upgrade[1];
const priceMult = upgrade[2];
let cost = 0;
let disabled = false;
switch (i) {
case 0: //Coffee, cost is static per employee
cost = props.office.employees.length * baseCost;
disabled = cost > corp.funds || props.office.coffeeMult > 0;
break;
default:
cost = baseCost * Math.pow(priceMult, division.upgrades[i]);
disabled = cost > corp.funds;
break;
}
function onClick(): void {
if (corp.funds < cost) return;
corp.funds = corp.funds - cost;
if (i == 0) {
BuyCoffee(corp, props.office);
} else {
division.upgrade(upgrade, {
corporation: corp,
office: props.office,
});
}
props.rerender();
}
upgrades.push(
<Tooltip key={index} title={upgrade[5]}>
<span> <span>
<Button disabled={disabled} onClick={onClick}> <Button disabled={false} onClick={() => undefined}>
{upgrade[4]} -&nbsp; {"coffee"} -&nbsp;
<MoneyCost money={cost} corp={corp} /> <MoneyCost money={1e6} corp={corp} />
</Button> </Button>
</span> </span>
</Tooltip>, </Tooltip>
<Tooltip
title={
<Typography>
Hire AdVert.Inc to advertise your company. Each level of
this upgrade grants your company a static increase of 3 and 1 to its awareness and
popularity, respectively. It will then increase your company's awareness by 1%, and its popularity
by a random percentage between 1% and 3%. These effects are increased by other upgrades
that increase the power of your advertising.
</Typography>
}>
<span>
<Button disabled={division.getAdVertCost() > corp.funds} onClick={() => HireAdVert(corp, division)}>
{"Hire AdVert"} -&nbsp;
<MoneyCost money={division.getAdVertCost()} corp={corp} />
</Button>
</span>
</Tooltip>
</Box>
</>
); );
} }
return <>{upgrades}</>;
}
interface IProps { interface IProps {
currentCity: string; currentCity: string;
office: OfficeSpace; office: OfficeSpace;
@ -285,8 +254,6 @@ export function IndustryOverview(props: IProps): React.ReactElement {
<Paper> <Paper>
<Text /> <Text />
<br /> <br />
<Typography>Purchases & Upgrades</Typography>
<Upgrades office={props.office} rerender={props.rerender} /> <br />
{division.makesProducts && <MakeProductButton />} {division.makesProducts && <MakeProductButton />}
</Paper> </Paper>
); );

@ -64,7 +64,6 @@ import { calculateIntelligenceBonus } from "../PersonObjects/formulas/intelligen
import { Industry } from "../Corporation/Industry"; import { Industry } from "../Corporation/Industry";
import { IndustryResearchTrees, IndustryStartingCosts } from "../Corporation/IndustryData"; import { IndustryResearchTrees, IndustryStartingCosts } from "../Corporation/IndustryData";
import { CorporationConstants } from "../Corporation/data/Constants"; import { CorporationConstants } from "../Corporation/data/Constants";
import { IndustryUpgrades } from "../Corporation/IndustryUpgrades";
import { ResearchMap } from "../Corporation/ResearchMap"; import { ResearchMap } from "../Corporation/ResearchMap";
import { Factions } from "../Faction/Factions"; import { Factions } from "../Faction/Factions";
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
@ -303,7 +302,7 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
lastCycleExpenses: division.lastCycleExpenses, lastCycleExpenses: division.lastCycleExpenses,
thisCycleRevenue: division.thisCycleRevenue, thisCycleRevenue: division.thisCycleRevenue,
thisCycleExpenses: division.thisCycleExpenses, thisCycleExpenses: division.thisCycleExpenses,
upgrades: division.upgrades.slice(), upgrades: [0, division.numAdVerts],
cities: cities, cities: cities,
products: division.products === undefined ? [] : Object.keys(division.products), products: division.products === undefined ? [] : Object.keys(division.products),
makesProducts: division.makesProducts, makesProducts: division.makesProducts,
@ -659,8 +658,7 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = ctx.helper.string("divisionName", _divisionName); const divisionName = ctx.helper.string("divisionName", _divisionName);
const division = getDivision(divisionName); const division = getDivision(divisionName);
const upgrade = IndustryUpgrades[1]; return division.getAdVertCost();
return upgrade[1] * Math.pow(upgrade[2], division.upgrades[1]);
}, },
getHireAdVertCount: getHireAdVertCount:
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
@ -668,7 +666,7 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = ctx.helper.string("divisionName", _divisionName); const divisionName = ctx.helper.string("divisionName", _divisionName);
const division = getDivision(divisionName); const division = getDivision(divisionName);
return division.upgrades[1]; return division.numAdVerts;
}, },
getResearchCost: getResearchCost:
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
@ -802,7 +800,7 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = ctx.helper.string("divisionName", _divisionName); const divisionName = ctx.helper.string("divisionName", _divisionName);
const corporation = getCorporation(); const corporation = getCorporation();
HireAdVert(corporation, getDivision(divisionName), getOffice(divisionName, "Sector-12")); HireAdVert(corporation, getDivision(divisionName));
}, },
research: research:
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>