Research func, gopublic function, and validation

This commit is contained in:
pigalot 2022-01-13 17:47:11 +00:00
parent 2269f79b15
commit 98e8910c3a
4 changed files with 118 additions and 25 deletions

@ -94,7 +94,7 @@ export function SellMaterial(mat: Material, amt: string, price: string): void {
throw new Error("Invalid value or expression for sell price field: " + e); throw new Error("Invalid value or expression for sell price field: " + e);
} }
if (temp == null || isNaN(parseFloat(temp))) { if (temp == null || isNaN(parseFloat(temp)) || parseFloat(temp) < 0) {
throw new Error("Invalid value or expression for sell price field"); throw new Error("Invalid value or expression for sell price field");
} }
@ -117,13 +117,13 @@ export function SellMaterial(mat: Material, amt: string, price: string): void {
throw new Error("Invalid value or expression for sell price field: " + e); throw new Error("Invalid value or expression for sell price field: " + e);
} }
if (tempQty == null || isNaN(parseFloat(tempQty))) { if (tempQty == null || isNaN(parseFloat(tempQty)) || parseFloat(tempQty) < 0) {
throw new Error("Invalid value or expression for sell price field"); throw new Error("Invalid value or expression for sell price field");
} }
mat.sllman[0] = true; mat.sllman[0] = true;
mat.sllman[1] = q; //Use sanitized input mat.sllman[1] = q; //Use sanitized input
} else if (isNaN(parseFloat(amt))) { } else if (isNaN(parseFloat(amt)) || parseFloat(amt) < 0) {
throw new Error("Invalid value for sell quantity field! Must be numeric or 'MAX'"); throw new Error("Invalid value for sell quantity field! Must be numeric or 'MAX'");
} else { } else {
let q = parseFloat(amt); let q = parseFloat(amt);
@ -153,7 +153,7 @@ export function SellProduct(product: Product, city: string, amt: string, price:
} catch (e) { } catch (e) {
throw new Error("Invalid value or expression for sell quantity field: " + e); throw new Error("Invalid value or expression for sell quantity field: " + e);
} }
if (temp == null || isNaN(parseFloat(temp))) { if (temp == null || isNaN(parseFloat(temp)) || parseFloat(temp) < 0) {
throw new Error("Invalid value or expression for sell quantity field."); throw new Error("Invalid value or expression for sell quantity field.");
} }
product.sCost = price; //Use sanitized price product.sCost = price; //Use sanitized price
@ -182,7 +182,7 @@ export function SellProduct(product: Product, city: string, amt: string, price:
throw new Error("Invalid value or expression for sell price field: " + e); throw new Error("Invalid value or expression for sell price field: " + e);
} }
if (temp == null || isNaN(parseFloat(temp))) { if (temp == null || isNaN(parseFloat(temp)) || parseFloat(temp) < 0) {
throw new Error("Invalid value or expression for sell price field"); throw new Error("Invalid value or expression for sell price field");
} }
if (all) { if (all) {
@ -195,7 +195,7 @@ export function SellProduct(product: Product, city: string, amt: string, price:
product.sllman[city][0] = true; product.sllman[city][0] = true;
product.sllman[city][1] = qty; //Use sanitized input product.sllman[city][1] = qty; //Use sanitized input
} }
} else if (isNaN(parseFloat(amt))) { } else if (isNaN(parseFloat(amt)) || parseFloat(amt) < 0) {
throw new Error("Invalid value for sell quantity field! Must be numeric"); throw new Error("Invalid value for sell quantity field! Must be numeric");
} else { } else {
let qty = parseFloat(amt); let qty = parseFloat(amt);
@ -239,7 +239,7 @@ export function SetSmartSupplyUseLeftovers(warehouse: Warehouse, material: Mater
} }
export function BuyMaterial(material: Material, amt: number): void { export function BuyMaterial(material: Material, amt: number): void {
if (isNaN(amt)) { if (isNaN(amt) || amt < 0) {
throw new Error(`Invalid amount '${amt}' to buy material '${material.name}'`); throw new Error(`Invalid amount '${amt}' to buy material '${material.name}'`);
} }
material.buy = amt; material.buy = amt;

@ -30,7 +30,7 @@ function BulkPurchaseText(props: IBulkPurchaseTextProps): React.ReactElement {
<Typography color={"error"}>Not enough warehouse space to purchase this amount</Typography> <Typography color={"error"}>Not enough warehouse space to purchase this amount</Typography>
</> </>
); );
} else if (isNaN(cost)) { } else if (isNaN(cost) || parsedAmt < 0) {
return ( return (
<> <>
<Typography color={"error"}>Invalid put for Bulk Purchase amount</Typography> <Typography color={"error"}>Invalid put for Bulk Purchase amount</Typography>
@ -68,7 +68,7 @@ function BulkPurchase(props: IBPProps): React.ReactElement {
return; return;
} }
if (isNaN(amount)) { if (isNaN(amount) || amount < 0) {
dialogBoxCreate("Invalid input amount"); dialogBoxCreate("Invalid input amount");
} else { } else {
const cost = amount * props.mat.bCost; const cost = amount * props.mat.bCost;

@ -55,9 +55,10 @@ import { CorporationUpgrades } from "../Corporation/data/CorporationUpgrades";
import { EmployeePositions } from "../Corporation/EmployeePositions"; import { EmployeePositions } from "../Corporation/EmployeePositions";
import { calculateIntelligenceBonus } from "../PersonObjects/formulas/intelligence"; import { calculateIntelligenceBonus } from "../PersonObjects/formulas/intelligence";
import { Industry } from "../Corporation/Industry"; import { Industry } from "../Corporation/Industry";
import { 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 { IndustryUpgrades } from "../Corporation/IndustryUpgrades";
import { ResearchMap } from "../Corporation/ResearchMap";
export function NetscriptCorporation( export function NetscriptCorporation(
player: IPlayer, player: IPlayer,
@ -129,7 +130,7 @@ export function NetscriptCorporation(
function getInvestmentOffer(): InvestmentOffer { function getInvestmentOffer(): InvestmentOffer {
const corporation = getCorporation(); const corporation = getCorporation();
if (corporation.fundingRound >= CorporationConstants.FundingRoundShares.length || corporation.fundingRound >= CorporationConstants.FundingRoundMultiplier.length) if (corporation.fundingRound >= CorporationConstants.FundingRoundShares.length || corporation.fundingRound >= CorporationConstants.FundingRoundMultiplier.length || corporation.public)
return { return {
funds: 0, funds: 0,
shares: 0, shares: 0,
@ -149,7 +150,7 @@ export function NetscriptCorporation(
function acceptInvestmentOffer(): boolean { function acceptInvestmentOffer(): boolean {
const corporation = getCorporation(); const corporation = getCorporation();
if (corporation.fundingRound >= CorporationConstants.FundingRoundShares.length || corporation.fundingRound >= CorporationConstants.FundingRoundMultiplier.length) return false; if (corporation.fundingRound >= CorporationConstants.FundingRoundShares.length || corporation.fundingRound >= CorporationConstants.FundingRoundMultiplier.length || corporation.public) return false;
const val = corporation.determineValuation(); const val = corporation.determineValuation();
const percShares = CorporationConstants.FundingRoundShares[corporation.fundingRound]; const percShares = CorporationConstants.FundingRoundShares[corporation.fundingRound];
const roundMultiplier = CorporationConstants.FundingRoundMultiplier[corporation.fundingRound]; const roundMultiplier = CorporationConstants.FundingRoundMultiplier[corporation.fundingRound];
@ -161,6 +162,33 @@ export function NetscriptCorporation(
return true; return true;
} }
function goPublic(numShares: number): boolean {
const corporation = getCorporation();
const initialSharePrice = corporation.determineValuation() / 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: IIndustry, researchName: string): 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: IIndustry, researchName: string): boolean {
return division.researched[researchName] === undefined ? false : division.researched[researchName] as boolean;
}
function getCorporation(): ICorporation { function getCorporation(): ICorporation {
const corporation = player.corporation; const corporation = player.corporation;
if (corporation === null) throw new Error("cannot be called without a corporation"); if (corporation === null) throw new Error("cannot be called without a corporation");
@ -239,6 +267,7 @@ export function NetscriptCorporation(
thisCycleExpenses: division.thisCycleExpenses, thisCycleExpenses: division.thisCycleExpenses,
upgrades: division.upgrades, upgrades: division.upgrades,
cities: cities, cities: cities,
products: division.products === undefined ? [] : Object.keys(division.products),
}; };
} }
@ -286,6 +315,8 @@ export function NetscriptCorporation(
name: material.name, name: material.name,
qty: material.qty, qty: material.qty,
qlt: material.qlt, qlt: material.qlt,
prod: material.prd,
sell: material.sll,
}; };
}, },
getProduct: function (adivisionName: any, aproductName: any): NSProduct { getProduct: function (adivisionName: any, aproductName: any): NSProduct {
@ -299,6 +330,8 @@ export function NetscriptCorporation(
cmp: product.cmp, cmp: product.cmp,
pCost: product.pCost, pCost: product.pCost,
sCost: product.sCost, sCost: product.sCost,
cityData: product.data,
developmentProgress: product.prog,
}; };
}, },
purchaseWarehouse: function (adivisionName: any, acityName: any): void { purchaseWarehouse: function (adivisionName: any, acityName: any): void {
@ -363,6 +396,7 @@ export function NetscriptCorporation(
const cityName = helper.string("buyMaterial", "cityName", acityName); const cityName = helper.string("buyMaterial", "cityName", acityName);
const materialName = helper.string("buyMaterial", "materialName", amaterialName); const materialName = helper.string("buyMaterial", "materialName", amaterialName);
const amt = helper.number("buyMaterial", "amt", aamt); const amt = helper.number("buyMaterial", "amt", aamt);
if (amt < 0) throw new Error("Invalid value for ammount field! Must be numeric and grater than 0");
const material = getMaterial(divisionName, cityName, materialName); const material = getMaterial(divisionName, cityName, materialName);
BuyMaterial(material, amt); BuyMaterial(material, amt);
}, },
@ -449,19 +483,31 @@ export function NetscriptCorporation(
}; };
const officeAPI: OfficeAPI = { const officeAPI: OfficeAPI = {
getHireAdVertCost: function (adivisionName: string): number { getHireAdVertCost: function (adivisionName: any): number {
checkAccess("hireAdVert", 8); checkAccess("getHireAdVertCost", 8);
const divisionName = helper.string("hireAdVert", "divisionName", adivisionName); const divisionName = helper.string("getHireAdVertCost", "divisionName", adivisionName);
const division = getDivision(divisionName); const division = getDivision(divisionName);
const upgrade = IndustryUpgrades[1]; const upgrade = IndustryUpgrades[1];
return upgrade[1] * Math.pow(upgrade[2], division.upgrades[1]); return upgrade[1] * Math.pow(upgrade[2], division.upgrades[1]);
}, },
getHireAdVertCount: function (adivisionName: string): number { getHireAdVertCount: function (adivisionName: any): number {
checkAccess("hireAdVert", 8); checkAccess("getHireAdVertCount", 8);
const divisionName = helper.string("hireAdVert", "divisionName", adivisionName); const divisionName = helper.string("getHireAdVertCount", "divisionName", adivisionName);
const division = getDivision(divisionName); const division = getDivision(divisionName);
return division.upgrades[1] return division.upgrades[1]
}, },
getResearchCost: function (adivisionName: any, aresearchName: any): number {
checkAccess("getResearchCost", 8);
const divisionName = helper.string("getResearchCost", "divisionName", adivisionName);
const researchName = helper.string("getResearchCost", "researchName", aresearchName);
return getResearchCost(getDivision(divisionName), researchName);
},
hasResearched: function (adivisionName: any, aresearchName: any): boolean {
checkAccess("hasResearched", 8);
const divisionName = helper.string("hasResearched", "divisionName", adivisionName);
const researchName = helper.string("hasResearched", "researchName", aresearchName);
return hasResearched(getDivision(divisionName), researchName);
},
assignJob: function (adivisionName: any, acityName: any, aemployeeName: any, ajob: any): Promise<void> { assignJob: function (adivisionName: any, acityName: any, aemployeeName: any, ajob: any): Promise<void> {
checkAccess("assignJob", 8); checkAccess("assignJob", 8);
const divisionName = helper.string("assignJob", "divisionName", adivisionName); const divisionName = helper.string("assignJob", "divisionName", adivisionName);
@ -485,6 +531,7 @@ export function NetscriptCorporation(
const divisionName = helper.string("upgradeOfficeSize", "divisionName", adivisionName); const divisionName = helper.string("upgradeOfficeSize", "divisionName", adivisionName);
const cityName = helper.string("upgradeOfficeSize", "cityName", acityName); const cityName = helper.string("upgradeOfficeSize", "cityName", acityName);
const size = helper.number("upgradeOfficeSize", "size", asize); const size = helper.number("upgradeOfficeSize", "size", asize);
if (size < 0) throw new Error("Invalid value for size field! Must be numeric and grater than 0");
const office = getOffice(divisionName, cityName); const office = getOffice(divisionName, cityName);
const corporation = getCorporation(); const corporation = getCorporation();
UpgradeOfficeSize(corporation, office, size); UpgradeOfficeSize(corporation, office, size);
@ -494,6 +541,7 @@ export function NetscriptCorporation(
const divisionName = helper.string("throwParty", "divisionName", adivisionName); const divisionName = helper.string("throwParty", "divisionName", adivisionName);
const cityName = helper.string("throwParty", "cityName", acityName); const cityName = helper.string("throwParty", "cityName", acityName);
const costPerEmployee = helper.number("throwParty", "costPerEmployee", acostPerEmployee); const costPerEmployee = helper.number("throwParty", "costPerEmployee", acostPerEmployee);
if (costPerEmployee < 0) throw new Error("Invalid value for Cost Per Employee field! Must be numeric and grater than 0");
const office = getOffice(divisionName, cityName); const office = getOffice(divisionName, cityName);
const corporation = getCorporation(); const corporation = getCorporation();
return netscriptDelay( return netscriptDelay(
@ -588,6 +636,7 @@ export function NetscriptCorporation(
checkAccess("expandCity"); checkAccess("expandCity");
const divisionName = helper.string("expandCity", "divisionName", adivisionName); const divisionName = helper.string("expandCity", "divisionName", adivisionName);
const cityName = helper.string("expandCity", "cityName", acityName); const cityName = helper.string("expandCity", "cityName", acityName);
if (!CorporationConstants.Cities.includes(cityName)) throw new Error("Invalid city name");
const corporation = getCorporation(); const corporation = getCorporation();
const division = getDivision(divisionName); const division = getDivision(divisionName);
NewCity(corporation, division, cityName); NewCity(corporation, division, cityName);
@ -611,6 +660,7 @@ export function NetscriptCorporation(
issueDividends: function (apercent: any): void { issueDividends: function (apercent: any): void {
checkAccess("issueDividends"); checkAccess("issueDividends");
const percent = helper.number("issueDividends", "percent", apercent); const percent = helper.number("issueDividends", "percent", apercent);
if (percent < 0 || percent > 100) throw new Error("Invalid value for Cost Per Employee field! Must be numeric, grater than 0, and less than 100");
const corporation = getCorporation(); const corporation = getCorporation();
IssueDividends(corporation, percent); IssueDividends(corporation, percent);
}, },
@ -641,27 +691,33 @@ export function NetscriptCorporation(
divisions: corporation.divisions.map((division): NSDivision => getSafeDivision(division)), divisions: corporation.divisions.map((division): NSDivision => getSafeDivision(division)),
}; };
}, },
createCorporation: function (corporationName: string, selfFund = true): boolean { createCorporation: function (acorporationName: string, selfFund = true): boolean {
const corporationName = helper.string("createCorporation", "corporationName", acorporationName);
return createCorporation(corporationName, selfFund); return createCorporation(corporationName, selfFund);
}, },
hasUnlockUpgrade: function (upgradeName: string): boolean { hasUnlockUpgrade: function (aupgradeName: any): boolean {
checkAccess("hasUnlockUpgrade"); checkAccess("hasUnlockUpgrade");
const upgradeName = helper.string("hasUnlockUpgrade", "upgradeName", aupgradeName);
return hasUnlockUpgrade(upgradeName); return hasUnlockUpgrade(upgradeName);
}, },
getUnlockUpgradeCost: function (upgradeName: string): number { getUnlockUpgradeCost: function (aupgradeName: any): number {
checkAccess("getUnlockUpgradeCost"); checkAccess("getUnlockUpgradeCost");
const upgradeName = helper.string("getUnlockUpgradeCost", "upgradeName", aupgradeName);
return getUnlockUpgradeCost(upgradeName); return getUnlockUpgradeCost(upgradeName);
}, },
getUpgradeLevel: function (upgradeName: string): number { getUpgradeLevel: function (aupgradeName: any): number {
checkAccess("hasUnlockUpgrade"); checkAccess("hasUnlockUpgrade");
const upgradeName = helper.string("getUpgradeLevel", "upgradeName", aupgradeName);
return getUpgradeLevel(upgradeName); return getUpgradeLevel(upgradeName);
}, },
getUpgradeLevelCost: function (upgradeName: string): number { getUpgradeLevelCost: function (aupgradeName: any): number {
checkAccess("getUpgradeLevelCost"); checkAccess("getUpgradeLevelCost");
const upgradeName = helper.string("getUpgradeLevelCost", "upgradeName", aupgradeName);
return getUpgradeLevelCost(upgradeName); return getUpgradeLevelCost(upgradeName);
}, },
getExpandIndustryCost: function (industryName: string): number { getExpandIndustryCost: function (aindustryName: any): number {
checkAccess("getExpandIndustryCost"); checkAccess("getExpandIndustryCost");
const industryName = helper.string("getExpandIndustryCost", "industryName", aindustryName);
return getExpandIndustryCost(industryName); return getExpandIndustryCost(industryName);
}, },
getExpandCityCost: function(): number { getExpandCityCost: function(): number {
@ -676,5 +732,10 @@ export function NetscriptCorporation(
checkAccess("acceptInvestmentOffer"); checkAccess("acceptInvestmentOffer");
return acceptInvestmentOffer(); return acceptInvestmentOffer();
}, },
goPublic(anumShares: any): boolean {
checkAccess("acceptInvestmentOffer");
const numShares = helper.number("goPublic", "numShares", anumShares);
return goPublic(numShares);
},
}; };
} }

@ -6145,13 +6145,27 @@ export interface OfficeAPI {
* @param divisionName - Name of the division * @param divisionName - Name of the division
* @returns Cost * @returns Cost
*/ */
getHireAdVertCost(adivisionName: string): number; getHireAdVertCost(divisionName: string): number;
/** /**
* Get the number of times you have Hired AdVert * Get the number of times you have Hired AdVert
* @param divisionName - Name of the division * @param divisionName - Name of the division
* @returns Number of times you have Hired AdVert * @returns Number of times you have Hired AdVert
*/ */
getHireAdVertCount(adivisionName: string): number; getHireAdVertCount(adivisionName: string): number;
/**
* Get the cost to unlock research
* @param divisionName - Name of the division
* @param cityName - Name of the city
* @returns cost
*/
getResearchCost(divisionName: string, researchName: string): number;
/**
* Gets if you have unlocked a research
* @param divisionName - Name of the division
* @param cityName - Name of the city
* @returns true is unlocked, false if not
*/
hasResearched(divisionName: string, researchName: string): boolean;
} }
/** /**
@ -6395,6 +6409,12 @@ export interface Corporation extends WarehouseAPI, OfficeAPI {
* @returns An offer of investment * @returns An offer of investment
*/ */
acceptInvestmentOffer(): boolean; acceptInvestmentOffer(): boolean;
/**
* Go public
* @param numShares number of shares you would like to issue for your IPO
* @returns true if you successfully go public, false if not
*/
goPublic(numShares: number): boolean;
/** /**
* Get corporation data * Get corporation data
* @returns Corporation data * @returns Corporation data
@ -6507,6 +6527,12 @@ interface Product {
pCost: number; pCost: number;
/** Sell cost, can be "MP+5" */ /** Sell cost, can be "MP+5" */
sCost: string | number; sCost: string | number;
/** Data refers to the production, sale, and quantity of the products
* These values are specific to a city
* For each city, the data is [qty, prod, sell] */
cityData: {[key: string]:number[]};
/** Creation progress - A number betwee 0-100 representing percentage */
developmentProgress: number;
} }
/** /**
@ -6520,6 +6546,10 @@ interface Material {
qty: number; qty: number;
/** Quality of the material */ /** Quality of the material */
qlt: number; qlt: number;
/** Amount of material produced */
prod: number;
/** Amount of material sold */
sell: number;
} }
/** /**
@ -6607,6 +6637,8 @@ interface Division {
upgrades: number[]; upgrades: number[];
/** Cities in which this division has expanded */ /** Cities in which this division has expanded */
cities: string[]; cities: string[];
/** Products developed by this division */
products: string[];
} }
/** /**