C&C:TA Count Forgotten Bases in Range

Display the number of forgotten bases in range of selected world object and paste it to chat message

当前为 2014-07-17 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name C&C:TA Count Forgotten Bases in Range
  3. // @namespace CountBasesButton
  4. // @description Display the number of forgotten bases in range of selected world object and paste it to chat message
  5. // @include https://prodgame*.alliances.commandandconquer.com/*/index.aspx*
  6. // @version 1.0.0
  7. // @author
  8. // ==/UserScript==
  9. (function () {
  10. var CNCTACountBases_main = function () {
  11. try {
  12. function createCountButton() {
  13. console.log('C&C: Tiberium Alliances Count Forgotten Bases in Range: Loaded.');
  14. var countButton = {
  15. selectedBase: null,
  16. countBases: function (x, y) {
  17. var levelCount = [
  18. ];
  19. var count = 0;
  20. var maxAttack = ClientLib.Data.MainData.GetInstance() .get_Server() .get_MaxAttackDistance();
  21. var world = ClientLib.Data.MainData.GetInstance() .get_World();
  22. for (var scanY = y - 10; scanY <= y + 10; scanY++)
  23. {
  24. for (var scanX = x - 10; scanX <= x + 10; scanX++)
  25. {
  26. var distX = Math.abs(x - scanX);
  27. var distY = Math.abs(y - scanY);
  28. var distance = Math.sqrt((distX * distX) + (distY * distY));
  29. // too far away to scan
  30. if (distance >= maxAttack)
  31. {
  32. continue;
  33. }
  34. var object = world.GetObjectFromPosition(scanX, scanY);
  35. // Nothing to scan
  36. if (object === null)
  37. {
  38. continue;
  39. }
  40. // Object isnt a NPC Base / Camp / Outpost
  41. if (object.Type !== ClientLib.Data.WorldSector.ObjectType.NPCBase)
  42. {
  43. continue;
  44. }
  45. if (typeof object.getCampType === 'function' && object.getCampType() === ClientLib.Data.Reports.ENPCCampType.Destroyed)
  46. {
  47. continue;
  48. }
  49. if (typeof object.getLevel !== 'function')
  50. {
  51. countButton._patchClientLib();
  52. }
  53. var level = object.getLevel();
  54. levelCount[level] = (levelCount[level] || 0) + 1;
  55. count++;
  56. }
  57. }
  58. var output = [
  59. ];
  60. for (var i = 0; i < levelCount.length; i++)
  61. {
  62. var lvl = levelCount[i];
  63. if (lvl !== undefined)
  64. {
  65. output.push(lvl + ' x ' + i);
  66. }
  67. }
  68. console.log(x + ':' + y + ' - ' + count + ' bases in range: ' + output.join(', '));
  69. countButton.pasteCoords(x, y, count, output.join(', '));
  70. },
  71. countSoloBases: function (x, y) {
  72. var count = 0;
  73. var maxAttack = ClientLib.Data.MainData.GetInstance() .get_Server() .get_MaxAttackDistance();
  74. var world = ClientLib.Data.MainData.GetInstance() .get_World();
  75. for (var scanY = y - 10; scanY <= y + 10; scanY++)
  76. {
  77. for (var scanX = x - 10; scanX <= x + 10; scanX++)
  78. {
  79. var distX = Math.abs(x - scanX);
  80. var distY = Math.abs(y - scanY);
  81. var distance = Math.sqrt((distX * distX) + (distY * distY));
  82. // too far away to scan
  83. if (distance >= maxAttack)
  84. {
  85. continue;
  86. }
  87. var object = world.GetObjectFromPosition(scanX, scanY);
  88. // Nothing to scan
  89. if (object === null)
  90. {
  91. continue;
  92. }
  93. // Object isnt a NPC Base / Camp / Outpost
  94. if (object.Type !== ClientLib.Data.WorldSector.ObjectType.NPCBase)
  95. {
  96. continue;
  97. }
  98. if (typeof object.getCampType === 'function' && object.getCampType() === ClientLib.Data.Reports.ENPCCampType.Destroyed)
  99. {
  100. continue;
  101. }
  102. count++;
  103. }
  104. }
  105. return count;
  106. },
  107. count: function () {
  108. if (countButton.selectedBase === null || countButton.selectedBase === undefined) {
  109. return;
  110. }
  111. return countButton.countBases(countButton.selectedBase.get_RawX(), countButton.selectedBase.get_RawY());
  112. },
  113. pasteCoords: function (x, y, baseCount, baseData) {
  114. var input = qx.core.Init.getApplication() .getChat() .getChatWidget() .getEditable();
  115. // Input
  116. var dom = input.getContentElement() .getDomElement();
  117. // Input DOM Element
  118. var result = new Array();
  119. result.push(dom.value.substring(0, dom.selectionStart));
  120. // start
  121. result.push('[coords]' + x + ':' + y + '[/coords] - ' + baseCount + ' bases in range: ' + baseData);
  122. result.push(dom.value.substring(dom.selectionEnd, dom.value.length));
  123. // end
  124. input.setValue(result.join(' '));
  125. },
  126. _g: function (k, r, q, m) {
  127. var p = [
  128. ];
  129. var o = k.toString();
  130. var n = o.replace(/\s/gim, '');
  131. p = n.match(r);
  132. var l;
  133. for (l = 1; l < (m + 1); l++) {
  134. if (p !== null && p[l].length === 6) {
  135. console.debug(q, l, p[l]);
  136. } else {
  137. if (p !== null && p[l].length > 0) {
  138. console.warn(q, l, p[l]);
  139. } else {
  140. console.error('Error - ', q, l, 'not found');
  141. console.warn(q, n);
  142. }
  143. }
  144. }
  145. return p;
  146. },
  147. _patchClientLib: function () {
  148. var proto = ClientLib.Data.WorldSector.WorldObjectNPCBase.prototype;
  149. var re = /100\){0,1};this\.(.{6})=Math.floor.*d\+=f;this\.(.{6})=\(/;
  150. var x = countButton._g(proto.$ctor, re, 'ClientLib.Data.WorldSector.WorldObjectNPCBase', 2);
  151. if (x !== null && x[1].length === 6) {
  152. proto.getLevel = function () {
  153. return this[x[1]];
  154. };
  155. } else {
  156. console.error('Error - ClientLib.Data.WorldSector.WorldObjectNPCBase.Level undefined');
  157. }
  158. }
  159. };
  160. if (!webfrontend.gui.region.RegionCityMenu.prototype.__countButton_showMenu) {
  161. webfrontend.gui.region.RegionCityMenu.prototype.__countButton_showMenu = webfrontend.gui.region.RegionCityMenu.prototype.showMenu;
  162. webfrontend.gui.region.RegionCityMenu.prototype.showMenu = function (selectedVisObject) {
  163. countButton.selectedBase = selectedVisObject;
  164. if (this.__countButton_initialized != 1) {
  165. this.__countButton_initialized = 1;
  166. this.__countButton = new qx.ui.form.Button('count');
  167. this.__countButton.addListener('execute', function () {
  168. countButton.count();
  169. });
  170. }
  171. this.__countButton.setLabel('Paste Count (' + countButton.countSoloBases(countButton.selectedBase.get_RawX(), countButton.selectedBase.get_RawY()) + ')');
  172. this.add(this.__countButton);
  173. this.__countButton_showMenu(selectedVisObject);
  174. };
  175. }
  176. }
  177. } catch (e) {
  178. console.log('createCountButton: ', e);
  179. }
  180. function CNCTACountBases_checkIfLoaded() {
  181. try {
  182. if (typeof qx !== 'undefined') {
  183. createCountButton();
  184. } else {
  185. window.setTimeout(CNCTACountBases_checkIfLoaded, 1000);
  186. }
  187. } catch (e) {
  188. console.log('CNCTACountBases_checkIfLoaded: ', e);
  189. }
  190. }
  191. window.setTimeout(CNCTACountBases_checkIfLoaded, 1000);
  192. };
  193. try {
  194. var CNCTACountBases = document.createElement('script');
  195. CNCTACountBases.innerHTML = '(' + CNCTACountBases_main.toString() + ')();';
  196. CNCTACountBases.type = 'text/javascript';
  197. document.getElementsByTagName('head') [0].appendChild(CNCTACountBases);
  198. } catch (e) {
  199. console.log('C&C: Tiberium Alliances Count Forgotten Bases in Range: init error: ', e);
  200. }
  201. }) ();