bitburner-src/src/Corporation/Actions.ts

280 lines
9.1 KiB
TypeScript
Raw Normal View History

2021-09-02 04:16:48 +02:00
import { ICorporation } from "./ICorporation";
import { IIndustry } from "./IIndustry";
import { IndustryStartingCosts } from "./IndustryData";
import { Industry } from "./Industry";
import { CorporationConstants } from "./data/Constants";
import { OfficeSpace } from "./OfficeSpace";
2021-09-02 06:36:33 +02:00
import { Material } from "./Material";
import { Product } from "./Product";
import { Warehouse } from "./Warehouse";
2021-09-02 04:16:48 +02:00
import { CorporationUnlockUpgrade } from "./data/CorporationUnlockUpgrades";
import { CorporationUpgrade } from "./data/CorporationUpgrades";
2021-09-02 06:36:33 +02:00
import { Cities } from "../Locations/Cities";
2021-09-10 06:13:28 +02:00
import { EmployeePositions } from "./EmployeePositions";
2021-09-02 04:16:48 +02:00
2021-09-09 05:47:34 +02:00
export function NewIndustry(corporation: ICorporation, industry: string, name: string): void {
2021-09-05 01:09:30 +02:00
for (let i = 0; i < corporation.divisions.length; ++i) {
if (corporation.divisions[i].name === name) {
throw new Error("This division name is already in use!");
return;
2021-09-02 04:16:48 +02:00
}
2021-09-05 01:09:30 +02:00
}
2021-09-02 04:16:48 +02:00
2021-09-05 01:09:30 +02:00
const cost = IndustryStartingCosts[industry];
if (cost === undefined) {
2021-09-06 21:06:08 +02:00
throw new Error(`Invalid industry: '${industry}'`);
2021-09-05 01:09:30 +02:00
}
if (corporation.funds.lt(cost)) {
2021-09-09 05:47:34 +02:00
throw new Error("Not enough money to create a new division in this industry");
2021-09-05 01:09:30 +02:00
} else if (name === "") {
throw new Error("New division must have a name!");
} else {
corporation.funds = corporation.funds.minus(cost);
corporation.divisions.push(
new Industry({
corp: corporation,
name: name,
type: industry,
}),
);
}
2021-09-02 04:16:48 +02:00
}
2021-09-09 05:47:34 +02:00
export function NewCity(corporation: ICorporation, division: IIndustry, city: string): void {
2021-09-05 01:09:30 +02:00
if (corporation.funds.lt(CorporationConstants.OfficeInitialCost)) {
2021-09-09 05:47:34 +02:00
throw new Error("You don't have enough company funds to open a new office!");
2021-09-05 01:09:30 +02:00
} else {
2021-09-09 05:47:34 +02:00
corporation.funds = corporation.funds.minus(CorporationConstants.OfficeInitialCost);
2021-09-05 01:09:30 +02:00
division.offices[city] = new OfficeSpace({
loc: city,
size: CorporationConstants.OfficeInitialSize,
});
}
2021-09-02 04:16:48 +02:00
}
2021-09-09 05:47:34 +02:00
export function UnlockUpgrade(corporation: ICorporation, upgrade: CorporationUnlockUpgrade): void {
2021-09-05 01:09:30 +02:00
if (corporation.funds.lt(upgrade[1])) {
throw new Error("Insufficient funds");
}
corporation.unlock(upgrade);
2021-09-02 04:16:48 +02:00
}
2021-09-09 05:47:34 +02:00
export function LevelUpgrade(corporation: ICorporation, upgrade: CorporationUpgrade): void {
2021-09-05 01:09:30 +02:00
const baseCost = upgrade[1];
const priceMult = upgrade[2];
const level = corporation.upgrades[upgrade[0]];
const cost = baseCost * Math.pow(priceMult, level);
if (corporation.funds.lt(cost)) {
throw new Error("Insufficient funds");
} else {
corporation.upgrade(upgrade);
}
2021-09-02 04:16:48 +02:00
}
2021-09-09 05:47:34 +02:00
export function IssueDividends(corporation: ICorporation, percent: number): void {
if (isNaN(percent) || percent < 0 || percent > CorporationConstants.DividendMaxPercentage) {
throw new Error(`Invalid value. Must be an integer between 0 and ${CorporationConstants.DividendMaxPercentage}`);
2021-09-05 01:09:30 +02:00
}
2021-09-02 04:16:48 +02:00
2021-09-05 01:09:30 +02:00
corporation.dividendPercentage = percent * 100;
2021-09-02 06:36:33 +02:00
}
export function SellMaterial(mat: Material, amt: string, price: string): void {
2021-09-05 01:09:30 +02:00
if (price === "") price = "0";
if (amt === "") amt = "0";
let cost = price.replace(/\s+/g, "");
cost = cost.replace(/[^-()\d/*+.MP]/g, ""); //Sanitize cost
let temp = cost.replace(/MP/g, mat.bCost + "");
try {
temp = eval(temp);
} catch (e) {
throw new Error("Invalid value or expression for sell price field: " + e);
}
if (temp == null || isNaN(parseFloat(temp))) {
throw new Error("Invalid value or expression for sell price field");
}
if (cost.includes("MP")) {
mat.sCost = cost; //Dynamically evaluated
} else {
mat.sCost = temp;
}
//Parse quantity
if (amt.includes("MAX") || amt.includes("PROD")) {
let q = amt.replace(/\s+/g, "");
q = q.replace(/[^-()\d/*+.MAXPROD]/g, "");
let tempQty = q.replace(/MAX/g, "1");
tempQty = tempQty.replace(/PROD/g, "1");
2021-09-02 06:36:33 +02:00
try {
2021-09-05 01:09:30 +02:00
tempQty = eval(tempQty);
} catch (e) {
throw new Error("Invalid value or expression for sell price field: " + e);
2021-09-02 06:36:33 +02:00
}
2021-09-05 01:09:30 +02:00
if (tempQty == null || isNaN(parseFloat(tempQty))) {
throw new Error("Invalid value or expression for sell price field");
2021-09-02 06:36:33 +02:00
}
2021-09-05 01:09:30 +02:00
mat.sllman[0] = true;
mat.sllman[1] = q; //Use sanitized input
} else if (isNaN(parseFloat(amt))) {
2021-09-09 05:47:34 +02:00
throw new Error("Invalid value for sell quantity field! Must be numeric or 'MAX'");
2021-09-05 01:09:30 +02:00
} else {
let q = parseFloat(amt);
if (isNaN(q)) {
q = 0;
}
if (q === 0) {
mat.sllman[0] = false;
mat.sllman[1] = 0;
2021-09-02 06:36:33 +02:00
} else {
2021-09-05 01:09:30 +02:00
mat.sllman[0] = true;
mat.sllman[1] = q;
2021-09-02 06:36:33 +02:00
}
2021-09-05 01:09:30 +02:00
}
}
2021-09-02 06:36:33 +02:00
2021-09-09 05:47:34 +02:00
export function SellProduct(product: Product, city: string, amt: string, price: string, all: boolean): void {
2021-09-05 01:09:30 +02:00
//Parse price
if (price.includes("MP")) {
//Dynamically evaluated quantity. First test to make sure its valid
//Sanitize input, then replace dynamic variables with arbitrary numbers
price = price.replace(/\s+/g, "");
price = price.replace(/[^-()\d/*+.MP]/g, "");
let temp = price.replace(/MP/g, "1");
try {
temp = eval(temp);
} catch (e) {
2021-09-09 05:47:34 +02:00
throw new Error("Invalid value or expression for sell quantity field: " + e);
2021-09-05 01:09:30 +02:00
}
if (temp == null || isNaN(parseFloat(temp))) {
throw new Error("Invalid value or expression for sell quantity field.");
}
product.sCost = price; //Use sanitized price
} else {
const cost = parseFloat(price);
if (isNaN(cost)) {
throw new Error("Invalid value for sell price field");
}
product.sCost = cost;
}
2021-09-02 06:36:33 +02:00
2021-09-05 01:09:30 +02:00
// Array of all cities. Used later
const cities = Object.keys(Cities);
2021-09-02 06:36:33 +02:00
2021-09-05 01:09:30 +02:00
// Parse quantity
if (amt.includes("MAX") || amt.includes("PROD")) {
//Dynamically evaluated quantity. First test to make sure its valid
let qty = amt.replace(/\s+/g, "");
qty = qty.replace(/[^-()\d/*+.MAXPROD]/g, "");
let temp = qty.replace(/MAX/g, "1");
temp = temp.replace(/PROD/g, "1");
try {
temp = eval(temp);
} catch (e) {
throw new Error("Invalid value or expression for sell price field: " + e);
2021-09-02 06:36:33 +02:00
}
2021-09-05 01:09:30 +02:00
if (temp == null || isNaN(parseFloat(temp))) {
throw new Error("Invalid value or expression for sell price field");
}
if (all) {
for (let i = 0; i < cities.length; ++i) {
const tempCity = cities[i];
product.sllman[tempCity][0] = true;
product.sllman[tempCity][1] = qty; //Use sanitized input
}
2021-09-02 06:36:33 +02:00
} else {
2021-09-05 01:09:30 +02:00
product.sllman[city][0] = true;
product.sllman[city][1] = qty; //Use sanitized input
2021-09-02 06:36:33 +02:00
}
2021-09-05 01:09:30 +02:00
} else if (isNaN(parseFloat(amt))) {
throw new Error("Invalid value for sell quantity field! Must be numeric");
} else {
let qty = parseFloat(amt);
if (isNaN(qty)) {
qty = 0;
}
if (qty === 0) {
if (all) {
for (let i = 0; i < cities.length; ++i) {
const tempCity = cities[i];
product.sllman[tempCity][0] = false;
product.sllman[tempCity][1] = "";
2021-09-02 06:36:33 +02:00
}
2021-09-05 01:09:30 +02:00
} else {
product.sllman[city][0] = false;
product.sllman[city][1] = "";
}
2021-09-02 06:36:33 +02:00
} else {
2021-09-05 01:09:30 +02:00
if (all) {
for (let i = 0; i < cities.length; ++i) {
const tempCity = cities[i];
product.sllman[tempCity][0] = true;
product.sllman[tempCity][1] = qty;
2021-09-02 06:36:33 +02:00
}
2021-09-05 01:09:30 +02:00
} else {
product.sllman[city][0] = true;
product.sllman[city][1] = qty;
}
2021-09-02 06:36:33 +02:00
}
2021-09-05 01:09:30 +02:00
}
2021-09-02 06:36:33 +02:00
}
2021-09-09 05:47:34 +02:00
export function SetSmartSupply(warehouse: Warehouse, smartSupply: boolean): void {
2021-09-05 01:09:30 +02:00
warehouse.smartSupplyEnabled = smartSupply;
2021-09-03 22:02:41 +02:00
}
export function BuyMaterial(material: Material, amt: number): void {
2021-09-05 01:09:30 +02:00
if (isNaN(amt)) {
2021-09-09 05:47:34 +02:00
throw new Error(`Invalid amount '${amt}' to buy material '${material.name}'`);
2021-09-05 01:09:30 +02:00
}
material.buy = amt;
}
2021-09-10 06:13:28 +02:00
export function AssignJob(employee: Employee, job: string): void {
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
employee.pos = job;
}
export function UpgradeOfficeSize(corp: ICorporation, office: OfficeSpace, size: number): void {
const initialPriceMult = Math.round(office.size / CorporationConstants.OfficeInitialSize);
const costMultiplier = 1.09;
// Calculate cost to upgrade size by 15 employees
let mult = 0;
for (let i = 0; i < size / CorporationConstants.OfficeInitialSize; ++i) {
mult += Math.pow(costMultiplier, initialPriceMult + i);
}
const cost = CorporationConstants.OfficeInitialCost * mult;
console.log(cost);
if (corp.funds.lt(cost)) return;
office.size += size;
corp.funds = corp.funds.minus(cost);
}
export function ThrowParty(corp: ICorporation, office: OfficeSpace, costPerEmployee: number): number {
const totalCost = costPerEmployee * office.employees.length;
if (corp.funds.lt(totalCost)) return 0;
corp.funds = corp.funds.minus(totalCost);
let mult = 0;
for (let i = 0; i < office.employees.length; ++i) {
mult = office.employees[i].throwParty(costPerEmployee);
}
return mult;
}
export function PurchaseWarehouse(corp: ICorporation, division: IIndustry, city: string): void {
if (corp.funds.lt(CorporationConstants.WarehouseInitialCost)) return;
if (division.warehouses[city] instanceof Warehouse) return;
division.warehouses[city] = new Warehouse({
corp: corp,
industry: division,
loc: city,
size: CorporationConstants.WarehouseInitialSize,
});
corp.funds = corp.funds.minus(CorporationConstants.WarehouseInitialCost);
}