Roll

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

// ==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.");

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址