· 8 years ago · Mar 13, 2018, 01:36 PM
1// ==UserScript==
2// @name Talibri - Xmitty's Stat Tracker
3// @namespace StatTracker
4// @version 0.31
5// @description Track Statistics in Talibri
6// @author Xmitty
7// @match https://talibri.com/*
8// @require https://gist.github.com/raw/2625891/waitForKeyElements.js
9// @require https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.js
10// @grant none
11// ==/UserScript==
12
13//Globals (What Is Scope?)
14var craftingStarted = false;
15var combatStarted = false;
16
17var init = {
18
19 initialize: function() {
20 $('head').append('<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>');
21 $('head').append('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" />');
22 //$('head').append('<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/tabulator/3.4.3/js/tabulator.min.js"></script>');
23 //$('head').append('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tabulator/3.4.3/css/tabulator.min.css" />');
24 $('head').append('<script type="text/javascript">var script = script || {};</script>');
25
26 init.initalizeMenus();
27 init.initalizeGraphs();
28
29 crafting.data = crafting.new(); // Setting Up Basic Structure
30 combat.data = combat.new(); // Setting Up Basic Structure
31
32 storage.load(); // Load Previous Data
33
34 crafting.start();
35 combat.start();
36 window.setInterval(init.initalizeMenus, 500);
37 window.setInterval(init.initalizeGraphs, 500);
38 window.setInterval(crafting.start, 500);
39 window.setInterval(combat.start, 500);
40
41 },
42
43 initalizeMenus: function() {
44
45 if($(".trackingDropdown").length>0)
46 {
47 return;
48 }
49
50 var menuHtml = '<li class="trackingDropdown">';
51 menuHtml += '<a class="trackingDropdown-toggle" href="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded=false">';
52 menuHtml += 'StatTracker';
53 menuHtml += '<span class="caret"></span>';
54 menuHtml += '</a>';
55 menuHtml += '<ul class="dropdown-menu">';
56 menuHtml += '<li><a>Show StatTracker: <input type="checkbox" id="trackingCheck"> </a></li>';
57 menuHtml += '</ul>';
58 menuHtml += '</li>';
59 $('.navbar-nav').first().append(menuHtml);
60
61 $("#trackingCheck").on('click', function () { init.showUserInterface(); });
62
63 },
64
65 initalizeGraphs: function() {
66
67 if($("#myCraftingChart").length === 0) {
68
69 var Html = "";
70 Html += '<div id="trackingDialog" title="Stat Tracking" style="display: none">';
71 Html += '<div id="tabs_in_dialog"><ul>';
72 Html += '<li><a href="#tabs-1">Leol & XP - Live</a></li><li><a href="#tabs-2">Attributes - Live</a></li>'; // Tab Titles
73 Html += '<li><a href="#tabs-3">Component Crafting - Live</a></li></li><li><a href="#tabs-4">Combat Breakdown</a></li>'; // Tab Titles
74 Html += '<li><a href="#tabs-5">Crafting Breakdown</a></li></li><li><a href="#tabs-6">Settings / Reset</a></li>'; // Tab Titles
75 Html += '<div id="tabs-1" style="position: absolute; height: 90%; width: 97%; top: 50px">'; // Leol & XP - Live
76 Html += '<div id="wrapper" style="position: relative; width: 50%; height: 100%; float: left">'; // Leol Graph
77 Html += '<canvas id="myCombatChart"></canvas>';
78 Html += '</div>';
79 Html += '<div id="wrapper" style="position: relative; width: 50%; height: 100%; float: left">'; // XP Graph
80 Html += '<canvas id="myCombatChart2"></canvas>';
81 Html += '</div></div>';
82 Html += '<div id="tabs-2" style="position: absolute; height: 90%; width: 97%; top: 50px">'; // Attribute - Live
83 Html += '<div id="wrapper" style="position: relative; width: 100%; height: 100%; float: left">'; // Attributes Graph
84 Html += '<canvas id="myCombatChart3"></canvas>';
85 Html += '</div></div>';
86 Html += '<div id="tabs-3" style="position: absolute; height: 90%; width: 97%; top: 50px">'; // Component Crafting - Live
87 Html += '<div id="wrapper" style="position: relative; width: 100%; height: 100%; float: left">'; // Component Graph
88 Html += '<canvas id="myCraftingChart"></canvas>';
89 Html += '</div></div>';
90 Html += '<div id="tabs-4" style="position: absolute; height: 90%; width: 97%; top: 50px">'; // Combat Breakdown
91 Html += '<div id="wrapper" style="position: relative; width: 50%; height: 50%; float: left">'; // Combat Stat Table
92 Html += '<table id="combatStatTable" style="width: 80%; margin-left: auto; margin-right: auto; font-size: 20px">';
93 Html += '<tr><th>Total Actions</th><td id="combat_actions">0</td></tr>';
94 Html += '<tr><th>Attack Accuracy</th><td id="combat_accuracy">0/0</td></tr>';
95 Html += '<tr><th>Total Affinity XP Gained</th><td id="combat_exp">0</td></tr>';
96 Html += '<tr><th>Total Leol Gained</th><td id="combat_leol">0</td></tr>';
97 Html += '<tr><th>Affinity XP/Hour</th><td id="combat_exp_hour">0.00</td></tr>';
98 Html += '<tr><th>Leol/Hour</th><td id="combat_leol_hour">0.00</td></tr>';
99 Html += '<tr><th></th><td></td></tr>';
100 Html += '<tr><th>*** Combat Tick Information ***</th><td id="combat_tick_title"></td></tr>';
101 Html += '<tr><th>Average Tick Time</th><td id="combat_tick_time">0.00</td></tr>';
102 Html += '<tr><th>Ticks in 24 Hours</th><td id="combat_tick_day">0.00</td></tr>';
103 Html += '</table>';
104 Html += '</div>';
105 Html += '<div id="wrapper" style="position: relative; width: 50%; height: 50%; float: left">'; // Monster Kill Graph
106 Html += '<canvas id="myCombatChart4"></canvas>';
107 Html += '</div>';
108 Html += '<div id="wrapper" style="position: relative; width: 50%; height: 50%; float: left">'; // Combat Stat Table #2
109 Html += '<table id="combatStatTable" style="width: 80%; margin-left: auto; margin-right: auto; font-size: 20px">';
110 Html += '<tr><th>Total Strength</th><td id="combat_total_str">0</td></tr>';
111 Html += '<tr><th>Total Stamina</th><td id="combat_total_stam">0</td></tr>';
112 Html += '<tr><th>Total Dexterity</th><td id="combat_total_dex">0</td></tr>';
113 Html += '<tr><th>Total Intellect</th><td id="combat_total_int">0</td></tr>';
114 Html += '<tr><th>Total Will</th><td id="combat_total_will">0</td></tr>';
115 Html += '<tr><th>Attribute XP/Hour</th><td id="combat_att_per_hour">0.00</td></tr>';
116 Html += '<tr><th>Attribute XP/Tick</th><td id="combat_att_per_tick">0.00</td></tr>';
117 Html += '</table>';
118 Html += '</div>';
119 Html += '<div id="wrapper" style="position: relative; width: 50%; height: 50%; float: left">'; // Monster Item Graph
120 Html += '<canvas id="myCombatChart5"></canvas>';
121 Html += '</div></div>';
122 Html += '<div id="tabs-5" style="position: absolute; height: 90%; width: 97%; top: 50px">'; // Crafting Breakdown
123 Html += '<div id="wrapper" style="position: relative; width: 100%; height: 100%; float: left">';
124 Html += '<div id="example-table"></div>'; // Testing out Tablulator
125 Html += '</div></div>';
126 Html += '<div id="tabs-6" style="position: absolute; height: 90%; width: 97%; top: 50px">'; // Settings / Reset
127 Html += '<div id="wrapper" style="position: relative; width: 100%; height: 100%; float: left">'; // Reset Buttons
128 Html += '<button type="button" id="combatResetBtn">Reset Combat Data</button>';
129 Html += '<button type="button" id="craftingResetBtn">Reset Crafting Data</button>';
130 Html += '</div></div>';
131 Html += '</div></div>';
132
133 $('body').append(Html);
134
135 $("#combatResetBtn").on('click', function () { combat.reset(); });
136 $("#craftingResetBtn").on('click', function () { crafting.reset(); });
137
138
139 var craftingConfig = {
140 type: 'line',
141 data: {
142 labels: [0.5,1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,8,8.5,9,9.5,10],
143 datasets: [{
144 label: "Star Curve",
145 data: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
146 backgroundColor: ['rgba(255, 99, 132, 0.5)'],
147 borderColor: ['rgba(255,99,132,1)'],
148 fill: false,
149 }, ]
150 },
151 options: {
152 maintainAspectRatio: false,
153 responsive: true,
154 layout: {
155 padding: {
156 top: 10 }
157 },
158 legend: {
159 position: 'bottom',
160 },
161 tooltips: {
162 mode: 'index',
163 intersect: false,
164 },
165 hover: {
166 mode: 'nearest',
167 intersect: true
168 },
169 scales: {
170 xAxes: [{
171 display: true,
172 scaleLabel: {
173 display: true,
174 labelString: 'Number Of Stars'
175 }
176 }],
177 yAxes: [{
178 display: true,
179 scaleLabel: {
180 display: true,
181 labelString: 'Number Of Crafts'
182 }
183 }]
184 }
185 }
186 };
187
188 var randColors = [];
189 for (i = 0; i < 10; i++)
190 {
191 randColors[i] = helper.getRandomColor();
192 }
193
194 var combatConfig = {
195 type: 'line',
196 data: {
197 labels: [],
198 datasets: [{
199 label: "Leol/Tick Avg.",
200 data: [],
201 backgroundColor: randColors[0],
202 borderColor: randColors[0],
203 yAxisID: "y-axis-1",
204 fill: false,
205 }, {
206 label: "Leol/Sec Avg.",
207 data: [],
208 backgroundColor: randColors[1],
209 borderColor: randColors[1],
210 yAxisID: "y-axis-2",
211 fill: false,
212 }, ]
213 },
214 options: {
215 maintainAspectRatio: false,
216 responsive: true,
217 title: {
218 display:true,
219 text:'Leol Per Tick & Second Averages'
220 },
221 elements: {
222 point: {
223 radius: 0
224 }
225 },
226 layout: {
227 padding: {
228 top: 10
229 }
230 },
231 legend: {
232 position: 'bottom',
233 },
234 tooltips: {
235 mode: 'index',
236 intersect: false,
237 },
238 hover: {
239 mode: 'nearest',
240 intersect: true
241 },
242 scales: {
243 xAxes: [{
244 display: true,
245 type: "time",
246 time: {
247 displayFormats: {
248 minute: 'h:mm:ss A',
249 hour: 'h:mm A',
250 day: 'MMMM D YYYY'
251 },
252 tooltipFormat: 'MMM D HH:mm:ss'
253 },
254 scaleLabel: {
255 display: true,
256 labelString: 'Date'
257 }
258 }],
259 yAxes: [{
260 type: "linear",
261 display: true,
262 position: "left",
263 id: "y-axis-1",
264 ticks: {
265 min: 0
266 },
267 scaleLabel: {
268 display: true,
269 labelString: 'Leol'
270 }
271 }, {
272 type: "linear",
273 display: true,
274 position: "right",
275 id: "y-axis-2",
276 scaleLabel: {
277 display: true,
278 lableString: 'Leol/Tick'
279 },
280 gridLines: {
281 drawOnChartArea: false
282 }
283 }]
284 }
285 }
286 };
287
288 var combatConfig2 = {
289 type: 'line',
290 data: {
291 labels: [],
292 datasets: [{
293 label: "Xp/Tick Avg.",
294 data: [],
295 backgroundColor: randColors[3],
296 borderColor: randColors[3],
297 yAxisID: "y-axis-1",
298 fill: false,
299 },{
300 label: "Xp/Sec Avg.",
301 data: [],
302 backgroundColor: randColors[4],
303 borderColor: randColors[4],
304 yAxisID: "y-axis-2",
305 fill: false,
306 }, ]
307 },
308 options: {
309 maintainAspectRatio: false,
310 responsive: true,
311 title: {
312 display:true,
313 text:'XP Per Tick & Second Averages'
314 },
315 elements: {
316 point: {
317 radius: 0
318 }
319 },
320 layout: {
321 padding: {
322 top: 10
323 }
324 },
325 legend: {
326 position: 'bottom',
327 },
328 tooltips: {
329 mode: 'index',
330 intersect: false,
331 },
332 hover: {
333 mode: 'nearest',
334 intersect: true
335 },
336 scales: {
337 xAxes: [{
338 display: true,
339 type: "time",
340 time: {
341 displayFormats: {
342 minute: 'h:mm:ss A',
343 hour: 'h:mm A',
344 day: 'MMMM D YYYY'
345 },
346 tooltipFormat: 'MMM D HH:mm:ss'
347 }
348 }],
349 yAxes: [{
350 type: "linear",
351 display: true,
352 position: "left",
353 id: "y-axis-1",
354 ticks: {
355 min: 0
356 },
357 scaleLabel: {
358 display: true,
359 labelString: 'Affinity Experience'
360 }
361 }, {
362 type: "linear",
363 display: true,
364 position: "right",
365 id: "y-axis-2",
366 scaleLabel: {
367 display: true,
368 lableString: 'Xp/Tick'
369 },
370 gridLines: {
371 drawOnChartArea: false
372 }
373 }]
374 }
375 }
376 };
377
378 var combatConfig3 = {
379 type: 'line',
380 data: {
381 labels: [],
382 },
383 options: {
384 maintainAspectRatio: false,
385 responsive: true,
386 title: {
387 display:true,
388 text:'Attributes Per Tick'
389 },
390 elements: {
391 point: {
392 radius: 0
393 }
394 },
395 layout: {
396 padding: {
397 top: 10
398 }
399 },
400 legend: {
401 position: 'bottom',
402 },
403 tooltips: {
404 mode: 'index',
405 intersect: false,
406 },
407 hover: {
408 mode: 'nearest',
409 intersect: true
410 },
411 scales: {
412 xAxes: [{
413 display: true,
414 type: "time",
415 time: {
416 displayFormats: {
417 minute: 'h:mm:ss A',
418 hour: 'h:mm A',
419 day: 'MMMM D YYYY'
420 },
421 tooltipFormat: 'MMM D HH:mm:ss'
422 }
423 }],
424 yAxes: [{
425 display: true,
426 ticks: {
427 min: 0
428 },
429 scaleLabel: {
430 display: true,
431 labelString: 'Attributes Per Tick'
432 }
433 }]
434 }
435 }
436 };
437
438 var combatConfig4 = {
439 type: 'pie',
440 data: {
441 datasets: [{
442 data: [0, 0, 0]
443 }],
444 labels: [
445 'Monster'
446 ]
447 },
448 options: {
449 maintainAspectRatio: false,
450 responsive: true,
451 title: {
452 display:true,
453 text:'Ratio of Enemies Killed'
454 },
455 layout: {
456 padding: {
457 top: 10
458 }
459 },
460 legend: {
461 position: 'bottom',
462 },
463 tooltips: {
464 mode: 'index',
465 intersect: false,
466 },
467 }
468 };
469
470 var combatConfig5 = {
471 type: 'pie',
472 data: {
473 datasets: [{
474 data: [0, 0, 0]
475 }],
476 labels: [
477 'Drops'
478 ]
479 },
480 options: {
481 maintainAspectRatio: false,
482 responsive: true,
483 title: {
484 display:true,
485 text:'Ratio of Enemy Drops'
486 },
487 layout: {
488 padding: {
489 top: 10
490 }
491 },
492 legend: {
493 position: 'bottom',
494 },
495 tooltips: {
496 mode: 'index',
497 intersect: false,
498 },
499 }
500 };
501
502 var craftingctx = document.getElementById("myCraftingChart").getContext("2d");
503 myCraftingLine = new Chart(craftingctx, craftingConfig);
504 var combatctx = document.getElementById("myCombatChart").getContext("2d");
505 myCombatLine = new Chart(combatctx, combatConfig);
506 var combatctx2 = document.getElementById("myCombatChart2").getContext("2d");
507 myCombatLine2 = new Chart(combatctx2, combatConfig2);
508 var combatctx3 = document.getElementById("myCombatChart3").getContext("2d");
509 myCombatLine3 = new Chart(combatctx3, combatConfig3);
510 var combatctx4 = document.getElementById("myCombatChart4").getContext("2d");
511 myCombatPie1 = new Chart(combatctx4, combatConfig4);
512 var combatctx5 = document.getElementById("myCombatChart5").getContext("2d");
513 myCombatPie2 = new Chart(combatctx5, combatConfig5);
514
515 }
516 },
517
518 loadTables: function() {
519 /*$("#example-table").tabulator({
520 height:'auto', // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
521 layout:"fitColumns",
522 columns:[ //Define Table Columns
523 {title:"Name", field:"name", width:150},
524 {title:"Age", field:"age", align:"left", formatter:"progress"},
525 {title:"Favourite Color", field:"col"},
526 {title:"Date Of Birth", field:"dob", sorter:"date", align:"center"},
527 ],
528 rowClick:function(e, row){ //trigger an alert message when the row is clicked
529 alert("Row " + row.getData().id + " Clicked!!!!");
530 },
531 });
532
533 var tabledata = [
534 {id:1, name:"Oli Bob", age:"12", col:"red", dob:""},
535 {id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
536 {id:3, name:"Christine Lobowski", age:"42", col:"green", dob:"22/05/1982"},
537 {id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
538 {id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
539 ];
540
541 //load sample data into the table
542 $("#example-table").tabulator("setData", tabledata);*/
543 },
544
545 showUserInterface: function () {
546 var checkBox = document.getElementById('trackingCheck');
547 if (checkBox.checked === true){
548
549 //init.loadTables();
550
551 $("#trackingDialog").tabs().dialog({
552 width: 1300,
553 height: 800,
554 modal: true,
555 open: function (){
556 //$(this).parent().children('.ui-dialog-titlebar').remove();
557 //combat.myResize();
558 },
559 resizeStop: combat.myResize
560 });
561 $(".trackingDropdown-toggle").dropdown("toggle");
562
563 checkBox.checked = false;
564
565 //$("#example-table").tabulator("redraw")
566
567
568 } else {
569 $("#trackingDialog").dialog('close');
570 }
571 }
572};
573
574var storage = {
575 STORAGE_KEY: 'TrackingData',
576 Structure: {Data: {CraftingData: {StatData: {}, ChartData: {}}, CombatData: {StatData: {}, ChartData: {}}}},
577
578 save: function() {
579 localStorage.setItem(storage.STORAGE_KEY, JSON.stringify(storage.Structure));
580 },
581
582 load: function() {
583
584 var storedCrafting = localStorage.getItem(storage.STORAGE_KEY);
585
586 if (storedCrafting !== undefined) {
587
588 var loadedData = {};
589
590 storedCrafting = JSON.parse(storedCrafting);
591 Object.keys(storedCrafting).forEach(function(key) {
592 loadedData[key] = storedCrafting[key];
593 });
594
595 console.log("We have pulled the key.");
596
597 // Handles Loading Crafting Data
598 crafting.data = loadedData.Data.CraftingData.ChartData;
599
600 for(i = 0; i < 20; i++) {
601 myCraftingLine.data.datasets[0].data[i] = crafting.data[i+1];
602 }
603
604 storage.Structure.Data.CraftingData.ChartData = crafting.data;
605
606 console.log("Crafting Data Loaded");
607
608 // Handles Loading Combat Data
609 combat.data = loadedData.Data.CombatData.ChartData;
610
611
612 for(var stat in combat.data.stats) {
613 if(combat.data.stats[stat] > -1 && combat.data.statsEnabled[stat] == true) {
614 combat.data.statsEnabled[stat] = false;
615 }
616 }
617
618 if(Object.keys(combat.data.monsters).length > 0) {
619 var monList = [];
620 var monData = [];
621 var monColor = [];
622
623 for(var monster in combat.data.monsters) {
624 monData.push(combat.data.monsters[monster]);
625 monList.push(helper.toTitleCase(monster));
626 monColor.push(helper.getRandomColor());
627 }
628
629 for(i = 0; i < Object.keys(combat.data.monsters).length; i++)
630 {
631 combat.monPieKillList.push(monList[i]);
632 combat.monPieKillChart.backgroundColor.push(monColor[i]);
633 combat.monPieKillChart.borderColor.push(monColor[i]);
634 if(i == 0) { myCombatPie1.config.data.labels[i] = (combat.monPieKillList[i]); }
635 else { myCombatPie1.config.data.labels.push(combat.monPieKillList[i]); }
636 }
637
638 combat.monPieKillChart.data = monData;
639 combat.totalMonKilled = Object.keys(combat.data.monsters).length;
640 }
641
642 if(Object.keys(combat.data.loot).length > 0) {
643 var monDropList = [];
644 var monDropData = [];
645 var monDropColor = [];
646 var monDropCount = 0;
647
648 for(var loots in combat.data.loot) {
649 monDropData.push(combat.data.monsters[loots]);
650 monDropList.push(helper.toTitleCase(loots));
651 monDropColor.push(helper.getRandomColor());
652 }
653
654 for(i = 0; i < Object.keys(combat.data.loot).length; i++)
655 {
656 combat.monPieDropList.push(monDropList[i]);
657 combat.monPieDropChart.backgroundColor.push(monDropColor[i]);
658 combat.monPieDropChart.borderColor.push(monDropColor[i]);
659 if(i == 0) { myCombatPie2.config.data.labels[i] = (combat.monPieDropList[i]); }
660 else { myCombatPie2.config.data.labels.push(combat.monPieDropList[i]); }
661 }
662
663 combat.monPieDropChart.data = monDropData;
664 combat.totalMonDrops = Object.keys(combat.data.loot).length;
665 }
666
667 console.log("Combat Data Loaded");
668
669 storage.Structure.Data.CombatData.ChartData = combat.data;
670
671 storage.save();
672
673 console.log(storage.Structure);
674
675 } else {
676 storage.save();
677 }
678 }
679};
680
681var crafting = {
682 data: null,
683 stop: function() {
684 craftingStarted = false;
685 },
686 start: function() {
687 var splitURL = document.URL.split("/");
688 var findWord = splitURL.indexOf("crafting");
689
690 if(findWord > 0 && craftingStarted == false)
691 {
692 $(document).ajaxComplete(crafting.listen);
693 craftingStarted = true;
694 }
695 else if(findWord > 0 && craftingStarted == true)
696 {
697 }
698 else if(findWord < 0 && craftingStarted == false)
699 {
700 craftingStarted = false;
701 }
702 else
703 {
704 craftingStarted = false;
705 }
706 },
707 destory: function() {
708 crafting.stop();
709 $.removeCookie(crafting.cookieName(), {path: crafting.cookiePath()});
710 },
711 reset: function() {
712 console.log("Crafting Resetting.");
713 crafting.data = crafting.new();
714 storage.Structure.Data.CraftingData.ChartData = crafting.data;
715 storage.save();
716 myCraftingLine.data.datasets[0].data = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
717 myCraftingLine.update();
718 },
719 new: function() {
720 var empty_data = {
721 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 0,
722 total: 0,
723 failure: 0,
724 };
725 return empty_data;
726 },
727 listen: function(event, xhr, settings) {
728 if(craftingStarted == false) {
729 $(e.currentTarget).unbind('ajaxComplete');
730 return;
731 }
732
733 var result = crafting.process(xhr.responseText);
734 crafting.logTickResult(result);
735 },
736 process: function(response) {
737 var result = {
738 stars: 0,
739 };
740
741 var craftingWindow = response.split("\n")[0];
742 craftingWindow = craftingWindow.split("html(")[1];
743 craftingWindow = craftingWindow.substr(1, craftingWindow.length-4);
744 craftingWindow = craftingWindow.replace(/\\n/g,"");
745 craftingWindow = craftingWindow.replace(/\\/g,"");
746 var craftResult = $(craftingWindow);
747 result.stars = ($('.fa-star', craftResult).length * 2 + $('.fa-star-half-o', craftResult).length);
748
749 return result;
750 },
751 logTickResult: function(result) {
752 if(result.stars > 0)
753 {
754 if(!crafting.data[result.stars]) {
755 crafting.data[result.stars] = 1;
756 myCraftingLine.data.datasets[0].data[result.stars-1] = crafting.data[result.stars];
757 }
758 else {
759 crafting.data[result.stars] += 1;
760 myCraftingLine.data.datasets[0].data[result.stars-1] = crafting.data[result.stars];
761 }
762 }
763 else if(result.stars == 0)
764 {
765 crafting.data.failure += 1;
766 }
767 crafting.data.total += 1;
768 crafting.data.success = crafting.data.total - crafting.data.failure;
769 myCraftingLine.update();
770
771 storage.Structure.Data.CraftingData.ChartData = crafting.data;
772
773 storage.save();
774 }
775};
776
777var combat = {
778
779 data: null,
780 tickCounter: 0,
781 totalMonKilled: 0,
782 totalMonDrops: 0,
783 monPieDropChart: { backgroundColor: [], borderColor: [], data: [], },
784 monPieKillChart: { backgroundColor: [], borderColor: [], data: [], },
785 monPieKillList: [],
786 monPieDropList: [],
787 actionDictionary: { skills: [
788 {name: "Stab",successful: true, text: "You lunged at the enemy stabbing them"},
789 {name: "Stab",successful: false, text: "You attempted to use Stab"},
790 {name: "Shock Strike",successful: true, text: "You channel lightning energy into your blade"},
791 {name: "Shock Strike",successful: false, text: "You attempted to use Shock Strike"},
792 {name: "Lightning Defense",successful: true, text: "Lightning courses through your body"},
793 {name: "Lightning Defense",successful: false, text: "You attempted to use Lightning Defense"},
794 {name: "Dash",successful: true, text: "You dash into the enemy's defenses"},
795 {name: "Bash",successful: true, text: "You bash the enemy dealing"},
796 {name: "Bash",successful: false, text: "You attempted to use Bash"},
797 {name: "ShieldBash",successful: true, text: "You stunned the enemy!"},
798 {name: "Shout",successful: true, text: "You shout at the enemy building your adrenaline"},
799 {name: "Fiery Strike",successful: true, text: "You cover your weapon in oil and light it ablaze before striking the enemy"},
800 {name: "Fiery Strike",successful: false, text: "You attempted to use Fiery Strike"},
801 {name: "Aimed Shot",successful: true, text: "You line up the shot and let your arrow fly"},
802 {name: "Aimed Shot",successful: false, text: "You attempted to use Aimed Shot"},
803 {name: "Rapid Shot",successful: true, text: "One of your arrows launched in quick succession"},
804 {name: "Rapid Shot",successful: false, text: "You attempted to use Rapid Shot"},
805 {name: "Wing Clip",successful: true, text: "You aim for the enemy's weapon"},
806 {name: "Wing Clip",successful: false, text: "You attempted to use Wing Clip"},
807 {name: "Ignite",successful: true, text: "You set your enemy ablaze"},
808 {name: "Ignite",successful: false, text: "You attempted to use Ignite"},
809 {name: "Freeze",successful: true, text: "You freeze your enemy"},
810 {name: "Freeze",successful: false, text: "You attempted to use Freeze"},
811 {name: "Electrify",successful: true, text: "You Electrify your enemy"},
812 {name: "Electrify",successful: false, text: "You attempted to use Electrify"},
813 {name: "Earth Eruption",successful: true, text: "The Earth Erupts under your enemy"},
814 {name: "Earth Eruption",successful: false, text: "You attempted to use Earth Eruption"},
815 {name: "Item Failed",successful: false, text: "You are out of"},
816 ]},
817 stop: function() {
818 combatStarted = false;
819 },
820 start: function() {
821 var splitURL = document.URL.split("/");
822 var findWord = splitURL.indexOf("combat_zones");
823
824 if(findWord > 0 && combatStarted == false)
825 {
826 $(document).ajaxComplete(combat.listen);
827 combatStarted = true;
828 }
829 else if(findWord > 0 && combatStarted == true)
830 {
831 }
832 else if(findWord < 0 && combatStarted == false)
833 {
834 combatStarted = false;
835 }
836 else
837 {
838 combatStarteds = false;
839 }
840 },
841 myResize: function(event, ui) {
842 $(this).height($(this).parent().height() - $(this).prev('.ui-dialog-titlebar').height() - 34);
843 $(this).width($(this).prev('.ui-dialog-titlebar').width() + 2);
844 },
845 destory: function() {
846 combat.stop();
847 $.removeCookie(combat.cookieName(), {path: combat.cookiePath()});
848 },
849 reset: function() {
850 combat.data = combat.new();
851 storage.Structure.Data.CombatData.ChartData = combat.data;
852 storage.save();
853
854 },
855 new: function() {
856 var empty_data = {
857 update: moment().valueOf(),
858 since: moment().valueOf(),
859 ticks: 0,
860 rounds: 0,
861 win: 0,
862 loss: 0,
863 flee: 0,
864 inCombat: false,
865 leol: 0,
866 actions: {},
867 items: {},
868 monsters: {},
869 stats: {strength: 0,stamina: 0, dexterity: 0,will: 0,intellect: 0},
870 statsEnabled: {dexterity: false, intellect: false, stamina: false, strength: false, will: false},
871 affinities: {},
872 loot: {}
873 };
874 return empty_data;
875 },
876 listen: function(event, xhr, settings) {
877 if(combatStarted == false) {
878 $(e.currentTarget).unbind('ajaxComplete');
879 return;
880 }
881 if(settings.url.indexOf('adventure/continue') > -1) {
882 if(script.reset_component == true) {
883 combat.reset();
884 }
885 if(!combat.data) {
886 combat.data = combat.load();
887 if(!combat.data) {
888 return;
889 }
890 }
891
892 var result = combat.getResult(xhr.responseText);
893
894 combat.logBattleRound(result);
895 }
896 },
897 getResult: function(response) {
898 var result = {
899 player: {
900 slain: false
901 },
902 monster: {
903 name: "Unknown",
904 slain: false
905 },
906 leol: 0,
907 action: {
908 type: "Nothing",
909 name: "Unknown",
910 successful: false
911 },
912 stats: {},
913 affinities: {},
914 loot: {}
915 };
916
917 if(response.indexOf('You limped back to town on the verge of death') > -1) {
918 result.player.slain = true;
919 }
920
921 responseLines = response.split(";");
922
923 for(var i = 0; i < responseLines.length; i++) {
924 var item = responseLines[i].toLowerCase();
925 if(item.indexOf("$('button:contains(\"") > -1) {
926 var userItem = item.substr(item.indexOf("$('button:contains(\"")+20);
927 result.action.type = "Item";
928 result.action.name = userItem.substr(0,userItem.indexOf(" ("));
929 result.action.successful = true;
930
931 } else if(item.indexOf("$combat_round.append") > -1 &&
932 item.indexOf("you") > -1)
933 {
934 var combatText = item.split("\"")[1];
935
936 if(combatText.indexOf("experience.") > -1) {
937 var parts = combatText.split(" ");
938 result.affinities[parts[3]] = parseInt(parts[2]);
939 } else if(combatText.indexOf("leol.") > -1) {
940 var parts = combatText.split(" ");
941 result.leol = parseInt(parts[2]);
942 } else if(combatText.indexOf("experience,") > -1) {
943 var parts = combatText
944 .replace("you gained ","")
945 .split(", ");
946 for(var j = 0; j < parts.length; j++){
947 var experienceString = parts[j].split(" ");
948 result.stats[experienceString[1]] = parseInt(experienceString[0]);
949 }
950 result.leol = parseInt(parts[2]);
951 } else if(combatText.indexOf("you killed the ") > -1) {
952 result.monster.name = combatText.replace("you killed the ","").replace("! <br/>","");
953 result.monster.slain = true;
954 } else if(combatText.indexOf(". you now have ") > -1) {
955 var itemStringParts = combatText.substr(11, combatText.indexOf("(")-11).split(" ");
956 var itemString = "";
957 for(var k = 1; k < itemStringParts.length; k++){
958 itemString += (itemString == "" ? "" : " ") + itemStringParts[k];
959 }
960 result.loot[itemString] = parseInt(itemStringParts[0]);
961 } else {
962 if(result.action.name == "Unknown") {
963 for(var l = 0; l < combat.actionDictionary.skills.length; l++) {
964 if(combatText.startsWith(combat.actionDictionary.skills[l].text.toLowerCase())) {
965 result.action = combat.actionDictionary.skills[l];
966 result.action.type = "Skill";
967 }
968 }
969 }
970 }
971
972 }
973 }
974 return result;
975 },
976 logBattleRound: function(result){
977
978
979
980 combat.data.update = moment().valueOf();
981 combat.data.rounds += 1;
982 combat.data.leol += result.leol;
983
984
985 if(result.player.slain) {
986 combat.data.loss += 1;
987 }
988
989 //create action stub if not exists:
990 if(result.action.type=="Skill") {
991 if(!combat.data.actions[result.action.name]) {
992 combat.data.actions[result.action.name] = {successful: 0, unsuccessful: 0};
993 }
994
995 //count action:
996 if(result.action.successful) {
997 combat.data.actions[result.action.name].successful += 1;
998 } else {
999 combat.data.actions[result.action.name].unsuccessful += 1;
1000 }
1001 } else if(result.action.type=="Item") {
1002 if(!combat.data.items[result.action.name]) {
1003 combat.data.items[result.action.name] = {count: 1};
1004 } else {
1005 combat.data.items[result.action.name].count += 1;
1006 }
1007 }
1008
1009 //if monster was slain, count:
1010 if(result.monster.slain) {
1011 if(!combat.data.monsters[result.monster.name]) {
1012 combat.data.monsters[result.monster.name] = 1;
1013 } else {
1014 combat.data.monsters[result.monster.name] += 1;
1015 }
1016 combat.data.inCombat = false;
1017 combat.data.win += 1;
1018 } else {
1019 combat.data.inCombat = true;
1020 }
1021
1022 for(var stat in result.stats)
1023 {
1024 if(!combat.data.stats[stat]) {
1025 combat.data.stats[stat] = result.stats[stat];
1026 } else {
1027 combat.data.stats[stat] += result.stats[stat];
1028 }
1029 }
1030
1031 for(var affinity in result.affinities)
1032 {
1033 if(!combat.data.affinities[affinity]) {
1034 combat.data.affinities[affinity] = result.affinities[affinity];
1035 } else {
1036 combat.data.affinities[affinity] += result.affinities[affinity];
1037 }
1038 }
1039
1040 for(var item in result.loot)
1041 {
1042 if(!combat.data.loot[item]) {
1043 combat.data.loot[item] = result.loot[item];
1044 } else {
1045 combat.data.loot[item] += result.loot[item];
1046 }
1047 }
1048
1049 storage.Structure.Data.CombatData.ChartData = combat.data;
1050
1051 storage.save();
1052
1053 combat.updateGraph();
1054
1055 console.log(combat.data.actions);
1056
1057 },
1058 updateGraph: function() {
1059
1060 var now = moment();
1061 var tickTime = combat.data.update - combat.data.since;
1062 combat.data.ticks += 1;
1063 var avgTickTime = tickTime / combat.data.ticks;
1064 var exp_all = 0;
1065 for(var affinity in combat.data.affinities) {
1066 exp_all += combat.data.affinities[affinity];
1067 }
1068
1069 //Handles Graph For Leol Data
1070 if(combat.data.ticks > 0) {
1071 myCombatLine.data.datasets[0].data.push({
1072 x: now,
1073 y: (combat.data.leol / combat.data.ticks).toFixed(2),
1074 });
1075 myCombatLine.data.datasets[1].data.push({
1076 x: now,
1077 y: (combat.data.leol / ((avgTickTime/1000) * combat.data.ticks)).toFixed(2),
1078 });
1079 }
1080
1081 //Handles Graph for Affiny XP
1082 if(combat.data.ticks > 0) {
1083 myCombatLine2.data.datasets[0].data.push({
1084 x: now,
1085 y: (exp_all / combat.data.ticks).toFixed(2),
1086 });
1087 myCombatLine2.data.datasets[1].data.push({
1088 x: now,
1089 y: (exp_all / ((avgTickTime/1000) * combat.data.ticks)).toFixed(2),
1090 });
1091 }
1092
1093 //Handles Graph for Attribute XP
1094 var increment = 0;
1095 for(var stat in combat.data.stats) {
1096 var newColor = helper.getRandomColor();
1097
1098 if(combat.data.stats[stat] > -1 && combat.data.statsEnabled[stat] == false) {
1099 var newDataset = {
1100 label: stat[0].toUpperCase() + stat.substring(1),
1101 backgroundColor: newColor,
1102 borderColor: newColor,
1103 data: [],
1104 fill: false
1105 };
1106 myCombatLine3.data.datasets.push(newDataset);
1107 combat.data.statsEnabled[stat] = true;
1108 }
1109 myCombatLine3.data.datasets[increment].data.push({
1110 x: now,
1111 y: (combat.data.stats[stat] / combat.data.ticks).toFixed(2),
1112 });
1113 increment++;
1114 }
1115
1116 // Handles Monster Kill Pie Chart
1117 var monList = [];
1118 var monData = [];
1119 var monColor = [];
1120 var monCount = 0;
1121
1122 for(var monster in combat.data.monsters) {
1123 monData.push(combat.data.monsters[monster]);
1124 monList.push(helper.toTitleCase(monster));
1125 monColor.push(helper.getRandomColor());
1126 monCount++;
1127 }
1128
1129 if(monCount > combat.totalMonKilled) {
1130 combat.monPieKillList[monCount-1] = monList[monCount-1];
1131 combat.monPieKillChart.backgroundColor[monCount-1] = monColor[monCount-1];
1132 combat.monPieKillChart.borderColor[monCount-1] = monColor[monCount-1];
1133 combat.monPieKillChart.data = monData;
1134
1135 myCombatPie1.config.data.labels = combat.monPieKillList;
1136 myCombatPie1.data.datasets[0] = combat.monPieKillChart;
1137 combat.totalMonKilled = monCount;
1138 } else {
1139 combat.monPieKillChart.data = monData;
1140 myCombatPie1.data.datasets[0] = combat.monPieKillChart;
1141 }
1142
1143 // Handles Monster Drop Pie Chart
1144 var monDropList = [];
1145 var monDropData = [];
1146 var monDropColor = [];
1147 var monDropCount = 0;
1148
1149 for(var loots in combat.data.loot) {
1150 monDropData.push(combat.data.loot[loots]);
1151 monDropList.push(helper.toTitleCase(loots));
1152 monDropColor.push(helper.getRandomColor());
1153
1154 monDropCount++;
1155 }
1156
1157 if(monDropCount > combat.totalMonDrops) {
1158 combat.monPieDropList[monDropCount-1] = monDropList[monDropCount-1];
1159 combat.monPieDropChart.backgroundColor[monDropCount-1] = monDropColor[monDropCount-1];
1160 combat.monPieDropChart.borderColor[monDropCount-1] = monDropColor[monDropCount-1];
1161 combat.monPieDropChart.data = monDropData;
1162
1163 myCombatPie2.config.data.labels = combat.monPieDropList;
1164 myCombatPie2.data.datasets[0] = combat.monPieDropChart;
1165 combat.totalMonDrops = monDropCount;
1166
1167 }
1168 else
1169 {
1170 combat.monPieDropChart.data = monDropData;
1171 myCombatPie2.data.datasets[0] = combat.monPieDropChart;
1172 }
1173
1174 // Handles Combat Data Tables
1175 var runtime = (new Date(combat.data.update) - new Date(combat.data.since))/(3600000);
1176 var success = 0;
1177 var failure = 0;
1178 var totalStat = 0;
1179 for(var action in combat.data.actions) {
1180 success += combat.data.actions[action].successful;
1181 failure += combat.data.actions[action].unsuccessful;
1182 }
1183 for(var stat in combat.data.stats) {
1184 totalStat += combat.data.stats[stat];
1185 }
1186 $("#combat_accuracy")[0].innerText = success.toString() + ' of ' + (success+failure).toString() + ' ('+ (Math.round(success/(success+failure)*10000)/100).toString() + '%)';
1187 $("#combat_actions")[0].innerText = helper.addCommas(combat.data.rounds);
1188 $("#combat_exp")[0].innerText = helper.addCommas(exp_all);
1189 $("#combat_leol")[0].innerText = helper.addCommas(combat.data.leol);
1190 $("#combat_exp_hour")[0].innerText = helper.addCommas(Math.round(exp_all/runtime*100)/100);
1191 $("#combat_leol_hour")[0].innerText = helper.addCommas(Math.round(combat.data.leol/runtime*100)/100);
1192
1193 $("#combat_tick_time")[0].innerText = helper.addCommas((avgTickTime/1000).toFixed(2)) + ' Seconds';
1194 $("#combat_tick_day")[0].innerText = helper.addCommas((86400/(avgTickTime/1000)).toFixed(2)) + ' Ticks';
1195
1196 $("#combat_total_str")[0].innerText = helper.addCommas(combat.data.stats.strength);
1197 $("#combat_total_stam")[0].innerText = helper.addCommas(combat.data.stats.stamina);
1198 $("#combat_total_dex")[0].innerText = helper.addCommas(combat.data.stats.dexterity);
1199 $("#combat_total_int")[0].innerText = helper.addCommas(combat.data.stats.intellect);
1200 $("#combat_total_will")[0].innerText = helper.addCommas(combat.data.stats.will);
1201 $("#combat_att_per_hour")[0].innerText = helper.addCommas(Math.round(totalStat/runtime*100)/100);
1202 var expPerTick = (combat.data.stats.strength+combat.data.stats.stamina+combat.data.stats.dexterity+combat.data.stats.intellect+combat.data.stats.will)/combat.data.rounds;
1203 $("#combat_att_per_tick")[0].innerText = helper.addCommas(Math.round(expPerTick));
1204
1205
1206
1207
1208 if(combat.tickCounter > 120) {
1209 myCombatLine.data.datasets[0].data.shift();
1210 myCombatLine.data.datasets[1].data.shift();
1211 myCombatLine2.data.datasets[0].data.shift();
1212 myCombatLine2.data.datasets[1].data.shift();
1213 for(var i = 0; i < increment; i++)
1214 {
1215 myCombatLine3.data.datasets[i].data.shift();
1216 }
1217 }
1218 combat.tickCounter++;
1219
1220 myCombatLine.update();
1221 myCombatLine2.update();
1222 myCombatLine3.update();
1223 myCombatPie1.update();
1224 myCombatPie2.update();
1225
1226 },
1227 getString: function() {
1228 return JSON.stringify(combat.data);
1229 },
1230 log: function() {
1231 console.log(combat.getString());
1232 }
1233};
1234
1235var helper = {
1236 toTitleCase: function(str)
1237 {
1238 return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
1239 },
1240 getRandomColor: function() {
1241 var letters = '0123456789ABCDEF';
1242 var color = '#';
1243 for (var i = 0; i < 6; i++) {
1244 color += letters[Math.floor(Math.random() * 16)];
1245 }
1246 return color;
1247 },
1248 addCommas: function(x) {
1249 return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
1250 }
1251};
1252
1253init.initialize();