Eternity Tower Enemy Target Button

Adds a target button to enemies in battle

目前为 2018-10-02 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Eternity Tower Enemy Target Button
  3. // @icon https://www.eternitytower.net/favicon.png
  4. // @namespace http://mean.cloud/
  5. // @version 1.04
  6. // @description Adds a target button to enemies in battle
  7. // @match *://*.eternitytower.net/*
  8. // @author psouza4@gmail.com
  9. // @copyright 2017-2018, MeanCloud
  10. // @run-at document-end
  11. // ==/UserScript==
  12.  
  13.  
  14. ////////////////////////////////////////////////////////////////
  15. ////////////// ** SCRIPT GLOBAL INITIALIZATION ** //////////////
  16. function startup() { ET_EnemyTargetButtonMod(); }
  17. ////////////////////////////////////////////////////////////////
  18.  
  19.  
  20. ET_EnemyTargetButtonMod = function()
  21. {
  22. ET.MCMF.Ready(function()
  23. {
  24. jQ("head").append
  25. (
  26. "<style type=\"text/css\">\r\n" +
  27. ".MCETMod_EnemyTarget_imgdisabled {\r\n" +
  28. " background-color: #fff7f7;\r\n" +
  29. "}\r\n" +
  30. ".MCETMod_EnemyTarget_btndisabled {\r\n" +
  31. " width: 96px; height: 30px; font-size: 10pt; font-weight: normal;\r\n" +
  32. "}\r\n" +
  33. ".MCETMod_EnemyTarget_imgenabled {\r\n" +
  34. " background-color: #fffadd;\r\n" +
  35. "}\r\n" +
  36. ".MCETMod_EnemyTarget_btnenabled {\r\n" +
  37. " width: 96px; height: 30px; font-size: 10pt; font-weight: bold;\r\n" +
  38. "}\r\n" +
  39. ".MCETMod_EnemyTarget_btnenabled:hover {\r\n" +
  40. " color: #fff;\r\n" +
  41. " background-color: #f0ad4e;\r\n" +
  42. " border-color: #f0ad4e;\r\n" +
  43. "}\r\n"
  44. );
  45.  
  46. Meteor.connection._stream.on('message', function(sMeteorRawData)
  47. {
  48. try
  49. {
  50. var oMeteorData = JSON.parse(sMeteorRawData);
  51.  
  52. if ((oMeteorData.id !== undefined) && (oMeteorData.collection === "battlesList") && (oMeteorData.msg === "added"))
  53. MCETMod_CurrentBattleListID = oMeteorData.id;
  54. }
  55. catch (err) { }
  56. });
  57. });
  58. ET.MCMF.EventSubscribe("ET:combatTick", function()
  59. {
  60. try
  61. {
  62. if (ET.MCMF.BattleUITemplate !== undefined)
  63. {
  64. //ET.MCMF.Log(JSON.stringify(ET.MCMF.LiveBattleData()));
  65. let battleData = ET.MCMF.LiveBattleData();
  66. // Note, the game does not switch targets if the currently-targeted enemy is dead.
  67. // Instead, we must assume that we're now automatically targeting the prior (or first) enemy in this case.
  68. MCETMod_CurrentTargetID = "";
  69. MCETMod_FirstEnemyID = "";
  70. jQ.makeArray(battleData.units).forEach(function(currentPlayer, index, array) {
  71. if (currentPlayer.name === ET.MCMF.UserName)
  72. MCETMod_CurrentTargetID = currentPlayer.target; });
  73. MCETMod_TargetIsDead = false;
  74. MCETMod_TargetIsFound = false;
  75. MCETMod_PriorMonster = "";
  76. jQ.makeArray(battleData.enemies).forEach(function(currentMonster, index, array)
  77. {
  78. if (currentMonster.id === MCETMod_CurrentTargetID)
  79. {
  80. MCETMod_TargetIsFound = true;
  81. if (currentMonster.health <= 0)
  82. MCETMod_TargetIsDead = true;
  83. }
  84.  
  85. if (!MCETMod_TargetIsFound)
  86. MCETMod_PriorMonster = currentMonster.id;
  87. });
  88. if (!MCETMod_TargetIsFound) MCETMod_PriorMonster = "";
  89. try { MCETMod_FirstEnemyID = jQ.makeArray(battleData.enemies)[0].id; } catch (err) { }
  90. if ((MCETMod_TargetIsDead) || (!MCETMod_TargetIsFound) || (MCETMod_CurrentTargetID === ""))
  91. MCETMod_CurrentTargetID = ((MCETMod_PriorMonster !== "") ? (MCETMod_PriorMonster) : (MCETMod_FirstEnemyID));
  92.  
  93. jQ.makeArray(battleData.enemies).forEach(function(currentMonster, index, array)
  94. {
  95. sThisMonsterID = currentMonster.id;
  96. dThisMonsterArmor = parseFloat(currentMonster.stats.armor);
  97. if (dThisMonsterArmor < parseFloat(0))
  98. dThisMonsterArmor = parseFloat(0);
  99.  
  100. jQ("div.battle-unit-container").each(function()
  101. {
  102. try
  103. {
  104. sMonsterID = jQ(this).find("img.enemy-icon")[0].id;
  105.  
  106. if (sThisMonsterID === sMonsterID)
  107. {
  108. jQ(this).parent().find(".MCETMod_EnemyTarget").remove();
  109.  
  110. if (MCETMod_CurrentTargetID === sThisMonsterID)
  111. {
  112. jQ(this).parent().find("img.enemy-icon").removeClass("MCETMod_EnemyTarget_imgenabled").addClass("MCETMod_EnemyTarget_imgdisabled").after(
  113. "<div class=\"MCETMod_EnemyTarget\">" +
  114. "<button class=\"MCETMod_EnemyTarget_btndisabled btn btn-danger\" type=\"button\" disabled>Targeting</button>" +
  115. "</div>");
  116. }
  117. else
  118. {
  119. jQ(this).parent().find("img.enemy-icon").removeClass("MCETMod_EnemyTarget_imgdisabled").addClass("MCETMod_EnemyTarget_imgenabled").after(
  120. "<div class=\"MCETMod_EnemyTarget\">" +
  121. "<button class=\"MCETMod_EnemyTarget_btnenabled btn btn-warning\" type=\"button\" onclick=\"javascript:ET_EnemyTargetButtonMod_TargetCreature('" + sThisMonsterID + "');\">Target</button>" +
  122. "</div>");
  123. }
  124. }
  125. }
  126. catch (err) { }
  127. });
  128. });
  129. }
  130. }
  131. catch (err) { }
  132. });
  133. };
  134.  
  135. ET_EnemyTargetButtonMod_TargetCreature = function(which_id)
  136. {
  137. // this is no longer sent in the main websocket
  138. //Meteor.connection._send({"msg":"method","method":"battles.castAbility","params":[MCETMod_CurrentBattleListID,"changeTarget",{"targets":[which_id],"caster":ET.MCMF.UserID}],"id":"MCETModRetarget"});
  139. // it's now sent in the battleSocket using battleSocket.emit()
  140. ET.MCMF.BattleSocket_UseAbility("changeTarget", which_id);
  141. };
  142.  
  143.  
  144. ////////////////////////////////////////////////////////////////
  145. /////////////// ** common.js -- DO NOT MODIFY ** ///////////////
  146. time_val = function()
  147. {
  148. return CDbl(Math.floor(Date.now() / 1000));
  149. };
  150.  
  151. IsValid = function(oObject)
  152. {
  153. if (oObject === undefined) return false;
  154. if (oObject === null) return false;
  155. return true;
  156. };
  157.  
  158. Random = function(iMin, iMax)
  159. {
  160. return parseInt(iMin + Math.floor(Math.random() * iMax));
  161. };
  162.  
  163. ShiftClick = function(oEl)
  164. {
  165. jQ(oEl).trigger(ShiftClickEvent());
  166. };
  167.  
  168. ShiftClickEvent = function(target)
  169. {
  170. let shiftclickOrig = jQ.Event("click");
  171. shiftclickOrig.which = 1; // 1 = left, 2 = middle, 3 = right
  172. //shiftclickOrig.type = "click"; // "mousedown" ?
  173. shiftclickOrig.currentTarget = target;
  174. shiftclickOrig.shiftKey = true;
  175.  
  176. let shiftclick = jQ.Event("click");
  177. //shiftclick.type = "click"; // "mousedown" ?
  178. shiftclick.which = 1; // 1 = left, 2 = middle, 3 = right
  179. shiftclick.shiftKey = true;
  180. shiftclick.currentTarget = target;
  181. shiftclick.originalEvent = shiftclickOrig;
  182.  
  183. //document.ET_Util_Log(shiftclick);
  184.  
  185. return shiftclick;
  186. };
  187.  
  188. if (!String.prototype.replaceAll)
  189. String.prototype.replaceAll = function(search, replace) { return ((replace === undefined) ? this.toString() : this.replace(new RegExp('[' + search + ']', 'g'), replace)); };
  190.  
  191. if (!String.prototype.startsWith)
  192. String.prototype.startsWith = function(search, pos) { return this.substr(((!pos) || (pos < 0)) ? 0 : +pos, search.length) === search; };
  193.  
  194. CInt = function(v)
  195. {
  196. try
  197. {
  198. if (!isNaN(v)) return Math.floor(v);
  199. if (typeof v === 'undefined') return parseInt(0);
  200. if (v === null) return parseInt(0);
  201. let t = parseInt(v);
  202. if (isNaN(t)) return parseInt(0);
  203. return Math.floor(t);
  204. }
  205. catch (err) { }
  206.  
  207. return parseInt(0);
  208. };
  209.  
  210. CDbl = function(v)
  211. {
  212. try
  213. {
  214. if (!isNaN(v)) return parseFloat(v);
  215. if (typeof v === 'undefined') return parseFloat(0.0);
  216. if (v === null) return parseFloat(0.0);
  217. let t = parseFloat(v);
  218. if (isNaN(t)) return parseFloat(0.0);
  219. return t;
  220. }
  221. catch (err) { }
  222.  
  223. return parseFloat(0.0);
  224. };
  225.  
  226. // dup of String.prototype.startsWith, but uses indexOf() instead of substr()
  227. startsWith = function (haystack, needle) { return (needle === "") || (haystack.indexOf(needle) === 0); };
  228. endsWith = function (haystack, needle) { return (needle === "") || (haystack.substring(haystack.length - needle.length) === needle); };
  229.  
  230. Chopper = function(sText, sSearch, sEnd)
  231. {
  232. let sIntermediate = "";
  233.  
  234. if (sSearch === "")
  235. sIntermediate = sText.substring(0, sText.length);
  236. else
  237. {
  238. let iIndexStart = sText.indexOf(sSearch);
  239. if (iIndexStart === -1)
  240. return sText;
  241.  
  242. sIntermediate = sText.substring(iIndexStart + sSearch.length);
  243. }
  244.  
  245. if (sEnd === "")
  246. return sIntermediate;
  247.  
  248. let iIndexEnd = sIntermediate.indexOf(sEnd);
  249.  
  250. return (iIndexEnd === -1) ? sIntermediate : sIntermediate.substring(0, iIndexEnd);
  251. };
  252.  
  253. ChopperBlank = function(sText, sSearch, sEnd)
  254. {
  255. let sIntermediate = "";
  256.  
  257. if (sSearch === "")
  258. sIntermediate = sText.substring(0, sText.length);
  259. else
  260. {
  261. let iIndexStart = sText.indexOf(sSearch);
  262. if (iIndexStart === -1)
  263. return "";
  264.  
  265. sIntermediate = sText.substring(iIndexStart + sSearch.length);
  266. }
  267.  
  268. if (sEnd === "")
  269. return sIntermediate;
  270.  
  271. let iIndexEnd = sIntermediate.indexOf(sEnd);
  272.  
  273. return (iIndexEnd === -1) ? "" : sIntermediate.substring(0, iIndexEnd);
  274. };
  275.  
  276. CondenseSpacing = function(text)
  277. {
  278. while (text.indexOf(" ") !== -1)
  279. text = text.replace(" ", " ");
  280. return text;
  281. };
  282.  
  283. // pad available both ways as pad(string, width, [char]) or string.pad(width, [char])
  284. pad = function(sText, iWidth, sChar)
  285. {
  286. sChar = ((sChar !== undefined) ? sChar : ('0'));
  287. sText = sText.toString();
  288. return ((sText.length >= iWidth) ? (sText) : (new Array(iWidth - sText.length + 1).join(sChar) + sText));
  289. };
  290.  
  291. if (!String.prototype.pad)
  292. String.prototype.pad = function(iWidth, sChar)
  293. {
  294. sChar = ((sChar !== undefined) ? sChar : ('0'));
  295. sText = sText.toString();
  296. return ((sText.length >= iWidth) ? (sText) : (new Array(iWidth - sText.length + 1).join(sChar) + sText));
  297. };
  298.  
  299. String.prototype.toHHMMSS = function () {
  300. var sec_num = parseInt(this, 10);
  301. var hours = Math.floor(sec_num / 3600);
  302. var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
  303. var seconds = sec_num - (hours * 3600) - (minutes * 60);
  304.  
  305. if (hours < 10) {hours = "0"+hours;}
  306. if (minutes < 10) {minutes = "0"+minutes;}
  307. if (seconds < 10) {seconds = "0"+seconds;}
  308. return hours+':'+minutes+':'+seconds;
  309. };
  310. is_visible = (function () {
  311. var x = window.pageXOffset ? window.pageXOffset + window.innerWidth - 1 : 0,
  312. y = window.pageYOffset ? window.pageYOffset + window.innerHeight - 1 : 0,
  313. relative = !!((!x && !y) || !document.elementFromPoint(x, y));
  314. function inside(child, parent) {
  315. while(child){
  316. if (child === parent) return true;
  317. child = child.parentNode;
  318. }
  319. return false;
  320. }
  321. return function (elem) {
  322. if (
  323. hidden ||
  324. elem.offsetWidth==0 ||
  325. elem.offsetHeight==0 ||
  326. elem.style.visibility=='hidden' ||
  327. elem.style.display=='none' ||
  328. elem.style.opacity===0
  329. ) return false;
  330. var rect = elem.getBoundingClientRect();
  331. if (relative) {
  332. if (!inside(document.elementFromPoint(rect.left + elem.offsetWidth/2, rect.top + elem.offsetHeight/2),elem)) return false;
  333. } else if (
  334. !inside(document.elementFromPoint(rect.left + elem.offsetWidth/2 + window.pageXOffset, rect.top + elem.offsetHeight/2 + window.pageYOffset), elem) ||
  335. (
  336. rect.top + elem.offsetHeight/2 < 0 ||
  337. rect.left + elem.offsetWidth/2 < 0 ||
  338. rect.bottom - elem.offsetHeight/2 > (window.innerHeight || document.documentElement.clientHeight) ||
  339. rect.right - elem.offsetWidth/2 > (window.innerWidth || document.documentElement.clientWidth)
  340. )
  341. ) return false;
  342. if (window.getComputedStyle || elem.currentStyle) {
  343. var el = elem,
  344. comp = null;
  345. while (el) {
  346. if (el === document) {break;} else if(!el.parentNode) return false;
  347. comp = window.getComputedStyle ? window.getComputedStyle(el, null) : el.currentStyle;
  348. if (comp && (comp.visibility=='hidden' || comp.display == 'none' || (typeof comp.opacity !=='undefined' && comp.opacity != 1))) return false;
  349. el = el.parentNode;
  350. }
  351. }
  352. return true;
  353. };
  354. })();
  355. ////////////////////////////////////////////////////////////////
  356.  
  357.  
  358. ////////////////////////////////////////////////////////////////
  359. ////////////// ** common_ET.js -- DO NOT MODIFY ** /////////////
  360. if (window.ET === undefined) window.ET = { };
  361. if ((window.ET.MCMF === undefined) || (CDbl(window.ET.MCMF.version) < 1.06)) // MeanCloud mod framework
  362. {
  363. window.ET.MCMF =
  364. {
  365. version: 1.06,
  366. TryingToLoad: false,
  367. WantDebug: false,
  368. WantFasterAbilityCDs: false,
  369.  
  370. InBattle: false,
  371. FinishedLoading: false,
  372. Initialized: false,
  373. AbilitiesReady: false,
  374. InitialAbilityCheck: true,
  375. TimeLeftOnCD: 9999,
  376. TimeLastFight: 0,
  377.  
  378. CombatID: undefined,
  379. BattleID: undefined,
  380.  
  381. ToastMessageSuccess: function(msg)
  382. {
  383. toastr.success(msg);
  384. },
  385.  
  386. ToastMessageWarning: function(msg)
  387. {
  388. toastr.warning(msg);
  389. },
  390.  
  391. EventSubscribe: function(sEventName, fnCallback, sNote)
  392. {
  393. if (window.ET.MCMF.EventSubscribe_events === undefined)
  394. window.ET.MCMF.EventSubscribe_events = [];
  395.  
  396. let newEvtData = {};
  397. newEvtData.name = ((!sEventName.startsWith("ET:")) ? ("ET:" + sEventName) : (sEventName));
  398. newEvtData.callback = fnCallback;
  399. newEvtData.note = sNote;
  400.  
  401. window.ET.MCMF.EventSubscribe_events.push(newEvtData);
  402.  
  403. /*
  404. jQ("div#ET_meancloud_bootstrap").off("ET:" + sEventName.trim()).on("ET:" + sEventName.trim(), function()
  405. {
  406. window.ET.MCMF.EventSubscribe_events.forEach(function(oThisEvent)
  407. {
  408. if (sEventName === oThisEvent.name)
  409. {
  410. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("FIRING '" + oThisEvent.name + "'!" + ((oThisEvent.note === undefined) ? "" : " (" + oThisEvent.note + ")"));
  411. oThisEvent.callback();
  412. }
  413. });
  414. });
  415. */
  416.  
  417. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Added event subscription '" + sEventName + "'!" + ((sNote === undefined) ? "" : " (" + sNote + ")"));
  418. },
  419.  
  420. EventTrigger: function(sEventName)
  421. {
  422. //jQ("div#ET_meancloud_bootstrap").trigger(sEventName);
  423.  
  424. if (window.ET.MCMF.EventSubscribe_events === undefined) return;
  425.  
  426. window.ET.MCMF.EventSubscribe_events.forEach(function(oThisEvent)
  427. {
  428. if (sEventName === oThisEvent.name)
  429. {
  430. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("FIRING '" + oThisEvent.name + "'!" + ((oThisEvent.note === undefined) ? "" : " (" + oThisEvent.note + ")"));
  431. try { oThisEvent.callback(); } catch (err) { if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Exception: " + err); }
  432. }
  433. });
  434. },
  435. Log: function(msg)
  436. {
  437. try
  438. {
  439. let now_time = new Date();
  440. let timestamp = (now_time.getMonth() + 1).toString() + "/" + now_time.getDate().toString() + "/" + (now_time.getYear() + 1900).toString() + " " + ((now_time.getHours() === 0) ? (12) : ((now_time.getHours() > 12) ? (now_time.getHours() - 12) : (now_time.getHours()))).toString() + ":" + now_time.getMinutes().toString().padStart(2, "0") + ":" + now_time.getSeconds().toString().padStart(2, "0") + ((now_time.getHours() < 12) ? ("am") : ("pm")) + " :: ";
  441. console.log(timestamp.toString() + msg);
  442. }
  443. catch (err) { }
  444. },
  445.  
  446. Time: function() // returns time in milliseconds (not seconds!)
  447. {
  448. return CInt((new Date()).getTime());
  449. },
  450.  
  451. SubscribeToGameChannel: function(channel_name)
  452. {
  453. let oChannel;
  454.  
  455. try
  456. {
  457. channel_name = channel_name.toString().trim();
  458.  
  459. let bAlreadySubscribed = false;
  460.  
  461. jQuery.makeArray(Object.keys(Package.meteor.global.Accounts.connection._subscriptions).map(key => Package.meteor.global.Accounts.connection._subscriptions[key])).forEach(function(oThisConnection)
  462. {
  463. try
  464. {
  465. if (oThisConnection.name === channel_name)
  466. bAlreadySubscribed = true;
  467. }
  468. catch (err) { }
  469. });
  470.  
  471. if (!bAlreadySubscribed)
  472. {
  473. Meteor.subscribe(channel_name);
  474. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Meteor::Subscribed to channel '" + channel_name + "'");
  475. }
  476. //else if (ET.MCMF.WantDebug)
  477. // window.ET.MCMF.Log("Meteor::Already subscribed to channel '" + channel_name + "'");
  478. }
  479. catch (err)
  480. {
  481. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Meteor::Exception in SubscribeToGameChannel(\"" + channel_name + "\")");
  482. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log(err);
  483. }
  484.  
  485. return oChannel;
  486. },
  487. CraftingBuff: function()
  488. {
  489. let oDate, iTimeLeft;
  490. try
  491. {
  492. oDate = new Date(Meteor.connection._stores.state._getCollection().find({ name: "buffCrafting" }).fetch()[0].value.activeTo);
  493. iTimeLeft = ((oDate) > (new Date())) ? CInt(Math.floor(Math.abs(oDate - (new Date())) / 1000.0)) : 0;
  494. return { active: (iTimeLeft > 0), remaining: iTimeLeft, expires: oDate };
  495. }
  496. catch (err) { }
  497. return { active: false, remaining: 0, expires: oDate };
  498. },
  499. CombatBuff: function()
  500. {
  501. let oDate, iTimeLeft;
  502. try
  503. {
  504. oDate = new Date(Meteor.connection._stores.state._getCollection().find({ name: "buffCombat" }).fetch()[0].value.activeTo);
  505. iTimeLeft = ((oDate) > (new Date())) ? CInt(Math.floor(Math.abs(oDate - (new Date())) / 1000.0)) : 0;
  506. return { active: (iTimeLeft > 0), remaining: iTimeLeft, expires: oDate };
  507. }
  508. catch (err) { }
  509. return { active: false, remaining: 0, expires: oDate };
  510. },
  511. GatheringBuff: function()
  512. {
  513. let oDate, iTimeLeft;
  514. try
  515. {
  516. oDate = new Date(Meteor.connection._stores.state._getCollection().find({ name: "buffGathering" }).fetch()[0].value.activeTo);
  517. iTimeLeft = ((oDate) > (new Date())) ? CInt(Math.floor(Math.abs(oDate - (new Date())) / 1000.0)) : 0;
  518. return { active: (iTimeLeft > 0), remaining: iTimeLeft, expires: oDate };
  519. }
  520. catch (err) { }
  521. return { active: false, remaining: 0, expires: oDate };
  522. },
  523. IsNewCombatTab: function()
  524. {
  525. try {
  526. if (window.location.href.indexOf("/newCombat") !== -1) {
  527. return true; }
  528. }
  529. catch (err) {
  530. }
  531. return false;
  532. },
  533. GetActiveTab: function()
  534. {
  535. let active_tab = "";
  536. /*
  537. try
  538. {
  539. active_tab = jQuery(jQuery("a.active").get(0)).text().trim().toLowerCase();
  540. if (active_tab.length === 0)
  541. throw "Invalid active tab";
  542. if (active_tab === "mine") active_tab = "mining";
  543. if (active_tab === "craft") active_tab = "crafting";
  544. if (active_tab === "battle") active_tab = "combat";
  545. if (active_tab === "woodcut") active_tab = "woodcutting";
  546. if (active_tab === "farm") active_tab = "farming";
  547. if (active_tab === "inscribe") active_tab = "inscription";
  548. //if (active_tab === "inscription") active_tab = "inscription";
  549. //if (active_tab === "magic") active_tab = "magic";
  550. //if (active_tab === "shop") active_tab = "shop";
  551. }
  552. catch (err)
  553. {
  554. */
  555. if (window.location.href.indexOf("/gameHome") !== -1) active_tab = "home";
  556. if (window.location.href.indexOf("/mining") !== -1) active_tab = "mining";
  557. if (window.location.href.indexOf("/crafting") !== -1) active_tab = "crafting";
  558. if (window.location.href.indexOf("/combat") !== -1) active_tab = "combat";
  559. if (window.location.href.indexOf("/newCombat") !== -1) active_tab = "combat";
  560. if (window.location.href.indexOf("/woodcutting") !== -1) active_tab = "woodcutting";
  561. if (window.location.href.indexOf("/farming") !== -1) active_tab = "farming";
  562. if (window.location.href.indexOf("/inscription") !== -1) active_tab = "inscription";
  563. if (window.location.href.indexOf("/magic") !== -1) active_tab = "magic";
  564. if (window.location.href.indexOf("/faq") !== -1) active_tab = "faq";
  565. if (window.location.href.indexOf("/chat") !== -1) active_tab = "chat";
  566. if (window.location.href.indexOf("/skills") !== -1) active_tab = "skills";
  567. if (window.location.href.indexOf("/achievements") !== -1) active_tab = "achievements";
  568. if (window.location.href.indexOf("/updates") !== -1) active_tab = "updates";
  569. /*
  570. }
  571. */
  572. return active_tab;
  573. },
  574. GetActiveTabSection: function()
  575. {
  576. let active_tab_section = "";
  577. try
  578. {
  579. let active_tab = window.ET.MCMF.GetActiveTab();
  580.  
  581. if (active_tab === "mining") active_tab_section = Meteor.connection._stores.users._getCollection().find().fetch()[0].uiState.miningTab;
  582. if (active_tab === "crafting") active_tab_section = Meteor.connection._stores.users._getCollection().find().fetch()[0].uiState.craftingFilter;
  583. if (active_tab === "combat")
  584. {
  585. if (window.ET.MCMF.IsNewCombatTab())
  586. active_tab_section = Meteor.connection._stores.users._getCollection().find().fetch()[0].uiState.newCombatType;
  587. else
  588. active_tab_section = Meteor.connection._stores.users._getCollection().find().fetch()[0].uiState.combatTab;
  589. }
  590. if (active_tab === "farming") active_tab_section = Meteor.connection._stores.users._getCollection().find().fetch()[0].uiState.farmingTab;
  591. if (active_tab === "inscription") active_tab_section = Meteor.connection._stores.users._getCollection().find().fetch()[0].uiState.inscriptionFilter;
  592. if (active_tab === "achievements") active_tab_section = Meteor.connection._stores.users._getCollection().find().fetch()[0].uiState.achievementTab;
  593. if (active_tab === "magic") active_tab_section = Meteor.connection._stores.users._getCollection().find().fetch()[0].uiState.magicTab;
  594.  
  595. active_tab_section = active_tab_section.trim().toLowerCase();
  596.  
  597. if (active_tab_section === "minepit") active_tab_section = "mine pit";
  598. if (active_tab_section === "personalquest") active_tab_section = "personal quest";
  599. if (active_tab_section === "tower") active_tab_section = "the tower";
  600. if (active_tab_section === "battlelog") active_tab_section = "battle log";
  601. if (active_tab_section === "pigment") active_tab_section = "pigments";
  602. if (active_tab_section === "book") active_tab_section = "books";
  603. if (active_tab_section === "magic_book") active_tab_section = "magic books";
  604. if (active_tab_section === "spellbook") active_tab_section = "spell book";
  605. if (active_tab_section.length === 0)
  606. throw "Invalid active tab section";
  607. }
  608. catch (err)
  609. {
  610. try
  611. {
  612. active_tab_section = jQuery(jQuery("a.active").get(1)).text().trim().toLowerCase();
  613. if (active_tab_section.length === 0)
  614. throw "Invalid active tab section";
  615. }
  616. catch (err) { }
  617. }
  618. return active_tab_section;
  619. },
  620. BattleSocket_UseAbility: function(abil, targ)
  621. {
  622. try
  623. {
  624. let sMsg = '';
  625. if (targ === undefined)
  626. {
  627. sMsg = '["action",{"abilityId":"' + abil + '","targets":[],"caster":"' + window.ET.MCMF.UserID + '"}]';
  628. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Battle socket emitting: '" + sMsg + "'");
  629. battleSocket.emit
  630. (
  631. "action",
  632. {
  633. abilityId: abil,
  634. targets: [],
  635. caster: window.ET.MCMF.UserID
  636. }
  637. );
  638. }
  639. else
  640. {
  641. sMsg = '["action",{"abilityId":"' + abil + '","targets":[' + targ + '],"caster":"' + window.ET.MCMF.UserID + '"}]';
  642. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Battle socket emitting: '" + sMsg + "'");
  643. battleSocket.emit
  644. (
  645. "action",
  646. {
  647. abilityId: abil,
  648. targets: [targ],
  649. caster: window.ET.MCMF.UserID
  650. }
  651. );
  652. }
  653. }
  654. catch (err) { }
  655. },
  656.  
  657. CallGameCmd: function()
  658. {
  659. try
  660. {
  661. if (arguments.length > 0)
  662. {
  663. let cmd = arguments[0];
  664. let fnc = function() { };
  665.  
  666. if (arguments.length === 1)
  667. {
  668. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Calling: '" + cmd + "' with no data");
  669. Package.meteor.Meteor.call(cmd, fnc);
  670. }
  671. else
  672. {
  673. let data1, data2, data3, data4;
  674.  
  675. if (typeof arguments[arguments.length - 1] === "function")
  676. {
  677. fnc = arguments[arguments.length - 1];
  678. if (arguments.length >= 3) data1 = arguments[1];
  679. if (arguments.length >= 4) data2 = arguments[2];
  680. if (arguments.length >= 5) data3 = arguments[3];
  681. if (arguments.length >= 6) data4 = arguments[4];
  682. }
  683. else
  684. {
  685. if (arguments.length >= 2) data1 = arguments[1];
  686. if (arguments.length >= 3) data2 = arguments[2];
  687. if (arguments.length >= 4) data3 = arguments[3];
  688. if (arguments.length >= 5) data4 = arguments[4];
  689. }
  690.  
  691. if (data1 === undefined)
  692. {
  693. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Calling: '" + cmd + "' with no data");
  694. Package.meteor.Meteor.call(cmd, fnc);
  695. }
  696. else if (data2 === undefined)
  697. {
  698. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Calling: '" + cmd + "' with { " + JSON.stringify(data1) + " }");
  699. Package.meteor.Meteor.call(cmd, data1, fnc);
  700. }
  701. else if (data3 === undefined)
  702. {
  703. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Calling: '" + cmd + "' with { " + JSON.stringify(data1) + ", " + JSON.stringify(data2) + " }");
  704. Package.meteor.Meteor.call(cmd, data1, data2, fnc);
  705. }
  706. else if (data4 === undefined)
  707. {
  708. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Calling: '" + cmd + "' with { " + JSON.stringify(data1) + ", " + JSON.stringify(data2) + ", " + JSON.stringify(data3) + " }");
  709. Package.meteor.Meteor.call(cmd, data1, data2, data3, fnc);
  710. }
  711. else
  712. {
  713. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Calling: '" + cmd + "' with { " + JSON.stringify(data1) + ", " + JSON.stringify(data2) + ", " + JSON.stringify(data3) + ", " + JSON.stringify(data4) + " }");
  714. Package.meteor.Meteor.call(cmd, data1, data2, data3, data4, fnc);
  715. }
  716. }
  717. }
  718. else if (window.ET.MCMF.WantDebug)
  719. window.ET.MCMF.Log("Meteor::Warning, CallGameCmd() with no arguments!");
  720. }
  721. catch (err)
  722. {
  723. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Meteor::Exception in CallGameCmd()");
  724. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log(err);
  725. }
  726. },
  727.  
  728. SendGameCmd: function(cmd)
  729. {
  730. try
  731. {
  732. Meteor.connection._send(cmd);
  733. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Meteor::Sending: " + JSON.stringify(cmd));
  734. }
  735. catch (err)
  736. {
  737. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("Meteor::Exception in SendGameCmd(" + JSON.stringify(cmd) + ")");
  738. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log(err);
  739. }
  740. },
  741.  
  742. FasterAbilityUpdates: function()
  743. {
  744. try
  745. {
  746. window.ET.MCMF.SubscribeToGameChannel("abilities");
  747. if ((window.ET.MCMF.WantFasterAbilityCDs) && (window.ET.MCMF.FinishedLoading) && (!window.ET.MCMF.InBattle) && (!window.ET.MCMF.AbilitiesReady))
  748. window.ET.MCMF.CallGameCmd("abilities.gameUpdate");
  749. }
  750. catch (err) { }
  751.  
  752. setTimeout(window.ET.MCMF.FasterAbilityUpdates, 2000);
  753. },
  754.  
  755. PlayerInCombat: function()
  756. {
  757. return ((window.ET.MCMF.InBattle) || ((time_val() - window.ET.MCMF.TimeLastFight) < 3));
  758. },
  759. AbilityCDTrigger: function()
  760. {
  761. try
  762. {
  763. if ((window.ET.MCMF.FinishedLoading) && (!window.ET.MCMF.PlayerInCombat()))
  764. {
  765. iTotalCD = 0;
  766. iTotalCDTest = 0;
  767. iHighestCD = 0;
  768.  
  769. window.ET.MCMF.GetAbilities().forEach(function(oThisAbility)
  770. {
  771. if (oThisAbility.equipped)
  772. {
  773. if (parseInt(oThisAbility.currentCooldown) > 0)
  774. {
  775. iTotalCD += parseInt(oThisAbility.currentCooldown);
  776. if (iHighestCD < parseInt(oThisAbility.currentCooldown))
  777. iHighestCD = parseInt(oThisAbility.currentCooldown);
  778. }
  779. }
  780.  
  781. iTotalCDTest += parseInt(oThisAbility.cooldown);
  782. });
  783.  
  784. if ((iTotalCDTest > 0) && (iTotalCD === 0))
  785. {
  786. if (!window.ET.MCMF.AbilitiesReady)
  787. {
  788. if (!window.ET.MCMF.InitialAbilityCheck)
  789. {
  790. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("<-- triggering ET:abilitiesReady -->");
  791. window.ET.MCMF.EventTrigger("ET:abilitiesReady");
  792. }
  793. }
  794.  
  795. window.ET.MCMF.AbilitiesReady = true;
  796. window.ET.MCMF.TimeLeftOnCD = 0;
  797. }
  798. else
  799. {
  800. window.ET.MCMF.AbilitiesReady = false;
  801. window.ET.MCMF.TimeLeftOnCD = iHighestCD;
  802. }
  803.  
  804. window.ET.MCMF.InitialAbilityCheck = false;
  805. }
  806. else
  807. {
  808. window.ET.MCMF.AbilitiesReady = false;
  809. window.ET.MCMF.TimeLeftOnCD = 9999;
  810. }
  811. }
  812. catch (err) { }
  813.  
  814. setTimeout(window.ET.MCMF.AbilityCDTrigger, 500);
  815. },
  816. BattleFloorRoom: "0.0",
  817. BattleFirstFrame: undefined,
  818. BattleUnitList: [],
  819. BattleUITemplate: undefined,
  820.  
  821. LiveBattleData: function()
  822. {
  823. try
  824. {
  825. if (window.ET.MCMF.BattleUITemplate !== undefined)
  826. return window.ET.MCMF.BattleUITemplate.state.get("currentBattle");
  827. }
  828. catch (err) { }
  829. return undefined;
  830. },
  831. InitGameTriggers: function()
  832. {
  833. if ((Package.meteor.Meteor === undefined) || (Package.meteor.Meteor.connection === undefined) || (Package.meteor.Meteor.connection._stream === undefined) || (Template.currentBattleUi === undefined))
  834. {
  835. setTimeout(window.ET.MCMF.InitGameTriggers, 100);
  836. return;
  837. }
  838. Blaze._getTemplate("battleUnit").onRendered(function()
  839. {
  840. if ((this.data !== undefined) && (this.data.unit !== undefined))
  841. {
  842. window.ET.MCMF.BattleUnitList.push(this);
  843. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("<-- Template.battleUnit.onRendered triggered -->");
  844. }
  845. });
  846. Template.currentBattleUi.onCreated(function()
  847. {
  848. window.ET.MCMF.BattleUITemplate = this;
  849. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("<-- Template.currentBattleUi.onCreated triggered -->");
  850. });
  851. Template.currentBattleUi.onDestroyed(function()
  852. {
  853. window.ET.MCMF.BattleUITemplate = undefined;
  854. window.ET.MCMF.BattleUnitList = [];
  855. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("<-- Template.currentBattleUi.onDestroyed triggered -->");
  856. });
  857.  
  858. Package.meteor.Meteor.connection._stream.on('message', function(sMeteorRawData)
  859. {
  860. if (window.ET.MCMF.CombatID === undefined)
  861. window.ET.MCMF.GetPlayerCombatData();
  862.  
  863. try
  864. {
  865. oMeteorData = JSON.parse(sMeteorRawData);
  866.  
  867. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  868. //
  869. // BACKUP TO RETRIEVE USER AND COMBAT IDS
  870. //
  871. if (oMeteorData.collection === "users")
  872. if ((window.ET.MCMF.UserID === undefined) || (window.ET.MCMF.UserID.length !== 17))
  873. window.ET.MCMF.UserID = oMeteorData.id;
  874.  
  875. if (oMeteorData.collection === "combat")
  876. if ((window.ET.MCMF.CombatID === undefined) || (window.ET.MCMF.CombatID.length !== 17))
  877. if (oMeteorData.fields.owner === window.ET.MCMF.UserID)
  878. window.ET.MCMF.CombatID = oMeteorData.id;
  879. //
  880. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  881.  
  882. if (oMeteorData.collection === "battlesList")
  883. {
  884. window.ET.MCMF.AbilitiesReady = false;
  885.  
  886. if ((oMeteorData.msg === "added") || (oMeteorData.msg === "removed"))
  887. {
  888. window.ET.MCMF.BattleUnitList = [];
  889. window.ET.MCMF.InBattle = (oMeteorData.msg === "added");
  890. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("<-- triggering ET:combat" + (((oMeteorData.msg === "added")) ? ("Start") : ("End")) + " -->");
  891. window.ET.MCMF.EventTrigger("ET:combat" + (((oMeteorData.msg === "added")) ? ("Start") : ("End")));
  892. if (window.ET.MCMF.InBattle)
  893. {
  894. battleSocket.on('tick', function(oAllData)
  895. {
  896. let battleData = window.ET.MCMF.LiveBattleData();
  897. let currentFloorRoom = CInt(battleData.floor).toFixed(0) + "." + CInt(battleData.room).toFixed(0);
  898. if (window.ET.MCMF.BattleFloorRoom !== currentFloorRoom)
  899. {
  900. window.ET.MCMF.BattleFloorRoom = currentFloorRoom;
  901. window.ET.MCMF.BattleFirstFrame = undefined;
  902. }
  903. if (window.ET.MCMF.BattleFirstFrame === undefined)
  904. window.ET.MCMF.BattleFirstFrame = battleData;
  905. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("<-- triggering ET:combatTick -->");
  906. window.ET.MCMF.EventTrigger("ET:combatTick");
  907. });
  908. }
  909. else
  910. {
  911. window.ET.MCMF.BattleFloorRoom = "0.0";
  912. window.ET.MCMF.BattleFirstFrame = undefined;
  913. }
  914. }
  915. }
  916.  
  917. if ((oMeteorData.collection === "battles") && (oMeteorData.msg === "added"))
  918. {
  919. if (oMeteorData.fields.finished)
  920. {
  921. window.ET.MCMF.WonLast = oMeteorData.fields.win;
  922. window.ET.MCMF.TimeLastFight = time_val();
  923.  
  924. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("<-- triggering ET:combat" + ((oMeteorData.fields.win) ? ("Won") : ("Lost")) + " -->");
  925. window.ET.MCMF.EventTrigger("ET:combat" + ((oMeteorData.fields.win) ? ("Won") : ("Lost")));
  926. }
  927. }
  928. }
  929. catch (err) { }
  930. });
  931. },
  932. PlayerHP: function()
  933. {
  934. //if (!window.ET.MCMF.PlayerInCombat())
  935. return window.ET.MCMF.GetPlayerCombatData().stats.health;
  936. //return window.ET.MCMF.PlayerUnitData.stats.health;
  937. },
  938. PlayerHPMax: function()
  939. {
  940. //if (!window.ET.MCMF.PlayerInCombat())
  941. return window.ET.MCMF.GetPlayerCombatData().stats.healthMax;
  942. //return window.ET.MCMF.PlayerUnitData.stats.healthMax;
  943. },
  944. PlayerEnergy: function()
  945. {
  946. //if (!window.ET.MCMF.PlayerInCombat())
  947. return window.ET.MCMF.GetPlayerCombatData().stats.energy;
  948. //return window.ET.MCMF.PlayerUnitData.stats.energy;
  949. },
  950.  
  951. AbilityCDCalc: function()
  952. {
  953. iTotalCD = 0;
  954. iTotalCDTest = 0;
  955. iHighestCD = 0;
  956.  
  957. window.ET.MCMF.GetAbilities().forEach(function(oThisAbility)
  958. {
  959. if (oThisAbility.equipped)
  960. {
  961. if (parseInt(oThisAbility.currentCooldown) > 0)
  962. {
  963. iTotalCD += parseInt(oThisAbility.currentCooldown);
  964. if (iHighestCD < parseInt(oThisAbility.currentCooldown))
  965. iHighestCD = parseInt(oThisAbility.currentCooldown);
  966. }
  967. }
  968.  
  969. iTotalCDTest += parseInt(oThisAbility.cooldown);
  970. });
  971.  
  972. if ((iTotalCDTest > 0) && (iTotalCD === 0))
  973. {
  974. if (!window.ET.MCMF.AbilitiesReady)
  975. {
  976. if (!window.ET.MCMF.InitialAbilityCheck)
  977. {
  978. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("<-- triggering ET:abilitiesReady -->");
  979. window.ET.MCMF.EventTrigger("ET:abilitiesReady");
  980. //jQ("div#ET_meancloud_bootstrap").trigger("ET:abilitiesReady");
  981. }
  982. }
  983.  
  984. window.ET.MCMF.AbilitiesReady = true;
  985. window.ET.MCMF.TimeLeftOnCD = 0;
  986. }
  987. else
  988. {
  989. window.ET.MCMF.AbilitiesReady = false;
  990. window.ET.MCMF.TimeLeftOnCD = iHighestCD;
  991. }
  992.  
  993. window.ET.MCMF.InitialAbilityCheck = false;
  994. },
  995.  
  996. GetUnitCombatData: function(sUnitID)
  997. {
  998. let oCombatPlayerData;
  999. try
  1000. {
  1001. // get recent combat data from stored 'state' data in 'BattleUITemplate' template (comes from 'battleSocket')
  1002. if (window.ET.MCMF.LiveBattleData() !== undefined)
  1003. {
  1004. jQ.makeArray(window.ET.MCMF.LiveBattleData().units).forEach(function(oCurrentUnit)
  1005. {
  1006. if (oCurrentUnit.id === sUnitID)
  1007. oCombatPlayerData = oCurrentUnit;
  1008. });
  1009. }
  1010. }
  1011. catch (err) { }
  1012. return oCombatPlayerData;
  1013. },
  1014. GetEnemyCombatData: function(sUnitID)
  1015. {
  1016. let oCombatEnemyData;
  1017. try
  1018. {
  1019. // get recent combat data from stored 'state' data in 'BattleUITemplate' template (comes from 'battleSocket')
  1020. if (window.ET.MCMF.LiveBattleData() !== undefined)
  1021. {
  1022. jQ.makeArray(window.ET.MCMF.LiveBattleData().enemies).forEach(function(oCurrentUnit)
  1023. {
  1024. if (oCurrentUnit.id === sUnitID)
  1025. oCombatEnemyData = oCurrentUnit;
  1026. });
  1027. }
  1028. }
  1029. catch (err) { }
  1030. return oCombatEnemyData;
  1031. },
  1032. GetPlayerCombatData: function()
  1033. {
  1034. let oCombatPlayerData;
  1035. try
  1036. {
  1037. window.ET.MCMF.CombatID = undefined;
  1038. Meteor.connection._stores.combat._getCollection().find().fetch().forEach(function(oThisCombatUnit)
  1039. {
  1040. if (oThisCombatUnit.owner === window.ET.MCMF.UserID)
  1041. {
  1042. oCombatPlayerData = oThisCombatUnit;
  1043. window.ET.MCMF.CombatID = oCombatPlayerData._id;
  1044. if (!window.ET.MCMF.PlayerInCombat())
  1045. window.ET.MCMF.PlayerUnitData = oCombatPlayerData;
  1046. }
  1047. });
  1048. // new: get updated combat data from stored 'state' data in 'BattleUITemplate' template (comes from 'battleSocket')
  1049. if (window.ET.MCMF.LiveBattleData() !== undefined)
  1050. {
  1051. jQ.makeArray(window.ET.MCMF.LiveBattleData().units).forEach(function(oCurrentUnit)
  1052. {
  1053. if (oCurrentUnit.id === window.ET.MCMF.UserID)
  1054. window.ET.MCMF.PlayerUnitData = oCurrentUnit;
  1055. });
  1056. oCombatPlayerData = window.ET.MCMF.PlayerUnitData;
  1057. }
  1058. }
  1059. catch (err) { }
  1060. return oCombatPlayerData;
  1061. },
  1062. GetAbilities: function()
  1063. {
  1064. return Meteor.connection._stores.abilities._getCollection().find().fetch()[0].learntAbilities;
  1065. },
  1066. GetAdventures: function()
  1067. {
  1068. let oAdventureDetails = { AllAdventures: [], ShortAdventures: [], LongAdventures: [], EpicAdventures: [], PhysicalAdventures: [], MagicalAdventures: [], ActiveAdventures: [], CurrentAdventure: undefined };
  1069. // oThisAdventure
  1070. // .duration {duration in seconds} (integer)
  1071. // .endDate {end date/time} (Date()) (property only exists if the adventure is ongoing)
  1072. // .floor {corresponding Tower Floor} (integer)
  1073. // .icon "{imageofbattle.ext}" (string)
  1074. // .id "{guid}" (13-digit alphanumeric string)
  1075. // .length "short" / "long" / "epic" (string)
  1076. // .level {general level} (integer)
  1077. // .name "{Name of Battle}" (string)
  1078. // .room {corresponding Tower Room in Tower Floor} (integer)
  1079. // .type "physical" / "magic" (string)
  1080. // .startDate {start date/time} (Date()) (property only exists if the adventure is ongoing)
  1081. window.ET.MCMF.GetAdventures_raw().forEach(function(oThisAdventure)
  1082. {
  1083. try
  1084. {
  1085. oAdventureDetails.AllAdventures.push(oThisAdventure);
  1086. if (oThisAdventure.length === "short") oAdventureDetails.ShortAdventures .push(oThisAdventure);
  1087. if (oThisAdventure.length === "long") oAdventureDetails.LongAdventures .push(oThisAdventure);
  1088. if (oThisAdventure.length === "epic") oAdventureDetails.EpicAdventures .push(oThisAdventure);
  1089. if (oThisAdventure.type === "physical") oAdventureDetails.PhysicalAdventures.push(oThisAdventure);
  1090. if (oThisAdventure.type === "magic") oAdventureDetails.MagicalAdventures .push(oThisAdventure);
  1091. if (oThisAdventure.endDate !== undefined) oAdventureDetails.ActiveAdventures .push(oThisAdventure);
  1092. }
  1093. catch (err) { }
  1094. });
  1095. oAdventureDetails.AllAdventures.sort(function(advA, advB)
  1096. {
  1097. if ((advA.startDate === undefined) && (advB.startDate !== undefined)) return 1;
  1098. if ((advA.startDate !== undefined) && (advB.startDate === undefined)) return -1;
  1099. if ((advA.startDate !== undefined) && (advB.startDate !== undefined))
  1100. {
  1101. if (advA.startDate > advB.startDate) return 1;
  1102. if (advA.startDate < advB.startDate) return -1;
  1103. }
  1104. if (advA.duration > advB.duration) return 1;
  1105. if (advA.duration < advB.duration) return -1;
  1106. return 0;
  1107. });
  1108. oAdventureDetails.ActiveAdventures.sort(function(advA, advB)
  1109. {
  1110. if (advA.startDate > advB.startDate) return 1;
  1111. if (advA.startDate < advB.startDate) return -1;
  1112. return 0;
  1113. });
  1114. oAdventureDetails.PhysicalAdventures.sort(function(advA, advB)
  1115. {
  1116. if (advA.duration > advB.duration) return 1;
  1117. if (advA.duration < advB.duration) return -1;
  1118. return 0;
  1119. });
  1120. oAdventureDetails.MagicalAdventures.sort(function(advA, advB)
  1121. {
  1122. if (advA.duration > advB.duration) return 1;
  1123. if (advA.duration < advB.duration) return -1;
  1124. return 0;
  1125. });
  1126. if (oAdventureDetails.ActiveAdventures.length > 0)
  1127. oAdventureDetails.CurrentAdventure = oAdventureDetails.ActiveAdventures[0];
  1128. return oAdventureDetails;
  1129. },
  1130.  
  1131. GetAdventures_raw: function()
  1132. {
  1133. return Meteor.connection._stores.adventures._getCollection().find().fetch()[0].adventures;
  1134. },
  1135. GetChats: function()
  1136. {
  1137. return Meteor.connection._stores.simpleChats._getCollection().find().fetch();
  1138. },
  1139.  
  1140. GetItems: function()
  1141. {
  1142. return Meteor.connection._stores.items._getCollection().find().fetch();
  1143. },
  1144. GetSkills: function()
  1145. {
  1146. return Meteor.connection._stores.skills._getCollection().find().fetch();
  1147. },
  1148.  
  1149. // need a better way to check if the game has loaded basic data, but this is fine for now
  1150. Setup: function()
  1151. {
  1152. if ((!window.ET.MCMF.TryingToLoad) && (!window.ET.MCMF.FinishedLoading))
  1153. {
  1154. // use whatever version of jQuery available to us
  1155. $("body").append("<div id=\"ET_meancloud_bootstrap\" style=\"visibility: hidden; display: none;\"></div>");
  1156. window.ET.MCMF.TryingToLoad = true;
  1157. window.ET.MCMF.Setup_Initializer();
  1158. }
  1159. },
  1160.  
  1161. Setup_Initializer: function()
  1162. {
  1163. // wait for Meteor availability
  1164. if ((Package === undefined) || (Package.meteor === undefined) || (Package.meteor.Meteor === undefined) || (Package.meteor.Meteor.connection === undefined) || (Package.meteor.Meteor.connection._stream === undefined))
  1165. {
  1166. setTimeout(window.ET.MCMF.Setup_Initializer, 10);
  1167. return;
  1168. }
  1169.  
  1170. if (!window.ET.MCMF.Initialized)
  1171. {
  1172. window.ET.MCMF.Initialized = true;
  1173. window.ET.MCMF.Setup_SendDelayedInitializer();
  1174. window.ET.MCMF.InitGameTriggers();
  1175. window.ET.MCMF.Setup_remaining();
  1176. }
  1177. },
  1178.  
  1179. Setup_SendDelayedInitializer: function()
  1180. {
  1181. try
  1182. {
  1183. jQ("div#ET_meancloud_bootstrap").trigger("ET:initialized");
  1184. window.ET.MCMF.EventTrigger("ET:initialized");
  1185. //if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("<-- triggering ET:initialized -->");
  1186. }
  1187. catch (err)
  1188. {
  1189. setTimeout(window.ET.MCMF.Setup_SendDelayedInitializer, 100);
  1190. }
  1191. },
  1192.  
  1193. Setup_remaining: function()
  1194. {
  1195. try
  1196. {
  1197. if (Meteor === undefined) throw "[MCMF Setup] Not loaded yet: Meteor not initialized";
  1198. if (Meteor.connection === undefined) throw "[MCMF Setup] Not loaded yet: Meteor not initialized";
  1199. if (Meteor.connection._userId === undefined) throw "[MCMF Setup] Not loaded yet: Meteor not initialized";
  1200. window.ET.MCMF.UserID = Meteor.connection._userId;
  1201. window.ET.MCMF.UserName = Meteor.connection._stores.users._getCollection()._collection._docs._map[window.ET.MCMF.UserID].username;
  1202. window.ET.MCMF.GetPlayerCombatData();
  1203.  
  1204. if (window.ET.MCMF.GetAbilities().length < 0) throw "[MCMF Setup] Not loaded yet: no abilities";
  1205. if (window.ET.MCMF.GetItems().length < 0) throw "[MCMF Setup]Not loaded yet: no items";
  1206. if (window.ET.MCMF.GetChats().length < 0) throw "[MCMF Setup]Not loaded yet: no chats";
  1207. if (window.ET.MCMF.GetSkills().length < 0) throw "[MCMF Setup]Not loaded yet: no skills";
  1208.  
  1209. // if the above is all good, then this should be no problem:
  1210.  
  1211. window.ET.MCMF.AbilityCDTrigger(); // set up ability CD trigger
  1212. window.ET.MCMF.AbilityCDCalc();
  1213. window.ET.MCMF.FasterAbilityUpdates(); // set up faster ability updates (do not disable, this is controlled via configurable setting)
  1214.  
  1215. // trigger finished-loading event
  1216. if (!window.ET.MCMF.FinishedLoading)
  1217. {
  1218. if (window.ET.MCMF.WantDebug) window.ET.MCMF.Log("<-- triggering ET:loaded -->");
  1219. window.ET.MCMF.EventTrigger("ET:loaded");
  1220. window.ET.MCMF.FinishedLoading = true;
  1221. }
  1222. }
  1223. catch (err) // any errors and we retry setup
  1224. {
  1225. if (err.toString().indexOf("[MCMF Setup]") !== -1)
  1226. {
  1227. window.ET.MCMF.Log("ET MCMF setup exception");
  1228. window.ET.MCMF.Log(err);
  1229. }
  1230. setTimeout(window.ET.MCMF.Setup_remaining, 500);
  1231. }
  1232. },
  1233.  
  1234. // Ready means the mod framework has been initialized, but Meteor is not yet available
  1235. Ready: function(fnCallback, sNote)
  1236. {
  1237. if (!window.ET.MCMF.Initialized)
  1238. window.ET.MCMF.EventSubscribe("initialized", fnCallback, sNote);
  1239. else
  1240. fnCallback();
  1241. },
  1242.  
  1243. // Loaded means the mod framework and Meteor are fully loaded and available
  1244. Loaded: function(fnCallback, sNote)
  1245. {
  1246. if (!window.ET.MCMF.FinishedLoading)
  1247. window.ET.MCMF.EventSubscribe("loaded", fnCallback, sNote);
  1248. else
  1249. fnCallback();
  1250. },
  1251. };
  1252.  
  1253. window.ET.MCMF.Setup();
  1254. }
  1255. ////////////////////////////////////////////////////////////////
  1256.  
  1257.  
  1258. ////////////////////////////////////////////////////////////////
  1259. ////////// ** CORE SCRIPT STARTUP -- DO NOT MODIFY ** //////////
  1260. function LoadJQ(callback) {
  1261. if (window.jQ === undefined) { var script=document.createElement("script");script.setAttribute("src","//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js");script.addEventListener('load',function() {
  1262. var subscript=document.createElement("script");subscript.textContent="window.jQ=jQuery.noConflict(true);("+callback.toString()+")();";document.body.appendChild(subscript); },
  1263. !1);document.body.appendChild(script); } else callback(); } LoadJQ(startup);
  1264. ////////////////////////////////////////////////////////////////