Roll

Faire des jets avec prise en compte des stats via des compétences

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name        Roll
// @namespace   InGame
// @author      Odul, MockingJay
// @match       https://www.dreadcast.net/Main
// @version     1.2
// @grant       none
// @description Faire des jets avec prise en compte des stats via des compétences
// ==/UserScript==

// Alias de commandes, utiliser le format suivant:
// alias: "commande",
const aliases = {
    for: "force",
    agi: "agilite",
    res: "resistance",
    per: "perception",
    fur: "furtivite",
    fufu: "furtivite",
    info: "informatique",
    inf: "informatique",
    med: "medecine",
    inge: "ingenierie",
    ing: "ingenierie",
}

// Pour ajouter des formules personnalisées:
// - Le nom doit être en minuscules, sans accents si espaces, underscores autorisés
// - Les coefficients sont dans l'ordre: force, agilité, résistance, perception, furtivité, informatique, médecine, ingénierie
const formulas = {
    force: [1, 0, 0, 0, 0, 0, 0, 0],
    agilite: [0, 1, 0, 0, 0, 0, 0, 0],
    resistance: [0, 0, 1, 0, 0, 0, 0, 0],
    perception: [0, 0, 0, 1, 0, 0, 0, 0],
    furtivite: [0, 0, 0, 0, 1, 0, 0, 0],
    informatique: [0, 0, 0, 0, 0, 1, 0, 0],
    medecine: [0, 0, 0, 0, 0, 0, 1, 0],
    ingenierie: [0, 0, 0, 0, 0, 0, 0, 1],
    dpasse: [1, 2, 0, 1, 0, 0, 0, 0],
    drecep: [1, 1, 0, 2, 0, 0, 0, 0],
    dplaque: [3, 1, 0, 0, 0, 0, 0, 0],
    dfeinte: [1, 1, 0, 1, 0, 0, 0, 0],
    dinter: [0, 1, 0, 1, 0, 0, 0, 0],
    dtir: [1, 1, 0, 0, 0, 0, 0, 0],
    darret: [1, 0, 0, 3, 0, 0, 0, 0],
    hack: [0, 1, 0, 0, 0, 16, 0, 3],
    programmation: [0, 0, 0, 0, 0, 9, 0, 1],
    diag_meca: [0, 0, 0, 2, 0, 1, 0, 2],
    cablage: [0, 0, 0, 0, 0, 3, 0, 7],
    assemblage: [0, 0, 0, 1, 0, 0, 0, 4],
    desassemblage: [1, 0, 0, 0, 0, 0, 0, 4],
    reparation: [1, 0, 0, 0, 0, 0, 0, 4],
    soudure: [1, 0, 0, 3, 0, 0, 0, 6],
    crochetage: [0, 1, 0, 0, 0, 0, 0, 3],
    desamorcer: [0, 1, 0, 3, 0, 0, 0, 16],
    diag_medical: [0, 0, 0, 1, 0, 0, 4, 0],
    chirurgie: [0, 1, 0, 1, 0, 0, 3, 0],
    massage_cardiaque: [3, 0, 0, 0, 0, 0, 7, 0],
    perfusion: [0, 1, 0, 2, 0, 0, 2, 0],
    desinfecter: [0, 3, 0, 0, 0, 0, 2, 0],
    garot: [1, 0, 0, 0, 0, 0, 1, 0],
    tir: [0, 1, 0, 4, 0, 0, 0, 0],
    parade: [0, 4, 0, 1, 0, 0, 0, 0],
    esquive: [1, 9, 0, 0, 0, 0, 0, 0],
    liberation: [4, 5, 0, 0, 0, 0, 0, 1],
    immobilisation: [1, 0, 1, 0, 0, 0, 0, 0],
    equilibre: [0, 4, 1, 0, 0, 0, 0, 0],
    volonte: [4, 2, 9, 1, 1, 1, 1, 1],
    blessure: [0, 1, 9, 0, 0, 0, 0, 0],
    enfoncer: [7, 0, 3, 0, 0, 0, 0, 0],
    mensonge: [0, 3, 0, 0, 5, 0, 2, 0],
    dmensonge: [0, 3, 0, 5, 0, 0, 2, 0],
    maquillage: [0, 8, 0, 2, 0, 0, 0, 0],
    musique: [0, 3, 0, 2, 0, 0, 0, 0],
    accorder: [0, 0, 0, 2, 0, 0, 0, 3],
    fee_lation: [0, 6, 0, 1, 0, 0, 4, 0],
    orgasme: [0, 1, 1, 0, 0, 0, 0, 0],
    skype: [0, 0, 0, 0, 0, 0, 2, 0],
    fee_niasse: [0, 1, 1, 0, 0, 0, 0, 0],
    overflow: [1, 1, 1, 1, 1, 1, 1, 1],
}

// CORE FNS //

const getStats = function() {
    let stats = [];

    for (let i = 1; i <= 8; i++) {
        stats.push(parseInt($('#statistiques .infos .stat_' + i + '_entier').text()));
    }

    return stats;
}

const computeValue = function(skillName){
    if (!formulas[skillName]) {
        return null;
    }

    const stats = getStats();
    const totalWeight = formulas[skillName].reduce(((total, weight) => total + weight), 0);
    const skillPoints = stats.reduce(((total, stat, i) => total + stat * formulas[skillName][i]), 0);

    return 100 - Math.floor((skillPoints / totalWeight) / 6);
}

const retrieveValue = function(facesde, comp, diff)
{
    const ligne = $("#chatContent > .msg.hrp > em").last().text();

    if (!ligne) {
        return;
    }

    if (ligne.includes($("txt_pseudo").text() + " lance 1 dé de " + facesde + " et fait")) {
        let result = parseInt(ligne.substring(ligne.indexOf("et fait") + 7).trim()) + (100 - facesde);
        let threshold = 0;

        switch(diff) {
            case "f":
            case "facile":
                threshold = 25;
                diff = "facile";
                break;
            case "m":
            case "moyen":
                threshold = 50;
                diff = "moyen";
                break;
            case "d":
            case "difficile":
                threshold = 75;
                diff = "difficile";
                break;
            default:
                threshold = parseInt(diff) || 0;
        }

        let textResult = "";

        if (!threshold) {
            textResult += "/me [couleur=jaune]fait "+ result +" à son jet de " + comp + "[/couleur]";
        }
        else if (["facile", "moyen", "difficile"].includes(diff)) {
            textResult += result >= threshold ?
                "/me [couleur=vert]réussit[/couleur] " :
            "/me [couleur=rouge]rate[/couleur] ";
            textResult += "[couleur=jaune]un jet " + diff + " de " + comp + " et fait " + result + "[/couleur]";
        }
        else {
            textResult += result >= threshold ?
                "/me [couleur=vert]réussit[/couleur] " :
            "/me [couleur=rouge]rate[/couleur] ";
            textResult += "[couleur=jaune]un jet de " + comp + " en faisant " + result + " contre un seuil de " + threshold + "[/couleur]";
        }

        $("#chatForm .text_chat").val(textResult);
        nav.getChat().send();
    }

}

const jetDes = function(e) {
    let value = $("#chatForm .text_chat").val();

    if (!value.match(/^\/roll [a-zA-Z]+/)) {
        return; // Ne traiter que l'envoi de /roll avec commande (ignore également les XdY)
    }

    value = value.replace(/[àâ]/g, "a").replace(/[éèê]/g, "e").replace(/[î]/g, "i").replace(/[ô]/g, "o").replace(/[ûù]/g, "u");
    // Essayer d'ignorer les accents

    let comp = value.trim().split(" ")[1].toLowerCase();
    const diff = value.trim().split(" ")[2];

    comp = aliases[comp] || comp;
    const facesde = computeValue(comp);

    if (facesde) {
        value = '/roll 1d' + facesde;
        setTimeout(function() {
            retrieveValue(facesde, comp, diff)
        }, 500);
    }
    else {
        e.preventDefault(); // Empêche l'envoi d'un roll mal écrit
    }

    $("#chatForm .text_chat").val(value);
}

// GUI //

$("body").append(`<style>
#rollPanel {
	position: absolute;
	right: -220px;
	bottom: 20px;
	z-index: 999999;
	display: flex;
}

#rollPanel button, #rollPanel input, #rollPanel select {
	background-color: #8ab6e4;
}

#rollToggle {
	background-color: #6ea0d3;
	height: fit-content;
}

#rollToggle button {
	height: 50px;
	width: 50px;
}

#rollOptions {
	background-color: #6ea0d3;
	padding: 10px;
	width: 200px;
}

#rollOptions label, #rollHasThreshold {
	vertical-align: middle;
}

#rollType, #rollThreshold, .rollPresetDiff {
	height: 30px;
}

.rollPresetDiff {
	flex: 1;
}

#rollType {
	max-width: 160px;
}

#rollThreshold {
	-moz-appearance: textfield;
	text-align: center;
}

#rollThreshold::-webkit-outer-spin-button,
#rollThreshold::-webkit-inner-spin-button {
	-webkit-appearance: none;
 	margin: 0;
}

#rollPresetDiffs {
	display: flex;
}

#rollSubmit {
	width: 100%;
    height: 40px;
    font-size: 18px;
}
</style>`);

$("body").append(`
<div id="rollPanel">
  <div id="rollToggle">
    <button>&lt; Roll</button>
  </div>
  <div id="rollOptions">
    <label for="rollType">Test:</label>

    <select name="rollType" id="rollType">
        <option value="">Standard (1d100)</option>
    </select>

    <br><br>

    <input type="checkbox" name="rollHasThreshold" id="rollHasThreshold">
    <label for="rollHasThreshold">Seuil de réussite</label>
    <input type="number" name="rollThreshold" id="rollThreshold" min="0" max="100" value="0" disabled>

    <br><br>

    <div id="rollPresetDiffs">
      <button id="rollSetEasy" class="rollPresetDiff" value="25" disabled>Facile</button>
      <button id="rollSetMedium" class="rollPresetDiff" value="50" disabled>Moyen</button>
      <button id="rollSetHard" class="rollPresetDiff" value="75" disabled>Difficile</button>
    </div>

    <br>

    <button id="rollSubmit">Lancer</button>
  </div>
</div>
`);

for (let formula in formulas) {
    $("#rollType").append(`<option value="${formula}">${formula}</option>`);
}

let showGUI = false;

$("#rollToggle button").click(function() {
    if (showGUI) {
        $("#rollPanel").css("right", "-220px");
        $("#rollToggle button").text("< Roll");
        showGUI = false;
    }
    else {
        $("#rollPanel").css("right", "0px");
        $("#rollToggle button").text("> Roll");
        showGUI = true;
    }
});

$("#rollHasThreshold").change(function() {
    if ($("#rollHasThreshold").attr("checked")) {
        $(".rollPresetDiff, #rollThreshold").prop("disabled", false);
        $("#rollThreshold").select();
    }
    else {
        $(".rollPresetDiff, #rollThreshold").prop("disabled", true);
    }
});

$(".rollPresetDiff").click(function() {
    $("#rollThreshold").val($(this).attr("value")).select();
});

$("#rollSubmit").click(function() {

    const rollType = $("#rollType").val();
    let roll = "/roll ";

    if (!rollType) {
        roll += "1d100";
    } else {
        roll += rollType;
        if ($("#rollHasThreshold").attr("checked")) {
            roll += " ";
            const threshold = parseInt($("#rollThreshold").val());
            switch (threshold) {
                case 25:
                    roll += "f";
                break;
                case 50:
                    roll += "m";
                break;
                case 75:
                    roll += "d";
                break;
                default:
                    roll += threshold;
            }
        }
    }

    $("#chatForm .text_chat").val(roll);
    $("#chatForm .text_valider").click();

    $("#rollPanel").css("right", "-220px");
    $("#rollToggle button").text("< Roll");
    showGUI = false;
});


// MAIN //

document.addEventListener('keypress', (e) => {
    if (e.keyCode == 13) {
        jetDes(e);
    }
}, false);

$("#chatForm .text_valider").click(jetDes);

console.log("Script Roll - Actif.");