The West - Skills Calc

Calculates sum of skills obtained from items

当前为 2015-04-26 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @namespace https://greasyfork.org/users/8637
  3. // @name The West - Skills Calc
  4. // @author neversleep1911
  5. // @description Calculates sum of skills obtained from items
  6. // @include http://*.the-west.*/game.php*
  7. // @grant none
  8. // @version 2.1.1
  9. // @copyright Copyright (c) 2015 neversleep1911 (full list of contributors/translators see here: https://greasyfork.org/scripts/7829)
  10. // @license MIT (http://opensource.org/licenses/MIT)
  11. // ==/UserScript==
  12.  
  13. (function(func) {
  14. var script;
  15. script = document.createElement("script");
  16. script.setAttribute("type", "text/javascript");
  17. script.textContent = "(" + func.toString() + ")();";
  18. document.body.appendChild(script);
  19. document.body.removeChild(script);
  20. })(function() {
  21. var Gui, I18n, SkillsCalc;
  22. I18n = function() {
  23. function I18n() {}
  24. var DEFAULT_LANGUAGE, STRINGS, language;
  25. DEFAULT_LANGUAGE = "en_US";
  26. STRINGS = {
  27. en_US: {
  28. dialogs: {
  29. add_item: "Add item",
  30. add_character_items: "Character's items"
  31. },
  32. groups: {
  33. skills: "Skills",
  34. items: "Items"
  35. },
  36. buttons: {
  37. character: "Character",
  38. add: "Add",
  39. reset: "Reset"
  40. },
  41. checkboxes: {
  42. show_bonus: "Show bonus",
  43. show_skills: "Show my skills"
  44. },
  45. labels: {
  46. level: "Level",
  47. item_id: "Item ID",
  48. character_name: "Character's name",
  49. health: "Health"
  50. },
  51. tooltip: {
  52. health: "Normal / Solder / Solder with bonus"
  53. },
  54. errors: {
  55. player_not_found: "Player not found!"
  56. }
  57. },
  58. pl_PL: {
  59. dialogs: {
  60. add_item: "Dodaj przedmiot",
  61. add_character_items: "Przedmioty gracza"
  62. },
  63. groups: {
  64. skills: "Umiejętności",
  65. items: "Przedmioty"
  66. },
  67. buttons: {
  68. character: "Gracz",
  69. add: "Dodaj",
  70. reset: "Reset"
  71. },
  72. checkboxes: {
  73. show_bonus: "Pokaż bonus",
  74. show_skills: "Pokaż moje umiejętności"
  75. },
  76. labels: {
  77. level: "Level",
  78. item_id: "ID przedmiotu",
  79. character_name: "Nazwa gracza",
  80. health: "Życie"
  81. },
  82. tooltip: {
  83. health: "Normalny / Żołnierz / Żołnierz z bonusem"
  84. },
  85. errors: {
  86. player_not_found: "Gracz nie znaleziony!"
  87. }
  88. },
  89. ru_RU: {
  90. dialogs: {
  91. add_item: "Добавить предмет",
  92. add_character_items: "Предметы персонажа"
  93. },
  94. groups: {
  95. skills: "Навыки",
  96. items: "Предметы"
  97. },
  98. buttons: {
  99. character: "Персонаж",
  100. add: "Добавить",
  101. reset: "Сбросить"
  102. },
  103. checkboxes: {
  104. show_bonus: "Показывать бонусы",
  105. show_skills: "Показывать мои навыки"
  106. },
  107. labels: {
  108. level: "Уровень",
  109. item_id: "ID предмета",
  110. character_name: "Имя персонажа",
  111. health: "Здоровье"
  112. },
  113. tooltip: {
  114. health: "Минимум / Солдат / Солдат с бонусом"
  115. },
  116. errors: {
  117. player_not_found: "Игрок не найден!"
  118. }
  119. }
  120. };
  121. language = DEFAULT_LANGUAGE;
  122. I18n.language = function() {
  123. return language;
  124. };
  125. I18n.setLanguage = function(lang) {
  126. return language = STRINGS[lang] ? lang : DEFAULT_LANGUAGE;
  127. };
  128. I18n.tr = function(id) {
  129. var string;
  130. string = STRINGS[language];
  131. $(id.split(".")).each(function(k, v) {
  132. return (string = string[v]) !== void 0;
  133. });
  134. return string || id;
  135. };
  136. return I18n;
  137. }();
  138. Gui = function() {
  139. function Gui() {}
  140. Gui.createMenuButton = function(options) {
  141. var button;
  142. if (options == null) {
  143. options = {};
  144. }
  145. button = $("<div class='menulink' title='" + options.title + "' />");
  146. if (options.image) {
  147. button.css("background-image", "url(" + options.image + ")");
  148. }
  149. button.hover(function() {
  150. $(this).css("background-position", "-25px 0px");
  151. return true;
  152. }, function() {
  153. $(this).css("background-position", "0px 0px");
  154. return true;
  155. }).on("click", options.onclick);
  156. $("div#ui_menubar").append($('<div class="ui_menucontainer" />').append(button).append('<div class="menucontainer_bottom" />'));
  157. return button;
  158. };
  159. Gui.createGroup = function(options) {
  160. var content, group, scrollPane;
  161. if (options == null) {
  162. options = {};
  163. }
  164. group = new west.gui.Groupframe("", "<div />");
  165. if (options.css) {
  166. $(group.getMainDiv()).css(options.css);
  167. }
  168. content = $(".tw2gui_groupframe_content_pane div", group.getMainDiv()).first();
  169. if (options.title) {
  170. content.append($("<h2>" + options.title + "</h2><hr style='margin-top: 2px; margin-bottom: 4px;' />"));
  171. }
  172. if (options.scrollPane) {
  173. scrollPane = new west.gui.Scrollpane;
  174. if (options.scrollPane.css) {
  175. $(scrollPane.getMainDiv()).css(options.scrollPane.css);
  176. }
  177. content.append(scrollPane.getMainDiv());
  178. group.scrollPane = scrollPane;
  179. group.appendToScrollContentPane = function(content) {
  180. scrollPane.appendContent(content);
  181. return group;
  182. };
  183. }
  184. return group;
  185. };
  186. Gui.createButton = function(options) {
  187. var button;
  188. if (options == null) {
  189. options = {};
  190. }
  191. button = new west.gui.Button(options.text);
  192. button.click(options.onclick);
  193. $(button.getMainDiv()).css(options.css);
  194. return button;
  195. };
  196. Gui.createCheckbox = function(options) {
  197. var checkbox;
  198. if (options == null) {
  199. options = {};
  200. }
  201. checkbox = new west.gui.Checkbox(options.text, "", options.onclick);
  202. $(checkbox.getMainDiv()).css(options.css);
  203. return checkbox;
  204. };
  205. Gui.createTextfield = function(options) {
  206. var field;
  207. if (options == null) {
  208. options = {};
  209. }
  210. field = new west.gui.Textfield;
  211. field.setSize(options.size);
  212. field.setLabel($("<span>" + options.label + "</span>"));
  213. if (options.value) {
  214. field.setValue(options.value);
  215. }
  216. if (options.css) {
  217. $(field.getMainDiv()).css(options.css);
  218. }
  219. return field;
  220. };
  221. return Gui;
  222. }();
  223. SkillsCalc = function() {
  224. function SkillsCalc() {
  225. var self;
  226. self = this;
  227. I18n.setLanguage(Game.locale);
  228. Gui.createMenuButton({
  229. title: SkillsCalc.NAME,
  230. image: this.MENU_BUTTON_IMAGE,
  231. onclick: function(e) {
  232. self.createWindow();
  233. e.preventDefault();
  234. return false;
  235. }
  236. });
  237. }
  238. var ItemCalculator, Window;
  239. SkillsCalc.ID = "tw_skills_calc";
  240. SkillsCalc.NAME = "Skills Calc";
  241. SkillsCalc.AUTHOR = "neversleep1911";
  242. SkillsCalc.WEB_SITE = "https://greasyfork.org/scripts/7829";
  243. SkillsCalc.MIN_GAME_VERSION = "2.21";
  244. SkillsCalc.MAX_GAME_VERSION = Game.version.toString();
  245. SkillsCalc.prototype.MENU_BUTTON_IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAZCAIAAAD8NuoTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QQICBgbVC0rcwAACI5JREFUSMel10tvXFcBAODzuq+5987MHY/nYTvx24lj13k0KQ5NmjR90ELVVoIKSitARWxAFSyqskKskLphwQKJFUKilUCIBVIXFVSN0tKmTVPbbdwkjhOPXzPjGd953vc9557Dgp8wf+Dbf/A3PzpZr9m5wum7ew+E45maEau+nphaOgwYzBqWE0WdXldLWF/iFiCAiYyebXa9nUbbjkNAcN5IJ0FUzmpL87l6LcyXypW9Wux76WzOdblhcaIBHqpZM+X73O32uBwyCrmaGJTIKb1l9xpdp+VTpCADK0Qkw2kF/vZ7p48tnH7zrb/UEw4ZAAQxLrCQhJA4DIlIEoAEEjLHMUSKSMW4iwAWPOECaUSlLBhJg1+/8dPmyodYTY3PnF+7vd6MXAFBwmIFmgD0w5BIipaoLosQEZCRSIksriYgcaFAnKMEJJIkYRhnFfPM4kJl5WP42hNz9zYas6cnVQP2Omx/rxNxIKeU9HCxnNYuP/aYnskW86n1O41/vvv+5pc3MUYSQQFLKBcYAiBAkoiTJyZ//tz8v95fWbtvLywNRH3n/MnnL5Tga08c+2Tl3ty5b2ZzOe53GaVKSpcVOUlY1G712n2Js8jxy4Y6kTc5Rm7IXInU7P6n24c84UVDVQjad9pvvv7K/Tv3rn2xNzM7PQiVyZvPP/8kkUvTG9373s1VAQAVYFgmZ4sZgrGlEBUhT0W6ZoAhsxfGn9e6LQBOjFrLC+Ndjj7Z+k/Li2nCRywd+0q9Xp2YmLh2s7I6GDWby+xubZKhMVUiXJZJTLklkyPZ1Mf1bsDFuKnO5E0VIwWAbbt/y3ZeeejI0089nD8+4dzZys1N5IvDb/zhXRH2I5oUCnm1VesEkcphNBiFk82COY1PWWhnrxsJwBKOIPRposskRTCHsOGEaVXe9ughgJamVDm+H2p2vTe9MJudndM1hPPj318amjalzWb3Zy8+UtltVJq27bBBqJbtXVy+RFKCmhjbjKsSkgkCECQQRkKUDO2g4+72/FcvLz77wqU9FxqHNWXIGiqXuQgwdVzXG7WkV0994+1/fKCpbjOqZS3dDTFj8SCU3bMODxrILBYpogIILgDnIi0RGYCcIilAICBOF8zlh+cbd++OTU/v3a04bTvkMVK0pNu0NFL2Gq7rFpYWi2a/fTDVFRbkwYAUkAQFHCWpnJAkhJCAIKAsSrhB8PJM8cx0Ka3IkqJyDgFDW7c2xs4vsjC8/+H1+tpa6ERhgvpBIFsFynDkRx3vy1wBSHoyIMUjCuKYJDw0JMwEdAKaIigRoh1RgYAXxAQBM59e94nkRp59a8wkaQIalWbQdTVVjhHmCeJqdqv2VbvbPzrxzL3aVuxDTSaDUHajIS/M4EePZ1fu2C9+a9LUFQkRxjiGoG67mHOaiI1mN2o1G4H47oXjnUYrlZJHZkeMrIIQAFFYKpaUI+Mra6th3z81u9RsB/+9ufXSczODUFZKOX5illi62fejZ58c9rz87Vvue1f3XT+EBAYxQwi8/Pip5TOzSemEgf15UxxWbGt6xKs3+o2+H0b7lH/W+KjV2w0pkFHnWFbmCA9Iuf2oHVDitx2aIEVKZAuMj8u6jps9birQS7ipkHqze39zO+yi21iZSaOR6el+o51EIAxZ4NAudK7euDE7Jd3cqFzZmavWtoRIBqSuXt8cKg+jSvUwEAwJGEXCyKKHlsyUQSIuFIJdxu9sVGOXikZ1OKtHSp4K0d1t0Jh2O06CycLinKKQfE5hHK6u73tB6MTJgFRIycGhg8YfOsoEhxgyAASC5XJWVaWIJgaGiItDmgQdp8zCocOq7reqn3+FsMwoS/wYCUF933X9fj9OIJg7l5u7cjYBYkAqk1GPlCdJSs/mlfTeNq1UQ8fhgR1Rj8aM9WIGILQgmBofGr/8dO2rz6Dt8oiFfV+TQMaUQ8EnJos//uFLURSUU7tHi8refjCclQekDPy3ctEiO1/vTI2of/rrfT9OZIwJQhBCDmEnYkCI+bwu0kYQBIVT56K9u2EYeEF89d5BXsLHJ4f9+s78VAnynNvvr20dOrVg6sjwgFRMnPWtVXzpzNint/Y9j3djGsXMiRngnCci4gJBEDHRbnTt2/cmDWEa5IvP773z2YPF+bHzy8dYEAFFpyniNR9cu75tDRsToxPvvLcOmRiEWllrEijIdCkrUzF6NI3iOJ3WCAAEw2xakmJhO7TS867v2Tdo42qlHiUCSuhXP7gwM1nAkqrlM7erdGNdefyIsji/lCe9vCkmdVwqDUQtnzhmGAhVIzWVMYZKWgSgwxIfQpdyR6COqo4eyZ4rWzMZ/eyIdeiF375y8ve/eHKIRf1aP05gulwMws6DrV25sLR3sK9ocqUjkRQekNrYvtXo7JIPPt7YbLYvXixtbUMci5iyWEDgs0yK1+sxZ0JDKEDwlxePTYxl9lf3s6M5WVc5hI1PbxwvFeauvPLFtfe3q3sCNLGob9r+5YI8CHXzrt30BXnh4kSvc6iloCYRjzFM0KyhDClS7NE2FRAIxrkI6epWK+qEw4WMbhGc0/lBzTzxjDR9KuSqXhrLl5TJscKl+VOxWB2QmpuckVUB//76+UOReevtf9u+NDWUcnicVlXap1wDQQB1whAGcSQ4QBzLUhxxCLR0yqUBTyK7z9OUT0zpjz991v16ZfmRea4u/fHP7+xGIiOritZXuc7jSFItGrbqkRg1VcejwsgYMQNy3Le5NGRmM1Jlx85IYqMVLS2P/mSpWK3uwN+9/EgaoY1Go+6y0VKx7UT1jud6Hog9azivQZ4GwJCArOB0SklZWJWBFwotV/Tttt13uGg9dWFaTrpr2xZ1SYaA7S7dPTwYGRn1YlFttnuURf12TtUky8i5sJghHg7KukZ0nM7+/zsAkbGuvSM1e5OPphNjaGd3/38JylRK90rXAwAAAABJRU5ErkJggg==";
  246. SkillsCalc.prototype.windows = {};
  247. SkillsCalc.prototype.createWindow = function() {
  248. var self, wndId;
  249. self = this;
  250. while (true) {
  251. wndId = Math.ceil(Math.random() * 1024);
  252. if (!this.windows[wndId]) {
  253. break;
  254. }
  255. }
  256. this.windows[wndId] = new Window({
  257. id: wndId,
  258. title: SkillsCalc.NAME,
  259. miniTitle: SkillsCalc.NAME
  260. });
  261. this.windows[wndId].onDestroy = function(wnd) {
  262. delete self.windows[wnd.id];
  263. return true;
  264. };
  265. return true;
  266. };
  267. Window = function() {
  268. function Window(options) {
  269. var self;
  270. self = this;
  271. this.images = {};
  272. this.items = {};
  273. this.calculator = new ItemCalculator;
  274. this.calculator.level = Character.level;
  275. this.id = options.id;
  276. this.wnd = wman.open("skills-calc-window-" + options.id, null, "noreload");
  277. this.wnd.setTitle(options.title);
  278. this.wnd.setMiniTitle(options.miniTitle);
  279. this.wnd.addEventListener("WINDOW_DESTROY", function() {
  280. if (self.onDestroy) {
  281. return self.onDestroy(self);
  282. } else {
  283. return true;
  284. }
  285. });
  286. this.wnd.appendToContentPane((this.groupSkills = Gui.createGroup({
  287. id: "skills",
  288. title: I18n.tr("groups.skills"),
  289. css: {
  290. width: 402,
  291. position: "absolute"
  292. },
  293. scrollPane: {
  294. css: {
  295. height: 264
  296. }
  297. }
  298. })).getMainDiv());
  299. this.wnd.appendToContentPane((this.groupItems = Gui.createGroup({
  300. id: "items",
  301. title: I18n.tr("groups.items"),
  302. css: {
  303. left: 400,
  304. width: 294
  305. },
  306. scrollPane: {
  307. css: {
  308. height: 264
  309. }
  310. }
  311. })).getMainDiv());
  312. this.wnd.appendToContentPane(Gui.createButton({
  313. text: I18n.tr("buttons.reset"),
  314. css: {
  315. left: 592,
  316. top: 342,
  317. position: "absolute"
  318. },
  319. onclick: function(button, data) {
  320. return self.onButtonResetClick(button, data);
  321. }
  322. }).getMainDiv());
  323. this.wnd.appendToContentPane(Gui.createButton({
  324. text: I18n.tr("buttons.add"),
  325. css: {
  326. left: 490,
  327. top: 342,
  328. position: "absolute"
  329. },
  330. onclick: function(button, data) {
  331. return self.onButtonAddClick(button, data);
  332. }
  333. }).getMainDiv());
  334. this.wnd.appendToContentPane(Gui.createButton({
  335. text: I18n.tr("buttons.character"),
  336. css: {
  337. left: 388,
  338. top: 342,
  339. position: "absolute"
  340. },
  341. onclick: function(button, data) {
  342. return self.onButtonCharacterClick(button, data);
  343. }
  344. }).getMainDiv());
  345. this.wnd.appendToContentPane((this.checkboxBonus = Gui.createCheckbox({
  346. text: I18n.tr("checkboxes.show_bonus"),
  347. css: {
  348. left: 2,
  349. top: 324,
  350. position: "absolute"
  351. },
  352. onclick: function(state) {
  353. return self.onCheckboxBonusClick(state);
  354. }
  355. })).getMainDiv());
  356. this.wnd.appendToContentPane((this.checkboxSkills = Gui.createCheckbox({
  357. text: I18n.tr("checkboxes.show_skills"),
  358. css: {
  359. left: 2,
  360. top: 350,
  361. position: "absolute"
  362. },
  363. onclick: function(state) {
  364. return self.onCheckboxSkillsClick(state);
  365. }
  366. })).getMainDiv());
  367. this.wnd.appendToContentPane((this.textfieldLevel = Gui.createTextfield({
  368. size: 6,
  369. label: I18n.tr("labels.level"),
  370. value: this.calculator.level,
  371. css: {
  372. left: 180,
  373. top: 320,
  374. position: "absolute"
  375. }
  376. })).getMainDiv());
  377. this.wnd.appendToContentPane(this.labelHealth = $("<span />").css({
  378. position: "absolute",
  379. left: 180,
  380. top: 352
  381. }).attr("title", I18n.tr("tooltip.health")));
  382. this.textfieldLevel.onlyNumeric().getField().keyup(function(e) {
  383. var level;
  384. level = parseInt(self.textfieldLevel.getValue());
  385. if (!isNaN(level) && level > 0) {
  386. self.calculator.level = level;
  387. self.recalc();
  388. self.repaint();
  389. }
  390. return true;
  391. });
  392. this.initGroupSkills();
  393. this.initGroupItems();
  394. }
  395. Window.prototype.initGroupSkills = function() {
  396. var attr, attrs, div, img, j, l, len, len1, skill, skillType, skills;
  397. attrs = CharacterSkills.allAttrKeys;
  398. for (j = 0, len = attrs.length; j < len; j++) {
  399. attr = attrs[j];
  400. div = $('<div style="height: 41px;" />');
  401. skills = CharacterSkills.skillKeys4Attr[attr];
  402. for (l = 0, len1 = skills.length; l < len1; l++) {
  403. skillType = skills[l];
  404. skill = new Skill(skillType);
  405. img = skill.getSkillImage();
  406. img.removeAttr("class").css({
  407. width: 72,
  408. display: "inline-block",
  409. "text-align": "center",
  410. "font-weight": "bold",
  411. "margin-left": 2
  412. });
  413. $("img.skillicon", img).removeAttr("class").css({
  414. width: "100%"
  415. });
  416. $("span.skillpoints_label", img).attr("class", "skills-calc-skillpoints_label").css({
  417. display: "inline-block",
  418. position: "relative",
  419. top: -16,
  420. width: "100%",
  421. height: 12,
  422. color: "#ffffff",
  423. "text-align": "center",
  424. "font-size": "9pt",
  425. "text-shadow": "1px 1px 1px rgb(0, 0, 0)",
  426. "background-image": "url('/images/tw2gui/plusminus/plusminus_display_bg2.png')"
  427. });
  428. div.append(img);
  429. this.images[skillType] = img.get(0);
  430. }
  431. this.groupSkills.appendToScrollContentPane(div);
  432. this.groupSkills.appendToScrollContentPane($('<hr style="margin: 12px 0;" />'));
  433. }
  434. return true;
  435. };
  436. Window.prototype.initGroupItems = function() {
  437. var items, j, len, ref, slot;
  438. items = [];
  439. ref = Wear.slots;
  440. for (j = 0, len = ref.length; j < len; j++) {
  441. slot = ref[j];
  442. if (Wear.wear[slot]) {
  443. items.push(Wear.wear[slot].obj);
  444. }
  445. }
  446. this.addItems(items);
  447. return this.repaint();
  448. };
  449. Window.prototype.onButtonCharacterClick = function() {
  450. var content, dlg, ok, self, textfieldName;
  451. self = this;
  452. dlg = new west.gui.Dialog(I18n.tr("dialogs.add_character_items"));
  453. content = $("<div style='margin-top: 10px; text-align: center;'></div>");
  454. content.append((textfieldName = Gui.createTextfield({
  455. size: 25,
  456. label: I18n.tr("labels.character_name")
  457. })).getMainDiv());
  458. ok = function() {
  459. var name;
  460. if (!(name = $.trim(textfieldName.getValue()))) {
  461. return false;
  462. }
  463. self.wnd.showLoader();
  464. return Ajax.remoteCallMode("ranking", "get_data", {
  465. rank: NaN,
  466. search: name = name.toLowerCase(),
  467. tab: "duels"
  468. }, function(json) {
  469. var found, j, len, player, ref;
  470. if (json.error) {
  471. self.wnd.hideLoader();
  472. return (new UserMessage(json.msg, UserMessage.TYPE_ERROR)).show();
  473. }
  474. found = false;
  475. ref = json.ranking;
  476. for (j = 0, len = ref.length; j < len; j++) {
  477. player = ref[j];
  478. found = player.name.toLowerCase() === name;
  479. if (found) {
  480. Ajax.remoteCallMode("profile", "init", {
  481. name: player.name,
  482. playerId: player.id
  483. }, function(resp) {
  484. var items, l, len1, ref1, slot;
  485. if (resp.error) {
  486. self.wnd.hideLoader();
  487. return (new UserMessage(resp.message, UserMessage.TYPE_ERROR)).show();
  488. } else {
  489. items = [];
  490. ref1 = Wear.slots;
  491. for (l = 0, len1 = ref1.length; l < len1; l++) {
  492. slot = ref1[l];
  493. if (resp.wear[slot]) {
  494. items.push(ItemManager.get(resp.wear[slot]));
  495. }
  496. }
  497. self.reset();
  498. self.calculator.level = resp.level;
  499. self.textfieldLevel.setValue(resp.level);
  500. self.addItems(items);
  501. self.repaint();
  502. self.wnd.hideLoader();
  503. }
  504. return true;
  505. });
  506. break;
  507. }
  508. }
  509. if (!found) {
  510. self.wnd.hideLoader();
  511. (new UserMessage(I18n.tr("errors.player_not_found"), UserMessage.TYPE_ERROR)).show();
  512. }
  513. return true;
  514. });
  515. };
  516. textfieldName.getField().keypress(function(e) {
  517. if (e.which === 13 && ok()) {
  518. dlg.hide();
  519. }
  520. return true;
  521. });
  522. dlg.setText(content).addButton("ok", ok).addButton("cancel").show();
  523. textfieldName.getField().focus();
  524. return true;
  525. };
  526. Window.prototype.onButtonAddClick = function() {
  527. var content, dlg, ok, self, textfieldId;
  528. self = this;
  529. dlg = new west.gui.Dialog(I18n.tr("dialogs.add_item"));
  530. content = $('<div style="margin-top: 10px; text-align: center;"><div id="skills-calc-preview-item" style="height: 60px; width: 60px; float: right; border: 1px solid black; border-radius: 4px;" /></div>');
  531. content.append((textfieldId = Gui.createTextfield({
  532. size: 25,
  533. label: I18n.tr("labels.item_id")
  534. })).maxlength(8).getMainDiv());
  535. textfieldId.getItem = function() {
  536. var id;
  537. id = parseInt(this.getValue());
  538. if (isNaN(id)) {
  539. return void 0;
  540. } else {
  541. return ItemManager.get(id);
  542. }
  543. };
  544. ok = function() {
  545. var item;
  546. if (item = textfieldId.getItem()) {
  547. self.addItems([ item ]);
  548. self.repaint();
  549. return true;
  550. } else {
  551. return false;
  552. }
  553. };
  554. dlg.setText(content).addButton("ok", ok).addButton("cancel").show();
  555. textfieldId.getField().keypress(function(e) {
  556. if (e.which === 13 && ok()) {
  557. dlg.hide();
  558. }
  559. return true;
  560. }).keyup(function(e) {
  561. var item, preview;
  562. preview = $("#skills-calc-preview-item", content).empty();
  563. if (item = textfieldId.getItem()) {
  564. item = new tw2widget.InventoryItem(item);
  565. preview.append($(item.getMainDiv()).css({
  566. "float": "none"
  567. }));
  568. }
  569. return true;
  570. }).focus();
  571. return true;
  572. };
  573. Window.prototype.onButtonResetClick = function() {
  574. return this.reset();
  575. };
  576. Window.prototype.onCheckboxBonusClick = function(state) {
  577. return this.repaint();
  578. };
  579. Window.prototype.onCheckboxSkillsClick = function(state) {
  580. this.recalc();
  581. return this.repaint();
  582. };
  583. Window.prototype.addItems = function(items) {
  584. var item, j, len, self;
  585. self = this;
  586. for (j = 0, len = items.length; j < len; j++) {
  587. item = items[j];
  588. this.removeItem(item);
  589. this.items[item.type] = new tw2widget.InventoryItem(item);
  590. $(this.items[item.type].getMainDiv()).css({
  591. "float": "none",
  592. display: "inline-block"
  593. }).on("click", function(e) {
  594. if (!e.shiftKey) {
  595. item = ItemManager.get($(e.target).data("itemId"));
  596. if (item && self.removeItem(item)) {
  597. self.repaint();
  598. }
  599. }
  600. return true;
  601. });
  602. this.calculator.sumItem(item);
  603. this.groupItems.appendToScrollContentPane($(this.items[item.type].getMainDiv()));
  604. }
  605. return true;
  606. };
  607. Window.prototype.removeItem = function(item) {
  608. if (this.items[item.type]) {
  609. this.calculator.subItem(this.items[item.type].obj);
  610. $(this.items[item.type].getMainDiv()).remove();
  611. delete this.items[item.type];
  612. return true;
  613. } else {
  614. return false;
  615. }
  616. };
  617. Window.prototype.recalc = function() {
  618. var item, ref, ref1, skill, type, value;
  619. this.calculator.reset();
  620. ref = this.items;
  621. for (type in ref) {
  622. item = ref[type];
  623. this.calculator.sumItem(item.obj);
  624. }
  625. if (this.checkboxSkills.isSelected()) {
  626. ref1 = CharacterSkills.skills;
  627. for (skill in ref1) {
  628. value = ref1[skill];
  629. this.calculator.calcSkill(skill, value.points, ItemCalculator.SUM_OP);
  630. }
  631. }
  632. return true;
  633. };
  634. Window.prototype.repaint = function() {
  635. var health, min_health, result, skill, value;
  636. result = this.checkboxBonus.isSelected() ? this.calculator.resultWithBonus() : this.calculator.result;
  637. for (skill in result) {
  638. value = result[skill];
  639. if (this.images[skill]) {
  640. $("span.skills-calc-skillpoints_label", this.images[skill]).text(value);
  641. }
  642. }
  643. min_health = this.calculator.level * 10 + 90;
  644. health = {
  645. normal: format_number(min_health + result.health * 10),
  646. solder: format_number(min_health + result.health * 15),
  647. solderBonus: format_number(min_health + result.health * 20),
  648. toString: function() {
  649. return this.normal + " / " + this.solder + " / " + this.solderBonus;
  650. }
  651. };
  652. this.labelHealth.text(I18n.tr("labels.health") + ": " + health.toString());
  653. return true;
  654. };
  655. Window.prototype.reset = function() {
  656. var item, ref, type;
  657. ref = this.items;
  658. for (type in ref) {
  659. item = ref[type];
  660. $(item.getMainDiv()).remove();
  661. }
  662. $("span.skills-calc-skillpoints_label", this.groupSkills.getMainDiv()).text("0");
  663. this.items = {};
  664. this.calculator.reset();
  665. this.calculator.level = Character.level;
  666. this.textfieldLevel.setValue(Character.level);
  667. this.labelHealth.text(I18n.tr("labels.health") + ": 0 / 0 / 0");
  668. this.checkboxBonus.setSelected(false, true);
  669. this.checkboxSkills.setSelected(false, true);
  670. return true;
  671. };
  672. return Window;
  673. }();
  674. ItemCalculator = function() {
  675. function ItemCalculator() {
  676. this.level = 1;
  677. this._bonusExtractor = new west.item.BonusExtractor({
  678. level: this.level
  679. });
  680. this._resultStack = [];
  681. this.reset();
  682. }
  683. ItemCalculator.SUM_OP = "sum";
  684. ItemCalculator.SUB_OP = "sub";
  685. ItemCalculator.prototype.sum = function(skill, value) {
  686. return this.result[skill] += value;
  687. };
  688. ItemCalculator.prototype.sub = function(skill, value) {
  689. return this.result[skill] -= value;
  690. };
  691. ItemCalculator.prototype.sumItem = function(item) {
  692. return this.calcItem(item, ItemCalculator.SUM_OP);
  693. };
  694. ItemCalculator.prototype.subItem = function(item) {
  695. return this.calcItem(item, ItemCalculator.SUB_OP);
  696. };
  697. ItemCalculator.prototype.calcItem = function(item, operator) {
  698. if (item.bonus.attributes) {
  699. this.calcAttributes(item.bonus.attributes, operator);
  700. }
  701. if (item.bonus.skills) {
  702. this.calcSkills(item.bonus.skills, operator);
  703. }
  704. if (item.bonus.item) {
  705. this.calcBonuses(item.bonus.item, operator);
  706. }
  707. if (item.item_level > 0) {
  708. this.calcDifference(item.bonus.item, item.item_level, operator);
  709. }
  710. if (item.set) {
  711. this.calcSet(item.set, operator);
  712. }
  713. return this.result;
  714. };
  715. ItemCalculator.prototype.calcAttribute = function(attr, value, operator) {
  716. var j, len, skill, skills;
  717. skills = CharacterSkills.skillKeys4Attr[attr];
  718. for (j = 0, len = skills.length; j < len; j++) {
  719. skill = skills[j];
  720. this[operator](skill, value);
  721. }
  722. return this.result;
  723. };
  724. ItemCalculator.prototype.calcAttributes = function(attrs, operator) {
  725. var attr, value;
  726. for (attr in attrs) {
  727. value = attrs[attr];
  728. if (this.isAttribute(attr)) {
  729. this.calcAttribute(attr, value, operator);
  730. }
  731. }
  732. return this.result;
  733. };
  734. ItemCalculator.prototype.calcSkill = function(skill, value, operator) {
  735. return this[operator](skill, value);
  736. };
  737. ItemCalculator.prototype.calcSkills = function(skills, operator) {
  738. var skill, value;
  739. for (skill in skills) {
  740. value = skills[skill];
  741. if (this.isSkill(skill)) {
  742. this.calcSkill(skill, value, operator);
  743. }
  744. }
  745. return this.result;
  746. };
  747. ItemCalculator.prototype.calcDifference = function(bonuses, itemLevel, operator) {
  748. var bonus, diff, j, len;
  749. for (j = 0, len = bonuses.length; j < len; j++) {
  750. bonus = bonuses[j];
  751. diff = this._bonusExtractor.getCharacterItemValueDifferenceToItemLevel(bonus, 0, itemLevel);
  752. if (diff <= 0) {
  753. continue;
  754. }
  755. switch (bonus.bonus.type) {
  756. case "attribute":
  757. this.calcAttribute(bonus.bonus.name, diff, operator);
  758. break;
  759. case "skill":
  760. this.calcSkill(bonus.bonus.name, diff, operator);
  761. }
  762. }
  763. return this.result;
  764. };
  765. ItemCalculator.prototype.calcBonuses = function(bonuses, operator) {
  766. var bonus, j, len;
  767. this._bonusExtractor.character.level = this.level;
  768. for (j = 0, len = bonuses.length; j < len; j++) {
  769. bonus = bonuses[j];
  770. this.calcSkills(this._bonusExtractor.getAffectedSkills(bonus), operator);
  771. }
  772. return this.result;
  773. };
  774. ItemCalculator.prototype.calcSet = function(set, operator) {
  775. switch (operator) {
  776. case ItemCalculator.SUM_OP:
  777. this.itemSets[set] = (this.itemSets[set] || 0) + 1;
  778. break;
  779. case ItemCalculator.SUB_OP:
  780. if (this.itemSets[set] && (this.itemSets[set] -= 1) <= 0) {
  781. delete this.itemSets[set];
  782. }
  783. }
  784. return this.result;
  785. };
  786. ItemCalculator.prototype.isAttribute = function(attr) {
  787. return CharacterSkills.allAttrKeys.indexOf(attr) !== -1;
  788. };
  789. ItemCalculator.prototype.isSkill = function(skill) {
  790. return CharacterSkills.allSkillKeys.indexOf(skill) !== -1;
  791. };
  792. ItemCalculator.prototype.reset = function() {
  793. var j, len, ref, skill;
  794. this.itemSets = {};
  795. this.result = {};
  796. ref = CharacterSkills.allSkillKeys;
  797. for (j = 0, len = ref.length; j < len; j++) {
  798. skill = ref[j];
  799. this.result[skill] = 0;
  800. }
  801. return this.result;
  802. };
  803. ItemCalculator.prototype.resultWithBonus = function() {
  804. var b, bonus, cb, found, i, itemCount, itemSet, j, l, len, len1, len2, m, n, name1, name2, ref, ref1, ref2, ref3, result, setId, stage, value;
  805. this.pushResult();
  806. this._bonusExtractor.level = this.level;
  807. bonus = {};
  808. ref = this.itemSets;
  809. for (setId in ref) {
  810. itemCount = ref[setId];
  811. itemSet = west.storage.ItemSetManager.get(setId);
  812. for (i = j = 1, ref1 = itemCount; 1 <= ref1 ? j <= ref1 : j >= ref1; i = 1 <= ref1 ? ++j : --j) {
  813. stage = itemSet.bonus[i];
  814. if (stage) {
  815. for (l = 0, len = stage.length; l < len; l++) {
  816. b = stage[l];
  817. switch (b.type) {
  818. case "attribute":
  819. case "skill":
  820. bonus[name1 = b.type] || (bonus[name1] = {});
  821. bonus[b.type][b.name] = (bonus[b.type][b.name] || 0) + b.value;
  822. break;
  823. case "character":
  824. bonus[name2 = b.type] || (bonus[name2] = []);
  825. found = false;
  826. ref2 = bonus[b.type];
  827. for (i = m = 0, len1 = ref2.length; m < len1; i = ++m) {
  828. cb = ref2[i];
  829. found = cb.type === b.bonus.type && cb.name === b.bonus.name && cb.key === b.key && cb.roundingMethod === b.roundingMethod;
  830. if (found) {
  831. bonus[b.type][i].value += b.bonus.value;
  832. break;
  833. }
  834. }
  835. if (!found) {
  836. bonus[b.type].push({
  837. type: b.bonus.type,
  838. name: b.bonus.name,
  839. value: b.bonus.value,
  840. key: b.key,
  841. roundingMethod: b.roundingMethod
  842. });
  843. }
  844. }
  845. }
  846. }
  847. }
  848. }
  849. if (bonus.attribute) {
  850. this.calcAttributes(bonus.attribute, ItemCalculator.SUM_OP);
  851. }
  852. if (bonus.skill) {
  853. this.calcSkills(bonus.skill, ItemCalculator.SUM_OP);
  854. }
  855. if (bonus.character) {
  856. ref3 = bonus.character;
  857. for (n = 0, len2 = ref3.length; n < len2; n++) {
  858. b = ref3[n];
  859. if (b.key === "level") {
  860. value = this._bonusExtractor.getRoundedValue(b.value * this.level, b.roundingMethod);
  861. switch (b.type) {
  862. case "attribute":
  863. this.calcAttribute(b.name, value, ItemCalculator.SUM_OP);
  864. break;
  865. case "skill":
  866. this.calcSkill(b.name, value, ItemCalculator.SUM_OP);
  867. }
  868. }
  869. }
  870. }
  871. result = this.result;
  872. this.popResult();
  873. return result;
  874. };
  875. ItemCalculator.prototype.pushResult = function() {
  876. return this._resultStack.push($.extend(true, {}, this.result));
  877. };
  878. ItemCalculator.prototype.popResult = function() {
  879. return this.result = this._resultStack.pop();
  880. };
  881. return ItemCalculator;
  882. }();
  883. return SkillsCalc;
  884. }();
  885. $(document).ready(function() {
  886. var api, calc;
  887. api = TheWestApi.register(SkillsCalc.ID, SkillsCalc.NAME, SkillsCalc.MIN_GAME_VERSION, SkillsCalc.MAX_GAME_VERSION, SkillsCalc.AUTHOR, SkillsCalc.WEB_SITE);
  888. api.setGui("Copyrights, changelog and other details see <a href='" + SkillsCalc.WEB_SITE + "' target='_blank'>here</a>.");
  889. calc = null;
  890. EventHandler.listen([ "itemmanager_loaded", "itemsetmanager_loaded" ], function() {
  891. if (calc === null && ItemManager.isLoaded() && west.storage.ItemSetManager.isLoaded()) {
  892. calc = new SkillsCalc;
  893. }
  894. return EventHandler.ONE_TIME_EVENT;
  895. });
  896. return true;
  897. });
  898. return true;
  899. });