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.6 // ==/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 // Version Screwup = Quick hack to work with new design - prosoft // ---------------------------------------------------------------------------------------- // 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(/[,]/g,'')));} return 0; } function evalNode(node) { if (node) {return eval(node.data.split(" ")[0]);} 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)); } /* I don't care about incorrect targetting scores, it just makes people compare the wrong shit. // 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("//span[@id='drivespeed']/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var firegun = evalNode(document.evaluate("//span[@id='vgunAstrike']/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var firecannon = evalNode(document.evaluate("//span[@id='vcannonAstrike']/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var shield = evalNode(document.evaluate("//span[@id='veffshield']/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var armor = evalNode(document.evaluate("//span[@id='veffarmor']/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue); var mass = eval(document.evaluate("//div[text()[contains(.,'Hull Mass')]]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.innerHTML.split(" ")[2]); // CALCULATE TARGETING SCORE var fire = (firecannon ? firecannon : 0.0) + (firegun ? firegun : 0.0); document.getElementById("massused").innerHTML = mass; document.getElementById("speedused").innerHTML = speed; document.getElementById("fireused").innerHTML = fire; document.getElementById("armorused").innerHTML = armor; document.getElementById("shieldused").innerHTML = shield; return calculateAndFormatTS(fire, armor, shield, mass, speed); } // compute and display targeting score for ship being designed window.processDynamic = function() { var ts = grabAndCalculateDynamic(); document.getElementById("targetingscore").innerHTML = ts } function insertAfter(newNode, referenceNode) { referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } /* // 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 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() { var massdiv = document.createElement("div"); massdiv.className = "padding5 light tbborder"; massdiv.innerHTML = 'Mass Used: <span id="massused"></span>'; var speeddiv = document.createElement("div"); speeddiv.className = "padding5 light tbborder"; speeddiv.innerHTML = 'Speed Used: <span id="speedused"></span>'; var firediv = document.createElement("div"); firediv.className = "padding5 light tbborder"; firediv.innerHTML = 'Fire Used: <span id="fireused"></span>'; var shielddiv = document.createElement("div"); shielddiv.className = "padding5 light tbborder"; shielddiv.innerHTML = 'Shield Used: <span id="shieldused"></span>'; var armordiv = document.createElement("div"); armordiv.className = "padding5 light tbborder"; armordiv.innerHTML = 'Armor Used: <span id="armorused"></span>'; insertAfter(shielddiv, document.getElementById("targetingscore").parentNode); insertAfter(armordiv, document.getElementById("targetingscore").parentNode); insertAfter(firediv, document.getElementById("targetingscore").parentNode); insertAfter(speeddiv, document.getElementById("targetingscore").parentNode); insertAfter(massdiv, document.getElementById("targetingscore").parentNode); } document.onclick = function(){ if(evalNode(document.evaluate("//span[@id='drivespeed']/child::text()", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue) != 0) { processDynamic(); } } //document.getElementById("targetingscore").insertAdjacentHTML( 'beforeBegin', '<input type="button" value="Update Score" onclick="processDynamic();">' ); if( document.location.href.indexOf('designid') == -1 ) { initializeScript(); } //window.addEventListener("load", initializeScript, false);