bitburner-src/src/NetscriptFunctions/Corporation.ts

867 lines
41 KiB
TypeScript
Raw Normal View History

NETSCRIPT: ns.sleeve.getSleeve added. getPlayer and getSleeve can both be used for formulas. (#200) * BREAKING CHANGE: Removed getSleeveStats and getSleeveInformation because this info is provided by getSleeve in a more usable form. * BREAKING CHANGE: Removed tor, inBladeburner, and hasCorporation fields from ns.getPlayer. Functionality still exists via added functions ns.hasTorRouter, ns.corporation.hasCorporation, and ns.bladeburner.inBladeburner. * Separated ns definitions for Person, Sleeve, and Player interfaces with both Player and Sleeve just extending Person. Added getSleeve, which provides a Sleeve object similar to getPlayer. * Renamed the sleeve ns layer's interface as sleeve lowercase because of name conflict. todo: May move all the ns layers interface names to lowercase for consistency * Added ns.formulas.work.crimeSuccessChance and reworked to allow both sleeve and player calculations. * Removed internal Person.getIntelligenceBonus function which was just a wrapper for calculateIntelligenceBonus. Any use of the former in formulas creates a conflict where ns-provided Person objects throw an error. * Renamed helpers.player to helpers.person for netscript person validation. Reduced number of fields validated due to Person being a smaller interface. * Fixed bug in bladeburner where Player multipliers and int were being used no matter which person was performing the task * Fixed leak of Player.jobs at ns.getPlayer * Person / Player / Sleeve classes now implement the netscript equivalent interfaces. Netscript helper for person no longer asserts that it's a real Person class member, only that it's a Person interface. Functions that use netscript persons have been changed to expect just a person interface to prevent needing this incorrect type assertion.
2022-11-09 13:26:26 +01:00
import { Player, Player as player } from "../Player";
2021-10-14 09:22:02 +02:00
import { OfficeSpace } from "../Corporation/OfficeSpace";
import { Product } from "../Corporation/Product";
import { Material } from "../Corporation/Material";
import { Warehouse } from "../Corporation/Warehouse";
import { Division } from "../Corporation/Division";
2022-09-20 12:47:54 +02:00
import { Corporation } from "../Corporation/Corporation";
import { cloneDeep, omit } from "lodash";
2021-12-04 05:06:04 +01:00
import {
Corporation as NSCorporation,
Division as NSDivision,
WarehouseAPI,
OfficeAPI,
2022-03-30 02:24:04 +02:00
InvestmentOffer,
CorpResearchName,
CorpMaterialName,
} from "@nsdefs";
2021-10-14 09:22:02 +02:00
import {
NewDivision,
purchaseOffice,
2021-10-14 09:22:02 +02:00
IssueDividends,
IssueNewShares,
2021-10-14 09:22:02 +02:00
SellMaterial,
SellProduct,
SetSmartSupply,
BuyMaterial,
UpgradeOfficeSize,
purchaseWarehouse,
2021-10-14 09:22:02 +02:00
UpgradeWarehouse,
BuyTea,
ThrowParty,
2021-10-14 09:22:02 +02:00
HireAdVert,
MakeProduct,
Research,
ExportMaterial,
CancelExportMaterial,
SetMaterialMarketTA1,
SetMaterialMarketTA2,
SetProductMarketTA1,
SetProductMarketTA2,
BulkPurchase,
SellShares,
BuyBackShares,
SetSmartSupplyOption,
LimitMaterialProduction,
LimitProductProduction,
UpgradeWarehouseCost,
2021-10-14 09:22:02 +02:00
} from "../Corporation/Actions";
import { CorpUnlocks } from "../Corporation/data/CorporationUnlocks";
import { CorpUpgrades } from "../Corporation/data/CorporationUpgrades";
2023-06-26 04:53:35 +02:00
import { CorpUnlockName, CorpUpgradeName, CorpEmployeeJob, CityName, FactionName } from "@enums";
import { IndustriesData, IndustryResearchTrees } from "../Corporation/data/IndustryData";
import * as corpConstants from "../Corporation/data/Constants";
import { ResearchMap } from "../Corporation/ResearchMap";
2022-01-13 22:05:06 +01:00
import { Factions } from "../Faction/Factions";
import { currentNodeMults } from "../BitNode/BitNodeMultipliers";
2023-08-07 08:38:38 +02:00
import { InternalAPI, NetscriptContext, setRemovedFunctions } from "../Netscript/APIWrapper";
import { helpers } from "../Netscript/NetscriptHelpers";
import { getEnumHelper } from "../utils/EnumHelper";
import { MaterialInfo } from "../Corporation/MaterialInfo";
import { calculateUpgradeCost } from "../Corporation/helpers";
import { PositiveInteger } from "../types";
import { getRecordKeys } from "../Types/Record";
2021-10-14 09:22:02 +02:00
2022-08-09 21:41:47 +02:00
export function NetscriptCorporation(): InternalAPI<NSCorporation> {
2022-01-11 20:43:29 +01:00
function createCorporation(corporationName: string, selfFund = true): boolean {
NETSCRIPT: ns.sleeve.getSleeve added. getPlayer and getSleeve can both be used for formulas. (#200) * BREAKING CHANGE: Removed getSleeveStats and getSleeveInformation because this info is provided by getSleeve in a more usable form. * BREAKING CHANGE: Removed tor, inBladeburner, and hasCorporation fields from ns.getPlayer. Functionality still exists via added functions ns.hasTorRouter, ns.corporation.hasCorporation, and ns.bladeburner.inBladeburner. * Separated ns definitions for Person, Sleeve, and Player interfaces with both Player and Sleeve just extending Person. Added getSleeve, which provides a Sleeve object similar to getPlayer. * Renamed the sleeve ns layer's interface as sleeve lowercase because of name conflict. todo: May move all the ns layers interface names to lowercase for consistency * Added ns.formulas.work.crimeSuccessChance and reworked to allow both sleeve and player calculations. * Removed internal Person.getIntelligenceBonus function which was just a wrapper for calculateIntelligenceBonus. Any use of the former in formulas creates a conflict where ns-provided Person objects throw an error. * Renamed helpers.player to helpers.person for netscript person validation. Reduced number of fields validated due to Person being a smaller interface. * Fixed bug in bladeburner where Player multipliers and int were being used no matter which person was performing the task * Fixed leak of Player.jobs at ns.getPlayer * Person / Player / Sleeve classes now implement the netscript equivalent interfaces. Netscript helper for person no longer asserts that it's a real Person class member, only that it's a Person interface. Functions that use netscript persons have been changed to expect just a person interface to prevent needing this incorrect type assertion.
2022-11-09 13:26:26 +01:00
if (!player.canAccessCorporation() || player.corporation) return false;
2022-01-11 20:43:29 +01:00
if (!corporationName) return false;
2022-01-11 20:53:53 +01:00
if (player.bitNodeN !== 3 && !selfFund) throw new Error("cannot use seed funds outside of BitNode 3");
if (currentNodeMults.CorporationSoftcap < 0.15)
2022-04-11 15:54:50 +02:00
throw new Error(`You cannot create a corporation in Bitnode ${player.bitNodeN}`);
2022-01-11 20:43:29 +01:00
if (selfFund) {
if (!player.canAfford(150e9)) return false;
player.startCorporation(corporationName, false);
2022-01-11 20:43:29 +01:00
player.loseMoney(150e9, "corporation");
} else {
player.startCorporation(corporationName, true);
2022-01-11 20:43:29 +01:00
}
return true;
}
function hasUnlock(unlockName: CorpUnlockName): boolean {
2022-01-12 00:47:04 +01:00
const corporation = getCorporation();
return corporation.unlocks.has(unlockName);
2022-01-12 00:47:04 +01:00
}
function getUnlockCost(unlockName: CorpUnlockName): number {
return CorpUnlocks[unlockName].price;
2022-01-12 00:47:04 +01:00
}
function getUpgradeLevel(upgradeName: CorpUpgradeName): number {
2022-01-12 00:47:04 +01:00
const corporation = getCorporation();
return corporation.upgrades[upgradeName].level;
2022-01-12 00:47:04 +01:00
}
function getUpgradeLevelCost(upgradeName: CorpUpgradeName): number {
2022-01-12 00:47:04 +01:00
const corporation = getCorporation();
const cost = calculateUpgradeCost(corporation, CorpUpgrades[upgradeName], 1 as PositiveInteger);
return cost;
2022-01-12 00:47:04 +01:00
}
2022-01-13 12:42:23 +01:00
function getInvestmentOffer(): InvestmentOffer {
const corporation = getCorporation();
2022-03-30 02:24:04 +02:00
if (
corporation.fundingRound >= corpConstants.fundingRoundShares.length ||
corporation.fundingRound >= corpConstants.fundingRoundMultiplier.length ||
2022-03-30 02:24:04 +02:00
corporation.public
)
2022-01-13 12:42:23 +01:00
return {
funds: 0,
shares: 0,
2022-03-30 02:24:04 +02:00
round: corporation.fundingRound + 1, // Make more readable
2022-01-13 12:42:23 +01:00
}; // Don't throw an error here, no reason to have a second function to check if you can get investment.
const val = corporation.valuation;
const percShares = corpConstants.fundingRoundShares[corporation.fundingRound];
const roundMultiplier = corpConstants.fundingRoundMultiplier[corporation.fundingRound];
2022-01-13 12:42:23 +01:00
const funding = val * percShares * roundMultiplier;
const investShares = Math.floor(corpConstants.initialShares * percShares);
2022-01-13 12:42:23 +01:00
return {
funds: funding,
shares: investShares,
2022-03-30 02:24:04 +02:00
round: corporation.fundingRound + 1, // Make more readable
2022-01-13 12:42:23 +01:00
};
}
function acceptInvestmentOffer(): boolean {
const corporation = getCorporation();
2022-03-30 02:24:04 +02:00
if (
corporation.fundingRound >= corpConstants.fundingRoundShares.length ||
corporation.fundingRound >= corpConstants.fundingRoundMultiplier.length ||
2022-03-30 02:24:04 +02:00
corporation.public
)
return false;
const val = corporation.valuation;
const percShares = corpConstants.fundingRoundShares[corporation.fundingRound];
const roundMultiplier = corpConstants.fundingRoundMultiplier[corporation.fundingRound];
2022-01-13 12:42:23 +01:00
const funding = val * percShares * roundMultiplier;
const investShares = Math.floor(corpConstants.initialShares * percShares);
2022-01-13 12:42:23 +01:00
corporation.fundingRound++;
corporation.addFunds(funding);
corporation.numShares -= investShares;
return true;
}
function goPublic(numShares: number): boolean {
const corporation = getCorporation();
const initialSharePrice = corporation.valuation / corporation.totalShares;
if (isNaN(numShares)) throw new Error("Invalid value for number of issued shares");
if (numShares < 0) throw new Error("Invalid value for number of issued shares");
if (numShares > corporation.numShares) throw new Error("You don't have that many shares to issue!");
corporation.public = true;
corporation.sharePrice = initialSharePrice;
corporation.issuedShares = numShares;
corporation.numShares -= numShares;
corporation.addFunds(numShares * initialSharePrice);
return true;
}
function getResearchCost(division: Division, researchName: CorpResearchName): number {
const researchTree = IndustryResearchTrees[division.type];
if (researchTree === undefined) throw new Error(`No research tree for industry '${division.type}'`);
const allResearch = researchTree.getAllNodes();
if (!allResearch.includes(researchName)) throw new Error(`No research named '${researchName}'`);
const research = ResearchMap[researchName];
return research.cost;
}
function hasResearched(division: Division, researchName: CorpResearchName): boolean {
return division.researched.has(researchName);
}
2023-06-26 04:53:35 +02:00
function bribe(factionName: FactionName, amountCash: number): boolean {
if (isNaN(amountCash) || amountCash < 0)
2022-10-09 07:32:44 +02:00
throw new Error("Invalid value for amount field! Must be numeric, greater than 0.");
2022-01-13 22:05:06 +01:00
const corporation = getCorporation();
if (corporation.funds < amountCash) return false;
2022-03-30 02:24:04 +02:00
const faction = Factions[factionName];
2022-01-13 22:05:06 +01:00
const info = faction.getInfo();
if (!info.offersWork()) return false;
if (player.hasGangWith(factionName)) return false;
const repGain = amountCash / corpConstants.bribeAmountPerReputation;
2022-01-13 22:05:06 +01:00
faction.playerReputation += repGain;
corporation.funds = corporation.funds - amountCash;
return true;
}
2022-09-20 12:47:54 +02:00
function getCorporation(): Corporation {
2021-10-14 09:22:02 +02:00
const corporation = player.corporation;
if (corporation === null) throw new Error("cannot be called without a corporation");
2021-12-04 05:06:04 +01:00
return corporation;
}
function getDivision(divisionName: string): Division {
2021-12-04 05:06:04 +01:00
const corporation = getCorporation();
const division = corporation.divisions.get(divisionName);
2021-10-14 09:22:02 +02:00
if (division === undefined) throw new Error(`No division named '${divisionName}'`);
return division;
}
function getOffice(divisionName: string, cityName: CityName): OfficeSpace {
2021-10-14 09:22:02 +02:00
const division = getDivision(divisionName);
const office = division.offices[cityName];
if (!office) throw new Error(`${division.name} has not expanded to '${cityName}'`);
2021-10-14 09:22:02 +02:00
return office;
}
function getWarehouse(divisionName: string, cityName: CityName): Warehouse {
2021-10-14 09:22:02 +02:00
const division = getDivision(divisionName);
const warehouse = division.warehouses[cityName];
if (!warehouse) throw new Error(`${division.name} does not have a warehouse in '${cityName}'`);
2021-10-14 09:22:02 +02:00
return warehouse;
}
function getMaterial(divisionName: string, cityName: CityName, materialName: CorpMaterialName): Material {
2021-10-14 09:22:02 +02:00
const warehouse = getWarehouse(divisionName, cityName);
const material = warehouse.materials[materialName];
2021-10-14 09:22:02 +02:00
return material;
}
function getProduct(divisionName: string, productName: string): Product {
2021-10-14 09:22:02 +02:00
const division = getDivision(divisionName);
const product = division.products.get(productName);
2021-10-14 09:22:02 +02:00
if (product === undefined) throw new Error(`Invalid product name: '${productName}'`);
return product;
}
function checkAccess(ctx: NetscriptContext, api?: CorpUnlockName): void {
if (!player.corporation) throw helpers.makeRuntimeErrorMsg(ctx, "Must own a corporation.");
2021-12-04 05:06:04 +01:00
if (!api) return;
if (!player.corporation.unlocks.has(api)) {
2022-08-08 19:43:41 +02:00
throw helpers.makeRuntimeErrorMsg(ctx, "You do not have access to this API.");
}
2021-12-04 05:06:04 +01:00
}
function getSafeDivision(division: Division): NSDivision {
const cities = getRecordKeys(division.offices);
return {
name: division.name,
type: division.type,
awareness: division.awareness,
popularity: division.popularity,
productionMult: division.productionMult,
researchPoints: division.researchPoints,
lastCycleRevenue: division.lastCycleRevenue,
lastCycleExpenses: division.lastCycleExpenses,
thisCycleRevenue: division.thisCycleRevenue,
thisCycleExpenses: division.thisCycleExpenses,
numAdVerts: division.numAdVerts,
cities: cities,
products: [...division.products.keys()],
makesProducts: division.makesProducts,
maxProducts: division.maxProducts,
};
}
2022-05-08 01:08:07 +02:00
const warehouseAPI: InternalAPI<WarehouseAPI> = {
getUpgradeWarehouseCost:
(ctx) =>
(_divisionName, _cityName, _amt = 1) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
2022-08-08 19:43:41 +02:00
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
2022-08-08 19:43:41 +02:00
const amt = helpers.number(ctx, "amount", _amt);
2022-05-08 01:08:07 +02:00
if (amt < 1) {
2022-08-08 19:43:41 +02:00
throw helpers.makeRuntimeErrorMsg(ctx, "You must provide a positive number");
2022-05-08 01:08:07 +02:00
}
const warehouse = getWarehouse(divisionName, cityName);
return UpgradeWarehouseCost(warehouse, amt);
},
hasWarehouse: (ctx) => (_divisionName, _cityName) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const division = getDivision(divisionName);
return cityName in division.warehouses;
},
getWarehouse: (ctx) => (_divisionName, _cityName) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const warehouse = getWarehouse(divisionName, cityName);
return {
level: warehouse.level,
city: warehouse.city,
size: warehouse.size,
sizeUsed: warehouse.sizeUsed,
smartSupplyEnabled: warehouse.smartSupplyEnabled,
};
},
getMaterial: (ctx) => (_divisionName, _cityName, _materialName) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
const material = getMaterial(divisionName, cityName, materialName);
const corporation = getCorporation();
const exports = cloneDeep(material.exports);
return {
marketPrice: material.marketPrice,
desiredSellPrice: material.desiredSellPrice,
desiredSellAmount: material.desiredSellAmount,
name: material.name,
stored: material.stored,
quality: material.quality,
demand: corporation.unlocks.has(CorpUnlockName.MarketResearchDemand) ? material.demand : undefined,
competition: corporation.unlocks.has(CorpUnlockName.MarketDataCompetition) ? material.competition : undefined,
productionAmount: material.productionAmount,
actualSellAmount: material.actualSellAmount,
exports: exports,
};
},
getProduct: (ctx) => (_divisionName, _cityName, _productName) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const productName = helpers.string(ctx, "productName", _productName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const product = getProduct(divisionName, productName);
const corporation = getCorporation();
const cityData = product.cityData[cityName];
return {
name: product.name,
demand: corporation.unlocks.has(CorpUnlockName.MarketResearchDemand) ? product.demand : undefined,
competition: corporation.unlocks.has(CorpUnlockName.MarketDataCompetition) ? product.competition : undefined,
rating: product.rating,
effectiveRating: cityData.effectiveRating,
stats: cloneDeep(product.stats),
productionCost: product.productionCost,
desiredSellPrice: cityData.desiredSellPrice,
desiredSellAmount: cityData.desiredSellAmount,
stored: cityData.stored,
productionAmount: cityData.productionAmount,
actualSellAmount: cityData.actualSellAmount,
developmentProgress: product.developmentProgress,
advertisingInvestment: product.advertisingInvestment,
designInvestment: product.designInvestment,
};
},
purchaseWarehouse: (ctx) => (_divisionName, _cityName) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const corporation = getCorporation();
purchaseWarehouse(corporation, getDivision(divisionName), cityName);
},
2022-05-08 01:08:07 +02:00
upgradeWarehouse:
(ctx) =>
(_divisionName, _cityName, _amt = 1): void => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
2022-08-08 19:43:41 +02:00
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
2022-08-08 19:43:41 +02:00
const amt = helpers.number(ctx, "amount", _amt);
2022-05-08 01:08:07 +02:00
const corporation = getCorporation();
if (amt < 1) {
2022-08-08 19:43:41 +02:00
throw helpers.makeRuntimeErrorMsg(ctx, "You must provide a positive number");
2022-05-08 01:08:07 +02:00
}
UpgradeWarehouse(corporation, getDivision(divisionName), getWarehouse(divisionName, cityName), amt);
},
sellMaterial: (ctx) => (_divisionName, _cityName, _materialName, _amt, _price) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
const amt = helpers.string(ctx, "amt", _amt);
const price = helpers.string(ctx, "price", _price);
const material = getMaterial(divisionName, cityName, materialName);
SellMaterial(material, amt, price);
},
2022-05-08 01:08:07 +02:00
sellProduct:
(ctx) =>
(_divisionName, _cityName, _productName, _amt, _price, _all): void => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
2022-08-08 19:43:41 +02:00
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
2022-08-08 19:43:41 +02:00
const productName = helpers.string(ctx, "productName", _productName);
const amt = helpers.string(ctx, "amt", _amt);
const price = helpers.string(ctx, "price", _price);
const all = !!_all;
const product = getProduct(divisionName, productName);
2022-05-08 01:08:07 +02:00
SellProduct(product, cityName, amt, price, all);
},
discontinueProduct: (ctx) => (_divisionName, _productName) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const productName = helpers.string(ctx, "productName", _productName);
getDivision(divisionName).discontinueProduct(productName);
},
setSmartSupply: (ctx) => (_divisionName, _cityName, _enabled) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const enabled = !!_enabled;
const warehouse = getWarehouse(divisionName, cityName);
if (!hasUnlock(CorpUnlockName.SmartSupply))
throw helpers.makeRuntimeErrorMsg(ctx, `You have not purchased the Smart Supply upgrade!`);
SetSmartSupply(warehouse, enabled);
},
setSmartSupplyOption: (ctx) => (_divisionName, _cityName, _materialName, _option) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
const warehouse = getWarehouse(divisionName, cityName);
const material = getMaterial(divisionName, cityName, materialName);
const option = getEnumHelper("SmartSupplyOption").nsGetMember(ctx, _option);
if (!hasUnlock(CorpUnlockName.SmartSupply))
throw helpers.makeRuntimeErrorMsg(ctx, `You have not purchased the Smart Supply upgrade!`);
SetSmartSupplyOption(warehouse, material, option);
},
buyMaterial: (ctx) => (_divisionName, _cityName, _materialName, _amt) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const division = getCorporation().divisions.get(divisionName);
if (!division) throw helpers.makeRuntimeErrorMsg(ctx, `No division with provided name ${divisionName}`);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
const amt = helpers.number(ctx, "amt", _amt);
if (amt < 0 || !Number.isFinite(amt))
throw new Error("Invalid value for amount field! Must be numeric and greater than 0");
const material = getMaterial(divisionName, cityName, materialName);
BuyMaterial(division, material, amt);
},
bulkPurchase: (ctx) => (_divisionName, _cityName, _materialName, _amt) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const division = getCorporation().divisions.get(divisionName);
if (!division) throw helpers.makeRuntimeErrorMsg(ctx, `No division with provided name ${divisionName}`);
const corporation = getCorporation();
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
const amt = helpers.number(ctx, "amt", _amt);
const warehouse = getWarehouse(divisionName, cityName);
const material = getMaterial(divisionName, cityName, materialName);
BulkPurchase(corporation, division, warehouse, material, amt);
},
2022-05-08 01:08:07 +02:00
makeProduct:
(ctx) =>
(_divisionName, _cityName, _productName, _designInvest, _marketingInvest): void => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
2022-08-08 19:43:41 +02:00
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
2022-08-08 19:43:41 +02:00
const productName = helpers.string(ctx, "productName", _productName);
const designInvest = helpers.number(ctx, "designInvest", _designInvest);
const marketingInvest = helpers.number(ctx, "marketingInvest", _marketingInvest);
2022-05-08 01:08:07 +02:00
const corporation = getCorporation();
MakeProduct(corporation, getDivision(divisionName), cityName, productName, designInvest, marketingInvest);
},
limitProductProduction: (ctx) => (_divisionName, _cityName, _productName, _qty) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const productName = helpers.string(ctx, "productName", _productName);
const qty = helpers.number(ctx, "qty", _qty);
LimitProductProduction(getProduct(divisionName, productName), cityName, qty);
},
2022-05-08 01:08:07 +02:00
exportMaterial:
(ctx) =>
(_sourceDivision, _sourceCity, _targetDivision, _targetCity, _materialName, _amt): void => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
2022-08-08 19:43:41 +02:00
const sourceDivision = helpers.string(ctx, "sourceDivision", _sourceDivision);
const sourceCity = getEnumHelper("CityName").nsGetMember(ctx, _sourceCity, "sourceCity");
const targetDivision = getDivision(helpers.string(ctx, "targetDivision", _targetDivision));
const targetCity = getEnumHelper("CityName").nsGetMember(ctx, _targetCity, "targetCity");
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
2022-08-08 19:43:41 +02:00
const amt = helpers.string(ctx, "amt", _amt);
ExportMaterial(targetDivision, targetCity, getMaterial(sourceDivision, sourceCity, materialName), amt);
2022-05-08 01:08:07 +02:00
},
cancelExportMaterial:
(ctx) =>
(_sourceDivision, _sourceCity, _targetDivision, _targetCity, _materialName): void => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
2022-08-08 19:43:41 +02:00
const sourceDivision = helpers.string(ctx, "sourceDivision", _sourceDivision);
const sourceCity = getEnumHelper("CityName").nsGetMember(ctx, _sourceCity, "sourceCity");
2022-08-08 19:43:41 +02:00
const targetDivision = helpers.string(ctx, "targetDivision", _targetDivision);
const targetCity = getEnumHelper("CityName").nsGetMember(ctx, _targetCity, "targetCity");
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
CancelExportMaterial(targetDivision, targetCity, getMaterial(sourceDivision, sourceCity, materialName));
2022-05-08 01:08:07 +02:00
},
limitMaterialProduction: (ctx) => (_divisionName, _cityName, _materialName, _qty) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
const qty = helpers.number(ctx, "qty", _qty);
LimitMaterialProduction(getMaterial(divisionName, cityName, materialName), qty);
},
setMaterialMarketTA1: (ctx) => (_divisionName, _cityName, _materialName, _on) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
const on = !!_on;
if (!getDivision(divisionName).hasResearch("Market-TA.I"))
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.I for division: ${divisionName}`);
SetMaterialMarketTA1(getMaterial(divisionName, cityName, materialName), on);
},
setMaterialMarketTA2: (ctx) => (_divisionName, _cityName, _materialName, _on) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
const on = !!_on;
if (!getDivision(divisionName).hasResearch("Market-TA.II"))
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.II for division: ${divisionName}`);
SetMaterialMarketTA2(getMaterial(divisionName, cityName, materialName), on);
},
setProductMarketTA1: (ctx) => (_divisionName, _productName, _on) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const productName = helpers.string(ctx, "productName", _productName);
const on = !!_on;
if (!getDivision(divisionName).hasResearch("Market-TA.I"))
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.I for division: ${divisionName}`);
SetProductMarketTA1(getProduct(divisionName, productName), on);
},
setProductMarketTA2: (ctx) => (_divisionName, _productName, _on) => {
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const productName = helpers.string(ctx, "productName", _productName);
const on = !!_on;
if (!getDivision(divisionName).hasResearch("Market-TA.II"))
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.II for division: ${divisionName}`);
SetProductMarketTA2(getProduct(divisionName, productName), on);
},
2021-12-04 05:06:04 +01:00
};
2022-05-08 01:08:07 +02:00
const officeAPI: InternalAPI<OfficeAPI> = {
getHireAdVertCost: (ctx) => (_divisionName) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const division = getDivision(divisionName);
return division.getAdVertCost();
},
getHireAdVertCount: (ctx) => (_divisionName) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const division = getDivision(divisionName);
return division.numAdVerts;
},
getResearchCost: (ctx) => (_divisionName, _researchName) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const researchName = getEnumHelper("CorpResearchName").nsGetMember(ctx, _researchName, "researchName");
return getResearchCost(getDivision(divisionName), researchName);
},
hasResearched: (ctx) => (_divisionName, _researchName) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const researchName = getEnumHelper("CorpResearchName").nsGetMember(ctx, _researchName, "researchName");
return hasResearched(getDivision(divisionName), researchName);
},
getOfficeSizeUpgradeCost: (ctx) => (_divisionName, _cityName, _size) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const size = helpers.number(ctx, "size", _size);
if (size < 0) throw new Error("Invalid value for size field! Must be numeric and greater than 0");
const office = getOffice(divisionName, cityName);
const initialPriceMult = Math.round(office.size / corpConstants.officeInitialSize);
const costMultiplier = 1.09;
let mult = 0;
for (let i = 0; i < size / corpConstants.officeInitialSize; ++i) {
mult += Math.pow(costMultiplier, initialPriceMult + i);
}
return corpConstants.officeInitialCost * mult;
},
setAutoJobAssignment: (ctx) => (_divisionName, _cityName, _job, _amount) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const amount = helpers.number(ctx, "amount", _amount);
const job = getEnumHelper("CorpEmployeeJob").nsGetMember(ctx, _job, "job");
if (job === CorpEmployeeJob.Unassigned) return false;
if (amount < 0 || !Number.isInteger(amount))
throw helpers.makeRuntimeErrorMsg(
ctx,
`Invalid value for amount! Must be an integer and greater than or be 0". Amount:'${amount}'`,
);
const office = getOffice(divisionName, cityName);
const totalNewEmployees = amount - office.employeeNextJobs[job];
if (office.employeeNextJobs[CorpEmployeeJob.Unassigned] < totalNewEmployees)
throw helpers.makeRuntimeErrorMsg(
ctx,
`Unable to bring '${job} employees to ${amount}. Requires ${totalNewEmployees} unassigned employees`,
);
2023-01-29 14:14:12 +01:00
return office.autoAssignJob(job, amount);
},
hireEmployee: (ctx) => (_divisionName, _cityName, _position) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
_position ??= CorpEmployeeJob.Unassigned;
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const position = getEnumHelper("CorpEmployeeJob").nsGetMember(ctx, _position, "position");
const office = getOffice(divisionName, cityName);
return office.hireRandomEmployee(position);
},
upgradeOfficeSize: (ctx) => (_divisionName, _cityName, _size) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const size = helpers.number(ctx, "size", _size);
if (size < 0) throw new Error("Invalid value for size field! Must be numeric and greater than 0");
const office = getOffice(divisionName, cityName);
const corporation = getCorporation();
UpgradeOfficeSize(corporation, office, size);
},
throwParty: (ctx) => (_divisionName, _cityName, _costPerEmployee) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const costPerEmployee = helpers.number(ctx, "costPerEmployee", _costPerEmployee);
if (costPerEmployee < 0) {
throw new Error("Invalid value for Cost Per Employee field! Must be numeric and greater than 0");
}
const corporation = getCorporation();
const office = getOffice(divisionName, cityName);
return ThrowParty(corporation, office, costPerEmployee);
},
buyTea: (ctx) => (_divisionName, _cityName) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const corporation = getCorporation();
const office = getOffice(divisionName, cityName);
return BuyTea(corporation, office);
},
hireAdVert: (ctx) => (_divisionName) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const corporation = getCorporation();
HireAdVert(corporation, getDivision(divisionName));
},
research: (ctx) => (_divisionName, _researchName) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const researchName = getEnumHelper("CorpResearchName").nsGetMember(ctx, _researchName, "researchName");
Research(getDivision(divisionName), researchName);
},
getOffice: (ctx) => (_divisionName, _cityName) => {
checkAccess(ctx, CorpUnlockName.OfficeAPI);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const office = getOffice(divisionName, cityName);
return {
city: office.city,
size: office.size,
maxEnergy: office.maxEnergy,
maxMorale: office.maxMorale,
numEmployees: office.numEmployees,
avgEnergy: office.avgEnergy,
avgMorale: office.avgMorale,
totalExperience: office.totalExperience,
employeeProductionByJob: Object.assign({}, office.employeeProductionByJob),
employeeJobs: Object.assign({}, office.employeeJobs),
};
},
2021-12-04 05:06:04 +01:00
};
// TODO 2.2: Add removed function error dialogs for all the functions removed/replaced by getConstants.
const corpFunctions: InternalAPI<NSCorporation> = {
2021-12-04 05:06:04 +01:00
...warehouseAPI,
...officeAPI,
NETSCRIPT: ns.sleeve.getSleeve added. getPlayer and getSleeve can both be used for formulas. (#200) * BREAKING CHANGE: Removed getSleeveStats and getSleeveInformation because this info is provided by getSleeve in a more usable form. * BREAKING CHANGE: Removed tor, inBladeburner, and hasCorporation fields from ns.getPlayer. Functionality still exists via added functions ns.hasTorRouter, ns.corporation.hasCorporation, and ns.bladeburner.inBladeburner. * Separated ns definitions for Person, Sleeve, and Player interfaces with both Player and Sleeve just extending Person. Added getSleeve, which provides a Sleeve object similar to getPlayer. * Renamed the sleeve ns layer's interface as sleeve lowercase because of name conflict. todo: May move all the ns layers interface names to lowercase for consistency * Added ns.formulas.work.crimeSuccessChance and reworked to allow both sleeve and player calculations. * Removed internal Person.getIntelligenceBonus function which was just a wrapper for calculateIntelligenceBonus. Any use of the former in formulas creates a conflict where ns-provided Person objects throw an error. * Renamed helpers.player to helpers.person for netscript person validation. Reduced number of fields validated due to Person being a smaller interface. * Fixed bug in bladeburner where Player multipliers and int were being used no matter which person was performing the task * Fixed leak of Player.jobs at ns.getPlayer * Person / Player / Sleeve classes now implement the netscript equivalent interfaces. Netscript helper for person no longer asserts that it's a real Person class member, only that it's a Person interface. Functions that use netscript persons have been changed to expect just a person interface to prevent needing this incorrect type assertion.
2022-11-09 13:26:26 +01:00
hasCorporation: () => () => !!Player.corporation,
getConstants: (ctx) => () => {
checkAccess(ctx);
/* TODO 2.2: possibly just rework the whole corp constants structure to be more readable, and just use cloneDeep
* to provide it directly to player.
* TODO 2.2: Roll product information into industriesData, there's no reason to look up a product separately */
// TODO: add functions for getting materialInfo and research info
return cloneDeep(omit(corpConstants, "fundingRoundShares", "fundingRoundMultiplier", "valuationLength"));
},
getIndustryData: (ctx) => (_industryName) => {
checkAccess(ctx);
const industryName = getEnumHelper("IndustryType").nsGetMember(ctx, _industryName, "industryName");
return cloneDeep(IndustriesData[industryName]);
},
getMaterialData: (ctx) => (_materialName) => {
checkAccess(ctx);
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
return cloneDeep(MaterialInfo[materialName]);
2022-08-10 00:25:02 +02:00
},
expandIndustry: (ctx) => (_industryName, _divisionName) => {
checkAccess(ctx);
const industryName = getEnumHelper("IndustryType").nsGetMember(ctx, _industryName, "industryName");
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const corporation = getCorporation();
NewDivision(corporation, industryName, divisionName);
},
expandCity: (ctx) => (_divisionName, _cityName) => {
checkAccess(ctx);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
const corporation = getCorporation();
const division = getDivision(divisionName);
purchaseOffice(corporation, division, cityName);
},
purchaseUnlock: (ctx) => (_unlockName) => {
checkAccess(ctx);
const unlockName = getEnumHelper("CorpUnlockName").nsGetMember(ctx, _unlockName, "unlockName");
const corporation = getCorporation();
const message = corporation.purchaseUnlock(unlockName);
if (message) throw new Error(`Could not unlock ${unlockName}: ${message}`);
},
levelUpgrade: (ctx) => (_upgradeName) => {
checkAccess(ctx);
const upgradeName = getEnumHelper("CorpUpgradeName").nsGetMember(ctx, _upgradeName, "upgradeName");
const corporation = getCorporation();
const message = corporation.purchaseUpgrade(upgradeName, 1);
if (message) throw new Error(`Could not upgrade ${upgradeName}: ${message}`);
},
issueDividends: (ctx) => (_rate) => {
checkAccess(ctx);
const rate = helpers.number(ctx, "rate", _rate);
const max = corpConstants.dividendMaxRate;
if (rate < 0 || rate > max)
throw new Error(`Invalid value for rate field! Must be numeric, greater than 0, and less than ${max}`);
const corporation = getCorporation();
if (!corporation.public) throw helpers.makeRuntimeErrorMsg(ctx, `Your company has not gone public!`);
IssueDividends(corporation, rate);
},
issueNewShares: (ctx) => (_amount) => {
checkAccess(ctx);
const corporation = getCorporation();
const maxNewShares = corporation.calculateMaxNewShares();
if (_amount == undefined) _amount = maxNewShares;
const amount = helpers.number(ctx, "amount", _amount);
if (corporation.issueNewSharesCooldown > 0) throw new Error(`Can't issue new shares, action on cooldown.`);
if (amount < 10e6 || amount > maxNewShares)
throw new Error(
`Invalid value for amount field! Must be numeric, greater than 10m, and less than ${maxNewShares} (20% of total shares)`,
);
if (!corporation.public) throw helpers.makeRuntimeErrorMsg(ctx, `Your company has not gone public!`);
const [funds] = IssueNewShares(corporation, amount);
return funds;
},
getDivision: (ctx) => (_divisionName) => {
checkAccess(ctx);
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const division = getDivision(divisionName);
return getSafeDivision(division);
},
getCorporation: (ctx) => () => {
2022-05-08 01:08:07 +02:00
checkAccess(ctx);
2021-12-04 05:06:04 +01:00
const corporation = getCorporation();
return {
name: corporation.name,
funds: corporation.funds,
revenue: corporation.revenue,
expenses: corporation.expenses,
public: corporation.public,
totalShares: corporation.totalShares,
numShares: corporation.numShares,
shareSaleCooldown: corporation.shareSaleCooldown,
issuedShares: corporation.issuedShares,
sharePrice: corporation.sharePrice,
dividendRate: corporation.dividendRate,
dividendTax: corporation.dividendTax,
dividendEarnings: corporation.getCycleDividends() / corpConstants.secondsPerMarketCycle,
state: corporation.state.getState(),
divisions: [...corporation.divisions.keys()],
2021-12-04 05:06:04 +01:00
};
2021-10-14 09:22:02 +02:00
},
2022-05-08 01:08:07 +02:00
createCorporation:
(ctx) =>
(_corporationName, _selfFund = true): boolean => {
2022-08-08 19:43:41 +02:00
const corporationName = helpers.string(ctx, "corporationName", _corporationName);
2022-08-20 16:37:39 +02:00
const selfFund = !!_selfFund;
2022-05-08 01:08:07 +02:00
return createCorporation(corporationName, selfFund);
},
hasUnlock: (ctx) => (_unlockName) => {
checkAccess(ctx);
const unlockName = getEnumHelper("CorpUnlockName").nsGetMember(ctx, _unlockName, "unlockName");
return hasUnlock(unlockName);
},
getUnlockCost: (ctx) => (_unlockName) => {
checkAccess(ctx);
const unlockName = getEnumHelper("CorpUnlockName").nsGetMember(ctx, _unlockName, "unlockName");
return getUnlockCost(unlockName);
},
getUpgradeLevel: (ctx) => (_upgradeName) => {
checkAccess(ctx);
const upgradeName = getEnumHelper("CorpUpgradeName").nsGetMember(ctx, _upgradeName, "upgradeName");
return getUpgradeLevel(upgradeName);
},
getUpgradeLevelCost: (ctx) => (_upgradeName) => {
checkAccess(ctx);
const upgradeName = getEnumHelper("CorpUpgradeName").nsGetMember(ctx, _upgradeName, "upgradeName");
return getUpgradeLevelCost(upgradeName);
},
getInvestmentOffer: (ctx) => () => {
2022-05-08 01:08:07 +02:00
checkAccess(ctx);
2022-01-13 12:42:23 +01:00
return getInvestmentOffer();
},
acceptInvestmentOffer: (ctx) => () => {
2022-05-08 01:08:07 +02:00
checkAccess(ctx);
2022-01-13 12:42:23 +01:00
return acceptInvestmentOffer();
},
goPublic: (ctx) => (_numShares) => {
checkAccess(ctx);
2022-11-29 14:24:04 +01:00
const corporation = getCorporation();
if (corporation.public) throw helpers.makeRuntimeErrorMsg(ctx, "corporation is already public");
const numShares = helpers.number(ctx, "numShares", _numShares);
return goPublic(numShares);
},
sellShares: (ctx) => (_numShares) => {
checkAccess(ctx);
const numShares = helpers.number(ctx, "numShares", _numShares);
return SellShares(getCorporation(), numShares);
},
buyBackShares: (ctx) => (_numShares) => {
checkAccess(ctx);
const numShares = helpers.number(ctx, "numShares", _numShares);
return BuyBackShares(getCorporation(), numShares);
},
bribe: (ctx) => (_factionName, _amountCash) => {
checkAccess(ctx);
2023-06-26 04:53:35 +02:00
const factionName = getEnumHelper("FactionName").nsGetMember(ctx, _factionName);
const amountCash = helpers.number(ctx, "amountCash", _amountCash);
return bribe(factionName, amountCash);
},
getBonusTime: (ctx) => () => {
2022-05-08 01:08:07 +02:00
checkAccess(ctx);
return Math.round(getCorporation().storedCycles / 5) * 1000;
2022-03-30 02:24:04 +02:00
},
2021-10-14 09:22:02 +02:00
};
2023-01-02 19:18:02 +01:00
2023-08-07 08:38:38 +02:00
// Removed functions
setRemovedFunctions(corpFunctions, {
assignJob: {
version: "2.2.0",
replacement: "Removed due to employees no longer being objects. Use ns.corporation.setAutoJobAssignment instead.",
replaceMsg: true,
},
getEmployee: {
version: "2.2.0",
replacement: "Removed due to employees no longer being individual objects.",
replaceMsg: true,
},
getExpandCityCost: { version: "2.2.0", replacement: "corporation.getConstants().officeInitialCost" },
getExpandIndustryCost: { version: "2.2.0", replacement: "corporation.getIndustryData" },
getIndustryTypes: { version: "2.2.0", replacement: "corporation.getConstants().industryNames" },
getMaterialNames: { version: "2.2.0", replacement: "corporation.getConstants().materialNames" },
getPurchaseWarehouseCost: { version: "2.2.0", replacement: "corporation.getConstants().warehouseInitialCost" },
getResearchNames: { version: "2.2.0", replacement: "corporation.getConstants().researchNames" },
getUnlockables: { version: "2.2.0", replacement: "corporation.getConstants().unlockNames" },
getUpgradeNames: { version: "2.2.0", replacement: "corporation.getConstants().upgradeNames" },
});
return corpFunctions;
2021-10-14 09:22:02 +02:00
}