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

  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.4
  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.__baseCounterButton_showMenu ){
  173. webfrontend.gui.region.RegionCityMenu.prototype.showMenu = webfrontend.gui.region.RegionCityMenu.prototype.__baseCounterButton_showMenu;
  174. webfrontend.gui.region.RegionCityMenu.prototype.__baseCounterButton_initialized = false;
  175. webfrontend.gui.region.RegionCityMenu.prototype.__baseCounterButton_showMenu = undefined;
  176. };
  177. if (!webfrontend.gui.region.RegionCityMenu.prototype.__countButton_showMenu) {
  178. webfrontend.gui.region.RegionCityMenu.prototype.__countButton_showMenu = webfrontend.gui.region.RegionCityMenu.prototype.showMenu;
  179. webfrontend.gui.region.RegionCityMenu.prototype.showMenu = function (selectedVisObject) {
  180. var self = this;
  181. countButton.selectedBase = selectedVisObject;
  182. if (this.__countButton_initialized != 1) {
  183. this.__countButton_initialized = 1;
  184. this.__coordButton = [];
  185. this.__countButton = [];
  186. this.__countComposite = new qx.ui.container.Composite(new qx.ui.layout.VBox(0)).set({
  187. padding: 2
  188. });
  189. for (var i in this) {
  190. try {
  191. if (this[i] && this[i].basename == "Composite") {
  192. var coordbutton = new qx.ui.form.Button("Paste Coords");
  193. coordbutton.addListener("execute", function () {
  194. countButton.pasteCoords();
  195. });
  196. var countbutton = new qx.ui.form.Button("Paste Count");
  197. countbutton.addListener("execute", function () {
  198. countButton.count();
  199. });
  200. this[i].add(coordbutton);
  201. this[i].add(countbutton);
  202. this.__coordButton.push(coordbutton);
  203. this.__countButton.push(countbutton);
  204. }
  205. } catch (e) {
  206. console.log("buttons ", e);
  207. }
  208. }
  209. }
  210. for (var i = 0; i < self.__countButton.length; ++i) {
  211. self.__countButton[i].setLabel('Paste Count (' + countButton.countSoloBases(countButton.selectedBase.get_RawX(), countButton.selectedBase.get_RawY()) + ')');
  212. }
  213. switch (selectedVisObject.get_VisObjectType()) {
  214. case ClientLib.Vis.VisObject.EObjectType.RegionPointOfInterest:
  215. case ClientLib.Vis.VisObject.EObjectType.RegionRuin:
  216. case ClientLib.Vis.VisObject.EObjectType.RegionHubControl:
  217. case ClientLib.Vis.VisObject.EObjectType.RegionHubServer:
  218. this.add(this.__countComposite);
  219. break;
  220. }
  221. this.__countButton_showMenu(selectedVisObject);
  222. };
  223. }
  224. }
  225. } catch (e) {
  226. console.log('createCountButton: ', e);
  227. }
  228. function CNCTACountBases_checkIfLoaded() {
  229. try {
  230. if (typeof qx !== 'undefined') {
  231. createCountButton();
  232. } else {
  233. window.setTimeout(CNCTACountBases_checkIfLoaded, 1000);
  234. }
  235. } catch (e) {
  236. console.log('CNCTACountBases_checkIfLoaded: ', e);
  237. }
  238. }
  239. window.setTimeout(CNCTACountBases_checkIfLoaded, 1000);
  240. };
  241. try {
  242. var CNCTACountBases = document.createElement('script');
  243. CNCTACountBases.innerHTML = '(' + CNCTACountBases_main.toString() + ')();';
  244. CNCTACountBases.type = 'text/javascript';
  245. document.getElementsByTagName('head') [0].appendChild(CNCTACountBases);
  246. } catch (e) {
  247. console.log('C&C:Tiberium Alliances Count Forgotten Bases in Range: init error: ', e);
  248. }
  249. }) ();