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/01 23:56] – 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
 ========================================================= */ ========================================================= */
  
Ligne 1776: Ligne 763:
     let total=0;     let total=0;
  
 +    for(const stat in costTable){
  
-    for( +        const input=document.getElementById("up_"+stat);
-        const stat in costTable +
-    ){+
  
-        const input= +        if(!input) continue;
-            document.getElementById( +
-                "up_"+stat +
-            );+
  
 +        const level=Math.max(0,parseInt(input.value,10)||0);
  
-        if(!input){ +        if(!level) continue;
-            continue; +
-        }+
  
 +        const [B,M1,M2]=costTable[stat];
  
-        let level= +        for(let n=1;n<=level;n++){
-            parseInt(input.value) || +
-            0;+
  
 +            let cost;
  
-        const costs= +            if(n===1){ 
-            costTable[stat];+                cost=B; 
 +            }else if(n===2){ 
 +                cost=B+M1; 
 +            }else if(n===3){ 
 +                cost=B+2*M1; 
 +            }else{ 
 +                cost=B+2*M1+(n-3)*M2; 
 +            }
  
- +            total+=cost;
-        /* +
-           Chaque niveau est payé séparément. +
- +
-           Exemple pour A : +
-           niveau 1 = 800 +
-           niveau 2 = 1000 +
- +
-           2A = 1800 PI +
-        */ +
- +
-        for( +
-            let i=0; +
-            i<level; +
-            i++ +
-        ){ +
- +
-            total += +
-                costs[ +
-                    Math.min( +
-                        i, +
-                        costs.length-1 +
-                    ) +
-                ];+
         }         }
     }     }
- 
  
     return total;     return total;
 } }
- 
  
 function updateCost(){ function updateCost(){
  
-    document.getElementById( +    document.getElementById("cost").textContent= 
-        "cost" +        "Coût total : "+calcCost();
-    ).textContent= +
-        "Coût total : "+ +
-        calcCost();+
 } }
  
 +/* =========================================================
 +   LECTURE DES PASSIFS
 +========================================================= */
 +
 +function isChecked(index){
 +
 +    const cb=document.getElementById("skill_"+index);
 +
 +    return cb?cb.checked:false;
 +}
  
 /* ========================================================= /* =========================================================
-   CALCUL+   CALCUL DU PERSONNAGE
 ========================================================= */ ========================================================= */
  
 function calculate(){ function calculate(){
  
-    const race= +    const race=races[raceSelect.value];
-        races[ +
-            raceSelect.value +
-        ]; +
- +
- +
-    if(!race){ +
-        return; +
-    }+
  
 +    if(!race) return;
  
     updateCost();     updateCost();
- 
     displayBase();     displayBase();
  
 +    const char={...race};
  
-    /* +    /* Améliorations */
-       Copie des stats raciales +
-    */+
  
-    const char={}; +    for(const stat in costTable){
- +
- +
-    for( +
-        const stat in race +
-    ){ +
- +
-        char[stat]= +
-            race[stat]; +
-    } +
- +
- +
-    /* +
-       Ajout des améliorations +
-    */ +
- +
-    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]=
-                (char[stat] || 0)+ +                (char[stat]||0)+ 
-                ( +                (parseInt(input.value,10)||0);
-                    parseInt( +
-                        input.value +
-                    ) || 0 +
-                );+
         }         }
     }     }
  
 +    /* Equipements */
  
-    /* +    for(const key in slots){
-       Ajout équipement +
-    */+
  
-    for( +        const value=slots[key].value;
-        const key in slots +
-    ){+
  
-        const index= +        if(value==="") continue;
-            slots[key].value;+
  
 +        const item=equipments[Number(value)];
  
-        if(index===""){ +        if(!item) continue;
-            continue; +
-        } +
- +
- +
-        const e= +
-            equipments[ +
-                Number(index) +
-            ]; +
- +
- +
-        if(!e){ +
-            continue; +
-        } +
  
-        for( +        for(const [stat,bonus] of Object.entries(item.stats||{})){
-            const [stat,value] +
-            of Object.entries( +
-                e.stats || {} +
-            ) +
-        ){+
  
-            if( +            if(typeof bonus==="number"){
-                typeof value === +
-                "number" +
-            ){+
  
-                char[stat]= +                char[stat]=(char[stat]||0)+bonus;
-                    (char[stat] || 0)+ +
-                    value;+
             }             }
         }         }
     }     }
  
 +    /* Passifs */
  
-    /* +    const fulgurance=isChecked(0); 
-       Sorts actifs +    const couverture=isChecked(1); 
-    */+    const reflexes=isChecked(2); 
 +    const griffes=isChecked(4);
  
-    let bestDex=0; +    /* Griffes : mains nues ou Ceste */
-    let bestProt=0;+
  
-    let spellDetails=[];+    const mainDroite=rightHand.value==="" 
 +        ? null 
 +        : equipments[Number(rightHand.value)];
  
 +    const griffesActives=
 +        griffes&&(!mainDroite||mainDroite.name==="Ceste");
  
-    spells.forEach( +    if(griffesActives){ 
-        (s,i)=>{+        char.f+=3; 
 +    }
  
-            const cb= +    /* Sorts : bonus de plus grande valeur absolue */
-                document.getElementById( +
-                    "spell_"+i +
-                );+
  
 +    let bestDex=0;
 +    let bestProt=0;
  
-            if( +    const spellDetails=[];
-                cb && +
-                cb.checked +
-            ){+
  
-                bestDex= +    spells.forEach((spell,i)=>{
-                    Math.max( +
-                        bestDex, +
-                        s.dex +
-                    );+
  
 +        const cb=document.getElementById("spell_"+i);
  
-                bestProt= +        if(!cb||!cb.checked) return;
-                    Math.max( +
-                        bestProt, +
-                        s.prot +
-                    );+
  
 +        if(Math.abs(spell.dex)>Math.abs(bestDex)){
 +            bestDex=spell.dex;
 +        }
  
-                spellDetails.push( +        if(Math.abs(spell.prot)>Math.abs(bestProt)){ 
-                    s.name +            bestProt=spell.prot;
-                ); +
-            }+
         }         }
-    ); 
  
 +        spellDetails.push(spell.name);
 +    });
  
-    document.getElementById( +    document.getElementById("spellBonus").textContent=
-        "spellBonus" +
-    ).textContent= +
         spellDetails.length         spellDetails.length
 +        ? "Sorts actifs : "+spellDetails.join(", ")+
 +          " | Bonus Dex : "+bestDex+
 +          " | Protection : "+bestProt
 +        : "";
  
-        ?+    /* Dés */
  
-        "Sorts actifs : "+ +    const ccDice=char.cc*2; 
-        spellDetails.join(", ")+ +    const ctDice=char.ct*2; 
-        " | Bonus Dex : "+ +    const fmDice=char.fm*2; 
-        bestDex+ +    const agiDice=char.agi*2;
-        " | Protection : "+ +
-        bestProt+
  
-        :+    /* Fiche personnage */
  
-        "";+    let result="=== PERSONNAGE ===\n\n";
  
 +    statOrder.forEach(stat=>{
  
-    /* +        if(char[stat]!==undefined){
-       Dés de caractéristiques +
-    */+
  
-    const ccDice= +            result+= 
-        char.cc*2; +                (statLabels[stat]||stat)+ 
- +                ": "+char[stat]+"\n";
-    const ctDice= +
-        char.ct*2; +
- +
-    const fmDice= +
-        char.fm*2; +
- +
-    const agiDice= +
-        char.agi*2; +
- +
- +
-    /* +
-       Résultats principaux +
-    */ +
- +
-    let result=""; +
- +
- +
-    result += +
-        "=== PERSONNAGE ===\n\n"; +
- +
- +
-    /* +
-       Même ordre que les stats +
-       de base et les améliorations. +
-    */ +
- +
-    statOrder.forEach( +
-        stat=>{ +
- +
-            if( +
-                char[stat] !== +
-                undefined +
-            ){ +
- +
-                result += +
-                    ( +
-                        statLabels[stat] || +
-                        stat +
-                    )+ +
-                    ": "+ +
-                    char[stat]+ +
-                    "\n"; +
-            }+
         }         }
-    );+    });
  
 +    if(griffes){
  
-    result += +        result+=griffesActives 
-        "\n=== COMBAT ===\n\n";+            ? "\nGriffes : +3 F appliqué." 
 +            : "\nGriffes : inactif (arme autre que ceste)."; 
 +    }
  
 +    result+="\n\n=== COMBAT ===\n\n";
  
-    /* +    /* Touchers */
-       CC / CT / FM +
-    */+
  
     const finalCC=     const finalCC=
-        ccDice+ +        ccDice+bestDex+(fulgurance?1:0);
-        bestDex; +
  
     const finalCT=     const finalCT=
-        ctDice+ +        ctDice+bestDex;
-        bestDex; +
  
     const finalFM=     const finalFM=
-        fmDice+ +        fmDice+bestDex;
-        bestDex;+
  
 +    result+="Toucher CAC : "+finalCC+"\n";
 +    result+="Toucher tir : "+finalCT+"\n";
 +    result+="FM : "+finalFM+"\n";
  
-    result += +    /* Tir par distance */
-        "Toucher CAC : "+ +
-        finalCC+ +
-        "\n";+
  
 +    result+="\n=== TIR ===\n\n";
  
-    result += +    for(let cases=1;cases<=4;cases++){
-        "Toucher tir : "+ +
-        finalCT+ +
-        "\n"; +
- +
- +
-    result += +
-        "FM : "+ +
-        finalFM+ +
-        "\n"; +
- +
- +
-    /* +
-       Tir selon distance +
-    */ +
- +
-    result += +
-        "\n=== TIR ===\n\n"; +
- +
- +
-    for( +
-        let cases=1; +
-        cases<=4; +
-        cases++ +
-    ){ +
- +
-        let ctDistance= +
-            finalCT;+
  
 +        let ctDistance=finalCT;
  
         if(cases>2){         if(cases>2){
- +            ctDistance-=(cases-2)*3;
-            ctDistance -= +
-                (cases-2)*3;+
         }         }
  
- +        result+=cases+" case(s) : CT "+ctDistance+"\n";
-        result += +
-            cases+ +
-            " case(s) : CT "+ +
-            ctDistance+ +
-            "\n";+
     }     }
  
 +    /* Esquive CAC */
  
-    /* +    const meleeDodge= 
-       Esquive CAC +        Math.max(ccDice,agiDice)+bestProt;
-    */+
  
-    let meleeDodge= +    result+="\n=== ESQUIVE CAC ===\n\n"; 
-        Math.max( +    result+="Esquive : "+meleeDodge+"\n";
-            ccDice, +
-            agiDice +
-        )+ +
-        bestProt;+
  
 +    /* Esquive tir */
  
-    /* +    let evadeStat;
-       Fulgurance +
-    */+
  
-    const fulg= +    if(couverture){ 
-        document.getElementById( + 
-            "skill_0"+        evadeStat=Math.floor( 
 +            char.cc*0.85+char.agi*0.15
         );         );
  
 +    }else if(reflexes){
  
-    if( +        evadeStat=Math.floor( 
-        fulg && +            char.agi*0.85+char.cc*0.15 
-        fulg.checked +        );
-    ){+
  
-        meleeDodge+=1;+    }else{ 
 + 
 +        evadeStat=Math.max( 
 +            Math.floor(char.cc*0.75+char.agi*0.25), 
 +            Math.floor(char.agi*0.75+char.cc*0.25) 
 +        );
     }     }
  
 +    const fulguranceDodge=
 +        fulgurance?Math.floor(char.mvt/5):0;
  
-    result += +    const rangedDodge= 
-        "\n=== ESQUIVE CAC ===\n\n";+        evadeStat*2+bestProt+fulguranceDodge;
  
 +    result+="\n=== ESQUIVE TIR ===\n\n";
 +    result+="Esquive tir : "+rangedDodge+"\n";
  
-    result += +    /* Esquive FM */
-        "Esquive : "+ +
-        meleeDodge+ +
-        "\n";+
  
 +    const fmDodge=fmDice+bestProt;
  
-    /* +    result+="\n=== ESQUIVE FM ===\n\n"; 
-       Esquive tir +    result+="Esquive FM : "+fmDodge+"\n";
-    */+
  
-    let rangedDodge= +    /* Magie */
-        agiDice+ +
-        bestProt;+
  
 +    result+="\n=== MAGIE ===\n\n";
 +    result+="Jet FM : "+finalFM+"\n";
  
-    result += +    for(let lvl=1;lvl<=5;lvl++){
-        "\n=== ESQUIVE TIR ===\n\n";+
  
 +        const threshold=6+6*lvl;
  
-    result += +        result+= 
-        "Esquive tir : "+ +            "Sort niveau "+lvl+ 
-        rangedDodge+ +            " (seuil "+threshold+") : "+ 
-        "\n";+            (finalFM>=threshold?"Réussi":"Échec")+ 
 +            "\n"; 
 +    }
  
- +    document.getElementById("result").textContent=result;
-    /* +
-       Affichage +
-    */ +
- +
-    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 2333: 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 2355: 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 3023: Ligne 1357:
 ========================================================= */ ========================================================= */
  
-raceSelect.addEventListener( +raceSelect.addEventListener("change",()=>{
-    "change", +
-    ()=>{ +
- +
-        resetSlots(); +
- +
-        fillEquip(); +
- +
-        calculate(); +
-    } +
-);+
  
 +    resetSlots();
 +    fillEquip();
 +    calculate();
 +});
  
 /* ========================================================= /* =========================================================
Ligne 3041: Ligne 1369:
  
 fillEquip(); fillEquip();
- 
 displayBase(); displayBase();
- 
 calculate(); calculate();
- 
 calculatePush(); calculatePush();
- 
 loadFromURL(); loadFromURL();
  
simulateur_saison3_1.1790891790.txt.gz · Dernière modification : 2026/10/01 23:56 de nanaki