您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Calculates success chance for r00t field actions.
// ==UserScript== // @name R00t Success Chance // @description Calculates success chance for r00t field actions. // @namespace http://userscripts.org/users/dtkarlsson // @include http*://*animecubed.com/billy/bvs/villagefields* // @include http*://*animecubedgaming.com/billy/bvs/villagefields* // @licence MIT; http://www.opensource.org/licenses/mit-license.php // @copyright 2009, Daniel Karlsson // @version 0.12.0 // @history 0.12.0 New domain - animecubedgaming.com - Channel28 // @history 0.11.0 Now https compatible (Updated by Channel28) // @history 0.10.0 Added rough estimate of max difficulty // @history 0.9.1 Text was supposed to be white, now it is // @grant none // ==/UserScript== var jutsuTypes = { gen: "Genjutsu", nin: "Ninjutsu", tai: "Taijutsu", dou: "Doujutsu" } var basicJutsuTypes = { gen: "Genjutsu", nin: "Ninjutsu", tai: "Taijutsu" } function Ability() { this.lvl = 0; this.str = 0; this.rng = 0; this.suc = 0; } function Ninja() { this.gen = new Ability(); this.nin = new Ability(); this.tai = new Ability(); this.dou = new Ability(); } function Challenge() { this.dif = 0; this.suc = 0; } function Mission() { this.gen = new Challenge(); this.nin = new Challenge(); this.tai = new Challenge(); this.dou = new Challenge(); this.order = []; this.crank = 0; } // Math stuff below function binomialCoefficient(n, k) { // n!/[k!(n-k)!] if (k > n || k < 0) return 0; k = Math.max(k, n - k); var i = 1; var j = k + 1; var c = 1; // i = 1 ... n-k => (n-k)! // j = k+1 ... n => n!/k! while (j <= n) c *= j++ / i++; return c; } function binomdist(k, n, p, cumulative) { // Cumulative distribution, k or less successes in n trials if (cumulative) { var sum = 0; for (var i = 0; i <= k; i++) sum += binomdist(i, n, p, false); return sum; } // Exactly k successes in n trials with probability p return binomialCoefficient(n, k) * Math.pow(p, k) * Math.pow(1 - p, n - k); } function successChance(challenge, ability, crank) { if (!crank) crank = 0; // Successful rolls required var req = (challenge.suc + crank)- ability.suc; if (req > ability.lvl) return 0; else if (req <= 0) return 1; if ((challenge.dif + crank) > ability.rng) return 0; // Success probability per roll var prob = (ability.str + ability.rng - (challenge.dif + crank) + 1) / ability.rng; if (prob >= 1) return 1; return Math.min(0.9999, 1 - binomdist(req - 1, ability.lvl, prob, true)); } function expectedSuccesses(challenge, ability, crank) { if (!crank) crank = 0; if ((challenge.dif + crank) > ability.rng) return 0; // Success probability per roll var prob = (ability.str + ability.rng - (challenge.dif + crank) + 1) / ability.rng; return ability.suc + Math.min(1, prob) * ability.lvl; } function percent(n) { if (n == 1.0) return "100%"; else if (n == 0.0) return "0%"; var p = Math.round(n * 1000) / 10; if (p > 99.9) return ">99.9%"; else if (p < 0.1) return "<0.1%"; return p + "%"; } // Parsing function parseAbilities() { var ninja = new Ninja(); var tables = document.evaluate("//table[count(descendant::table)=4]//table", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); for (var i = 0; i < tables.snapshotLength; i++) { var ab = new Ability(); var type = ""; var lines = tables.snapshotItem(i).textContent.split(/\n/); for (var l in lines) { var m; m = lines[l].match(/Suc: (\d+)( \(\+(\d+)\))?/); if (m) { ab.suc += parseInt(m[1]); if (m[3]) ab.suc += parseInt(m[3]); continue; } m = lines[l].match(/Str: (\d+)( \(\+(\d+)\))?/); if (m) { ab.str += parseInt(m[1]); if (m[3]) ab.str += parseInt(m[3]); continue; } m = lines[l].match(/Rng: (\d+)( \(\+(\d+)\))?/); if (m) { ab.rng += parseInt(m[1]); if (m[3]) ab.rng += parseInt(m[3]); continue; } m = lines[l].match(/Lvl: (\d+)( \(\+(\d+)\))?/); if (m) { ab.lvl += parseInt(m[1]); if (m[3]) ab.lvl += parseInt(m[3]); continue; } m = lines[l].match(/(\w{3}): (\d+)/); if (m) { type = m[1].toLowerCase(); ab.lvl += parseInt(m[2]); continue; } } ninja[type] = ab; } return ninja; } function parseMission() { var tables = document.evaluate("//table[count(descendant::table)=0]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); var node = null; var mission = new Mission(); for (var i = 0; i < tables.snapshotLength; i++) { var txt = tables.snapshotItem(i).textContent; if (/virus attack/i.test(txt)) { var lines = txt.split(/\n/); // Gen D: 15 S: 15 for (var l in lines) { var line = lines[l].replace(/\s+/g, " "); var m = line.match(/(\w{3}) D: (\d+) S: (\d+)/); if (m) { var type = m[1].toLowerCase(); mission[type].dif = parseInt(m[2]); mission[type].suc = parseInt(m[3]); node = tables.snapshotItem(i); } } break; } } if (node) return {mission: mission, node: node}; } var ninja = parseAbilities(); var missionNode = parseMission(); if (missionNode) { var mission = missionNode.mission; var node = missionNode.node; var p = 1; for (var t in jutsuTypes) { p *= successChance(mission[t], ninja[t]); } var tr = document.createElement("tr"); var td = document.createElement("td"); td.textContent = "Success chance: " + percent(p); td.style.color = "white"; tr.appendChild(td); node.firstChild.appendChild(tr); } // Rough estimate of average field difficulty function fieldChallenge(diff) { diff = Math.min(230, diff); diff = Math.max(0, diff); var c = new Challenge(); c.dif = Math.round(0.13 * diff + 15); c.suc = Math.round(0.11 * diff + 15); return c; } // Calculate max difficulty a ninja can reliably handle var diff, p; for (diff = 230; diff >= 0; diff -= 5) { p = 1; for (var t in basicJutsuTypes) p = Math.min(p, successChance(fieldChallenge(diff), ninja[t])); if (p > 0.95) break; } var form = document.getElementsByName("field")[0]; var div = document.createElement("div"); div.textContent = "Recommended difficulty (estimate): " + diff + " (" + percent(p) + ")"; form.parentNode.insertBefore(div, form);
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址