2019-04-11 10:37:40 +02:00
|
|
|
import {
|
2021-09-05 01:09:30 +02:00
|
|
|
CodingContract,
|
|
|
|
CodingContractRewardType,
|
|
|
|
CodingContractTypes,
|
|
|
|
ICodingContractReward,
|
2019-04-11 10:37:40 +02:00
|
|
|
} from "./CodingContracts";
|
|
|
|
import { Factions } from "./Faction/Factions";
|
|
|
|
import { Player } from "./Player";
|
2021-10-07 22:04:04 +02:00
|
|
|
import { GetAllServers } from "./Server/AllServers";
|
|
|
|
import { getServer } from "./Server/ServerHelpers";
|
2019-04-30 05:54:20 +02:00
|
|
|
import { SpecialServerNames } from "./Server/SpecialServerIps";
|
2021-03-14 07:31:23 +01:00
|
|
|
import { Server } from "./Server/Server";
|
2021-10-07 22:04:04 +02:00
|
|
|
import { BaseServer } from "./Server/BaseServer";
|
2019-04-11 10:37:40 +02:00
|
|
|
|
2021-09-25 20:42:57 +02:00
|
|
|
import { getRandomInt } from "./utils/helpers/getRandomInt";
|
2018-10-27 21:26:22 +02:00
|
|
|
|
2021-05-01 09:17:31 +02:00
|
|
|
export function generateRandomContract(): void {
|
2021-09-05 01:09:30 +02:00
|
|
|
// First select a random problem type
|
|
|
|
const problemType = getRandomProblemType();
|
2018-10-27 21:26:22 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Then select a random reward type. 'Money' will always be the last reward type
|
|
|
|
const reward = getRandomReward();
|
2018-10-27 22:48:33 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Choose random server
|
|
|
|
const randServer = getRandomServer();
|
2018-10-27 22:48:33 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
const contractFn = getRandomFilename(randServer, reward);
|
|
|
|
const contract = new CodingContract(contractFn, problemType, reward);
|
2018-10-27 22:48:33 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
randServer.addContract(contract);
|
2018-10-27 22:48:33 +02:00
|
|
|
}
|
|
|
|
|
2021-05-01 09:17:31 +02:00
|
|
|
export function generateRandomContractOnHome(): void {
|
2021-09-05 01:09:30 +02:00
|
|
|
// First select a random problem type
|
|
|
|
const problemType = getRandomProblemType();
|
2019-02-01 09:27:24 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Then select a random reward type. 'Money' will always be the last reward type
|
|
|
|
const reward = getRandomReward();
|
2019-02-01 09:27:24 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Choose random server
|
|
|
|
const serv = Player.getHomeComputer();
|
2019-02-01 09:27:24 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
const contractFn = getRandomFilename(serv, reward);
|
|
|
|
const contract = new CodingContract(contractFn, problemType, reward);
|
2019-02-01 09:27:24 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
serv.addContract(contract);
|
2019-02-01 09:27:24 +01:00
|
|
|
}
|
|
|
|
|
2021-03-14 07:31:23 +01:00
|
|
|
export interface IGenerateContractParams {
|
2021-09-05 01:09:30 +02:00
|
|
|
problemType?: string;
|
|
|
|
server?: string;
|
|
|
|
fn?: string;
|
2021-03-14 07:31:23 +01:00
|
|
|
}
|
|
|
|
|
2021-05-01 09:17:31 +02:00
|
|
|
export function generateContract(params: IGenerateContractParams): void {
|
2021-09-05 01:09:30 +02:00
|
|
|
// Problem Type
|
|
|
|
let problemType;
|
|
|
|
const problemTypes = Object.keys(CodingContractTypes);
|
|
|
|
if (params.problemType != null && problemTypes.includes(params.problemType)) {
|
|
|
|
problemType = params.problemType;
|
|
|
|
} else {
|
|
|
|
problemType = getRandomProblemType();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reward Type - This is always random for now
|
|
|
|
const reward = getRandomReward();
|
|
|
|
|
|
|
|
// Server
|
|
|
|
let server;
|
|
|
|
if (params.server != null) {
|
2021-10-07 22:04:04 +02:00
|
|
|
server = getServer(params.server);
|
2021-09-05 01:09:30 +02:00
|
|
|
if (server == null) {
|
|
|
|
server = getRandomServer();
|
2018-10-27 22:48:33 +02:00
|
|
|
}
|
2021-09-05 01:09:30 +02:00
|
|
|
} else {
|
|
|
|
server = getRandomServer();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Filename
|
|
|
|
let fn;
|
|
|
|
if (params.fn != null) {
|
|
|
|
fn = params.fn;
|
|
|
|
} else {
|
|
|
|
fn = getRandomFilename(server, reward);
|
|
|
|
}
|
|
|
|
|
|
|
|
const contract = new CodingContract(fn, problemType, reward);
|
|
|
|
server.addContract(contract);
|
2018-10-27 22:48:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Ensures that a contract's reward type is valid
|
2021-09-09 05:47:34 +02:00
|
|
|
function sanitizeRewardType(rewardType: CodingContractRewardType): CodingContractRewardType {
|
2021-09-05 01:09:30 +02:00
|
|
|
let type = rewardType; // Create copy
|
|
|
|
|
|
|
|
const factionsThatAllowHacking = Player.factions.filter((fac) => {
|
|
|
|
try {
|
|
|
|
return Factions[fac].getInfo().offerHackingWork;
|
|
|
|
} catch (e) {
|
2021-09-09 05:47:34 +02:00
|
|
|
console.error(`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`);
|
2021-09-05 01:09:30 +02:00
|
|
|
return false;
|
2018-10-27 21:26:22 +02:00
|
|
|
}
|
2021-09-05 01:09:30 +02:00
|
|
|
});
|
2021-09-09 05:47:34 +02:00
|
|
|
if (type === CodingContractRewardType.FactionReputation && factionsThatAllowHacking.length === 0) {
|
2021-09-05 01:09:30 +02:00
|
|
|
type = CodingContractRewardType.CompanyReputation;
|
|
|
|
}
|
2021-09-09 05:47:34 +02:00
|
|
|
if (type === CodingContractRewardType.FactionReputationAll && factionsThatAllowHacking.length === 0) {
|
2021-09-05 01:09:30 +02:00
|
|
|
type = CodingContractRewardType.CompanyReputation;
|
|
|
|
}
|
2021-09-09 05:47:34 +02:00
|
|
|
if (type === CodingContractRewardType.CompanyReputation && Object.keys(Player.jobs).length === 0) {
|
2021-09-05 01:09:30 +02:00
|
|
|
type = CodingContractRewardType.Money;
|
|
|
|
}
|
|
|
|
|
|
|
|
return type;
|
2018-10-27 22:48:33 +02:00
|
|
|
}
|
|
|
|
|
2021-05-01 09:17:31 +02:00
|
|
|
function getRandomProblemType(): string {
|
2021-09-05 01:09:30 +02:00
|
|
|
const problemTypes = Object.keys(CodingContractTypes);
|
|
|
|
const randIndex = getRandomInt(0, problemTypes.length - 1);
|
2019-02-01 09:27:24 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
return problemTypes[randIndex];
|
2019-02-01 09:27:24 +01:00
|
|
|
}
|
|
|
|
|
2021-03-14 07:31:23 +01:00
|
|
|
function getRandomReward(): ICodingContractReward {
|
2021-09-05 01:09:30 +02:00
|
|
|
const reward: ICodingContractReward = {
|
|
|
|
name: "",
|
|
|
|
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) {
|
2021-09-09 05:47:34 +02:00
|
|
|
console.error(`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`);
|
2021-09-05 01:09:30 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
switch (reward.type) {
|
|
|
|
case CodingContractRewardType.FactionReputation: {
|
|
|
|
// Get a random faction that player is a part of. That
|
|
|
|
// faction must allow hacking contracts
|
|
|
|
const numFactions = factionsThatAllowHacking.length;
|
2021-09-09 05:47:34 +02:00
|
|
|
const randFaction = factionsThatAllowHacking[getRandomInt(0, numFactions - 1)];
|
2021-09-05 01:09:30 +02:00
|
|
|
reward.name = randFaction;
|
|
|
|
break;
|
2018-10-27 21:26:22 +02:00
|
|
|
}
|
2021-09-05 01:09:30 +02:00
|
|
|
case CodingContractRewardType.CompanyReputation: {
|
|
|
|
const allJobs = Object.keys(Player.jobs);
|
|
|
|
if (allJobs.length > 0) {
|
|
|
|
reward.name = allJobs[getRandomInt(0, allJobs.length - 1)];
|
|
|
|
} else {
|
|
|
|
reward.type = CodingContractRewardType.Money;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2018-10-27 21:26:22 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
return reward;
|
2018-10-27 22:48:33 +02:00
|
|
|
}
|
|
|
|
|
2021-10-07 22:04:04 +02:00
|
|
|
function getRandomServer(): BaseServer {
|
|
|
|
const servers = GetAllServers();
|
2021-09-05 01:09:30 +02:00
|
|
|
let randIndex = getRandomInt(0, servers.length - 1);
|
2021-10-07 22:04:04 +02:00
|
|
|
let randServer = servers[randIndex];
|
2021-09-05 01:09:30 +02:00
|
|
|
|
|
|
|
// 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 instanceof Server &&
|
|
|
|
!randServer.purchasedByPlayer &&
|
|
|
|
randServer.hostname !== SpecialServerNames.WorldDaemon
|
|
|
|
) {
|
|
|
|
break;
|
2018-10-27 21:26:22 +02:00
|
|
|
}
|
2021-09-05 01:09:30 +02:00
|
|
|
randIndex = getRandomInt(0, servers.length - 1);
|
2021-10-07 22:04:04 +02:00
|
|
|
randServer = servers[randIndex];
|
2021-09-05 01:09:30 +02:00
|
|
|
}
|
2018-10-27 21:26:22 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
return randServer;
|
2018-10-27 22:48:33 +02:00
|
|
|
}
|
|
|
|
|
2021-10-07 22:04:04 +02:00
|
|
|
function getRandomFilename(server: BaseServer, reward: ICodingContractReward): string {
|
2021-09-05 01:09:30 +02:00
|
|
|
let contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
|
|
|
|
|
|
|
for (let i = 0; i < 1000; ++i) {
|
|
|
|
if (
|
|
|
|
server.contracts.filter((c: CodingContract) => {
|
|
|
|
return c.fn === contractFn;
|
|
|
|
}).length <= 0
|
|
|
|
) {
|
|
|
|
break;
|
2018-10-27 21:26:22 +02:00
|
|
|
}
|
2021-09-05 01:09:30 +02:00
|
|
|
contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
|
|
|
}
|
2018-10-27 22:48:33 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
if (reward.name) {
|
|
|
|
contractFn += `-${reward.name.replace(/\s/g, "")}`;
|
|
|
|
}
|
2018-10-27 21:26:22 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
return contractFn;
|
2018-10-27 21:26:22 +02:00
|
|
|
}
|