2019-01-15 14:11:14 +01:00
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" ;
2019-01-18 18:57:21 +01:00
import { Bladeburner } from "./Bladeburner" ;
2018-12-25 11:14:18 +01:00
import { CodingContractRewardType } from "./CodingContracts" ;
import { Company } from "./Company/Company" ;
import { Companies } from "./Company/Companies" ;
import { getNextCompanyPosition } from "./Company/GetNextCompanyPosition" ;
import { getJobRequirementText } from "./Company/GetJobRequirementText" ;
import { CompanyPositions } from "./Company/CompanyPositions" ;
2018-11-16 04:45:03 +01:00
import * as posNames from "./Company/data/CompanyPositionNames" ;
2018-06-26 18:34:11 +02:00
import { CONSTANTS } from "./Constants" ;
2018-12-09 14:36:18 +01:00
import { Corporation } from "./Corporation/Corporation" ;
2018-12-25 11:14:18 +01:00
import { Programs } from "./Programs/Programs" ;
2019-01-15 04:34:04 +01:00
import { determineCrimeSuccess } from "./Crime/CrimeHelpers" ;
import { Crimes } from "./Crime/Crimes" ;
2018-06-26 18:34:11 +02:00
import { Engine } from "./engine" ;
2018-12-07 11:54:26 +01:00
import { Faction } from "./Faction/Faction" ;
import { Factions } from "./Faction/Factions" ;
import { displayFactionContent } from "./Faction/FactionHelpers" ;
2018-06-26 18:34:11 +02:00
import { Gang , resetGangs } from "./Gang" ;
2018-07-21 06:22:04 +02:00
import { Locations } from "./Locations" ;
2018-06-26 18:34:11 +02:00
import { hasBn11SF , hasWallStreetSF , hasAISF } from "./NetscriptFunctions" ;
2019-01-17 20:10:35 +01:00
import { Sleeve } from "./PersonObjects/Sleeve/Sleeve" ;
2018-06-26 18:34:11 +02:00
import { AllServers , Server , AddToAllServers } from "./Server" ;
2019-01-27 23:08:45 +01:00
import { Settings } from "./Settings/Settings" ;
2018-06-26 18:34:11 +02:00
import { SpecialServerIps , SpecialServerNames } from "./SpecialServerIps" ;
import { SourceFiles , applySourceFile } from "./SourceFile" ;
2019-01-17 20:10:35 +01:00
import { SourceFileFlags } from "./SourceFile/SourceFileFlags" ;
2018-05-30 19:41:17 +02:00
import Decimal from "decimal.js" ;
2018-09-12 17:53:08 +02:00
import { numeralWrapper } from "./ui/numeralFormat" ;
2019-02-22 03:26:28 +01:00
import { MoneySourceTracker } from "./utils/MoneySourceTracker" ;
2018-06-26 18:34:11 +02:00
import { dialogBoxCreate } from "../utils/DialogBox" ;
2018-07-08 05:19:19 +02:00
import { clearEventListeners } from "../utils/uiHelpers/clearEventListeners" ;
2018-06-26 18:34:11 +02:00
import { createRandomIp } from "../utils/IPAddress" ;
2017-08-30 19:44:29 +02:00
import { Reviver , Generic _toJSON ,
2018-06-26 18:34:11 +02:00
Generic _fromJSON } from "../utils/JSONReviver" ;
2018-10-23 20:55:42 +02:00
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions" ;
2017-08-30 19:44:29 +02:00
2018-09-05 22:36:18 +02:00
const CYCLES _PER _SEC = 1000 / CONSTANTS . MilliPerCycle ;
2016-12-01 23:18:18 +01:00
function PlayerObject ( ) {
//Skills and stats
2017-09-13 16:22:22 +02:00
this . hacking _skill = 1 ;
2017-07-27 04:56:14 +02:00
2017-09-13 16:22:22 +02:00
//Combat stats
this . hp = 10 ;
this . max _hp = 10 ;
2018-12-07 11:54:26 +01:00
this . strength = 1 ;
this . defense = 1 ;
this . dexterity = 1 ;
this . agility = 1 ;
2017-07-27 04:56:14 +02:00
2016-12-01 23:18:18 +01:00
//Labor stats
2017-09-13 16:22:22 +02:00
this . charisma = 1 ;
//Special stats
this . intelligence = 0 ;
2017-07-27 04:56:14 +02:00
2016-12-01 23:18:18 +01:00
//Hacking multipliers
2018-03-03 22:05:33 +01:00
this . hacking _chance _mult = 1 ;
this . hacking _speed _mult = 1 ;
this . hacking _money _mult = 1 ;
2017-05-18 22:00:37 +02:00
this . hacking _grow _mult = 1 ;
2017-07-27 04:56:14 +02:00
2016-12-01 23:18:18 +01:00
//Experience and multipliers
this . hacking _exp = 0 ;
this . strength _exp = 0 ;
this . defense _exp = 0 ;
this . dexterity _exp = 0 ;
this . agility _exp = 0 ;
this . charisma _exp = 0 ;
2017-09-13 16:22:22 +02:00
this . intelligence _exp = 0 ;
2017-07-27 04:56:14 +02:00
2017-02-20 23:06:16 +01: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 ;
2017-07-27 04:56:14 +02:00
2016-12-01 23:18:18 +01: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 ;
2017-02-17 23:19:25 +01:00
this . company _rep _mult = 1 ;
2017-07-27 04:56:14 +02:00
this . faction _rep _mult = 1 ;
2016-12-01 23:18:18 +01:00
//Money
2017-07-29 18:25:40 +02:00
this . money = new Decimal ( 1000 ) ;
2017-07-27 04:56:14 +02:00
2016-12-15 18:51:23 +01:00
//IP Address of Starting (home) computer
2017-01-11 21:00:51 +01:00
this . homeComputer = "" ;
2017-07-27 04:56:14 +02:00
2017-01-31 04:41:42 +01:00
//Location information
2017-02-03 23:05:59 +01:00
this . city = Locations . Sector12 ;
2017-01-11 21:00:51 +01:00
this . location = "" ;
2017-07-27 04:56:14 +02:00
2019-01-15 04:34:04 +01:00
// Jobs that the player holds
// Map of company name (key) -> name of company position (value. Just the name, not the CompanyPosition object)
// The CompanyPosition name must match a key value in CompanyPositions
this . jobs = { } ;
// Company at which player is CURRENTLY working (only valid when the player is actively working)
2018-11-16 02:28:23 +01:00
this . companyName = "" ; // Name of Company. Must match a key value in Companies map
2017-07-27 04:56:14 +02:00
2016-12-01 23:18:18 +01:00
//Servers
2017-05-10 19:42:46 +02:00
this . currentServer = "" ; //IP address of Server currently being accessed through terminal
2017-09-26 04:44:33 +02:00
this . purchasedServers = [ ] ; //IP Addresses of purchased servers
2017-05-10 19:42:46 +02:00
this . hacknetNodes = [ ] ;
2017-07-27 04:56:14 +02:00
2017-02-17 23:19:25 +01:00
//Factions
2017-07-27 04:56:14 +02:00
this . factions = [ ] ; //Names of all factions player has joined
this . factionInvitations = [ ] ; //Outstanding faction invitations
2017-02-09 23:40:55 +01:00
//Augmentations
2017-08-03 06:21:15 +02:00
this . queuedAugmentations = [ ] ;
this . augmentations = [ ] ;
this . sourceFiles = [ ] ;
2017-07-27 04:56:14 +02:00
2017-08-13 07:01:33 +02:00
//Crime statistics
2017-09-01 18:59:11 +02:00
this . numPeopleKilled = 0 ;
2017-05-03 19:52:54 +02:00
this . karma = 0 ;
2017-07-27 04:56:14 +02:00
2017-05-12 20:12:32 +02:00
this . crime _money _mult = 1 ;
2017-05-18 22:00:37 +02:00
this . crime _success _mult = 1 ;
2017-07-27 04:56:14 +02:00
//Flags/variables for working (Company, Faction, Creating Program, Taking Class)
2017-02-06 06:01:01 +01:00
this . isWorking = false ;
2017-04-24 21:10:35 +02:00
this . workType = "" ;
2017-07-27 04:56:14 +02:00
2017-02-17 23:19:25 +01:00
this . currentWorkFactionName = "" ;
this . currentWorkFactionDescription = "" ;
2017-07-27 04:56:14 +02:00
2017-02-08 01:27:11 +01:00
this . workHackExpGainRate = 0 ;
this . workStrExpGainRate = 0 ;
this . workDefExpGainRate = 0 ;
this . workDexExpGainRate = 0 ;
this . workAgiExpGainRate = 0 ;
2017-02-16 19:52:11 +01:00
this . workChaExpGainRate = 0 ;
2017-02-08 01:27:11 +01:00
this . workRepGainRate = 0 ;
this . workMoneyGainRate = 0 ;
2017-04-24 21:10:35 +02:00
this . workMoneyLossRate = 0 ;
2017-07-27 04:56:14 +02:00
2017-02-06 06:01:01 +01:00
this . workHackExpGained = 0 ;
this . workStrExpGained = 0 ;
this . workDefExpGained = 0 ;
this . workDexExpGained = 0 ;
this . workAgiExpGained = 0 ;
2017-02-16 19:52:11 +01:00
this . workChaExpGained = 0 ;
2017-02-06 06:01:01 +01:00
this . workRepGained = 0 ;
this . workMoneyGained = 0 ;
2017-07-27 04:56:14 +02:00
2017-03-31 23:47:06 +02:00
this . createProgramName = "" ;
2017-09-15 16:06:59 +02:00
this . createProgramReqLvl = 0 ;
2017-07-27 04:56:14 +02:00
2017-04-24 21:10:35 +02:00
this . className = "" ;
2017-07-27 04:56:14 +02:00
2017-05-03 19:52:54 +02:00
this . crimeType = "" ;
2017-07-27 04:56:14 +02:00
2017-02-06 06:01:01 +01:00
this . timeWorked = 0 ; //in ms
2017-09-15 16:06:59 +02:00
this . timeWorkedCreateProgram = 0 ;
2017-04-19 23:39:25 +02:00
this . timeNeededToCompleteWork = 0 ;
2017-07-27 04:56:14 +02:00
2017-02-08 01:27:11 +01:00
this . work _money _mult = 1 ;
2017-07-27 04:56:14 +02:00
2017-05-02 21:24:24 +02:00
//Hacknet Node multipliers
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 ;
2017-07-27 04:56:14 +02:00
2017-07-03 21:42:11 +02:00
//Stock Market
this . hasWseAccount = false ;
this . hasTixApiAccess = false ;
2018-08-23 20:51:57 +02:00
this . has4SData = false ;
this . has4SDataTixApi = false ;
2017-07-27 04:56:14 +02:00
2017-08-13 07:01:33 +02:00
//Gang
2017-09-01 18:59:11 +02:00
this . gang = 0 ;
2017-08-13 07:01:33 +02:00
2017-12-02 04:50:08 +01:00
//Corporation
this . corporation = 0 ;
2018-05-02 19:38:11 +02:00
//Bladeburner
this . bladeburner = 0 ;
this . bladeburner _max _stamina _mult = 1 ;
this . bladeburner _stamina _gain _mult = 1 ;
this . bladeburner _analysis _mult = 1 ; //Field Analysis Only
this . bladeburner _success _chance _mult = 1 ;
2019-01-17 06:15:00 +01:00
// Sleeves & Re-sleeving
2019-01-10 09:20:04 +01:00
this . sleeves = [ ] ;
2019-01-17 06:15:00 +01:00
this . resleeves = [ ] ;
2019-01-30 07:02:27 +01:00
this . sleevesFromCovenant = 0 ; // # of Duplicate sleeves purchased from the covenant
2019-01-10 09:20:04 +01:00
2017-08-13 07:01:33 +02:00
//bitnode
this . bitNodeN = 1 ;
2017-09-01 18:59:11 +02:00
//Flags for determining whether certain "thresholds" have been achieved
this . firstFacInvRecvd = false ;
this . firstAugPurchased = false ;
this . firstTimeTraveled = false ;
this . firstProgramAvailable = false ;
2017-07-27 04:56:14 +02:00
//Used to store the last update time.
2017-05-15 21:11:40 +02:00
this . lastUpdate = 0 ;
2017-05-15 16:15:59 +02:00
this . totalPlaytime = 0 ;
2017-06-17 19:47:04 +02:00
this . playtimeSinceLastAug = 0 ;
2018-06-22 21:38:25 +02:00
this . playtimeSinceLastBitnode = 0 ;
2017-09-26 04:44:33 +02:00
2019-02-22 03:26:28 +01:00
// Keep track of where money comes from
this . moneySourceA = new MoneySourceTracker ( ) ; // Where money comes from since last-installed Augmentation
this . moneySourceB = new MoneySourceTracker ( ) ; // Where money comes from for this entire BitNode run
// Production since last Augmentation installation
2017-09-26 04:44:33 +02:00
this . scriptProdSinceLastAug = 0 ;
2016-12-01 23:18:18 +01:00
} ;
PlayerObject . prototype . init = function ( ) {
/* Initialize Player's home computer */
2018-05-06 23:20:00 +02:00
var t _homeComp = new Server ( {
ip : createRandomIp ( ) , hostname : "home" , organizationName : "Home PC" ,
isConnectedTo : true , adminRights : true , purchasedByPlayer : true , maxRam : 8
} ) ;
2016-12-01 23:18:18 +01:00
this . homeComputer = t _homeComp . ip ;
this . currentServer = t _homeComp . ip ;
AddToAllServers ( t _homeComp ) ;
2017-07-27 04:56:14 +02:00
2018-06-02 01:31:34 +02:00
this . getHomeComputer ( ) . programs . push ( Programs . NukeProgram . name ) ;
2017-05-08 16:33:26 +02:00
}
2016-10-14 23:02:06 +02:00
2017-08-30 19:44:29 +02:00
PlayerObject . prototype . prestigeAugmentation = function ( ) {
var homeComp = this . getHomeComputer ( ) ;
this . currentServer = homeComp . ip ;
this . homeComputer = homeComp . ip ;
this . numPeopleKilled = 0 ;
this . karma = 0 ;
//Reset stats
this . hacking _skill = 1 ;
this . strength = 1 ;
this . defense = 1 ;
this . dexterity = 1 ;
this . agility = 1 ;
this . charisma = 1 ;
this . hacking _exp = 0 ;
this . strength _exp = 0 ;
this . defense _exp = 0 ;
this . dexterity _exp = 0 ;
this . agility _exp = 0 ;
this . charisma _exp = 0 ;
this . money = new Decimal ( 1000 ) ;
this . city = Locations . Sector12 ;
this . location = "" ;
this . companyName = "" ;
2019-01-15 04:34:04 +01:00
this . jobs = { } ;
2017-08-30 19:44:29 +02:00
this . purchasedServers = [ ] ;
this . factions = [ ] ;
this . factionInvitations = [ ] ;
this . queuedAugmentations = [ ] ;
2019-01-17 20:10:35 +01:00
this . resleeves = [ ] ;
2019-01-22 05:39:52 +01:00
for ( let i = 0 ; i < this . sleeves . length ; ++ i ) {
if ( this . sleeves [ i ] instanceof Sleeve ) {
this . sleeves [ i ] . resetTaskStatus ( ) ;
}
}
2017-08-30 19:44:29 +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 ( ) ;
2019-02-22 03:26:28 +01:00
// Statistics Trackers
2017-08-30 19:44:29 +02:00
this . playtimeSinceLastAug = 0 ;
2017-09-27 17:13:42 +02:00
this . scriptProdSinceLastAug = 0 ;
2019-02-22 03:26:28 +01:00
this . moneySourceA . reset ( ) ;
2017-08-30 19:44:29 +02:00
this . hacknetNodes . length = 0 ;
2018-07-08 02:16:58 +02:00
//Re-calculate skills and reset HP
this . updateSkillLevels ( ) ;
this . hp = this . max _hp ;
2017-08-30 19:44:29 +02:00
}
PlayerObject . prototype . prestigeSourceFile = function ( ) {
var homeComp = this . getHomeComputer ( ) ;
this . currentServer = homeComp . ip ;
this . homeComputer = homeComp . ip ;
this . numPeopleKilled = 0 ;
this . karma = 0 ;
//Reset stats
this . hacking _skill = 1 ;
this . strength = 1 ;
this . defense = 1 ;
this . dexterity = 1 ;
this . agility = 1 ;
this . charisma = 1 ;
this . hacking _exp = 0 ;
this . strength _exp = 0 ;
this . defense _exp = 0 ;
this . dexterity _exp = 0 ;
this . agility _exp = 0 ;
this . charisma _exp = 0 ;
this . money = new Decimal ( 1000 ) ;
this . city = Locations . Sector12 ;
this . location = "" ;
this . companyName = "" ;
2019-01-15 04:34:04 +01:00
this . jobs = { } ;
2017-08-30 19:44:29 +02:00
this . purchasedServers = [ ] ;
this . factions = [ ] ;
this . factionInvitations = [ ] ;
this . queuedAugmentations = [ ] ;
this . augmentations = [ ] ;
2019-01-17 20:10:35 +01:00
this . resleeves = [ ] ;
// Duplicate sleeves are reset to level 1 every Bit Node (but the number of sleeves you have persists)
2019-01-30 07:02:27 +01:00
this . sleeves . length = SourceFileFlags [ 10 ] + this . sleevesFromCovenant ;
2019-01-17 20:10:35 +01:00
for ( let i = 0 ; i < this . sleeves . length ; ++ i ) {
this . sleeves [ i ] = new Sleeve ( ) ;
}
2017-08-30 19:44:29 +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 ( ) ;
this . hacknetNodes . length = 0 ;
//Gang
this . gang = null ;
2017-09-02 22:05:42 +02:00
resetGangs ( ) ;
2017-08-30 19:44:29 +02:00
//Reset Stock market
this . hasWseAccount = false ;
this . hasTixApiAccess = false ;
2018-08-27 07:23:04 +02:00
this . has4SData = false ;
this . has4SDataTixApi = false ;
2017-08-30 19:44:29 +02:00
2017-12-02 04:50:08 +01:00
//BitNode 3: Corporatocracy
2017-12-07 04:45:47 +01:00
this . corporation = 0 ;
2017-12-02 04:50:08 +01:00
2019-02-22 03:26:28 +01:00
// Statistics trackers
2017-08-30 19:44:29 +02:00
this . playtimeSinceLastAug = 0 ;
2018-06-22 21:38:25 +02:00
this . playtimeSinceLastBitnode = 0 ;
2017-09-27 17:13:42 +02:00
this . scriptProdSinceLastAug = 0 ;
2019-02-22 03:26:28 +01:00
this . moneySourceA . reset ( ) ;
this . moneySourceB . reset ( ) ;
2018-07-08 02:16:58 +02:00
this . updateSkillLevels ( ) ;
this . hp = this . max _hp ;
2017-08-30 19:44:29 +02:00
}
2016-12-01 23:18:18 +01:00
PlayerObject . prototype . getCurrentServer = function ( ) {
return AllServers [ this . currentServer ] ;
}
PlayerObject . prototype . getHomeComputer = function ( ) {
return AllServers [ this . homeComputer ] ;
}
2018-06-07 20:54:34 +02:00
PlayerObject . prototype . getUpgradeHomeRamCost = function ( ) {
//Calculate how many times ram has been upgraded (doubled)
2019-02-14 03:08:18 +01:00
const currentRam = this . getHomeComputer ( ) . maxRam ;
2018-06-07 20:54:34 +02:00
const numUpgrades = Math . log2 ( currentRam ) ;
//Calculate cost
//Have cost increase by some percentage each time RAM has been upgraded
const mult = Math . pow ( 1.58 , numUpgrades ) ;
2019-02-14 03:08:18 +01:00
var cost = currentRam * CONSTANTS . BaseCostFor1GBOfRamHome * mult * BitNodeMultipliers . HomeComputerRamCost ;
2018-06-07 20:54:34 +02:00
return cost ;
}
2018-06-12 21:27:37 +02:00
PlayerObject . prototype . receiveInvite = function ( factionName ) {
if ( this . factionInvitations . includes ( factionName ) || this . factions . includes ( factionName ) ) {
return ;
}
this . firstFacInvRecvd = true ;
this . factionInvitations . push ( factionName ) ;
}
2016-12-01 23:18:18 +01:00
//Calculates skill level based on experience. The same formula will be used for every skill
2018-06-19 06:37:56 +02:00
PlayerObject . prototype . calculateSkill = function ( exp , mult = 1 ) {
return Math . max ( Math . floor ( mult * ( 32 * Math . log ( exp + 534.5 ) - 200 ) ) , 1 ) ;
2016-12-15 23:22:42 +01:00
}
PlayerObject . prototype . updateSkillLevels = function ( ) {
2018-07-28 03:50:25 +02:00
this . hacking _skill = Math . max ( 1 , Math . floor ( this . calculateSkill ( this . hacking _exp , this . hacking _mult * BitNodeMultipliers . HackingLevelMultiplier ) ) ) ;
2019-01-17 20:10:35 +01:00
this . strength = Math . max ( 1 , Math . floor ( this . calculateSkill ( this . strength _exp , this . strength _mult * BitNodeMultipliers . StrengthLevelMultiplier ) ) ) ;
this . defense = Math . max ( 1 , Math . floor ( this . calculateSkill ( this . defense _exp , this . defense _mult * BitNodeMultipliers . DefenseLevelMultiplier ) ) ) ;
this . dexterity = Math . max ( 1 , Math . floor ( this . calculateSkill ( this . dexterity _exp , this . dexterity _mult * BitNodeMultipliers . DexterityLevelMultiplier ) ) ) ;
this . agility = Math . max ( 1 , Math . floor ( this . calculateSkill ( this . agility _exp , this . agility _mult * BitNodeMultipliers . AgilityLevelMultiplier ) ) ) ;
this . charisma = Math . max ( 1 , Math . floor ( this . calculateSkill ( this . charisma _exp , this . charisma _mult * BitNodeMultipliers . CharismaLevelMultiplier ) ) ) ;
2017-07-27 04:56:14 +02:00
2017-09-15 16:06:59 +02:00
if ( this . intelligence > 0 ) {
this . intelligence = Math . floor ( this . calculateSkill ( this . intelligence _exp ) ) ;
} else {
this . intelligence = 0 ;
}
2017-07-03 21:42:11 +02:00
var ratio = this . hp / this . max _hp ;
this . max _hp = Math . floor ( 10 + this . defense / 10 ) ;
Player . hp = Math . round ( this . max _hp * ratio ) ;
2016-12-15 23:22:42 +01:00
}
2016-12-01 23:18:18 +01:00
2017-08-13 07:01:33 +02:00
PlayerObject . prototype . resetMultipliers = function ( ) {
this . hacking _chance _mult = 1 ;
this . hacking _speed _mult = 1 ;
this . hacking _money _mult = 1 ;
this . hacking _grow _mult = 1 ;
this . hacking _mult = 1 ;
this . strength _mult = 1 ;
this . defense _mult = 1 ;
this . dexterity _mult = 1 ;
this . agility _mult = 1 ;
this . charisma _mult = 1 ;
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 ;
this . company _rep _mult = 1 ;
this . faction _rep _mult = 1 ;
this . crime _money _mult = 1 ;
this . crime _success _mult = 1 ;
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 ;
this . work _money _mult = 1 ;
2018-05-02 19:38:11 +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 ;
2017-08-13 07:01:33 +02:00
}
2017-05-11 06:20:17 +02:00
PlayerObject . prototype . hasProgram = function ( programName ) {
var home = Player . getHomeComputer ( ) ;
2018-08-29 21:06:21 +02:00
if ( home == null ) { return false ; }
2017-05-11 06:20:17 +02:00
for ( var i = 0 ; i < home . programs . length ; ++ i ) {
2017-06-05 17:31:46 +02:00
if ( programName . toLowerCase ( ) == home . programs [ i ] . toLowerCase ( ) ) { return true ; }
2017-05-11 06:20:17 +02:00
}
return false ;
}
2016-12-01 23:18:18 +01:00
2017-08-30 19:44:29 +02:00
PlayerObject . prototype . setMoney = function ( money ) {
if ( isNaN ( money ) ) {
console . log ( "ERR: NaN passed into Player.setMoney()" ) ; return ;
}
this . money = money ;
}
2016-12-19 21:59:13 +01:00
PlayerObject . prototype . gainMoney = function ( money ) {
2017-04-18 06:32:17 +02:00
if ( isNaN ( money ) ) {
console . log ( "ERR: NaN passed into Player.gainMoney()" ) ; return ;
}
2017-07-29 18:25:40 +02:00
this . money = this . money . plus ( money ) ;
2016-12-19 21:59:13 +01:00
}
2017-04-24 21:10:35 +02:00
PlayerObject . prototype . loseMoney = function ( money ) {
if ( isNaN ( money ) ) {
console . log ( "ERR: NaN passed into Player.loseMoney()" ) ; return ;
}
2017-07-29 18:25:40 +02:00
this . money = this . money . minus ( money ) ;
2017-04-24 21:10:35 +02:00
}
2019-01-20 23:57:38 +01:00
PlayerObject . prototype . canAfford = function ( cost ) {
if ( isNaN ( cost ) ) {
console . error ( ` NaN passed into Player.canAfford() ` ) ;
return false ;
}
return this . money . gte ( cost ) ;
}
2019-02-22 03:26:28 +01:00
PlayerObject . prototype . recordMoneySource = function ( amt , source ) {
this . moneySourceA . record ( amt , source ) ;
this . moneySourceB . record ( amt , source ) ;
}
2017-04-18 06:32:17 +02:00
PlayerObject . prototype . gainHackingExp = function ( exp ) {
if ( isNaN ( exp ) ) {
console . log ( "ERR: NaN passed into Player.gainHackingExp()" ) ; return ;
}
this . hacking _exp += exp ;
2018-06-12 22:06:05 +02:00
if ( this . hacking _exp < 0 ) {
this . hacking _exp = 0 ;
}
2017-04-18 06:32:17 +02:00
}
PlayerObject . prototype . gainStrengthExp = function ( exp ) {
if ( isNaN ( exp ) ) {
console . log ( "ERR: NaN passed into Player.gainStrengthExp()" ) ; return ;
}
this . strength _exp += exp ;
2018-06-12 22:06:05 +02:00
if ( this . strength _exp < 0 ) {
this . strength _exp = 0 ;
}
2017-04-18 06:32:17 +02:00
}
PlayerObject . prototype . gainDefenseExp = function ( exp ) {
if ( isNaN ( exp ) ) {
console . log ( "ERR: NaN passed into player.gainDefenseExp()" ) ; return ;
}
this . defense _exp += exp ;
2018-06-12 22:06:05 +02:00
if ( this . defense _exp < 0 ) {
this . defense _exp = 0 ;
}
2017-04-18 06:32:17 +02:00
}
PlayerObject . prototype . gainDexterityExp = function ( exp ) {
if ( isNaN ( exp ) ) {
console . log ( "ERR: NaN passed into Player.gainDexterityExp()" ) ; return ;
}
this . dexterity _exp += exp ;
2018-06-12 22:06:05 +02:00
if ( this . dexterity _exp < 0 ) {
this . dexterity _exp = 0 ;
}
2017-04-18 06:32:17 +02:00
}
PlayerObject . prototype . gainAgilityExp = function ( exp ) {
if ( isNaN ( exp ) ) {
console . log ( "ERR: NaN passed into Player.gainAgilityExp()" ) ; return ;
}
this . agility _exp += exp ;
2018-06-12 22:06:05 +02:00
if ( this . agility _exp < 0 ) {
this . agility _exp = 0 ;
}
2017-04-18 06:32:17 +02:00
}
PlayerObject . prototype . gainCharismaExp = function ( exp ) {
if ( isNaN ( exp ) ) {
console . log ( "ERR: NaN passed into Player.gainCharismaExp()" ) ; return ;
}
this . charisma _exp += exp ;
2018-06-12 22:06:05 +02:00
if ( this . charisma _exp < 0 ) {
this . charisma _exp = 0 ;
}
2017-07-27 04:56:14 +02:00
}
2017-05-03 19:52:54 +02:00
2017-09-13 16:22:22 +02:00
PlayerObject . prototype . gainIntelligenceExp = function ( exp ) {
if ( isNaN ( exp ) ) {
console . log ( "ERROR: NaN passed into Player.gainIntelligenceExp()" ) ; return ;
}
2018-05-02 19:38:11 +02:00
if ( hasAISF || this . intelligence > 0 ) {
2017-09-15 16:06:59 +02:00
this . intelligence _exp += exp ;
}
2017-09-13 16:22:22 +02:00
}
2018-05-02 19:38:11 +02:00
//Given a string expression like "str" or "strength", returns the given stat
PlayerObject . prototype . queryStatFromString = function ( str ) {
2018-12-07 11:54:26 +01:00
const tempStr = str . toLowerCase ( ) ;
2018-05-02 19:38:11 +02:00
if ( tempStr . includes ( "hack" ) ) { return Player . hacking _skill ; }
if ( tempStr . includes ( "str" ) ) { return Player . strength ; }
if ( tempStr . includes ( "def" ) ) { return Player . defense ; }
if ( tempStr . includes ( "dex" ) ) { return Player . dexterity ; }
if ( tempStr . includes ( "agi" ) ) { return Player . agility ; }
if ( tempStr . includes ( "cha" ) ) { return Player . charisma ; }
if ( tempStr . includes ( "int" ) ) { return Player . intelligence ; }
}
2017-05-03 19:52:54 +02:00
/******* Working functions *******/
PlayerObject . prototype . resetWorkStatus = function ( ) {
this . workHackExpGainRate = 0 ;
this . workStrExpGainRate = 0 ;
this . workDefExpGainRate = 0 ;
this . workDexExpGainRate = 0 ;
this . workAgiExpGainRate = 0 ;
this . workChaExpGainRate = 0 ;
this . workRepGainRate = 0 ;
this . workMoneyGainRate = 0 ;
2018-09-05 22:36:18 +02:00
this . workMoneyLossRate = 0 ;
2017-07-27 04:56:14 +02:00
2017-05-03 19:52:54 +02:00
this . workHackExpGained = 0 ;
this . workStrExpGained = 0 ;
this . workDefExpGained = 0 ;
this . workDexExpGained = 0 ;
this . workAgiExpGained = 0 ;
this . workChaExpGained = 0 ;
this . workRepGained = 0 ;
this . workMoneyGained = 0 ;
2017-07-27 04:56:14 +02:00
2017-05-03 19:52:54 +02:00
this . timeWorked = 0 ;
2017-09-15 16:06:59 +02:00
this . timeWorkedCreateProgram = 0 ;
2017-07-27 04:56:14 +02:00
2017-05-03 19:52:54 +02:00
this . currentWorkFactionName = "" ;
this . currentWorkFactionDescription = "" ;
this . createProgramName = "" ;
this . className = "" ;
2017-07-27 04:56:14 +02:00
2017-05-21 23:04:57 +02:00
document . getElementById ( "work-in-progress-text" ) . innerHTML = "" ;
2017-05-03 19:52:54 +02:00
}
2018-09-05 22:36:18 +02:00
PlayerObject . prototype . processWorkEarnings = function ( numCycles = 1 ) {
2018-11-20 06:54:03 +01:00
const hackExpGain = this . workHackExpGainRate * numCycles ;
const strExpGain = this . workStrExpGainRate * numCycles ;
const defExpGain = this . workDefExpGainRate * numCycles ;
const dexExpGain = this . workDexExpGainRate * numCycles ;
const agiExpGain = this . workAgiExpGainRate * numCycles ;
const chaExpGain = this . workChaExpGainRate * numCycles ;
const moneyGain = ( this . workMoneyGainRate - this . workMoneyLossRate ) * numCycles ;
2018-08-30 23:51:25 +02:00
this . gainHackingExp ( hackExpGain ) ;
this . gainStrengthExp ( strExpGain ) ;
this . gainDefenseExp ( defExpGain ) ;
this . gainDexterityExp ( dexExpGain ) ;
this . gainAgilityExp ( agiExpGain ) ;
this . gainCharismaExp ( chaExpGain ) ;
2018-11-20 06:54:03 +01:00
this . gainMoney ( moneyGain ) ;
2019-02-22 03:26:28 +01:00
this . recordMoneySource ( moneyGain , "work" ) ;
2018-08-30 23:51:25 +02:00
this . workHackExpGained += hackExpGain ;
this . workStrExpGained += strExpGain ;
this . workDefExpGained += defExpGain ;
this . workDexExpGained += dexExpGain ;
this . workAgiExpGained += agiExpGain ;
this . workChaExpGained += chaExpGain ;
this . workRepGained += this . workRepGainRate * numCycles ;
this . workMoneyGained += this . workMoneyGainRate * numCycles ;
2018-09-05 22:36:18 +02:00
this . workMoneyGained -= this . workMoneyLossRate * numCycles ;
2017-04-18 06:32:17 +02:00
}
2017-02-16 19:52:11 +01:00
/* Working for Company */
2019-01-18 18:57:21 +01:00
PlayerObject . prototype . startWork = function ( companyName ) {
2017-05-03 19:52:54 +02:00
this . resetWorkStatus ( ) ;
2017-02-06 06:01:01 +01:00
this . isWorking = true ;
2019-01-18 18:57:21 +01:00
this . companyName = companyName ;
2017-04-24 21:10:35 +02:00
this . workType = CONSTANTS . WorkTypeCompany ;
2017-07-27 04:56:14 +02:00
2017-02-08 01:27:11 +01:00
this . workHackExpGainRate = this . getWorkHackExpGain ( ) ;
this . workStrExpGainRate = this . getWorkStrExpGain ( ) ;
this . workDefExpGainRate = this . getWorkDefExpGain ( ) ;
this . workDexExpGainRate = this . getWorkDexExpGain ( ) ;
this . workAgiExpGainRate = this . getWorkAgiExpGain ( ) ;
2017-02-16 19:52:11 +01:00
this . workChaExpGainRate = this . getWorkChaExpGain ( ) ;
2017-02-08 01:27:11 +01:00
this . workRepGainRate = this . getWorkRepGain ( ) ;
this . workMoneyGainRate = this . getWorkMoneyGain ( ) ;
2017-07-27 04:56:14 +02:00
2017-04-19 23:39:25 +02:00
this . timeNeededToCompleteWork = CONSTANTS . MillisecondsPer8Hours ;
2017-07-27 04:56:14 +02:00
2017-02-16 19:52:11 +01:00
//Remove all old event listeners from Cancel button
2017-05-10 19:42:46 +02:00
var newCancelButton = clearEventListeners ( "work-in-progress-cancel-button" ) ;
2017-05-16 05:06:25 +02:00
newCancelButton . innerHTML = "Cancel Work" ;
2017-02-16 19:52:11 +01:00
newCancelButton . addEventListener ( "click" , function ( ) {
2017-02-08 05:48:50 +01:00
Player . finishWork ( true ) ;
2017-02-16 19:52:11 +01:00
return false ;
2017-02-08 01:27:11 +01:00
} ) ;
2017-07-27 04:56:14 +02:00
2017-02-08 01:27:11 +01:00
//Display Work In Progress Screen
Engine . loadWorkInProgressContent ( ) ;
2017-02-06 06:01:01 +01:00
}
2017-07-27 04:56:14 +02:00
2017-02-06 06:01:01 +01:00
PlayerObject . prototype . work = function ( numCycles ) {
2018-08-30 23:51:25 +02:00
//Cap the number of cycles being processed to whatever would put you at
//the work time limit (8 hours)
var overMax = false ;
if ( this . timeWorked + ( Engine . _idleSpeed * numCycles ) >= CONSTANTS . MillisecondsPer8Hours ) {
overMax = true ;
numCycles = Math . round ( ( CONSTANTS . MillisecondsPer8Hours - this . timeWorked ) / Engine . _idleSpeed ) ;
}
2017-02-08 01:27:11 +01:00
this . timeWorked += Engine . _idleSpeed * numCycles ;
2017-07-27 04:56:14 +02:00
2018-08-30 23:51:25 +02:00
this . workRepGainRate = this . getWorkRepGain ( ) ;
this . processWorkEarnings ( numCycles ) ;
2017-02-16 19:52:11 +01:00
//If timeWorked == 8 hours, then finish. You can only gain 8 hours worth of exp and money
2018-08-30 23:51:25 +02:00
if ( overMax || this . timeWorked >= CONSTANTS . MillisecondsPer8Hours ) {
return this . finishWork ( false ) ;
2017-02-08 01:27:11 +01:00
}
2017-07-27 04:56:14 +02:00
2018-03-03 22:05:33 +01:00
var comp = Companies [ this . companyName ] , companyRep = "0" ;
if ( comp == null || ! ( comp instanceof Company ) ) {
2018-11-16 02:28:23 +01:00
console . error ( ` Could not find Company: ${ this . companyName } ` ) ;
2018-03-03 22:05:33 +01:00
} else {
companyRep = comp . playerReputation ;
}
2019-01-15 04:34:04 +01:00
const position = this . jobs [ this . companyName ] ;
2017-02-06 06:01:01 +01:00
var txt = document . getElementById ( "work-in-progress-text" ) ;
2019-01-15 04:34:04 +01:00
txt . innerHTML = "You are currently working as a " + position +
2018-03-03 22:05:33 +01:00
" at " + this . companyName + " (Current Company Reputation: " +
2018-10-23 20:55:42 +02:00
numeralWrapper . format ( companyRep , '0,0' ) + ")<br><br>" +
2017-02-06 06:01:01 +01:00
"You have been working for " + convertTimeMsToTimeElapsedString ( this . timeWorked ) + "<br><br>" +
2017-07-27 04:56:14 +02:00
"You have earned: <br><br>" +
2018-10-23 20:55:42 +02:00
"$" + numeralWrapper . format ( this . workMoneyGained , '0,0.00' ) + " ($" + numeralWrapper . format ( this . workMoneyGainRate * CYCLES _PER _SEC , '0,0.00' ) + " / sec) <br><br>" +
numeralWrapper . format ( this . workRepGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workRepGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) reputation for this company <br><br>" +
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workHackExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) hacking exp <br><br>" +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workStrExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) strength exp <br>" +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workDefExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) defense exp <br>" +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workDexExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) dexterity exp <br>" +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workAgiExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) agility exp <br><br> " +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workChaExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) charisma exp <br><br>" +
2017-07-27 04:56:14 +02:00
"You will automatically finish after working for 8 hours. You can cancel earlier if you wish, " +
2017-05-31 17:58:09 +02:00
"but you will only gain half of the reputation you've earned so far."
2018-08-30 23:51:25 +02:00
}
2017-08-30 19:44:29 +02:00
PlayerObject . prototype . finishWork = function ( cancelled , sing = false ) {
2017-02-08 01:27:11 +01:00
//Since the work was cancelled early, player only gains half of what they've earned so far
2017-05-31 17:58:09 +02:00
if ( cancelled ) {
this . workRepGained /= 2 ;
2017-02-16 19:52:11 +01:00
}
2017-05-03 19:52:54 +02:00
2017-02-08 01:27:11 +01:00
var company = Companies [ this . companyName ] ;
2017-05-31 17:58:09 +02:00
company . playerReputation += ( this . workRepGained ) ;
2017-07-27 04:56:14 +02:00
2017-02-08 01:27:11 +01:00
this . updateSkillLevels ( ) ;
2017-07-27 04:56:14 +02:00
var txt = "You earned a total of: <br>" +
2018-10-23 20:55:42 +02:00
"$" + numeralWrapper . format ( this . workMoneyGained , '0,0.00' ) + "<br>" +
numeralWrapper . format ( this . workRepGained , '0,0.0000' ) + " reputation for the company <br>" +
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " hacking exp <br>" +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " strength exp <br>" +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " defense exp <br>" +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " dexterity exp <br>" +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " agility exp <br>" +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " charisma exp<br>" ;
2017-07-27 04:56:14 +02:00
2017-05-10 19:42:46 +02:00
if ( cancelled ) {
txt = "You worked a short shift of " + convertTimeMsToTimeElapsedString ( this . timeWorked ) + " <br><br> " +
2017-07-27 04:56:14 +02:00
"Since you cancelled your work early, you only gained half of the reputation you earned. <br><br>" + txt ;
2017-02-08 01:27:11 +01:00
} else {
2017-10-04 03:50:13 +02:00
txt = "You worked a full shift of 8 hours! <br><br> " + txt ;
2017-02-08 01:27:11 +01:00
}
2017-08-30 19:44:29 +02:00
if ( ! sing ) { dialogBoxCreate ( txt ) ; }
2017-07-27 04:56:14 +02:00
2017-02-08 05:48:50 +01:00
var mainMenu = document . getElementById ( "mainmenu-container" ) ;
mainMenu . style . visibility = "visible" ;
2017-03-31 14:32:04 +02:00
this . isWorking = false ;
2017-09-15 16:06:59 +02:00
Engine . loadLocationContent ( ) ;
2017-08-30 19:44:29 +02:00
if ( sing ) {
2018-03-03 22:05:33 +01:00
var res = "You worked a short shift of " + convertTimeMsToTimeElapsedString ( this . timeWorked ) + " and " +
2018-10-23 20:55:42 +02:00
"earned $" + numeralWrapper . format ( this . workMoneyGained , '0,0.00' ) + ", " +
numeralWrapper . format ( this . workRepGained , '0,0.0000' ) + " reputation, " +
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " hacking exp, " +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " strength exp, " +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " defense exp, " +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " dexterity exp, " +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " agility exp, and " +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " charisma exp." ;
2018-03-03 22:05:33 +01:00
this . resetWorkStatus ( ) ;
return res ;
2017-08-30 19:44:29 +02:00
}
2018-03-03 22:05:33 +01:00
this . resetWorkStatus ( ) ;
2017-02-08 01:27:11 +01:00
}
2019-01-18 18:57:21 +01:00
PlayerObject . prototype . startWorkPartTime = function ( companyName ) {
2017-05-03 19:52:54 +02:00
this . resetWorkStatus ( ) ;
2017-02-06 06:01:01 +01:00
this . isWorking = true ;
2019-01-18 18:57:21 +01:00
this . companyName = companyName ;
2017-05-10 19:42:46 +02:00
this . workType = CONSTANTS . WorkTypeCompanyPartTime ;
2017-07-27 04:56:14 +02:00
2017-02-08 01:27:11 +01:00
this . workHackExpGainRate = this . getWorkHackExpGain ( ) ;
this . workStrExpGainRate = this . getWorkStrExpGain ( ) ;
this . workDefExpGainRate = this . getWorkDefExpGain ( ) ;
this . workDexExpGainRate = this . getWorkDexExpGain ( ) ;
this . workAgiExpGainRate = this . getWorkAgiExpGain ( ) ;
2017-02-16 19:52:11 +01:00
this . workChaExpGainRate = this . getWorkChaExpGain ( ) ;
2017-02-08 01:27:11 +01:00
this . workRepGainRate = this . getWorkRepGain ( ) ;
this . workMoneyGainRate = this . getWorkMoneyGain ( ) ;
2017-07-27 04:56:14 +02:00
2017-04-19 23:39:25 +02:00
this . timeNeededToCompleteWork = CONSTANTS . MillisecondsPer8Hours ;
2017-07-27 04:56:14 +02:00
2017-05-10 19:42:46 +02:00
var newCancelButton = clearEventListeners ( "work-in-progress-cancel-button" ) ;
2017-05-16 05:06:25 +02:00
newCancelButton . innerHTML = "Stop Working" ;
2017-02-16 19:52:11 +01:00
newCancelButton . addEventListener ( "click" , function ( ) {
2017-05-10 19:42:46 +02:00
Player . finishWorkPartTime ( ) ;
2017-02-16 19:52:11 +01:00
return false ;
2017-02-08 01:27:11 +01:00
} ) ;
2017-07-27 04:56:14 +02:00
2017-02-08 01:27:11 +01:00
//Display Work In Progress Screen
Engine . loadWorkInProgressContent ( ) ;
2017-02-06 06:01:01 +01:00
}
2017-07-27 04:56:14 +02:00
2017-05-10 19:42:46 +02:00
PlayerObject . prototype . workPartTime = function ( numCycles ) {
2018-08-30 23:51:25 +02:00
//Cap the number of cycles being processed to whatever would put you at the
//work time limit (8 hours)
var overMax = false ;
if ( this . timeWorked + ( Engine . _idleSpeed * numCycles ) >= CONSTANTS . MillisecondsPer8Hours ) {
overMax = true ;
numCycles = Math . round ( ( CONSTANTS . MillisecondsPer8Hours - this . timeWorked ) / Engine . _idleSpeed ) ;
}
2017-02-08 01:27:11 +01:00
this . timeWorked += Engine . _idleSpeed * numCycles ;
2017-07-27 04:56:14 +02:00
2018-08-30 23:51:25 +02:00
this . workRepGainRate = this . getWorkRepGain ( ) ;
this . processWorkEarnings ( numCycles ) ;
2017-02-16 19:52:11 +01:00
//If timeWorked == 8 hours, then finish. You can only gain 8 hours worth of exp and money
2018-08-30 23:51:25 +02:00
if ( overMax || this . timeWorked >= CONSTANTS . MillisecondsPer8Hours ) {
return this . finishWorkPartTime ( ) ;
2017-02-08 01:27:11 +01:00
}
2017-07-27 04:56:14 +02:00
2018-03-03 22:05:33 +01:00
var comp = Companies [ this . companyName ] , companyRep = "0" ;
if ( comp == null || ! ( comp instanceof Company ) ) {
console . log ( "ERROR: Could not find Company: " + this . companyName ) ;
} else {
companyRep = comp . playerReputation ;
}
2019-01-15 04:34:04 +01:00
const position = this . jobs [ this . companyName ] ;
2017-02-06 06:01:01 +01:00
var txt = document . getElementById ( "work-in-progress-text" ) ;
2019-01-15 04:34:04 +01:00
txt . innerHTML = "You are currently working as a " + position +
" at " + this . companyName + " (Current Company Reputation: " +
2018-10-23 20:55:42 +02:00
numeralWrapper . format ( companyRep , '0,0' ) + ")<br><br>" +
2017-02-06 06:01:01 +01:00
"You have been working for " + convertTimeMsToTimeElapsedString ( this . timeWorked ) + "<br><br>" +
2017-07-27 04:56:14 +02:00
"You have earned: <br><br>" +
2018-10-23 20:55:42 +02:00
"$" + numeralWrapper . format ( this . workMoneyGained , '0,0.00' ) + " ($" + numeralWrapper . format ( this . workMoneyGainRate * CYCLES _PER _SEC , '0,0.00' ) + " / sec) <br><br>" +
numeralWrapper . format ( this . workRepGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workRepGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) reputation for this company <br><br>" +
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workHackExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) hacking exp <br><br>" +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workStrExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) strength exp <br>" +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workDefExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) defense exp <br>" +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workDexExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) dexterity exp <br>" +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workAgiExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) agility exp <br><br> " +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workChaExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) charisma exp <br><br>" +
2017-07-27 04:56:14 +02:00
"You will automatically finish after working for 8 hours. You can cancel earlier if you wish, <br>" +
2017-05-10 19:42:46 +02:00
"and there will be no penalty because this is a part-time job." ;
2017-07-27 04:56:14 +02:00
2017-05-10 19:42:46 +02:00
}
2017-08-30 19:44:29 +02:00
PlayerObject . prototype . finishWorkPartTime = function ( sing = false ) {
2017-05-10 19:42:46 +02:00
var company = Companies [ this . companyName ] ;
2017-05-10 22:21:15 +02:00
company . playerReputation += ( this . workRepGained ) ;
2017-07-27 04:56:14 +02:00
2017-05-10 19:42:46 +02:00
this . updateSkillLevels ( ) ;
2017-07-27 04:56:14 +02:00
var txt = "You earned a total of: <br>" +
2018-10-23 20:55:42 +02:00
"$" + numeralWrapper . format ( this . workMoneyGained , '0,0.00' ) + "<br>" +
numeralWrapper . format ( this . workRepGained , '0,0.0000' ) + " reputation for the company <br>" +
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " hacking exp <br>" +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " strength exp <br>" +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " defense exp <br>" +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " dexterity exp <br>" +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " agility exp <br>" +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " charisma exp<br>" ;
2017-05-15 19:49:49 +02:00
txt = "You worked for " + convertTimeMsToTimeElapsedString ( this . timeWorked ) + "<br><br> " + txt ;
2017-08-30 19:44:29 +02:00
if ( ! sing ) { dialogBoxCreate ( txt ) ; }
2017-07-27 04:56:14 +02:00
2017-05-10 19:42:46 +02:00
var mainMenu = document . getElementById ( "mainmenu-container" ) ;
mainMenu . style . visibility = "visible" ;
this . isWorking = false ;
2017-09-15 16:06:59 +02:00
Engine . loadLocationContent ( ) ;
2017-08-30 19:44:29 +02:00
if ( sing ) {
2018-03-03 22:05:33 +01:00
var res = "You worked for " + convertTimeMsToTimeElapsedString ( this . timeWorked ) + " and " +
2017-08-30 19:44:29 +02:00
"earned a total of " +
2018-10-23 20:55:42 +02:00
"$" + numeralWrapper . format ( this . workMoneyGained , '0,0.00' ) + ", " +
numeralWrapper . format ( this . workRepGained , '0,0.0000' ) + " reputation, " +
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " hacking exp, " +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " strength exp, " +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " defense exp, " +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " dexterity exp, " +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " agility exp, and " +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " charisma exp" ;
2018-03-03 22:05:33 +01:00
this . resetWorkStatus ( ) ;
return res ;
2017-08-30 19:44:29 +02:00
}
2018-03-03 22:05:33 +01:00
this . resetWorkStatus ( ) ;
2017-05-10 19:42:46 +02:00
}
2017-02-16 19:52:11 +01:00
/* Working for Faction */
2017-02-27 23:14:11 +01:00
PlayerObject . prototype . startFactionWork = function ( faction ) {
2017-06-20 18:11:33 +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 ;
2017-08-13 07:01:33 +02:00
this . workRepGainRate *= BitNodeMultipliers . FactionWorkRepGain ;
2017-07-27 04:56:14 +02:00
2017-02-16 19:52:11 +01:00
this . isWorking = true ;
2017-04-24 21:10:35 +02:00
this . workType = CONSTANTS . WorkTypeFaction ;
2017-02-17 23:19:25 +01:00
this . currentWorkFactionName = faction . name ;
2017-07-27 04:56:14 +02:00
2017-04-19 23:39:25 +02:00
this . timeNeededToCompleteWork = CONSTANTS . MillisecondsPer20Hours ;
2017-07-27 04:56:14 +02:00
var cancelButton = clearEventListeners ( "work-in-progress-cancel-button" ) ;
2017-05-16 05:06:25 +02:00
cancelButton . innerHTML = "Stop Faction Work" ;
cancelButton . addEventListener ( "click" , function ( ) {
2017-08-30 19:44:29 +02:00
Player . finishFactionWork ( true ) ;
2017-02-16 19:52:11 +01:00
return false ;
} ) ;
2017-07-27 04:56:14 +02:00
2017-02-16 19:52:11 +01:00
//Display Work In Progress Screen
Engine . loadWorkInProgressContent ( ) ;
}
2017-02-17 23:19:25 +01:00
PlayerObject . prototype . startFactionHackWork = function ( faction ) {
2017-05-03 19:52:54 +02:00
this . resetWorkStatus ( ) ;
2017-07-27 04:56:14 +02:00
2017-08-30 19:44:29 +02:00
this . workHackExpGainRate = . 15 * this . hacking _exp _mult * BitNodeMultipliers . FactionWorkExpGain ;
2017-09-15 16:06:59 +02:00
this . workRepGainRate = this . workRepGainRate = ( this . hacking _skill + this . intelligence ) / CONSTANTS . MaxSkillLevel * this . faction _rep _mult ;
2017-07-27 04:56:14 +02:00
2017-04-20 10:29:07 +02:00
this . factionWorkType = CONSTANTS . FactionWorkHacking ;
2017-02-17 23:19:25 +01:00
this . currentWorkFactionDescription = "carrying out hacking contracts" ;
2017-07-27 04:56:14 +02:00
2017-02-17 23:19:25 +01:00
this . startFactionWork ( faction ) ;
}
PlayerObject . prototype . startFactionFieldWork = function ( faction ) {
2017-05-03 19:52:54 +02:00
this . resetWorkStatus ( ) ;
2017-07-27 04:56:14 +02:00
2017-08-30 19:44:29 +02:00
this . workHackExpGainRate = . 1 * this . hacking _exp _mult * BitNodeMultipliers . FactionWorkExpGain ;
this . workStrExpGainRate = . 1 * this . strength _exp _mult * BitNodeMultipliers . FactionWorkExpGain ;
this . workDefExpGainRate = . 1 * this . defense _exp _mult * BitNodeMultipliers . FactionWorkExpGain ;
this . workDexExpGainRate = . 1 * this . dexterity _exp _mult * BitNodeMultipliers . FactionWorkExpGain ;
this . workAgiExpGainRate = . 1 * this . agility _exp _mult * BitNodeMultipliers . FactionWorkExpGain ;
this . workChaExpGainRate = . 1 * this . charisma _exp _mult * BitNodeMultipliers . FactionWorkExpGain ;
2017-02-17 23:19:25 +01:00
this . workRepGainRate = this . getFactionFieldWorkRepGain ( ) ;
2017-07-27 04:56:14 +02:00
2017-06-23 16:23:35 +02:00
this . factionWorkType = CONSTANTS . FactionWorkField ;
2017-02-17 23:19:25 +01:00
this . currentWorkFactionDescription = "carrying out field missions"
2017-07-27 04:56:14 +02:00
2017-02-17 23:19:25 +01:00
this . startFactionWork ( faction ) ;
}
2017-02-27 23:14:11 +01:00
PlayerObject . prototype . startFactionSecurityWork = function ( faction ) {
2017-05-03 19:52:54 +02:00
this . resetWorkStatus ( ) ;
2017-08-30 19:44:29 +02:00
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.00 * this . charisma _exp _mult * BitNodeMultipliers . FactionWorkExpGain ;
2017-04-20 10:29:07 +02:00
this . workRepGainRate = this . getFactionSecurityWorkRepGain ( ) ;
2017-07-27 04:56:14 +02:00
2017-04-20 10:29:07 +02:00
this . factionWorkType = CONSTANTS . FactionWorkSecurity ;
2017-02-17 23:19:25 +01:00
this . currentWorkFactionDescription = "performing security detail"
2017-07-27 04:56:14 +02:00
2017-02-17 23:19:25 +01:00
this . startFactionWork ( faction ) ;
}
2017-07-27 04:56:14 +02:00
2017-02-16 19:52:11 +01:00
PlayerObject . prototype . workForFaction = function ( numCycles ) {
2017-02-17 23:19:25 +01:00
var faction = Factions [ this . currentWorkFactionName ] ;
2017-07-27 04:56:14 +02:00
2017-04-20 10:29:07 +02:00
//Constantly update the rep gain rate
switch ( this . factionWorkType ) {
case CONSTANTS . FactionWorkHacking :
2017-09-15 16:06:59 +02:00
this . workRepGainRate = ( this . hacking _skill + this . intelligence ) / CONSTANTS . MaxSkillLevel * this . faction _rep _mult ;
2017-04-20 10:29:07 +02:00
break ;
case CONSTANTS . FactionWorkField :
this . workRepGainRate = this . getFactionFieldWorkRepGain ( ) ;
break ;
case CONSTANTS . FactionWorkSecurity :
this . workRepGainRate = this . getFactionSecurityWorkRepGain ( ) ;
break ;
default :
break ;
}
2017-07-27 04:56:14 +02:00
2017-06-20 18:11:33 +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 ;
2017-08-13 07:01:33 +02:00
this . workRepGainRate *= BitNodeMultipliers . FactionWorkRepGain ;
2017-07-27 04:56:14 +02:00
2018-09-05 22:36:18 +02:00
//Cap the number of cycles being processed to whatever would put you at limit (20 hours)
var overMax = false ;
if ( this . timeWorked + ( Engine . _idleSpeed * numCycles ) >= CONSTANTS . MillisecondsPer20Hours ) {
overMax = true ;
numCycles = Math . round ( ( CONSTANTS . MillisecondsPer20Hours - this . timeWorked ) / Engine . _idleSpeed ) ;
}
2017-02-16 19:52:11 +01:00
this . timeWorked += Engine . _idleSpeed * numCycles ;
2017-07-27 04:56:14 +02:00
2018-09-05 22:36:18 +02:00
this . processWorkEarnings ( numCycles ) ;
2017-02-17 23:19:25 +01:00
//If timeWorked == 20 hours, then finish. You can only work for the faction for 20 hours
2018-09-05 22:36:18 +02:00
if ( overMax || this . timeWorked >= CONSTANTS . MillisecondsPer20Hours ) {
2018-09-16 21:48:36 +02:00
return this . finishFactionWork ( false ) ;
2017-02-16 19:52:11 +01:00
}
2017-07-27 04:56:14 +02:00
2017-02-16 19:52:11 +01:00
var txt = document . getElementById ( "work-in-progress-text" ) ;
2018-02-24 23:55:06 +01:00
txt . innerHTML = "You are currently " + this . currentWorkFactionDescription + " for your faction " + faction . name +
2018-10-23 20:55:42 +02:00
" (Current Faction Reputation: " + numeralWrapper . format ( faction . playerReputation , '0,0' ) + "). <br>" +
2018-02-24 23:55:06 +01:00
"You have been doing this for " + convertTimeMsToTimeElapsedString ( this . timeWorked ) + "<br><br>" +
2017-07-27 04:56:14 +02:00
"You have earned: <br><br>" +
2018-10-23 20:55:42 +02:00
"$" + numeralWrapper . format ( this . workMoneyGained , '0,0.00' ) + " (" + numeralWrapper . format ( this . workMoneyGainRate * CYCLES _PER _SEC , '0,0.00' ) + " / sec) <br><br>" +
numeralWrapper . format ( this . workRepGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workRepGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) reputation for this faction <br><br>" +
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workHackExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) hacking exp <br><br>" +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workStrExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) strength exp <br>" +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workDefExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) defense exp <br>" +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workDexExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) dexterity exp <br>" +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workAgiExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) agility exp <br><br> " +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workChaExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) charisma exp <br><br>" +
2017-07-27 04:56:14 +02:00
"You will automatically finish after working for 20 hours. You can cancel earlier if you wish.<br>" +
"There is no penalty for cancelling earlier." ;
2017-02-16 19:52:11 +01:00
}
2018-08-30 23:51:25 +02:00
PlayerObject . prototype . finishFactionWork = function ( cancelled , sing = false ) {
var faction = Factions [ this . currentWorkFactionName ] ;
faction . playerReputation += ( this . workRepGained ) ;
this . updateSkillLevels ( ) ;
var txt = "You worked for your faction " + faction . name + " for a total of " + convertTimeMsToTimeElapsedString ( this . timeWorked ) + " <br><br> " +
"You earned a total of: <br>" +
2018-10-23 20:55:42 +02:00
"$" + numeralWrapper . format ( this . workMoneyGained , '0,0.00' ) + "<br>" +
numeralWrapper . format ( this . workRepGained , '0,0.0000' ) + " reputation for the faction <br>" +
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " hacking exp <br>" +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " strength exp <br>" +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " defense exp <br>" +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " dexterity exp <br>" +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " agility exp <br>" +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " charisma exp<br>" ;
2018-08-30 23:51:25 +02:00
if ( ! sing ) { dialogBoxCreate ( txt ) ; }
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 " +
2018-10-23 20:55:42 +02:00
numeralWrapper . format ( this . workRepGained , '0,0.0000' ) + " rep, " +
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " hacking exp, " +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " str exp, " +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " def exp, " +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " dex exp, " +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " agi exp, and " +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " cha exp." ;
2018-08-30 23:51:25 +02:00
this . resetWorkStatus ( ) ;
return res ;
}
this . resetWorkStatus ( ) ;
}
2017-02-16 19:52:11 +01:00
2017-02-06 06:01:01 +01:00
//Money gained per game cycle
2017-02-08 01:27:11 +01:00
PlayerObject . prototype . getWorkMoneyGain = function ( ) {
2018-11-16 02:28:23 +01:00
// If player has SF-11, calculate salary multiplier from favor
let bn11Mult = 1 ;
const company = Companies [ this . companyName ] ;
if ( hasBn11SF ) { bn11Mult = 1 + ( company . favor / 100 ) ; }
// Get base salary
2019-01-15 04:34:04 +01:00
const companyPositionName = this . jobs [ this . companyName ] ;
const companyPosition = CompanyPositions [ companyPositionName ] ;
2018-11-16 02:28:23 +01:00
if ( companyPosition == null ) {
2019-01-15 04:34:04 +01:00
console . error ( ` Could not find CompanyPosition object for ${ companyPositionName } . Work salary will be 0 ` ) ;
2018-11-16 02:28:23 +01:00
return 0 ;
2017-10-10 07:07:28 +02:00
}
2018-11-16 02:28:23 +01:00
return companyPosition . baseSalary * company . salaryMultiplier * this . work _money _mult * BitNodeMultipliers . CompanyWorkMoney * bn11Mult ;
2017-02-06 06:01:01 +01:00
}
//Hack exp gained per game cycle
2017-02-08 01:27:11 +01:00
PlayerObject . prototype . getWorkHackExpGain = function ( ) {
2018-11-16 02:28:23 +01:00
const company = Companies [ this . companyName ] ;
2019-01-15 04:34:04 +01:00
const companyPositionName = this . jobs [ this . companyName ] ;
const companyPosition = CompanyPositions [ companyPositionName ] ;
2018-11-16 02:28:23 +01:00
if ( company == null || companyPosition == null ) {
console . error ( [ ` Could not find Company object for ${ this . companyName } ` ,
2019-01-15 04:34:04 +01:00
` or CompanyPosition object for ${ companyPositionName } . ` ,
2018-11-16 02:28:23 +01:00
` Work hack exp gain will be 0 ` ] . join ( " " ) ) ;
return 0 ;
}
return companyPosition . hackingExpGain * company . expMultiplier * this . hacking _exp _mult * BitNodeMultipliers . CompanyWorkExpGain ;
2017-02-06 06:01:01 +01:00
}
//Str exp gained per game cycle
2017-02-08 01:27:11 +01:00
PlayerObject . prototype . getWorkStrExpGain = function ( ) {
2018-11-16 02:28:23 +01:00
const company = Companies [ this . companyName ] ;
2019-01-15 04:34:04 +01:00
const companyPositionName = this . jobs [ this . companyName ] ;
const companyPosition = CompanyPositions [ companyPositionName ] ;
2018-11-16 02:28:23 +01:00
if ( company == null || companyPosition == null ) {
console . error ( [ ` Could not find Company object for ${ this . companyName } ` ,
2019-01-15 04:34:04 +01:00
` or CompanyPosition object for ${ companyPositionName } . ` ,
2018-11-16 02:28:23 +01:00
` Work str exp gain will be 0 ` ] . join ( " " ) ) ;
return 0 ;
}
2018-11-18 01:23:48 +01:00
return companyPosition . strengthExpGain * company . expMultiplier * this . strength _exp _mult * BitNodeMultipliers . CompanyWorkExpGain ;
2017-02-06 06:01:01 +01:00
}
//Def exp gained per game cycle
2017-02-08 01:27:11 +01:00
PlayerObject . prototype . getWorkDefExpGain = function ( ) {
2018-11-16 02:28:23 +01:00
const company = Companies [ this . companyName ] ;
2019-01-15 04:34:04 +01:00
const companyPositionName = this . jobs [ this . companyName ] ;
const companyPosition = CompanyPositions [ companyPositionName ] ;
2018-11-16 02:28:23 +01:00
if ( company == null || companyPosition == null ) {
console . error ( [ ` Could not find Company object for ${ this . companyName } ` ,
2019-01-15 04:34:04 +01:00
` or CompanyPosition object for ${ companyPositionName } . ` ,
2018-11-16 02:28:23 +01:00
` Work def exp gain will be 0 ` ] . join ( " " ) ) ;
return 0 ;
}
2018-11-18 01:23:48 +01:00
return companyPosition . defenseExpGain * company . expMultiplier * this . defense _exp _mult * BitNodeMultipliers . CompanyWorkExpGain ;
2017-02-06 06:01:01 +01:00
}
//Dex exp gained per game cycle
2017-02-08 01:27:11 +01:00
PlayerObject . prototype . getWorkDexExpGain = function ( ) {
2018-11-16 02:28:23 +01:00
const company = Companies [ this . companyName ] ;
2019-01-15 04:34:04 +01:00
const companyPositionName = this . jobs [ this . companyName ] ;
const companyPosition = CompanyPositions [ companyPositionName ] ;
2018-11-16 02:28:23 +01:00
if ( company == null || companyPosition == null ) {
console . error ( [ ` Could not find Company object for ${ this . companyName } ` ,
2019-01-15 04:34:04 +01:00
` or CompanyPosition object for ${ companyPositionName } . ` ,
2018-11-16 02:28:23 +01:00
` Work dex exp gain will be 0 ` ] . join ( " " ) ) ;
return 0 ;
}
2018-11-18 01:23:48 +01:00
return companyPosition . dexterityExpGain * company . expMultiplier * this . dexterity _exp _mult * BitNodeMultipliers . CompanyWorkExpGain ;
2017-02-06 06:01:01 +01:00
}
//Agi exp gained per game cycle
2017-02-08 01:27:11 +01:00
PlayerObject . prototype . getWorkAgiExpGain = function ( ) {
2018-11-16 02:28:23 +01:00
const company = Companies [ this . companyName ] ;
2019-01-15 04:34:04 +01:00
const companyPositionName = this . jobs [ this . companyName ] ;
const companyPosition = CompanyPositions [ companyPositionName ] ;
2018-11-16 02:28:23 +01:00
if ( company == null || companyPosition == null ) {
console . error ( [ ` Could not find Company object for ${ this . companyName } ` ,
2019-01-15 04:34:04 +01:00
` or CompanyPosition object for ${ companyPositionName } . ` ,
2018-11-16 02:28:23 +01:00
` Work agi exp gain will be 0 ` ] . join ( " " ) ) ;
return 0 ;
}
2018-11-18 01:23:48 +01:00
return companyPosition . agilityExpGain * company . expMultiplier * this . agility _exp _mult * BitNodeMultipliers . CompanyWorkExpGain ;
2017-02-06 06:01:01 +01:00
}
2017-02-16 19:52:11 +01:00
//Charisma exp gained per game cycle
PlayerObject . prototype . getWorkChaExpGain = function ( ) {
2018-11-16 02:28:23 +01:00
const company = Companies [ this . companyName ] ;
2019-01-15 04:34:04 +01:00
const companyPositionName = this . jobs [ this . companyName ] ;
const companyPosition = CompanyPositions [ companyPositionName ] ;
2018-11-16 02:28:23 +01:00
if ( company == null || companyPosition == null ) {
console . error ( [ ` Could not find Company object for ${ this . companyName } ` ,
2019-01-15 04:34:04 +01:00
` or CompanyPosition object for ${ companyPositionName } . ` ,
2018-11-16 02:28:23 +01:00
` Work cha exp gain will be 0 ` ] . join ( " " ) ) ;
return 0 ;
}
2018-11-18 01:23:48 +01:00
return companyPosition . charismaExpGain * company . expMultiplier * this . charisma _exp _mult * BitNodeMultipliers . CompanyWorkExpGain ;
2017-02-16 19:52:11 +01:00
}
2017-02-06 06:01:01 +01:00
//Reputation gained per game cycle
2017-02-08 01:27:11 +01:00
PlayerObject . prototype . getWorkRepGain = function ( ) {
2018-11-16 02:28:23 +01:00
const company = Companies [ this . companyName ] ;
2019-01-15 04:34:04 +01:00
const companyPositionName = this . jobs [ this . companyName ] ;
const companyPosition = CompanyPositions [ companyPositionName ] ;
2018-11-16 02:28:23 +01:00
if ( company == null || companyPosition == null ) {
console . error ( [ ` Could not find Company object for ${ this . companyName } ` ,
2019-01-15 04:34:04 +01:00
` or CompanyPosition object for ${ companyPositionName } . ` ,
2018-11-16 02:28:23 +01:00
` Work rep gain will be 0 ` ] . join ( " " ) ) ;
return 0 ;
}
2018-11-18 01:23:48 +01:00
var jobPerformance = companyPosition . calculateJobPerformance ( this . hacking _skill , this . strength ,
this . defense , this . dexterity ,
this . agility , this . charisma ) ;
2017-09-15 16:06:59 +02:00
//Intelligence provides a flat bonus to job performance
jobPerformance += ( this . intelligence / CONSTANTS . MaxSkillLevel ) ;
2017-06-20 18:11:33 +02:00
//Update reputation gain rate to account for company favor
var favorMult = 1 + ( company . favor / 100 ) ;
2018-11-16 02:28:23 +01:00
if ( isNaN ( favorMult ) ) { favorMult = 1 ; }
2017-07-27 04:56:14 +02:00
return jobPerformance * this . company _rep _mult * favorMult ;
2017-02-17 23:19:25 +01:00
}
PlayerObject . prototype . getFactionSecurityWorkRepGain = function ( ) {
2017-07-27 04:56:14 +02:00
var t = 0.9 * ( this . hacking _skill / CONSTANTS . MaxSkillLevel +
this . strength / CONSTANTS . MaxSkillLevel +
this . defense / CONSTANTS . MaxSkillLevel +
this . dexterity / CONSTANTS . MaxSkillLevel +
2017-10-15 03:55:41 +02:00
this . agility / CONSTANTS . MaxSkillLevel ) / 4.5 ;
2017-02-17 23:19:25 +01:00
return t * this . faction _rep _mult ;
}
PlayerObject . prototype . getFactionFieldWorkRepGain = function ( ) {
2017-07-27 04:56:14 +02:00
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 +
2017-09-15 16:06:59 +02:00
this . charisma / CONSTANTS . MaxSkillLevel +
2017-10-15 03:55:41 +02:00
this . intelligence / CONSTANTS . MaxSkillLevel ) / 5.5 ;
2017-02-17 23:19:25 +01:00
return t * this . faction _rep _mult ;
2017-02-06 06:01:01 +01:00
}
2017-03-31 14:32:04 +02:00
/* Creating a Program */
2017-05-17 16:23:47 +02:00
PlayerObject . prototype . startCreateProgramWork = function ( programName , time , reqLevel ) {
2017-05-03 19:52:54 +02:00
this . resetWorkStatus ( ) ;
2017-03-31 14:32:04 +02:00
this . isWorking = true ;
2017-04-24 21:10:35 +02:00
this . workType = CONSTANTS . WorkTypeCreateProgram ;
2017-07-27 04:56:14 +02:00
2017-05-17 16:23:47 +02:00
//Time needed to complete work affected by hacking skill (linearly based on
//ratio of (your skill - required level) to MAX skill)
2017-09-15 16:06:59 +02:00
//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 ;
2017-07-27 04:56:14 +02:00
2017-09-15 16:06:59 +02:00
this . timeNeededToCompleteWork = time ;
2017-06-23 16:23:35 +02:00
//Check for incomplete program
2017-09-15 16:06:59 +02:00
for ( var i = 0 ; i < this . getHomeComputer ( ) . programs . length ; ++ i ) {
var programFile = this . getHomeComputer ( ) . programs [ i ] ;
2017-06-23 16:23:35 +02:00
if ( programFile . startsWith ( programName ) && programFile . endsWith ( "%-INC" ) ) {
var res = programFile . split ( "-" ) ;
if ( res . length != 3 ) { break ; }
var percComplete = Number ( res [ 1 ] . slice ( 0 , - 1 ) ) ;
2017-06-24 23:33:44 +02:00
if ( isNaN ( percComplete ) || percComplete < 0 || percComplete >= 100 ) { break ; }
2017-09-15 16:06:59 +02:00
this . timeWorkedCreateProgram = percComplete / 100 * this . timeNeededToCompleteWork ;
this . getHomeComputer ( ) . programs . splice ( i , 1 ) ;
2017-06-23 16:23:35 +02:00
}
}
2017-07-27 04:56:14 +02:00
2017-03-31 23:47:06 +02:00
this . createProgramName = programName ;
2017-07-27 04:56:14 +02:00
2017-05-16 05:06:25 +02:00
var cancelButton = clearEventListeners ( "work-in-progress-cancel-button" ) ;
cancelButton . innerHTML = "Cancel work on creating program" ;
cancelButton . addEventListener ( "click" , function ( ) {
2017-08-30 19:44:29 +02:00
Player . finishCreateProgramWork ( true ) ;
2017-03-31 14:32:04 +02:00
return false ;
} ) ;
2017-07-27 04:56:14 +02:00
2017-03-31 14:32:04 +02:00
//Display Work In Progress Screen
Engine . loadWorkInProgressContent ( ) ;
}
2017-03-31 23:47:06 +02:00
PlayerObject . prototype . createProgramWork = function ( numCycles ) {
2017-09-15 16:06:59 +02:00
//Higher hacking skill will allow you to create programs faster
var reqLvl = this . createProgramReqLvl ;
var skillMult = ( this . hacking _skill / reqLvl ) ; //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 ) ;
2017-03-31 23:47:06 +02:00
var programName = this . createProgramName ;
2017-07-27 04:56:14 +02:00
2017-09-15 16:06:59 +02:00
if ( this . timeWorkedCreateProgram >= this . timeNeededToCompleteWork ) {
2017-08-30 19:44:29 +02:00
this . finishCreateProgramWork ( false ) ;
2017-03-31 23:47:06 +02:00
}
2017-07-27 04:56:14 +02:00
2017-03-31 23:47:06 +02:00
var txt = document . getElementById ( "work-in-progress-text" ) ;
2017-07-27 04:56:14 +02:00
txt . innerHTML = "You are currently working on coding " + programName + ".<br><br> " +
2017-03-31 23:47:06 +02:00
"You have been working for " + convertTimeMsToTimeElapsedString ( this . timeWorked ) + "<br><br>" +
2017-09-15 16:06:59 +02:00
"The program is " + ( this . timeWorkedCreateProgram / this . timeNeededToCompleteWork * 100 ) . toFixed ( 2 ) + "% complete. <br>" +
2017-07-27 04:56:14 +02:00
"If you cancel, your work will be saved and you can come back to complete the program later." ;
2017-03-31 14:32:04 +02:00
}
2017-08-30 19:44:29 +02:00
PlayerObject . prototype . finishCreateProgramWork = function ( cancelled , sing = false ) {
var programName = this . createProgramName ;
if ( cancelled === false ) {
2017-07-27 04:56:14 +02:00
dialogBoxCreate ( "You've finished creating " + programName + "!<br>" +
2017-03-31 23:47:06 +02:00
"The new program can be found on your home computer." ) ;
2017-07-27 04:56:14 +02:00
2017-09-15 16:06:59 +02:00
this . getHomeComputer ( ) . programs . push ( programName ) ;
2017-06-23 16:23:35 +02:00
} else {
2018-05-07 04:21:36 +02:00
var perc = ( Math . floor ( this . timeWorkedCreateProgram / this . timeNeededToCompleteWork * 10000 ) / 100 ) . toString ( ) ;
2017-06-23 16:23:35 +02:00
var incompleteName = programName + "-" + perc + "%-INC" ;
2017-09-15 16:06:59 +02:00
this . getHomeComputer ( ) . programs . push ( incompleteName ) ;
2017-03-31 23:47:06 +02:00
}
2017-07-27 04:56:14 +02:00
2017-09-25 14:50:19 +02:00
if ( ! cancelled ) {
this . gainIntelligenceExp ( this . createProgramReqLvl / CONSTANTS . IntelligenceProgramBaseExpGain ) ;
}
2017-09-15 16:06:59 +02:00
2017-03-31 23:47:06 +02:00
var mainMenu = document . getElementById ( "mainmenu-container" ) ;
mainMenu . style . visibility = "visible" ;
2017-07-27 04:56:14 +02:00
2017-09-15 16:06:59 +02:00
this . isWorking = false ;
2017-07-27 04:56:14 +02:00
2017-03-31 23:47:06 +02:00
Engine . loadTerminalContent ( ) ;
2018-03-03 22:05:33 +01:00
this . resetWorkStatus ( ) ;
2017-03-31 14:32:04 +02:00
}
2017-04-24 21:10:35 +02:00
/* Studying/Taking Classes */
PlayerObject . prototype . startClass = function ( costMult , expMult , className ) {
2017-05-03 19:52:54 +02:00
this . resetWorkStatus ( ) ;
2017-04-24 21:10:35 +02:00
this . isWorking = true ;
this . workType = CONSTANTS . WorkTypeStudyClass ;
2017-07-27 04:56:14 +02:00
2017-04-24 21:10:35 +02:00
this . className = className ;
2017-07-27 04:56:14 +02:00
2017-04-24 21:10:35 +02:00
var gameCPS = 1000 / Engine . _idleSpeed ;
2017-07-27 04:56:14 +02:00
2017-05-10 23:21:45 +02:00
//Base exp gains per second
2017-08-01 21:03:45 +02:00
var baseStudyComputerScienceExp = 0.5 ;
var baseDataStructuresExp = 1 ;
var baseNetworksExp = 2 ;
var baseAlgorithmsExp = 4 ;
var baseManagementExp = 2 ;
var baseLeadershipExp = 4 ;
2017-07-05 18:49:01 +02:00
var baseGymExp = 1 ;
2017-07-27 04:56:14 +02:00
2017-04-24 21:10:35 +02:00
//Find cost and exp gain per game cycle
2017-05-10 19:42:46 +02:00
var cost = 0 ;
var hackExp = 0 , strExp = 0 , defExp = 0 , dexExp = 0 , agiExp = 0 , chaExp = 0 ;
2017-04-24 21:10:35 +02:00
switch ( className ) {
case CONSTANTS . ClassStudyComputerScience :
hackExp = baseStudyComputerScienceExp * expMult / gameCPS ;
break ;
case CONSTANTS . ClassDataStructures :
2017-05-08 16:33:26 +02:00
cost = CONSTANTS . ClassDataStructuresBaseCost * costMult / gameCPS ;
2017-04-24 21:10:35 +02:00
hackExp = baseDataStructuresExp * expMult / gameCPS ;
break ;
case CONSTANTS . ClassNetworks :
2017-07-27 04:56:14 +02:00
cost = CONSTANTS . ClassNetworksBaseCost * costMult / gameCPS ;
2017-04-24 21:10:35 +02:00
hackExp = baseNetworksExp * expMult / gameCPS ;
break ;
case CONSTANTS . ClassAlgorithms :
2017-05-08 16:33:26 +02:00
cost = CONSTANTS . ClassAlgorithmsBaseCost * costMult / gameCPS ;
2017-04-24 21:10:35 +02:00
hackExp = baseAlgorithmsExp * expMult / gameCPS ;
break ;
2017-04-25 21:14:01 +02:00
case CONSTANTS . ClassManagement :
2017-05-08 16:33:26 +02:00
cost = CONSTANTS . ClassManagementBaseCost * costMult / gameCPS ;
2017-04-25 21:14:01 +02:00
chaExp = baseManagementExp * expMult / gameCPS ;
break ;
case CONSTANTS . ClassLeadership :
2017-05-08 16:33:26 +02:00
cost = CONSTANTS . ClassLeadershipBaseCost * costMult / gameCPS ;
2017-04-25 21:14:01 +02:00
chaExp = baseLeadershipExp * expMult / gameCPS ;
break ;
2017-05-10 19:42:46 +02:00
case CONSTANTS . ClassGymStrength :
cost = CONSTANTS . ClassGymBaseCost * costMult / gameCPS ;
strExp = baseGymExp * expMult / gameCPS ;
break ;
case CONSTANTS . ClassGymDefense :
cost = CONSTANTS . ClassGymBaseCost * costMult / gameCPS ;
defExp = baseGymExp * expMult / gameCPS ;
break ;
case CONSTANTS . ClassGymDexterity :
cost = CONSTANTS . ClassGymBaseCost * costMult / gameCPS ;
dexExp = baseGymExp * expMult / gameCPS ;
break ;
case CONSTANTS . ClassGymAgility :
cost = CONSTANTS . ClassGymBaseCost * costMult / gameCPS ;
agiExp = baseGymExp * expMult / gameCPS ;
break ;
2017-04-24 21:10:35 +02:00
default :
2017-09-12 01:31:42 +02:00
throw new Error ( "ERR: Invalid/unrecognized class name" ) ;
2017-04-24 21:10:35 +02:00
return ;
}
2017-07-27 04:56:14 +02:00
2017-04-25 21:14:01 +02:00
this . workMoneyLossRate = cost ;
2017-08-30 19:44:29 +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 ; ;
2017-07-27 04:56:14 +02:00
2017-05-16 05:06:25 +02:00
var cancelButton = clearEventListeners ( "work-in-progress-cancel-button" ) ;
2017-07-27 04:56:14 +02:00
if ( className == CONSTANTS . ClassGymStrength ||
className == CONSTANTS . ClassGymDefense ||
className == CONSTANTS . ClassGymDexterity ||
2017-05-16 05:06:25 +02:00
className == CONSTANTS . ClassGymAgility ) {
cancelButton . innerHTML = "Stop training at gym" ;
} else {
cancelButton . innerHTML = "Stop taking course" ;
}
cancelButton . addEventListener ( "click" , function ( ) {
2017-04-24 21:10:35 +02:00
Player . finishClass ( ) ;
return false ;
} ) ;
2017-07-27 04:56:14 +02:00
2017-04-24 21:10:35 +02:00
//Display Work In Progress Screen
Engine . loadWorkInProgressContent ( ) ;
}
PlayerObject . prototype . takeClass = function ( numCycles ) {
this . timeWorked += Engine . _idleSpeed * numCycles ;
var className = this . className ;
2017-07-27 04:56:14 +02:00
2018-09-05 22:36:18 +02:00
this . processWorkEarnings ( numCycles ) ;
2017-07-27 04:56:14 +02:00
2017-04-24 21:10:35 +02:00
var txt = document . getElementById ( "work-in-progress-text" ) ;
2017-05-15 21:11:40 +02:00
txt . innerHTML = "You have been " + className + " for " + convertTimeMsToTimeElapsedString ( this . timeWorked ) + "<br><br>" +
2017-07-27 04:56:14 +02:00
"This has cost you: <br>" +
2018-10-23 20:55:42 +02:00
"$" + numeralWrapper . format ( this . workMoneyGained , '0,0.00' ) + " ($" + numeralWrapper . format ( this . workMoneyLossRate * CYCLES _PER _SEC , '0,0.00' ) + " / sec) <br><br>" +
2017-07-27 04:56:14 +02:00
"You have gained: <br>" +
2018-10-23 20:55:42 +02:00
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workHackExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) hacking exp <br>" +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workStrExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) strength exp <br>" +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workDefExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) defense exp <br>" +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workDexExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) dexterity exp <br>" +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workAgiExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) agility exp <br>" +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " (" + numeralWrapper . format ( this . workChaExpGainRate * CYCLES _PER _SEC , '0,0.0000' ) + " / sec) charisma exp <br>" +
2017-07-27 04:56:14 +02:00
"You may cancel at any time" ;
2017-04-24 21:10:35 +02:00
}
2017-08-21 18:59:06 +02:00
//The 'sing' argument defines whether or not this function was called
//through a Singularity Netscript function
PlayerObject . prototype . finishClass = function ( sing = false ) {
2017-09-26 04:44:33 +02:00
this . gainIntelligenceExp ( CONSTANTS . IntelligenceClassBaseExpGain * Math . round ( this . timeWorked / 1000 ) ) ;
2017-07-27 04:56:14 +02:00
2017-04-24 21:10:35 +02:00
if ( this . workMoneyGained > 0 ) {
throw new Error ( "ERR: Somehow gained money while taking class" ) ;
}
2017-07-27 04:56:14 +02:00
2017-04-24 21:10:35 +02:00
this . updateSkillLevels ( ) ;
var txt = "After " + this . className + " for " + convertTimeMsToTimeElapsedString ( this . timeWorked ) + ", <br>" +
2018-10-23 20:55:42 +02:00
"you spent a total of $" + numeralWrapper . format ( this . workMoneyGained * - 1 , '0,0.00' ) + ". <br><br>" +
2017-07-27 04:56:14 +02:00
"You earned a total of: <br>" +
2018-10-23 20:55:42 +02:00
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " hacking exp <br>" +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " strength exp <br>" +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " defense exp <br>" +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " dexterity exp <br>" +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " agility exp <br>" +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " charisma exp<br>" ;
2017-08-21 18:59:06 +02:00
if ( ! sing ) { dialogBoxCreate ( txt ) ; }
2017-07-27 04:56:14 +02:00
2017-04-24 21:10:35 +02:00
var mainMenu = document . getElementById ( "mainmenu-container" ) ;
mainMenu . style . visibility = "visible" ;
2017-07-27 04:56:14 +02:00
2017-04-24 21:10:35 +02:00
this . isWorking = false ;
2017-07-27 04:56:14 +02:00
2017-05-04 07:05:48 +02:00
Engine . loadLocationContent ( ) ;
2018-03-03 22:05:33 +01:00
if ( sing ) {
var res = "After " + this . className + " for " + convertTimeMsToTimeElapsedString ( this . timeWorked ) + ", " +
2018-10-23 20:55:42 +02:00
"you spent a total of $" + numeralWrapper . format ( this . workMoneyGained * - 1 , '0,0.00' ) + ". " +
2017-08-21 18:59:06 +02:00
"You earned a total of: " +
2018-10-23 20:55:42 +02:00
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " hacking exp, " +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " strength exp, " +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " defense exp, " +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " dexterity exp, " +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " agility exp, and " +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " charisma exp" ;
2018-03-03 22:05:33 +01:00
this . resetWorkStatus ( ) ;
return res ;
}
this . resetWorkStatus ( ) ;
2017-04-24 21:10:35 +02:00
}
2017-05-03 19:52:54 +02:00
//The EXP and $ gains are hardcoded. Time is in ms
2019-01-15 04:34:04 +01:00
PlayerObject . prototype . startCrime = function ( crimeType , hackExp , strExp , defExp , dexExp , agiExp , chaExp , money , time , singParams = null ) {
this . crimeType = crimeType ;
2017-05-03 19:52:54 +02:00
this . resetWorkStatus ( ) ;
this . isWorking = true ;
this . workType = CONSTANTS . WorkTypeCrime ;
2017-07-27 04:56:14 +02:00
2017-10-12 04:00:22 +02:00
if ( singParams && singParams . workerscript ) {
this . committingCrimeThruSingFn = true ;
this . singFnCrimeWorkerScript = singParams . workerscript ;
}
2017-08-30 19:44:29 +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 ;
2017-08-13 07:01:33 +02:00
this . workMoneyGained = money * this . crime _money _mult * BitNodeMultipliers . CrimeMoney ;
2017-07-27 04:56:14 +02:00
2017-05-03 19:52:54 +02:00
this . timeNeededToCompleteWork = time ;
2017-07-27 04:56:14 +02:00
2017-05-03 19:52:54 +02:00
//Remove all old event listeners from Cancel button
2017-05-10 19:42:46 +02:00
var newCancelButton = clearEventListeners ( "work-in-progress-cancel-button" )
2017-05-16 05:06:25 +02:00
newCancelButton . innerHTML = "Cancel crime"
2017-05-03 19:52:54 +02:00
newCancelButton . addEventListener ( "click" , function ( ) {
Player . finishCrime ( true ) ;
return false ;
} ) ;
2017-07-27 04:56:14 +02:00
2017-05-03 19:52:54 +02:00
//Display Work In Progress Screen
Engine . loadWorkInProgressContent ( ) ;
}
2017-05-04 07:27:22 +02:00
PlayerObject . prototype . commitCrime = function ( numCycles ) {
2017-05-03 19:52:54 +02:00
this . timeWorked += Engine . _idleSpeed * numCycles ;
2017-07-27 04:56:14 +02:00
2017-09-15 16:06:59 +02:00
if ( this . timeWorked >= this . timeNeededToCompleteWork ) { this . finishCrime ( false ) ; return ; }
2017-07-27 04:56:14 +02:00
2017-09-15 16:06:59 +02:00
var percent = Math . round ( this . timeWorked / this . timeNeededToCompleteWork * 100 ) ;
2017-05-08 16:33:26 +02:00
var numBars = Math . round ( percent / 5 ) ;
2017-05-10 19:42:46 +02:00
if ( numBars < 0 ) { numBars = 0 ; }
if ( numBars > 20 ) { numBars = 20 ; }
2017-05-08 16:33:26 +02:00
var progressBar = "[" + Array ( numBars + 1 ) . join ( "|" ) + Array ( 20 - numBars + 1 ) . join ( " " ) + "]" ;
2017-07-27 04:56:14 +02:00
2017-05-03 19:52:54 +02:00
var txt = document . getElementById ( "work-in-progress-text" ) ;
2017-09-15 16:06:59 +02:00
txt . innerHTML = "You are attempting to " + this . crimeType + ".<br>" +
2017-07-27 04:56:14 +02:00
"Time remaining: " + convertTimeMsToTimeElapsedString ( this . timeNeededToCompleteWork - this . timeWorked ) + "<br>" +
2017-05-08 16:33:26 +02:00
progressBar . replace ( / /g , " " ) ;
2017-05-03 19:52:54 +02:00
}
PlayerObject . prototype . finishCrime = function ( cancelled ) {
2017-05-04 07:05:48 +02:00
//Determine crime success/failure
2017-05-04 07:27:22 +02:00
if ( ! cancelled ) {
2017-05-08 18:00:34 +02:00
var statusText = "" ; //TODO, unique message for each crime when you succeed
2019-02-22 03:26:28 +01:00
if ( determineCrimeSuccess ( Player , this . crimeType ) ) {
2017-05-04 09:05:43 +02:00
//Handle Karma and crime statistics
2018-05-29 22:36:52 +02:00
let crime = null ;
for ( const i in Crimes ) {
if ( Crimes [ i ] . type == this . crimeType ) {
crime = Crimes [ i ] ;
2017-05-04 09:05:43 +02:00
break ;
2018-05-29 22:36:52 +02:00
}
}
if ( crime == null ) {
console . log ( this . crimeType ) ;
dialogBoxCreate ( "ERR: Unrecognized crime type. This is probably a bug please contact the developer" ) ;
}
2019-02-22 03:26:28 +01:00
Player . gainMoney ( this . workMoneyGained ) ;
Player . recordMoneySource ( this . workMoneyGained , "crime" ) ;
2018-05-29 22:36:52 +02:00
this . karma -= crime . karma ;
this . numPeopleKilled += crime . kills ;
if ( crime . intelligence _exp > 0 ) {
this . gainIntelligenceExp ( crime . intelligence _exp ) ;
2017-05-04 09:05:43 +02:00
}
2017-07-27 04:56:14 +02:00
2017-05-04 07:27:22 +02:00
//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 ;
2017-10-12 04:00:22 +02:00
if ( this . committingCrimeThruSingFn ) {
2018-05-06 05:59:55 +02:00
if ( this . singFnCrimeWorkerScript . disableLogs . ALL == null && this . singFnCrimeWorkerScript . disableLogs . commitCrime == null ) {
this . singFnCrimeWorkerScript . scriptRef . log ( "Crime successful! Gained " +
2018-09-12 17:53:08 +02:00
numeralWrapper . format ( this . workMoneyGained , "$0.000a" ) + ", " +
2018-10-23 20:55:42 +02:00
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " hack exp, " +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " str exp, " +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " def exp, " +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " dex exp, " +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " agi exp, " +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " cha exp." ) ;
2018-05-06 05:59:55 +02:00
}
2017-10-12 04:00:22 +02:00
} else {
dialogBoxCreate ( "Crime successful! <br><br>" +
"You gained:<br>" +
2018-10-23 20:55:42 +02:00
"$" + numeralWrapper . format ( this . workMoneyGained , '0,0.00' ) + "<br>" +
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " hacking experience <br>" +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " strength experience<br>" +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " defense experience<br>" +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " dexterity experience<br>" +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " agility experience<br>" +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " charisma experience" ) ;
2017-10-12 04:00:22 +02:00
}
2017-07-27 04:56:14 +02:00
2017-05-04 07:27:22 +02:00
} else {
2017-09-26 04:44:33 +02:00
//Exp halved on failure
this . workHackExpGained /= 2 ;
this . workStrExpGained /= 2 ;
this . workDefExpGained /= 2 ;
this . workDexExpGained /= 2 ;
this . workAgiExpGained /= 2 ;
this . workChaExpGained /= 2 ;
2017-10-12 04:00:22 +02:00
if ( this . committingCrimeThruSingFn ) {
2018-05-06 05:59:55 +02:00
if ( this . singFnCrimeWorkerScript . disableLogs . ALL == null && this . singFnCrimeWorkerScript . disableLogs . commitCrime == null ) {
this . singFnCrimeWorkerScript . scriptRef . log ( "Crime failed! Gained " +
2018-10-23 20:55:42 +02:00
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " hack exp, " +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " str exp, " +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " def exp, " +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " dex exp, " +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " agi exp, " +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " cha exp." ) ;
2018-05-06 05:59:55 +02:00
}
2017-10-12 04:00:22 +02:00
} else {
dialogBoxCreate ( "Crime failed! <br><br>" +
"You gained:<br>" +
2018-10-23 20:55:42 +02:00
numeralWrapper . format ( this . workHackExpGained , '0,0.0000' ) + " hacking experience <br>" +
numeralWrapper . format ( this . workStrExpGained , '0,0.0000' ) + " strength experience<br>" +
numeralWrapper . format ( this . workDefExpGained , '0,0.0000' ) + " defense experience<br>" +
numeralWrapper . format ( this . workDexExpGained , '0,0.0000' ) + " dexterity experience<br>" +
numeralWrapper . format ( this . workAgiExpGained , '0,0.0000' ) + " agility experience<br>" +
numeralWrapper . format ( this . workChaExpGained , '0,0.0000' ) + " charisma experience" ) ;
2017-10-12 04:00:22 +02:00
}
2017-05-04 07:27:22 +02:00
}
2017-07-27 04:56:14 +02:00
2018-09-05 22:36:18 +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 ) ;
2017-05-04 07:05:48 +02:00
}
2017-10-12 04:00:22 +02:00
this . committingCrimeThruSingFn = false ;
this . singFnCrimeWorkerScript = null ;
2017-05-03 19:52:54 +02:00
var mainMenu = document . getElementById ( "mainmenu-container" ) ;
mainMenu . style . visibility = "visible" ;
this . isWorking = false ;
2018-03-03 22:05:33 +01:00
this . resetWorkStatus ( ) ;
2017-05-04 07:05:48 +02:00
Engine . loadLocationContent ( ) ;
2017-05-03 19:52:54 +02:00
}
2017-08-21 18:59:06 +02:00
//Cancels the player's current "work" assignment and gives the proper rewards
//Used only for Singularity functions, so no popups are created
PlayerObject . prototype . singularityStopWork = function ( ) {
2017-09-01 16:12:40 +02:00
if ( ! this . isWorking ) { return "" ; }
2017-08-30 19:44:29 +02:00
var res ; //Earnings text for work
2017-08-21 18:59:06 +02:00
switch ( this . workType ) {
case CONSTANTS . WorkTypeStudyClass :
2017-08-30 19:44:29 +02:00
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 , true ) ;
2017-08-21 18:59:06 +02:00
break ;
2017-10-16 04:09:49 +02:00
case CONSTANTS . WorkTypeCrime :
res = this . finishCrime ( true ) ;
break ;
2017-08-21 18:59:06 +02:00
default :
console . log ( "ERROR: Unrecognized work type" ) ;
2017-08-30 19:44:29 +02:00
return "" ;
2017-08-21 18:59:06 +02:00
}
2017-08-30 19:44:29 +02:00
return res ;
2017-08-21 18:59:06 +02:00
}
2017-07-03 21:42:11 +02:00
//Returns true if hospitalized, false otherwise
PlayerObject . prototype . takeDamage = function ( amt ) {
2019-02-20 09:42:27 +01:00
if ( typeof amt !== "number" ) {
console . warn ( ` Player.takeDamage() called without a numeric argument: ${ amt } ` ) ;
return ;
}
2017-07-03 21:42:11 +02:00
this . hp -= amt ;
if ( this . hp <= 0 ) {
this . hospitalize ( ) ;
return true ;
} else {
return false ;
}
2017-06-28 22:53:12 +02:00
}
2019-02-20 09:42:27 +01:00
PlayerObject . prototype . regenerateHp = function ( amt ) {
if ( typeof amt !== "number" ) {
console . warn ( ` Player.regenerateHp() called without a numeric argument: ${ amt } ` ) ;
return ;
}
this . hp += amt ;
if ( this . hp > this . max _hp ) { this . hp = this . max _hp ; }
}
2017-06-28 22:53:12 +02:00
PlayerObject . prototype . hospitalize = function ( ) {
2018-08-12 07:39:37 +02:00
if ( Settings . SuppressHospitalizationPopup === false ) {
dialogBoxCreate (
"You were in critical condition! You were taken to the hospital where " +
"luckily they were able to save your life. You were charged " +
2018-09-12 17:53:08 +02:00
numeralWrapper . format ( this . max _hp * CONSTANTS . HospitalCostPerHp , '$0.000a' )
2018-08-12 07:39:37 +02:00
) ;
}
2018-08-23 20:51:57 +02:00
2017-09-15 16:06:59 +02:00
this . loseMoney ( this . max _hp * CONSTANTS . HospitalCostPerHp ) ;
2017-07-03 21:42:11 +02:00
this . hp = this . max _hp ;
2017-06-28 22:53:12 +02:00
}
2017-08-30 19:44:29 +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
PlayerObject . prototype . applyForJob = function ( entryPosType , sing = false ) {
2018-11-16 02:28:23 +01:00
// Get current company and job
let currCompany = null ;
if ( this . companyName !== "" ) {
2017-08-30 19:44:29 +02:00
currCompany = Companies [ this . companyName ] ;
}
2019-01-15 04:34:04 +01:00
const currPositionName = this . jobs [ this . companyName ] ;
2018-11-16 02:28:23 +01:00
// Get company that's being applied to
const company = Companies [ this . location ] ; //Company being applied to
if ( ! ( company instanceof Company ) ) {
if ( sing ) {
return "ERROR: Invalid company name: " + this . location + ". applyToCompany() failed" ;
} else {
console . error ( ` Could not find company that matches the location: ${ this . location } . Player.applyToCompany() failed ` ) ;
return ;
}
2017-08-30 19:44:29 +02:00
}
2018-11-16 02:28:23 +01:00
let pos = entryPosType ;
2017-08-30 19:44:29 +02:00
if ( ! this . isQualified ( company , pos ) ) {
var reqText = getJobRequirementText ( company , pos ) ;
if ( sing ) { return false ; }
dialogBoxCreate ( "Unforunately, you do not qualify for this position<br>" + reqText ) ;
return ;
}
while ( true ) {
2018-11-16 02:28:23 +01:00
let newPos = getNextCompanyPosition ( pos ) ;
2017-08-30 19:44:29 +02:00
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 ;
}
}
//Check if the determined job is the same as the player's current job
2018-11-16 02:28:23 +01:00
if ( currCompany != null ) {
if ( currCompany . name == company . name && pos . name == currPositionName ) {
2017-08-30 19:44:29 +02:00
var nextPos = getNextCompanyPosition ( pos ) ;
if ( nextPos == null ) {
if ( sing ) { return false ; }
dialogBoxCreate ( "You are already at the highest position for your field! No promotion available" ) ;
} else if ( company . hasPosition ( nextPos ) ) {
if ( sing ) { return false ; }
var reqText = getJobRequirementText ( company , nextPos ) ;
dialogBoxCreate ( "Unfortunately, you do not qualify for a promotion<br>" + reqText ) ;
} else {
if ( sing ) { return false ; }
dialogBoxCreate ( "You are already at the highest position for your field! No promotion available" ) ;
}
return ; //Same job, do nothing
}
}
2018-11-16 02:28:23 +01:00
this . companyName = company . name ;
2019-01-15 04:34:04 +01:00
this . jobs [ company . name ] = pos . name ;
2017-09-01 18:59:11 +02:00
2018-11-01 19:18:32 +01:00
document . getElementById ( "world-menu-header" ) . click ( ) ;
document . getElementById ( "world-menu-header" ) . click ( ) ;
2017-09-01 18:59:11 +02:00
2019-01-15 04:34:04 +01:00
if ( sing ) { return true ; }
dialogBoxCreate ( "Congratulations! You were offered a new job at " + this . companyName + " as a " + pos . name + "!" ) ;
2017-08-30 19:44:29 +02:00
Engine . loadLocationContent ( ) ;
}
//Returns your next position at a company given the field (software, business, etc.)
PlayerObject . prototype . getNextCompanyPosition = function ( company , entryPosType ) {
var currCompany = null ;
2018-11-18 01:23:48 +01:00
if ( this . companyName !== "" ) {
currCompany = Companies [ this . companyName ] ;
2017-08-30 19:44:29 +02:00
}
//Not employed at this company, so return the entry position
2018-11-16 02:28:23 +01:00
if ( currCompany == null || ( currCompany . name != company . name ) ) {
2017-08-30 19:44:29 +02:00
return entryPosType ;
}
//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.
2019-01-15 04:34:04 +01:00
const currentPositionName = this . jobs [ this . companyName ] ;
const currentPosition = CompanyPositions [ currentPositionName ] ;
2018-11-16 02:28:23 +01:00
if ( ( currentPosition . isSoftwareJob ( ) && entryPosType . isSoftwareJob ( ) ) ||
( currentPosition . isITJob ( ) && entryPosType . isITJob ( ) ) ||
( currentPosition . isBusinessJob ( ) && entryPosType . isBusinessJob ( ) ) ||
( currentPosition . isSecurityEngineerJob ( ) && entryPosType . isSecurityEngineerJob ( ) ) ||
( currentPosition . isNetworkEngineerJob ( ) && entryPosType . isNetworkEngineerJob ( ) ) ||
( currentPosition . isSecurityJob ( ) && entryPosType . isSecurityJob ( ) ) ||
( currentPosition . isAgentJob ( ) && entryPosType . isAgentJob ( ) ) ||
( currentPosition . isSoftwareConsultantJob ( ) && entryPosType . isSoftwareConsultantJob ( ) ) ||
( currentPosition . isBusinessConsultantJob ( ) && entryPosType . isBusinessConsultantJob ( ) ) ||
( currentPosition . isPartTimeJob ( ) && entryPosType . isPartTimeJob ( ) ) ) {
return getNextCompanyPosition ( currentPosition ) ;
2017-08-30 19:44:29 +02:00
}
return entryPosType ;
}
PlayerObject . prototype . applyForSoftwareJob = function ( sing = false ) {
2018-11-16 04:45:03 +01:00
return this . applyForJob ( CompanyPositions [ posNames . SoftwareCompanyPositions [ 0 ] ] , sing ) ;
2017-08-30 19:44:29 +02:00
}
PlayerObject . prototype . applyForSoftwareConsultantJob = function ( sing = false ) {
2018-11-16 04:45:03 +01:00
return this . applyForJob ( CompanyPositions [ posNames . SoftwareConsultantCompanyPositions [ 0 ] ] , sing ) ;
2017-08-30 19:44:29 +02:00
}
PlayerObject . prototype . applyForItJob = function ( sing = false ) {
2018-11-16 04:45:03 +01:00
return this . applyForJob ( CompanyPositions [ posNames . ITCompanyPositions [ 0 ] ] , sing ) ;
2017-08-30 19:44:29 +02:00
}
PlayerObject . prototype . applyForSecurityEngineerJob = function ( sing = false ) {
var company = Companies [ this . location ] ; //Company being applied to
2018-11-16 04:45:03 +01:00
if ( this . isQualified ( company , CompanyPositions [ posNames . SecurityEngineerCompanyPositions [ 0 ] ] ) ) {
return this . applyForJob ( CompanyPositions [ posNames . SecurityEngineerCompanyPositions [ 0 ] ] , sing ) ;
2017-08-30 19:44:29 +02:00
} else {
if ( sing ) { return false ; }
dialogBoxCreate ( "Unforunately, you do not qualify for this position" ) ;
}
}
PlayerObject . prototype . applyForNetworkEngineerJob = function ( sing = false ) {
var company = Companies [ this . location ] ; //Company being applied to
2018-11-16 04:45:03 +01:00
if ( this . isQualified ( company , CompanyPositions [ posNames . NetworkEngineerCompanyPositions [ 0 ] ] ) ) {
return this . applyForJob ( CompanyPositions [ posNames . NetworkEngineerCompanyPositions [ 0 ] ] , sing ) ;
2017-08-30 19:44:29 +02:00
} else {
if ( sing ) { return false ; }
dialogBoxCreate ( "Unforunately, you do not qualify for this position" ) ;
}
}
PlayerObject . prototype . applyForBusinessJob = function ( sing = false ) {
2018-11-16 04:45:03 +01:00
return this . applyForJob ( CompanyPositions [ posNames . BusinessCompanyPositions [ 0 ] ] , sing ) ;
2017-08-30 19:44:29 +02:00
}
PlayerObject . prototype . applyForBusinessConsultantJob = function ( sing = false ) {
2018-11-16 04:45:03 +01:00
return this . applyForJob ( CompanyPositions [ posNames . BusinessConsultantCompanyPositions [ 0 ] ] , sing ) ;
2017-08-30 19:44:29 +02:00
}
PlayerObject . prototype . applyForSecurityJob = function ( sing = false ) {
2018-11-16 04:45:03 +01:00
// TODO Police Jobs
// Indexing starts at 2 because 0 is for police officer
return this . applyForJob ( CompanyPositions [ posNames . SecurityCompanyPositions [ 2 ] ] , sing ) ;
2017-08-30 19:44:29 +02:00
}
PlayerObject . prototype . applyForAgentJob = function ( sing = false ) {
var company = Companies [ this . location ] ; //Company being applied to
2018-11-16 04:45:03 +01:00
if ( this . isQualified ( company , CompanyPositions [ posNames . AgentCompanyPositions [ 0 ] ] ) ) {
return this . applyForJob ( CompanyPositions [ posNames . AgentCompanyPositions [ 0 ] ] , sing ) ;
2017-08-30 19:44:29 +02:00
} else {
if ( sing ) { return false ; }
dialogBoxCreate ( "Unforunately, you do not qualify for this position" ) ;
}
}
PlayerObject . prototype . applyForEmployeeJob = function ( sing = false ) {
var company = Companies [ this . location ] ; //Company being applied to
2018-11-16 04:45:03 +01:00
if ( this . isQualified ( company , CompanyPositions [ posNames . MiscCompanyPositions [ 1 ] ] ) ) {
2018-11-18 01:23:48 +01:00
this . companyName = company . name ;
2019-01-15 04:34:04 +01:00
this . jobs [ company . name ] = posNames . MiscCompanyPositions [ 1 ] ;
2018-11-01 19:18:32 +01:00
document . getElementById ( "world-menu-header" ) . click ( ) ;
document . getElementById ( "world-menu-header" ) . click ( ) ;
2017-08-30 19:44:29 +02:00
if ( sing ) { return true ; }
dialogBoxCreate ( "Congratulations, you are now employed at " + this . companyName ) ;
Engine . loadLocationContent ( ) ;
} else {
if ( sing ) { return false ; }
dialogBoxCreate ( "Unforunately, you do not qualify for this position" ) ;
}
}
PlayerObject . prototype . applyForPartTimeEmployeeJob = function ( sing = false ) {
var company = Companies [ this . location ] ; //Company being applied to
2018-11-16 04:45:03 +01:00
if ( this . isQualified ( company , CompanyPositions [ posNames . PartTimeCompanyPositions [ 1 ] ] ) ) {
2018-11-18 01:23:48 +01:00
this . companyName = company . name ;
2019-01-15 04:34:04 +01:00
this . jobs [ company . name ] = posNames . PartTimeCompanyPositions [ 1 ] ;
2018-11-01 19:18:32 +01:00
document . getElementById ( "world-menu-header" ) . click ( ) ;
document . getElementById ( "world-menu-header" ) . click ( ) ;
2017-08-30 19:44:29 +02:00
if ( sing ) { return true ; }
dialogBoxCreate ( "Congratulations, you are now employed part-time at " + this . companyName ) ;
Engine . loadLocationContent ( ) ;
} else {
if ( sing ) { return false ; }
dialogBoxCreate ( "Unforunately, you do not qualify for this position" ) ;
}
}
PlayerObject . prototype . applyForWaiterJob = function ( sing = false ) {
var company = Companies [ this . location ] ; //Company being applied to
2018-11-16 04:45:03 +01:00
if ( this . isQualified ( company , CompanyPositions [ posNames . MiscCompanyPositions [ 0 ] ] ) ) {
2018-11-18 01:23:48 +01:00
this . companyName = company . name ;
2019-01-15 04:34:04 +01:00
this . jobs [ company . name ] = posNames . MiscCompanyPositions [ 0 ] ;
2018-11-01 19:18:32 +01:00
document . getElementById ( "world-menu-header" ) . click ( ) ;
document . getElementById ( "world-menu-header" ) . click ( ) ;
2017-08-30 19:44:29 +02:00
if ( sing ) { return true ; }
dialogBoxCreate ( "Congratulations, you are now employed as a waiter at " + this . companyName ) ;
Engine . loadLocationContent ( ) ;
} else {
if ( sing ) { return false ; }
dialogBoxCreate ( "Unforunately, you do not qualify for this position" ) ;
}
}
PlayerObject . prototype . applyForPartTimeWaiterJob = function ( sing = false ) {
var company = Companies [ this . location ] ; //Company being applied to
2018-11-16 04:45:03 +01:00
if ( this . isQualified ( company , CompanyPositions [ posNames . PartTimeCompanyPositions [ 0 ] ] ) ) {
2018-11-18 01:23:48 +01:00
this . companyName = company . name ;
2019-01-15 04:34:04 +01:00
this . jobs [ company . name ] = posNames . PartTimeCompanyPositions [ 0 ] ;
2018-11-01 19:18:32 +01:00
document . getElementById ( "world-menu-header" ) . click ( ) ;
document . getElementById ( "world-menu-header" ) . click ( ) ;
2017-08-30 19:44:29 +02:00
if ( sing ) { return true ; }
dialogBoxCreate ( "Congratulations, you are now employed as a part-time waiter at " + this . companyName ) ;
Engine . loadLocationContent ( ) ;
} else {
if ( sing ) { return false ; }
dialogBoxCreate ( "Unforunately, you do not qualify for this position" ) ;
}
}
//Checks if the Player is qualified for a certain position
PlayerObject . prototype . isQualified = function ( company , position ) {
var offset = company . jobStatReqOffset ;
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 ;
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 ;
}
/********** Reapplying Augmentations and Source File ***********/
PlayerObject . prototype . reapplyAllAugmentations = function ( resetMultipliers = true ) {
console . log ( "Re-applying augmentations" ) ;
if ( resetMultipliers ) {
this . resetMultipliers ( ) ;
}
for ( let i = 0 ; i < this . augmentations . length ; ++ i ) {
//Compatibility with new version
2018-02-24 23:55:06 +01:00
if ( this . augmentations [ i ] . name === "HacknetNode NIC Architecture Neural-Upload" ) {
this . augmentations [ i ] . name = "Hacknet Node NIC Architecture Neural-Upload" ;
2017-08-30 19:44:29 +02:00
}
2018-10-23 20:55:42 +02:00
const augName = this . augmentations [ i ] . name ;
2017-08-30 19:44:29 +02:00
var aug = Augmentations [ augName ] ;
if ( aug == null ) {
2018-10-23 20:55:42 +02:00
console . log ( ` WARNING: Invalid augmentation name in Player.reapplyAllAugmentations(). Aug ${ augName } will be skipped ` ) ;
2017-08-30 19:44:29 +02:00
continue ;
}
2018-02-24 23:55:06 +01:00
aug . owned = true ;
2017-08-30 19:44:29 +02:00
if ( aug . name == AugmentationNames . NeuroFluxGovernor ) {
for ( let j = 0 ; j < aug . level ; ++ j ) {
applyAugmentation ( this . augmentations [ i ] , true ) ;
}
continue ;
}
applyAugmentation ( this . augmentations [ i ] , true ) ;
}
}
PlayerObject . prototype . reapplyAllSourceFiles = function ( ) {
console . log ( "Re-applying source files" ) ;
//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 . log ( "ERROR: Invalid source file number: " + this . sourceFiles [ i ] . n ) ;
continue ;
}
applySourceFile ( this . sourceFiles [ i ] ) ;
}
}
/*************** 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
PlayerObject . prototype . checkForFactionInvitations = function ( ) {
2018-08-29 17:12:33 +02:00
let invitedFactions = [ ] ; //Array which will hold all Factions the player should be invited to
2017-08-30 19:44:29 +02:00
var numAugmentations = this . augmentations . length ;
2019-01-15 04:34:04 +01:00
const allCompanies = Object . keys ( this . jobs ) ;
const allPositions = Object . values ( this . jobs ) ;
2019-02-24 04:02:57 +01: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 ;
} else {
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
function checkMegacorpRequirements ( companyName , repNeeded = CONSTANTS . CorpFactionRepRequirement ) {
return allCompanies . includes ( companyName ) && ( getCompanyRep ( companyName ) > repNeeded ) ;
}
2017-08-30 19:44:29 +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 &&
2019-02-14 03:08:18 +01:00
numAugmentations >= Math . round ( 30 * BitNodeMultipliers . DaedalusAugsRequirement ) &&
2017-08-30 19:44:29 +02:00
this . money . gte ( 100000000000 ) &&
( this . hacking _skill >= 2500 ||
( this . strength >= 1500 && this . defense >= 1500 &&
this . dexterity >= 1500 && this . agility >= 1500 ) ) ) {
invitedFactions . push ( daedalusFac ) ;
}
//The Covenant
var covenantFac = Factions [ "The Covenant" ] ;
if ( ! covenantFac . isBanned && ! covenantFac . isMember && ! covenantFac . alreadyInvited &&
2019-02-14 03:08:18 +01:00
numAugmentations >= 20 &&
2017-08-30 19:44:29 +02:00
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 &&
2019-02-24 04:02:57 +01:00
checkMegacorpRequirements ( Locations . AevumECorp ) ) {
2017-08-30 19:44:29 +02:00
invitedFactions . push ( ecorpFac ) ;
}
//MegaCorp
var megacorpFac = Factions [ "MegaCorp" ] ;
if ( ! megacorpFac . isBanned && ! megacorpFac . isMember && ! megacorpFac . alreadyInvited &&
2019-02-24 04:02:57 +01:00
checkMegacorpRequirements ( Locations . Sector12MegaCorp ) ) {
2017-08-30 19:44:29 +02:00
invitedFactions . push ( megacorpFac ) ;
}
//Bachman & Associates
var bachmanandassociatesFac = Factions [ "Bachman & Associates" ] ;
if ( ! bachmanandassociatesFac . isBanned && ! bachmanandassociatesFac . isMember &&
! bachmanandassociatesFac . alreadyInvited &&
2019-02-24 04:02:57 +01:00
checkMegacorpRequirements ( Locations . AevumBachmanAndAssociates ) ) {
2017-08-30 19:44:29 +02:00
invitedFactions . push ( bachmanandassociatesFac ) ;
}
//Blade Industries
var bladeindustriesFac = Factions [ "Blade Industries" ] ;
if ( ! bladeindustriesFac . isBanned && ! bladeindustriesFac . isMember && ! bladeindustriesFac . alreadyInvited &&
2019-02-24 04:02:57 +01:00
checkMegacorpRequirements ( Locations . Sector12BladeIndustries ) ) {
2017-08-30 19:44:29 +02:00
invitedFactions . push ( bladeindustriesFac ) ;
}
//NWO
var nwoFac = Factions [ "NWO" ] ;
if ( ! nwoFac . isBanned && ! nwoFac . isMember && ! nwoFac . alreadyInvited &&
2019-02-24 04:02:57 +01:00
checkMegacorpRequirements ( Locations . VolhavenNWO ) ) {
2017-08-30 19:44:29 +02:00
invitedFactions . push ( nwoFac ) ;
}
//Clarke Incorporated
var clarkeincorporatedFac = Factions [ "Clarke Incorporated" ] ;
if ( ! clarkeincorporatedFac . isBanned && ! clarkeincorporatedFac . isMember && ! clarkeincorporatedFac . alreadyInvited &&
2019-02-24 04:02:57 +01:00
checkMegacorpRequirements ( Locations . AevumClarkeIncorporated ) ) {
2017-08-30 19:44:29 +02:00
invitedFactions . push ( clarkeincorporatedFac ) ;
}
//OmniTek Incorporated
var omnitekincorporatedFac = Factions [ "OmniTek Incorporated" ] ;
if ( ! omnitekincorporatedFac . isBanned && ! omnitekincorporatedFac . isMember && ! omnitekincorporatedFac . alreadyInvited &&
2019-02-24 04:02:57 +01:00
checkMegacorpRequirements ( Locations . VolhavenOmniTekIncorporated ) ) {
2017-08-30 19:44:29 +02:00
invitedFactions . push ( omnitekincorporatedFac ) ;
}
//Four Sigma
var foursigmaFac = Factions [ "Four Sigma" ] ;
if ( ! foursigmaFac . isBanned && ! foursigmaFac . isMember && ! foursigmaFac . alreadyInvited &&
2019-02-24 04:02:57 +01:00
checkMegacorpRequirements ( Locations . Sector12FourSigma ) ) {
2017-08-30 19:44:29 +02:00
invitedFactions . push ( foursigmaFac ) ;
}
//KuaiGong International
var kuaigonginternationalFac = Factions [ "KuaiGong International" ] ;
if ( ! kuaigonginternationalFac . isBanned && ! kuaigonginternationalFac . isMember &&
! kuaigonginternationalFac . alreadyInvited &&
2019-02-24 04:02:57 +01:00
checkMegacorpRequirements ( Locations . ChongqingKuaiGongInternational ) ) {
2017-08-30 19:44:29 +02:00
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" ] ;
var fulcrumSecretServer = AllServers [ SpecialServerIps [ SpecialServerNames . FulcrumSecretTechnologies ] ] ;
if ( fulcrumSecretServer == null ) {
console . log ( "ERROR: Could not find Fulcrum Secret Technologies Server" ) ;
} else {
if ( ! fulcrumsecrettechonologiesFac . isBanned && ! fulcrumsecrettechonologiesFac . isMember &&
! fulcrumsecrettechonologiesFac . alreadyInvited &&
fulcrumSecretServer . manuallyHacked &&
2019-02-24 04:02:57 +01:00
checkMegacorpRequirements ( Locations . AevumFulcrumTechnologies , 250e3 ) ) {
2017-08-30 19:44:29 +02:00
invitedFactions . push ( fulcrumsecrettechonologiesFac ) ;
}
}
//BitRunners
var bitrunnersFac = Factions [ "BitRunners" ] ;
var homeComp = this . getHomeComputer ( ) ;
var bitrunnersServer = AllServers [ SpecialServerIps [ SpecialServerNames . BitRunnersServer ] ] ;
if ( bitrunnersServer == null ) {
console . log ( "ERROR: Could not find BitRunners Server" ) ;
} else if ( ! bitrunnersFac . isBanned && ! bitrunnersFac . isMember && bitrunnersServer . manuallyHacked &&
! bitrunnersFac . alreadyInvited && this . hacking _skill >= 500 && homeComp . maxRam >= 128 ) {
invitedFactions . push ( bitrunnersFac ) ;
}
//The Black Hand
var theblackhandFac = Factions [ "The Black Hand" ] ;
var blackhandServer = AllServers [ SpecialServerIps [ SpecialServerNames . TheBlackHandServer ] ] ;
if ( blackhandServer == null ) {
console . log ( "ERROR: Could not find The Black Hand Server" ) ;
} else if ( ! theblackhandFac . isBanned && ! theblackhandFac . isMember && blackhandServer . manuallyHacked &&
! theblackhandFac . alreadyInvited && this . hacking _skill >= 350 && homeComp . maxRam >= 64 ) {
invitedFactions . push ( theblackhandFac ) ;
}
//NiteSec
var nitesecFac = Factions [ "NiteSec" ] ;
var nitesecServer = AllServers [ SpecialServerIps [ SpecialServerNames . NiteSecServer ] ] ;
if ( nitesecServer == null ) {
console . log ( "ERROR: Could not find NiteSec Server" ) ;
} else if ( ! nitesecFac . isBanned && ! nitesecFac . isMember && nitesecServer . manuallyHacked &&
! nitesecFac . alreadyInvited && this . hacking _skill >= 200 && homeComp . maxRam >= 32 ) {
invitedFactions . push ( nitesecFac ) ;
}
//Chongqing
var chongqingFac = Factions [ "Chongqing" ] ;
if ( ! chongqingFac . isBanned && ! chongqingFac . isMember && ! chongqingFac . alreadyInvited &&
this . money . gte ( 20000000 ) && this . city == Locations . Chongqing ) {
invitedFactions . push ( chongqingFac ) ;
}
//Sector-12
var sector12Fac = Factions [ "Sector-12" ] ;
if ( ! sector12Fac . isBanned && ! sector12Fac . isMember && ! sector12Fac . alreadyInvited &&
this . money . gte ( 15000000 ) && this . city == Locations . Sector12 ) {
invitedFactions . push ( sector12Fac ) ;
}
//New Tokyo
var newtokyoFac = Factions [ "New Tokyo" ] ;
if ( ! newtokyoFac . isBanned && ! newtokyoFac . isMember && ! newtokyoFac . alreadyInvited &&
this . money . gte ( 20000000 ) && this . city == Locations . NewTokyo ) {
invitedFactions . push ( newtokyoFac ) ;
}
//Aevum
var aevumFac = Factions [ "Aevum" ] ;
if ( ! aevumFac . isBanned && ! aevumFac . isMember && ! aevumFac . alreadyInvited &&
this . money . gte ( 40000000 ) && this . city == Locations . Aevum ) {
invitedFactions . push ( aevumFac ) ;
}
//Ishima
var ishimaFac = Factions [ "Ishima" ] ;
if ( ! ishimaFac . isBanned && ! ishimaFac . isMember && ! ishimaFac . alreadyInvited &&
this . money . gte ( 30000000 ) && this . city == Locations . Ishima ) {
invitedFactions . push ( ishimaFac ) ;
}
//Volhaven
var volhavenFac = Factions [ "Volhaven" ] ;
if ( ! volhavenFac . isBanned && ! volhavenFac . isMember && ! volhavenFac . alreadyInvited &&
this . money . gte ( 50000000 ) && this . city == Locations . 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 &&
2019-01-15 04:34:04 +01:00
this . karma <= - 45 && ! allCompanies . includes ( Locations . Sector12CIA ) &&
! allCompanies . includes ( Locations . Sector12NSA ) ) {
2017-08-30 19:44:29 +02:00
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 == Locations . Chongqing &&
2019-01-15 04:34:04 +01:00
this . numPeopleKilled >= 5 && this . karma <= - 45 && ! allCompanies . includes ( Locations . Sector12CIA ) &&
! allCompanies . includes ( Locations . Sector12NSA ) ) {
2017-08-30 19:44:29 +02:00
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 == Locations . Aevum || this . city == Locations . Sector12 ) &&
this . money . gte ( 10000000 ) && this . karma <= - 90 &&
2019-01-15 04:34:04 +01:00
! allCompanies . includes ( Locations . Sector12CIA ) && ! allCompanies . includes ( Locations . Sector12NSA ) ) {
2017-08-30 19:44:29 +02:00
invitedFactions . push ( thesyndicateFac ) ;
}
//Silhouette
var silhouetteFac = Factions [ "Silhouette" ] ;
if ( ! silhouetteFac . isBanned && ! silhouetteFac . isMember && ! silhouetteFac . alreadyInvited &&
2019-01-15 04:34:04 +01:00
( allPositions . includes ( "Chief Technology Officer" ) ||
allPositions . includes ( "Chief Financial Officer" ) ||
allPositions . includes ( "Chief Executive Officer" ) ) &&
2017-08-30 19:44:29 +02:00
this . money . gte ( 15000000 ) && this . karma <= - 22 ) {
invitedFactions . push ( silhouetteFac ) ;
}
//Tetrads
var tetradsFac = Factions [ "Tetrads" ] ;
if ( ! tetradsFac . isBanned && ! tetradsFac . isMember && ! tetradsFac . alreadyInvited &&
( this . city == Locations . Chongqing || this . city == Locations . NewTokyo ||
this . city == Locations . Ishima ) && 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 ;
2017-09-15 16:06:59 +02:00
for ( var i = 0 ; i < this . hacknetNodes . length ; ++ i ) {
totalHacknetLevels += this . hacknetNodes [ i ] . level ;
totalHacknetRam += this . hacknetNodes [ i ] . ram ;
totalHacknetCores += this . hacknetNodes [ i ] . cores ;
2017-08-30 19:44:29 +02:00
}
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 &&
( this . city == Locations . Chongqing || this . city == Locations . NewTokyo ||
this . city == Locations . Ishima ) ) {
invitedFactions . push ( tiandihuiFac ) ;
}
//CyberSec
var cybersecFac = Factions [ "CyberSec" ] ;
var cybersecServer = AllServers [ SpecialServerIps [ SpecialServerNames . CyberSecServer ] ] ;
if ( cybersecServer == null ) {
console . log ( "ERROR: Could not find CyberSec Server" ) ;
} else if ( ! cybersecFac . isBanned && ! cybersecFac . isMember && cybersecServer . manuallyHacked &&
! cybersecFac . alreadyInvited && this . hacking _skill >= 50 ) {
invitedFactions . push ( cybersecFac ) ;
}
return invitedFactions ;
}
/*************** Gang ****************/
//Returns true if Player is in a gang and false otherwise
PlayerObject . prototype . inGang = function ( ) {
if ( this . gang == null || this . gang == undefined ) { return false ; }
return ( this . gang instanceof Gang ) ;
}
2017-09-01 18:59:11 +02:00
PlayerObject . prototype . startGang = function ( factionName , hacking ) {
this . gang = new Gang ( factionName , hacking ) ;
}
2019-01-18 18:57:21 +01:00
/*************** Corporation ****************/
PlayerObject . prototype . hasCorporation = function ( ) {
if ( this . corporation == null ) { return false ; }
return ( this . corporation instanceof Corporation ) ;
}
/*************** Bladeburner ****************/
PlayerObject . prototype . inBladeburner = function ( ) {
if ( this . bladeburner == null ) { return false ; }
return ( this . bladeburner instanceof Bladeburner ) ;
}
2017-08-30 19:44:29 +02:00
/************* BitNodes **************/
PlayerObject . prototype . setBitNodeNumber = function ( n ) {
this . bitNodeN = n ;
}
2018-06-11 19:41:02 +02:00
PlayerObject . prototype . queueAugmentation = function ( name ) {
for ( const i in this . queuedAugmentations ) {
if ( this . queuedAugmentations [ i ] . name == name ) {
console . log ( 'tried to queue ' + name + ' twice, this may be a bug' ) ;
return ;
}
}
for ( const i in this . augmentations ) {
if ( this . augmentations [ i ] . name == name ) {
console . log ( 'tried to queue ' + name + ' but we already have that aug' ) ;
return ;
}
}
2018-07-08 02:16:58 +02:00
2018-06-12 22:44:21 +02:00
this . firstAugPurchased = true ;
2018-06-11 19:41:02 +02:00
this . queuedAugmentations . push ( new PlayerOwnedAugmentation ( name ) ) ;
}
2018-09-14 23:03:31 +02:00
/************* Coding Contracts **************/
PlayerObject . prototype . gainCodingContractReward = function ( 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 ;
2018-09-23 02:25:48 +02:00
// 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 ) {
2018-09-14 23:03:31 +02:00
if ( ! ( Factions [ facName ] instanceof Faction ) ) { continue ; }
Factions [ facName ] . playerReputation += gainPerFaction ;
}
2018-09-23 02:25:48 +02:00
return ` Gained ${ gainPerFaction } reputation for each of the following factions: ${ factions . toString ( ) } ` ;
2018-09-14 23:03:31 +02:00
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 :
2018-11-19 10:03:38 +01:00
var moneyGain = CONSTANTS . CodingContractBaseMoneyGain * difficulty * BitNodeMultipliers . CodingContractMoney ;
2018-09-14 23:03:31 +02:00
this . gainMoney ( moneyGain ) ;
2019-02-22 03:26:28 +01:00
this . recordMoneySource ( moneyGain , "codingcontract" ) ;
2018-09-14 23:03:31 +02:00
return ` Gained ${ numeralWrapper . format ( moneyGain , '$0.000a' ) } ` ;
break ;
}
/* eslint-enable no-case-declarations */
}
2017-04-24 21:10:35 +02:00
/* Functions for saving and loading the Player data */
2017-08-30 19:44:29 +02:00
function loadPlayer ( saveString ) {
Player = JSON . parse ( saveString , Reviver ) ;
//Parse Decimal.js objects
Player . money = new Decimal ( Player . money ) ;
2017-12-02 04:50:08 +01:00
if ( Player . corporation instanceof Corporation ) {
Player . corporation . funds = new Decimal ( Player . corporation . funds ) ;
Player . corporation . revenue = new Decimal ( Player . corporation . revenue ) ;
Player . corporation . expenses = new Decimal ( Player . corporation . expenses ) ;
for ( var i = 0 ; i < Player . corporation . divisions . length ; ++ i ) {
var ind = Player . corporation . divisions [ i ] ;
ind . lastCycleRevenue = new Decimal ( ind . lastCycleRevenue ) ;
ind . lastCycleExpenses = new Decimal ( ind . lastCycleExpenses ) ;
ind . thisCycleRevenue = new Decimal ( ind . thisCycleRevenue ) ;
ind . thisCycleExpenses = new Decimal ( ind . thisCycleExpenses ) ;
}
}
2017-08-30 19:44:29 +02:00
}
2016-12-01 23:18:18 +01:00
PlayerObject . prototype . toJSON = function ( ) {
return Generic _toJSON ( "PlayerObject" , this ) ;
2017-02-08 01:27:11 +01:00
}
2016-12-01 23:18:18 +01:00
PlayerObject . fromJSON = function ( value ) {
return Generic _fromJSON ( PlayerObject , value . data ) ;
2017-07-27 04:56:14 +02:00
}
2016-12-01 23:18:18 +01:00
Reviver . constructors . PlayerObject = PlayerObject ;
2017-08-30 19:44:29 +02:00
let Player = new PlayerObject ( ) ;
export { Player , loadPlayer } ;