C&C: TA POIs Analyser

Display alliance's POIs scores and next tier requirements.

  1. // ==UserScript==
  2. // @name C&C: TA POIs Analyser
  3. // @description Display alliance's POIs scores and next tier requirements.
  4. // @namespace https://prodgame*.alliances.commandandconquer.com/*/index.aspx*
  5. // @include https://prodgame*.alliances.commandandconquer.com/*/index.aspx*
  6. // @version 2.0.3
  7. // @grant none
  8. // @author zdoom, Gryphon
  9.  
  10. // ==/UserScript==
  11.  
  12. (function()
  13. {
  14. var injectScript = function()
  15. {
  16. function create_ccta_pa_class()
  17. {
  18. qx.Class.define('ccta_pa',
  19. {
  20. type: 'singleton',
  21. extend: qx.ui.tabview.Page,
  22. construct: function()
  23. {
  24. try
  25. {
  26. this.base(arguments);
  27. this.set({layout: new qx.ui.layout.Grow(), label: "Alliance POIs", padding: 10});
  28. var root = this;
  29. var footerLayout = new qx.ui.layout.Grid();
  30. footerLayout.setColumnFlex(1,1);
  31. var footer = new qx.ui.container.Composite(footerLayout).set({font: "font_size_13", padding: [5, 10], marginTop: 5, decorator: "pane-light-opaque"});
  32. var label = new qx.ui.basic.Label().set({textColor: "text-value", font: "font_size_13", padding: 10, alignX: 'right'});
  33. var checkBox = new qx.ui.form.CheckBox('Show/Hide image and alliance appreviation.')
  34. checkBox.set({textColor: webfrontend.gui.util.BBCode.clrLink, font: "font_size_13"});
  35. var abr = new qx.ui.basic.Label().set({alignX: 'center', marginTop: 30, font: 'font_size_14', textColor: 'black'});
  36. var manager = qx.theme.manager.Font.getInstance();
  37. var defaultFont = manager.resolve(abr.getFont());
  38. var newFont = defaultFont.clone();
  39. newFont.setSize(32);
  40. abr.setFont(newFont);
  41. var deco = new qx.ui.decoration.Background().set({backgroundImage: "http://archeikhmeri.co.uk/images/fop2.png"});
  42. var imgCont = new qx.ui.container.Composite(new qx.ui.layout.VBox());
  43. imgCont.set({minWidth: 363, minHeight: 356, maxWidth: 363, maxHeight: 356, decorator: deco, alignX: 'center'});
  44. var scrl = new qx.ui.container.Scroll();
  45. var cont = new qx.ui.container.Composite(new qx.ui.layout.VBox()).set({allowGrowY: true, padding: 10});
  46. var gb = new qx.ui.groupbox.GroupBox("Statistics").set({layout: new qx.ui.layout.VBox(), marginLeft: 2});
  47. var lgb = new webfrontend.gui.GroupBoxLarge().set({layout: new qx.ui.layout.Canvas()});
  48. var lgbc = new qx.ui.container.Composite(new qx.ui.layout.VBox()).set({padding: [50,10,20,10]});
  49. var widget = new qx.ui.core.Widget().set({minWidth: 628, minHeight: 335});
  50. var html = new qx.html.Element('div', null, {id: "graph"});
  51. var info = new qx.ui.groupbox.GroupBox("Additional Information").set({layout: new qx.ui.layout.VBox(), marginTop: 10});
  52. var buttonCont = new qx.ui.container.Composite(new qx.ui.layout.VBox()).set({marginTop: 10});
  53. var tableCont = new qx.ui.container.Composite(new qx.ui.layout.VBox()).set({minWidth: 500});
  54. var grid = new qx.ui.container.Composite(new qx.ui.layout.Grid(2,1));
  55. grid.add(buttonCont, {row: 1, column: 1});
  56. grid.add(tableCont, {row: 1, column: 2});
  57. var noAllianceLabel = new qx.ui.basic.Label('No Alliance found, please create or join an alliance.').set({maxHeight: 30});
  58. var data = ClientLib.Data.MainData.GetInstance();
  59. var alliance = data.get_Alliance();
  60. var exists = alliance.get_Exists();
  61. var allianceName = alliance.get_Name();
  62. var allianceAbbr = alliance.get_Abbreviation();
  63. var faction = ClientLib.Base.Util.GetFactionGuiPatchText();
  64. var fileManager = ClientLib.File.FileManager.GetInstance();
  65. var opois = alliance.get_OwnedPOIs();
  66. var poiUtil = ClientLib.Base.PointOfInterestTypes;
  67. var getScore = poiUtil.GetScoreByLevel;
  68. var getMultiplier = poiUtil.GetBoostModifierByRank;
  69. var getBonus = poiUtil.GetBonusByType;
  70. var getNextScore = poiUtil.GetNextScore;
  71. var startRank = ClientLib.Base.EPOIType.RankedTypeBegin;
  72. var endRank = ClientLib.Base.EPOIType.RankedTypeEnd;
  73. var maxPoiLevel = ClientLib.Data.MainData.GetInstance().get_Server().get_MaxCenterLevel();
  74. var poiInfo = phe.cnc.gui.util.Text.getPoiInfosByType;
  75. var startRank = ClientLib.Base.EPOIType.RankedTypeBegin;
  76. var tiersData = [], scoreData = [], bonusData = [], tiers = [];
  77. for (var i = 0; i < 50; i++)
  78. {
  79. var previousScore = (i == 0) ? 0 : bonusData[i - 1][1];
  80. var score = getNextScore(previousScore);
  81. var bonus = getBonus(startRank, score);
  82. var percent = getBonus(endRank - 1, score);
  83. if (score != previousScore)
  84. {
  85. bonusData[i] = [i + 1, score, bonus, percent + '%'];
  86. tiers[i] = [i, previousScore, score];
  87. }
  88. else break;
  89. }
  90. for (var i = 1; i <= maxPoiLevel; i++)
  91. {
  92. if (getScore(i + 1) == 1) continue;
  93. scoreData.push([i, getScore(i)]);
  94. }
  95. for (var i = 1; i < 41; i++) tiersData.push([i, '+' + getMultiplier(i) + '%']);
  96. var createTable = function()
  97. {
  98. var columns = [["POI Level", "Score"], ["Tier", "Score Required", "Bonus", "Percentage"], ["Rank", "Multiplier"]];
  99. var rows = [scoreData, bonusData, tiersData];
  100. var make = function(n)
  101. {
  102. var model = new qx.ui.table.model.Simple().set({columns: columns[n], data: rows[n]});
  103. var table = new qx.ui.table.Table(model).set({
  104. columnVisibilityButtonVisible: false,
  105. headerCellHeight: 25,
  106. marginTop: 20,
  107. minWidth: 500,
  108. height: 400});
  109. var renderer = new qx.ui.table.cellrenderer.Default().set({useAutoAlign: false});
  110. for (i = 0; i < columns[n].length; i++) table.getTableColumnModel().setDataCellRenderer(i, renderer);
  111. return table;
  112. };
  113. this.Scores = make(0);
  114. this.Tiers = make(1);
  115. this.Multiplier = make(2);
  116. };
  117. var tables = new createTable();
  118. ['Scores', 'Multiplier', 'Tiers'].map(function(key)
  119. {
  120. var table = tables[key];
  121. var button = new qx.ui.form.Button(key).set({width: 100, margin: [10, 10, 0, 10]}) ;
  122. button.addListener('execute', function()
  123. {
  124. tableCont.removeAll();
  125. tableCont.add(table)
  126. scrl.scrollChildIntoViewY(tableCont, 'top');
  127. }, this);
  128. buttonCont.add(button);
  129. });
  130.  
  131. info.add(grid);
  132. var tabview = new qx.ui.tabview.TabView().set({marginTop: 20, maxWidth: 500, maxHeight: 500});
  133. var coordsButton = new qx.ui.form.Button('Coords').set({width: 100, margin: [10, 10, 0, 10]});
  134. coordsButton.addListener('execute', function()
  135. {
  136. tableCont.removeAll();
  137. tableCont.add(tabview);
  138. scrl.scrollChildIntoViewY(tableCont, 'top');
  139. }, this);
  140. var res =
  141. [
  142. "ui/common/icn_res_tiberium.png",
  143. "ui/common/icn_res_chrystal.png",
  144. "ui/common/icn_res_power.png",
  145. "ui/" + faction + "/icons/icon_arsnl_off_squad.png",
  146. "ui/" + faction + "/icons/icon_arsnl_off_vehicle.png",
  147. "ui/" + faction + "/icons/icon_arsnl_off_plane.png",
  148. "ui/" + faction + "/icons/icon_def_army_points.png"
  149. ];
  150. var columns = ['Coords', 'Level', 'Score'], models = [], pages = [];
  151. for (var i = 0; i < 7; i++)
  152. {
  153. var page = new qx.ui.tabview.Page().set({layout: new qx.ui.layout.VBox()});
  154. page.setIcon(fileManager.GetPhysicalPath(res[i]));
  155. var model = new qx.ui.table.model.Simple().set({columns: columns});
  156. model.sortByColumn(1, false);
  157. var table = new qx.ui.table.Table(model)
  158. table.set({columnVisibilityButtonVisible: false, headerCellHeight: 25, marginTop: 10, minWidth: 470, showCellFocusIndicator: false, height: 320});
  159. var renderer = new qx.ui.table.cellrenderer.Default().set({useAutoAlign: false});
  160. for (var n = 0; n < columns.length; n++)
  161. {
  162. if (n == 0) renderer = new qx.ui.table.cellrenderer.Html();
  163. table.getTableColumnModel().setDataCellRenderer(n, renderer);
  164. }
  165. page.add(table);
  166. tabview.add(page);
  167. models.push(model);
  168. pages.push(page);
  169. }
  170. this.__poisCoordsPages = pages;
  171. //Simulator
  172. var wrapper = new qx.ui.container.Composite(new qx.ui.layout.VBox()).set({decorator: 'tabview-pane-clear', padding: [10, 14, 13, 10], marginTop: 20});
  173. var header = new qx.ui.container.Composite(new qx.ui.layout.HBox()).set({decorator: 'pane-light-opaque', padding: [8, 12]});
  174. var initValCont = new qx.ui.container.Composite(new qx.ui.layout.HBox()).set({padding: [5,0], marginLeft: 20});
  175. var initVals = ['Score:', 'Tier: ', 'Rank:', 'Bonus:'], valueLabels = [];
  176. for (var i = 0; i < 4; i++)
  177. {
  178. var initCont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
  179. var ln = new qx.ui.basic.Label(initVals[i]).set({textColor: webfrontend.gui.util.BBCode.clrLink, font: 'font_size_11'});
  180. var lv = new qx.ui.basic.Label().set({font: 'font_size_11', paddingLeft: 5, paddingRight: 10});
  181. initCont.add(ln);
  182. initCont.add(lv);
  183. initValCont.add(initCont, {flex: 1});
  184. valueLabels.push(lv);
  185. }
  186. var mainCont = new qx.ui.container.Composite(new qx.ui.layout.VBox()).set({maxWidth: 480});
  187. var modifierCont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
  188. var rankingModel = new qx.ui.table.model.Simple().set({columns: ['Rank', 'Name', 'Score', 'Multiplier', 'Total Bonus']});
  189. /*
  190. var custom =
  191. {
  192. tableColumnModel : function(obj)
  193. {
  194. return new qx.ui.table.columnmodel.Resize(obj);
  195. }
  196. };
  197. */
  198. //var rankingTable = new qx.ui.table.Table(rankingModel, custom);
  199. var rankingTable = new qx.ui.table.Table(rankingModel);
  200. rankingTable.set({
  201. columnVisibilityButtonVisible: false,
  202. headerCellHeight: 25,
  203. marginTop: 3,
  204. showCellFocusIndicator: false,
  205. statusBarVisible: false,
  206. keepFirstVisibleRowComplete: false,
  207. height: 105});
  208. for (var n = 0; n < 5; n++)
  209. {
  210. if (n == 1) rankingTable.getTableColumnModel().setDataCellRenderer(n, new qx.ui.table.cellrenderer.Html());
  211. else rankingTable.getTableColumnModel().setDataCellRenderer(n, new qx.ui.table.cellrenderer.Default().set({useAutoAlign: false}));
  212. }
  213. var rankingTableColumnModel = rankingTable.getTableColumnModel();
  214. /*
  215. var rankingTableResizeBehavior = rankingTableColumnModel.getBehavior();
  216. rankingTableResizeBehavior.setWidth(0, 50);
  217. rankingTableResizeBehavior.setWidth(1, "2*");
  218. rankingTableResizeBehavior.setWidth(2, 100);
  219. rankingTableResizeBehavior.setWidth(3, 70);
  220. rankingTableResizeBehavior.setWidth(4, 100);
  221. */
  222. var resultsModel = new qx.ui.table.model.Simple().set({columns: ['Property', 'Value']});
  223. //var resultsTable = new qx.ui.table.Table(resultsModel, custom);
  224. var resultsTable = new qx.ui.table.Table(resultsModel);
  225. var resultsTableColumnModel = resultsTable.getTableColumnModel();
  226. /*
  227. var resultsTableResizeBehavior = resultsTableColumnModel.getBehavior();
  228. resultsTableResizeBehavior.setWidth(0, 100);
  229. resultsTableResizeBehavior.setWidth(1, "2*");
  230. */
  231. resultsTable.set({
  232. columnVisibilityButtonVisible: false,
  233. headerCellHeight: 25,
  234. marginTop: 5,
  235. width: 210,
  236. maxWidth: 210,
  237. showCellFocusIndicator: false,
  238. height: 300});
  239. resultsTable.getTableColumnModel().setDataCellRenderer(0, new qx.ui.table.cellrenderer.Html());
  240. resultsTable.getTableColumnModel().setDataCellRenderer(1, new qx.ui.table.cellrenderer.Html());
  241. var codeToString = function(s){ return String.fromCharCode(s).toLowerCase() };
  242. label.setValue(String.fromCharCode(77) + [65,68,69,32,66,89,32,90,68,79,79,77].map(codeToString).join().replace(/,/g, ''));
  243. var poisColumns = ['Coords', 'Level', 'Score', 'Enabled'];
  244. var poisModel = new qx.ui.table.model.Simple().set({columns: poisColumns });
  245. //var poisTable = new qx.ui.table.Table(poisModel, custom);
  246. var poisTable = new qx.ui.table.Table(poisModel);
  247. poisTable.set({
  248. columnVisibilityButtonVisible: false,
  249. headerCellHeight: 25,
  250. marginTop: 5,
  251. marginLeft: 5,
  252. showCellFocusIndicator: false,
  253. height: 300});
  254. for (var n = 0; n < 4; n++)
  255. {
  256. if (n == 0) poisTable.getTableColumnModel().setDataCellRenderer(n, new qx.ui.table.cellrenderer.Html());
  257. else if (n == 3) poisTable.getTableColumnModel().setDataCellRenderer(n, new qx.ui.table.cellrenderer.Boolean())
  258. else poisTable.getTableColumnModel().setDataCellRenderer(n, new qx.ui.table.cellrenderer.Default().set({useAutoAlign: false}));
  259. }
  260. var poisTableColumnModel = poisTable.getTableColumnModel();
  261. /*
  262. var poisTableResizeBehavior = poisTableColumnModel.getBehavior();
  263. poisTableResizeBehavior.setWidth(0, 70);
  264. poisTableResizeBehavior.setWidth(1, 50);
  265. poisTableResizeBehavior.setWidth(2, "2*");
  266. poisTableResizeBehavior.setWidth(3, 60);
  267. */
  268. var selectionModel = poisTable.getSelectionManager().getSelectionModel();
  269. selectionModel.setSelectionMode(qx.ui.table.selection.Model.MULTIPLE_INTERVAL_SELECTION_TOGGLE);
  270. poisTable.getSelectionModel().addListener('changeSelection', function(e)
  271. {
  272. var table = this.__poisTable;
  273. var tableModel = table.getTableModel();
  274. var data = tableModel.getDataAsMapArray();
  275. var score = 0;
  276. for (var i = 0; i < data.length; i++)
  277. {
  278. var isSelected = selectionModel.isSelectedIndex(i);
  279. var level = tableModel.getValue(1, i);
  280. tableModel.setValue(3, i, !isSelected);
  281. if (!isSelected) score += getScore(parseInt(level, 10));
  282. }
  283. this.__setResultsRows(score);
  284. this.__setRankingRows(score);
  285. table.setUserData('score', score);
  286. }, this);
  287. var addRowCont = new qx.ui.container.Composite(new qx.ui.layout.HBox()).set({decorator: 'pane-light-opaque', padding: [8, 12], marginTop: 5});
  288. var selectPoiLabelCont = new qx.ui.container.Composite(new qx.ui.layout.HBox());
  289. var selectPoiLabel = new qx.ui.basic.Label('Select POI\'s Level').set({margin: [5, 10], font: 'font_size_11'});
  290. var selectLevel = new qx.ui.form.SelectBox().set({padding: [5, 15]});
  291. for (var i = 12; i <= maxPoiLevel; i++) selectLevel.add(new qx.ui.form.ListItem('Level ' + i, null, i));
  292. var addButton = new qx.ui.form.Button('Add POI').set({padding: [5, 20]});
  293. var resetButton = new qx.ui.form.Button('Reset').set({padding: [5, 20], marginLeft: 5});
  294. addButton.addListener('execute', function()
  295. {
  296. var level = selectLevel.getSelection()[0].getModel();
  297. var score = getScore(parseInt(level, 10));
  298. var originalScore = poisTable.getUserData('score');
  299. poisModel.addRows([['<p style="padding:0; margin:0; color:' + webfrontend.gui.util.BBCode.clrLink + '">New</p>', level, this.__format(score), true]]);
  300. var newScore = originalScore + score;
  301. this.__setResultsRows(newScore);
  302. this.__setRankingRows(newScore);
  303. poisTable.setUserData('score', newScore);
  304. }, this);
  305. resetButton.addListener('execute', this.__initSim, this);
  306. mainCont.add(rankingTable, {flex: 1});
  307. modifierCont.add(resultsTable);
  308. modifierCont.add(poisTable, {flex: 1});
  309. mainCont.add(modifierCont);
  310. selectPoiLabelCont.add(selectPoiLabel);
  311. addRowCont.add(selectLevel);
  312. addRowCont.add(selectPoiLabelCont, {flex: 1});
  313. addRowCont.add(addButton);
  314. addRowCont.add(resetButton);
  315. mainCont.add(addRowCont);
  316. var selectBox = new qx.ui.form.SelectBox().set({padding: [5,20]});
  317. for (var i = 0; i < 7; i++)
  318. {
  319. var type = poiInfo(i + startRank).type;
  320. var listItem = new qx.ui.form.ListItem(type, null, type);
  321. selectBox.add(listItem);
  322. }
  323. selectBox.addListener('changeSelection', function(e)
  324. {
  325. if (!e.getData()[0]) return;
  326. var type = e.getData()[0].getModel();
  327. this.__selectedSimPoi = type;
  328. this.__initSim();
  329. }, this);
  330. header.add(selectBox);
  331. header.add(initValCont, {flex: 1});
  332. wrapper.add(header);
  333. wrapper.add(mainCont);
  334. this.__simLabels = valueLabels;
  335. this.__rankingModel = rankingModel;
  336. this.__resultsModel = resultsModel;
  337. this.__poisModel = poisModel;
  338. this.__poisTable = poisTable;
  339. this.__selectPoiLevel = selectLevel;
  340. this.__simCont = wrapper;
  341. this.__selectedSimPoi = poiInfo(startRank).type;
  342. var simulatorButton = new qx.ui.form.Button('Simulator').set({width: 100, margin: [10, 10, 0, 10]});
  343. simulatorButton.addListener('execute', function()
  344. {
  345. scrl.scrollChildIntoViewY(tableCont, 'top');
  346. tableCont.removeAll();
  347. tableCont.add(wrapper);
  348. }, this);
  349. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  350. var showImage = false;
  351. if (typeof localStorage.ccta_pa == 'undefined')
  352. {
  353. localStorage.ccta_pa = JSON.stringify({'showImage': false});
  354. }
  355. else showImage = JSON.parse(localStorage.ccta_pa).showImage;
  356. checkBox.setValue(showImage);
  357. var toggleImage = function()
  358. {
  359. var isChecked = checkBox.getValue();
  360. localStorage.ccta_pa = JSON.stringify({'showImage': isChecked});
  361. if (!isChecked) cont.remove(imgCont);
  362. else cont.addAt(imgCont, 0);
  363. };
  364. checkBox.addListener('changeValue', toggleImage, this);
  365. //footer.add(checkBox, {row: 0, column: 0});
  366. //footer.add(label, {row: 0, column: 1});
  367. scrl.add(cont);
  368. imgCont.add(abr);
  369. if (showImage) cont.add(imgCont);
  370. cont.add(lgb);
  371. lgb.add(lgbc);
  372. lgbc.add(gb);
  373. lgbc.add(info);
  374. lgbc.add(footer);
  375. widget.getContentElement().add(html);
  376. this.add(scrl);
  377.  
  378. if (exists)
  379. {
  380. gb.add(widget);
  381. buttonCont.addAt(coordsButton, 0);
  382. buttonCont.addAt(simulatorButton, 1);
  383. tableCont.add(tabview);
  384. abr.setValue(allianceAbbr);
  385. this.__allianceName = allianceName;
  386. this.__allianceAbbr = allianceAbbr;
  387. }
  388. else
  389. {
  390. gb.add(noAllianceLabel);
  391. tableCont.add(tables.Scores);
  392. noAllianceLabel.setValue('No Alliance found, please create or join an alliance.');
  393. this.__isReset = true;
  394. }
  395. this.__models = models;
  396. this.__tableCont = tableCont;
  397. this.__timer = new qx.event.Timer(1000);
  398. this.__tiers = tiers;
  399. this.__timer.addListener('interval', this.__update, this);
  400. this.addListener('appear', function()
  401. {
  402. try
  403. {
  404. var alliance = ClientLib.Data.MainData.GetInstance().get_Alliance();
  405. var allianceName = alliance.get_Name();
  406. var allianceAbbr = alliance.get_Abbreviation();
  407. var exists = alliance.get_Exists();
  408. if (!exists && !this.__isReset)
  409. {
  410. console.log('No alliance found');
  411. gb.removeAll();
  412. gb.add(noAllianceLabel);
  413. buttonCont.remove(coordsButton);
  414. buttonCont.remove(simulatorButton);
  415. tableCont.removeAll();
  416. tableCont.add(tables.Scores);
  417. abr.setValue('');
  418. this.__allianceName = '';
  419. this.__allianceAbbr = '';
  420. this.__pois = {};
  421. this.__isReset = true;
  422. }
  423. else if (exists)
  424. {
  425. if (this.__isReset)
  426. {
  427. gb.removeAll();
  428. gb.add(widget);
  429. buttonCont.addAt(coordsButton, 0);
  430. buttonCont.addAt(simulatorButton, 1);
  431. abr.setValue(allianceAbbr);
  432. this.__isReset = false;
  433. this.__allianceName = allianceName;
  434. this.__allianceAbbr = allianceAbbr;
  435. }
  436. tableCont.removeAll();
  437. tableCont.add(tabview);
  438. this.__update();
  439. }
  440. }
  441. catch(e)
  442. {
  443. console.log(e.toString())
  444. }
  445. }, this);
  446. var overlay = webfrontend.gui.alliance.AllianceOverlay.getInstance();
  447. var mainTabview = overlay.getChildren()[12].getChildren()[0];
  448. mainTabview.addAt(this, 0);
  449. mainTabview.setSelection([this]);
  450. }
  451. catch(e)
  452. {
  453. console.log(e.toString());
  454. }
  455. },
  456. destruct: function(){},
  457. members:
  458. {
  459. __isReset: false,
  460. __timer: null,
  461. __allianceName: null,
  462. __allianceAbbr: null,
  463. __pois: null,
  464. __tiers: null,
  465. __ranks: {},
  466. __models: null,
  467. __poisCoordsPages: null,
  468. __tableCont: null,
  469. __simCont: null,
  470. __selectedSimPoi: null,
  471. __isolatedRanks: null,
  472. __simLabels: [],
  473. __rankingModel: null,
  474. __resultsModel: null,
  475. __poisModel: null,
  476. __poisTable: null,
  477. __selectPoi: null,
  478. __style:
  479. {
  480. "table": {"margin": "5px", "borderTop": "1px solid #333", "borderBottom": "1px solid #333", "fontFamily": "Verdana, Geneva, sans-serif"},
  481. "graph":
  482. {
  483. "td": {"width": "68px", "verticalAlign": "bottom", "textAlign": "center"},
  484. "div": {"width": "24px", "margin": "0 auto -1px auto", "border": "3px solid #333", "borderBottom": "none"}
  485. },
  486. "icon":
  487. {
  488. "ul": {"listStyleType": "none", "margin": 0, "padding": 0},
  489. "div": {"padding": "6px", "marginRight": "6px", "display": "inline-block", "border": "1px solid #000"},
  490. "p": {"display": "inline", "fontSize": "10px", "color": "#555"},
  491. "li": {"height": "15px", "padding": "2px", "marginLeft": "10px"}
  492. },
  493. "cell":
  494. {
  495. "data": {"width": "68px", "textAlign": "center", "color": "#555", "padding": "3px 2px"},
  496. "header": {"color": "#416d96", "padding": "3px 2px"}
  497. },
  498. "rows":
  499. {
  500. "graph": {"borderBottom": "3px solid #333", "height": "200px"},
  501. "tr": {"fontSize": "11px", "borderBottom": "1px solid #333", "backgroundColor": "#d6dde1"}
  502. }
  503. },
  504. __element: function(tag)
  505. {
  506. var elm = document.createElement(tag), root = this;
  507. this.css = function(a)
  508. {
  509. for (var b in a)
  510. {
  511. root.elm.style[b] = a[b];
  512. root.__style[b] = a[b];
  513. }
  514. }
  515. this.set = function(a)
  516. {
  517. for (var b in a) root.elm[b] = a[b];
  518. }
  519. this.append = function()
  520. {
  521. for (var i in arguments)
  522. {
  523. if (arguments[i].__instanceof == 'element') root.elm.appendChild(arguments[i].elm);
  524. else if (arguments[i] instanceof Element) root.elm.appendChild(arguments[i]);
  525. else console.log(arguments[i] + ' is not an element');
  526. }
  527. }
  528. this.text = function(str)
  529. {
  530. var node = document.createTextNode(str);
  531. root.elm.appendChild(node);
  532. }
  533. this.elm = elm;
  534. this.__style = {};
  535. this.__instanceof = 'element';
  536. },
  537. __format: function(n)
  538. {
  539. var f = "", n = n.toString();
  540. if (n.length < 3) return n;
  541. for (var i = 0; i < n.length; i++)
  542. {
  543. (((n.length - i) % 3 === 0) && (i !== 0)) ? f += "," + n[i] : f += n[i];
  544. }
  545. return f;
  546. },
  547. __update: function()
  548. {
  549. this.__timer.stop();
  550. var div = document.getElementById('graph');
  551. if (!div)
  552. {
  553. this.__timer.start();
  554. console.log('Waiting for div dom element to be loaded');
  555. }
  556. if (div)
  557. {
  558. console.log('Reloading graph');
  559. div.innerHTML = "";
  560. this.__updatePOIList();
  561. this.__updateGraph();
  562. this.__updateRanks();
  563. }
  564. },
  565. __updatePOIList: function()
  566. {
  567. var alliance = ClientLib.Data.MainData.GetInstance().get_Alliance();
  568. var opois = alliance.get_OwnedPOIs();
  569. var startRank = ClientLib.Base.EPOIType.RankedTypeBegin;
  570. var getScore = ClientLib.Base.PointOfInterestTypes.GetScoreByLevel;
  571. var models = this.__models, format = this.__format, pages = this.__poisCoordsPages;
  572. for (var i = 0; i < 7; i++)
  573. {
  574. var rows = [];
  575. opois.map(function(poi)
  576. {
  577. if (poi.t - startRank === i)
  578. {
  579. var a = webfrontend.gui.util.BBCode.createCoordsLinkText((poi.x + ':' + poi.y), poi.x, poi.y);
  580. rows.push([a, poi.l, format(getScore(poi.l))]);
  581. }
  582. });
  583. models[i].setData(rows);
  584. models[i].sortByColumn(1, false);
  585. pages[i].setLabel(rows.length);
  586. }
  587. },
  588. __updateRanks: function()
  589. {
  590. this.__ranks = {}, this.__isolatedRanks = {}, root = this, allianceName = this.__allianceName;
  591. var getPoiRankType = ClientLib.Base.PointOfInterestTypes.GetPOITypeFromPOIRanking;
  592. var poiInfo = phe.cnc.gui.util.Text.getPoiInfosByType, startRank;
  593. for (var i = 0; i < 20; i++) if (getPoiRankType(i) > 0) { startRank = i; break; };
  594. var getPoiRanks = function(type, poiType, increment)
  595. {
  596. ClientLib.Net.CommunicationManager.GetInstance().SendSimpleCommand("RankingGetData",
  597. {'ascending': true, 'firstIndex': 0, 'lastIndex': 100, 'rankingType': poiType, 'sortColumn': 200 + increment, 'view': 1},
  598. phe.cnc.Util.createEventDelegate(ClientLib.Net.CommandResult, root, function(context, data)
  599. {
  600. if (data !== null)
  601. {
  602. var skip = 1, arr = [];
  603. for (var i = 0; i < data.a.length; i++)
  604. {
  605. var alliance = data.a[i], name = alliance.an, score = (alliance.pois || 0);
  606. if (name == allianceName)
  607. {
  608. skip = 0;
  609. continue;
  610. }
  611. alliance.r = i + skip;
  612. arr.push(alliance);
  613. }
  614. this.__isolatedRanks[type] = arr;
  615. this.__ranks[type] = data.a;
  616. if (this.__selectedSimPoi == type) this.__initSim();
  617. }
  618. }), null);
  619. };
  620. if (startRank) for (var n = 0; n < 7; n++) getPoiRanks(poiInfo(getPoiRankType(n + startRank)).type, n + startRank, n);
  621. },
  622. __setSimLabels: function()
  623. {
  624. var labels = this.__simLabels, pois = this.__pois, type = this.__selectedSimPoi, format = this.__format;
  625. if (pois[type])
  626. {
  627. labels[0].setValue(pois[type].s);
  628. labels[1].setValue((pois[type].tier == 0) ? "0" : pois[type].tier);
  629. labels[2].setValue((pois[type].rank == 0) ? "0" : pois[type].rank);
  630. labels[3].setValue(pois[type].tb);
  631. }
  632. },
  633. __setRankingRows: function(score)
  634. {
  635. var isolatedRanks = this.__isolatedRanks, format = this.__format, allianceName = this.__allianceName, type = this.__selectedSimPoi, pois = this.__pois;
  636. var poiUtil = ClientLib.Base.PointOfInterestTypes;
  637. var getMultiplier = poiUtil.GetBoostModifierByRank;
  638. var getBonus = poiUtil.GetBonusByType;
  639. var getRankingData = function(i, type, nr)
  640. {
  641. var x = isolatedRanks[type][i], score = (x.pois || 0), name = webfrontend.gui.util.BBCode.createAllianceLinkText(x.an);
  642. var bonus = getBonus(pois[type].index, score), multiplier = getMultiplier(nr), totalBonus = bonus + (bonus * multiplier / 100);
  643. totalBonus = (pois[type].bonusType == 1) ? format(Math.round(totalBonus)) : Math.round(totalBonus * 100) / 100 + '%';
  644. return [nr, name, format(score), '+' + multiplier + '%', totalBonus]
  645. };
  646. getMyRanking = function(s, i, p)
  647. {
  648. var b = getBonus(pois[p].index, s);
  649. var m = getMultiplier(i);
  650. var tb = b + (b * m / 100);
  651. tb = (pois[p].bonusType == 1) ? format(Math.round(tb)) : Math.round(tb * 100) / 100 + '%';
  652. var n = webfrontend.gui.util.BBCode.createAllianceLinkText(allianceName);
  653. return [i, n, format(s), '+' + m + '%', tb];
  654. };
  655. var getRankingRows = function(s, type)
  656. {
  657. var rows;
  658. for (var i = 0; i < isolatedRanks[type].length; i++)
  659. {
  660. if (s >= (isolatedRanks[type][i].pois || 0))
  661. {
  662. var matched = getRankingData(i, type, i + 2);
  663. var nextMatched = getRankingData(i + 1, type, i + 3);
  664. var preMatched = (i > 0) ? getRankingData(i - 1, type, i) : null;
  665. if (i == 0) rows = [getMyRanking(s, i + 1, type), matched, nextMatched];
  666. else rows = [preMatched, getMyRanking(s, i + 1, type), matched];
  667. break;
  668. }
  669. }
  670. return rows;
  671. }
  672. var rankingRows = getRankingRows(score, type);
  673. if (rankingRows) this.__rankingModel.setData(rankingRows);
  674. },
  675. __setResultsRows: function(score)
  676. {
  677. var pois = this.__pois, tiers = this.__tiers, format = this.__format, type = this.__selectedSimPoi, ranks = this.__isolatedRanks;
  678. var poiUtil = ClientLib.Base.PointOfInterestTypes;
  679. var getScore = poiUtil.GetScoreByLevel;
  680. var getMultiplier = poiUtil.GetBoostModifierByRank;
  681. var getBonus = poiUtil.GetBonusByType;
  682. var getTier = function(s)
  683. {
  684. if (s == 0) return "0";
  685. else for (var i = 0; i < tiers.length; i++) if (s >= tiers[i][1] && s < tiers[i][2]) return tiers[i][0];
  686. };
  687. var getNextTier = function(s)
  688. {
  689. for (var i = 0; i < tiers.length; i++) if (s >= tiers[i][1] && s < tiers[i][2]) return (tiers[i][2] - s);
  690. };
  691. var getPreviousTier = function(s)
  692. {
  693. for (var i = 0; i < tiers.length; i++) if (s >= tiers[i][1] && s < tiers[i][2]) return (s - tiers[i][1]);
  694. };
  695. var getRank = function(s, t)
  696. {
  697. for (var i = 0; i < ranks[t].length; i++) if (s >= (ranks[t][i].pois || 0)) return i + 1;
  698. };
  699. var getNextRank = function(s, t)
  700. {
  701. for (var i = 0; i < ranks[t].length; i++) if (s >= (ranks[t][i].pois || 0)) return (ranks[t][i-1]) ? ranks[t][i-1].pois : s;
  702. };
  703. var getPreviousRank = function(s, t)
  704. {
  705. for (var i = 0; i < ranks[t].length; i++) if (s >= (ranks[t][i].pois || 0)) return (ranks[t][i].pois || 0);
  706. };
  707. var getSimulatedData = function(s, p)
  708. {
  709. var ot = pois[p].tier;
  710. var or = pois[p].rank;
  711. var ob = pois[p].bonus;
  712. var otb = pois[p].totalBonus;
  713. var pp = pois[p].bonusType;
  714. var t = getTier(s);
  715. var r = getRank(s, p);
  716. var ps = getPreviousRank(s, p);
  717. var ns = getNextRank(s, p);
  718. var pr = s - ps;
  719. var nr = ns - s;
  720. var nt = getNextTier(s);
  721. var pt = getPreviousTier(s);
  722. var b = getBonus(pois[p].index, s);
  723. var m = getMultiplier(r);
  724. var f = format;
  725. var tb = b + (b * m / 100);
  726. var sc = function(val, org, poiType, fac)
  727. {
  728. var cs = [webfrontend.gui.util.BBCode.clrLink, '#41a921', '#e23636'];
  729. var st = function(c){return '<p style="padding: 0; margin: 0; color: ' + c + '">'}, et = '</p>';
  730. if (val == undefined) return null;
  731. if (org == undefined) return st(cs[0]) + val + et;
  732. else if (org != undefined && poiType == null) return ((val-org)*fac > 0) ? st(cs[1])+val+et : ((val-org)* fac < 0) ? st(cs[2])+val+et : val;
  733. else
  734. {
  735. var fv = (poiType == 1) ? format(Math.round(val)) : Math.round(val * 100) / 100 + '%';
  736. return ((val - org) * fac > 0) ? st(cs[1]) + fv + et : ((val - org) * fac < 0) ? st(cs[2]) + fv + et : fv;
  737. }
  738. };
  739. var rows = ['Score', 'Tier', 'Rank', 'Multiplier', 'Previous Rank', 'Next Rank', 'Previous Tier', 'Next Tier', 'Bonus', 'Total Bonus'];
  740. var data = [f(s), sc(t,ot,null,1), sc(r,or,null,-1), '+'+m+'%', '+'+f(pr), '-'+f(nr), '+'+f(pt), '-'+f(nt), sc(b,ob,pp,1), sc(tb,otb,pp,1)];
  741. var results = [];
  742. for (var i = 0; i < rows.length; i++) results.push([sc(rows[i]), data[i]]);
  743. return results;
  744. };
  745. var resultsRows = getSimulatedData(score, type);
  746. if (resultsRows) this.__resultsModel.setData(resultsRows);
  747. },
  748. __setPoisRows: function()
  749. {
  750. var poiUtil = ClientLib.Base.PointOfInterestTypes;
  751. var getScore = poiUtil.GetScoreByLevel; //poi level
  752. var alliance = ClientLib.Data.MainData.GetInstance().get_Alliance();
  753. var opois = alliance.get_OwnedPOIs();
  754. var poiInfo = phe.cnc.gui.util.Text.getPoiInfosByType;
  755. var poisRows = [], type = this.__selectedSimPoi;
  756. opois.map(function(poi)
  757. {
  758. if (poiInfo(poi.t).type == type)
  759. {
  760. var a = webfrontend.gui.util.BBCode.createCoordsLinkText((poi.x + ':' + poi.y), poi.x, poi.y);
  761. poisRows.push([a, poi.l, getScore(poi.l), true]);
  762. }
  763. });
  764. if (poisRows) this.__poisModel.setData(poisRows);
  765. },
  766. __initSim: function()
  767. {
  768. var score = this.__pois[this.__selectedSimPoi].score;
  769. this.__setSimLabels();
  770. this.__setRankingRows(score);
  771. this.__setResultsRows(score);
  772. this.__setPoisRows();
  773. this.__poisTable.setUserData('score', score);
  774. this.__poisTable.resetSelection();
  775. this.__selectPoiLevel.setSelection([this.__selectPoiLevel.getSelectables()[0]]);
  776. },
  777. __updateGraph: function()
  778. {
  779. try
  780. {
  781. var data = ClientLib.Data.MainData.GetInstance();
  782. var alliance = data.get_Alliance();
  783. var ranks = alliance.get_POIRankScore();
  784. var poiUtil = ClientLib.Base.PointOfInterestTypes;
  785. var getScore = poiUtil.GetScoreByLevel;
  786. var getMultiplier = poiUtil.GetBoostModifierByRank;
  787. var getBonus = poiUtil.GetBonusByType;
  788. var getNextScore = poiUtil.GetNextScore;
  789. var startRank = ClientLib.Base.EPOIType.RankedTypeBegin;
  790. var endRank = ClientLib.Base.EPOIType.RankedTypeEnd;
  791. var poiInfo = phe.cnc.gui.util.Text.getPoiInfosByType;
  792.  
  793. var pois = {}, format = this.__format, tiers = this.__tiers;
  794. var colors = ["#8dc186", "#5b9dcb", "#8cc1c7", "#d7d49c", "#dbb476", "#c47f76", "#928195"];
  795. var getTier = function(s)
  796. {
  797. for (var i = 0; i < tiers.length; i++) if (s >= tiers[i][1] && s < tiers[i][2]) return tiers[i][0];
  798. };
  799. var getHeight = function(s)
  800. {
  801. if (s == 0) return 0;
  802. for (var i = 0; i < tiers.length; i++)
  803. if (s >= tiers[i][1] && s < tiers[i][2]) return Math.round((s - tiers[i][1]) / (tiers[i][2] - tiers[i][1]) * 100);
  804. };
  805.  
  806. var colors = ["#8dc186", "#5b9dcb", "#8cc1c7", "#d7d49c", "#dbb476", "#c47f76", "#928195"];
  807. for (var i = 0; i < ranks.length; i++)
  808. {
  809. var type = i + startRank;
  810. var name = poiInfo(type).type;
  811. var rank = ranks[i].r;
  812. var multiplier = getMultiplier(rank);
  813. var score = ranks[i].s;
  814. var bonus = getBonus(type, score);
  815. var nextScore = getNextScore(score);
  816. var nextBonus = getBonus(type, nextScore);
  817. var totalBonus = bonus + (bonus * multiplier / 100);
  818. var nextTotalBonus = nextBonus + (nextBonus * multiplier / 100);
  819. var nextTier = format(nextScore - score);
  820. var poiType = (i > 2) ? 2 : 1;
  821. var color = colors[i];
  822. var tier = getTier(ranks[i].s);
  823. var height = getHeight(ranks[i].s);
  824. var f_score = format(score);
  825. var f_rank = rank + ' (' + multiplier + '%)';
  826. var f_totalBonus = (poiType == 1) ? format(totalBonus) : Math.round(totalBonus * 100) / 100 + ' %';
  827. nextTotalBonus = (poiType == 1) ? format(nextTotalBonus) : Math.round(nextTotalBonus * 100) / 100 + ' %';
  828. pois[name] =
  829. {
  830. 'score': score,
  831. 'tier': tier,
  832. 'bonus': bonus,
  833. 'totalBonus': totalBonus,
  834. 'index': type,
  835. 'bonusType': poiType,
  836. 'rank': rank,
  837. 'multiplier': multiplier,
  838. 't': tier,
  839. 's': f_score,
  840. 'r': f_rank,
  841. 'nt': nextTier,
  842. 'tb': f_totalBonus,
  843. 'ntb': nextTotalBonus,
  844. 'c': color,
  845. 'h': height
  846. };
  847. }
  848. console.log('data ready')
  849. this.__pois = pois;
  850. this.__graph.call(this);
  851. }
  852. catch(e)
  853. {
  854. console.log(e.toString());
  855. }
  856. },
  857. __graph: function()
  858. {
  859. console.log('creating graph');
  860. var root = this, pois = this.__pois, style = this.__style;
  861. var create = function(a, b)
  862. {
  863. var elm = new root.__element(a);
  864. if (b instanceof Object) elm.css(b);
  865. return elm;
  866. };
  867. var addRow = function(title, arr, table, selected)
  868. {
  869. var row = create('tr', style.rows.tr), header = create('td', style.cell.header);
  870. row.elm.onclick = function()
  871. {
  872. var tr = table.elm.getElementsByTagName('tr');
  873. for (var i = 1; i < tr.length; i++)
  874. {
  875. tr[i].style.backgroundColor = '#d6dde1';
  876. }
  877. this.style.backgroundColor ='#ecf6fc';
  878. };
  879. if (selected == 1) row.css({'backgroundColor': '#ecf6fc'});
  880. header.text(title);
  881. row.append(header);
  882. for (var key in arr)
  883. {
  884. var td = create('td', style.cell.data);
  885. td.text(arr[key]);
  886. row.append(td);
  887. }
  888. table.append(row);
  889. };
  890. var table = create('table', style.table);
  891. var gc = create('tr', style.rows.graph);
  892. var gh = create('td');
  893. var ul = create('ul', style.icon.ul);
  894. table.set({"id": "data", "cell-spacing": 0, "cell-padding": 0, "rules": "groups", "width": "100%"});
  895. gh.append(ul);
  896. gc.append(gh);
  897. table.append(gc);
  898. var score = [], tier = [], nextTier = [], bns = [], nextBns = [], poiRank = [], m = 0;
  899. for (var key in pois)
  900. {
  901. var color = pois[key].c,
  902. name = key,
  903. h = pois[key].h,
  904. td = create('td', style.graph.td),
  905. div = create('div', style.graph.div),
  906. li = create('li', style.icon.li),
  907. icon = create('div', style.icon.div),
  908. p = create('p', style.icon.p);
  909. bns[m] = pois[key].tb;
  910. poiRank[m] = pois[key].r;
  911. score[m] = pois[key].s;
  912. tier[m] = pois[key].t;
  913. nextTier[m] = pois[key].nt;
  914. nextBns[m] = pois[key].ntb;
  915. div.css({'backgroundColor': color, 'height': h * 2 - 3 + 'px'});
  916. td.append(div);
  917. gc.append(td);
  918. icon.css({'backgroundColor': color});
  919. p.text(name);
  920. li.append(icon);
  921. li.append(p);
  922. ul.append(li);
  923. m++;
  924. }
  925. addRow('Tier', tier, table, 0);
  926. addRow('Alliance Rank', poiRank, table, 0);
  927. addRow('Score', score, table);
  928. addRow('Next Tier Requires', nextTier, table, 0);
  929. addRow('Bonus', bns, table, 1);
  930. addRow('Next Tier Bonus', nextBns, table, 0);
  931. document.getElementById('graph').appendChild(table.elm);
  932. }
  933. }
  934. });
  935. }
  936. function initialize_ccta_pa()
  937. {
  938. console.log('poiAnalyser: ' + 'POIs Analyser retrying...');
  939. if (typeof qx != 'undefined' && typeof qx.core != 'undefined' && typeof qx.core.Init != 'undefined' && typeof ClientLib != 'undefined' && typeof webfrontend != 'undefined' && typeof phe != 'undefined')
  940. {
  941. var app = qx.core.Init.getApplication();
  942. if (app.initDone == true)
  943. {
  944. try
  945. {
  946. var isDefined = function(a){return (typeof a == 'undefined') ? false : true};
  947. var data = ClientLib.Data.MainData.GetInstance();
  948. var net = ClientLib.Net.CommunicationManager.GetInstance();
  949. if (isDefined(data) && isDefined(net))
  950. {
  951. var alliance = data.get_Alliance();
  952. var player = data.get_Player();
  953. var poiUtil = ClientLib.Base.PointOfInterestTypes;
  954. var poiInfo = phe.cnc.gui.util.Text.getPoiInfosByType;
  955. if (isDefined(alliance) && isDefined(player) && isDefined(alliance.get_Exists()) && isDefined(player.get_Name()) && player.get_Name() != '' && isDefined(poiUtil) && isDefined(poiInfo))
  956. {
  957. try
  958. {
  959. console.log('poiAnalyser: ' + 'initializing POIs Analyser');
  960. create_ccta_pa_class();
  961. ccta_pa.getInstance();
  962. }
  963. catch(e)
  964. {
  965. console.log('poiAnalyser: ' + "POIs Analyser script init error:");
  966. console.log('poiAnalyser: ' + e.toString());
  967. }
  968. }
  969. else window.setTimeout(initialize_ccta_pa, 10000);
  970. }
  971. else window.setTimeout(initialize_ccta_pa, 10000);
  972. }
  973. catch(e)
  974. {
  975. console.log('poiAnalyser: ' + e.toString());
  976. }
  977. }
  978. else window.setTimeout(initialize_ccta_pa, 10000);
  979. }
  980. else window.setTimeout(initialize_ccta_pa, 10000);
  981. };
  982. window.setTimeout(initialize_ccta_pa, 10000);
  983. };
  984. function inject()
  985. {
  986. var script = document.createElement("script");
  987. script.innerHTML = "(" + injectScript.toString() + ")();";
  988. script.type = "text/javascript";
  989. if (/commandandconquer\.com/i.test(document.domain)) {
  990. document.getElementsByTagName("head")[0].appendChild(script);
  991. console.log('injected');
  992. }
  993. };
  994. inject();
  995. })();