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