forked from Argembarger/IdleClassAutocrat
-
Notifications
You must be signed in to change notification settings - Fork 2
/
AutocratV3.js
441 lines (428 loc) · 20.2 KB
/
AutocratV3.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
"use strict";
// The Idle Class Autocrat
// made with luv by argembarger
// v3.2.0, last tested with The Idle Class v0.6.0
// USE AT OWN RISK -- feel free to steal
// not responsible if your game gets hurt >_>
// Export Early / Export Often
// There are options! Skim through the code to see ‘em
// Settings are in the constructor right underneath these comments.
// See the very bottom of this script for the actual loop function.
//
// Instructions: just copy this entire text file (ctrl-a, ctrl-c)
// and paste it (ctrl-v) into the console, and hit enter to submit
// (Use F12 to access developer console on most browsers)
// Only paste once!
//
// IMPORTANT NOTES:
// You can change any of the below values at runtime
// through the console by inputting activeIdleClassAutocrat.<desiredStatName> = <whatever>;
// You have to re-inject this code on every refresh.
// I have observed page-cache-wrecking errors on occasion, not sure if it's this script or just me messing around while making it.
// I recommend exporting your save once in a while
// Clearing the page's cache data through the browser can restore function if your save file gets corrupted and it fails to load.
class IdleClassAutocrat {
constructor() {
// THE FOLLOWING 6 VALUES CAN BE TWEAKED TO YOUR LIKING
// FEEL FREE TO TWEAK IF YOU FEEL LIKE THINGS ARE TOO SLOW
// Especially the bankruptcy modifier...
// Early on, a higher employee/upgrade spend may be desirable.
this.autocratManageLoopMillis = 2500; // Default 2500, runs an Autocrat update every 2.5 seconds
this.autocratInnerLoopMillis = 100; // Default 100, does individual Autocrat actions every 0.1 seconds
this.upgradeSpendFraction = 1.0; // Default 1.0, willing to spend 100% on upgrades, RATIO VALUE, 0.67 = 67%
this.employeeSpendFraction = 0.999; // Default 0.999, willing to spend 99.9% on employees, RATIO VALUE, 0.67 = 67%
this.maxAllowableRisk = 0.0; // Default 0.0%, stops R&D hiring above this risk value, PERCENTAGE VALUE, 67.0 = 67%
this.acquisitionStopHiringFraction = 0.666; // Default 0.666, stops hiring acq employees at less than 66.6% workers remaining, RATIO VALUE, 0.67 = 67%
this.bankruptcyResetFraction = 1.0; // Default 1.0, makes every bankruptcy 200%, RATIO VALUE, 0.67 = 67%
// ONES WITH LISTS OF WORDS AND PHRASES CAN BE EDITED OR ADDED TO IF YOU FANCY
this.autoBusinessWords = ["ASAP", "B2B", "B2C", "BYOD", "CTR", "EBITDA", "EOD", "KPI", "ROI", "SEO", "SAAS", "accelerator", "action", "advertainment", "agile", "analytic", "bandwidth", "ballpark", "best practice", "blue sky thinking", "boot strap", "bootstrap", "brand", "bubble", "cash flow", "churn rate", "circle back", "client", "content marketing", "crowdfund", "crowdsource", "customer", "deep dive", "deliverable", "digital nomad", "disrupt", "downsiz", "drill down", "dynamism", "early adopter", "end-user", "end user", "enterprise", "equity", "evangelist", "evergreen", "executive", "exit strategy", "freemium", "gamification", "gamified", "globalization", "growth hack", "golden parachute", "hacking", "holistic", "hyperlocal", "ideat", "influencer", "innovat", "intellectual property", "invest", "iterat", "layoff", "leverage", "market", "millennial", "mission", "monetiz", "moving forward", "optimiz", "outsourc", "overhead", "paradigm", "pivot", "profit", "redundanc", "revenue", "sale", "scaleable", "share", "shareholder", "stakeholder", "startup", "stock", "synergy", "thought leader", "trim the fat", "unicorn", "valuation", "visionary", "wheelhouse", "wunderkind"];
this.autoChatPhrases = ["... Are you seriously wasting my time like this?", ", I really don't want to hear about it.", ", do you feel ready to fire your friends?", ", you put our glorious company to shame.", "!! Guess what?? You are an ass!", ", have you considered getting back to work?", ": I love hearing from you, almost as much as I hate it.", " is such a freakin tool, I mean really, they... oh ww lol!", " -- this better be good news.", ": ¯\_(ツ)_/¯", ", hold on, I'm playing this idle game called The Idle Class", ", hold on, my Trimps are just about to hit my target zone...", "!! Guess what?? Hevipelle eats ass!"];
// Shamelessly stolen from game code
this.firstNames = [ 'John', 'Jane', 'Steve', 'Bill', 'Mark', 'Sheryl', 'Larry', 'Travis', 'George', 'Marissa', 'Jeff', 'Ken', 'Dara', 'Richard' ];
this.lastNames = [ 'Smith', 'Johnson', 'Jones', 'Williams', 'Taylor', 'Singh', 'Wang', 'Sato', 'Kim', 'Tremblay', 'Rodriguez', 'Martin', 'Rossi', 'Schmidt' ];
this.currentBankruptcyStatsIndex = 38; // Current bankruptcy bonus in game.stats()[]
// THE REST BELOW SHOULDN'T NEED TO BE MESSED WITH
this.currOuterProcessHandle = 0; // Everything else is private
this.currProcess = 0; // PRIVATE
this.currProcessHandle = 0; // PRIVATE
this.currUpgrade; // STILL PRIVATE
this.currEmployee; // ETC.
this.currMail;
this.currOutgoing;
this.outgoingMailDelay = 0;
this.invBought;
this.invChecks;
this.invTargetMins;
this.invTargetMs;
this.invFoundTarget;
this.invSorted;
this.invAcquired;
this.currAcq;
this.acqCurrWorker;
this.acqCurrChat;
this.acqCurrMail;
this.autocratSelfNaming = function() {
if(game.businessName().name() !== "Unnamed Business") return;
let pastBizCheckIndex = -1;
let maxKnownBusiness = -1;
while(pastBizCheckIndex < game.pastBusinesses().length - 1) {
pastBizCheckIndex = pastBizCheckIndex + 1;
let pastBizName = game.pastBusinesses()[pastBizCheckIndex].name;
if(pastBizName.startsWith("AutoBiz#")) {
let foundBiz = parseInt(pastBizName.substr(pastBizName.indexOf("#") + 1, pastBizName.length), 10);
if(foundBiz > maxKnownBusiness) maxKnownBusiness = foundBiz;
}
}
game.businessName().newName("AutoBiz#" + (maxKnownBusiness + 1));
game.businessName().save();
}
this.randomBizWord = function() {
return this.autoBusinessWords[Math.floor(Math.random()*this.autoBusinessWords.length)];
};
this.randomDialogue = function() {
return this.autoChatPhrases[Math.floor(Math.random()*this.autoChatPhrases.length)];
};
// Shamelessly stolen from game code
this.randomName = function() {
return this.firstNames[Math.floor(Math.random() * this.firstNames.length)] + ' ' + this.lastNames[Math.floor(Math.random() * this.lastNames.length)];
};
this.autoEarnDollars = function() {
game.addManualClicks();
};
this.autoUpgrade = function() {
if(this.upgradeSpendFraction >= 1.0) {
game.buyAllUpgrades();
} else {
for(let i = 0; i < game.availableUpgrades().length; i++) {
this.currUpgrade = game.availableUpgrades()[i];
if(this.currUpgrade.price.val() < (game.currentCash.val() * this.upgradeSpendFraction)) {
this.currUpgrade.buy();
}
}
}
};
this.autoHR = function() {
// Based on currently-selected Purchase Rate.
// Try to buy first employee of each type right away, though.
for(let i = 0; i <= 11; i++) {
this.currEmployee = game.units.peek(0)[i];
if(this.currEmployee.num.val() <= 4 && (this.currEmployee.price.val() <= game.currentCash.val())) {
this.currEmployee.buy();
} else if(this.currEmployee.price.val() < (game.currentCash.val() * this.employeeSpendFraction)) {
this.currEmployee.buy();
}
}
};
this.autoMail = function() {
this.autoOutgoingMail();
// Automatically replies to emails with "<sender_name>: <string_of_biz_babble>"
for(let i = game.mail().length - 1; i >= 0; i--) {
this.currMail = game.mail()[i];
// EMAIL CHEAT: You can uncomment the following line to exploit emails
if(this.currMail.replied() === true) { continue; }
if(this.currMail.from !== "B2B B2C CTR EOD KPI ROI SEO")
{
let mailtext = this.currMail.from + " B2B B2C CTR EOD KPI ROI SEO ASAP BYOD SAAS sale agile brand ideat pivot share stock EBITDA action bubble client equity invest iterat layoff market profit disrupt downsiz hacking innovat mission";
let mailtextrim = mailtext.substring(0,200);
this.currMail.inputText(mailtextrim);
}else{
this.currMail.inputText("B2B B2C CTR EOD KPI ROI SEO ASAP BYOD SAAS sale agile brand ideat pivot share stock EBITDA action bubble client equity invest iterat layoff market profit disrupt downsiz hacking innovat mission")
}
// Uncomment to catch what these actually are in console, for funsies :)
//console.log("" + this.currMail.inputText());
this.currMail.respond();
}
};
this.autoOutgoingMail = function() {
// Send random emails to departments unless stress is above 50% (then spam to HR)
if(game.locked().outgoingMail === false && game.composedMail().resting() === false && this.outgoingMailDelay === 0) {
this.outgoingMailDelay = 1;
this.currOutgoing = game.composedMail();
if(this.currOutgoing.stressLevel.val() > 50) {
// Human Resources
this.currOutgoing.selectedDepartment('4');
} else {
// Random other. 0 = investments, 1 = r&d, 2 = acquisitions, 3 = training. R&D is available before investments.
let r = Math.random();
//check for trainings
let activeTrainings = 0;
for (let i = 0; i < game.units().length; i++)
{
if(game.units()[i].trainingActive()){
activeTrainings++;
};
};
var choice = ["1"];
// check for traing
if(activeTrainings !== 0) { choice.push("3"); }
// check for acq
if(game.activeAcquisitions().length !== 0) { choice.push("2"); }
// check for investments
if(game.activeInvestments().length !== 0) { choice.push("0"); }
this.currOutgoing.selectedDepartment(choice[Math.floor(Math.random()*choice.length)]);
r = Math.random();
this.currOutgoing.selectedUrgency((r <= 0.333) ? '1' : ((r <= 0.666) ? '0' : '2'));
}
//let rando = this.randomName();
this.currOutgoing.to("B2B B2C CTR EOD KPI ROI SEO");
this.currOutgoing.subject("B2B B2C CTR EOD KPI ROI SEO");
this.currOutgoing.message("B2B B2C CTR EOD KPI ROI SEO ASAP BYOD SAAS sale agile brand ideat pivot share stock EBITDA action bubble client equity invest iterat layoff market profit disrupt downsiz hacking innovat mission");
setTimeout(this.autoSendMail, 2000);
setTimeout(this.autoStopWaitingForMail, 5000);
}
}
this.autoSendMail = function() {
game.composedMail().send();
};
this.autoStopWaitingForMail = function() {
activeIdleClassAutocrat.outgoingMailDelay = 0;
};
this.autoScience = function() {
// Disables research to sell patents
// Assigns employees only when research disabled (no cheating!)
// You can manually disable research in-game to update employee numbers
if(game.research().patents().length > 0) {
if(game.research().active() === true) { game.research().toggleProduction(); }
else { game.research().sellPatents(); }
} else if(game.research().active() === false) {
if(game.research().risk.baseVal() <= this.maxAllowableRisk) {
let hiredSomeone = false;
if(game.research().intern() < game.units.peek(0)[0].num.val()) {
game.research().intern(parseInt(game.research().intern() + 1));
hiredSomeone = true;
}
if(game.research().wage() < game.units.peek(0)[1].num.val()) {
game.research().wage(parseInt(game.research().wage() + 1));
hiredSomeone = true;
}
// There is no need for autoselling.
//if(game.research().sales() < game.units.peek(0)[2].num.val()) {
// game.research().sales(parseInt(game.research().sales() + 1));
// hiredSomeone = true;
//}
// There is no need for storage.
//if(game.research().manager() < game.units.peek(0)[3].num.val()) {
// game.research().manager(parseInt(game.research().manager() + 1));
// hiredSomeone = true;
//}
if(hiredSomeone == false) { // Toggle production when no one to hire
game.research().toggleProduction();
}
}
else { // Toggle production when risk is reached
game.research().toggleProduction();
}
}
};
this.autoInvest = function() {
if(game.activeInvestments().length < game.simultaneousInvestments.val()) {
this.invBought = false;
this.invChecks = 0;
// Check existing investment target times, fill shortest-found slot
// Remember that target time is in milliseconds; 1 min = 60000 ms
// Desired target times by default are 1, 9, 59, 1:59, 2:59, etc...
// Desired percentages by default are based on number of slots
// 1 slot = 50%, 2 = 40%, 3 = 30%, 4 = 20%, 5+ = 10%
while(this.invBought === false) {
this.invTargetMins = 1;
this.invTargetMs = 60000;
this.invFoundTarget = false;
if(this.invChecks === 1) {
this.invTargetMins = 9;
this.invTargetMs = 9 * 60000;
}
else if(this.invChecks === 2) {
this.invTargetMins = 59;
this.invTargetMs = 59 * 60000;
}
else if(this.invChecks > 2) {
this.invTargetMins = 59 + (60 * (this.invChecks - 2));
this.invTargetMs = this.invTargetMins * 60000;
}
for(let i = 0; i < game.activeInvestments().length; i++) {
if(game.activeInvestments()[i].targetTime === this.invTargetMs) {
this.invFoundTarget = true;
}
}
if(this.invFoundTarget === true) {
this.invChecks++;
} else {
this.invBought = true;
game.makeInvestment(Math.max(60 - (game.simultaneousInvestments.val() * 10), 10), this.invTargetMins);
}
}
}
};
this.autoDivest = function() {
if(game.pendingInvestmentCount.val() > 0) {
for(let i = game.activeInvestments().length - 1; i >= 0; i--) {
// Auto Sell
if(game.activeInvestments()[i].timeRemaining() === 0) {
// Auto Acquire
if(game.locked().acquisitions === false && game.simultaneousInvestments.val() > 1 && game.activeAcquisitions().length < game.simultaneousAcquisitions.val()) {
// Only acquire investments if some better investment is not closer to completion than
// half of the finished investment's original target time.
this.invSorted = game.activeInvestments().slice();
this.invAcquired = false;
this.invSorted.sort(function(a, b){return b.targetTime - a.targetTime});
for(let j = 0; j < this.invSorted.length; j++) {
if(this.invSorted[j].targetTime === game.activeInvestments()[i].targetTime) {
this.invAcquired = true;
break;
} else if(this.invSorted[j].timeRemaining() < game.activeInvestments()[i].targetTime * 0.5) {
break;
}
}
if(this.invAcquired === false) {
game.activeInvestments()[i].handlePayout();
} else {
game.activeInvestments()[i].handleAcquisition();
}
} else if(game.pendingAcquisitionCount.val() === 0) {
// ONLY pay out if there ISN'T a currently-pending acquisition.
// If an acquisition is actively paying out, do nothing, simply wait.
game.activeInvestments()[i].handlePayout();
}
}
}
}
};
this.autoMicromanage = function() {
for (let i = game.activeAcquisitions().length - 1; i >= 0; i--) {
this.currAcq = game.activeAcquisitions()[i];
// Acquisition Clicker
this.currAcq.fire();
// Acquisition AutoAssign
if(this.currAcq.currentEmployees.val() > this.currAcq.initialEmployees * this.acquisitionStopHiringFraction) {
for(let j = 0; j < this.currAcq.workers().length; j++) {
this.acqCurrWorker = this.currAcq.workers()[j];
if(this.acqCurrWorker.price.val() < game.currentCash.val()) {
this.acqCurrWorker.hire();
}
}
}
// Acquisition AutoChat
// The cleanest way to handle these is by using the document elements.
for(let j = this.currAcq.chats().length - 1; j >= 0; j--) {
this.acqCurrChat = this.currAcq.chats()[j];
if(this.acqCurrChat.finished() === true) {
this.acqCurrChat.close();
} else if(this.acqCurrChat.messages().length > 0 && this.acqCurrChat.messages()[this.acqCurrChat.messages().length - 1].source !== "You") {
this.acqCurrChat.select();
document.getElementById('chat-response').value = this.acqCurrChat.name + this.randomDialogue();
document.getElementsByClassName("chat-submit")[0].click();
}
}
// Acquisition AutoPolicy
for(let j = this.currAcq.mail().length - 1; j >= 0; j--) {
this.acqCurrMail = this.currAcq.mail()[j];
if(this.acqCurrMail.replied() === true) { continue; }
this.acqCurrMail.inputText(this.acqCurrMail.from + ",");
while(this.acqCurrMail.inputText().length < 180) {
this.acqCurrMail.inputText(this.acqCurrMail.inputText() + " " + this.randomBizWord());
}
this.acqCurrMail.respond();
}
// Acquisition Sell
if(this.currAcq.sold() === false && this.currAcq.currentEmployees.val() === 0) {
this.currAcq.sell();
}
}
};
this.autoUntilEmails = function() {
this.autoEarnDollars();
this.autoUpgrade();
this.autoHR();
};
this.autoUntilResearchAndDevelopment = function() {
this.autoEarnDollars();
this.autoUpgrade();
this.autoHR();
this.autoMail();
};
this.autoUntilInvestments = function() {
this.autoEarnDollars();
this.autoUpgrade();
this.autoHR();
this.autoMail();
this.autoScience();
};
this.autoUntilAcquisitions = function() {
this.autoEarnDollars();
this.autoUpgrade();
this.autoHR();
this.autoMail();
this.autoScience();
this.autoInvest();
this.autoDivest();
};
this.autoUntilBankruptcy = function() {
this.autoEarnDollars();
this.autoUpgrade();
this.autoHR();
this.autoMail();
this.autoScience();
this.autoInvest();
this.autoDivest();
this.autoMicromanage();
};
// Function to manage state of autocratInnerLoopMillis inner loop
this.autoAutocrat = function() { // fractionOfCurrentBankruptcyBonus
this.autocratSelfNaming();
switch(this.currProcess) {
case 0: // Not running; new Autocrat state. Clear any existing loop and start pre-email loop.
this.currProcess = 1;
if(this.currProcessHandle !== 0) { clearInterval(this.currProcessHandle); }
this.currProcessHandle = setInterval(this.autoUntilEmails.bind(this), this.autocratInnerLoopMillis);
break;
case 1: // Wait for emails before changing loop to pre-R&D loop.
if(game.locked().mail === true) { break; }
this.currProcess = 2;
clearInterval(this.currProcessHandle);
this.currProcessHandle = setInterval(this.autoUntilResearchAndDevelopment.bind(this), this.autocratInnerLoopMillis);
break;
case 2: // Wait for R&D before changing loop to pre-Investments loop.
if(game.locked().research === true) { break; }
this.currProcess = 3;
clearInterval(this.currProcessHandle);
this.currProcessHandle = setInterval(this.autoUntilInvestments.bind(this), this.autocratInnerLoopMillis);
break;
case 3: // Wait for Investments before changing loop to pre-Acquisitions loop.
if(game.locked().investments === true) { break; }
this.currProcess = 4;
clearInterval(this.currProcessHandle);
this.currProcessHandle = setInterval(this.autoUntilAcquisitions.bind(this), this.autocratInnerLoopMillis);
break;
case 4: // Wait for Acquisitions before changing loop to pre-Bankruptcy loop
if(game.locked().acquisitions === true) { break; }
this.currProcess = 5;
clearInterval(this.currProcessHandle);
this.currProcessHandle = setInterval(this.autoUntilBankruptcy.bind(this), this.autocratInnerLoopMillis);
break;
case 5: // Wait until bankruptcy, then wait for conditions, before declaring bankruptcy and restarting loop.
if(game.locked().mail === true) { this.currProcess = 0; break; }
if(game.locked().bankruptcy === true) { break; }
if(game.nextBankruptcyBonus.val() > game.stats[this.currentBankruptcyStatsIndex].val() * this.bankruptcyResetFraction) {
this.currProcess = 0;
game.restartGame();
}
break;
default:
this.currProcess = 0;
}
};
// Function to lazily kick off autocratManageLoopMillis outer loop
this.autoAutoAutocrat = function() {
if(this.currOuterProcessHandle !== 0) { clearInterval(this.currOuterProcessHandle); }
this.currOuterProcessHandle = setInterval(this.autoAutocrat.bind(this), this.autocratManageLoopMillis);
};
}
// Static function to super-lazily kick off The Autocrat
static autoAutoAutoAutocrat() {
var newlyBirthedAutocrat = new IdleClassAutocrat();
newlyBirthedAutocrat.autoAutoAutocrat();
return newlyBirthedAutocrat;
}
}
// Actually kicks off the Autocrat.
var activeIdleClassAutocrat = IdleClassAutocrat.autoAutoAutoAutocrat();