Outils pour utilisateurs

Outils du site


simulateur_saison3_1

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
simulateur_saison3_1 [2026/10/02 00:38] – nanakisimulateur_saison3_1 [2026/10/02 08:33] (Version actuelle) – nanaki
Ligne 1: Ligne 1:
 +Bonjour,
 +Voici le simulateur pour la saison 3.
 +N'hésitez pas à remonter des problèmes si il y a.
 <html> <html>
 <head> <head>
 <meta charset="UTF-8"> <meta charset="UTF-8">
 +<meta name="viewport" content="width=device-width, initial-scale=1">
 <title>Simulateur RPG</title> <title>Simulateur RPG</title>
  
 <style> <style>
 body { body {
-    font-family: Arial;+    font-family: Arial, sans-serif;
     background:#0b1a13;     background:#0b1a13;
     color:#7dd3fc;     color:#7dd3fc;
Ligne 12: Ligne 16:
 } }
  
-h1,h2 { +h1,h2 { color:gold; } 
-    color:gold; +h3 { color:#7dd3fc; }
-}+
  
 .box { .box {
Ligne 24: Ligne 27:
 select { select {
     margin:3px;     margin:3px;
-    max-width:180px;+    max-width:220px;
 } }
  
 input { input {
     margin:3px;     margin:3px;
-    width:60px;+    width:65px;
 } }
  
Ligne 43: Ligne 46:
     padding:10px;     padding:10px;
     white-space:pre-wrap;     white-space:pre-wrap;
 +    overflow-wrap:anywhere;
 } }
  
Ligne 50: Ligne 54:
 } }
  
-.equipStats { +.equipStats { margin-left:5px; }
-    margin-left:5px; +
-}+
  
-.bonus { +.bonus,.special { color:#00ff00; } 
-    color:#00ff00; +.malus { color:#ff3333; }
-} +
- +
-.malus { +
-    color:#ff3333; +
-}+
  
-.special { +button { 
-    color:#00ff00;+    margin:4px; 
 +    padding:7px 10px; 
 +    cursor:pointer;
 } }
 </style> </style>
Ligne 181: Ligne 180:
 </div> </div>
  
-<button onclick="resetAll()">Reset</button> +<button type="button" onclick="resetAll()">Reset</button> 
-<button onclick="exportBuild()">📤 Export</button> +<button type="button" onclick="exportBuild()">📤 Export</button> 
-<button onclick="importBuild()">📥 Import</button> +<button type="button" onclick="importBuild()">📥 Import</button> 
-<button onclick="copyLink()">🔗 Lien</button>+<button type="button" onclick="copyLink()">🔗 Lien</button>
  
 <pre id="result" class="result"></pre> <pre id="result" class="result"></pre>
- 
  
 <script> <script>
 +"use strict";
  
 /* ========================================================= /* =========================================================
Ligne 198: Ligne 197:
  
     Elfe:{     Elfe:{
-        a:2, +        a:2,cc:9,ct:10,f:9,e:4,agi:9, 
-        cc:9, +        p:5,mvt:5,pv:55,pm:30,r:4,rm:6, 
-        ct:10, +        fm:8,pui:6,res:5
-        f:9, +
-        e:4, +
-        agi:9, +
-        p:5, +
-        mvt:5, +
-        pv:55, +
-        pm:30, +
-        r:4, +
-        rm:6, +
-        fm:8, +
-        pui:6, +
-        res:5+
     },     },
  
     Nain:{     Nain:{
-        a:2, +        a:2,cc:11,ct:8,f:11,e:6,agi:7, 
-        cc:11, +        p:4,mvt:4,pv:60,pm:25,r:7,rm:5, 
-        ct:8, +        fm:10,pui:4,res:3
-        f:11, +
-        e:6, +
-        agi:7, +
-        p:4, +
-        mvt:4, +
-        pv:60, +
-        pm:25, +
-        r:7, +
-        rm:5, +
-        fm:10, +
-        pui:4, +
-        res:3+
     },     },
  
     Géant:{     Géant:{
-        a:2, +        a:2,cc:9,ct:10,f:12,e:4,agi:8, 
-        cc:9, +        p:4,mvt:5,pv:70,pm:30,r:6,rm:6, 
-        ct:10, +        fm:6,pui:5,res:4
-        f:12, +
-        e:4, +
-        agi:8, +
-        p:4, +
-        mvt:5, +
-        pv:70, +
-        pm:30, +
-        r:6, +
-        rm:6, +
-        fm:6, +
-        pui:5, +
-        res:4+
     },     },
  
     Olympien:{     Olympien:{
-        a:2, +        a:2,cc:10,ct:9,f:10,e:5,agi:9, 
-        cc:10, +        p:4,mvt:5,pv:60,pm:30,r:5,rm:6, 
-        ct:9, +        fm:7,pui:5,res:5
-        f:10, +
-        e:5, +
-        agi:9, +
-        p:4, +
-        mvt:5, +
-        pv:60, +
-        pm:30, +
-        r:5, +
-        rm:6, +
-        fm:7, +
-        pui:5, +
-        res:5+
     },     },
  
     HS:{     HS:{
-        a:2, +        a:2,cc:8,ct:9,f:8,e:3,agi:11, 
-        cc:8, +        p:5,mvt:6,pv:50,pm:40,r:3,rm:6, 
-        ct:9, +        fm:9,pui:5,res:6
-        f:8, +
-        e:3, +
-        agi:11, +
-        p:5, +
-        mvt:6, +
-        pv:50, +
-        pm:40, +
-        r:3, +
-        rm:6, +
-        fm:9, +
-        pui:5, +
-        res:6+
     }     }
 }; };
- 
  
 /* ========================================================= /* =========================================================
-   ORDRE DES CARACTERISTIQUES+   CARACTERISTIQUES
 ========================================================= */ ========================================================= */
  
 const statOrder = [ const statOrder = [
-    "a", +    "a","cc","ct","f","e","agi","p", 
-    "cc", +    "pui","fm","mvt","pv","pm","r","res","rm"
-    "ct", +
-    "f", +
-    "e", +
-    "agi", +
-    "p", +
-    "pui", +
-    "fm", +
-    "mvt", +
-    "pv", +
-    "pm", +
-    "r", +
-    "res", +
-    "rm"+
 ]; ];
  
 const statLabels = { const statLabels = {
- +    a:"A",cc:"CC",ct:"CT",f:"F",e:"E", 
-    a:"A", +    agi:"Agi",p:"P",pui:"Pui",fm:"FM", 
-    cc:"CC", +    mvt:"Mvt",pv:"PV",pm:"PM",r:"R", 
-    ct:"CT", +    res:"Rés",rm:"RM"
-    f:"F", +
-    e:"E", +
-    agi:"Agi", +
-    p:"P", +
-    pui:"Pui", +
-    fm:"FM", +
-    mvt:"Mvt", +
-    pv:"PV", +
-    pm:"PM", +
-    r:"R", +
-    res:"Rés", +
-    rm:"RM"+
 }; };
- 
  
 /* ========================================================= /* =========================================================
Ligne 336: Ligne 248:
  
 const costTable = { const costTable = {
- 
     a:[800,200,100],     a:[800,200,100],
- 
     cc:[100,50,30],     cc:[100,50,30],
     ct:[110,50,30],     ct:[110,50,30],
- 
     f:[120,55,30],     f:[120,55,30],
     e:[120,55,30],     e:[120,55,30],
- 
     agi:[95,45,25],     agi:[95,45,25],
- 
     pui:[110,55,35],     pui:[110,55,35],
     res:[110,55,35],     res:[110,55,35],
- 
     fm:[100,50,30],     fm:[100,50,30],
- 
     p:[110,85,78],     p:[110,85,78],
- 
     pv:[4,2,1],     pv:[4,2,1],
     pm:[5,3,1],     pm:[5,3,1],
- 
     mvt:[100,50,30],     mvt:[100,50,30],
- 
     r:[40,30,15],     r:[40,30,15],
     rm:[50,40,20]     rm:[50,40,20]
 }; };
- 
  
 /* ========================================================= /* =========================================================
    EQUIPEMENTS    EQUIPEMENTS
-========================================================= +========================================================= */
- +
-Règle : +
-- équipement normal = toutes les races +
-- équipement exo = uniquement la race indiquée dans "race" +
- +
-Rappel : +
-R   = r +
-Rés = res +
-*/+
  
 const equipments = [ const equipments = [
  
-/* ========================= +/* COMMUN */
-   COMMUN +
-========================= */+
  
-{ +{name:"Bâton de marche",race:"all",slot:"rightHand",stats:{mvt:1}}, 
-    name:"Bâton de marche", +{name:"Gladius",race:"all",slot:"rightHand",stats:{cc:1}}, 
-    race:"all", +{name:"Sceptre",race:"all",slot:"rightHand",stats:{fm:1}}, 
-    slot:"rightHand", +{name:"Fustibale",race:"all",slot:"rightHand",stats:{ct:1,cc:-2}}, 
-    stats:{mvt:1} +{name:"Arbalète de poing",race:"all",slot:"rightHand",stats:{f:12,ct:1}}, 
-},+{name:"Torche",race:"all",slot:"rightHand",stats:{cc:-2,f:-2,feu:true}}, 
 +{name:"Lance barbelée",race:"all",slot:"rightHand",stats:{ct:1,f:1,cc:-1}}, 
 +{name:"Lance",race:"all",slot:"rightHand",stats:{ct:1,cc:-1}}, 
 +{name:"Rapière",race:"all",slot:"rightHand",stats:{cc:2,f:-1}}, 
 +{name:"Arc",race:"all",slot:"rightHand",stats:{ct:1,cc:-1}}, 
 +{name:"Arc long",race:"all",slot:"rightHand",stats:{ct:2,f:-1,cc:-2}}, 
 +{name:"Bélier",race:"all",slot:"rightHand",stats:{demolition:10,cc:-2}}, 
 +{name:"Pioche",race:"all",slot:"rightHand",stats:{demolition:5}}, 
 +{name:"Catalyseur magique",race:"all",slot:"rightHand",stats:{magique:true,cc:-3,demolition:10}},
  
-{ +{name:"Targe",race:"all",slot:"leftHand",stats:{cc:1,agi:-1}}, 
-    name:"Gladius", +{name:"Bouclier Parma",race:"all",slot:"leftHand",stats:{e:1,agi:-1}}, 
-    race:"all", +{name:"Écu brillant",race:"all",slot:"leftHand",stats:{res:1,agi:-1}},
-    slot:"rightHand", +
-    stats:{cc:1} +
-},+
  
-{ +{name:"Armure matelassée",race:"all",slot:"body",stats:{e:1,agi:-1}}, 
-    name:"Sceptre", +{name:"Toge d'apprenti",race:"all",slot:"body",stats:{res:1,agi:-1}}, 
-    race:"all", +{name:"Ceinture",race:"all",slot:"body",stats:{r:1}},
-    slot:"rightHand", +
-    stats:{fm:1} +
-},+
  
-{ +{name:"Cape de chasse",race:"all",slot:"cape",stats:{ct:1}},
-    name:"Fustibale", +
-    race:"all", +
-    slot:"rightHand", +
-    stats:{ct:1,cc:-2} +
-},+
  
-{ +{name:"Couronne d'adonis",race:"all",slot:"head",stats:{rm:1}}, 
-    name:"Arbalète de poing", +{name:"Visière",race:"all",slot:"head",stats:{p:1,cc:-1,fm:-1}}, 
-    race:"all", +{name:"Collier tressé",race:"all",slot:"head",stats:{pv:5,pm:5}},
-    slot:"rightHand", +
-    stats:{f:12,ct:1} +
-},+
  
-{ +{name:"Bottes de marche",race:"all",slot:"feet",stats:{mvt:1}}, 
-    name:"Torche", +{name:"Sceptre de mage",race:"all",slot:"rightHand",stats:{pui:1,fm:1}}, 
-    race:"all", +{name:"Sarbacane",race:"all",slot:"rightHand",stats:{ct:1,f:10,cc:-1}}, 
-    slot:"rightHand", +{name:"Pierre Noire",race:"all",slot:"rightHand",stats:{f:1,cc:-1}},
-    stats:{cc:-2,f:-2,feu:true} +
-},+
  
-{ +/* OLYMPIENS */
-    name:"Lance barbelée", +
-    race:"all", +
-    slot:"rightHand", +
-    stats:{ct:1,f:1,cc:-1} +
-},+
  
-{ +{name:"Spatha",race:"Olympien",slot:"rightHand",stats:{cc:1,f:1}}, 
-    name:"Lance", +{name:"Lame sainte",race:"Olympien",slot:"rightHand",stats:{cc:1,pui:1,magique:true}}, 
-    race:"all", +{name:"Pilum",race:"Olympien",slot:"rightHand",stats:{f:1,mvt:1,cc:-1}}, 
-    slot:"rightHand", +{name:"Sceptre de puissance",race:"Olympien",slot:"rightHand",stats:{pui:1,pm:8}}, 
-    stats:{ct:1,cc:-1} +{name:"Gastraphète",race:"Olympien",slot:"rightHand",stats:{f:15,ct:-2,cc:-1}}, 
-},+{name:"Bouclier Ancile",race:"Olympien",slot:"leftHand",stats:{e:1,pv:5}}, 
 +{name:"Armure Hoplitique",race:"Olympien",slot:"body",stats:{e:1,res:1}}, 
 +{name:"Lorica",race:"Olympien",exo:true,slot:"body",stats:{e:1,res:1}}, 
 +{name:"Cape de dueliste",race:"Olympien",slot:"cape",stats:{cc:2,f:-1}}, 
 +{name:"Diadème",race:"Olympien",slot:"head",stats:{r:1,rm:2}}, 
 +{name:"Tiare d'Oracle",race:"Olympien",slot:"head",stats:{fm:1,p:1}}, 
 +{name:"Cnémides",race:"Olympien",slot:"feet",stats:{mvt:1,rm:1,r:1}},
  
-{ +/* ELFES */
-    name:"Rapière", +
-    race:"all", +
-    slot:"rightHand", +
-    stats:{cc:2,f:-1} +
-},+
  
-{ +{name:"Lance de garde Sylvestre",race:"Elfe",slot:"rightHand",stats:{cc:1,f:1}}, 
-    name:"Arc", +{name:"Baton du Pelerin",race:"Elfe",slot:"rightHand",stats:{mvt:1,fm:1}}, 
-    race:"all", +{name:"Charybde",race:"Elfe",slot:"rightHand",stats:{pui:2,e:-1}}, 
-    slot:"rightHand", +{name:"Arc Ensorcelé",race:"Elfe",slot:"rightHand",stats:{ct:1,rm:2,cc:-1,magique:true}}, 
-    stats:{ct:1,cc:-1} +{name:"Arc Elfique",race:"Elfe",exo:true,slot:"rightHand",stats:{ct:1,f:1,mvt:1,cc:-2}}, 
-},+{name:"Targe renforcée",race:"Elfe",slot:"leftHand",stats:{e:1,cc:1}}, 
 +{name:"Cuirasse",race:"Elfe",slot:"body",stats:{res:1,r:2}}, 
 +{name:"Armure de garde Sylvestre",race:"Elfe",exo:true,slot:"body",stats:{res:2,pm:-10}}, 
 +{name:"Cape de feuillages",race:"Elfe",slot:"cape",stats:{fm:1,pv:5}}, 
 +{name:"Marque Forestière",race:"Elfe",slot:"head",stats:{pm:10,r:1}}, 
 +{name:"Capuche du chasseur",race:"Elfe",slot:"head",stats:{ct:1,r:1,rm:1}}, 
 +{name:"Bottes Tâlroval",race:"Elfe",slot:"feet",stats:{mvt:2}},
  
-{ +/* NAINS */
-    name:"Arc long", +
-    race:"all", +
-    slot:"rightHand", +
-    stats:{ct:2,f:-1,cc:-2} +
-},+
  
-{ +{name:"Labrys",race:"Nain",slot:"rightHand",stats:{cc:1,f:1}}, 
-    name:"Bélier", +{name:"Hache runique",race:"Nain",slot:"rightHand",stats:{cc:1,fm:1}}, 
-    race:"all", +{name:"Marteau runique",race:"Nain",slot:"rightHand",stats:{magique:true,pui:2}}, 
-    slot:"rightHand", +{name:"Baton d'archimage",race:"Nain",slot:"rightHand",stats:{fm:1,pm:10}}, 
-    stats:{demolition:10,cc:-2} +{name:"Marteau de guerre",race:"Nain",slot:"rightHand",stats:{f:2,cc:-1}}, 
-},+{name:"Bouclier Miroir",race:"Nain",slot:"leftHand",stats:{res:1,pv:5}}, 
 +{name:"Armure runique",race:"Nain",slot:"body",stats:{e:1,pm:8}}, 
 +{name:"Cotte de mailles",race:"Nain",exo:true,slot:"body",stats:{e:2,esquive:-4}}, 
 +{name:"Cape dorée",race:"Nain",exo:true,slot:"cape",stats:{res:1,mvt:1}}, 
 +{name:"Casque grossissant",race:"Nain",slot:"head",stats:{ct:2,p:-1}}, 
 +{name:"Casque de guerre",race:"Nain",slot:"head",stats:{pv:5,r:1,pm:5,rm:1}}, 
 +{name:"Solerets",race:"Nain",slot:"feet",stats:{mvt:1,pm:5,pv:5}},
  
-{ +/* GEANTS */
-    name:"Pioche", +
-    race:"all", +
-    slot:"rightHand", +
-    stats:{demolition:5} +
-},+
  
-{ +{name:"Masse d'arme",race:"Géant",slot:"rightHand",stats:{cc:1,f:1}}, 
-    name:"Catalyseur magique", +{name:"Hallebarde de pierre",race:"Géant",slot:"rightHand",stats:{f:1,mvt:1}}, 
-    race:"all", +{name:"Javelot lourd",race:"Géant",slot:"rightHand",stats:{f:2,ct:-1,cc:-1}}, 
-    slot:"rightHand", +{name:"Pierre en fusion",race:"Géant",slot:"rightHand",stats:{magique:true,ct:-2,feu:true}}, 
-    stats:{magique:true,cc:-3,demolition:10} +{name:"Baton de shaman",race:"Géant",exo:true,slot:"rightHand",stats:{fm:2}}, 
-},+{name:"Bouclier Clipeus",race:"Géant",slot:"leftHand",stats:{e:1,pv:10}}, 
 +{name:"Peau de granit manifiée",race:"Géant",slot:"body",stats:{res:1,rm:2,esquive:-2}}, 
 +{name:"Broigne",race:"Géant",exo:true,slot:"body",stats:{res:2,fm:-1}}, 
 +{name:"Cape de l'arpenteur",race:"Géant",slot:"cape",stats:{cc:1,ct:1}}, 
 +{name:"Fétiche de shaman",race:"Géant",slot:"head",stats:{r:2,pm:5}}, 
 +{name:"Coiffe de rage",race:"Géant",slot:"head",stats:{cc:1,pv:5,r:1}}, 
 +{name:"Bottes incandescentes",race:"Géant",slot:"feet",stats:{mvt:1,r:1,pv:5}},
  
-{ +/* HS */
-    name:"Targe", +
-    race:"all", +
-    slot:"leftHand", +
-    stats:{cc:1,agi:-1} +
-},+
  
-{ +{name:"Ceste",race:"HS",slot:"rightHand",stats:{f:1,cc:1}}, 
-    name:"Bouclier Parma", +{name:"Mains de mana",race:"HS",slot:"rightHand",stats:{magique:true,cc:2}}, 
-    race:"all", +{name:"Baton de Sage",race:"HS",slot:"rightHand",stats:{pui:1,agi:1}}, 
-    slot:"leftHand", +{name:"Orbe de mana",race:"HS",slot:"rightHand",stats:{pui:2,fm:-1}}, 
-    stats:{e:1,agi:-1} +{name:"Bouclier en lianes",race:"HS",slot:"leftHand",stats:{res:1,agi:1}}, 
-},+{name:"Manteau de feuillage",race:"HS",slot:"body",stats:{e:1,agi:1}}, 
 +{name:"Armure de fourrure",race:"HS",exo:true,slot:"body",stats:{e:2,rm:-3}}, 
 +{name:"Cape de mage",race:"HS",slot:"cape",stats:{fm:1,rm:1}}, 
 +{name:"Collier d'apaisement",race:"HS",slot:"head",stats:{pv:10,pm:5}}, 
 +{name:"Coiffe de rapace",race:"HS",slot:"head",stats:{ct:1,p:1}}, 
 +{name:"Bottes griffues",race:"HS",exo:true,slot:"feet",stats:{cc:1,f:1,pv:5}}, 
 +{name:"Bottes de voleur",race:"HS",slot:"feet",stats:{mvt:1,agi:1}},
  
-{ +/* LUTINS : ANNEAUX */
-    name:"Écu brillant", +
-    race:"all", +
-    slot:"leftHand", +
-    stats:{res:1,agi:-1} +
-},+
  
-{ +{name:"Anneau d'Horizon",race:"Lutin",slot:"ring",stats:{p:1}}, 
-    name:"Armure matelassée", +{name:"Anneau de Caprice",race:"Lutin",slot:"ring",stats:{fm:1}}, 
-    race:"all", +{name:"Anneau de Puissance",race:"Lutin",slot:"ring",stats:{pui:1}}, 
-    slot:"body", +{name:"Anneau de Férocité",race:"Lutin",slot:"ring",stats:{f:1}}, 
-    stats:{e:1,agi:-1} +{name:"Anneau de Résistance",race:"Lutin",slot:"ring",stats:{res:1}}, 
-},+{name:"Anneau d'Équilibre",race:"Lutin",slot:"ring",stats:{pv:5,pm:5}}, 
 +{name:"Anneau de Finesse",race:"Lutin",slot:"ring",stats:{cc:1}}, 
 +{name:"Anneau de Prétention",race:"Lutin",slot:"ring",stats:{ct:1}}, 
 +{name:"Anneau de Tenacité",race:"Lutin",slot:"ring",stats:{e:1}}, 
 +{name:"Anneau de Souplesse",race:"Lutin",slot:"ring",stats:{agi:1}},
  
-{ +{name:"Bottes de 7 lieux",race:"Lutin",exo:true,slot:"feet",stats:{mvt:3}}
-    name:"Toge d'apprenti", +
-    race:"all", +
-    slot:"body", +
-    stats:{res:1,agi:-1} +
-}, +
- +
-{ +
-    name:"Ceinture", +
-    race:"all", +
-    slot:"body", +
-    stats:{r:1} +
-}, +
- +
-{ +
-    name:"Cape de chasse", +
-    race:"all", +
-    slot:"cape", +
-    stats:{ct:1} +
-}, +
- +
-{ +
-    name:"Couronne d'adonis", +
-    race:"all", +
-    slot:"head", +
-    stats:{rm:1} +
-}, +
- +
-{ +
-    name:"Visière", +
-    race:"all", +
-    slot:"head", +
-    stats:{p:1,cc:-1,fm:-1} +
-}, +
- +
-{ +
-    name:"Collier tressé", +
-    race:"all", +
-    slot:"head", +
-    stats:{pv:5,pm:5} +
-}, +
- +
-{ +
-    name:"Bottes de marche", +
-    race:"all", +
-    slot:"feet", +
-    stats:{mvt:1} +
-}, +
- +
-{ +
-    name:"Sceptre de mage", +
-    race:"all", +
-    slot:"rightHand", +
-    stats:{pui:1,fm:1} +
-}, +
- +
-{ +
-    name:"Sarbacane", +
-    race:"all", +
-    slot:"rightHand", +
-    stats:{ct:1,f:10,cc:-1} +
-}, +
- +
-{ +
-    name:"Pierre Noire", +
-    race:"all", +
-    slot:"rightHand", +
-    stats:{f:1,cc:-1} +
-}, +
- +
- +
-/* ========================= +
-   OLYMPIENS +
-========================= */ +
- +
-{ +
-    name:"Spatha", +
-    race:"Olympiens", +
-    slot:"rightHand", +
-    stats:{cc:1,f:1} +
-}, +
- +
-{ +
-    name:"Lame sainte", +
-    race:"Olympiens", +
-    slot:"rightHand", +
-    stats:{cc:1,pui:1,magique:true} +
-}, +
- +
-{ +
-    name:"Pilum", +
-    race:"Olympiens", +
-    slot:"rightHand", +
-    stats:{f:1,mvt:1,cc:-1} +
-}, +
- +
-{ +
-    name:"Sceptre de puissance", +
-    race:"Olympiens", +
-    slot:"rightHand", +
-    stats:{pui:1,pm:8} +
-}, +
- +
-{ +
-    name:"Gastraphète", +
-    race:"Olympiens", +
-    slot:"rightHand", +
-    stats:{f:15,ct:-2,cc:-1} +
-}, +
- +
-{ +
-    name:"Bouclier Ancile", +
-    race:"Olympiens", +
-    slot:"leftHand", +
-    stats:{e:1,pv:5} +
-}, +
- +
-{ +
-    name:"Armure Hoplitique", +
-    race:"Olympiens", +
-    slot:"body", +
-    stats:{e:1,res:1} +
-}, +
- +
-{ +
-    name:"Lorica", +
-    race:"Olympiens", +
-    exo:true, +
-    slot:"body", +
-    stats:{e:1,res:1} +
-}, +
- +
-{ +
-    name:"Cape de dueliste", +
-    race:"Olympiens", +
-    slot:"cape", +
-    stats:{cc:2,f:-1} +
-}, +
- +
-{ +
-    name:"Diadème", +
-    race:"Olympiens", +
-    slot:"head", +
-    stats:{r:1,rm:2} +
-}, +
- +
-{ +
-    name:"Tiare d'Oracle", +
-    race:"Olympiens", +
-    slot:"head", +
-    stats:{fm:1,p:1} +
-}, +
- +
-{ +
-    name:"Cnémides", +
-    race:"Olympiens", +
-    slot:"feet", +
-    stats:{mvt:1,rm:1,r:1} +
-}, +
- +
- +
-/* ========================= +
-   ELFES +
-========================= */ +
- +
-{ +
-    name:"Lance de garde Sylvestre", +
-    race:"Elfes", +
-    slot:"rightHand", +
-    stats:{cc:1,f:1} +
-}, +
- +
-{ +
-    name:"Baton du Pelerin", +
-    race:"Elfes", +
-    slot:"rightHand", +
-    stats:{mvt:1,fm:1} +
-}, +
- +
-{ +
-    name:"Charybde", +
-    race:"Elfes", +
-    slot:"rightHand", +
-    stats:{pui:2,e:-1} +
-}, +
- +
-{ +
-    name:"Arc Ensorcelé", +
-    race:"Elfes", +
-    slot:"rightHand", +
-    stats:{ct:1,rm:2,cc:-1,magique:true} +
-}, +
- +
-{ +
-    name:"Arc Elfique", +
-    race:"Elfes", +
-    exo:true, +
-    slot:"rightHand", +
-    stats:{ct:1,f:1,mvt:1,cc:-2} +
-}, +
- +
-{ +
-    name:"Targe renforcée", +
-    race:"Elfes", +
-    slot:"leftHand", +
-    stats:{e:1,cc:1} +
-}, +
- +
-{ +
-    name:"Cuirasse", +
-    race:"Elfes", +
-    slot:"body", +
-    stats:{res:1,r:2} +
-}, +
- +
-{ +
-    name:"Armure de garde Sylvestre", +
-    race:"Elfes", +
-    exo:true, +
-    slot:"body", +
-    stats:{res:2,pm:-10} +
-}, +
- +
-{ +
-    name:"Cape de feuillages", +
-    race:"Elfes", +
-    slot:"cape", +
-    stats:{fm:1,pv:5} +
-}, +
- +
-{ +
-    name:"Marque Forestière", +
-    race:"Elfes", +
-    slot:"head", +
-    stats:{pm:10,r:1} +
-}, +
- +
-{ +
-    name:"Capuche du chasseur", +
-    race:"Elfes", +
-    slot:"head", +
-    stats:{ct:1,r:1,rm:1} +
-}, +
- +
-{ +
-    name:"Bottes Tâlroval", +
-    race:"Elfes", +
-    slot:"feet", +
-    stats:{mvt:2} +
-}, +
- +
- +
-/* ========================= +
-   NAINS +
-========================= */ +
- +
-{ +
-    name:"Labrys", +
-    race:"Nains", +
-    slot:"rightHand", +
-    stats:{cc:1,f:1} +
-}, +
- +
-{ +
-    name:"Hache runique", +
-    race:"Nains", +
-    slot:"rightHand", +
-    stats:{cc:1,fm:1} +
-}, +
- +
-{ +
-    name:"Marteau runique", +
-    race:"Nains", +
-    slot:"rightHand", +
-    stats:{magique:true,pui:2} +
-}, +
- +
-{ +
-    name:"Baton d'archimage", +
-    race:"Nains", +
-    slot:"rightHand", +
-    stats:{fm:1,pm:10} +
-}, +
- +
-{ +
-    name:"Marteau de guerre", +
-    race:"Nains", +
-    slot:"rightHand", +
-    stats:{f:2,cc:-1} +
-}, +
- +
-{ +
-    name:"Bouclier Miroir", +
-    race:"Nains", +
-    slot:"leftHand", +
-    stats:{res:1,pv:5} +
-}, +
- +
-{ +
-    name:"Armure runique", +
-    race:"Nains", +
-    slot:"body", +
-    stats:{e:1,pm:8} +
-}, +
- +
-{ +
-    name:"Cotte de mailles", +
-    race:"Nains", +
-    exo:true, +
-    slot:"body", +
-    stats:{e:2,esquive:-4} +
-}, +
- +
-{ +
-    name:"Cape dorée", +
-    race:"Nains", +
-    exo:true, +
-    slot:"cape", +
-    stats:{res:1,mvt:1} +
-}, +
- +
-{ +
-    name:"Casque grossissant", +
-    race:"Nains", +
-    slot:"head", +
-    stats:{ct:2,p:-1} +
-}, +
- +
-{ +
-    name:"Casque de guerre", +
-    race:"Nains", +
-    slot:"head", +
-    stats:{pv:5,r:1,pm:5,rm:1} +
-}, +
- +
-{ +
-    name:"Solerets", +
-    race:"Nains", +
-    slot:"feet", +
-    stats:{mvt:1,pm:5,pv:5} +
-}, +
- +
- +
-/* ========================= +
-   GEANTS +
-========================= */ +
- +
-{ +
-    name:"Masse d'arme", +
-    race:"Géants", +
-    slot:"rightHand", +
-    stats:{cc:1,f:1} +
-}, +
- +
-{ +
-    name:"Hallebarde de pierre", +
-    race:"Géants", +
-    slot:"rightHand", +
-    stats:{f:1,mvt:1} +
-}, +
- +
-{ +
-    name:"Javelot lourd", +
-    race:"Géants", +
-    slot:"rightHand", +
-    stats:{f:2,ct:-1,cc:-1} +
-}, +
- +
-{ +
-    name:"Pierre en fusion", +
-    race:"Géants", +
-    slot:"rightHand", +
-    stats:{magique:true,ct:-2,feu:true} +
-}, +
- +
-{ +
-    name:"Baton de shaman", +
-    race:"Géants", +
-    exo:true, +
-    slot:"rightHand", +
-    stats:{fm:2} +
-}, +
- +
-{ +
-    name:"Bouclier Clipeus", +
-    race:"Géants", +
-    slot:"leftHand", +
-    stats:{e:1,pv:10} +
-}, +
- +
-{ +
-    name:"Peau de granit manifiée", +
-    race:"Géants", +
-    slot:"body", +
-    stats:{res:1,rm:2,esquive:-2} +
-}, +
- +
-{ +
-    name:"Broigne", +
-    race:"Géants", +
-    exo:true, +
-    slot:"body", +
-    stats:{res:2,fm:-1} +
-}, +
- +
-{ +
-    name:"Cape de l'arpenteur", +
-    race:"Géants", +
-    slot:"cape", +
-    stats:{cc:1,ct:1} +
-}, +
- +
-{ +
-    name:"Fétiche de shaman", +
-    race:"Géants", +
-    slot:"head", +
-    stats:{r:2,pm:5} +
-}, +
- +
-{ +
-    name:"Coiffe de rage", +
-    race:"Géants", +
-    slot:"head", +
-    stats:{cc:1,pv:5,r:1} +
-}, +
- +
-{ +
-    name:"Bottes incandescentes", +
-    race:"Géants", +
-    slot:"feet", +
-    stats:{mvt:1,r:1,pv:5} +
-}, +
- +
- +
-/* ========================= +
-   HS +
-========================= */ +
- +
-{ +
-    name:"Ceste", +
-    race:"HS", +
-    slot:"rightHand", +
-    stats:{f:1,cc:1} +
-}, +
- +
-{ +
-    name:"Mains de mana", +
-    race:"HS", +
-    slot:"rightHand", +
-    stats:{magique:true,cc:2} +
-}, +
- +
-{ +
-    name:"Baton de Sage", +
-    race:"HS", +
-    slot:"rightHand", +
-    stats:{pui:1,agi:1} +
-}, +
- +
-{ +
-    name:"Orbe de mana", +
-    race:"HS", +
-    slot:"rightHand", +
-    stats:{pui:2,fm:-1} +
-}, +
- +
-{ +
-    name:"Bouclier en lianes", +
-    race:"HS", +
-    slot:"leftHand", +
-    stats:{res:1,agi:1} +
-}, +
- +
-{ +
-    name:"Manteau de feuillage", +
-    race:"HS", +
-    slot:"body", +
-    stats:{e:1,agi:1} +
-}, +
- +
-{ +
-    name:"Armure de fourrure", +
-    race:"HS", +
-    exo:true, +
-    slot:"body", +
-    stats:{e:2,rm:-3} +
-}, +
- +
-{ +
-    name:"Cape de mage", +
-    race:"HS", +
-    slot:"cape", +
-    stats:{fm:1,rm:1} +
-}, +
- +
-{ +
-    name:"Collier d'apaisement", +
-    race:"HS", +
-    slot:"head", +
-    stats:{pv:10,pm:5} +
-}, +
- +
-{ +
-    name:"Coiffe de rapace", +
-    race:"HS", +
-    slot:"head", +
-    stats:{ct:1,p:1} +
-}, +
- +
-{ +
-    name:"Bottes griffues", +
-    race:"HS", +
-    exo:true, +
-    slot:"feet", +
-    stats:{cc:1,f:1,pv:5} +
-}, +
- +
-{ +
-    name:"Bottes de voleur", +
-    race:"HS", +
-    slot:"feet", +
-    stats:{mvt:1,agi:1} +
-}, +
- +
- +
-/* ========================= +
-   LUTINS +
-========================= */ +
- +
-{ +
-    name:"Anneau d'Horizon", +
-    race:"Lutin", +
-    slot:"ring", +
-    stats:{p:1} +
-}, +
- +
-{ +
-    name:"Anneau de Caprice", +
-    race:"Lutin", +
-    slot:"ring", +
-    stats:{fm:1} +
-}, +
- +
-{ +
-    name:"Anneau de Puissance", +
-    race:"Lutin", +
-    slot:"ring", +
-    stats:{pui:1} +
-}, +
- +
-{ +
-    name:"Anneau de Férocité", +
-    race:"Lutin", +
-    slot:"ring", +
-    stats:{f:1} +
-}, +
- +
-{ +
-    name:"Anneau de Résistance", +
-    race:"Lutin", +
-    slot:"ring", +
-    stats:{res:1} +
-}, +
- +
-{ +
-    name:"Anneau d'Équilibre", +
-    race:"Lutin", +
-    slot:"ring", +
-    stats:{pv:5,pm:5} +
-}, +
- +
-{ +
-    name:"Anneau de Finesse", +
-    race:"Lutin", +
-    slot:"ring", +
-    stats:{cc:1} +
-}, +
- +
-{ +
-    name:"Anneau de Prétention", +
-    race:"Lutin", +
-    slot:"ring", +
-    stats:{ct:1} +
-}, +
- +
-{ +
-    name:"Anneau de Tenacité", +
-    race:"Lutin", +
-    slot:"ring", +
-    stats:{e:1} +
-}, +
- +
-{ +
-    name:"Anneau de Souplesse", +
-    race:"Lutin", +
-    slot:"ring", +
-    stats:{agi:1} +
-}, +
- +
-{ +
-    name:"Bottes de 7 lieux", +
-    race:"Lutin", +
-    exo:true, +
-    slot:"feet", +
-    stats:{mvt:3} +
-}+
  
 ]; ];
- 
  
 /* ========================================================= /* =========================================================
Ligne 1124: Ligne 404:
  
 const skills = [ const skills = [
- 
     {     {
         name:"Fulgurance",         name:"Fulgurance",
-        desc:"+1 toucher au cac + 1 esquive tous les 5 mouvements"+        desc:"+1 toucher CAC et +1 esquive par tranche de 5 mouvements"
     },     },
- 
     {     {
         name:"Couverture",         name:"Couverture",
         desc:"85% CC / 15% AGI"         desc:"85% CC / 15% AGI"
     },     },
- 
     {     {
         name:"Réflexes fulgurants",         name:"Réflexes fulgurants",
         desc:"85% AGI / 15% CC"         desc:"85% AGI / 15% CC"
     },     },
- 
     {     {
         name:"Berserker",         name:"Berserker",
-        desc:"+1 F par tranche de 10 PV perdus"+        desc:"+1 F par tranche de 10 PV perdus (non calculé)"
     },     },
- 
     {     {
         name:"Griffes",         name:"Griffes",
-        desc:"+1 F et +1 CC"+        desc:"+3 F à mains nues ou avec une ceste"
     },     },
- 
     {     {
         name:"Anguille",         name:"Anguille",
-        desc:"+1 esquive"+        desc:"+1 esquive (non calculé)"
     }     }
- 
 ]; ];
- 
  
 /* ========================================================= /* =========================================================
Ligne 1163: Ligne 435:
  
 const spells = [ const spells = [
- 
     {name:"Peau de granit",dex:0,prot:2},     {name:"Peau de granit",dex:0,prot:2},
     {name:"Coup précis",dex:2,prot:0},     {name:"Coup précis",dex:2,prot:0},
Ligne 1179: Ligne 450:
     {name:"Guigne",dex:-8,prot:0},     {name:"Guigne",dex:-8,prot:0},
     {name:"Virtuose",dex:8,prot:0}     {name:"Virtuose",dex:8,prot:0}
- 
 ]; ];
- 
  
 /* ========================================================= /* =========================================================
Ligne 1189: Ligne 458:
 const raceSelect = document.getElementById("race"); const raceSelect = document.getElementById("race");
  
-for(const r in races){+Object.keys(races).forEach(r=>{ 
 +    const option=document.createElement("option"); 
 +    option.value=r; 
 +    option.textContent=r; 
 +    raceSelect.appendChild(option); 
 +});
  
-    const o=document.createElement("option"); +/* AMELIORATIONS */
- +
-    o.value=r; +
-    o.textContent=r; +
- +
-    raceSelect.appendChild(o); +
-} +
- +
- +
-/* ========================================================= +
-   STATS AMELIORATIONS +
-========================================================= */+
  
 const statsDiv=document.getElementById("stats"); const statsDiv=document.getElementById("stats");
  
 statOrder.forEach(stat=>{ statOrder.forEach(stat=>{
- +    if(!costTable[stat]) return;
-    if(!costTable[stat]){ +
-        return; +
-    }+
  
     const line=document.createElement("div");     const line=document.createElement("div");
- 
     line.className="statLine";     line.className="statLine";
  
     const label=document.createElement("label");     const label=document.createElement("label");
- +    label.textContent=statLabels[stat]||stat;
-    label.textContent= +
-        statLabels[stat] || stat;+
  
     const input=document.createElement("input");     const input=document.createElement("input");
- 
     input.type="number";     input.type="number";
     input.id="up_"+stat;     input.id="up_"+stat;
Ligne 1228: Ligne 484:
     input.min=0;     input.min=0;
  
-    input.addEventListener( +    input.addEventListener("input",calculate);
-        "input", +
-        calculate +
-    ); +
- +
-    line.appendChild(label); +
-    line.appendChild(input);+
  
 +    line.append(label,input);
     statsDiv.appendChild(line);     statsDiv.appendChild(line);
 }); });
  
- +/* PASSIFS */
-/* ========================================================= +
-   PASSIFS +
-========================================================= */+
  
 const skillsDiv=document.getElementById("skills"); const skillsDiv=document.getElementById("skills");
  
 skills.forEach((s,i)=>{ skills.forEach((s,i)=>{
- 
     const label=document.createElement("label");     const label=document.createElement("label");
- 
     const cb=document.createElement("input");     const cb=document.createElement("input");
  
     cb.type="checkbox";     cb.type="checkbox";
     cb.id="skill_"+i;     cb.id="skill_"+i;
 +    cb.addEventListener("change",calculate);
  
-    cb.addEventListener( +    label.append( 
-        "change", +        cb, 
-        calculate+        document.createTextNode(" "+s.name+" — "+s.desc)
     );     );
  
-    label.appendChild(cb); +    skillsDiv.append(label,document.createElement("br"));
- +
-    label.appendChild( +
-        document.createTextNode( +
-            " "+s.name+" — "+s.desc +
-        ) +
-    ); +
- +
-    skillsDiv.appendChild(label); +
-    skillsDiv.appendChild( +
-        document.createElement("br") +
-    );+
 }); });
  
- +/* SORTS */
-/* ========================================================= +
-   SORTS +
-========================================================= */+
  
 const spellsDiv=document.getElementById("spells"); const spellsDiv=document.getElementById("spells");
  
 spells.forEach((s,i)=>{ spells.forEach((s,i)=>{
- 
     const label=document.createElement("label");     const label=document.createElement("label");
- 
     const cb=document.createElement("input");     const cb=document.createElement("input");
  
     cb.type="checkbox";     cb.type="checkbox";
     cb.id="spell_"+i;     cb.id="spell_"+i;
 +    cb.addEventListener("change",calculate);
  
-    cb.addEventListener( +    label.append( 
-        "change", +        cb,
-        calculate +
-    ); +
- +
-    label.appendChild(cb); +
- +
-    label.appendChild(+
         document.createTextNode(         document.createTextNode(
-            " "+s.name+ +            " "+s.name+" (Dex "+s.dex+", Prot "+s.prot+")"
-            " (Dex "+s.dex+", Prot "+s.prot+")"+
         )         )
     );     );
  
-    spellsDiv.appendChild(label); +    spellsDiv.append(label,document.createElement("br"));
- +
-    spellsDiv.appendChild( +
-        document.createElement("br") +
-    );+
 }); });
- 
  
 /* ========================================================= /* =========================================================
    EQUIPEMENTS    EQUIPEMENTS
 ========================================================= */ ========================================================= */
- 
-const head=document.getElementById("head"); 
-const cape=document.getElementById("cape"); 
-const rightHand=document.getElementById("rightHand"); 
-const leftHand=document.getElementById("leftHand"); 
-const body=document.getElementById("body"); 
-const ring=document.getElementById("ring"); 
-const feet=document.getElementById("feet"); 
  
 const slots = { const slots = {
 +    head:document.getElementById("head"),
 +    cape:document.getElementById("cape"),
 +    rightHand:document.getElementById("rightHand"),
 +    leftHand:document.getElementById("leftHand"),
 +    body:document.getElementById("body"),
 +    ring:document.getElementById("ring"),
 +    feet:document.getElementById("feet")
 +};
  
-    head:head, +const statIds = { 
-    cape:cape, +    head:"headStats", 
-    rightHand:rightHand, +    cape:"capeStats", 
-    leftHand:leftHand, +    rightHand:"rightStats", 
-    body:body, +    leftHand:"leftStats", 
-    ring:ring, +    body:"bodyStats", 
-    feet:feet +    ring:"ringStats", 
 +    feet:"feetStats"
 }; };
  
 +/* COMPATIBILITE EXOTIQUE */
  
-/* ========================================================= +function canEquip(item,race){
-   REGLE D'EQUIPEMENT +
-=========================================================+
  
-Normal : +    if(!item.exo){ 
-    toutes les races+        return true; 
 +    }
  
-Exo : +    const aliases = { 
-    uniquement la race propriétaire +        "Olympiens":"Olympien", 
-*/+        "Elfes":"Elfe", 
 +        "Nains":"Nain", 
 +        "Géants":"Géant" 
 +    };
  
-function canEquip(e,race){+    const owner=aliases[item.race]||item.race;
  
-    if(e.exo === true){ +    return owner===race;
- +
-        return e.race === race; +
-    } +
- +
-    return true;+
 } }
  
- +/* REMPLISSAGE */
-/* ========================================================= +
-   REMPLISSAGE DES EQUIPEMENTS +
-========================================================= */+
  
 function fillEquip(){ function fillEquip(){
  
     const race=raceSelect.value;     const race=raceSelect.value;
- 
-    const statIds = { 
- 
-        head:"headStats", 
-        cape:"capeStats", 
-        rightHand:"rightStats", 
-        leftHand:"leftStats", 
-        body:"bodyStats", 
-        ring:"ringStats", 
-        feet:"feetStats" 
- 
-    }; 
- 
  
     for(const key in slots){     for(const key in slots){
  
         const select=slots[key];         const select=slots[key];
- 
         select.innerHTML="";         select.innerHTML="";
- 
  
         const empty=document.createElement("option");         const empty=document.createElement("option");
- 
         empty.value="";         empty.value="";
         empty.textContent="— Aucun —";         empty.textContent="— Aucun —";
- 
         select.appendChild(empty);         select.appendChild(empty);
  
- +        const available=equipments 
-        /* +            .filter(e=>e.slot===key) 
-           On récupère uniquement les objets compatibles +            .filter(e=>canEquip(e,race)) 
-           avec le slot et la race. +            .sort((a,b)=> 
-            +                a.name.localeCompare( 
-           Puis on les trie par ordre alphabétique. +                    b.name, 
-            +                    "fr", 
-           localeCompare avec sensitivity:"base" permet +                    {sensitivity:"base"}
-           notamment de ne pas différencier : +
-             É / E +
-             é / e +
-             majuscule / minuscule +
-        */ +
- +
-        const availableEquipments = +
-            equipments +
- +
-                .filter( +
-                    e => e.slot === key+
                 )                 )
- 
-                .filter( 
-                    e => canEquip(e,race) 
-                ) 
- 
-                .sort( 
-                    (a,b) => 
-                        a.name.localeCompare( 
-                            b.name, 
-                            "fr", 
-                            { 
-                                sensitivity:"base" 
-                            } 
-                        ) 
-                ); 
- 
- 
-        availableEquipments.forEach(e=>{ 
- 
-            const o=document.createElement( 
-                "option" 
             );             );
  
-            o.value= +        available.forEach(item=>{
-                equipments.indexOf(e);+
  
-            o.textContent= +            const option=document.createElement("option");
-                e.name+ +
-                (e.exo ? " (exo)" : "");+
  
-            select.appendChild(o);+            option.value=String(equipments.indexOf(item)); 
 +            option.textContent=item.name+(item.exo?" (exo)":"");
  
 +            select.appendChild(option);
         });         });
- 
  
         select.onchange=()=>{         select.onchange=()=>{
- 
-            displayStats( 
-                select, 
-                statIds[key] 
-            ); 
  
             checkLimit(key);             checkLimit(key);
 +            displayAllEquipStats();
             calculate();             calculate();
         };         };
     }     }
- 
  
     displayAllEquipStats();     displayAllEquipStats();
- 
     checkLimit();     checkLimit();
- 
     calculate();     calculate();
 } }
  
 +/* AFFICHAGE DES BONUS */
  
-/* ========================================================= +const statNames = { 
-   AFFICHAGE DES CARACTERISTIQUES +    a:"A",f:"F",e:"E",agi:"Agi", 
-========================================================= */ +    cc:"CC",ct:"CT",fm:"FM",mvt:"Mvt", 
- +    pv:"PV",pm:"PM",r:"R",res:"Rés", 
-const statNames={ +    rm:"RM",p:"P",pui:"Pui",
- +
-    a:"A", +
- +
-    f:"F", +
-    e:"E", +
- +
-    agi:"Agi", +
- +
-    cc:"CC", +
-    ct:"CT", +
-    fm:"FM", +
- +
-    mvt:"Mvt", +
- +
-    pv:"PV", +
-    pm:"PM", +
- +
-    r:"R", +
-    res:"Rés", +
-    rm:"RM", +
- +
-    p:"P", +
-    pui:"Pui", +
     esquive:"Esquive",     esquive:"Esquive",
- 
     demolition:"Démolition",     demolition:"Démolition",
- 
     magique:"Magique",     magique:"Magique",
     feu:"Feu"     feu:"Feu"
 }; };
- 
  
 function displayStats(select,id){ function displayStats(select,id){
Ligne 1513: Ligne 643:
     const el=document.getElementById(id);     const el=document.getElementById(id);
  
-    if(!el){ +    if(!el) return;
-        return; +
-    } +
- +
- +
-    const index=select.value; +
- +
- +
-    if(index===""){+
  
 +    if(select.value===""){
         el.innerHTML="";         el.innerHTML="";
- 
         return;         return;
     }     }
  
 +    const item=equipments[Number(select.value)];
  
-    const e=equipments[ +    if(!item){
-        Number(index) +
-    ]; +
- +
- +
-    if(!e){ +
         el.innerHTML="";         el.innerHTML="";
- 
         return;         return;
     }     }
- 
  
     let html="";     let html="";
  
 +    for(const [stat,value] of Object.entries(item.stats||{})){
  
-    for( +        const name=statNames[stat]||stat;
-        const [stat,value] +
-        of Object.entries( +
-            e.stats || {} +
-        ) +
-    ){ +
- +
-        const name= +
-            statNames[stat] || +
-            stat; +
  
         if(value===true){         if(value===true){
- +            html+=`<span class="special">${name}</span> `;
-            html += +
-                `<span class="special">${name}</span> `; +
             continue;             continue;
         }         }
  
- +        if(typeof value!=="number"||value===0){
-        if( +
-            value===false || +
-            value===0 +
-        ){ +
             continue;             continue;
         }         }
- 
  
         if(value>0){         if(value>0){
- +            html+=`<span class="bonus">+${value} ${name}</span> `;
-            html += +
-                `<span class="bonus">+${value} ${name}</span> `; +
         }else{         }else{
- +            html+=`<span class="malus">${value} ${name}</span> `;
-            html += +
-                `<span class="malus">${value} ${name}</span> `; +
         }         }
     }     }
- 
  
     el.innerHTML=html;     el.innerHTML=html;
 } }
- 
  
 function displayAllEquipStats(){ function displayAllEquipStats(){
  
-    displayStats( +    for(const key in slots){ 
-        head, +        displayStats(slots[key],statIds[key]); 
-        "headStats" +    }
-    ); +
- +
-    displayStats( +
-        cape, +
-        "capeStats" +
-    ); +
- +
-    displayStats( +
-        rightHand, +
-        "rightStats" +
-    ); +
- +
-    displayStats( +
-        leftHand, +
-        "leftStats" +
-    ); +
- +
-    displayStats( +
-        body, +
-        "bodyStats" +
-    ); +
- +
-    displayStats( +
-        ring, +
-        "ringStats" +
-    ); +
- +
-    displayStats( +
-        feet, +
-        "feetStats" +
-    );+
 } }
- 
  
 /* ========================================================= /* =========================================================
-   LIMITE 3 EQUIPEMENTS + 1 ANNEAU+   LIMITE : 3 EQUIPEMENTS + 1 ANNEAU
 ========================================================= */ ========================================================= */
  
-function checkLimit( +function checkLimit(changedSlot=null){
-    changedSlot = null +
-){+
  
-    let count=0; +    const warn=document.getElementById("limitWarn");
- +
- +
-    for( +
-        const key in slots +
-    ){ +
- +
-        if(key==="ring"){ +
-            continue; +
-        } +
- +
- +
-        if( +
-            slots[key].value !== "" +
-        ){ +
- +
-            count++; +
-        } +
-    } +
- +
- +
-    const warn= +
-        document.getElementById( +
-            "limitWarn" +
-        );+
  
 +    const count=Object.keys(slots)
 +        .filter(key=>key!=="ring")
 +        .filter(key=>slots[key].value!=="")
 +        .length;
  
     if(count>3){     if(count>3){
  
-        if( +        if(changedSlot&&changedSlot!=="ring"){
-            changedSlot && +
-            changedSlot !== "ring" +
-        ){ +
- +
-            slots[ +
-                changedSlot +
-            ].value="";+
  
 +            slots[changedSlot].value="";
  
             displayStats(             displayStats(
                 slots[changedSlot],                 slots[changedSlot],
-                changedSlot+"Stats"+                statIds[changedSlot]
             );             );
         }         }
- 
- 
-        count--; 
- 
  
         warn.textContent=         warn.textContent=
-            "⚠️ Maximum 3 équipements hors anneau.";+            "⚠️ Maximum 3 équipements hors anneau. L'anneau est un emplacement supplémentaire.";
  
-    }else{+        return false; 
 +    }
  
-        warn.textContent=""; +    warn.textContent=""; 
-    }+    return true;
 } }
- 
- 
-/* ========================================================= 
-   RESET DES EQUIPEMENTS 
-========================================================= */ 
  
 function resetSlots(){ function resetSlots(){
  
-    for( +    for(const key in slots){
-        const key in slots +
-    ){ +
         slots[key].value="";         slots[key].value="";
     }     }
- 
  
     displayAllEquipStats();     displayAllEquipStats();
- 
     checkLimit();     checkLimit();
 } }
- 
  
 /* ========================================================= /* =========================================================
Ligne 1725: Ligne 740:
 function displayBase(){ function displayBase(){
  
-    const r= +    const r=races[raceSelect.value];
-        races[ +
-            raceSelect.value +
-        ]; +
- +
- +
-    const baseStats= +
-        document.getElementById( +
-            "baseStats" +
-        ); +
  
     let text="";     let text="";
- 
- 
-    /* 
-       Utilisation du même ordre que 
-       les améliorations et la fiche finale. 
-    */ 
  
     statOrder.forEach(stat=>{     statOrder.forEach(stat=>{
  
-        if( +        if(r[stat]!==undefined){
-            r[stat] !== undefined +
-        ){+
  
-            text += +            text+=(statLabels[stat]||stat)+": "+r[stat]+"\n";
-                ( +
-                    statLabels[stat] || +
-                    stat +
-                )+ +
-                ": "+ +
-                r[stat]+ +
-                "\n";+
         }         }
     });     });
  
- +    document.getElementById("baseStats").textContent=text.trim();
-    baseStats.textContent= +
-        text.trim();+
 } }
- 
  
 /* ========================================================= /* =========================================================
-   CALCUL DU COUT+   COUT
 ========================================================= */ ========================================================= */
  
 function calcCost(){ function calcCost(){
  
-    let total = 0;+    let total=0;
  
     for(const stat in costTable){     for(const stat in costTable){
  
-        const input = document.getElementById("up_"+stat);+        const input=document.getElementById("up_"+stat);
  
-        if(!input){ +        if(!input) continue;
-            continue; +
-        }+
  
-        const level = Math.max(0, parseInt(input.value) || 0); +        const level=Math.max(0,parseInt(input.value,10)||0);
-        const costs = costTable[stat];+
  
-        if(level === 0){ +        if(!level) continue;
-            continue; +
-        }+
  
-        const B = costs[0]; +        const [B,M1,M2]=costTable[stat];
-        const M1 = costs[1]; +
-        const M2 = costs[2];+
  
-        for(let n = 1; n <= level; n++){+        for(let n=1;n<=level;n++){
  
             let cost;             let cost;
  
-            if(n === 1){ +            if(n===1){ 
-                cost = B; +                cost=B; 
-            } +            }else if(n===2){ 
-            else if(n === 2){ +                cost=B+M1; 
-                cost = B + M1; +            }else if(n===3){ 
-            } +                cost=B+2*M1; 
-            else if(n === 3){ +            }else{ 
-                cost = B + 2 * M1; +                cost=B+2*M1+(n-3)*M2;
-            } +
-            else{ +
-                cost = B + 2 * M1 + (n - 3) * M2;+
             }             }
  
-            total += cost;+            total+=cost;
         }         }
     }     }
Ligne 1819: Ligne 796:
 } }
  
 +function updateCost(){
  
 +    document.getElementById("cost").textContent=
 +        "Coût total : "+calcCost();
 +}
  
 +/* =========================================================
 +   LECTURE DES PASSIFS
 +========================================================= */
  
-function updateCost(){+function isChecked(index){
  
-    document.getElementById( +    const cb=document.getElementById("skill_"+index);
-        "cost" +
-    ).textContent= +
-        "Coût total : "+ +
-        calcCost(); +
-}+
  
 +    return cb?cb.checked:false;
 +}
  
 /* ========================================================= /* =========================================================
-   CALCUL+   CALCUL DU PERSONNAGE
 ========================================================= */ ========================================================= */
  
 function calculate(){ function calculate(){
  
-    const race = races[raceSelect.value];+    const race=races[raceSelect.value];
  
     if(!race) return;     if(!race) return;
Ligne 1845: Ligne 826:
     displayBase();     displayBase();
  
-    // Copie des caractéristiques raciales +    const char={...race}; 
-    const char = {...race};+ 
 +    /* Améliorations */
  
-    // Améliorations 
     for(const stat in costTable){     for(const stat in costTable){
  
-        const input = document.getElementById("up_"+stat);+        const input=document.getElementById("up_"+stat);
  
         if(input){         if(input){
-            char[stat] = + 
-                (char[stat] || 0) + +            char[stat]= 
-                (parseInt(input.value) || 0);+                (char[stat]||0)+ 
 +                (parseInt(input.value,10)||0);
         }         }
     }     }
  
-    // Équipements +    /* Equipements */
-    const equipped = [];+
  
     for(const key in slots){     for(const key in slots){
  
-        const index = slots[key].value;+        const value=slots[key].value;
  
-        if(index === "") continue;+        if(value==="") continue;
  
-        const item = equipments[Number(index)];+        const item=equipments[Number(value)];
  
         if(!item) continue;         if(!item) continue;
  
-        equipped.push(item);+        for(const [stat,bonus] of Object.entries(item.stats||{})){
  
-        for(const [stat,value] of Object.entries(item.stats || {})){+            if(typeof bonus==="number"){
  
-            if(typeof value === "number"){ +                char[stat]=(char[stat]||0)+bonus;
-                char[stat] = (char[stat] || 0) + value;+
             }             }
         }         }
     }     }
  
-    // Passifs +    /* Passifs */
-    const fulgurance = isChecked(0); +
-    const couverture = isChecked(1); +
-    const reflexes = isChecked(2); +
-    const griffes = isChecked(4);+
  
-    // Griffes : mains nues ou ceste +    const fulgurance=isChecked(0); 
-    const mainDroite = rightHand.value === ""+    const couverture=isChecked(1); 
 +    const reflexes=isChecked(2); 
 +    const griffes=isChecked(4); 
 + 
 +    /* Griffes : mains nues ou Ceste */ 
 + 
 +    const mainDroite=rightHand.value===""
         ? null         ? null
         : equipments[Number(rightHand.value)];         : equipments[Number(rightHand.value)];
  
-    const mainsNues = mainDroite === null; +    const griffesActives= 
-    const cesteEquipee = mainDroite?.name === "Ceste"; +        griffes&&(!mainDroite||mainDroite.name==="Ceste");
- +
-    const griffesActives = +
-        griffes && (mainsNues || cesteEquipee);+
  
     if(griffesActives){     if(griffesActives){
-        char.f += 3;+        char.f+=3;
     }     }
  
-    // Sélection des meilleurs bonus de sorts +    /* Sorts : bonus de plus grande valeur absolue */
-    let bestDex = 0; +
-    let bestProt = 0; +
-    const spellDetails = [];+
  
-    spells.forEach((s,i)=>{+    let bestDex=0; 
 +    let bestProt=0;
  
-        const cb = document.getElementById("spell_"+i);+    const spellDetails=[];
  
-        if(cb && cb.checked){+    spells.forEach((spell,i)=>{
  
-            if(Math.abs(s.dex) > Math.abs(bestDex)){ +        const cb=document.getElementById("spell_"+i);
-                bestDex = s.dex; +
-            }+
  
-            if(Math.abs(s.prot) > Math.abs(bestProt)){ +        if(!cb||!cb.checked) return;
-                bestProt = s.prot; +
-            }+
  
-            spellDetails.push(s.name);+        if(Math.abs(spell.dex)>Math.abs(bestDex)){ 
 +            bestDex=spell.dex;
         }         }
 +
 +        if(Math.abs(spell.prot)>Math.abs(bestProt)){
 +            bestProt=spell.prot;
 +        }
 +
 +        spellDetails.push(spell.name);
     });     });
  
-    document.getElementById("spellBonus").textContent =+    document.getElementById("spellBonus").textContent=
         spellDetails.length         spellDetails.length
-        ? "Sorts actifs : " + spellDetails.join(", ") + +        ? "Sorts actifs : "+spellDetails.join(", ")+ 
-          " | Bonus Dex : " + bestDex + +          " | Bonus Dex : "+bestDex+ 
-          " | Protection : " + bestProt+          " | Protection : "+bestProt
         : "";         : "";
  
-    // Dés +    /* Dés */
-    const ccDice = char.cc * 2; +
-    const ctDice = char.ct * 2; +
-    const fmDice = char.fm * 2; +
-    const agiDice = char.agi * 2;+
  
-    // Résultats +    const ccDice=char.cc*2; 
-    let result = "=== PERSONNAGE ===\n\n";+    const ctDice=char.ct*2; 
 +    const fmDice=char.fm*2; 
 +    const agiDice=char.agi*2; 
 + 
 +    /* Fiche personnage */ 
 + 
 +    let result="=== PERSONNAGE ===\n\n";
  
     statOrder.forEach(stat=>{     statOrder.forEach(stat=>{
  
-        if(char[stat] !== undefined){+        if(char[stat]!==undefined){
  
-            result += +            result+= 
-                (statLabels[stat] || stat) + +                (statLabels[stat]||stat)+ 
-                ": " + char[stat] + "\n";+                ": "+char[stat]+"\n";
         }         }
     });     });
Ligne 1955: Ligne 937:
     if(griffes){     if(griffes){
  
-        result += griffesActives+        result+=griffesActives
             ? "\nGriffes : +3 F appliqué."             ? "\nGriffes : +3 F appliqué."
             : "\nGriffes : inactif (arme autre que ceste).";             : "\nGriffes : inactif (arme autre que ceste).";
     }     }
  
-    result += "\n\n=== COMBAT ===\n\n";+    result+="\n\n=== COMBAT ===\n\n";
  
-    // Touchers +    /* Touchers */
-    const finalCC = +
-        ccDice + bestDex + (fulgurance ? 1 : 0);+
  
-    const finalCT = +    const finalCC= 
-        ctDice + bestDex;+        ccDice+bestDex+(fulgurance?1:0);
  
-    const finalFM = +    const finalCT= 
-        fmDice + bestDex;+        ctDice+bestDex;
  
-    result += "Toucher CAC : " + finalCC + "\n"; +    const finalFM= 
-    result += "Toucher tir : " + finalCT + "\n"; +        fmDice+bestDex;
-    result += "FM : " + finalFM + "\n";+
  
-    // Tir selon distance +    result+="Toucher CAC : "+finalCC+"\n"; 
-    result += "\n=== TIR ===\n\n";+    result+="Toucher tir : "+finalCT+"\n"; 
 +    result+="FM : "+finalFM+"\n";
  
-    for(let cases=1; cases<=4; cases++){+    /* Tir par distance */
  
-        let ctDistance = finalCT;+    result+="\n=== TIR ===\n\n";
  
-        if(cases > 2){ +    for(let cases=1;cases<=4;cases++){ 
-            ctDistance -= (cases-2)*3;+ 
 +        let ctDistance=finalCT; 
 + 
 +        if(cases>2){ 
 +            ctDistance-=(cases-2)*3;
         }         }
  
-        result += cases + " case(s) : CT " + ctDistance + "\n";+        result+=cases+" case(s) : CT "+ctDistance+"\n";
     }     }
  
-    // Esquive CAC +    /* Esquive CAC */ 
-    const meleeDodge = + 
-        Math.max(ccDice,agiDice) + bestProt;+    const meleeDodge= 
 +        Math.max(ccDice,agiDice)+bestProt; 
 + 
 +    result+="\n=== ESQUIVE CAC ===\n\n"; 
 +    result+="Esquive : "+meleeDodge+"\n";
  
-    result += "\n=== ESQUIVE CAC ===\n\n"; +    /* Esquive tir */
-    result += "Esquive : " + meleeDodge + "\n";+
  
-    // Esquive tir 
     let evadeStat;     let evadeStat;
  
     if(couverture){     if(couverture){
  
-        evadeStat = Math.floor( +        evadeStat=Math.floor( 
-            char.cc * 0.85 + char.agi * 0.15+            char.cc*0.85+char.agi*0.15
         );         );
  
     }else if(reflexes){     }else if(reflexes){
  
-        evadeStat = Math.floor( +        evadeStat=Math.floor( 
-            char.agi * 0.85 + char.cc * 0.15+            char.agi*0.85+char.cc*0.15
         );         );
  
     }else{     }else{
  
-        evadeStat = Math.max( +        evadeStat=Math.max( 
-            Math.floor(char.cc * 0.75 + char.agi * 0.25), +            Math.floor(char.cc*0.75+char.agi*0.25), 
-            Math.floor(char.agi * 0.75 + char.cc * 0.25)+            Math.floor(char.agi*0.75+char.cc*0.25)
         );         );
     }     }
  
-    const fulguranceDodge = +    const fulguranceDodge= 
-        fulgurance ? Math.floor(char.mvt / 5) : 0;+        fulgurance?Math.floor(char.mvt/5):0; 
 + 
 +    const rangedDodge= 
 +        evadeStat*2+bestProt+fulguranceDodge; 
 + 
 +    result+="\n=== ESQUIVE TIR ===\n\n"; 
 +    result+="Esquive tir : "+rangedDodge+"\n";
  
-    const rangedDodge = +    /* Esquive FM */
-        evadeStat * 2 + +
-        bestProt + +
-        fulguranceDodge;+
  
-    result += "\n=== ESQUIVE TIR ===\n\n"; +    const fmDodge=fmDice+bestProt;
-    result += "Esquive tir : " + rangedDodge + "\n";+
  
-    // Esquive FM +    result+="\n=== ESQUIVE FM ===\n\n"; 
-    const fmDodge = fmDice + bestProt;+    result+="Esquive FM : "+fmDodge+"\n";
  
-    result += "\n=== ESQUIVE FM ===\n\n"; +    /* Magie */
-    result += "Esquive FM : " + fmDodge + "\n";+
  
-    // Magie +    result+="\n=== MAGIE ===\n\n"; 
-    result += "\n=== MAGIE ===\n\n"; +    result+="Jet FM : "+finalFM+"\n";
-    result += "Jet FM : " + finalFM + "\n";+
  
-    for(let lvl=1; lvl<=5; lvl++){+    for(let lvl=1;lvl<=5;lvl++){
  
-        const threshold = 6 + 6*lvl;+        const threshold=6+6*lvl;
  
-        result += +        result+= 
-            "Sort niveau " + lvl + +            "Sort niveau "+lvl+ 
-            " (seuil " + threshold + ") : " + +            " (seuil "+threshold+") : "+ 
-            (finalFM >= threshold ? "Réussi" : "Échec") ++            (finalFM>=threshold?"Réussi":"Échec")+
             "\n";             "\n";
     }     }
  
-    document.getElementById("result").textContent = result;+    document.getElementById("result").textContent=result;
 } }
  
 /* ========================================================= /* =========================================================
    SIMULATEUR DE POUSSEE    SIMULATEUR DE POUSSEE
 +   FORMULE CONSERVEE
 ========================================================= */ ========================================================= */
  
 function calculatePush(){ function calculatePush(){
  
-    const F= +    const F=parseInt( 
-        parseInt( +        document.getElementById("pushF").value,10 
-            document.getElementById( +    )||0;
-                "pushF" +
-            ).value +
-        ) || 0;+
  
 +    const E=parseInt(
 +        document.getElementById("pushE").value,10
 +    )||0;
  
-    const E= +    const Agi=parseInt( 
-        parseInt( +        document.getElementById("pushAgi").value,10 
-            document.getElementById( +    )||0;
-                "pushE" +
-            ).value +
-        ) || 0;+
  
 +    const PV=parseInt(
 +        document.getElementById("pushPV").value,10
 +    )||0;
  
-    const Agi= +    const buff=parseInt( 
-        parseInt( +        document.getElementById("pushBuff").value,10 
-            document.getElementById( +    )||0;
-                "pushAgi" +
-            ).value +
-        ) || 0;+
  
 +    const debuff=parseInt(
 +        document.getElementById("pushDebuff").value,10
 +    )||0;
  
-    const PV= +    const stab=parseInt( 
-        parseInt( +        document.getElementById("pushStab").value,10 
-            document.getElementById( +    )||0;
-                "pushPV" +
-            ).value +
-        ) || 0;+
  
 +    const finalF=F+buff+debuff+stab;
  
-    const buff= +    const score=finalF+E+Agi;
-        parseInt( +
-            document.getElementById( +
-                "pushBuff" +
-            ).value +
-        ) || 0;+
  
- +    document.getElementById("pushResult").textContent= 
-    const debuff= +        "Force finale : "+finalF+ 
-        parseInt( +        "\nEndurance : "+E+ 
-            document.getElementById( +        "\nAgilité : "+Agi+ 
-                "pushDebuff" +        "\nPV actuels : "+PV+ 
-            ).value +        "\n\nScore : "+score;
-        ) || 0; +
- +
- +
-    const stab= +
-        parseInt( +
-            document.getElementById( +
-                "pushStab" +
-            ).value +
-        ) || 0; +
- +
- +
-    const finalF= +
-        F+ +
-        buff+ +
-        debuff+ +
-        stab; +
- +
- +
-    const score= +
-        finalF+ +
-        E+ +
-        Agi; +
- +
- +
-    const result= +
-        "Force finale : "+ +
-        finalF+ +
-        "\n"+ +
-        "Endurance : "+ +
-        E+ +
-        "\n"+ +
-        "Agilité : "+ +
-        Agi+ +
-        "\n"+ +
-        "PV actuels : "+ +
-        PV+ +
-        "\n\n"+ +
-        "Score : "+ +
-        score; +
- +
- +
-    document.getElementById( +
-        "pushResult" +
-    ).textContent= +
-        result;+
 } }
  
- +/* EVENEMENTS POUSSEE */
-/* ========================================================= +
-   EVENEMENTS POUSSEE +
-========================================================= */+
  
 [ [
Ligne 2168: Ligne 1100:
 ].forEach(id=>{ ].forEach(id=>{
  
-    document.getElementById( +    const el=document.getElementById(id);
-        id +
-    ).addEventListener( +
-        "input", +
-        calculatePush +
-    );+
  
- +    el.addEventListener("input",calculatePush); 
-    document.getElementById( +    el.addEventListener("change",calculatePush);
-        id +
-    ).addEventListener( +
-        "change", +
-        calculatePush +
-    );+
 }); });
- 
  
 /* ========================================================= /* =========================================================
Ligne 2190: Ligne 1111:
  
 function resetAll(){ function resetAll(){
- 
-    /* 
-       Race 
-    */ 
  
     raceSelect.selectedIndex=0;     raceSelect.selectedIndex=0;
  
 +    statOrder.forEach(stat=>{
  
-    /* +        const input=document.getElementById("up_"+stat);
-       Améliorations +
-    */+
  
-    statOrder.forEach( +        if(input){ 
-        stat=>{ +            input.value=0;
- +
-            const input= +
-                document.getElementById( +
-                    "up_"+stat +
-                ); +
- +
- +
-            if(input){ +
- +
-                input.value=0; +
-            }+
         }         }
-    ); +    });
- +
- +
-    /* +
-       Equipements +
-    */+
  
     resetSlots();     resetSlots();
  
 +    skills.forEach((s,i)=>{
  
-    /* +        const cb=document.getElementById("skill_"+i);
-       Passifs +
-    */+
  
-    skills.forEach( +        if(cb){ 
-        (s,i)=>{ +            cb.checked=false;
- +
-            const cb= +
-                document.getElementById( +
-                    "skill_"+i +
-                ); +
- +
- +
-            if(cb){ +
-                cb.checked=false; +
-            }+
         }         }
-    );+    });
  
 +    spells.forEach((s,i)=>{
  
-    /* +        const cb=document.getElementById("spell_"+i);
-       Sorts +
-    */+
  
-    spells.forEach( +        if(cb){ 
-        (s,i)=>{ +            cb.checked=false;
- +
-            const cb= +
-                document.getElementById( +
-                    "spell_"+i +
-                ); +
- +
- +
-            if(cb){ +
-                cb.checked=false; +
-            }+
         }         }
-    ); +    });
- +
- +
-    /* +
-       Poussée +
-    */ +
- +
-    document.getElementById( +
-        "pushF" +
-    ).value=10; +
- +
- +
-    document.getElementById( +
-        "pushBuff" +
-    ).value=0; +
- +
- +
-    document.getElementById( +
-        "pushE" +
-    ).value=5; +
- +
- +
-    document.getElementById( +
-        "pushAgi" +
-    ).value=5; +
- +
- +
-    document.getElementById( +
-        "pushPV" +
-    ).value=50; +
- +
- +
-    document.getElementById( +
-        "pushDebuff" +
-    ).value=0; +
- +
- +
-    document.getElementById( +
-        "pushStab" +
-    ).value=0;+
  
 +    document.getElementById("pushF").value=10;
 +    document.getElementById("pushBuff").value=0;
 +    document.getElementById("pushE").value=5;
 +    document.getElementById("pushAgi").value=5;
 +    document.getElementById("pushPV").value=50;
 +    document.getElementById("pushDebuff").value=0;
 +    document.getElementById("pushStab").value=0;
  
     fillEquip();     fillEquip();
- 
     calculate();     calculate();
- 
     calculatePush();     calculatePush();
 } }
- 
  
 /* ========================================================= /* =========================================================
-   EXPORT+   EXPORT / IMPORT / PARTAGE
 ========================================================= */ ========================================================= */
  
-function exportBuild(){+function getBuildData(){
  
     const data={     const data={
- +        race:raceSelect.value,
-        race: +
-            raceSelect.value, +
         upgrades:{},         upgrades:{},
- 
         equipment:{},         equipment:{},
- 
         skills:[],         skills:[],
- 
         spells:[]         spells:[]
- 
     };     };
  
 +    statOrder.forEach(stat=>{
  
-    /* +        const input=document.getElementById("up_"+stat);
-       Améliorations +
-    */+
  
-    statOrder.forEach( +        if(input){ 
-        stat=>{ +            data.upgrades[stat]=parseInt(input.value,10)||0;
- +
-            const input= +
-                document.getElementById( +
-                    "up_"+stat +
-                ); +
- +
- +
-            if(input){ +
- +
-                data.upgrades[stat]= +
-                    parseInt( +
-                        input.value +
-                    ) || 0; +
-            }+
         }         }
-    );+    });
  
- +    for(const key in slots){ 
-    /* +        data.equipment[key]=slots[key].value;
-       Equipements +
-    */ +
- +
-    for( +
-        const key in slots +
-    ){ +
- +
-        data.equipment[key]= +
-            slots[key].value;+
     }     }
  
 +    skills.forEach((s,i)=>{
  
-    /* +        const cb=document.getElementById("skill_"+i);
-       Passifs +
-    */+
  
-    skills.forEach( +        if(cb&&cb.checked){ 
-        (s,i)=>{ +            data.skills.push(i);
- +
-            const cb= +
-                document.getElementById( +
-                    "skill_"+i +
-                ); +
- +
- +
-            if( +
-                cb && +
-                cb.checked +
-            ){ +
- +
-                data.skills.push(i); +
-            }+
         }         }
-    );+    });
  
 +    spells.forEach((s,i)=>{
  
-    /* +        const cb=document.getElementById("spell_"+i);
-       Sorts +
-    */+
  
-    spells.forEach( +        if(cb&&cb.checked){ 
-        (s,i)=>{ +            data.spells.push(i);
- +
-            const cb= +
-                document.getElementById( +
-                    "spell_"+i +
-                ); +
- +
- +
-            if( +
-                cb && +
-                cb.checked +
-            ){ +
- +
-                data.spells.push(i); +
-            }+
         }         }
-    );+    });
  
- +    return data;
-    const text= +
-        JSON.stringify( +
-            data, +
-            null, +
-            2 +
-        ); +
- +
- +
-    prompt( +
-        "Copiez cette configuration :", +
-        text +
-    );+
 } }
  
 +function applyBuildData(data){
  
-/* ========================================================= +    if(data.race&&races[data.race]){ 
-   IMPORT +        raceSelect.value=data.race; 
-========================================================= */+    }
  
-function importBuild(){+    if(data.upgrades){
  
-    const text= +        statOrder.forEach(stat=>{
-        prompt( +
-            "Collez la configuration :" +
-        );+
  
 +            const input=document.getElementById("up_"+stat);
  
-    if(!text){ +            if(input&&data.upgrades[stat]!==undefined){ 
-        return;+                input.value=data.upgrades[stat]; 
 +            } 
 +        });
     }     }
  
 +    fillEquip();
  
-    try{+    if(data.equipment){
  
-        const data= +        for(const key in slots){
-            JSON.parse(text);+
  
 +            if(data.equipment[key]!==undefined){
  
-        /* +                const wanted=String(data.equipment[key]);
-           Race +
-        */+
  
-        if( +                const exists=[...slots[key].options] 
-            data.race && +                    .some(option=>option.value===wanted);
-            races[data.race] +
-        ){+
  
-            raceSelect.value= +                if(exists){ 
-                data.race;+                    slots[key].value=wanted; 
 +                } 
 +            }
         }         }
 +    }
  
 +    skills.forEach((s,i)=>{
  
-        /* +        const cb=document.getElementById("skill_"+i);
-           Améliorations +
-        */+
  
-        if(data.upgrades){+        if(cb){ 
 +            cb.checked= 
 +                Array.isArray(data.skills)&& 
 +                data.skills.includes(i); 
 +        } 
 +    });
  
-            statOrder.forEach( +    spells.forEach((s,i)=>{
-                stat=>{+
  
-                    const input= +        const cb=document.getElementById("spell_"+i);
-                        document.getElementById( +
-                            "up_"+stat +
-                        );+
  
- +        if(cb){ 
-                    if( +            cb.checked= 
-                        input && +                Array.isArray(data.spells)&& 
-                        data.upgrades[stat] !== +                data.spells.includes(i);
-                        undefined +
-                    ){ +
- +
-                        input.value= +
-                            data.upgrades[stat]; +
-                    } +
-                } +
-            );+
         }         }
 +    });
  
 +    /* Corrige les configurations importées dépassant la limite */
  
-        /* +    let count=0;
-           Equipements +
-        */+
  
-        fillEquip();+    for(const key of [ 
 +        "head","cape","rightHand", 
 +        "leftHand","body","feet" 
 +    ]){
  
 +        if(slots[key].value!==""){
  
-        if(data.equipment){+            count++;
  
-            for( +            if(count>3){ 
-                const key in slots +                slots[key].value="";
-            ){ +
- +
-                if( +
-                    data.equipment[key] !== +
-                    undefined +
-                ){ +
- +
-                    slots[key].value= +
-                        data.equipment[key]; +
-                }+
             }             }
         }         }
 +    }
  
 +    displayAllEquipStats();
 +    checkLimit();
 +    calculate();
 +}
  
-        /* +function exportBuild(){
-           Passifs +
-        */+
  
-        skills.forEach( +    const text=JSON.stringify(getBuildData(),null,2);
-            (s,i)=>{+
  
-                const cb= +    prompt("Copiez cette configuration :",text); 
-                    document.getElementById( +}
-                        "skill_"+i +
-                    );+
  
 +function importBuild(){
  
-                if(cb){ +    const text=prompt("Collez la configuration :");
- +
-                    cb.checked= +
-                        Array.isArray( +
-                            data.skills +
-                        ) && +
-                        data.skills.includes(i); +
-                } +
-            } +
-        ); +
- +
- +
-        /* +
-           Sorts +
-        */ +
- +
-        spells.forEach( +
-            (s,i)=>{ +
- +
-                const cb= +
-                    document.getElementById( +
-                        "spell_"+i +
-                    ); +
- +
- +
-                if(cb){ +
- +
-                    cb.checked= +
-                        Array.isArray( +
-                            data.spells +
-                        ) && +
-                        data.spells.includes(i); +
-                } +
-            } +
-        ); +
- +
- +
-        displayAllEquipStats(); +
- +
-        checkLimit(); +
- +
-        calculate();+
  
 +    if(!text) return;
  
 +    try{
 +        applyBuildData(JSON.parse(text));
     }catch(e){     }catch(e){
- +        alert("Configuration invalide.");
-        alert( +
-            "Configuration invalide." +
-        );+
     }     }
 } }
- 
- 
-/* ========================================================= 
-   LIEN DE PARTAGE 
-========================================================= */ 
  
 function copyLink(){ function copyLink(){
  
-    const data={ +    const encoded=btoa( 
- +        encodeURIComponent(JSON.stringify(getBuildData()))
-        race: +
-            raceSelect.value, +
- +
-        upgrades:{}, +
- +
-        equipment:{}, +
- +
-        skills:[], +
- +
-        spells:[] +
- +
-    }; +
- +
- +
-    statOrder.forEach( +
-        stat=>{ +
- +
-            const input= +
-                document.getElementById( +
-                    "up_"+stat +
-                ); +
- +
- +
-            if(input){ +
- +
-                data.upgrades[stat]= +
-                    parseInt( +
-                        input.value +
-                    ) || 0; +
-            } +
-        }+
     );     );
- 
- 
-    for( 
-        const key in slots 
-    ){ 
- 
-        data.equipment[key]= 
-            slots[key].value; 
-    } 
- 
- 
-    skills.forEach( 
-        (s,i)=>{ 
- 
-            const cb= 
-                document.getElementById( 
-                    "skill_"+i 
-                ); 
- 
- 
-            if( 
-                cb && 
-                cb.checked 
-            ){ 
- 
-                data.skills.push(i); 
-            } 
-        } 
-    ); 
- 
- 
-    spells.forEach( 
-        (s,i)=>{ 
- 
-            const cb= 
-                document.getElementById( 
-                    "spell_"+i 
-                ); 
- 
- 
-            if( 
-                cb && 
-                cb.checked 
-            ){ 
- 
-                data.spells.push(i); 
-            } 
-        } 
-    ); 
- 
- 
-    const encoded= 
-        btoa( 
-            encodeURIComponent( 
-                JSON.stringify(data) 
-            ) 
-        ); 
- 
  
     const url=     const url=
         location.origin+         location.origin+
         location.pathname+         location.pathname+
-        "?build="+ +        "?build="+encoded;
-        encoded;+
  
 +    if(navigator.clipboard&&navigator.clipboard.writeText){
  
-    navigator.clipboard.writeText( +        navigator.clipboard.writeText(url) 
-        url +            .then(()=>alert("Lien copié dans le presse-papiers.")) 
-    );+            .catch(()=>prompt("Copiez ce lien :",url));
  
 +    }else{
  
-    alert( +        prompt("Copiez ce lien :",url); 
-        "Lien copié dans le presse-papiers." +    }
-    );+
 } }
- 
- 
-/* ========================================================= 
-   CHARGEMENT D'UN LIEN 
-========================================================= */ 
  
 function loadFromURL(){ function loadFromURL(){
  
-    const params= +    const params=new URLSearchParams(location.search);
-        new URLSearchParams( +
-            location.search +
-        );+
  
 +    const encoded=params.get("build");
  
-    const encoded= +    if(!encoded) return;
-        params.get("build"); +
- +
- +
-    if(!encoded){ +
-        return; +
-    } +
  
     try{     try{
  
-        const data= +        const data=JSON.parse( 
-            JSON.parse( +            decodeURIComponent(atob(encoded))
-                decodeURIComponent( +
-                    atob(encoded) +
-                ) +
-            ); +
- +
- +
-        if( +
-            data.race && +
-            races[data.race] +
-        ){ +
- +
-            raceSelect.value= +
-                data.race; +
-        } +
- +
- +
-        if(data.upgrades){ +
- +
-            statOrder.forEach( +
-                stat=>{ +
- +
-                    const input= +
-                        document.getElementById( +
-                            "up_"+stat +
-                        ); +
- +
- +
-                    if( +
-                        input && +
-                        data.upgrades[stat] !== +
-                        undefined +
-                    ){ +
- +
-                        input.value= +
-                            data.upgrades[stat]; +
-                    } +
-                } +
-            ); +
-        } +
- +
- +
-        fillEquip(); +
- +
- +
-        if(data.equipment){ +
- +
-            for( +
-                const key in slots +
-            ){ +
- +
-                if( +
-                    data.equipment[key] !== +
-                    undefined +
-                ){ +
- +
-                    slots[key].value= +
-                        data.equipment[key]; +
-                } +
-            } +
-        } +
- +
- +
-        skills.forEach( +
-            (s,i)=>{ +
- +
-                const cb= +
-                    document.getElementById( +
-                        "skill_"+i +
-                    ); +
- +
- +
-                if(cb){ +
- +
-                    cb.checked= +
-                        Array.isArray( +
-                            data.skills +
-                        ) && +
-                        data.skills.includes(i); +
-                } +
-            }+
         );         );
  
- +        applyBuildData(data);
-        spells.forEach( +
-            (s,i)=>{ +
- +
-                const cb= +
-                    document.getElementById( +
-                        "spell_"+i +
-                    ); +
- +
- +
-                if(cb){ +
- +
-                    cb.checked= +
-                        Array.isArray( +
-                            data.spells +
-                        ) && +
-                        data.spells.includes(i); +
-                } +
-            } +
-        ); +
- +
- +
-        displayAllEquipStats(); +
- +
-        checkLimit(); +
- +
-        calculate(); +
  
     }catch(e){     }catch(e){
  
-        console.log( +        console.log("Lien invalide");
-            "Lien invalide" +
-        );+
     }     }
 } }
- 
  
 /* ========================================================= /* =========================================================
Ligne 2858: Ligne 1357:
 ========================================================= */ ========================================================= */
  
-raceSelect.addEventListener( +raceSelect.addEventListener("change",()=>{
-    "change", +
-    ()=>{ +
- +
-        resetSlots(); +
- +
-        fillEquip(); +
- +
-        calculate(); +
-    } +
-);+
  
 +    resetSlots();
 +    fillEquip();
 +    calculate();
 +});
  
 /* ========================================================= /* =========================================================
Ligne 2876: Ligne 1369:
  
 fillEquip(); fillEquip();
- 
 displayBase(); displayBase();
- 
 calculate(); calculate();
- 
 calculatePush(); calculatePush();
- 
 loadFromURL(); loadFromURL();
  
simulateur_saison3_1.1790894294.txt.gz · Dernière modification : 2026/10/02 00:38 de nanaki