diff --git a/src/CodingContractGenerator.js b/src/CodingContractGenerator.js index c56290330..a77ffcf2a 100644 --- a/src/CodingContractGenerator.js +++ b/src/CodingContractGenerator.js @@ -3,7 +3,8 @@ import {CodingContract, CodingContractTypes} from "./CodingContracts"; import {Factions} from "./Faction"; import {Player} from "./Player"; -import {AllServers} from "./Server"; +import {GetServerByHostname, + AllServers} from "./Server"; import {getRandomInt} from "../utils/helpers/getRandomInt"; @@ -14,11 +15,62 @@ export function generateRandomContract() { let problemType = problemTypes[randIndex]; // Then select a random reward type. 'Money' will always be the last reward type - var reward = {}; - reward.type = getRandomInt(0, CodingContractRewardType.Money); + const reward = getRandomReward(); - // Change type based on certain conditions - var factionsThatAllowHacking = Player.factions.filter((fac) => { + // Choose random server + const randServer = getRandomServer(); + + let contractFn = getRandomFilename(randServer, reward); + let contract = new CodingContract(contractFn, problemType, reward); + + randServer.addContract(contract); +} + +export function generateContract(params) { + // Problem Type + let problemType; + const problemTypes = Object.keys(CodingContractTypes); + if (params.problemType != null && problemTypes.includes(params.problemType)) { + problemType = params.problemType; + } else { + let randIndex = getRandomInt(0, problemTypes.length - 1); + problemType = problemTypes[randIndex]; + } + + // Reward Type - This is always random for now + const reward = getRandomReward(); + + // Server + let server; + if (params.server != null) { + server = GetServerByHostname(params.server); + if (server == null) { + server = AllServers[param.server]; + } + if (server == null) { + server = getRandomServer(); + } + } else { + server = getRandomServer(); + } + + // Filename + let fn; + if (params.fn != null) { + fn = params.fn; + } else { + fn = getRandomFilename(server, reward); + } + + let contract = new CodingContract(fn, problemType, reward); + server.addContract(contract); +} + +// Ensures that a contract's reward type is valid +function sanitizeRewardType(rewardType) { + let type = rewardType; // Create copy + + const factionsThatAllowHacking = Player.factions.filter((fac) => { try { return Factions[fac].getInfo().offerHackingWork; } catch (e) { @@ -26,17 +78,34 @@ export function generateRandomContract() { return false; } }); - if (reward.type === CodingContractRewardType.FactionReputation && factionsThatAllowHacking.length === 0) { - reward.type = CodingContractRewardType.CompanyReputation; + if (type === CodingContractRewardType.FactionReputation && factionsThatAllowHacking.length === 0) { + type = CodingContractRewardType.CompanyReputation; } - if (reward.type === CodingContractRewardType.FactionReputationAll && factionsThatAllowHacking.length === 0) { - reward.type = CodingContractRewardType.CompanyReputation; + if (type === CodingContractRewardType.FactionReputationAll && factionsThatAllowHacking.length === 0) { + type = CodingContractRewardType.CompanyReputation; } - if (reward.type === CodingContractRewardType.CompanyReputation && Player.companyName === "") { - reward.type = CodingContractRewardType.Money; + if (type === CodingContractRewardType.CompanyReputation && Player.companyName === "") { + type = CodingContractRewardType.Money; } + return type; +} + +function getRandomReward() { + let reward = {}; + reward.type = getRandomInt(0, CodingContractRewardType.Money); + reward.type = sanitizeRewardType(reward.type); + // Add additional information based on the reward type + const factionsThatAllowHacking = Player.factions.filter((fac) => { + try { + return Factions[fac].getInfo().offerHackingWork; + } catch (e) { + console.error(`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`); + return false; + } + }); + switch (reward.type) { case CodingContractRewardType.FactionReputation: // Get a random faction that player is a part of. That @@ -56,21 +125,34 @@ export function generateRandomContract() { break; } - // Choose random server + return reward; +} + +function getRandomServer() { const servers = Object.keys(AllServers); - randIndex = getRandomInt(0, servers.length - 1); - var randServer = AllServers[servers[randIndex]]; - while (randServer.purchasedByPlayer === true) { + let randIndex = getRandomInt(0, servers.length - 1); + let randServer = AllServers[servers[randIndex]]; + + // An infinite loop shouldn't ever happen, but to be safe we'll use + // a for loop with a limited number of tries + for (let i = 0; i < 200; ++i) { + if (randServer.purchasedByPlayer === false) { break; } randIndex = getRandomInt(0, servers.length - 1); randServer = AllServers[servers[randIndex]]; } + return randServer; +} + +function getRandomFilename(server, reward) { let contractFn = `contract-${getRandomInt(0, 1e6)}`; - while (randServer.contracts.filter((c) => {return c.fn === contractFn}).length > 0) { + + for (let i = 0; i < 1000; ++i) { + if (server.contracts.filter((c) => {return c.fn === contractFn}).length <= 0) { break; } contractFn = `contract-${getRandomInt(0, 1e6)}`; } - if (reward.name) { contractFn += `-${reward.name.replace(/\s/g, "")}`; } - let contract = new CodingContract(contractFn, problemType, reward); - randServer.addContract(contract); + if (reward.name) { contractFn += `-${reward.name.replace(/\s/g, "")}`; } + + return contractFn; } diff --git a/src/DevMenu.js b/src/DevMenu.js index 7226723a5..2f1e7405b 100644 --- a/src/DevMenu.js +++ b/src/DevMenu.js @@ -431,6 +431,8 @@ export function createDevMenu() { devMenuContainer.appendChild(gangStoredCyclesInput); devMenuContainer.appendChild(gangAddStoredCycles); devMenuContainer.appendChild(createElement("br")); + devMenuContainer.appendChild(contractsHeader); + devMenuContainer.appendChild(generateRandomContractBtn); const entireGameContainer = document.getElementById("entire-game-container"); if (entireGameContainer == null) { diff --git a/src/data/codingcontracttypes.ts b/src/data/codingcontracttypes.ts index 27c29d382..8c44f9924 100644 --- a/src/data/codingcontracttypes.ts +++ b/src/data/codingcontracttypes.ts @@ -248,7 +248,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ if (Math.random() < 0.2) { arr[i] = 0; // 20% chance of being 0 } else { - arr[i] = getRandomInt(0, 24); + arr[i] = getRandomInt(0, 10); } }