hwmTroopsDeploymentHelper

Помощник в расстановке войск

目前为 2024-02-03 提交的版本。查看 最新版本

// ==UserScript==
// @name           hwmTroopsDeploymentHelper
// @namespace      Tamozhnya1
// @author         Tamozhnya1
// @description    Помощник в расстановке войск
// @version        1.3
// @include        *heroeswm.ru/war.php*
// @include        *lordswm.com/war.php*
// @grant          GM_deleteValue
// @grant          GM_getValue
// @grant          GM_setValue
// @grant 		   GM.xmlHttpRequest
// @grant 		   GM.notification
// @license        MIT
// ==/UserScript==

const playerIdMatch = document.cookie.match(/pl_id=(\d+)/);
if(!playerIdMatch) {
    return;
}
const PlayerId = playerIdMatch[1];
const battleTypes = { _NABEG: 2, _GN_OTRYAD: 5, _GN_MONSTER: 7, _GN_NABEGI: 8, _GN_ZASHITA: 10, _GN_ARMY: 12, _MAL_TOUR: 14, _THIEF_WAR: 16, _SURVIVAL: 20, _NEWGROUP: 21, _ELEMENTALS: 22, _GNOMES: 23, _NEWKZS: 24, NEWKZS: 24, _NEWKZS_T: 25, NEWKZS_T: 25, _NEWTHIEF: 26, _NEWCARAVAN: 27, _NEWGNCARAVAN: 29, _SURVIVALGN: 28, _TUNNEL: 30, _SEA: 32, _HELL: 33, _CASTLEWALLS: 35, _UNIWAR: 36, _DIFFTUR: 37, _UNIWARCARAVAN: 38, _PVPGUILDTEST: 39, _PVPGUILD: 40, _BALANCED_EVENT: 41, _NECR_EVENT: 42, _NECR_EVENT2: 43, _HELLOWEEN: 44, _SURVIVAL_GNOM: 45, _DEMON_EVENT: 46, _DEMON_EVENT2: 47, _DEMON_EVENT3: 48, _DEMON_EVENT4: 49, _PVEDUEL: 50, _DEMONVALENTIN: 51, _QUICKTOUR: 52, _BARBTE_ATTACK: 53, _BARBTE_DEEP: 54, _BARBTE_BOSS: 55, _TRANSEVENT: 56, _STEPEVENT: 57, _STEPEVENT2: 58, _KZS_PVE: 59, _2TUR: 60, _RANGER: 61, _PRAET: 62, _RANGER_TEST: 63, _SUN_EVENT1: 64, _SUN_EVENT2: 65, _NEWCARAVAN2: 66, _23ATTACK: 67, _2TU_FAST: 68, _SV_ATTACK: 69, _KILLER_BOT: 70, _SV_DUEL: 71, _SV_WAR: 72, _FAST_TEST: 73, _TRUE_EVENT: 74, _TIKVA_BOT: 75, _TIKVA_ATTACK: 76, _ELKA_DEFENSE: 77, _PPE_EVENT: 78, _ALTNECR_EVENT: 79, 
_CLAN_SUR_DEF: 80, _CLAN_SUR_ATT: 81, _QUESTWAR: 82, _BARBNEW_DEEP: 83, _BARBNEW_BOSS: 84, _ELKA_RESCUE: 85, _REGWAR1: 86, _REGWAR2: 87, _CLAN_SUR_CAPT: 88, _CLAN_SUR_DEF_PVP: 89, _TRUE_TOUR: 90, _NOOB_DUEL: 91, _ALTMAG_EVENT: 92, _ALTELF_EVENT: 93, _NEWPORTAL_EVENT: 94, _UNIGUILD: 95, _PIRATE_EVENT: 96, _TOUR_EVENT: 97, _PAST_EVENT: 98, _GOLD_EVENT: 99, 
_FAST_TEST2: 100, _OHOTA_EVENT: 101, _BUNT_EVENT: 102, _ZASADA_EVENT: 103, _CLAN_NEW_PVP: 104, _SURV_DEEP: 105, _SURV_DEEP_BOSS: 106, _2AND3_EVENT: 107, _CASTLE_EVENT: 108, _CARAVAN_EVENT: 109, _CAMPAIGN_WAR: 110, _NY2016: 111, _ALTTE_EVENT: 112, _PVP_EVENT: 113, _ALTTE2_EVENT: 114, _PIRATE_NEW_EVENT: 115, _PVP_KR_EVENT: 116, _CATCH_EVENT: 117, _PVP_DIAGONAL_EVENT: 118, _VILLAGE_EVENT: 119, _TRAVEL_EVENT: 120, _CASTLE_BATTLE2X2: 121, _PVP_BOT: 122, _PIRATE_SELF_EVENT: 123, _2ZASADA_EVENT: 124, _NEWCARAVAN3: 125, _ONEDAY_EVENT: 126, _CRE_EVENT: 127, _GL_EVENT: 128, _1ZASADA_EVENT: 129, _NYGL2018_EVENT: 130, _EGYPT_EVENT: 131, _GL_DWARF_EVENT: 132, _NAIM_MAP_EVENT: 133, _2BOT_TUR: 134, _CRE_SPEC: 135, _CRE_INSERT: 136, _CRE_TOUR: 137, _GNOM_EVENT: 138, _MAPHERO_EVENT: 138, _NEWCRE_EVENT: 139, _NEWOHOTA_EVENT: 140, _2SURVIVAL: 141, _ADVENTURE_EVENT: 142, _AMBUSHHERO_EVENT: 143, _FRACTION_EVENT: 144, _PVP_KZS: 145, _REAPING_MAP_EVENT: 147 };


const lang = document.documentElement.lang || (location.hostname == "www.lordswm.com" ? "en" : "ru");
const isEn = lang == "en";
const windowObject = window.wrappedJSObject || unsafeWindow;
// Типы боёв с постоянным числом партнеров
const staticAmounts = {
    [battleTypes._CLAN_SUR_DEF]: 2,
    [battleTypes._2BOT_TUR]: 2
};

var loadId;
var startId;

main();
function main() {
    loadId = setInterval(waitForBattleLoad, 200);
}
function waitForBattleLoad() {
    if(windowObject.stage[windowObject.war_scr].setted_atb) {
        clearInterval(loadId);
        console.log(`btype: ${windowObject.btype}`);
        const playersPositions = getPlayersPositions();
        if(windowObject.warlog == 0) {
            createMirrorDeploymentButton();
            startId = setInterval(waitForBattleStart, 200);
            document.getElementById("confirm_ins_img").addEventListener("click", removeMirrorDeploymentButton, true);
        }
    }
}
function waitForBattleStart() {
    if (windowObject.lastturn > -1) {
        clearInterval(startId);
        removeMirrorDeploymentButton();
    }
}
function removeMirrorDeploymentButton() {
    const mirrorDeploymentButton = document.getElementById("mirrorDeploymentButton");
    if(mirrorDeploymentButton) {
        mirrorDeploymentButton.remove();
    }
}
// TODO Подобрать картинку
function createMirrorDeploymentButton() {
    document.getElementById('right_button').insertAdjacentHTML("beforeend", `
<div id="mirrorDeploymentButton" class="toolbars_img">
    <img src="https://dcdn.heroeswm.ru/i/combat/btn_autoalignment.png?v=6" alt="${isEn ? "Deployment mirror vertical" : "Отразить расстановку по вертикали"}" title="${isEn ? "Deployment mirror vertical" : "Отразить расстановку по вертикали"}" style="filter: sepia(100%) hue-rotate(190deg) saturate(900%);">
</div>`);
    document.getElementById("mirrorDeploymentButton").addEventListener("click", mirrorDeployment);
}
function mirrorDeployment() {
    const pole = windowObject.stage[windowObject.war_scr]; //stage[war_scr].obj
    const poleObj = windowObject.stage[windowObject.war_scr].obj; //console.log(poleObj);
    const playerStekIds = Array.from(windowObject.stekid).filter((x, i) => i >= 1 && i <= windowObject.stackcount);
    const playerUnits = Object.keys(poleObj).filter(k => !poleObj[k].hero && playerStekIds.includes(poleObj[k].id)).map(k => poleObj[k]);
    const minY = playerUnits.reduce((t, x) => Math.min(t, x.y), playerUnits[0].y); //    console.log(playerUnits.map(x => x.y))
    
    const friendsCount = getVerticalSegmentsAmount();
    const onePlayerFieldWidth = windowObject.defyn / friendsCount; // Ширина пространства для расстановки игрока
    let deploymentFieldWidthBegin;
    let deploymentFieldWidthEnd;
    for(let i = 0; i < friendsCount; i++) {
        const leftEdge = 1 + i * onePlayerFieldWidth;
        const rightEdge = (i + 1) * onePlayerFieldWidth;
        if(leftEdge <= minY && minY <= rightEdge) {
            deploymentFieldWidthBegin = leftEdge;
            deploymentFieldWidthEnd = rightEdge;
        }
    }
    console.log(`minY: ${minY}, defxn: ${windowObject.defxn}, defyn: ${windowObject.defyn}, deploymentFieldWidthBegin: ${deploymentFieldWidthBegin}, deploymentFieldWidthEnd: ${deploymentFieldWidthEnd}`);
    const deployment = playerUnits.map(x => [x.id, x.nownumber, x.x, deploymentFieldWidthBegin + deploymentFieldWidthEnd - x.y - x.big]);
    const insStr = deployment.map(x => x.join("#")).join("^") + "^"; console.log(insStr);
    pole.useinsertion_cre(insStr); // Расстановка по данным из текстовой строки
}
function getVerticalSegmentsAmount() {
    const playersPositions = getPlayersPositions();
    const playerPosition = playersPositions.find(x => x.playerId == PlayerId).playerPosition;
    
    const staticAmountByBattleType = staticAmounts[windowObject.btype];
    if(staticAmountByBattleType) {
        return staticAmountByBattleType;
    }
    return 1; // Должно возвращать количество отрядов со стороны игрока по вертикали. Предполагается, что каждому отряду выделяется одинаковая ширина.
}
function getPlayersPositions() {
    //const playersPositions = Object.keys(windowObject).filter(k => k.startsWith("plid")).map(k => ({ playerId: windowObject[k], playerPosition: parseInt(k.slice(4)) }));
    const playersPositions = [];
    let plidExec;
    const plidRe = /plid(\d+)\|(\d+)/g;
    while(plidExec = plidRe.exec(document.documentElement.innerHTML)) {
        playersPositions.push({ playerId: plidExec[2], playerPosition: parseInt(plidExec[1]) });
    }
    console.log(playersPositions);
    return playersPositions;
}
//defxn: 14, defyn: 20, deploymentFieldWidthBegin: 1, deploymentFieldWidthEnd: 10 //162#77#1#8^167#11#1#6^169#4#1#4^163#68#2#10^165#22#1#10^
// warlog|0|crclink||show_enemy||nb|0|gtype|18|pl_level|21|abilversion|72796|soundstereo|1|soundeff|0|soundvol|100|iscastle|0|stackcount|7|opera|0|imgpath||lshift|3|quality|1|firstbattle|0|hint_arrow|0|soundon|0|
//btype|80|btypeo|80|fastbut|0|fastbut2|0|animspeed|15|
// player|1939235|ruler|0|warid|1424105634|rwi|0|chksum|341|clanid|8433|playero|3|playero2|3|timer|45|
// defxn|14|defyn|20|fb_tutorial|0|width|0|lng|0|lt|-2|no_trees|0|isshadow|1|israstr|0|isblood|1|
// plid1|2945143|plid3|1939235|umka|16BBBEBABBBB002600000C00000038988DEA8D980047000000C00000 |
// insertions|
// 7#4#1#12^3#77#1#15^6#11#1#18^4#32#2#14^5#22#1#17^4#36#2#17^:
// 3#84#1#15^7#4#1#12^6#11#1#18^4#36#2#14^5#23#1#11^4#36#2#17^:
// 3#81#1#12^6#11#1#14^7#4#1#18^4#34#2#11^5#10#1#20^4#33#2#20^5#10#1#11^:
// 4#79#2#12^7#4#1#15^3#84#1#17^6#11#1#13^5#10#1#19^4#1#2#19^5#10#1#11^:
// 7#4#1#13^4#79#2#15^5#20#1#15^6#11#1#16^3#84#1#18^4#1#2#12^:
// 3#81#1#12^6#11#1#15^7#4#1#18^4#31#2#11^5#22#1#20^4#30#2#20^4#1#2#14^:
// 7#4#1#14^6#11#1#16^3#77#1#18^4#78#2#11^5#17#1#13^4#2#2#13^:
// 3#70#1#14^6#11#1#12^4#73#2#18^7#4#1#16^5#22#1#11^:
// 4#40#2#17^6#11#1#15^7#4#1#18^3#84#1#12^5#10#1#20^4#40#2#14^5#10#1#11^:
// 4#79#2#12^7#4#1#15^3#77#1#13^6#11#1#17^5#6#1#19^4#1#2#19^5#11#1#11^:|", "pole", 0, 0, 0, "https://dcdn.heroeswm.ru/i/", 1000, 1000, 1);};