NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name WFTargettingScore // @namespace sk.seko // @description Computes targetting score for ship design. // @include http://*.war-facts.com/ship_designs.php* // @grant none // @version 2.4 // ==/UserScript== // Version 1.0 = grab params from displayed design, calculate targeting score and display it // Version 2.0 = added support for "dynamic" display, i.e. during design creation // Version 2.1 = fixed sliders and input fields for armor/shields // Version 2.2 = fixed keyboard input // Version 2.3 = fixed float vs. int speed issue, and fixed score display during ship design // Version 2.4 = fixed formula for H5 (it has been changed, apparently!) // Version 2.5 = fixed html/css changes in H6 // ---------------------------------------------------------------------------------------- // Note for v2.4: // TS value calculated (and displayed) on View ship class screen is not accurate, i.e. real // TS is probably lower. This is because formula is using 'Hull mass', not 'Total mass' and // there is no way to find you what hull mass exactly is. This is only possible on Ship // design screen, for wich TS displayed should be correct. Sorry for inconveniece! // - Seko // ---------------------------------------------------------------------------------------- function eval(s) { if (s) {return Math.round(parseFloat(s.replace(/[,\s]/g,'')));} return 0; } function evalNode(node) { if (node) {return eval(node.nodeValue);} return 0.0; } // returns number formatted with commas, like 1234567 => "1,234,567" function addCommas(nStr) { var x = nStr.split('.'); var x1 = x[0]; var x2 = x.length > 1 ? '.' + x[1] : ''; var rgx = /(\d+)(\d{3})/; while (rgx.test(x1)) { x1 = x1.replace(rgx, '$1' + ',' + '$2'); } return x1 + x2; } // calculate targeting score and return it as formatted string function calculateAndFormatTS(firepower, base_armor, base_shield, hull_mass, speed) { // ===================================================================================== // THIS is formula for targetting score (TS); it can change in the future instances :-( // ===================================================================================== var ts = firepower * ((base_armor + base_shield + hull_mass - speed) / 2); //alert('fire=' + firepower + ', armor=' + base_armor + ', shield=' + base_shield + ', mass=' + hull_mass + ', speed=' + speed + ', ts=' + ts); return addCommas(String(ts)); } // grab params and compute targeting score for existing design window.grabAndCalculateStatic = function() { // GET SHIP DESIGN ATTRIBUTES var speed = evalNode(document.evaluate("//td[(child::text() = 'Cruise Speed:')]/following-sibling::node()/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var fireIter = document.evaluate("//td[(child::text() = 'Full Strike:')]/following-sibling::node()/child::text()", document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); var fire = 0.0; var fireVal = fireIter.iterateNext(); while (fireVal) { if (fireVal.nodeValue && fireVal.nodeValue.replace(/\s/,'') != '') { fire += evalNode(fireVal); } fireVal = fireIter.iterateNext(); } var shield = evalNode(document.evaluate("//td[(child::text() = 'Shield:')]/following-sibling::node()/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var armor = evalNode(document.evaluate("//td[(child::text() = 'Armor:')]/following-sibling::node()/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var mass = evalNode(document.evaluate("//td[(child::text() = 'Mass:')]/following-sibling::node()/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); // CALCULATE TARGETING SCORE return calculateAndFormatTS(fire, armor, shield, mass, speed); } // compute targeting score for ship being designed window.grabAndCalculateDynamic = function() { // GET SHIP DESIGN ATTRIBUTES var speed = evalNode(document.evaluate("//td/span[@id='drivespeed']/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var firegun = evalNode(document.evaluate("//td/span[@id='vgunAstrike']/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var firecannon = evalNode(document.evaluate("//td/span[@id='vcannonAstrike']/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var shield = evalNode(document.evaluate("//td/span[@id='vshieldarmor']/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var armor = evalNode(document.evaluate("//td/span[@id='varmorshield']/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var mass = evalNode(document.evaluate("//td[(child::text() = 'Hull Mass:')]/following-sibling::node()/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); // CALCULATE TARGETING SCORE var fire = (firecannon ? firecannon : 0.0) + (firegun ? firegun : 0.0); return calculateAndFormatTS(fire, armor, shield, mass, speed); } // displays targeting score as a table row window.displayTS = function(tablerow, ts) { var ncol1 = document.createElement('td'); ncol1.setAttribute("class","strong"); ncol1.appendChild(document.createTextNode('Targeting Score:')); var ncol2 = document.createElement('td'); ncol2.setAttribute("colspan", "3"); var scoreElem = document.createTextNode(ts); ncol2.appendChild(scoreElem); var nrow = document.createElement('tr'); nrow.appendChild(ncol1); nrow.appendChild(ncol2); tablerow.parentNode.insertBefore(nrow, tablerow); return scoreElem; } // compute and display targeting score for ship being designed window.processDynamic = function() { var ts = grabAndCalculateDynamic(); if (window.scoreElem) { window.scoreElem.nodeValue = ts; } else { var tablerow = document.evaluate("//center/table/tbody/tr/td/form/table[1]/tbody/tr/td[1]/table/tbody/tr[last()]", document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null).iterateNext(); if (tablerow) { window.scoreElem = displayTS(tablerow, ts); } } return false; } // compute and display targeting score for existing design window.processStatic = function() { // check if this is design is displayed //var tablerow = document.evaluate("//center/table/tbody/tr[2]", var check = document.evaluate("//input[@value='Delete Design']", document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null).iterateNext(); if (!check) { return; // design is not displayed, just quit } var tablerow = document.evaluate("//center/table/tbody/tr[2]", document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null).iterateNext(); if (!tablerow) { return; // something wrong, just quit } // calculate targeting score var ts = grabAndCalculateStatic(); // DISPLAY TARGETING SCORE displayTS(tablerow, 'less than ' + ts); } // adds 'processDynamic' callback to all elements matching elements event window.registerDynamicElements = function(xpath, attr) { var it = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); if (it) { var b = it.iterateNext(); var elems = []; while (b) { elems.push(b); b = it.iterateNext(); } for (x in elems) { elems[x].setAttribute(attr,elems[x].getAttribute(attr) + ";setTimeout(\"processDynamic()\", 100);"); } } } // compute and display targeting score for existing design window.initializeScript = function() { // dynamic/callbacks only when designing a ship if (!document.evaluate("//select[@name='designid']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue) { registerDynamicElements("//select[@id='driveselect']", 'onchange'); registerDynamicElements("//select[@id='gunselect']", 'onchange'); registerDynamicElements("//select[@id='cannonselect']", 'onchange'); registerDynamicElements("//select[@id='armorselect']", 'onchange'); registerDynamicElements("//select[@id='shieldselect']", 'onchange'); registerDynamicElements("/html/body", 'onmouseup'); } processStatic(); } window.addEventListener("load", initializeScript, false);