Greasy Fork 还支持 简体中文。

IQRPG Battle Stats

Tracks various battle stats over multiple battles.

目前為 2021-12-08 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         IQRPG Battle Stats
// @namespace    https://www.iqrpg.com/
// @version      0.2
// @description  Tracks various battle stats over multiple battles.
// @author       Coastis
// @match        http://iqrpg.com/game.php
// @match        https://iqrpg.com/game.php
// @match        http://www.iqrpg.com/game.php
// @match        https://www.iqrpg.com/game.php
// @match        http://test.iqrpg.com/game.php
// @match        https://test.iqrpg.com/game.php
// @require      http://code.jquery.com/jquery-latest.js
// @grant        GM_addStyle
// ==/UserScript==

//TODO add persistant storage between browser sessions
//TODO const track_abyss_battles = false; // to track abyss battles or not - Abyssal

///////////////////////////////////
/////////// config ////////////////
///////////////////////////////////

const track_boss_battles = false; // true or false
const track_clan_battles = false; // true or false

//////////////////////////////////////////////////////////////////
/////////// Don't change anything below this line ////////////////
//////////////////////////////////////////////////////////////////

/* globals jQuery, $ */

// init
var player_stats = { dmg:0, hits:0, misses:0 }; //TODO update from local storage
var enemy_stats = { dmg:0, hits:0, misses:0, dodges:0 }; //TODO update from local storage
var player_cache = '';
var enemy_cache = '';

// run every xxx ms updating stuffs
setInterval(iqrpgbs_loop, 100);

// main loop
function iqrpgbs_loop() {

    var we_battling = false;
    var display_needs_update = false;

    // check we're on the battle page
    if(document.getElementsByClassName("battle-container").length > 0) we_battling = true;

    // and not in a boss battle - Boss Tokens
    if(track_boss_battles!==true) {
        if($("div.game-grid > div.main-game-section > div.main-section__body:contains('Boss Tokens')").length > 0) {
            //console.log("skipping boss fight");
            return false;
        }
    }

    // and not in a dragon battle or clan battle - Clan Exp
    if(track_clan_battles!==true) {
        if($("div.game-grid > div.main-game-section > div.main-section__body:contains('Clan Exp')").length > 0) {
            //console.log("skipping clan fight");
            return false;
        }
    }

    // and not in a dungeon - Dungeoneering Exp
    if($("div.game-grid > div.main-game-section > div.main-section__body:contains('Dungeoneering Exp')").length > 0) {
        return false;
    }

    // all good
    if(we_battling === true) {

        // Add the battle stat panel to dom, if not already there
        if(!document.getElementById("iqrpgbs_bs_panel")) {
            var iqrpg_body = $( "div.game-grid > div.main-game-section > div.main-section__body" );
            iqrpg_body[0].children[0].children[0].insertAdjacentHTML('beforeend', render_battle_stats_panel() );
            document.getElementById('igrpg_bs_reset').addEventListener('click', iqrpg_bs_reset_stats, false);
        }

        // get the players stat line & compare it to previous stored stats
        var player_sl = $("div.game-grid > div.main-game-section > div.main-section__body > div > div > div > div:nth-child(2)");
        if(player_sl.prop('innerHTML') !== player_cache) {
            player_cache = player_sl.prop('innerHTML');
            parse_player_stat_line(player_sl);
            display_needs_update = true;
        }

        // get the mobs stat line & compare it to previous stored stats
        var mobs_sl = $("div.game-grid > div.main-game-section > div.main-section__body > div > div > div > div:nth-child(3)");
        if(mobs_sl.prop('innerHTML') !== enemy_cache) {
            enemy_cache = mobs_sl.prop('innerHTML');
            parse_enemy_stat_line(mobs_sl);
            display_needs_update = true;
        }

        // update displayed values
        if(display_needs_update === true) {
            update_display();
        }

    }
}

function parse_player_stat_line(player_sl) {
    var hits = player_sl.find("p:nth-child(1) > span:nth-child(2)");
    if(hits.length > 0) {
        var actual_hits = hits.prop('innerHTML').replaceAll(" time(s)", "");
        player_stats.hits += parseInt(actual_hits);
    }
    var dmg = player_sl.find("p:nth-child(1) > span:nth-child(3)");
    if(dmg.length > 0 && hits.length > 0) {
        var actual_dmg = dmg.prop('innerHTML').replaceAll(" damage", "").replaceAll(",", "");
        player_stats.dmg += parseInt(actual_dmg) * parseInt(actual_hits);
    }
    var misses = player_sl.find("p:nth-child(2) > span:nth-child(1)");
    if(misses.length > 0) {
        var actual_misses = misses.prop('innerHTML').replaceAll(" time(s)", "");
        player_stats.misses += parseInt(actual_misses);
    }
}

function parse_enemy_stat_line(stat_line) {
    var hits = stat_line.find("p:nth-child(1) > span:nth-child(2)");
    if(hits.length > 0) {
        var actual_hits = hits.prop('innerHTML').replaceAll(" time(s)", "");
        enemy_stats.hits += parseInt(actual_hits);
    }
    var dmg = stat_line.find("p:nth-child(1) > span:nth-child(3)");
    if(dmg.length > 0 && hits.length > 0) {
        var actual_dmg = dmg.prop('innerHTML').replaceAll(" damage", "").replaceAll(",", "");
        enemy_stats.dmg += parseInt(actual_dmg) * parseInt(actual_hits);
    }
    var misses = stat_line.find("p:nth-child(2) > span:nth-child(2)");
    if(misses.length > 0) {
        var actual_misses = misses.prop('innerHTML').replaceAll(" time(s)", "");
        enemy_stats.misses += parseInt(actual_misses);
    }
    var dodges = stat_line.find("p:nth-child(2) > span:nth-child(3)");
    if(dodges.length > 0) {
        var actual_dodges = dodges.prop('innerHTML').replaceAll(" attack(s)", "");
        enemy_stats.dodges += parseInt(actual_dodges);
    }
    //console.log("hits :: "+hits);
    //console.log("misses :: "+actual_misses);
    //console.log(actual_dodges);
}

function iqrpg_bs_reset_stats() {
    player_stats.dmg = 0;
    player_stats.hits = 0;
    player_stats.misses = 0;
    enemy_stats.dmg = 0;
    enemy_stats.hits = 0;
    enemy_stats.misses = 0;
    enemy_stats.dodges = 0;
    update_display();
}

function update_display() {
    // players
    $("#iqrpgbs_pl_dmg").html(new Intl.NumberFormat().format(player_stats.dmg));
    $("#iqrpgbs_pl_hits").html(new Intl.NumberFormat().format(player_stats.hits));
    var avg = Math.round(player_stats.dmg / player_stats.hits);
    if(isNaN(avg)) avg = 0;
    $("#iqrpgbs_pl_avg").html(new Intl.NumberFormat().format(avg));
    var acc = (player_stats.hits / (player_stats.hits + player_stats.misses))*100;
    if(isNaN(acc)) acc = 0;
    $("#iqrpgbs_pl_acc").html(new Intl.NumberFormat().format(acc.toFixed(2)));
    // enemy
    var enemy_avg = Math.round(enemy_stats.dmg / enemy_stats.hits);
    if(isNaN(enemy_avg)) enemy_avg = 0;
    $("#iqrpgbs_enmy_avg").html(new Intl.NumberFormat().format(enemy_avg));
    var enemy_acc = ( (enemy_stats.hits + enemy_stats.dodges) / (enemy_stats.hits + enemy_stats.misses + enemy_stats.dodges))*100;
    if(isNaN(enemy_acc)) enemy_acc = 0;
    $("#iqrpgbs_enmy_acc").html(new Intl.NumberFormat().format(enemy_acc.toFixed(2)));
    var enemy_dodges = (enemy_stats.dodges / (enemy_stats.hits /*+ enemy_stats.misses*/ + enemy_stats.dodges))*100;
    if(isNaN(enemy_dodges)) enemy_dodges = 0;
    $("#iqrpgbs_enmy_dodges").html(new Intl.NumberFormat().format(enemy_dodges.toFixed(2)));
}

function render_battle_stats_panel() {
    var content = `
<div id="iqrpgbs_bs_panel" class="margin-top-large">
<div>Battle Stats <span>by Coastis</span></div>
<div>You dealt a total of <span id="iqrpgbs_pl_dmg">0</span> damage in <span id="iqrpgbs_pl_hits">0</span> hits,
with an average of <span id="iqrpgbs_pl_avg">0</span> per hit and <span id="iqrpgbs_pl_acc">0</span>% accuracy</div>
<div>Enemy dealt an average of <span id="iqrpgbs_enmy_avg">0</span> per hit
with an accuracy of <span id="iqrpgbs_enmy_acc">0</span>%, and you dodged <span id="iqrpgbs_enmy_dodges">0</span>% of attacks</div>
<div>[<a href=#" id="igrpg_bs_reset">Reset Battle Stats</a>]</div>
</div>
`;
    return content;
}

GM_addStyle ( `
    div#iqrpgbs_bs_panel div { text-align:center;padding:1px;}
    div#iqrpgbs_bs_panel div:nth-child(1) { font-weight:bold;}
    div#iqrpgbs_bs_panel div:nth-child(1) span { font-size:8px;font-weight:normal;}
` );