-
Notifications
You must be signed in to change notification settings - Fork 3
/
trackResources.user.js
641 lines (594 loc) · 23.4 KB
/
trackResources.user.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
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
// ==UserScript==
// @name MQO Resource Tracker
// @namespace https://github.com/trigunshin/miden_quest
// @description MQO resource tracker; need to run clearTSResults() to reset tile% after moving
// @homepage https://trigunshin.github.com/miden_quest
// @version 28
// @downloadURL http://trigunshin.github.io/miden_quest/trackResources.user.js
// @updateURL http://trigunshin.github.io/miden_quest/trackResources.user.js
// @include http://midenquest.com/Game.aspx
// @include http://www.midenquest.com/Game.aspx
// @include https://www.midenquest.com/Game.aspx
// @grant GM_log
// ==/UserScript==
/*
INSTRUCTIONS
Copy/paste the entire script into console & hit enter. It should track gather rates (%) for Gathering, Fishing,
Mining and Woodcutting. It will update the results after every gather; please note that this will never give
exact values, and you should probably wait for 500-1000+ attempts on a tile to draw conclusions.
To reset the values (necessary if you move tiles) you can copy/paste the whole script again or just enter
this into the console: "clearTSResults();". For tampermonkey this will require the "Tampermonkey" frame
option instead of the "Top" frame option at the top-left part of the console.
This *should* be compatible with Ryalane's script if Ryalane's script loads first.
TODO
fix data_reset in tampermonkey?
//*/
// preferences; data is still tracked, this only affects output
var outputItems = true;
var outputTaxes = true;
var outputTiers = true;
var outputQuests = true;
var outputPerks = true;
var printItemDrops = true;
var outputToConsole = false;
var saveLogText = false;
var logText = [];
var tsXPRegex = /(\d+) skill exp/;
var questItemRegex = /(\d+) \/ (\d+)/;
var itemDropCountRegex = /^\[.+\] Found (\d+)/;
var scoutRelicRegex = / (\d+) relics/;
var resourceListId = 'resourceLogList';
var normalAverageMultiplier = 60/5*60;
var quadAverageMultiplier = 60/3*60*4;
// results aren't stored under the resource because we aren't tracking tile changes/types
var tsResults = {
actions: 0,
xp: 0,
taxedActions: 0,
items: 0,
questActive: false,
questActions: 0,
questItems: 0,
keyInfo: {
// total key drops are tracked under tsResults.iteminfo.keyDrop
pendingKeys: 0,
currentKeys: 0,
single: 0,
double: 0,
triple: 0,
init: false
},
1: {drop: 0, total: 0, gained: 0, taxed: 0},
2: {drop: 0, total: 0, gained: 0, taxed: 0},
3: {drop: 0, total: 0, gained: 0, taxed: 0},
4: {drop: 0, total: 0, gained: 0, taxed: 0},
5: {drop: 0, total: 0, gained: 0, taxed: 0},
lumber:{
items: ['Pine', 'Oak', 'Maple', 'Ironwood', 'Yggdrasil'],
tracker: [/(\d+) Pine/, /(\d+) Oak/, /(\d+) Maple/, /(\d+) Ironwood/, /(\d+) Yggdrasil/]
},
ore: {
items: ['Iron', 'Silver', 'Obsidian', 'Mythril', 'Ethernium'],
tracker: [/(\d+) Iron/, /(\d+) Silver/, /(\d+) Obsidian/, /(\d+) Mythril/, /(\d+) Ethernium/]
},
plant: {
items: ['Plant Stem', 'Cotton', 'Living Leather', 'Silver Vine', 'Nimbus Fruit'],
tracker: [/(\d+) Plant Stem/, /(\d+) Cotton/, /(\d+) Living Leather/, /(\d+) Silver Vine/, /(\d+) Nimbus Fruit/]
},
fish: {
items: ['Tuna', 'Salmon', 'Flyfish', 'Marlin', 'Dragonfish'],
tracker: [/(\d+) Tuna/, /(\d+) Salmon/, /(\d+) Flyfish/, /(\d+) Marlin/, /(\d+) Dragonfish/]
},
sales: {
tracker: /(\d+) gold/,
total: 0,
taxed: 0,
gained: 0
},
scouts: {
tracker: /(\d+) landmark/,
total: 0,
taxed: 0,
gained: 0,
relicGained: 0,
relicDouble: 0,
relicDrop: 0,
relicTaxedCount: 0,
relicTaxed: 0
},
itemInfo: {
equipDrop: 0,
resourceBagDrop: 0,
keyDrop: 0,
magicElementsDrop: 0,
magicElementsTotal: 0,
goldDrop: 0,
goldTotal: 0,
gemDrop: 0,
relicDrop: 0,
relicTotal: 0,
relicDouble: 0
},
perks: {
enraged: 0,
hoarder: 0,
drunken: 0,
// drunken is not currently taxed, but keep this form so we can re-use the same function as the main TS
1: {drop: 0, total: 0, gained: 0, taxed: 0},
2: {drop: 0, total: 0, gained: 0, taxed: 0},
3: {drop: 0, total: 0, gained: 0, taxed: 0},
4: {drop: 0, total: 0, gained: 0, taxed: 0},
5: {drop: 0, total: 0, gained: 0, taxed: 0},
sales: {
total: 0,
taxed: 0,
gained: 0,
drunken: 0
},
scouts: {
total: 0,
taxed: 0,
gained: 0,
drunken: 0
}
}
};
function clearTSResults() {
console.info('clearing results');
tsResults.actions = 0;
tsResults.items = 0;
tsResults.questActive = false;
tsResults.questActions = 0;
tsResults.questItems = 0;
tsResults.taxedActions = 0;
tsResults.itemInfo = {
equipDrop: 0,
resourceBagDrop: 0,
keyDrop: 0,
magicElementsDrop: 0,
magicElementsTotal: 0,
goldDrop: 0,
goldTotal: 0,
gemDrop: 0,
relicDrop: 0,
relicTotal: 0,
relicDouble: 0
};
tsResults.keyInfo = {
pendingKeys: 0,
currentKeys: 0,
single: 0,
double: 0,
triple: 0,
init: false
};
tsResults.xp = 0;
tsResults.sales.total = 0;
tsResults.sales.taxed = 0;
tsResults.sales.gained = 0;
tsResults.scouts.total = 0;
tsResults.scouts.taxed = 0;
tsResults.scouts.gained = 0;
tsResults.scouts.relicTaxed = 0;
tsResults.scouts.relicTaxedCount = 0;
tsResults.scouts.relicGained = 0;
tsResults.scouts.relicDouble = 0;
tsResults.scouts.relicDrop = 0;
tsResults.perks = {
enraged: 0,
hoarder: 0,
drunken: 0
};
for(var i=1, iLen=6; i<iLen;i++) {
tsResults[i] = {drop: 0, total: 0, gained: 0, taxed: 0};
}
updateOutput(tsResults, 'data reset complete');
}
function handleQuestItem(msg) {
var matches = msg.match(questItemRegex);
var current = parseInt(matches[1]);
var total = parseInt(matches[2]);
if(current == total) {
// this message is sent after the channel2 message, so we won't lose an action here
tsResults.questActive = false;
} else {
tsResults.questActive = true;
tsResults.questItems += 1;
}
}
function handleItemDrop(msg) {
tsResults.items += 1;
if(printItemDrops) console.info(Date(), msg);
// TODO better method than this?
if(msg.indexOf('a resource bag') >= 0) tsResults.itemInfo.resourceBagDrop += 1;
else if(msg.indexOf('resource bags') >= 0) tsResults.itemInfo.resourceBagDrop += 1;
else if(msg.indexOf('resources bag') >= 0) tsResults.itemInfo.resourceBagDrop += 1;
else if(msg.indexOf('a gem') >= 0) tsResults.itemInfo.gemDrop += 1;
// these will eventually be broken out by tier as well
else if(msg.indexOf('Found Broken') >= 0) tsResults.itemInfo.equipDrop += 1;
else if(msg.indexOf('Found Basic') >= 0) tsResults.itemInfo.equipDrop += 1;
else if(msg.indexOf('Found Fine') >= 0) tsResults.itemInfo.equipDrop += 1;
else if(msg.indexOf('Found Elite') >= 0) tsResults.itemInfo.equipDrop += 1;
else if(msg.indexOf('Found Master') >= 0) tsResults.itemInfo.equipDrop += 1;
else if(msg.indexOf('key') >= 0) {
/*
Important timing note: SETKEYS| occurs *before* NLOG|3| updates with the itemlog message
SETKEYS can be called for many reasons; this uses the last value to estimate whether the last SETKEYS
was due to an item drop, as opposed to expo/purchase/naval/????.
The mechanism for this is:
setkeys overwrites this value whenever called
N - currentKeys = # added (only update if 1-3 keys)
if >3 keys or 0 keys, set to 0 keys
itemlog .indexof('key') >0 means itemlog found a key
so use the pendingKeys value to increment currentKeys as well as single|double|triple
This could be misleading if we get a sequence like:
SETKEYS|3 // from itemlog's drop%
SETKEYS|2 // from expeditions
NSLOG|You found a key // itemlog drop notification which sees a 2 instead of a 3
however this sequence seems unlikely due to expedition/purchase timing
//*/
tsResults.itemInfo.keyDrop += 1;
switch (tsResults.keyInfo.pendingKeys) {
case 1:
tsResults.keyInfo.single++;
break;
case 2:
tsResults.keyInfo.double++;
break;
case 3:
tsResults.keyInfo.triple++;
break;
}
}
else if(msg.indexOf('a relic') >= 0) {
tsResults.itemInfo.relicDrop += 1;
tsResults.itemInfo.relicTotal += 1;
} else if(msg.indexOf('relics') >= 0) {
var count = parseInt(msg.match(itemDropCountRegex)[1]);
tsResults.itemInfo.relicDrop += 1;
tsResults.itemInfo.relicTotal += count;
} else if(msg.indexOf('gold coins') >= 0) {
var count = parseInt(msg.match(itemDropCountRegex)[1]);
tsResults.itemInfo.goldDrop += 1;
tsResults.itemInfo.goldTotal += count;
} else if(msg.indexOf('magic elements') >= 0) {
var count = parseInt(msg.match(itemDropCountRegex)[1]);
tsResults.itemInfo.magicElementsDrop += 1;
tsResults.itemInfo.magicElementsTotal += count;
}
if(msg.indexOf('doubled') > -1) tsResults.itemInfo.relicDouble += 1;
// if an item drop occurred (key or otherwise) zero this out as we've already handled or ignored it
// handle this outside the if(key) block as this value can be set by any SETKEYS packet and we want to keep it clean
tsResults.keyInfo.pendingKeys = 0;
}
function parsePrimaryTS(msg, resourceInfo, tierData, tsKey, wasTaxed) {
var patterns = resourceInfo[tsKey].tracker;
var itemTypes = resourceInfo[tsKey].items;
for(var i=0,iLen=itemTypes.length;i<iLen;i++) {
if(msg.indexOf(itemTypes[i]) >= 0) {
tierData[i+1].drop += 1;
// track total/gained/taxed counts
var amt = parseInt(msg.match(patterns[i])[1]);
tierData[i+1].total += amt;
if(wasTaxed) tierData[i+1].taxed += amt;
else tierData[i+1].gained += amt;
}
}
}
function parseSales(msg, resourceInfo, resourceData, wasTaxed) {
var goldEarned = parseInt(msg.match(resourceInfo.sales.tracker)[1]);
resourceData.sales.total += goldEarned;
if(wasTaxed) resourceData.sales.taxed += goldEarned;
else resourceData.sales.gained += goldEarned;
}
function parseScouts(msg, resourceInfo, resourceData, wasTaxed) {
var marksEarned = parseInt(msg.match(resourceInfo.scouts.tracker)[1]);
resourceData.scouts.total += marksEarned;
if(wasTaxed) resourceData.scouts.taxed += marksEarned;
else resourceData.scouts.gained += marksEarned;
}
function parseScoutResourceRelic(msg) {
var count = parseInt(msg.match(scoutRelicRegex)[1]);
// not sure if this one occurs, safety first
if(msg.indexOf('a relic') >= 0) count = 1;
// relics can be taxed now
if(msg.indexOf("taxes") >=0)
tsResults.scouts.relicTaxedCount += count;
else
tsResults.scouts.relicGained += count;
// track the total relic drops for taxes/doubles
tsResults.scouts.relicDrop += 1;
if(msg.indexOf('double') >= 0) tsResults.scouts.relicDouble += 1;
if(msg.indexOf('taxes') >= 0) tsResults.scouts.relicTaxed += 1;
}
function logPerk(perk, msg) {
tsResults.perks[perk]+= 1;
if(perk === 'drunken') {
if(msg.indexOf('sold') >= 0) {
tsResults.perks.sales.drunken += 1;
parseSales(msg, tsResults, tsResults.perks, false);
}
else if(msg.indexOf('scouted') >= 0) {
tsResults.perks.scouts.drunken += 1;
parseScouts(msg, tsResults, tsResults.perks, false);
}
else if(msg.indexOf('mined') >= 0) {parsePrimaryTS(msg, tsResults, tsResults.perks, 'ore', false);}
else if(msg.indexOf('gathered') >= 0) {parsePrimaryTS(msg, tsResults, tsResults.perks, 'plant', false);}
else if(msg.indexOf('fished') >= 0) {parsePrimaryTS(msg, tsResults, tsResults.perks, 'fish', false);}
else if(msg.indexOf('cut') >= 0) {parsePrimaryTS(msg, tsResults, tsResults.perks, 'lumber', false);}
}
}
function handleSetKey(count) {
count = parseInt(count, 10);
const addedKeys = count - tsResults.keyInfo.currentKeys;
tsResults.keyInfo.currentKeys = count;
/*
if keyInfo.init is false, we haven't initialized the value; set it & don't count as a real drop
if count is 0, we just opened all keys; reset local count to that value
if count is 1-3, increment local value & track the type of key drop
handleItemDrop's key section will actually update the type of key drop if necessary
*/
if (tsResults.keyInfo.init === false) {
//console.info('healthy init');
// first setkeys called, which 'should' mean the game is loading
// this also means we can skip the pending values
tsResults.keyInfo.currentKeys = count;
tsResults.keyInfo.pendingKeys = 0;
tsResults.keyInfo.init = true;
} else if (addedKeys <= 0) {
// received after opening all keys with OPENALL|1
//console.info('key reset triggered by OPENALL|1', tsResults.keyInfo);
} else if (addedKeys === 1) {
//console.info('+1 added keys', count, addedKeys, tsResults.keyInfo);
tsResults.keyInfo.pendingKeys = addedKeys;
} else if (addedKeys === 2) {
//console.info('+2 added keys', count, addedKeys, tsResults.keyInfo);
tsResults.keyInfo.pendingKeys = addedKeys;
} else if (addedKeys === 3) {
//console.info('+3 added keys', count, addedKeys, tsResults.keyInfo);
tsResults.keyInfo.pendingKeys = addedKeys;
} else {
//console.info('+? added keys', count, addedKeys, tsResults.keyInfo);
}
}
function parseTSLog(datum) {
var arr = datum.split('|');
// SETKEY|1
// and then
// NLOG|3|[11:13:07] Found a key
if (arr[0] === 'OPENALL') {
tsResults.keyInfo.currentKeys = 0;
tsResults.keyInfo.initialized = true;
return;
}
if (arr[0] === 'SETKEY') {
return handleSetKey(arr[1]);
}
if (arr[0] != 'NLOG') {return;}
var channel = arr[1];
var msg = arr[2];
// save all lines of text if requested
if(saveLogText) {
logText.push(msg);
}
// track relic, item, gem, gold drops
if(channel == 3) {
// track quest drops separately
if(msg.indexOf('quest') > 0) return handleQuestItem(msg);
return handleItemDrop(msg);
} else if(channel == 2) {
// skip level up message before counting the action
if(msg.indexOf('gained a new tradeskill level') > -1) return;
// scouting's relic gain is in resource log now
if(msg.indexOf('relic') > -1) return parseScoutResourceRelic(msg);
// handle perks; note the data and return as it is not an extra action
if(msg.indexOf('nraged\' Perk') > -1) logPerk('enraged', msg);
if(msg.indexOf('drunkenly') > -1) return logPerk('drunken', msg);
if(msg.indexOf('Hoarder') > -1) return logPerk('hoarder', msg);
tsResults.actions += 1;
if(tsResults.questActive) tsResults.questActions += 1;
var wasTaxed = msg.indexOf('to taxes') > -1;
if(wasTaxed) tsResults.taxedActions += 1;
tsResults.xp += parseInt(msg.match(tsXPRegex)[1]);
if(msg.indexOf('You cut') >= 0) {
parsePrimaryTS(msg, tsResults, tsResults, 'lumber', wasTaxed);
} else if(msg.indexOf('You mined') >= 0) {
parsePrimaryTS(msg, tsResults, tsResults, 'ore', wasTaxed);
} else if(msg.indexOf('You gathered') >= 0) {
parsePrimaryTS(msg, tsResults, tsResults, 'plant', wasTaxed);
} else if(msg.indexOf('You caught') >= 0) {
parsePrimaryTS(msg, tsResults, tsResults, 'fish', wasTaxed);
} else if(msg.indexOf('You earned') >= 0) {
parseSales(msg, tsResults, tsResults, wasTaxed);
} else if(msg.indexOf('You scouted') >= 0) {
// skip the "didn't find any" message
if(msg.indexOf('find any') < 0) parseScouts(msg, tsResults, tsResults, wasTaxed);
}
updateOutput(tsResults, msg);
}
}
function addTierInfo(tsResults, outputArgs) {
return outputArgs.concat([
't1%:', (100*tsResults[1].drop/tsResults.actions).toFixed(2),
't2%:', (100*tsResults[2].drop/tsResults.actions).toFixed(2),
't3%:', (100*tsResults[3].drop/tsResults.actions).toFixed(2),
't4%:', (100*tsResults[4].drop/tsResults.actions).toFixed(2),
't5%:', (100*tsResults[5].drop/tsResults.actions).toFixed(2),
' ', ' ',
' gained', ' ',
't1:', tsResults[1].gained,
't2:', tsResults[2].gained,
't3:', tsResults[3].gained,
't4:', tsResults[4].gained,
't5:', tsResults[5].gained,
' ', ' ']);
}
function addItemOutput(tsResults, outputArgs) {
return outputArgs.concat([
' ', ' ',
'equip%:', (100*tsResults.itemInfo.equipDrop/tsResults.actions).toFixed(4),
'res. bag%:', (100*tsResults.itemInfo.resourceBagDrop/tsResults.actions).toFixed(4),
'key%:', (100*tsResults.itemInfo.keyDrop/tsResults.actions).toFixed(4),
'gem%:', (100*tsResults.itemInfo.gemDrop/tsResults.actions).toFixed(4),
'ME%:', (100*tsResults.itemInfo.magicElementsDrop/tsResults.actions).toFixed(4),
'gold%:', (100*tsResults.itemInfo.goldDrop/tsResults.actions).toFixed(4),
'relic%:', (100*tsResults.itemInfo.relicDrop/tsResults.actions).toFixed(4),
' ', ' ',
'avg ME:', (tsResults.itemInfo.magicElementsTotal/tsResults.itemInfo.magicElementsDrop).toFixed(2),
'avg Gold:', (tsResults.itemInfo.goldTotal/tsResults.itemInfo.goldDrop).toFixed(2),
'avg Relics:', (tsResults.itemInfo.relicTotal/tsResults.itemInfo.relicDrop).toFixed(2),
' ', ' ',
'Total ME:', tsResults.itemInfo.magicElementsTotal,
'Total Gold:', tsResults.itemInfo.goldTotal,
'Total Relics:', tsResults.itemInfo.relicTotal,
'2x Relic %:', (tsResults.itemInfo.relicDouble/tsResults.itemInfo.relicDrop).toFixed(2),
' ', ' ']);
}
function addSalesInfo(tsResults, outputArgs) {
var avgSale = tsResults.sales.gained/tsResults.actions;
return outputArgs.concat([
'Sales:', tsResults.sales.gained,
'Avg Sale:', avgSale.toFixed(2),
'1x Estimate:', (avgSale * normalAverageMultiplier).toFixed(2),
'4x Estimate:', (avgSale * quadAverageMultiplier).toFixed(2),
]);
}
function addScoutsInfo(tsResults, outputArgs) {
var avgScout = tsResults.scouts.gained/tsResults.actions;
return outputArgs.concat([
'Scouts:', tsResults.scouts.gained,
'Avg Scout:', avgScout.toFixed(2),
'Scout Relics:', tsResults.scouts.relicGained,
'Scout 2x Relic%:', (tsResults.scouts.relicDouble/tsResults.scouts.relicDrop*100).toFixed(2),
'Actions/Relic', (tsResults.actions/tsResults.scouts.relicGained).toFixed(2),
'Relics/Action', (tsResults.scouts.relicGained/tsResults.actions).toFixed(2),
' ', ' ',
'1x Estimate:', (avgScout * normalAverageMultiplier).toFixed(2),
'4x Estimate:', (avgScout * quadAverageMultiplier).toFixed(2)
]);
}
function addTaxPercent(tsResults, outputArgs) {
return outputArgs.concat([
'tax%:', (100*tsResults.taxedActions/tsResults.actions).toFixed(2)]);
}
function addTaxSales(tsResults, outputArgs) {
return outputArgs.concat([
'sales tax:', tsResults.sales.taxed,
'avg tax:', (tsResults.sales.taxed/tsResults.taxedActions).toFixed(2)]);
}
function addTaxScouts(tsResults, outputArgs) {
return outputArgs.concat([
'Relics Taxed:', tsResults.scouts.relicTaxedCount,
'Avg tax:', (tsResults.scouts.relicTaxedCount/tsResults.scouts.relicTaxed).toFixed(2),
'Tax %:', (tsResults.scouts.relicTaxed/tsResults.scouts.relicDrop*100).toFixed(2)
]);
}
function addTaxedItems(tsResults, outputArgs) {
return outputArgs.concat([
' total taxed', ' ',
't1:', tsResults[1].taxed,
't2:', tsResults[2].taxed,
't3:', tsResults[3].taxed,
't4:', tsResults[4].taxed,
't5:', tsResults[5].taxed]);
}
function addXP(tsResults, outputArgs) {
return outputArgs.concat([
'total XP:', tsResults.xp,
'avg XP:', (tsResults.xp/tsResults.actions).toFixed(2),
' ', ' ']);
}
function addKeyInfo(tsResults, outputArgs) {
let keyInfo = [];
const keyDrops = tsResults.itemInfo.keyDrop;
//const keysNow = tsResults.keyInfo.currentKeys;
const singleKey = tsResults.keyInfo.single;
const doubleKey = tsResults.keyInfo.double;
const tripleKey = tsResults.keyInfo.triple;
keyInfo = keyInfo.concat(['Glvl Keys', ' ']);
keyInfo = keyInfo.concat(['1x %: ', (100*singleKey/keyDrops||0).toFixed(2)]);
keyInfo = keyInfo.concat(['2x %: ', (100*doubleKey/keyDrops||0).toFixed(2)]);
keyInfo = keyInfo.concat(['3x %: ', (100*tripleKey/keyDrops||0).toFixed(2)]);
keyInfo = keyInfo.concat([' ', ' ']);
return outputArgs.concat(keyInfo);
}
function addPerkInfo(tsResults, outputArgs) {
let perkInfo = [' ', ' ', 'Perks %', ' '];
const actions = tsResults.actions;
const perks = tsResults.perks;
const enraged = perks.enraged;
perkInfo = perkInfo.concat(['enraged: ', (enraged/actions*100).toFixed(2)]);
const hoarder= perks.hoarder;
perkInfo = perkInfo.concat(['hoarder: ', (hoarder/actions*100).toFixed(2)]);
const drunken = perks.drunken;
perkInfo = perkInfo.concat(['drunken: ', (drunken/actions*100).toFixed(2)]);
perkInfo = perkInfo.concat(['t1: ', (perks[1].total).toFixed(2)]);
perkInfo = perkInfo.concat(['t2: ', (perks[2].total).toFixed(2)]);
perkInfo = perkInfo.concat(['t3: ', (perks[3].total).toFixed(2)]);
perkInfo = perkInfo.concat(['t4: ', (perks[4].total).toFixed(2)]);
perkInfo = perkInfo.concat(['t5: ', (perks[5].total).toFixed(2)]);
perkInfo = perkInfo.concat(['gold: ', (perks.sales.total).toFixed(2)]);
perkInfo = perkInfo.concat(['avg gold: ', (perks.sales.total/perks.sales.drunken).toFixed(2)]);
perkInfo = perkInfo.concat(['scouted: ', (perks.scouts.total).toFixed(2)]);
perkInfo = perkInfo.concat(['avg scout: ', (perks.scouts.total/perks.scouts.drunken).toFixed(2)]);
perkInfo.concat([' ', ' ']);
return outputArgs.concat(perkInfo);
}
function updateOutput(results, msg) {
var outputArgs = ['actions:', tsResults.actions, ' ', ' '];
outputArgs = addXP(tsResults, outputArgs);
// don't display tier data if sales is active
var salesActive = tsResults.sales.total > 0;
var scoutsActive = tsResults.scouts.total > 0;
if(outputTiers && !salesActive && !scoutsActive) outputArgs = addTierInfo(tsResults, outputArgs);
else if(outputTiers && salesActive && !scoutsActive) outputArgs = addSalesInfo(tsResults, outputArgs);
else if(outputTiers && !salesActive && scoutsActive) outputArgs = addScoutsInfo(tsResults, outputArgs);
outputArgs = outputArgs.concat([' ', ' ', 'item%:', (100*tsResults.items/tsResults.actions).toFixed(2)]);
if(outputItems) outputArgs = addItemOutput(tsResults, outputArgs);
outputArgs = addKeyInfo(tsResults, outputArgs);
if(outputQuests) outputArgs = outputArgs.concat(['quest%:', (100*tsResults.questItems/tsResults.questActions||0).toFixed(2)]);
if(outputTaxes) {
// scouting tax functions differently
if(!scoutsActive) outputArgs = addTaxPercent(tsResults, outputArgs);
if(salesActive) outputArgs = addTaxSales(tsResults, outputArgs);
else if(scoutsActive) outputArgs = addTaxScouts(tsResults, outputArgs);
else outputArgs = addTaxedItems(tsResults, outputArgs);
}
if(outputPerks) outputArgs = addPerkInfo(tsResults, outputArgs);
outputArgs = outputArgs.concat(['\tmsg:', msg]);
if(outputToConsole) console.info.apply(console, outputArgs);
// skip posting the message to the UI
outputArgs.pop();
outputArgs.pop();
updateUI(outputArgs);
}
function formatResource(label, value) {
return '<li><div>' + label + ' ' + value + '</div></li>';
}
function updateUI(outputArgs) {
$('#'+resourceListId).empty();
$('#'+resourceListId).append('<li><div><a href="#" onClick="clearTSResults(); return false">Reset Data</a></div></li>');
for(var i=0,iLen=outputArgs.length;i<iLen;i+=2) {
$('#'+resourceListId).append(formatResource(outputArgs[i], outputArgs[i+1]));
}
}
function initializeUI() {
$("body").append('<div id="resourceLogContainer" style="position: absolute;top: 0;right: 0; width: 210px;"><div><span>Resource Log </span><div style="float: right;"><a href="javascript:toggleUI();">[Toggle]</a></div></div> <ul id="resourceLogList" style="display;text-align: left;"></ul></div>');
}
function toggleUI() {
$("#resourceLogList").toggle();
}
if(typeof unsafeWindow !== 'undefined') unsafeWindow.toggleUI = toggleUI;
function track_resources_onmsg(evt) {
track_resources_original_msg(evt);
parseTSLog(evt.data);
}
// set up handler & hook original game handler in
if(typeof track_resources_original_msg === 'undefined') {
console.info('resource tracker not yet loaded, loading...');
var track_resources_original_msg = ws.onmessage;
ws.onmessage=track_resources_onmsg;
initializeUI();
} else {
ws.onmessage=track_resources_onmsg;
}