bitburner-src/src/PersonObjects/Player/PlayerObjectGeneralMethods.jsx

2924 lines
97 KiB
React
Raw Normal View History

import { Augmentations } from "../../Augmentation/Augmentations";
import { applyAugmentation } from "../../Augmentation/AugmentationHelpers";
import { PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
import { CodingContractRewardType } from "../../CodingContracts";
import { Company } from "../../Company/Company";
import { Companies } from "../../Company/Companies";
import { getNextCompanyPositionHelper } from "../../Company/GetNextCompanyPosition";
import { getJobRequirementText } from "../../Company/GetJobRequirementText";
import { CompanyPositions } from "../../Company/CompanyPositions";
import * as posNames from "../../Company/data/companypositionnames";
2021-09-05 01:09:30 +02:00
import { CONSTANTS } from "../../Constants";
import { Programs } from "../../Programs/Programs";
import { determineCrimeSuccess } from "../../Crime/CrimeHelpers";
import { Crimes } from "../../Crime/Crimes";
import { Engine } from "../../engine";
import { Faction } from "../../Faction/Faction";
import { Factions } from "../../Faction/Factions";
import { displayFactionContent } from "../../Faction/FactionHelpers";
import { resetGangs } from "../../Gang/AllGangs";
import { hasHacknetServers } from "../../Hacknet/HacknetHelpers";
import { Cities } from "../../Locations/Cities";
import { Locations } from "../../Locations/Locations";
import { CityName } from "../../Locations/data/CityNames";
import { LocationName } from "../../Locations/data/LocationNames";
import { Sleeve } from "../../PersonObjects/Sleeve/Sleeve";
import { calculateSkill as calculateSkillF } from "../formulas/skill";
import { calculateIntelligenceBonus } from "../formulas/intelligence";
import {
2021-09-05 01:09:30 +02:00
getHackingWorkRepGain,
getFactionSecurityWorkRepGain,
getFactionFieldWorkRepGain,
} from "../formulas/reputation";
2021-09-09 05:47:34 +02:00
import { AllServers, AddToAllServers, createUniqueRandomIp } from "../../Server/AllServers";
import { safetlyCreateUniqueServer } from "../../Server/ServerHelpers";
import { Settings } from "../../Settings/Settings";
2021-09-09 05:47:34 +02:00
import { SpecialServerIps, SpecialServerNames } from "../../Server/SpecialServerIps";
import { applySourceFile } from "../../SourceFile/applySourceFile";
2021-03-09 02:31:34 +01:00
import { applyExploit } from "../../Exploits/applyExploits";
import { SourceFiles } from "../../SourceFile/SourceFiles";
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
import { influenceStockThroughCompanyWork } from "../../StockMarket/PlayerInfluencing";
import { getHospitalizationCost } from "../../Hospital/Hospital";
import Decimal from "decimal.js";
import { numeralWrapper } from "../../ui/numeralFormat";
import { MoneySourceTracker } from "../../utils/MoneySourceTracker";
import { dialogBoxCreate } from "../../../utils/DialogBox";
import { clearEventListeners } from "../../../utils/uiHelpers/clearEventListeners";
2021-05-01 09:17:31 +02:00
import { convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
2019-04-04 02:08:11 +02:00
import { Reputation } from "../../ui/React/Reputation";
import { Money } from "../../ui/React/Money";
import { MoneyRate } from "../../ui/React/MoneyRate";
import { ReputationRate } from "../../ui/React/ReputationRate";
import React from "react";
import ReactDOM from "react-dom";
2019-04-04 02:08:11 +02:00
const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle;
export function init() {
2021-09-05 01:09:30 +02:00
/* Initialize Player's home computer */
var t_homeComp = safetlyCreateUniqueServer({
adminRights: true,
hostname: "home",
ip: createUniqueRandomIp(),
isConnectedTo: true,
maxRam: 8,
organizationName: "Home PC",
purchasedByPlayer: true,
});
this.homeComputer = t_homeComp.ip;
this.currentServer = t_homeComp.ip;
AddToAllServers(t_homeComp);
this.getHomeComputer().programs.push(Programs.NukeProgram.name);
2019-04-04 02:08:11 +02:00
}
export function prestigeAugmentation() {
2021-09-05 01:09:30 +02:00
var homeComp = this.getHomeComputer();
this.currentServer = homeComp.ip;
this.homeComputer = homeComp.ip;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.numPeopleKilled = 0;
this.karma = 0;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
//Reset stats
this.hacking_skill = 1;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.strength = 1;
this.defense = 1;
this.dexterity = 1;
this.agility = 1;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.charisma = 1;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.hacking_exp = 0;
this.strength_exp = 0;
this.defense_exp = 0;
this.dexterity_exp = 0;
this.agility_exp = 0;
this.charisma_exp = 0;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.money = new Decimal(1000);
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.city = CityName.Sector12;
this.location = "";
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.companyName = "";
this.jobs = {};
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.purchasedServers = [];
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.factions = [];
this.factionInvitations = [];
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.queuedAugmentations = [];
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.resleeves = [];
2019-04-04 02:08:11 +02:00
2021-09-09 05:47:34 +02:00
let numSleeves = Math.min(3, SourceFileFlags[10] + (this.bitNodeN === 10 ? 1 : 0)) + this.sleevesFromCovenant;
2021-09-05 01:09:30 +02:00
if (this.sleeves.length > numSleeves) this.sleeves.length = numSleeves;
for (let i = this.sleeves.length; i < numSleeves; i++) {
this.sleeves.push(new Sleeve(this));
}
2021-09-05 01:09:30 +02:00
for (let i = 0; i < this.sleeves.length; ++i) {
if (this.sleeves[i] instanceof Sleeve) {
if (this.sleeves[i].shock >= 100) {
this.sleeves[i].synchronize(this);
} else {
this.sleeves[i].shockRecovery(this);
}
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
}
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.isWorking = false;
this.currentWorkFactionName = "";
this.currentWorkFactionDescription = "";
this.createProgramName = "";
this.className = "";
this.crimeType = "";
this.workHackExpGainRate = 0;
this.workStrExpGainRate = 0;
this.workDefExpGainRate = 0;
this.workDexExpGainRate = 0;
this.workAgiExpGainRate = 0;
this.workChaExpGainRate = 0;
this.workRepGainRate = 0;
this.workMoneyGainRate = 0;
this.workHackExpGained = 0;
this.workStrExpGained = 0;
this.workDefExpGained = 0;
this.workDexExpGained = 0;
this.workAgiExpGained = 0;
this.workChaExpGained = 0;
this.workRepGained = 0;
this.workMoneyGained = 0;
this.timeWorked = 0;
this.lastUpdate = new Date().getTime();
// Statistics Trackers
this.playtimeSinceLastAug = 0;
this.scriptProdSinceLastAug = 0;
this.moneySourceA.reset();
this.hacknetNodes.length = 0;
this.hashManager.prestige();
// Re-calculate skills and reset HP
this.updateSkillLevels();
this.hp = this.max_hp;
2019-04-04 02:08:11 +02:00
}
export function prestigeSourceFile() {
2021-09-05 01:09:30 +02:00
this.prestigeAugmentation();
// Duplicate sleeves are reset to level 1 every Bit Node (but the number of sleeves you have persists)
for (let i = 0; i < this.sleeves.length; ++i) {
2021-09-09 05:47:34 +02:00
if (this.sleeves[i] instanceof Sleeve) {
this.sleeves[i].prestige(this);
} else {
this.sleeves[i] = new Sleeve(this);
}
2021-09-05 01:09:30 +02:00
}
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
if (this.bitNodeN === 10) {
for (let i = 0; i < this.sleeves.length; i++) {
this.sleeves[i].shock = Math.max(25, this.sleeves[i].shock);
this.sleeves[i].sync = Math.max(25, this.sleeves[i].sync);
}
2021-09-05 01:09:30 +02:00
}
2021-09-05 01:09:30 +02:00
const characterMenuHeader = document.getElementById("character-menu-header");
if (characterMenuHeader instanceof HTMLElement) {
characterMenuHeader.click();
characterMenuHeader.click();
}
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.timeWorked = 0;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
// Gang
this.gang = null;
resetGangs();
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
// Reset Stock market
this.hasWseAccount = false;
this.hasTixApiAccess = false;
this.has4SData = false;
this.has4SDataTixApi = false;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
// BitNode 3: Corporatocracy
this.corporation = 0;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.moneySourceB.reset();
this.playtimeSinceLastBitnode = 0;
this.augmentations = [];
2019-04-04 02:08:11 +02:00
}
export function receiveInvite(factionName) {
2021-09-09 05:47:34 +02:00
if (this.factionInvitations.includes(factionName) || this.factions.includes(factionName)) {
2021-09-05 01:09:30 +02:00
return;
}
this.firstFacInvRecvd = true;
this.factionInvitations.push(factionName);
2019-04-04 02:08:11 +02:00
}
//Calculates skill level based on experience. The same formula will be used for every skill
2021-09-05 01:09:30 +02:00
export function calculateSkill(exp, mult = 1) {
return calculateSkillF(exp, mult);
2019-04-04 02:08:11 +02:00
}
export function updateSkillLevels() {
2021-09-05 01:09:30 +02:00
this.hacking_skill = Math.max(
1,
2021-09-09 05:47:34 +02:00
Math.floor(this.calculateSkill(this.hacking_exp, this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier)),
2021-09-05 01:09:30 +02:00
);
this.strength = Math.max(
1,
2021-09-09 05:47:34 +02:00
Math.floor(this.calculateSkill(this.strength_exp, this.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier)),
2021-09-05 01:09:30 +02:00
);
this.defense = Math.max(
1,
2021-09-09 05:47:34 +02:00
Math.floor(this.calculateSkill(this.defense_exp, this.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier)),
2021-09-05 01:09:30 +02:00
);
this.dexterity = Math.max(
1,
Math.floor(
2021-09-09 05:47:34 +02:00
this.calculateSkill(this.dexterity_exp, this.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier),
2021-09-05 01:09:30 +02:00
),
);
this.agility = Math.max(
1,
2021-09-09 05:47:34 +02:00
Math.floor(this.calculateSkill(this.agility_exp, this.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier)),
2021-09-05 01:09:30 +02:00
);
this.charisma = Math.max(
1,
2021-09-09 05:47:34 +02:00
Math.floor(this.calculateSkill(this.charisma_exp, this.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier)),
2021-09-05 01:09:30 +02:00
);
if (this.intelligence > 0) {
this.intelligence = Math.floor(this.calculateSkill(this.intelligence_exp));
} else {
this.intelligence = 0;
}
var ratio = this.hp / this.max_hp;
this.max_hp = Math.floor(10 + this.defense / 10);
this.hp = Math.round(this.max_hp * ratio);
2019-04-04 02:08:11 +02:00
}
export function resetMultipliers() {
2021-09-05 01:09:30 +02:00
this.hacking_chance_mult = 1;
this.hacking_speed_mult = 1;
this.hacking_money_mult = 1;
this.hacking_grow_mult = 1;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.hacking_mult = 1;
this.strength_mult = 1;
this.defense_mult = 1;
this.dexterity_mult = 1;
this.agility_mult = 1;
this.charisma_mult = 1;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.hacking_exp_mult = 1;
this.strength_exp_mult = 1;
this.defense_exp_mult = 1;
this.dexterity_exp_mult = 1;
this.agility_exp_mult = 1;
this.charisma_exp_mult = 1;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.company_rep_mult = 1;
this.faction_rep_mult = 1;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.crime_money_mult = 1;
this.crime_success_mult = 1;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.hacknet_node_money_mult = 1;
this.hacknet_node_purchase_cost_mult = 1;
this.hacknet_node_ram_cost_mult = 1;
this.hacknet_node_core_cost_mult = 1;
this.hacknet_node_level_cost_mult = 1;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.work_money_mult = 1;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.bladeburner_max_stamina_mult = 1;
this.bladeburner_stamina_gain_mult = 1;
this.bladeburner_analysis_mult = 1;
this.bladeburner_success_chance_mult = 1;
2019-04-04 02:08:11 +02:00
}
export function hasProgram(programName) {
2021-09-05 01:09:30 +02:00
const home = this.getHomeComputer();
if (home == null) {
return false;
}
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
for (var i = 0; i < home.programs.length; ++i) {
if (programName.toLowerCase() == home.programs[i].toLowerCase()) {
return true;
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
}
return false;
2019-04-04 02:08:11 +02:00
}
export function setMoney(money) {
2021-09-05 01:09:30 +02:00
if (isNaN(money)) {
console.error("NaN passed into Player.setMoney()");
return;
}
this.money = new Decimal(money);
2019-04-04 02:08:11 +02:00
}
export function gainMoney(money) {
2021-09-05 01:09:30 +02:00
if (isNaN(money)) {
console.error("NaN passed into Player.gainMoney()");
return;
}
this.money = this.money.plus(money);
2019-04-04 02:08:11 +02:00
}
export function loseMoney(money) {
2021-09-05 01:09:30 +02:00
if (isNaN(money)) {
console.error("NaN passed into Player.loseMoney()");
return;
}
if (this.money.eq(Infinity) && money === Infinity) return;
this.money = this.money.minus(money);
2019-04-04 02:08:11 +02:00
}
export function canAfford(cost) {
2021-09-05 01:09:30 +02:00
if (isNaN(cost)) {
console.error(`NaN passed into Player.canAfford()`);
return false;
}
return this.money.gte(cost);
2019-04-04 02:08:11 +02:00
}
export function recordMoneySource(amt, source) {
2021-09-05 01:09:30 +02:00
if (!(this.moneySourceA instanceof MoneySourceTracker)) {
console.warn(`Player.moneySourceA was not properly initialized. Resetting`);
this.moneySourceA = new MoneySourceTracker();
}
if (!(this.moneySourceB instanceof MoneySourceTracker)) {
console.warn(`Player.moneySourceB was not properly initialized. Resetting`);
this.moneySourceB = new MoneySourceTracker();
}
this.moneySourceA.record(amt, source);
this.moneySourceB.record(amt, source);
2019-04-04 02:08:11 +02:00
}
export function gainHackingExp(exp) {
2021-09-05 01:09:30 +02:00
if (isNaN(exp)) {
console.error("ERR: NaN passed into Player.gainHackingExp()");
return;
}
this.hacking_exp += exp;
if (this.hacking_exp < 0) {
this.hacking_exp = 0;
}
2021-09-09 05:47:34 +02:00
this.hacking_skill = calculateSkillF(this.hacking_exp, this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier);
2019-04-04 02:08:11 +02:00
}
export function gainStrengthExp(exp) {
2021-09-05 01:09:30 +02:00
if (isNaN(exp)) {
console.error("ERR: NaN passed into Player.gainStrengthExp()");
return;
}
this.strength_exp += exp;
if (this.strength_exp < 0) {
this.strength_exp = 0;
}
2021-09-09 05:47:34 +02:00
this.strength = calculateSkillF(this.strength_exp, this.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier);
2019-04-04 02:08:11 +02:00
}
export function gainDefenseExp(exp) {
2021-09-05 01:09:30 +02:00
if (isNaN(exp)) {
console.error("ERR: NaN passed into player.gainDefenseExp()");
return;
}
this.defense_exp += exp;
if (this.defense_exp < 0) {
this.defense_exp = 0;
}
2021-09-09 05:47:34 +02:00
this.defense = calculateSkillF(this.defense_exp, this.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier);
2019-04-04 02:08:11 +02:00
}
export function gainDexterityExp(exp) {
2021-09-05 01:09:30 +02:00
if (isNaN(exp)) {
console.error("ERR: NaN passed into Player.gainDexterityExp()");
return;
}
this.dexterity_exp += exp;
if (this.dexterity_exp < 0) {
this.dexterity_exp = 0;
}
2021-09-05 01:09:30 +02:00
this.dexterity = calculateSkillF(
this.dexterity_exp,
this.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier,
);
2019-04-04 02:08:11 +02:00
}
export function gainAgilityExp(exp) {
2021-09-05 01:09:30 +02:00
if (isNaN(exp)) {
console.error("ERR: NaN passed into Player.gainAgilityExp()");
return;
}
this.agility_exp += exp;
if (this.agility_exp < 0) {
this.agility_exp = 0;
}
2021-09-09 05:47:34 +02:00
this.agility = calculateSkillF(this.agility_exp, this.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier);
2019-04-04 02:08:11 +02:00
}
export function gainCharismaExp(exp) {
2021-09-05 01:09:30 +02:00
if (isNaN(exp)) {
console.error("ERR: NaN passed into Player.gainCharismaExp()");
return;
}
this.charisma_exp += exp;
if (this.charisma_exp < 0) {
this.charisma_exp = 0;
}
2021-09-09 05:47:34 +02:00
this.charisma = calculateSkillF(this.charisma_exp, this.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier);
2019-04-04 02:08:11 +02:00
}
export function gainIntelligenceExp(exp) {
2021-09-05 01:09:30 +02:00
if (isNaN(exp)) {
console.error("ERROR: NaN passed into Player.gainIntelligenceExp()");
return;
}
if (SourceFileFlags[5] > 0 || this.intelligence > 0) {
this.intelligence_exp += exp;
}
2019-04-04 02:08:11 +02:00
}
//Given a string expression like "str" or "strength", returns the given stat
export function queryStatFromString(str) {
2021-09-05 01:09:30 +02:00
const tempStr = str.toLowerCase();
if (tempStr.includes("hack")) {
return this.hacking_skill;
}
if (tempStr.includes("str")) {
return this.strength;
}
if (tempStr.includes("def")) {
return this.defense;
}
if (tempStr.includes("dex")) {
return this.dexterity;
}
if (tempStr.includes("agi")) {
return this.agility;
}
if (tempStr.includes("cha")) {
return this.charisma;
}
if (tempStr.includes("int")) {
return this.intelligence;
}
2019-04-04 02:08:11 +02:00
}
/******* Working functions *******/
2021-05-31 23:34:23 +02:00
export function resetWorkStatus(generalType, group, workType) {
2021-09-05 01:09:30 +02:00
if (generalType === this.workType && group === this.companyName) return;
2021-09-09 05:47:34 +02:00
if (generalType === this.workType && group === this.currentWorkFactionName && workType === this.factionWorkType)
2021-09-05 01:09:30 +02:00
return;
if (this.isWorking) this.singularityStopWork();
this.workHackExpGainRate = 0;
this.workStrExpGainRate = 0;
this.workDefExpGainRate = 0;
this.workDexExpGainRate = 0;
this.workAgiExpGainRate = 0;
this.workChaExpGainRate = 0;
this.workRepGainRate = 0;
this.workMoneyGainRate = 0;
this.workMoneyLossRate = 0;
this.workHackExpGained = 0;
this.workStrExpGained = 0;
this.workDefExpGained = 0;
this.workDexExpGained = 0;
this.workAgiExpGained = 0;
this.workChaExpGained = 0;
this.workRepGained = 0;
this.workMoneyGained = 0;
this.timeWorked = 0;
this.timeWorkedCreateProgram = 0;
this.currentWorkFactionName = "";
this.currentWorkFactionDescription = "";
this.createProgramName = "";
this.className = "";
2021-09-09 05:47:34 +02:00
ReactDOM.unmountComponentAtNode(document.getElementById("work-in-progress-text"));
2021-09-05 01:09:30 +02:00
}
export function processWorkEarnings(numCycles = 1) {
const focusBonus = this.focus ? 1 : 0.8;
const hackExpGain = focusBonus * this.workHackExpGainRate * numCycles;
const strExpGain = focusBonus * this.workStrExpGainRate * numCycles;
const defExpGain = focusBonus * this.workDefExpGainRate * numCycles;
const dexExpGain = focusBonus * this.workDexExpGainRate * numCycles;
const agiExpGain = focusBonus * this.workAgiExpGainRate * numCycles;
const chaExpGain = focusBonus * this.workChaExpGainRate * numCycles;
2021-09-09 05:47:34 +02:00
const moneyGain = (this.workMoneyGainRate - this.workMoneyLossRate) * numCycles;
2021-09-05 01:09:30 +02:00
this.gainHackingExp(hackExpGain);
this.gainStrengthExp(strExpGain);
this.gainDefenseExp(defExpGain);
this.gainDexterityExp(dexExpGain);
this.gainAgilityExp(agiExpGain);
this.gainCharismaExp(chaExpGain);
this.gainMoney(moneyGain);
if (this.className) {
this.recordMoneySource(moneyGain, "class");
} else {
this.recordMoneySource(moneyGain, "work");
}
this.workHackExpGained += hackExpGain;
this.workStrExpGained += strExpGain;
this.workDefExpGained += defExpGain;
this.workDexExpGained += dexExpGain;
this.workAgiExpGained += agiExpGain;
this.workChaExpGained += chaExpGain;
this.workRepGained += focusBonus * this.workRepGainRate * numCycles;
this.workMoneyGained += focusBonus * this.workMoneyGainRate * numCycles;
this.workMoneyGained -= focusBonus * this.workMoneyLossRate * numCycles;
2019-04-04 02:08:11 +02:00
}
/* Working for Company */
export function startWork(companyName) {
2021-09-05 01:09:30 +02:00
this.resetWorkStatus(CONSTANTS.WorkTypeCompany, companyName);
this.isWorking = true;
this.focus = true;
this.companyName = companyName;
this.workType = CONSTANTS.WorkTypeCompany;
this.workHackExpGainRate = this.getWorkHackExpGain();
this.workStrExpGainRate = this.getWorkStrExpGain();
this.workDefExpGainRate = this.getWorkDefExpGain();
this.workDexExpGainRate = this.getWorkDexExpGain();
this.workAgiExpGainRate = this.getWorkAgiExpGain();
this.workChaExpGainRate = this.getWorkChaExpGain();
this.workRepGainRate = this.getWorkRepGain();
this.workMoneyGainRate = this.getWorkMoneyGain();
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer8Hours;
//Remove all old event listeners from Cancel button
var newCancelButton = clearEventListeners("work-in-progress-cancel-button");
newCancelButton.innerHTML = "Cancel Work";
newCancelButton.addEventListener("click", () => {
this.finishWork(true);
return false;
});
2021-09-09 05:47:34 +02:00
const focusButton = clearEventListeners("work-in-progress-something-else-button");
2021-09-05 01:09:30 +02:00
focusButton.style.visibility = "visible";
focusButton.innerHTML = "Do something else simultaneously";
focusButton.addEventListener("click", () => {
this.stopFocusing();
return false;
});
//Display Work In Progress Screen
Engine.loadWorkInProgressContent();
2019-04-04 02:08:11 +02:00
}
export function cancelationPenalty() {
2021-09-05 01:09:30 +02:00
const specialIp = SpecialServerIps[this.companyName];
if (specialIp) {
const server = AllServers[specialIp];
if (server && server.backdoorInstalled) return 0.75;
}
return 0.5;
}
2019-04-04 02:08:11 +02:00
export function work(numCycles) {
2021-09-05 01:09:30 +02:00
// Cap the number of cycles being processed to whatever would put you at
// the work time limit (8 hours)
var overMax = false;
2021-09-09 05:47:34 +02:00
if (this.timeWorked + Engine._idleSpeed * numCycles >= CONSTANTS.MillisecondsPer8Hours) {
2021-09-05 01:09:30 +02:00
overMax = true;
2021-09-09 05:47:34 +02:00
numCycles = Math.round((CONSTANTS.MillisecondsPer8Hours - this.timeWorked) / Engine._idleSpeed);
2021-09-05 01:09:30 +02:00
}
this.timeWorked += Engine._idleSpeed * numCycles;
this.workRepGainRate = this.getWorkRepGain();
this.processWorkEarnings(numCycles);
// If timeWorked == 8 hours, then finish. You can only gain 8 hours worth of exp and money
if (overMax || this.timeWorked >= CONSTANTS.MillisecondsPer8Hours) {
return this.finishWork(false);
}
const comp = Companies[this.companyName];
let companyRep = "0";
if (comp == null || !(comp instanceof Company)) {
console.error(`Could not find Company: ${this.companyName}`);
} else {
companyRep = comp.playerReputation;
}
influenceStockThroughCompanyWork(comp, this.workRepGainRate, numCycles);
const position = this.jobs[this.companyName];
const penalty = this.cancelationPenalty();
const penaltyString = penalty === 0.5 ? "half" : "three-quarters";
var elem = document.getElementById("work-in-progress-text");
ReactDOM.render(
<>
2021-09-09 05:47:34 +02:00
You are currently working as a {position} at {this.companyName} (Current Company Reputation:{" "}
{Reputation(companyRep)})<br />
2021-09-05 01:09:30 +02:00
<br />
2021-09-09 05:47:34 +02:00
You have been working for {convertTimeMsToTimeElapsedString(this.timeWorked)}
2021-09-05 01:09:30 +02:00
<br />
<br />
You have earned: <br />
<br />
2021-09-09 05:47:34 +02:00
<Money money={this.workMoneyGained} /> ({MoneyRate(this.workMoneyGainRate * CYCLES_PER_SEC)}) <br />
2021-09-05 01:09:30 +02:00
<br />
2021-09-09 05:47:34 +02:00
{Reputation(this.workRepGained)} ({ReputationRate(this.workRepGainRate * CYCLES_PER_SEC)}) reputation for this
company <br />
2021-09-05 01:09:30 +02:00
<br />
{numeralWrapper.formatExp(this.workHackExpGained)} (
2021-09-09 05:47:34 +02:00
{`${numeralWrapper.formatExp(this.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
2021-09-05 01:09:30 +02:00
) hacking exp <br />
<br />
{numeralWrapper.formatExp(this.workStrExpGained)} (
2021-09-09 05:47:34 +02:00
{`${numeralWrapper.formatExp(this.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}
2021-09-05 01:09:30 +02:00
) strength exp <br />
{numeralWrapper.formatExp(this.workDefExpGained)} (
2021-09-09 05:47:34 +02:00
{`${numeralWrapper.formatExp(this.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}
2021-09-05 01:09:30 +02:00
) defense exp <br />
{numeralWrapper.formatExp(this.workDexExpGained)} (
2021-09-09 05:47:34 +02:00
{`${numeralWrapper.formatExp(this.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}
2021-09-05 01:09:30 +02:00
) dexterity exp <br />
{numeralWrapper.formatExp(this.workAgiExpGained)} (
2021-09-09 05:47:34 +02:00
{`${numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}
2021-09-05 01:09:30 +02:00
) agility exp <br />
<br />
{numeralWrapper.formatExp(this.workChaExpGained)} (
2021-09-09 05:47:34 +02:00
{`${numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}
2021-09-05 01:09:30 +02:00
) charisma exp <br />
<br />
2021-09-09 05:47:34 +02:00
You will automatically finish after working for 8 hours. You can cancel earlier if you wish, but you will only
gain {penaltyString} of the reputation you've earned so far.
2021-09-05 01:09:30 +02:00
</>,
elem,
);
}
export function finishWork(cancelled, sing = false) {
//Since the work was cancelled early, player only gains half of what they've earned so far
if (cancelled) {
this.workRepGained *= this.cancelationPenalty();
}
const company = Companies[this.companyName];
company.playerReputation += this.workRepGained;
this.updateSkillLevels();
let content = (
<>
You earned a total of: <br />
<Money money={this.workMoneyGained} />
<br />
{Reputation(this.workRepGained)} reputation for the company <br />
{numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br />
{numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br />
{numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br />
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity exp <br />
{numeralWrapper.formatExp(this.workAgiExpGained)} agility exp <br />
{numeralWrapper.formatExp(this.workChaExpGained)} charisma exp
<br />
</>
2021-09-05 01:09:30 +02:00
);
if (cancelled) {
content = (
<>
2021-09-09 05:47:34 +02:00
You worked a short shift of {convertTimeMsToTimeElapsedString(this.timeWorked)} <br />
2021-09-05 01:09:30 +02:00
<br />
2021-09-09 05:47:34 +02:00
Since you cancelled your work early, you only gained half of the reputation you earned. <br />
2021-09-05 01:09:30 +02:00
<br />
{content}
</>
);
} else {
content = (
<>
You worked a full shift of 8 hours! <br />
<br />
{content}
</>
);
}
if (!sing) {
dialogBoxCreate(content);
}
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
this.isWorking = false;
Engine.loadLocationContent(false);
if (sing) {
var res =
"You worked a short shift of " +
convertTimeMsToTimeElapsedString(this.timeWorked) +
" and " +
"earned $" +
numeralWrapper.formatMoney(this.workMoneyGained) +
", " +
numeralWrapper.formatReputation(this.workRepGained) +
" reputation, " +
numeralWrapper.formatExp(this.workHackExpGained) +
" hacking exp, " +
numeralWrapper.formatExp(this.workStrExpGained) +
" strength exp, " +
numeralWrapper.formatExp(this.workDefExpGained) +
" defense exp, " +
numeralWrapper.formatExp(this.workDexExpGained) +
" dexterity exp, " +
numeralWrapper.formatExp(this.workAgiExpGained) +
" agility exp, and " +
numeralWrapper.formatExp(this.workChaExpGained) +
" charisma exp.";
2019-04-04 02:08:11 +02:00
this.resetWorkStatus();
2021-09-05 01:09:30 +02:00
return res;
}
this.resetWorkStatus();
2019-04-04 02:08:11 +02:00
}
export function startWorkPartTime(companyName) {
2021-09-05 01:09:30 +02:00
this.resetWorkStatus(CONSTANTS.WorkTypeCompanyPartTime, companyName);
this.isWorking = true;
this.focus = true;
this.companyName = companyName;
this.workType = CONSTANTS.WorkTypeCompanyPartTime;
this.workHackExpGainRate = this.getWorkHackExpGain();
this.workStrExpGainRate = this.getWorkStrExpGain();
this.workDefExpGainRate = this.getWorkDefExpGain();
this.workDexExpGainRate = this.getWorkDexExpGain();
this.workAgiExpGainRate = this.getWorkAgiExpGain();
this.workChaExpGainRate = this.getWorkChaExpGain();
this.workRepGainRate = this.getWorkRepGain();
this.workMoneyGainRate = this.getWorkMoneyGain();
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer8Hours;
var newCancelButton = clearEventListeners("work-in-progress-cancel-button");
newCancelButton.innerHTML = "Stop Working";
newCancelButton.addEventListener("click", () => {
this.finishWorkPartTime();
return false;
});
//Display Work In Progress Screen
Engine.loadWorkInProgressContent();
2019-04-04 02:08:11 +02:00
}
export function workPartTime(numCycles) {
2021-09-05 01:09:30 +02:00
//Cap the number of cycles being processed to whatever would put you at the
//work time limit (8 hours)
var overMax = false;
2021-09-09 05:47:34 +02:00
if (this.timeWorked + Engine._idleSpeed * numCycles >= CONSTANTS.MillisecondsPer8Hours) {
2021-09-05 01:09:30 +02:00
overMax = true;
2021-09-09 05:47:34 +02:00
numCycles = Math.round((CONSTANTS.MillisecondsPer8Hours - this.timeWorked) / Engine._idleSpeed);
2021-09-05 01:09:30 +02:00
}
this.timeWorked += Engine._idleSpeed * numCycles;
this.workRepGainRate = this.getWorkRepGain();
this.processWorkEarnings(numCycles);
//If timeWorked == 8 hours, then finish. You can only gain 8 hours worth of exp and money
if (overMax || this.timeWorked >= CONSTANTS.MillisecondsPer8Hours) {
return this.finishWorkPartTime();
}
var comp = Companies[this.companyName],
companyRep = "0";
if (comp == null || !(comp instanceof Company)) {
console.error(`Could not find Company: ${this.companyName}`);
} else {
companyRep = comp.playerReputation;
}
const position = this.jobs[this.companyName];
const elem = document.getElementById("work-in-progress-text");
ReactDOM.render(
<>
2021-09-09 05:47:34 +02:00
You are currently working as a {position} at {this.companyName} (Current Company Reputation:{" "}
{Reputation(companyRep)})<br />
2021-09-05 01:09:30 +02:00
<br />
2021-09-09 05:47:34 +02:00
You have been working for {convertTimeMsToTimeElapsedString(this.timeWorked)}
2021-09-05 01:09:30 +02:00
<br />
<br />
You have earned: <br />
<br />
2021-09-09 05:47:34 +02:00
<Money money={this.workMoneyGained} /> ({MoneyRate(this.workMoneyGainRate * CYCLES_PER_SEC)}) <br />
2021-09-05 01:09:30 +02:00
<br />
{Reputation(this.workRepGained)} (
2021-09-09 05:47:34 +02:00
{Reputation(`${numeralWrapper.formatExp(this.workRepGainRate * CYCLES_PER_SEC)} / sec`)}
2021-09-05 01:09:30 +02:00
) reputation for this company <br />
<br />
{numeralWrapper.formatExp(this.workHackExpGained)} (
2021-09-09 05:47:34 +02:00
{`${numeralWrapper.formatExp(this.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
2021-09-05 01:09:30 +02:00
) hacking exp <br />
<br />
{numeralWrapper.formatExp(this.workStrExpGained)} (
2021-09-09 05:47:34 +02:00
{`${numeralWrapper.formatExp(this.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}
2021-09-05 01:09:30 +02:00
) strength exp <br />
{numeralWrapper.formatExp(this.workDefExpGained)} (
2021-09-09 05:47:34 +02:00
{`${numeralWrapper.formatExp(this.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}
2021-09-05 01:09:30 +02:00
) defense exp <br />
{numeralWrapper.formatExp(this.workDexExpGained)} (
2021-09-09 05:47:34 +02:00
{`${numeralWrapper.formatExp(this.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}
2021-09-05 01:09:30 +02:00
) dexterity exp <br />
{numeralWrapper.formatExp(this.workAgiExpGained)} (
2021-09-09 05:47:34 +02:00
{`${numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}
2021-09-05 01:09:30 +02:00
) agility exp <br />
<br />
{numeralWrapper.formatExp(this.workChaExpGained)} (
2021-09-09 05:47:34 +02:00
{`${numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}
2021-09-05 01:09:30 +02:00
) charisma exp <br />
<br />
2021-09-09 05:47:34 +02:00
You will automatically finish after working for 8 hours. You can cancel earlier if you wish, and there will be no
penalty because this is a part-time job.
2021-09-05 01:09:30 +02:00
</>,
elem,
);
}
export function finishWorkPartTime(sing = false) {
var company = Companies[this.companyName];
company.playerReputation += this.workRepGained;
this.updateSkillLevels();
const content = (
<>
You worked for {convertTimeMsToTimeElapsedString(this.timeWorked)}
<br />
<br />
You earned a total of: <br />
<Money money={this.workMoneyGained} />
<br />
{Reputation(this.workRepGained)} reputation for the company <br />
{numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br />
{numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br />
{numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br />
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity exp <br />
{numeralWrapper.formatExp(this.workAgiExpGained)} agility exp <br />
{numeralWrapper.formatExp(this.workChaExpGained)} charisma exp
<br />
</>
);
if (!sing) {
dialogBoxCreate(content);
}
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
this.isWorking = false;
Engine.loadLocationContent(false);
if (sing) {
var res =
"You worked for " +
convertTimeMsToTimeElapsedString(this.timeWorked) +
" and " +
"earned a total of " +
"$" +
numeralWrapper.formatMoney(this.workMoneyGained) +
", " +
numeralWrapper.formatReputation(this.workRepGained) +
" reputation, " +
numeralWrapper.formatExp(this.workHackExpGained) +
" hacking exp, " +
numeralWrapper.formatExp(this.workStrExpGained) +
" strength exp, " +
numeralWrapper.formatExp(this.workDefExpGained) +
" defense exp, " +
numeralWrapper.formatExp(this.workDexExpGained) +
" dexterity exp, " +
numeralWrapper.formatExp(this.workAgiExpGained) +
" agility exp, and " +
numeralWrapper.formatExp(this.workChaExpGained) +
" charisma exp";
2019-04-04 02:08:11 +02:00
this.resetWorkStatus();
2021-09-05 01:09:30 +02:00
return res;
}
this.resetWorkStatus();
2019-04-04 02:08:11 +02:00
}
2021-05-31 23:34:23 +02:00
export function startFocusing() {
2021-09-05 01:09:30 +02:00
const mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "hidden";
this.focus = true;
Engine.loadWorkInProgressContent();
2021-05-31 23:34:23 +02:00
}
export function stopFocusing() {
2021-09-05 01:09:30 +02:00
const mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
this.focus = false;
Engine.loadTerminalContent();
2021-05-31 23:34:23 +02:00
}
2019-04-04 02:08:11 +02:00
/* Working for Faction */
export function startFactionWork(faction) {
2021-09-05 01:09:30 +02:00
//Update reputation gain rate to account for faction favor
var favorMult = 1 + faction.favor / 100;
if (isNaN(favorMult)) {
favorMult = 1;
}
this.workRepGainRate *= favorMult;
this.workRepGainRate *= BitNodeMultipliers.FactionWorkRepGain;
this.isWorking = true;
this.focus = true;
this.workType = CONSTANTS.WorkTypeFaction;
this.currentWorkFactionName = faction.name;
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer20Hours;
const cancelButton = clearEventListeners("work-in-progress-cancel-button");
cancelButton.innerHTML = "Stop Faction Work";
cancelButton.addEventListener("click", () => {
this.finishFactionWork(true);
return false;
});
2021-09-09 05:47:34 +02:00
const focusButton = clearEventListeners("work-in-progress-something-else-button");
2021-09-05 01:09:30 +02:00
focusButton.style.visibility = "visible";
focusButton.innerHTML = "Do something else simultaneously";
focusButton.addEventListener("click", () => {
this.stopFocusing();
return false;
});
//Display Work In Progress Screen
Engine.loadWorkInProgressContent();
2019-04-04 02:08:11 +02:00
}
export function startFactionHackWork(faction) {
2021-09-09 05:47:34 +02:00
this.resetWorkStatus(CONSTANTS.WorkTypeFaction, faction.name, CONSTANTS.FactionWorkHacking);
2019-04-04 02:08:11 +02:00
2021-09-09 05:47:34 +02:00
this.workHackExpGainRate = 0.15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
2021-09-05 01:09:30 +02:00
this.workRepGainRate =
((this.hacking_skill + this.intelligence) / CONSTANTS.MaxSkillLevel) *
this.faction_rep_mult *
this.getIntelligenceBonus(0.5);
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.factionWorkType = CONSTANTS.FactionWorkHacking;
this.currentWorkFactionDescription = "carrying out hacking contracts";
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.startFactionWork(faction);
2019-04-04 02:08:11 +02:00
}
export function startFactionFieldWork(faction) {
2021-09-09 05:47:34 +02:00
this.resetWorkStatus(CONSTANTS.WorkTypeFaction, faction.name, CONSTANTS.FactionWorkField);
this.workHackExpGainRate = 0.1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.workStrExpGainRate = 0.1 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.workDefExpGainRate = 0.1 * this.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.workDexExpGainRate = 0.1 * this.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.workAgiExpGainRate = 0.1 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.workChaExpGainRate = 0.1 * this.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
2021-09-05 01:09:30 +02:00
this.workRepGainRate = getFactionFieldWorkRepGain(this, faction);
this.factionWorkType = CONSTANTS.FactionWorkField;
this.currentWorkFactionDescription = "carrying out field missions";
this.startFactionWork(faction);
2019-04-04 02:08:11 +02:00
}
export function startFactionSecurityWork(faction) {
2021-09-09 05:47:34 +02:00
this.resetWorkStatus(CONSTANTS.WorkTypeFaction, faction.name, CONSTANTS.FactionWorkSecurity);
this.workHackExpGainRate = 0.05 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.workStrExpGainRate = 0.15 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.workDefExpGainRate = 0.15 * this.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.workDexExpGainRate = 0.15 * this.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.workAgiExpGainRate = 0.15 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.workChaExpGainRate = 0.0 * this.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
2021-09-05 01:09:30 +02:00
this.workRepGainRate = getFactionSecurityWorkRepGain(this, faction);
this.factionWorkType = CONSTANTS.FactionWorkSecurity;
this.currentWorkFactionDescription = "performing security detail";
this.startFactionWork(faction);
2019-04-04 02:08:11 +02:00
}
export function workForFaction(numCycles) {
2021-09-05 01:09:30 +02:00
const faction = Factions[this.currentWorkFactionName];
//Constantly update the rep gain rate
switch (this.factionWorkType) {
case CONSTANTS.FactionWorkHacking:
this.workRepGainRate = getHackingWorkRepGain(this, faction);
break;
case CONSTANTS.FactionWorkField:
this.workRepGainRate = getFactionFieldWorkRepGain(this, faction);
break;
case CONSTANTS.FactionWorkSecurity:
this.workRepGainRate = getFactionSecurityWorkRepGain(this, faction);
break;
default:
break;
}
//Cap the number of cycles being processed to whatever would put you at limit (20 hours)
var overMax = false;
2021-09-09 05:47:34 +02:00
if (this.timeWorked + Engine._idleSpeed * numCycles >= CONSTANTS.MillisecondsPer20Hours) {
2021-09-05 01:09:30 +02:00
overMax = true;
2021-09-09 05:47:34 +02:00
numCycles = Math.round((CONSTANTS.MillisecondsPer20Hours - this.timeWorked) / Engine._idleSpeed);
2021-09-05 01:09:30 +02:00
}
this.timeWorked += Engine._idleSpeed * numCycles;
this.processWorkEarnings(numCycles);
//If timeWorked == 20 hours, then finish. You can only work for the faction for 20 hours
if (overMax || this.timeWorked >= CONSTANTS.MillisecondsPer20Hours) {
return this.finishFactionWork(false);
}
const elem = document.getElementById("work-in-progress-text");
ReactDOM.render(
<>
2021-09-09 05:47:34 +02:00
You are currently {this.currentWorkFactionDescription} for your faction {faction.name}
2021-09-05 01:09:30 +02:00
<br />
2021-09-09 05:47:34 +02:00
(Current Faction Reputation: {Reputation(faction.playerReputation)}). <br />
You have been doing this for {convertTimeMsToTimeElapsedString(this.timeWorked)}
2021-09-05 01:09:30 +02:00
<br />
<br />
You have earned: <br />
<br />
2021-09-09 05:47:34 +02:00
<Money money={this.workMoneyGained} /> ({MoneyRate(this.workMoneyGainRate * CYCLES_PER_SEC)}) <br />
2021-09-05 01:09:30 +02:00
<br />
2021-09-09 05:47:34 +02:00
{Reputation(this.workRepGained)} ({ReputationRate(this.workRepGainRate * CYCLES_PER_SEC)}) reputation for this
faction <br />
2021-09-05 01:09:30 +02:00
<br />
{numeralWrapper.formatExp(this.workHackExpGained)} (
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
2021-09-05 01:09:30 +02:00
<br />
{numeralWrapper.formatExp(this.workStrExpGained)} (
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp <br />
2021-09-05 01:09:30 +02:00
{numeralWrapper.formatExp(this.workDefExpGained)} (
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp <br />
2021-09-05 01:09:30 +02:00
{numeralWrapper.formatExp(this.workDexExpGained)} (
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp <br />
2021-09-05 01:09:30 +02:00
{numeralWrapper.formatExp(this.workAgiExpGained)} (
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp <br />
2021-09-05 01:09:30 +02:00
<br />
{numeralWrapper.formatExp(this.workChaExpGained)} (
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp <br />
2021-09-05 01:09:30 +02:00
<br />
2021-09-09 05:47:34 +02:00
You will automatically finish after working for 20 hours. You can cancel earlier if you wish.
2021-09-05 01:09:30 +02:00
<br />
There is no penalty for cancelling earlier.
</>,
elem,
);
}
export function finishFactionWork(cancelled, sing = false) {
var faction = Factions[this.currentWorkFactionName];
faction.playerReputation += this.workRepGained;
this.updateSkillLevels();
if (!sing) {
dialogBoxCreate(
<>
2021-09-09 05:47:34 +02:00
You worked for your faction {faction.name} for a total of {convertTimeMsToTimeElapsedString(this.timeWorked)}{" "}
<br />
2021-09-05 01:09:30 +02:00
<br />
You earned a total of: <br />
<Money money={this.workMoneyGained} />
<br />
{Reputation(this.workRepGained)} reputation for the faction <br />
{numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br />
{numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br />
{numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br />
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity exp <br />
{numeralWrapper.formatExp(this.workAgiExpGained)} agility exp <br />
{numeralWrapper.formatExp(this.workChaExpGained)} charisma exp
<br />
</>,
);
}
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
this.isWorking = false;
Engine.loadFactionContent();
displayFactionContent(faction.name);
if (sing) {
var res =
"You worked for your faction " +
faction.name +
" for a total of " +
convertTimeMsToTimeElapsedString(this.timeWorked) +
". " +
"You earned " +
numeralWrapper.formatReputation(this.workRepGained) +
" rep, " +
numeralWrapper.formatExp(this.workHackExpGained) +
" hacking exp, " +
numeralWrapper.formatExp(this.workStrExpGained) +
" str exp, " +
numeralWrapper.formatExp(this.workDefExpGained) +
" def exp, " +
numeralWrapper.formatExp(this.workDexExpGained) +
" dex exp, " +
numeralWrapper.formatExp(this.workAgiExpGained) +
" agi exp, and " +
numeralWrapper.formatExp(this.workChaExpGained) +
" cha exp.";
2019-04-04 02:08:11 +02:00
this.resetWorkStatus();
2021-09-05 01:09:30 +02:00
return res;
}
this.resetWorkStatus();
2019-04-04 02:08:11 +02:00
}
//Money gained per game cycle
export function getWorkMoneyGain() {
2021-09-05 01:09:30 +02:00
// If player has SF-11, calculate salary multiplier from favor
let bn11Mult = 1;
const company = Companies[this.companyName];
if (SourceFileFlags[11] > 0) {
bn11Mult = 1 + company.favor / 100;
}
// Get base salary
const companyPositionName = this.jobs[this.companyName];
const companyPosition = CompanyPositions[companyPositionName];
if (companyPosition == null) {
2021-09-09 05:47:34 +02:00
console.error(`Could not find CompanyPosition object for ${companyPositionName}. Work salary will be 0`);
2021-09-05 01:09:30 +02:00
return 0;
}
return (
companyPosition.baseSalary *
company.salaryMultiplier *
this.work_money_mult *
BitNodeMultipliers.CompanyWorkMoney *
bn11Mult
);
2019-04-04 02:08:11 +02:00
}
//Hack exp gained per game cycle
export function getWorkHackExpGain() {
2021-09-05 01:09:30 +02:00
const company = Companies[this.companyName];
const companyPositionName = this.jobs[this.companyName];
const companyPosition = CompanyPositions[companyPositionName];
if (company == null || companyPosition == null) {
console.error(
[
`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${companyPositionName}.`,
`Work hack exp gain will be 0`,
].join(" "),
);
return 0;
}
return (
companyPosition.hackingExpGain *
company.expMultiplier *
this.hacking_exp_mult *
BitNodeMultipliers.CompanyWorkExpGain
);
2019-04-04 02:08:11 +02:00
}
//Str exp gained per game cycle
export function getWorkStrExpGain() {
2021-09-05 01:09:30 +02:00
const company = Companies[this.companyName];
const companyPositionName = this.jobs[this.companyName];
const companyPosition = CompanyPositions[companyPositionName];
if (company == null || companyPosition == null) {
console.error(
[
`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${companyPositionName}.`,
`Work str exp gain will be 0`,
].join(" "),
);
return 0;
}
return (
companyPosition.strengthExpGain *
company.expMultiplier *
this.strength_exp_mult *
BitNodeMultipliers.CompanyWorkExpGain
);
2019-04-04 02:08:11 +02:00
}
//Def exp gained per game cycle
export function getWorkDefExpGain() {
2021-09-05 01:09:30 +02:00
const company = Companies[this.companyName];
const companyPositionName = this.jobs[this.companyName];
const companyPosition = CompanyPositions[companyPositionName];
if (company == null || companyPosition == null) {
console.error(
[
`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${companyPositionName}.`,
`Work def exp gain will be 0`,
].join(" "),
);
return 0;
}
return (
companyPosition.defenseExpGain *
company.expMultiplier *
this.defense_exp_mult *
BitNodeMultipliers.CompanyWorkExpGain
);
2019-04-04 02:08:11 +02:00
}
//Dex exp gained per game cycle
export function getWorkDexExpGain() {
2021-09-05 01:09:30 +02:00
const company = Companies[this.companyName];
const companyPositionName = this.jobs[this.companyName];
const companyPosition = CompanyPositions[companyPositionName];
if (company == null || companyPosition == null) {
console.error(
[
`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${companyPositionName}.`,
`Work dex exp gain will be 0`,
].join(" "),
);
return 0;
}
return (
companyPosition.dexterityExpGain *
company.expMultiplier *
this.dexterity_exp_mult *
BitNodeMultipliers.CompanyWorkExpGain
);
2019-04-04 02:08:11 +02:00
}
//Agi exp gained per game cycle
export function getWorkAgiExpGain() {
2021-09-05 01:09:30 +02:00
const company = Companies[this.companyName];
const companyPositionName = this.jobs[this.companyName];
const companyPosition = CompanyPositions[companyPositionName];
if (company == null || companyPosition == null) {
console.error(
[
`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${companyPositionName}.`,
`Work agi exp gain will be 0`,
].join(" "),
);
return 0;
}
return (
companyPosition.agilityExpGain *
company.expMultiplier *
this.agility_exp_mult *
BitNodeMultipliers.CompanyWorkExpGain
);
2019-04-04 02:08:11 +02:00
}
//Charisma exp gained per game cycle
export function getWorkChaExpGain() {
2021-09-05 01:09:30 +02:00
const company = Companies[this.companyName];
const companyPositionName = this.jobs[this.companyName];
const companyPosition = CompanyPositions[companyPositionName];
if (company == null || companyPosition == null) {
console.error(
[
`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${companyPositionName}.`,
`Work cha exp gain will be 0`,
].join(" "),
);
return 0;
}
return (
companyPosition.charismaExpGain *
company.expMultiplier *
this.charisma_exp_mult *
BitNodeMultipliers.CompanyWorkExpGain
);
2019-04-04 02:08:11 +02:00
}
//Reputation gained per game cycle
export function getWorkRepGain() {
2021-09-05 01:09:30 +02:00
const company = Companies[this.companyName];
const companyPositionName = this.jobs[this.companyName];
const companyPosition = CompanyPositions[companyPositionName];
if (company == null || companyPosition == null) {
console.error(
[
`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${companyPositionName}.`,
`Work rep gain will be 0`,
].join(" "),
);
return 0;
}
var jobPerformance = companyPosition.calculateJobPerformance(
this.hacking_skill,
this.strength,
this.defense,
this.dexterity,
this.agility,
this.charisma,
);
//Intelligence provides a flat bonus to job performance
jobPerformance += this.intelligence / CONSTANTS.MaxSkillLevel;
//Update reputation gain rate to account for company favor
var favorMult = 1 + company.favor / 100;
if (isNaN(favorMult)) {
favorMult = 1;
}
return jobPerformance * this.company_rep_mult * favorMult;
2019-04-04 02:08:11 +02:00
}
// export function getFactionSecurityWorkRepGain() {
// var t = 0.9 * (this.hacking_skill / CONSTANTS.MaxSkillLevel +
// this.strength / CONSTANTS.MaxSkillLevel +
// this.defense / CONSTANTS.MaxSkillLevel +
// this.dexterity / CONSTANTS.MaxSkillLevel +
// this.agility / CONSTANTS.MaxSkillLevel) / 4.5;
// return t * this.faction_rep_mult;
// }
// export function getFactionFieldWorkRepGain() {
// var t = 0.9 * (this.hacking_skill / CONSTANTS.MaxSkillLevel +
// this.strength / CONSTANTS.MaxSkillLevel +
// this.defense / CONSTANTS.MaxSkillLevel +
// this.dexterity / CONSTANTS.MaxSkillLevel +
// this.agility / CONSTANTS.MaxSkillLevel +
// this.charisma / CONSTANTS.MaxSkillLevel +
// this.intelligence / CONSTANTS.MaxSkillLevel) / 5.5;
// return t * this.faction_rep_mult;
// }
2019-04-04 02:08:11 +02:00
/* Creating a Program */
export function startCreateProgramWork(programName, time, reqLevel) {
2021-09-05 01:09:30 +02:00
this.resetWorkStatus();
this.isWorking = true;
this.focus = true;
this.workType = CONSTANTS.WorkTypeCreateProgram;
//Time needed to complete work affected by hacking skill (linearly based on
//ratio of (your skill - required level) to MAX skill)
//var timeMultiplier = (CONSTANTS.MaxSkillLevel - (this.hacking_skill - reqLevel)) / CONSTANTS.MaxSkillLevel;
//if (timeMultiplier > 1) {timeMultiplier = 1;}
//if (timeMultiplier < 0.01) {timeMultiplier = 0.01;}
this.createProgramReqLvl = reqLevel;
this.timeNeededToCompleteWork = time;
//Check for incomplete program
for (var i = 0; i < this.getHomeComputer().programs.length; ++i) {
var programFile = this.getHomeComputer().programs[i];
if (programFile.startsWith(programName) && programFile.endsWith("%-INC")) {
var res = programFile.split("-");
if (res.length != 3) {
break;
}
var percComplete = Number(res[1].slice(0, -1));
if (isNaN(percComplete) || percComplete < 0 || percComplete >= 100) {
break;
}
2021-09-09 05:47:34 +02:00
this.timeWorkedCreateProgram = (percComplete / 100) * this.timeNeededToCompleteWork;
2021-09-05 01:09:30 +02:00
this.getHomeComputer().programs.splice(i, 1);
}
}
this.createProgramName = programName;
var cancelButton = clearEventListeners("work-in-progress-cancel-button");
cancelButton.innerHTML = "Cancel work on creating program";
cancelButton.addEventListener("click", () => {
this.finishCreateProgramWork(true);
return false;
});
2019-04-04 02:08:11 +02:00
2021-09-09 05:47:34 +02:00
const focusButton = clearEventListeners("work-in-progress-something-else-button");
2021-09-05 01:09:30 +02:00
focusButton.style.visibility = "hidden";
2021-05-31 23:34:23 +02:00
2021-09-05 01:09:30 +02:00
//Display Work In Progress Screen
Engine.loadWorkInProgressContent();
2019-04-04 02:08:11 +02:00
}
export function createProgramWork(numCycles) {
2021-09-05 01:09:30 +02:00
//Higher hacking skill will allow you to create programs faster
var reqLvl = this.createProgramReqLvl;
var skillMult = (this.hacking_skill / reqLvl) * this.getIntelligenceBonus(3); //This should always be greater than 1;
skillMult = 1 + (skillMult - 1) / 5; //The divider constant can be adjusted as necessary
//Skill multiplier directly applied to "time worked"
this.timeWorked += Engine._idleSpeed * numCycles;
this.timeWorkedCreateProgram += Engine._idleSpeed * numCycles * skillMult;
var programName = this.createProgramName;
if (this.timeWorkedCreateProgram >= this.timeNeededToCompleteWork) {
this.finishCreateProgramWork(false);
}
const elem = document.getElementById("work-in-progress-text");
ReactDOM.render(
<>
You are currently working on coding {programName}.<br />
<br />
2021-09-09 05:47:34 +02:00
You have been working for {convertTimeMsToTimeElapsedString(this.timeWorked)}
2021-09-05 01:09:30 +02:00
<br />
<br />
2021-09-09 05:47:34 +02:00
The program is {((this.timeWorkedCreateProgram / this.timeNeededToCompleteWork) * 100).toFixed(2)}
2021-09-05 01:09:30 +02:00
% complete. <br />
2021-09-09 05:47:34 +02:00
If you cancel, your work will be saved and you can come back to complete the program later.
2021-09-05 01:09:30 +02:00
</>,
elem,
);
2019-04-04 02:08:11 +02:00
}
2021-05-01 09:17:31 +02:00
export function finishCreateProgramWork(cancelled) {
2021-09-05 01:09:30 +02:00
var programName = this.createProgramName;
if (cancelled === false) {
dialogBoxCreate(
2021-09-09 05:47:34 +02:00
"You've finished creating " + programName + "!<br>" + "The new program can be found on your home computer.",
2021-09-05 01:09:30 +02:00
);
this.getHomeComputer().programs.push(programName);
} else {
2021-09-09 05:47:34 +02:00
var perc = (Math.floor((this.timeWorkedCreateProgram / this.timeNeededToCompleteWork) * 10000) / 100).toString();
2021-09-05 01:09:30 +02:00
var incompleteName = programName + "-" + perc + "%-INC";
this.getHomeComputer().programs.push(incompleteName);
}
if (!cancelled) {
2021-09-09 05:47:34 +02:00
this.gainIntelligenceExp(this.createProgramReqLvl / CONSTANTS.IntelligenceProgramBaseExpGain);
2021-09-05 01:09:30 +02:00
}
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
this.isWorking = false;
Engine.loadTerminalContent();
this.resetWorkStatus();
2019-04-04 02:08:11 +02:00
}
/* Studying/Taking Classes */
export function startClass(costMult, expMult, className) {
2021-09-05 01:09:30 +02:00
this.resetWorkStatus();
this.isWorking = true;
this.focus = true;
this.workType = CONSTANTS.WorkTypeStudyClass;
this.className = className;
const gameCPS = 1000 / Engine._idleSpeed;
//Find cost and exp gain per game cycle
var cost = 0;
var hackExp = 0,
strExp = 0,
defExp = 0,
dexExp = 0,
agiExp = 0,
chaExp = 0;
const hashManager = this.hashManager;
switch (className) {
case CONSTANTS.ClassStudyComputerScience:
2021-09-09 05:47:34 +02:00
hackExp = ((CONSTANTS.ClassStudyComputerScienceBaseExp * expMult) / gameCPS) * hashManager.getStudyMult();
2021-09-05 01:09:30 +02:00
break;
case CONSTANTS.ClassDataStructures:
cost = (CONSTANTS.ClassDataStructuresBaseCost * costMult) / gameCPS;
2021-09-09 05:47:34 +02:00
hackExp = ((CONSTANTS.ClassDataStructuresBaseExp * expMult) / gameCPS) * hashManager.getStudyMult();
2021-09-05 01:09:30 +02:00
break;
case CONSTANTS.ClassNetworks:
cost = (CONSTANTS.ClassNetworksBaseCost * costMult) / gameCPS;
2021-09-09 05:47:34 +02:00
hackExp = ((CONSTANTS.ClassNetworksBaseExp * expMult) / gameCPS) * hashManager.getStudyMult();
2021-09-05 01:09:30 +02:00
break;
case CONSTANTS.ClassAlgorithms:
cost = (CONSTANTS.ClassAlgorithmsBaseCost * costMult) / gameCPS;
2021-09-09 05:47:34 +02:00
hackExp = ((CONSTANTS.ClassAlgorithmsBaseExp * expMult) / gameCPS) * hashManager.getStudyMult();
2021-09-05 01:09:30 +02:00
break;
case CONSTANTS.ClassManagement:
cost = (CONSTANTS.ClassManagementBaseCost * costMult) / gameCPS;
2021-09-09 05:47:34 +02:00
chaExp = ((CONSTANTS.ClassManagementBaseExp * expMult) / gameCPS) * hashManager.getStudyMult();
2021-09-05 01:09:30 +02:00
break;
case CONSTANTS.ClassLeadership:
cost = (CONSTANTS.ClassLeadershipBaseCost * costMult) / gameCPS;
2021-09-09 05:47:34 +02:00
chaExp = ((CONSTANTS.ClassLeadershipBaseExp * expMult) / gameCPS) * hashManager.getStudyMult();
2021-09-05 01:09:30 +02:00
break;
case CONSTANTS.ClassGymStrength:
cost = (CONSTANTS.ClassGymBaseCost * costMult) / gameCPS;
strExp = (expMult / gameCPS) * hashManager.getTrainingMult();
break;
case CONSTANTS.ClassGymDefense:
cost = (CONSTANTS.ClassGymBaseCost * costMult) / gameCPS;
defExp = (expMult / gameCPS) * hashManager.getTrainingMult();
break;
case CONSTANTS.ClassGymDexterity:
cost = (CONSTANTS.ClassGymBaseCost * costMult) / gameCPS;
dexExp = (expMult / gameCPS) * hashManager.getTrainingMult();
break;
case CONSTANTS.ClassGymAgility:
cost = (CONSTANTS.ClassGymBaseCost * costMult) / gameCPS;
agiExp = (expMult / gameCPS) * hashManager.getTrainingMult();
break;
default:
throw new Error("ERR: Invalid/unrecognized class name");
return;
}
this.workMoneyLossRate = cost;
2021-09-09 05:47:34 +02:00
this.workHackExpGainRate = hackExp * this.hacking_exp_mult * BitNodeMultipliers.ClassGymExpGain;
this.workStrExpGainRate = strExp * this.strength_exp_mult * BitNodeMultipliers.ClassGymExpGain;
this.workDefExpGainRate = defExp * this.defense_exp_mult * BitNodeMultipliers.ClassGymExpGain;
this.workDexExpGainRate = dexExp * this.dexterity_exp_mult * BitNodeMultipliers.ClassGymExpGain;
this.workAgiExpGainRate = agiExp * this.agility_exp_mult * BitNodeMultipliers.ClassGymExpGain;
this.workChaExpGainRate = chaExp * this.charisma_exp_mult * BitNodeMultipliers.ClassGymExpGain;
2021-09-05 01:09:30 +02:00
var cancelButton = clearEventListeners("work-in-progress-cancel-button");
if (
className == CONSTANTS.ClassGymStrength ||
className == CONSTANTS.ClassGymDefense ||
className == CONSTANTS.ClassGymDexterity ||
className == CONSTANTS.ClassGymAgility
) {
cancelButton.innerHTML = "Stop training at gym";
} else {
cancelButton.innerHTML = "Stop taking course";
}
cancelButton.addEventListener("click", () => {
this.finishClass();
return false;
});
2019-04-04 02:08:11 +02:00
2021-09-09 05:47:34 +02:00
const focusButton = clearEventListeners("work-in-progress-something-else-button");
2021-09-05 01:09:30 +02:00
focusButton.style.visibility = "hidden";
2021-09-05 01:09:30 +02:00
//Display Work In Progress Screen
Engine.loadWorkInProgressContent();
2019-04-04 02:08:11 +02:00
}
export function takeClass(numCycles) {
2021-09-05 01:09:30 +02:00
this.timeWorked += Engine._idleSpeed * numCycles;
var className = this.className;
this.processWorkEarnings(numCycles);
const elem = document.getElementById("work-in-progress-text");
ReactDOM.render(
<>
2021-09-09 05:47:34 +02:00
You have been {className} for {convertTimeMsToTimeElapsedString(this.timeWorked)}
2021-09-05 01:09:30 +02:00
<br />
<br />
This has cost you: <br />
2021-09-09 05:47:34 +02:00
<Money money={-this.workMoneyGained} /> ({MoneyRate(this.workMoneyLossRate * CYCLES_PER_SEC)}) <br />
2021-09-05 01:09:30 +02:00
<br />
You have gained: <br />
{numeralWrapper.formatExp(this.workHackExpGained)} (
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
2021-09-05 01:09:30 +02:00
{numeralWrapper.formatExp(this.workStrExpGained)} (
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp <br />
2021-09-05 01:09:30 +02:00
{numeralWrapper.formatExp(this.workDefExpGained)} (
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp <br />
2021-09-05 01:09:30 +02:00
{numeralWrapper.formatExp(this.workDexExpGained)} (
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp <br />
2021-09-05 01:09:30 +02:00
{numeralWrapper.formatExp(this.workAgiExpGained)} (
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp <br />
2021-09-05 01:09:30 +02:00
{numeralWrapper.formatExp(this.workChaExpGained)} (
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp <br />
2021-09-05 01:09:30 +02:00
You may cancel at any time
</>,
elem,
);
2019-04-04 02:08:11 +02:00
}
//The 'sing' argument defines whether or not this function was called
//through a Singularity Netscript function
2021-09-05 01:09:30 +02:00
export function finishClass(sing = false) {
2021-09-09 05:47:34 +02:00
this.gainIntelligenceExp(CONSTANTS.IntelligenceClassBaseExpGain * Math.round(this.timeWorked / 1000));
2021-09-05 01:09:30 +02:00
if (this.workMoneyGained > 0) {
throw new Error("ERR: Somehow gained money while taking class");
}
this.updateSkillLevels();
if (!sing) {
dialogBoxCreate(
<>
2021-09-09 05:47:34 +02:00
After {this.className} for {convertTimeMsToTimeElapsedString(this.timeWorked)}, <br />
2021-09-05 01:09:30 +02:00
you spent a total of <Money money={-this.workMoneyGained} />. <br />
<br />
You earned a total of: <br />
{numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br />
{numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br />
{numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br />
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity exp <br />
{numeralWrapper.formatExp(this.workAgiExpGained)} agility exp <br />
{numeralWrapper.formatExp(this.workChaExpGained)} charisma exp
<br />
</>,
);
}
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
this.isWorking = false;
Engine.loadLocationContent(false);
if (sing) {
var res =
"After " +
this.className +
" for " +
convertTimeMsToTimeElapsedString(this.timeWorked) +
", " +
"you spent a total of " +
numeralWrapper.formatMoney(this.workMoneyGained * -1) +
". " +
"You earned a total of: " +
numeralWrapper.formatExp(this.workHackExpGained) +
" hacking exp, " +
numeralWrapper.formatExp(this.workStrExpGained) +
" strength exp, " +
numeralWrapper.formatExp(this.workDefExpGained) +
" defense exp, " +
numeralWrapper.formatExp(this.workDexExpGained) +
" dexterity exp, " +
numeralWrapper.formatExp(this.workAgiExpGained) +
" agility exp, and " +
numeralWrapper.formatExp(this.workChaExpGained) +
" charisma exp";
2019-04-04 02:08:11 +02:00
this.resetWorkStatus();
2021-09-05 01:09:30 +02:00
return res;
}
this.resetWorkStatus();
2019-04-04 02:08:11 +02:00
}
//The EXP and $ gains are hardcoded. Time is in ms
2021-09-09 05:47:34 +02:00
export function startCrime(crimeType, hackExp, strExp, defExp, dexExp, agiExp, chaExp, money, time, singParams = null) {
2021-09-05 01:09:30 +02:00
this.crimeType = crimeType;
this.resetWorkStatus();
this.isWorking = true;
this.focus = true;
this.workType = CONSTANTS.WorkTypeCrime;
if (singParams && singParams.workerscript) {
this.committingCrimeThruSingFn = true;
this.singFnCrimeWorkerScript = singParams.workerscript;
}
2021-09-09 05:47:34 +02:00
this.workHackExpGained = hackExp * this.hacking_exp_mult * BitNodeMultipliers.CrimeExpGain;
this.workStrExpGained = strExp * this.strength_exp_mult * BitNodeMultipliers.CrimeExpGain;
this.workDefExpGained = defExp * this.defense_exp_mult * BitNodeMultipliers.CrimeExpGain;
this.workDexExpGained = dexExp * this.dexterity_exp_mult * BitNodeMultipliers.CrimeExpGain;
this.workAgiExpGained = agiExp * this.agility_exp_mult * BitNodeMultipliers.CrimeExpGain;
this.workChaExpGained = chaExp * this.charisma_exp_mult * BitNodeMultipliers.CrimeExpGain;
this.workMoneyGained = money * this.crime_money_mult * BitNodeMultipliers.CrimeMoney;
2021-09-05 01:09:30 +02:00
this.timeNeededToCompleteWork = time;
//Remove all old event listeners from Cancel button
const newCancelButton = clearEventListeners("work-in-progress-cancel-button");
newCancelButton.innerHTML = "Cancel crime";
newCancelButton.addEventListener("click", () => {
this.finishCrime(true);
return false;
});
2019-04-04 02:08:11 +02:00
2021-09-09 05:47:34 +02:00
const focusButton = clearEventListeners("work-in-progress-something-else-button");
2021-09-05 01:09:30 +02:00
focusButton.style.visibility = "hidden";
2021-05-31 23:34:23 +02:00
2021-09-05 01:09:30 +02:00
//Display Work In Progress Screen
Engine.loadWorkInProgressContent();
2019-04-04 02:08:11 +02:00
}
export function commitCrime(numCycles) {
2021-09-05 01:09:30 +02:00
this.timeWorked += Engine._idleSpeed * numCycles;
if (this.timeWorked >= this.timeNeededToCompleteWork) {
this.finishCrime(false);
return;
}
2021-09-09 05:47:34 +02:00
var percent = Math.round((this.timeWorked / this.timeNeededToCompleteWork) * 100);
2021-09-05 01:09:30 +02:00
var numBars = Math.round(percent / 5);
if (numBars < 0) {
numBars = 0;
}
if (numBars > 20) {
numBars = 20;
}
2021-09-09 05:47:34 +02:00
var progressBar = "[" + Array(numBars + 1).join("|") + Array(20 - numBars + 1).join(" ") + "]";
2021-09-05 01:09:30 +02:00
var txt = document.getElementById("work-in-progress-text");
txt.innerHTML =
"You are attempting to " +
this.crimeType +
".<br>" +
"Time remaining: " +
2021-09-09 05:47:34 +02:00
convertTimeMsToTimeElapsedString(this.timeNeededToCompleteWork - this.timeWorked) +
2021-09-05 01:09:30 +02:00
"<br>" +
progressBar.replace(/ /g, "&nbsp;");
2019-04-04 02:08:11 +02:00
}
export function finishCrime(cancelled) {
2021-09-05 01:09:30 +02:00
//Determine crime success/failure
if (!cancelled) {
if (determineCrimeSuccess(this, this.crimeType)) {
//Handle Karma and crime statistics
let crime = null;
for (const i in Crimes) {
if (Crimes[i].type == this.crimeType) {
crime = Crimes[i];
break;
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
}
if (crime == null) {
dialogBoxCreate(
`ERR: Unrecognized crime type (${this.crimeType}). This is probably a bug please contact the developer`,
);
}
this.gainMoney(this.workMoneyGained);
this.recordMoneySource(this.workMoneyGained, "crime");
this.karma -= crime.karma;
this.numPeopleKilled += crime.kills;
if (crime.intelligence_exp > 0) {
this.gainIntelligenceExp(crime.intelligence_exp);
}
//On a crime success, gain 2x exp
this.workHackExpGained *= 2;
this.workStrExpGained *= 2;
this.workDefExpGained *= 2;
this.workDexExpGained *= 2;
this.workAgiExpGained *= 2;
this.workChaExpGained *= 2;
if (this.committingCrimeThruSingFn) {
if (
this.singFnCrimeWorkerScript.disableLogs.ALL == null &&
this.singFnCrimeWorkerScript.disableLogs.commitCrime == null
) {
this.singFnCrimeWorkerScript.scriptRef.log(
"Crime successful! Gained " +
numeralWrapper.formatMoney(this.workMoneyGained) +
", " +
numeralWrapper.formatExp(this.workHackExpGained) +
" hack exp, " +
numeralWrapper.formatExp(this.workStrExpGained) +
" str exp, " +
numeralWrapper.formatExp(this.workDefExpGained) +
" def exp, " +
numeralWrapper.formatExp(this.workDexExpGained) +
" dex exp, " +
numeralWrapper.formatExp(this.workAgiExpGained) +
" agi exp, " +
numeralWrapper.formatExp(this.workChaExpGained) +
" cha exp.",
);
}
} else {
dialogBoxCreate(
<>
Crime successful!
<br />
<br />
You gained:
<br />
<Money money={this.workMoneyGained} />
<br />
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workHackExpGained)} hacking experience <br />
{numeralWrapper.formatExp(this.workStrExpGained)} strength experience
2021-09-05 01:09:30 +02:00
<br />
{numeralWrapper.formatExp(this.workDefExpGained)} defense experience
<br />
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity experience
2021-09-05 01:09:30 +02:00
<br />
{numeralWrapper.formatExp(this.workAgiExpGained)} agility experience
<br />
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workChaExpGained)} charisma experience
2021-09-05 01:09:30 +02:00
</>,
);
}
} else {
//Exp halved on failure
this.workHackExpGained /= 2;
this.workStrExpGained /= 2;
this.workDefExpGained /= 2;
this.workDexExpGained /= 2;
this.workAgiExpGained /= 2;
this.workChaExpGained /= 2;
if (this.committingCrimeThruSingFn) {
if (
this.singFnCrimeWorkerScript.disableLogs.ALL == null &&
this.singFnCrimeWorkerScript.disableLogs.commitCrime == null
) {
this.singFnCrimeWorkerScript.scriptRef.log(
"Crime failed! Gained " +
numeralWrapper.formatExp(this.workHackExpGained) +
" hack exp, " +
numeralWrapper.formatExp(this.workStrExpGained) +
" str exp, " +
numeralWrapper.formatExp(this.workDefExpGained) +
" def exp, " +
numeralWrapper.formatExp(this.workDexExpGained) +
" dex exp, " +
numeralWrapper.formatExp(this.workAgiExpGained) +
" agi exp, " +
numeralWrapper.formatExp(this.workChaExpGained) +
" cha exp.",
);
}
} else {
dialogBoxCreate(
<>
Crime failed!
<br />
<br />
You gained:
<br />
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workHackExpGained)} hacking experience <br />
{numeralWrapper.formatExp(this.workStrExpGained)} strength experience
2021-09-05 01:09:30 +02:00
<br />
{numeralWrapper.formatExp(this.workDefExpGained)} defense experience
<br />
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity experience
2021-09-05 01:09:30 +02:00
<br />
{numeralWrapper.formatExp(this.workAgiExpGained)} agility experience
<br />
2021-09-09 05:47:34 +02:00
{numeralWrapper.formatExp(this.workChaExpGained)} charisma experience
2021-09-05 01:09:30 +02:00
</>,
);
}
}
this.gainHackingExp(this.workHackExpGained);
this.gainStrengthExp(this.workStrExpGained);
this.gainDefenseExp(this.workDefExpGained);
this.gainDexterityExp(this.workDexExpGained);
this.gainAgilityExp(this.workAgiExpGained);
this.gainCharismaExp(this.workChaExpGained);
}
this.committingCrimeThruSingFn = false;
this.singFnCrimeWorkerScript = null;
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
this.isWorking = false;
this.resetWorkStatus();
Engine.loadLocationContent(false);
2019-04-04 02:08:11 +02:00
}
//Cancels the player's current "work" assignment and gives the proper rewards
//Used only for Singularity functions, so no popups are created
export function singularityStopWork() {
2021-09-05 01:09:30 +02:00
if (!this.isWorking) {
return "";
}
var res; //Earnings text for work
switch (this.workType) {
case CONSTANTS.WorkTypeStudyClass:
res = this.finishClass(true);
break;
case CONSTANTS.WorkTypeCompany:
res = this.finishWork(true, true);
break;
case CONSTANTS.WorkTypeCompanyPartTime:
res = this.finishWorkPartTime(true);
break;
case CONSTANTS.WorkTypeFaction:
res = this.finishFactionWork(true, true);
break;
case CONSTANTS.WorkTypeCreateProgram:
res = this.finishCreateProgramWork(true);
break;
case CONSTANTS.WorkTypeCrime:
res = this.finishCrime(true);
break;
default:
console.error(`Unrecognized work type (${this.workType})`);
return "";
}
return res;
2019-04-04 02:08:11 +02:00
}
// Returns true if hospitalized, false otherwise
export function takeDamage(amt) {
2021-09-05 01:09:30 +02:00
if (typeof amt !== "number") {
2021-09-09 05:47:34 +02:00
console.warn(`Player.takeDamage() called without a numeric argument: ${amt}`);
2021-09-05 01:09:30 +02:00
return;
}
this.hp -= amt;
if (this.hp <= 0) {
this.hospitalize();
return true;
} else {
return false;
}
2019-04-04 02:08:11 +02:00
}
export function regenerateHp(amt) {
2021-09-05 01:09:30 +02:00
if (typeof amt !== "number") {
2021-09-09 05:47:34 +02:00
console.warn(`Player.regenerateHp() called without a numeric argument: ${amt}`);
2021-09-05 01:09:30 +02:00
return;
}
this.hp += amt;
if (this.hp > this.max_hp) {
this.hp = this.max_hp;
}
2019-04-04 02:08:11 +02:00
}
export function hospitalize() {
2021-09-05 01:09:30 +02:00
const cost = getHospitalizationCost(this);
if (Settings.SuppressHospitalizationPopup === false) {
dialogBoxCreate(
<>
2021-09-09 05:47:34 +02:00
You were in critical condition! You were taken to the hospital where luckily they were able to save your life.
You were charged&nbsp;
2021-09-05 01:09:30 +02:00
<Money money={cost} />
</>,
);
}
this.loseMoney(cost);
this.recordMoneySource(-1 * cost, "hospitalization");
this.hp = this.max_hp;
return cost;
2019-04-04 02:08:11 +02:00
}
/********* Company job application **********/
//Determines the job that the Player should get (if any) at the current company
//The 'sing' argument designates whether or not this is being called from
//the applyToCompany() Netscript Singularity function
2021-09-05 01:09:30 +02:00
export function applyForJob(entryPosType, sing = false) {
// Get current company and job
let currCompany = null;
if (this.companyName !== "") {
currCompany = Companies[this.companyName];
}
const currPositionName = this.jobs[this.companyName];
// Get company that's being applied to
const company = Companies[this.location]; //Company being applied to
if (!(company instanceof Company)) {
if (sing) {
2021-09-09 05:47:34 +02:00
return "ERROR: Invalid company name: " + this.location + ". applyToCompany() failed";
2021-09-05 01:09:30 +02:00
} else {
console.error(
`Could not find company that matches the location: ${this.location}. Player.applyToCompany() failed`,
);
return;
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
}
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
let pos = entryPosType;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
if (!this.isQualified(company, pos)) {
var reqText = getJobRequirementText(company, pos);
if (sing) {
return false;
}
2021-09-09 05:47:34 +02:00
dialogBoxCreate("Unforunately, you do not qualify for this position<br>" + reqText);
2021-09-05 01:09:30 +02:00
return;
}
while (true) {
let newPos = getNextCompanyPositionHelper(pos);
if (newPos == null) {
break;
}
//Check if this company has this position
if (company.hasPosition(newPos)) {
if (!this.isQualified(company, newPos)) {
//If player not qualified for next job, break loop so player will be given current job
break;
}
pos = newPos;
} else {
break;
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
}
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
//Check if the determined job is the same as the player's current job
if (currCompany != null) {
if (currCompany.name == company.name && pos.name == currPositionName) {
var nextPos = getNextCompanyPositionHelper(pos);
if (nextPos == null) {
if (sing) {
return false;
2019-04-04 02:08:11 +02:00
}
2021-09-09 05:47:34 +02:00
dialogBoxCreate("You are already at the highest position for your field! No promotion available");
2021-09-05 01:09:30 +02:00
} else if (company.hasPosition(nextPos)) {
if (sing) {
return false;
}
var reqText = getJobRequirementText(company, nextPos);
2021-09-09 05:47:34 +02:00
dialogBoxCreate("Unfortunately, you do not qualify for a promotion<br>" + reqText);
2021-09-05 01:09:30 +02:00
} else {
if (sing) {
return false;
2019-04-04 02:08:11 +02:00
}
2021-09-09 05:47:34 +02:00
dialogBoxCreate("You are already at the highest position for your field! No promotion available");
2021-09-05 01:09:30 +02:00
}
return; //Same job, do nothing
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
}
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.jobs[company.name] = pos.name;
this.companyName = this.location;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
if (sing) {
return true;
}
2019-04-04 02:08:11 +02:00
2021-09-09 05:47:34 +02:00
dialogBoxCreate("Congratulations! You were offered a new job at " + this.companyName + " as a " + pos.name + "!");
2019-04-04 02:08:11 +02:00
}
//Returns your next position at a company given the field (software, business, etc.)
export function getNextCompanyPosition(company, entryPosType) {
2021-09-05 01:09:30 +02:00
var currCompany = null;
if (this.companyName !== "") {
currCompany = Companies[this.companyName];
}
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
//Not employed at this company, so return the entry position
if (currCompany == null || currCompany.name != company.name) {
2019-04-04 02:08:11 +02:00
return entryPosType;
2021-09-05 01:09:30 +02:00
}
//If the entry pos type and the player's current position have the same type,
//return the player's "nextCompanyPosition". Otherwise return the entryposType
//Employed at this company, so just return the next position if it exists.
const currentPositionName = this.jobs[this.companyName];
const currentPosition = CompanyPositions[currentPositionName];
if (
(currentPosition.isSoftwareJob() && entryPosType.isSoftwareJob()) ||
(currentPosition.isITJob() && entryPosType.isITJob()) ||
(currentPosition.isBusinessJob() && entryPosType.isBusinessJob()) ||
2021-09-09 05:47:34 +02:00
(currentPosition.isSecurityEngineerJob() && entryPosType.isSecurityEngineerJob()) ||
(currentPosition.isNetworkEngineerJob() && entryPosType.isNetworkEngineerJob()) ||
2021-09-05 01:09:30 +02:00
(currentPosition.isSecurityJob() && entryPosType.isSecurityJob()) ||
(currentPosition.isAgentJob() && entryPosType.isAgentJob()) ||
2021-09-09 05:47:34 +02:00
(currentPosition.isSoftwareConsultantJob() && entryPosType.isSoftwareConsultantJob()) ||
(currentPosition.isBusinessConsultantJob() && entryPosType.isBusinessConsultantJob()) ||
2021-09-05 01:09:30 +02:00
(currentPosition.isPartTimeJob() && entryPosType.isPartTimeJob())
) {
return getNextCompanyPositionHelper(currentPosition);
}
return entryPosType;
2019-04-04 02:08:11 +02:00
}
v0.51.6 (#905) * Make command `cd` without arguments an alias for `cd /` (#853) In most shells `cd` without arguments takes you to the home directory of the current user. I keep trying to do this due to muscle memory from working in terminals, so I figured I'd make it do something useful. There is no home directory in the game, but going to / is the closest thing we have, since that is the starting point for the user in the game. * Add new `backdoor` terminal command (#852) * Add the backdoor command to the terminal This command will perform a manual hack without rewarding money. It will be used for the story, mainly for faction hacking tests * Add tab completion for backdoor command * Add help text for backdoor command * Change condition syntax to be more consistent with others * Extract reused code block so it is always called after actions * Update documentation for new backdoor command Modified references to manual hack as it isn't for factions anymore * Remove extra parenthesis * Rename manuallyHacked to backdoorInstalled * Fix typo * Change faction test messages to use backdoor instad of hack * Rename more instances of manuallyHacked * fixed typo in helptext of darkweb buy (#858) * Fix typos and unify descriptions of augmentations (#859) Made an attempt to... - give all "+rep% company/faction" the same text - make all augmentations with a single effect use a single line to describe the effect - make all effects end with a period * Made Cashroot starter kit display its tooltip with the money formatted properly and in gold * fix typo in docs (#860) * Initial code for Casino Card Deck implementation * Casino Blackjack Implementation * Update some tools (eslint, typescript) * Blackjack code cleanup * Update README_contribution * Update ScriptHelpers.js (#861) expand error message * More augmentation typo fixes (#862) * Add Netscript function getCurrentScript (#856) Add netscript function that returns the current script. * Added milestones menu to guide new players. (#865) Milestone menu * fix typos in milestones (#866) Co-authored-by: sschmidTU <s.schmid@phonicscore.com> * Corrupt location title when backdoor is installed (#864) * Add corruptableText component * Corrupt location title if backdoor is installed * Formatting * Add helper to check value of backdoorInstalled Helper could be oneline but it would make it less readable * Fix some formatting * Add settings option to disable text effects * Import useState * getRunningScript (#867) * Replaced getCurrentScript with getRunningScript * Bunch of smaller fixes (#904) Fix #884 Fix #879 Fix #878 Fix #876 Fix #874 Fix #873 Fix #887 Fix #891 Fix #895 * rework the early servers to be more noob friendly (#903) * v0.51.6 Co-authored-by: Andreas Eriksson <2691182+AndreasTPC@users.noreply.github.com> Co-authored-by: Jack <jackdewinter1@gmail.com> Co-authored-by: Teun Pronk <5228255+Crownie88@users.noreply.github.com> Co-authored-by: Pimvgd <Pimvgd@gmail.com> Co-authored-by: Daniel Xie <daniel.xie@flockfreight.com> Co-authored-by: Simon <33069673+sschmidTU@users.noreply.github.com> Co-authored-by: sschmidTU <s.schmid@phonicscore.com>
2021-04-29 02:07:26 +02:00
export function quitJob(company) {
2021-09-05 01:09:30 +02:00
this.isWorking = false;
this.companyName = "";
delete this.jobs[company];
}
export function applyForSoftwareJob(sing = false) {
2021-09-09 05:47:34 +02:00
return this.applyForJob(CompanyPositions[posNames.SoftwareCompanyPositions[0]], sing);
2021-09-05 01:09:30 +02:00
}
export function applyForSoftwareConsultantJob(sing = false) {
2021-09-09 05:47:34 +02:00
return this.applyForJob(CompanyPositions[posNames.SoftwareConsultantCompanyPositions[0]], sing);
2021-09-05 01:09:30 +02:00
}
export function applyForItJob(sing = false) {
2021-09-09 05:47:34 +02:00
return this.applyForJob(CompanyPositions[posNames.ITCompanyPositions[0]], sing);
2021-09-05 01:09:30 +02:00
}
export function applyForSecurityEngineerJob(sing = false) {
var company = Companies[this.location]; //Company being applied to
2021-09-09 05:47:34 +02:00
if (this.isQualified(company, CompanyPositions[posNames.SecurityEngineerCompanyPositions[0]])) {
return this.applyForJob(CompanyPositions[posNames.SecurityEngineerCompanyPositions[0]], sing);
2021-09-05 01:09:30 +02:00
} else {
if (sing) {
return false;
}
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
}
export function applyForNetworkEngineerJob(sing = false) {
var company = Companies[this.location]; //Company being applied to
2021-09-09 05:47:34 +02:00
if (this.isQualified(company, CompanyPositions[posNames.NetworkEngineerCompanyPositions[0]])) {
return this.applyForJob(CompanyPositions[posNames.NetworkEngineerCompanyPositions[0]], sing);
2021-09-05 01:09:30 +02:00
} else {
if (sing) {
return false;
}
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
}
export function applyForBusinessJob(sing = false) {
2021-09-09 05:47:34 +02:00
return this.applyForJob(CompanyPositions[posNames.BusinessCompanyPositions[0]], sing);
2021-09-05 01:09:30 +02:00
}
export function applyForBusinessConsultantJob(sing = false) {
2021-09-09 05:47:34 +02:00
return this.applyForJob(CompanyPositions[posNames.BusinessConsultantCompanyPositions[0]], sing);
2021-09-05 01:09:30 +02:00
}
export function applyForSecurityJob(sing = false) {
// TODO Police Jobs
// Indexing starts at 2 because 0 is for police officer
2021-09-09 05:47:34 +02:00
return this.applyForJob(CompanyPositions[posNames.SecurityCompanyPositions[2]], sing);
2021-09-05 01:09:30 +02:00
}
export function applyForAgentJob(sing = false) {
var company = Companies[this.location]; //Company being applied to
2021-09-09 05:47:34 +02:00
if (this.isQualified(company, CompanyPositions[posNames.AgentCompanyPositions[0]])) {
return this.applyForJob(CompanyPositions[posNames.AgentCompanyPositions[0]], sing);
2021-09-05 01:09:30 +02:00
} else {
if (sing) {
return false;
}
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
}
export function applyForEmployeeJob(sing = false) {
var company = Companies[this.location]; //Company being applied to
2021-09-09 05:47:34 +02:00
if (this.isQualified(company, CompanyPositions[posNames.MiscCompanyPositions[1]])) {
2021-09-05 01:09:30 +02:00
this.companyName = company.name;
this.jobs[company.name] = posNames.MiscCompanyPositions[1];
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
if (sing) {
return true;
2019-04-04 02:08:11 +02:00
}
2021-09-09 05:47:34 +02:00
dialogBoxCreate("Congratulations, you are now employed at " + this.companyName);
2021-09-05 01:09:30 +02:00
} else {
if (sing) {
return false;
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
export function applyForPartTimeEmployeeJob(sing = false) {
var company = Companies[this.location]; //Company being applied to
2021-09-09 05:47:34 +02:00
if (this.isQualified(company, CompanyPositions[posNames.PartTimeCompanyPositions[1]])) {
2021-09-05 01:09:30 +02:00
this.jobs[company.name] = posNames.PartTimeCompanyPositions[1];
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
if (sing) {
return true;
2019-04-04 02:08:11 +02:00
}
2021-09-09 05:47:34 +02:00
dialogBoxCreate("Congratulations, you are now employed part-time at " + this.companyName);
2021-09-05 01:09:30 +02:00
} else {
if (sing) {
return false;
}
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
}
export function applyForWaiterJob(sing = false) {
var company = Companies[this.location]; //Company being applied to
2021-09-09 05:47:34 +02:00
if (this.isQualified(company, CompanyPositions[posNames.MiscCompanyPositions[0]])) {
2021-09-05 01:09:30 +02:00
this.companyName = company.name;
this.jobs[company.name] = posNames.MiscCompanyPositions[0];
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
if (sing) {
return true;
2019-04-04 02:08:11 +02:00
}
2021-09-09 05:47:34 +02:00
dialogBoxCreate("Congratulations, you are now employed as a waiter at " + this.companyName);
2021-09-05 01:09:30 +02:00
} else {
if (sing) {
return false;
}
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
}
export function applyForPartTimeWaiterJob(sing = false) {
var company = Companies[this.location]; //Company being applied to
2021-09-09 05:47:34 +02:00
if (this.isQualified(company, CompanyPositions[posNames.PartTimeCompanyPositions[0]])) {
2021-09-05 01:09:30 +02:00
this.companyName = company.name;
this.jobs[company.name] = posNames.PartTimeCompanyPositions[0];
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
if (sing) {
return true;
2019-04-04 02:08:11 +02:00
}
2021-09-09 05:47:34 +02:00
dialogBoxCreate("Congratulations, you are now employed as a part-time waiter at " + this.companyName);
2021-09-05 01:09:30 +02:00
} else {
if (sing) {
return false;
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
2019-04-04 02:08:11 +02:00
}
//Checks if the Player is qualified for a certain position
export function isQualified(company, position) {
2021-09-05 01:09:30 +02:00
var offset = company.jobStatReqOffset;
2021-09-09 05:47:34 +02:00
var reqHacking = position.requiredHacking > 0 ? position.requiredHacking + offset : 0;
var reqStrength = position.requiredStrength > 0 ? position.requiredStrength + offset : 0;
var reqDefense = position.requiredDefense > 0 ? position.requiredDefense + offset : 0;
var reqDexterity = position.requiredDexterity > 0 ? position.requiredDexterity + offset : 0;
var reqAgility = position.requiredDexterity > 0 ? position.requiredDexterity + offset : 0;
var reqCharisma = position.requiredCharisma > 0 ? position.requiredCharisma + offset : 0;
2021-09-05 01:09:30 +02:00
if (
this.hacking_skill >= reqHacking &&
this.strength >= reqStrength &&
this.defense >= reqDefense &&
this.dexterity >= reqDexterity &&
this.agility >= reqAgility &&
this.charisma >= reqCharisma &&
company.playerReputation >= position.requiredReputation
) {
return true;
}
return false;
2019-04-04 02:08:11 +02:00
}
/********** Reapplying Augmentations and Source File ***********/
2021-09-05 01:09:30 +02:00
export function reapplyAllAugmentations(resetMultipliers = true) {
if (resetMultipliers) {
this.resetMultipliers();
}
for (let i = 0; i < this.augmentations.length; ++i) {
//Compatibility with new version
2021-09-09 05:47:34 +02:00
if (this.augmentations[i].name === "HacknetNode NIC Architecture Neural-Upload") {
this.augmentations[i].name = "Hacknet Node NIC Architecture Neural-Upload";
2021-09-05 01:09:30 +02:00
}
const augName = this.augmentations[i].name;
var aug = Augmentations[augName];
if (aug == null) {
2021-09-09 05:47:34 +02:00
console.warn(`Invalid augmentation name in Player.reapplyAllAugmentations(). Aug ${augName} will be skipped`);
2021-09-05 01:09:30 +02:00
continue;
}
aug.owned = true;
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
for (let j = 0; j < aug.level; ++j) {
2019-04-04 02:08:11 +02:00
applyAugmentation(this.augmentations[i], true);
2021-09-05 01:09:30 +02:00
}
continue;
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
applyAugmentation(this.augmentations[i], true);
}
2019-04-04 02:08:11 +02:00
}
export function reapplyAllSourceFiles() {
2021-09-05 01:09:30 +02:00
//Will always be called after reapplyAllAugmentations() so multipliers do not have to be reset
//this.resetMultipliers();
for (let i = 0; i < this.sourceFiles.length; ++i) {
var srcFileKey = "SourceFile" + this.sourceFiles[i].n;
var sourceFileObject = SourceFiles[srcFileKey];
if (sourceFileObject == null) {
console.error(`Invalid source file number: ${this.sourceFiles[i].n}`);
continue;
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
applySourceFile(this.sourceFiles[i]);
}
applyExploit();
2019-04-04 02:08:11 +02:00
}
/*************** Check for Faction Invitations *************/
//This function sets the requirements to join a Faction. It checks whether the Player meets
//those requirements and will return an array of all factions that the Player should
//receive an invitation to
export function checkForFactionInvitations() {
2021-09-05 01:09:30 +02:00
let invitedFactions = []; //Array which will hold all Factions the player should be invited to
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
var numAugmentations = this.augmentations.length;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
const allCompanies = Object.keys(this.jobs);
const allPositions = Object.values(this.jobs);
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
// Given a company name, safely returns the reputation (returns 0 if invalid company is specified)
function getCompanyRep(companyName) {
const company = Companies[companyName];
if (company == null) {
return 0;
2019-04-04 02:08:11 +02:00
} else {
2021-09-05 01:09:30 +02:00
return company.playerReputation;
}
}
// Helper function that returns a boolean indicating whether the Player meets
// the requirements for the specified company. There are two requirements:
// 1. High enough reputation
// 2. Player is employed at the company
2021-09-09 05:47:34 +02:00
function checkMegacorpRequirements(companyName, repNeeded = CONSTANTS.CorpFactionRepRequirement) {
return allCompanies.includes(companyName) && getCompanyRep(companyName) > repNeeded;
2021-09-05 01:09:30 +02:00
}
//Illuminati
var illuminatiFac = Factions["Illuminati"];
if (
!illuminatiFac.isBanned &&
!illuminatiFac.isMember &&
!illuminatiFac.alreadyInvited &&
numAugmentations >= 30 &&
this.money.gte(150000000000) &&
this.hacking_skill >= 1500 &&
this.strength >= 1200 &&
this.defense >= 1200 &&
this.dexterity >= 1200 &&
this.agility >= 1200
) {
invitedFactions.push(illuminatiFac);
}
//Daedalus
var daedalusFac = Factions["Daedalus"];
if (
!daedalusFac.isBanned &&
!daedalusFac.isMember &&
!daedalusFac.alreadyInvited &&
2021-09-09 05:47:34 +02:00
numAugmentations >= Math.round(30 * BitNodeMultipliers.DaedalusAugsRequirement) &&
2021-09-05 01:09:30 +02:00
this.money.gte(100000000000) &&
(this.hacking_skill >= 2500 ||
2021-09-09 05:47:34 +02:00
(this.strength >= 1500 && this.defense >= 1500 && this.dexterity >= 1500 && this.agility >= 1500))
2021-09-05 01:09:30 +02:00
) {
invitedFactions.push(daedalusFac);
}
//The Covenant
var covenantFac = Factions["The Covenant"];
if (
!covenantFac.isBanned &&
!covenantFac.isMember &&
!covenantFac.alreadyInvited &&
numAugmentations >= 20 &&
this.money.gte(75000000000) &&
this.hacking_skill >= 850 &&
this.strength >= 850 &&
this.defense >= 850 &&
this.dexterity >= 850 &&
this.agility >= 850
) {
invitedFactions.push(covenantFac);
}
//ECorp
var ecorpFac = Factions["ECorp"];
if (
!ecorpFac.isBanned &&
!ecorpFac.isMember &&
!ecorpFac.alreadyInvited &&
checkMegacorpRequirements(LocationName.AevumECorp)
) {
invitedFactions.push(ecorpFac);
}
//MegaCorp
var megacorpFac = Factions["MegaCorp"];
if (
!megacorpFac.isBanned &&
!megacorpFac.isMember &&
!megacorpFac.alreadyInvited &&
checkMegacorpRequirements(LocationName.Sector12MegaCorp)
) {
invitedFactions.push(megacorpFac);
}
//Bachman & Associates
var bachmanandassociatesFac = Factions["Bachman & Associates"];
if (
!bachmanandassociatesFac.isBanned &&
!bachmanandassociatesFac.isMember &&
!bachmanandassociatesFac.alreadyInvited &&
checkMegacorpRequirements(LocationName.AevumBachmanAndAssociates)
) {
invitedFactions.push(bachmanandassociatesFac);
}
//Blade Industries
var bladeindustriesFac = Factions["Blade Industries"];
if (
!bladeindustriesFac.isBanned &&
!bladeindustriesFac.isMember &&
!bladeindustriesFac.alreadyInvited &&
checkMegacorpRequirements(LocationName.Sector12BladeIndustries)
) {
invitedFactions.push(bladeindustriesFac);
}
//NWO
var nwoFac = Factions["NWO"];
if (
!nwoFac.isBanned &&
!nwoFac.isMember &&
!nwoFac.alreadyInvited &&
checkMegacorpRequirements(LocationName.VolhavenNWO)
) {
invitedFactions.push(nwoFac);
}
//Clarke Incorporated
var clarkeincorporatedFac = Factions["Clarke Incorporated"];
if (
!clarkeincorporatedFac.isBanned &&
!clarkeincorporatedFac.isMember &&
!clarkeincorporatedFac.alreadyInvited &&
checkMegacorpRequirements(LocationName.AevumClarkeIncorporated)
) {
invitedFactions.push(clarkeincorporatedFac);
}
//OmniTek Incorporated
var omnitekincorporatedFac = Factions["OmniTek Incorporated"];
if (
!omnitekincorporatedFac.isBanned &&
!omnitekincorporatedFac.isMember &&
!omnitekincorporatedFac.alreadyInvited &&
checkMegacorpRequirements(LocationName.VolhavenOmniTekIncorporated)
) {
invitedFactions.push(omnitekincorporatedFac);
}
//Four Sigma
var foursigmaFac = Factions["Four Sigma"];
if (
!foursigmaFac.isBanned &&
!foursigmaFac.isMember &&
!foursigmaFac.alreadyInvited &&
checkMegacorpRequirements(LocationName.Sector12FourSigma)
) {
invitedFactions.push(foursigmaFac);
}
//KuaiGong International
var kuaigonginternationalFac = Factions["KuaiGong International"];
if (
!kuaigonginternationalFac.isBanned &&
!kuaigonginternationalFac.isMember &&
!kuaigonginternationalFac.alreadyInvited &&
checkMegacorpRequirements(LocationName.ChongqingKuaiGongInternational)
) {
invitedFactions.push(kuaigonginternationalFac);
}
//Fulcrum Secret Technologies - If u've unlocked fulcrum secret technolgoies server and have a high rep with the company
var fulcrumsecrettechonologiesFac = Factions["Fulcrum Secret Technologies"];
2021-09-09 05:47:34 +02:00
var fulcrumSecretServer = AllServers[SpecialServerIps[SpecialServerNames.FulcrumSecretTechnologies]];
2021-09-05 01:09:30 +02:00
if (fulcrumSecretServer == null) {
console.error("Could not find Fulcrum Secret Technologies Server");
} else {
if (
!fulcrumsecrettechonologiesFac.isBanned &&
!fulcrumsecrettechonologiesFac.isMember &&
!fulcrumsecrettechonologiesFac.alreadyInvited &&
fulcrumSecretServer.backdoorInstalled &&
checkMegacorpRequirements(LocationName.AevumFulcrumTechnologies, 250e3)
) {
invitedFactions.push(fulcrumsecrettechonologiesFac);
}
}
//BitRunners
var bitrunnersFac = Factions["BitRunners"];
2021-09-09 05:47:34 +02:00
var bitrunnersServer = AllServers[SpecialServerIps[SpecialServerNames.BitRunnersServer]];
2021-09-05 01:09:30 +02:00
if (bitrunnersServer == null) {
console.error("Could not find BitRunners Server");
} else if (
!bitrunnersFac.isBanned &&
!bitrunnersFac.isMember &&
bitrunnersServer.backdoorInstalled &&
!bitrunnersFac.alreadyInvited
2021-09-05 01:09:30 +02:00
) {
invitedFactions.push(bitrunnersFac);
}
//The Black Hand
var theblackhandFac = Factions["The Black Hand"];
2021-09-09 05:47:34 +02:00
var blackhandServer = AllServers[SpecialServerIps[SpecialServerNames.TheBlackHandServer]];
2021-09-05 01:09:30 +02:00
if (blackhandServer == null) {
console.error("Could not find The Black Hand Server");
} else if (
!theblackhandFac.isBanned &&
!theblackhandFac.isMember &&
blackhandServer.backdoorInstalled &&
!theblackhandFac.alreadyInvited
2021-09-05 01:09:30 +02:00
) {
invitedFactions.push(theblackhandFac);
}
//NiteSec
var nitesecFac = Factions["NiteSec"];
2021-09-09 05:47:34 +02:00
var nitesecServer = AllServers[SpecialServerIps[SpecialServerNames.NiteSecServer]];
2021-09-05 01:09:30 +02:00
if (nitesecServer == null) {
console.error("Could not find NiteSec Server");
} else if (
!nitesecFac.isBanned &&
!nitesecFac.isMember &&
nitesecServer.backdoorInstalled &&
!nitesecFac.alreadyInvited
2021-09-05 01:09:30 +02:00
) {
invitedFactions.push(nitesecFac);
}
//Chongqing
var chongqingFac = Factions["Chongqing"];
if (
!chongqingFac.isBanned &&
!chongqingFac.isMember &&
!chongqingFac.alreadyInvited &&
this.money.gte(20000000) &&
this.city == CityName.Chongqing
) {
invitedFactions.push(chongqingFac);
}
//Sector-12
var sector12Fac = Factions["Sector-12"];
if (
!sector12Fac.isBanned &&
!sector12Fac.isMember &&
!sector12Fac.alreadyInvited &&
this.money.gte(15000000) &&
this.city == CityName.Sector12
) {
invitedFactions.push(sector12Fac);
}
//New Tokyo
var newtokyoFac = Factions["New Tokyo"];
if (
!newtokyoFac.isBanned &&
!newtokyoFac.isMember &&
!newtokyoFac.alreadyInvited &&
this.money.gte(20000000) &&
this.city == CityName.NewTokyo
) {
invitedFactions.push(newtokyoFac);
}
//Aevum
var aevumFac = Factions["Aevum"];
if (
!aevumFac.isBanned &&
!aevumFac.isMember &&
!aevumFac.alreadyInvited &&
this.money.gte(40000000) &&
this.city == CityName.Aevum
) {
invitedFactions.push(aevumFac);
}
//Ishima
var ishimaFac = Factions["Ishima"];
if (
!ishimaFac.isBanned &&
!ishimaFac.isMember &&
!ishimaFac.alreadyInvited &&
this.money.gte(30000000) &&
this.city == CityName.Ishima
) {
invitedFactions.push(ishimaFac);
}
//Volhaven
var volhavenFac = Factions["Volhaven"];
if (
!volhavenFac.isBanned &&
!volhavenFac.isMember &&
!volhavenFac.alreadyInvited &&
this.money.gte(50000000) &&
this.city == CityName.Volhaven
) {
invitedFactions.push(volhavenFac);
}
//Speakers for the Dead
var speakersforthedeadFac = Factions["Speakers for the Dead"];
if (
!speakersforthedeadFac.isBanned &&
!speakersforthedeadFac.isMember &&
!speakersforthedeadFac.alreadyInvited &&
this.hacking_skill >= 100 &&
this.strength >= 300 &&
this.defense >= 300 &&
this.dexterity >= 300 &&
this.agility >= 300 &&
this.numPeopleKilled >= 30 &&
this.karma <= -45 &&
!allCompanies.includes(LocationName.Sector12CIA) &&
!allCompanies.includes(LocationName.Sector12NSA)
) {
invitedFactions.push(speakersforthedeadFac);
}
//The Dark Army
var thedarkarmyFac = Factions["The Dark Army"];
if (
!thedarkarmyFac.isBanned &&
!thedarkarmyFac.isMember &&
!thedarkarmyFac.alreadyInvited &&
this.hacking_skill >= 300 &&
this.strength >= 300 &&
this.defense >= 300 &&
this.dexterity >= 300 &&
this.agility >= 300 &&
this.city == CityName.Chongqing &&
this.numPeopleKilled >= 5 &&
this.karma <= -45 &&
!allCompanies.includes(LocationName.Sector12CIA) &&
!allCompanies.includes(LocationName.Sector12NSA)
) {
invitedFactions.push(thedarkarmyFac);
}
//The Syndicate
var thesyndicateFac = Factions["The Syndicate"];
if (
!thesyndicateFac.isBanned &&
!thesyndicateFac.isMember &&
!thesyndicateFac.alreadyInvited &&
this.hacking_skill >= 200 &&
this.strength >= 200 &&
this.defense >= 200 &&
this.dexterity >= 200 &&
this.agility >= 200 &&
(this.city == CityName.Aevum || this.city == CityName.Sector12) &&
this.money.gte(10000000) &&
this.karma <= -90 &&
!allCompanies.includes(LocationName.Sector12CIA) &&
!allCompanies.includes(LocationName.Sector12NSA)
) {
invitedFactions.push(thesyndicateFac);
}
//Silhouette
var silhouetteFac = Factions["Silhouette"];
if (
!silhouetteFac.isBanned &&
!silhouetteFac.isMember &&
!silhouetteFac.alreadyInvited &&
(allPositions.includes("Chief Technology Officer") ||
allPositions.includes("Chief Financial Officer") ||
allPositions.includes("Chief Executive Officer")) &&
this.money.gte(15000000) &&
this.karma <= -22
) {
invitedFactions.push(silhouetteFac);
}
//Tetrads
var tetradsFac = Factions["Tetrads"];
if (
!tetradsFac.isBanned &&
!tetradsFac.isMember &&
!tetradsFac.alreadyInvited &&
2021-09-09 05:47:34 +02:00
(this.city == CityName.Chongqing || this.city == CityName.NewTokyo || this.city == CityName.Ishima) &&
2021-09-05 01:09:30 +02:00
this.strength >= 75 &&
this.defense >= 75 &&
this.dexterity >= 75 &&
this.agility >= 75 &&
this.karma <= -18
) {
invitedFactions.push(tetradsFac);
}
//SlumSnakes
var slumsnakesFac = Factions["Slum Snakes"];
if (
!slumsnakesFac.isBanned &&
!slumsnakesFac.isMember &&
!slumsnakesFac.alreadyInvited &&
this.strength >= 30 &&
this.defense >= 30 &&
this.dexterity >= 30 &&
this.agility >= 30 &&
this.karma <= -9 &&
this.money.gte(1000000)
) {
invitedFactions.push(slumsnakesFac);
}
//Netburners
var netburnersFac = Factions["Netburners"];
var totalHacknetRam = 0;
var totalHacknetCores = 0;
var totalHacknetLevels = 0;
for (let i = 0; i < this.hacknetNodes.length; ++i) {
2021-09-09 09:17:01 +02:00
if (hasHacknetServers(this)) {
2021-09-05 01:09:30 +02:00
const hserver = AllServers[this.hacknetNodes[i]];
if (hserver) {
totalHacknetLevels += hserver.level;
totalHacknetRam += hserver.maxRam;
totalHacknetCores += hserver.cores;
}
} else {
totalHacknetLevels += this.hacknetNodes[i].level;
totalHacknetRam += this.hacknetNodes[i].ram;
totalHacknetCores += this.hacknetNodes[i].cores;
}
}
if (
!netburnersFac.isBanned &&
!netburnersFac.isMember &&
!netburnersFac.alreadyInvited &&
this.hacking_skill >= 80 &&
totalHacknetRam >= 8 &&
totalHacknetCores >= 4 &&
totalHacknetLevels >= 100
) {
invitedFactions.push(netburnersFac);
}
//Tian Di Hui
var tiandihuiFac = Factions["Tian Di Hui"];
if (
!tiandihuiFac.isBanned &&
!tiandihuiFac.isMember &&
!tiandihuiFac.alreadyInvited &&
this.money.gte(1000000) &&
this.hacking_skill >= 50 &&
2021-09-09 05:47:34 +02:00
(this.city == CityName.Chongqing || this.city == CityName.NewTokyo || this.city == CityName.Ishima)
2021-09-05 01:09:30 +02:00
) {
invitedFactions.push(tiandihuiFac);
}
//CyberSec
var cybersecFac = Factions["CyberSec"];
2021-09-09 05:47:34 +02:00
var cybersecServer = AllServers[SpecialServerIps[SpecialServerNames.CyberSecServer]];
2021-09-05 01:09:30 +02:00
if (cybersecServer == null) {
console.error("Could not find CyberSec Server");
} else if (
!cybersecFac.isBanned &&
!cybersecFac.isMember &&
cybersecServer.backdoorInstalled &&
!cybersecFac.alreadyInvited
) {
invitedFactions.push(cybersecFac);
}
return invitedFactions;
2019-04-04 02:08:11 +02:00
}
/************* BitNodes **************/
export function setBitNodeNumber(n) {
2021-09-05 01:09:30 +02:00
this.bitNodeN = n;
2019-04-04 02:08:11 +02:00
}
export function queueAugmentation(name) {
2021-09-05 01:09:30 +02:00
for (const i in this.queuedAugmentations) {
if (this.queuedAugmentations[i].name == name) {
console.warn(`tried to queue ${name} twice, this may be a bug`);
return;
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
}
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
for (const i in this.augmentations) {
if (this.augmentations[i].name == name) {
console.warn(`tried to queue ${name} twice, this may be a bug`);
return;
2019-04-04 02:08:11 +02:00
}
2021-09-05 01:09:30 +02:00
}
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
this.firstAugPurchased = true;
this.queuedAugmentations.push(new PlayerOwnedAugmentation(name));
2019-04-04 02:08:11 +02:00
}
/************* Coding Contracts **************/
2021-09-05 01:09:30 +02:00
export function gainCodingContractReward(reward, difficulty = 1) {
if (reward == null || reward.type == null || reward == null) {
return `No reward for this contract`;
}
/* eslint-disable no-case-declarations */
switch (reward.type) {
case CodingContractRewardType.FactionReputation:
if (reward.name == null || !(Factions[reward.name] instanceof Faction)) {
// If no/invalid faction was designated, just give rewards to all factions
reward.type = CodingContractRewardType.FactionReputationAll;
return this.gainCodingContractReward(reward);
}
var repGain = CONSTANTS.CodingContractBaseFactionRepGain * difficulty;
Factions[reward.name].playerReputation += repGain;
return `Gained ${repGain} faction reputation for ${reward.name}`;
case CodingContractRewardType.FactionReputationAll:
const totalGain = CONSTANTS.CodingContractBaseFactionRepGain * difficulty;
// Ignore Bladeburners and other special factions for this calculation
const specialFactions = ["Bladeburners"];
var factions = this.factions.slice();
factions = factions.filter((f) => {
return !specialFactions.includes(f);
});
// If the player was only part of the special factions, we'll just give money
if (factions.length == 0) {
reward.type = CodingContractRewardType.Money;
return this.gainCodingContractReward(reward, difficulty);
}
const gainPerFaction = Math.floor(totalGain / factions.length);
for (const facName of factions) {
if (!(Factions[facName] instanceof Faction)) {
continue;
}
Factions[facName].playerReputation += gainPerFaction;
}
return `Gained ${gainPerFaction} reputation for each of the following factions: ${factions.toString()}`;
break;
case CodingContractRewardType.CompanyReputation:
if (reward.name == null || !(Companies[reward.name] instanceof Company)) {
//If no/invalid company was designated, just give rewards to all factions
reward.type = CodingContractRewardType.FactionReputationAll;
return this.gainCodingContractReward(reward);
}
var repGain = CONSTANTS.CodingContractBaseCompanyRepGain * difficulty;
Companies[reward.name].playerReputation += repGain;
return `Gained ${repGain} company reputation for ${reward.name}`;
break;
case CodingContractRewardType.Money:
default:
2021-09-09 05:47:34 +02:00
var moneyGain = CONSTANTS.CodingContractBaseMoneyGain * difficulty * BitNodeMultipliers.CodingContractMoney;
2021-09-05 01:09:30 +02:00
this.gainMoney(moneyGain);
this.recordMoneySource(moneyGain, "codingcontract");
return `Gained ${numeralWrapper.formatMoney(moneyGain)}`;
break;
}
/* eslint-enable no-case-declarations */
2019-04-04 02:08:11 +02:00
}
export function travel(to) {
2021-09-05 01:09:30 +02:00
if (Cities[to] == null) {
console.warn(`Player.travel() called with invalid city: ${to}`);
return false;
}
this.city = to;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
return true;
2019-04-04 02:08:11 +02:00
}
export function gotoLocation(to) {
2021-09-05 01:09:30 +02:00
if (Locations[to] == null) {
console.warn(`Player.gotoLocation() called with invalid location: ${to}`);
return false;
}
this.location = to;
2019-04-04 02:08:11 +02:00
2021-09-05 01:09:30 +02:00
return true;
2019-04-04 02:08:11 +02:00
}
export function canAccessResleeving() {
2021-09-05 01:09:30 +02:00
return this.bitNodeN === 10 || SourceFileFlags[10] > 0;
2019-04-04 02:08:11 +02:00
}
2021-03-09 02:31:34 +01:00
export function giveExploit(exploit) {
2021-09-05 01:09:30 +02:00
if (!this.exploits.includes(exploit)) {
this.exploits.push(exploit);
}
}
export function getIntelligenceBonus(weight) {
2021-09-05 01:09:30 +02:00
return calculateIntelligenceBonus(this.intelligence, weight);
}
export function getCasinoWinnings() {
2021-09-05 01:09:30 +02:00
return this.moneySourceA.casino;
}