Eternity Tower Enemy Target Button

Adds a target button to enemies in battle

当前为 2023-09-26 提交的版本,查看 最新版本

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