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-09-08 提交的版本,查看 最新版本

  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.2
  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. var count = 0;
  19. var maxAttack = ClientLib.Data.MainData.GetInstance() .get_Server() .get_MaxAttackDistance();
  20. var world = ClientLib.Data.MainData.GetInstance() .get_World();
  21. for (var scanY = y - 10; scanY <= y + 10; scanY++)
  22. {
  23. for (var scanX = x - 10; scanX <= x + 10; scanX++)
  24. {
  25. var distX = Math.abs(x - scanX);
  26. var distY = Math.abs(y - scanY);
  27. var distance = Math.sqrt((distX * distX) + (distY * distY));
  28. // too far away to scan
  29. if (distance >= maxAttack)
  30. {
  31. continue;
  32. }
  33. var object = world.GetObjectFromPosition(scanX, scanY);
  34. // Nothing to scan
  35. if (object === null)
  36. {
  37. continue;
  38. }
  39. // Object isnt a NPC Base / Camp / Outpost
  40. if (object.Type !== ClientLib.Data.WorldSector.ObjectType.NPCBase)
  41. {
  42. continue;
  43. }
  44. if (typeof object.getCampType === 'function' && object.getCampType() === ClientLib.Data.Reports.ENPCCampType.Destroyed)
  45. {
  46. continue;
  47. }
  48. if (typeof object.getLevel !== 'function')
  49. {
  50. countButton._patchClientLib();
  51. }
  52. var level = object.getLevel();
  53. levelCount[level] = (levelCount[level] || 0) + 1;
  54. count++;
  55. }
  56. }
  57. var output = [];
  58. for (var i = 0; i < levelCount.length; i++)
  59. {
  60. var lvl = levelCount[i];
  61. if (lvl !== undefined)
  62. {
  63. output.push(lvl + ' x ' + i);
  64. }
  65. }
  66. console.log(x + ':' + y + ' [' + count + ' Bases: ' + output.join(' ') + ']');
  67. countButton.pasteCount(x, y, count, output.join(' '));
  68. },
  69. countSoloBases: function (x, y) {
  70. var count = 0;
  71. var maxAttack = ClientLib.Data.MainData.GetInstance() .get_Server() .get_MaxAttackDistance();
  72. var world = ClientLib.Data.MainData.GetInstance() .get_World();
  73. for (var scanY = y - 10; scanY <= y + 10; scanY++)
  74. {
  75. for (var scanX = x - 10; scanX <= x + 10; scanX++)
  76. {
  77. var distX = Math.abs(x - scanX);
  78. var distY = Math.abs(y - scanY);
  79. var distance = Math.sqrt((distX * distX) + (distY * distY));
  80. // too far away to scan
  81. if (distance >= maxAttack)
  82. {
  83. continue;
  84. }
  85. var object = world.GetObjectFromPosition(scanX, scanY);
  86. // Nothing to scan
  87. if (object === null)
  88. {
  89. continue;
  90. }
  91. // Object isnt a NPC Base / Camp / Outpost
  92. if (object.Type !== ClientLib.Data.WorldSector.ObjectType.NPCBase)
  93. {
  94. continue;
  95. }
  96. if (typeof object.getCampType === 'function' && object.getCampType() === ClientLib.Data.Reports.ENPCCampType.Destroyed)
  97. {
  98. continue;
  99. }
  100. count++;
  101. }
  102. }
  103. return count;
  104. },
  105. count: function () {
  106. if (countButton.selectedBase === null || countButton.selectedBase === undefined) {
  107. return;
  108. }
  109. return countButton.countBases(countButton.selectedBase.get_RawX(), countButton.selectedBase.get_RawY());
  110. },
  111. pasteCount: function (x, y, baseCount, baseData) {
  112. var input = qx.core.Init.getApplication() .getChat() .getChatWidget() .getEditable();
  113. // Input
  114. var dom = input.getContentElement() .getDomElement();
  115. // Input DOM Element
  116. var result = new Array();
  117. result.push(dom.value.substring(0, dom.selectionStart));
  118. // start
  119. result.push('[coords]' + x + ':' + y + '[/coords] [' + baseCount + ' Bases: ' + baseData + ']');
  120. result.push(dom.value.substring(dom.selectionEnd, dom.value.length));
  121. // end
  122. input.setValue(result.join(' '));
  123. },
  124. pasteCoords: function () {
  125. var input = qx.core.Init.getApplication() .getChat() .getChatWidget() .getEditable();
  126. // Input
  127. var dom = input.getContentElement() .getDomElement();
  128. // Input DOM Element
  129. var result = new Array();
  130. result.push(dom.value.substring(0, dom.selectionStart));
  131. // start
  132. result.push('[coords]' + countButton.selectedBase.get_RawX() + ':' + countButton.selectedBase.get_RawY() + '[/coords]');
  133. result.push(dom.value.substring(dom.selectionEnd, dom.value.length));
  134. // end
  135. input.setValue(result.join(' '));
  136. },
  137. _g: function (k, r, q, m) {
  138. var p = [
  139. ];
  140. var o = k.toString();
  141. var n = o.replace(/\s/gim, '');
  142. p = n.match(r);
  143. var l;
  144. for (l = 1; l < (m + 1); l++) {
  145. if (p !== null && p[l].length === 6) {
  146. console.debug(q, l, p[l]);
  147. } else {
  148. if (p !== null && p[l].length > 0) {
  149. console.warn(q, l, p[l]);
  150. } else {
  151. console.error('Error - ', q, l, 'not found');
  152. console.warn(q, n);
  153. }
  154. }
  155. }
  156. return p;
  157. },
  158. _patchClientLib: function () {
  159. var proto = ClientLib.Data.WorldSector.WorldObjectNPCBase.prototype;
  160. var re = /100\){0,1};this\.(.{6})=Math.floor.*d\+=f;this\.(.{6})=\(/;
  161. var x = countButton._g(proto.$ctor, re, 'ClientLib.Data.WorldSector.WorldObjectNPCBase', 2);
  162. if (x !== null && x[1].length === 6) {
  163. proto.getLevel = function () {
  164. return this[x[1]];
  165. };
  166. } else {
  167. console.error('Error - ClientLib.Data.WorldSector.WorldObjectNPCBase.Level undefined');
  168. }
  169. }
  170. };
  171. if (!webfrontend.gui.region.RegionCityMenu.prototype.__countButton_showMenu) {
  172. webfrontend.gui.region.RegionCityMenu.prototype.__countButton_showMenu = webfrontend.gui.region.RegionCityMenu.prototype.showMenu;
  173. webfrontend.gui.region.RegionCityMenu.prototype.showMenu = function (selectedVisObject) {
  174. var self = this;
  175. countButton.selectedBase = selectedVisObject;
  176. if (this.__countButton_initialized != 1) {
  177. this.__countButton_initialized = 1;
  178. this.__coordButton = [];
  179. this.__countButton = [];
  180. this.__countComposite = new qx.ui.container.Composite(new qx.ui.layout.VBox(0)).set({
  181. padding: 2
  182. });
  183. for (var i in this) {
  184. try {
  185. if (this[i] && this[i].basename == "Composite") {
  186. var coordbutton = new qx.ui.form.Button("Paste Coords");
  187. coordbutton.addListener("execute", function () {
  188. countButton.pasteCoords();
  189. });
  190. var countbutton = new qx.ui.form.Button("Paste Count");
  191. countbutton.addListener("execute", function () {
  192. countButton.count();
  193. });
  194. this[i].add(coordbutton);
  195. this[i].add(countbutton);
  196. this.__coordButton.push(coordbutton);
  197. this.__countButton.push(countbutton);
  198. }
  199. } catch (e) {
  200. console.log("buttons ", e);
  201. }
  202. }
  203. }
  204. for (var i = 0; i < self.__countButton.length; ++i) {
  205. self.__countButton[i].setLabel('Paste Count (' + countButton.countSoloBases(countButton.selectedBase.get_RawX(), countButton.selectedBase.get_RawY()) + ')');
  206. }
  207. switch (selectedVisObject.get_VisObjectType()) {
  208. case ClientLib.Vis.VisObject.EObjectType.RegionPointOfInterest:
  209. case ClientLib.Vis.VisObject.EObjectType.RegionRuin:
  210. case ClientLib.Vis.VisObject.EObjectType.RegionHubControl:
  211. case ClientLib.Vis.VisObject.EObjectType.RegionHubServer:
  212. this.add(this.__countComposite);
  213. break;
  214. }
  215. this.__countButton_showMenu(selectedVisObject);
  216. };
  217. }
  218. }
  219. } catch (e) {
  220. console.log('createCountButton: ', e);
  221. }
  222. function CNCTACountBases_checkIfLoaded() {
  223. try {
  224. if (typeof qx !== 'undefined') {
  225. createCountButton();
  226. } else {
  227. window.setTimeout(CNCTACountBases_checkIfLoaded, 1000);
  228. }
  229. } catch (e) {
  230. console.log('CNCTACountBases_checkIfLoaded: ', e);
  231. }
  232. }
  233. window.setTimeout(CNCTACountBases_checkIfLoaded, 1000);
  234. };
  235. try {
  236. var CNCTACountBases = document.createElement('script');
  237. CNCTACountBases.innerHTML = '(' + CNCTACountBases_main.toString() + ')();';
  238. CNCTACountBases.type = 'text/javascript';
  239. document.getElementsByTagName('head') [0].appendChild(CNCTACountBases);
  240. } catch (e) {
  241. console.log('C&C:Tiberium Alliances Count Forgotten Bases in Range: init error: ', e);
  242. }
  243. }) ();