Outils pour utilisateurs

Outils du site


brouillon3

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
brouillon3 [2026/04/18 22:17] nanakibrouillon3 [2026/05/12 13:53] (Version actuelle) nanaki
Ligne 1: Ligne 1:
-===== Liste des Sorts =====+Voici un simulateur en version beta, n'hésitez pas à faire vos remarques sur le discord ou le forum.
  
-Un complément d'information sur certains sorts a été ajouté après le tableau de sorts. 
  
 <html> <html>
 <head> <head>
 <meta charset="UTF-8"> <meta charset="UTF-8">
-<title>Compétences — Techniques & Sorts</title> +<title>Simulateur RPG</title>
-<style> +
-body { font-family: Arial, sans-serif; margin: 10px; } +
-h3 { text-align: center; } +
-.table-container { width: 100%; overflow-x: auto; margin-top: 10px; } +
-table { width: 100%; border-collapse: collapse; min-width: 1200px; } +
-th, td { padding: 8px; border: 1px solid #ccc; text-align: left; } +
-th { background: #f2f2f2; } +
-tbody tr:nth-child(odd) { background: #fafafa; } +
-tbody tr:nth-child(even) { background: #ffffff; }+
  
-/* Couleurs par race */ +<style> 
-td.race-Communs { color: #555; } +body { 
-td.race-Nain { color: red; } +  font-family: Arial; 
-td.race-Géant colorsaddlebrown; } +  background:#0b1a13; 
-td.race-Olympien colordarkorange; } +  color:#7dd3fc; 
-td.race-HS { color: darkgreen; } +  padding:10px; 
-td.race-Elfe { color: green; }+
 +h1,h2 { color:gold;} 
 +.box border:1px solid gold; padding:10px; margin-bottom:10px; } 
 +select { margin:3px; max-width:150px;
 +input margin:3px; width:60px; } 
 +.statLine { display:flex; justify-content:space-between; max-width:260px;
 +.result background:#000; color:#00ffcc; padding:10px; white-space:pre-wrap; } 
 +.small font-size:12px; color:#aaa; }
 </style> </style>
 </head> </head>
 +
 <body> <body>
  
-<!-- ================= TABLEAU 1 : sorts ================= --> +<h1>🎲 Simulateur</h1>
-<h3>Gestion des compétences — sorts</h3> +
-<label for="raceSelect1">Choisir une race :</label> +
-<select id="raceSelect1"> +
-  <option value="Toutes">Toutes</option> +
-  <option value="Communs">Communs</option> +
-  <option value="Nain">Nain</option> +
-  <option value="Géant">Géant</option> +
-  <option value="Olympien">Olympien</option> +
-  <option value="HS">HS</option> +
-  <option value="Elfe">Elfe</option> +
-</select>+
  
-<div class="table-container"> +<div class="box"> 
-<table id="competencesTable1"> +Race : 
-<thead+<select id="race"></select
-<tr> +<h3>Stats de base</h3
-<th>Race</th><th>Nom de la compétence</th><th>Type</th><th>Catégorie</th+<pre id="baseStats"></pre
-<th>Coût (PM)</th><th>Bonus / Malus</th><th>Cible</th><th>Portée</th+</div>
-<th>Description</th><th>Cumulable</th><th>Prix</th> +
-</tr> +
-</thead> +
-  <tbody>+
  
-<!-- ================= COMMUNS ================= -->+<div class="box"> 
 +<h3>Améliorations</h3> 
 +<div id="stats"></div> 
 +<div id="cost"></div> 
 +</div>
  
 +<div class="box">
 +<h3>Équipement (3 max + 1 anneau)</h3>
 +Tête <select id="head"></select> <span id="headStats"></span><br>
 +Cou <select id="neck"></select> <span id="neckStats"></span><br>
 +Dos <select id="cape"></select> <span id="capeStats"></span><br>
 +Main droite <select id="rightHand"></select> <span id="rightStats"></span><br>
 +Main gauche <select id="leftHand"></select> <span id="leftStats"></span><br>
 +Corps <select id="body"></select> <span id="bodyStats"></span><br>
 +Anneau <select id="ring"></select> <span id="ringStats"></span><br>
 +Pieds <select id="feet"></select> <span id="feetStats"></span>
 +<div id="limitWarn" style="color:red;"></div>
 +</div>
  
-<tr class="Communs"> +<div class="box"> 
-<td class="race-Communs">Communs</td><td>Arcane ajustée</td><td>Sort</td><td>Offensif</td+<h3>Passifs</h3
-<td>6 MP</td><td>Avantage au toucher</td><td>Autre</td><td>min 2</td> +<div id="skills"></div
-<td>Donne l’avantage au toucher</td><td>/</td><td>50 pos</td+</div>
-</tr>+
  
-<tr class="Communs"> +<div class="box"> 
-<td class="race-Communs">Communs</td><td>Arcanes précises</td><td>Sort</td><td>Offensif</td+<h3>Sorts actifs</h3
-<td>6 MP</td><td>+4 au toucher</td><td>Autre</td><td>min 2</td+<div id="spells"></div
-<td>Bonus de +4 pour toucher</td><td>/</td><td>50 pos</td+<div id="spellBonus" class="small"></div
-</tr>+</div>
  
-<tr class="Communs"> 
-<td class="race-Communs">Communs</td><td>Arcanes violentes</td><td>Sort</td><td>Offensif</td> 
-<td>6 MP</td><td>-6 au toucher, +5 dégâts</td><td>Autre</td><td>min 2</td> 
-<td>Malus de -6 pour toucher, bonus +5 dégâts</td><td>/</td><td>50 pos</td> 
-</tr> 
  
-<tr class="Communs"> 
-<td class="race-Communs">Communs</td><td>Aveuglement</td><td>Sort</td><td>Malédiction</td> 
-<td>4 MP</td><td>-1 P</td><td>Autre</td><td>min 2</td> 
-<td>Aveuglement (x1)</td><td>non cumulable</td><td>50 pos</td> 
-</tr> 
  
-<tr class="Communs"+<!-- ================= POUSSEE ================= --
-<td class="race-Communs">Communs</td><td>Coup précis</td><td>Sort</td><td>Bénédiction</td+<div class="box"> 
-<td>4 MP</td><td>Dextérité (x2)</td><td>Autre / Soi-même</td><td>max 1</td> +<h3>Simulateur de poussée</h3>
-<td>Dextérité (x2)</td><td>non cumulable</td><td>50 pos</td> +
-</tr>+
  
-<tr class="Communs"> +Force assaillant <input id="pushF" type="number" value="10"> 
-<td class="race-Communs">Communs</td><td>Épuisement arcanique</td><td>Sort</td><td>Malédiction</td> +Renforcement <select id="pushBuff"><option value="0">0</option><option value="6">+6</option></select><br>
-<td>4 MP</td><td>Essoufflement (X/3)</td><td>Autre</td><td>min 2</td> +
-<td>Réduction d’endurance</td><td>/</td><td>50 pos</td> +
-</tr>+
  
-<tr class="Communs"> +Endurance <input id="pushE" type="number" value="5"> 
-<td class="race-Communs">Communs</td><td>Maladresse</td><td>Sort</td><td>Malédiction</td> +Agilité <input id="pushAgi" type="number" value="5"><br>
-<td>4 MP</td><td>Maladresse (x2)</td><td>Autre</td><td>min 2</td> +
-<td>Réduit la précision</td><td>non cumulable</td><td>50 pos</td> +
-</tr>+
  
-<tr class="Communs"+PV actuels <input id="pushPVtype="number" value="50"><br>
-<td class="race-Communs">Communs</td><td>Peau de granit</td><td>Sort</td><td>Bénédiction</td> +
-<td>4 MP</td><td>Protection (x2)</td><td>Autre / Soi-même</td><td>max 1</td> +
-<td>Renforce la défense</td><td>non cumulable</td><td>50 pos</td> +
-</tr>+
  
-<tr class="Communs"> +Instabilité <select id="pushDebuff"><option value="0">0</option><option value="-6">-6</option></select
-<td class="race-Communs">Communs</td><td>Restauration mineure</td><td>Sort</td><td>Bénédiction</td+Stabilité <select id="pushStab"><option value="0">0</option><option value="6">+6</option><option value="12">+12</option><option value="18">+18</option></select>
-<td>6 MP</td><td>-5 malus</td><td>Autre / Soi-même</td><td>max 1</td> +
-<td>Réduit les malus</td><td>/</td><td>50 pos</td> +
-</tr>+
  
-<tr class="Communs"+<pre id="pushResult" class="result"></pre
-<td class="race-Communs">Communs</td><td>Vulnérabilité</td><td>Sort</td><td>Malédiction</td> +</div>
-<td>6 MP</td><td>Vulnérabilité (x2)</td><td>Autre</td><td>min 2</td> +
-<td>Augmente les dégâts subis</td><td>non cumulable</td><td>50 pos</td+
-</tr>+
  
-<tr class="Communs"> +<button onclick="resetAll()">Reset</button>
-<td class="race-Communs">Communs</td><td>Agressivité</td><td>Sort</td><td>Bénédiction</td> +
-<td>6 MP</td><td>Agressivité (x1)</td><td>Autre / Soi-même</td><td>max 1</td> +
-<td>Augmente l’agressivité</td><td>non cumulable</td><td>100 pos</td> +
-</tr>+
  
-<tr class="Communs"> +<button onclick="exportBuild()">📤 Export</button
-<td class="race-Communs">Communs</td><td>Armure</td><td>Sort</td><td>Bénédiction</td+<button onclick="importBuild()">📥 Import</button
-<td>8 MP</td><td>Armure (x1)</td><td>Autre / Soi-même</td><td>max 1</td> +<button onclick="copyLink()">🔗 Lien</button>
-<td>Renforce la défense</td><td>non cumulable</td><td>100 pos</td> +
-</tr>+
  
-<tr class="Communs"+<pre id="result" class="result"></pre>
-<td class="race-Communs">Communs</td><td>Colère de la nature</td><td>Sort</td><td>Malédiction</td> +
-<td>8 MP</td><td>Maladresse (x2), Vulnérabilité (x2)</td><td>Autre</td><td>min 2</td> +
-<td>Affaiblissement combiné</td><td>cumulable</td><td>100 pos</td> +
-</tr>+
  
-<tr class="Communs"> +<script>
-<td class="race-Communs">Communs</td><td>Drain</td><td>Sort</td><td>Offensif</td> +
-<td>6 MP</td><td>Vol de PV</td><td>Autre</td><td>min 2</td> +
-<td>Récupère une partie des dégâts</td><td>/</td><td>100 pos</td> +
-</tr>+
  
-<tr class="Communs"> +// ===== RACES ====
-<td class="race-Communs">Communs</td><td>Faiblesse</td><td>Sort</td><td>Malédiction</td> +const races { 
-<td>MP</td><td>Faiblesse (x1)</td><td>Autre</td><td>min 2</td> +Elfe:{a:2,cc:9,ct:10,f:9,e:4,agi:9,p:5,mvt:5,pv:55,pm:30,r:4,rm:6,fm:8,m:6}, 
-<td>Réduit les capacités</td><td>non cumulable</td><td>100 pos</td> +Nain:{a:2,cc:11,ct:8,f:11,e:6,agi:6,p:4,mvt:4,pv:50,pm:15,r:5,rm:4,fm:10,m:3}, 
-</tr>+Géant:{a:2,cc:9,ct:10,f:12,e:4,agi:7,p:4,mvt:5,pv:65,pm:20,r:5,rm:5,fm:6,m:5}, 
 +Olympien:{a:2,cc:10,ct:9,f:10,e:5,agi:8,p:4,mvt:5,pv:60,pm:30,r:5,rm:6,fm:7,m:5}, 
 +HS:{a:2,cc:8,ct:9,f:7,e:3,agi:11,p:5,mvt:6,pv:45,pm:40,r:3,rm:7,fm:9,m:5} 
 +};
  
-<tr class="Communs"> +// ===== COST ====
-<td class="race-Communs">Communs</td><td>Fragilité</td><td>Sort</td><td>Malédiction</td> +const costTable { 
-<td>10 MP</td><td>Fragilité (x1)</td><td>Autre</td><td>min 2</td> +a:[800,200,100], 
-<td>Augmente les dégâts subis</td><td>non cumulable</td><td>100 pos</td> +cc:[100,50,30], ct:[110,50,30], 
-</tr>+f:[120,55,30], e:[120,55,30], 
 +agi:[95,45,25], 
 +m:[110,55,35], 
 +fm:[100,50,30], 
 +p:[110,85,78], 
 +pv:[4,2,1], 
 +pm:[5,3,1], 
 +mvt:[100,50,30], 
 +r:[40,30,15], 
 +rm:[50,40,20] 
 +};
  
-<tr class="Communs"> +// ===== PASSIFS ===== 
-<td class="race-Communs">Communs</td><td>Instabilité</td><td>Sort</td><td>Malédiction</td> +const skills = [ 
-<td>6 MP</td><td>Instabilité (x6)</td><td>Autre</td><td>min 2</td> +{name:"Fulgurance",desc:"+1 toucher au cac + 1 esquive tous les 5 mouvements"}, 
-<td>Effet instable</td><td>cumulable</td><td>100 pos</td> +{name:"Couverture",desc:"85% CC 15% AGI"}, 
-</tr>+{name:"Réflexes fulgurants",desc:"85% AGI 15% CC"}, 
 +{name:"Berserker",desc:"+1 toucher au cac tous les 10 pv perdus"}, 
 +{name:"Griffes",desc:"+3 dégâts au poings"}, 
 +{name:"Anguille",desc:"Avantage esquive"
 +];
  
-<tr class="Communs"> +// ===== SORTS ===== 
-<td class="race-Communs">Communs</td><td>Migraine</td><td>Sort</td><td>Malédiction</td> +const spells = [ 
-<td>4 MP</td><td>Dégâts mentaux</td><td>Autre</td><td>min 2</td> +{name:"Peau de granit",dex:0,prot:2}, 
-<td>Inflige des dégâts mentaux</td><td>/</td><td>100 pos</td> +{name:"Coup précis",dex:2,prot:0},
-</tr>+
  
-<tr class="Communs"> +{name:"Maladresse",dex:-2,prot:0}, 
-<td class="race-Communs">Communs</td><td>Puissance de la nature</td><td>Sort</td><td>Bénédiction</td> +{name:"Vulnérabilité",dex:0,prot:-2},
-<td>8 MP</td><td>Dextérité + Protection</td><td>Autre / Soi-même</td><td>/</td> +
-<td>Boost multiple</td><td>cumulable</td><td>100 pos</td> +
-</tr>+
  
-<tr class="Communs"+{name:"Puissance de la nature",dex:2,prot:2},
-<td class="race-Communs">Communs</td><td>Régénération</td><td>Sort</td><td>Bénédiction</td> +
-<td>4 MP</td><td>Soin (R/2)</td><td>Autre / Soi-même</td><td>/</td> +
-<td>Soins basés sur R</td><td>/</td><td>100 pos</td> +
-</tr>+
  
-<tr class="Communs"> +{name:"Aide",dex:4,prot:0}, 
-<td class="race-Communs">Communs</td><td>Renforcement</td><td>Sort</td><td>Bénédiction</td> +{name:"Malchance",dex:-4,prot:0},
-<td>6 MP</td><td>Renforcement (x6)</td><td>Autre / Soi-même</td><td>/</td> +
-<td>Boost global</td><td>cumulable</td><td>100 pos</td> +
-</tr>+
  
-<tr class="Communs"> +{name:"Fatigue",dex:0,prot:-4}, 
-<td class="race-Communs">Communs</td><td>Restauration</td><td>Sort</td><td>Bénédiction</td> +{name:"Réflexes accrus",dex:0,prot:4},
-<td>6 MP</td><td>Restauration (R/2)</td><td>Autre / Soi-même</td><td>/</td> +
-<td>Restaure selon R</td><td>/</td><td>100 pos</td> +
-</tr>+
  
-<tr class="Communs"+{name:"Bénédiction",dex:4,prot:4},
-<td class="race-Communs">Communs</td><td>Siphon</td><td>Sort</td><td>Offensif</td> +
-<td>0 MP5 PV2 Mvt</td><td>Vol de PM</td><td>Autre</td><td>min 2</td> +
-<td>Convertit dégâts en PM</td><td>/</td><td>100 pos</td> +
-</tr>+
  
-<tr class="Communs"+{name:"Puissance du lutin capricieux",dex:-4,prot:-4},
-<td class="race-Communs">Communs</td><td>Stabilisation</td><td>Sort</td><td>Bénédiction</td> +
-<td>2 MP1 Mvt</td><td>Stabilité +6</td><td>Autre / Soi-même</td><td>/</td> +
-<td>Stabilise</td><td>/</td><td>100 pos</td> +
-</tr>+
  
-<tr class="Communs"> +{name:"Exténuation",dex:0,prot:-8}, 
-<td class="race-Communs">Communs</td><td>Aide</td><td>Sort</td><td>Bénédiction</td> +{name:"Sauvegarde",dex:0,prot:8}, 
-<td>MP</td><td>Dextérité (x4)</td><td>Autre / Soi-même</td><td>/</td> +{name:"Guigne",dex:-8,prot:0}, 
-<td>Boost fort</td><td>non cumulable</td><td>200 pos</td> +{name:"Virtuose",dex:8,prot:0} 
-</tr>+];
  
-<tr class="Communs"> 
-<td class="race-Communs">Communs</td><td>Fatigue</td><td>Sort</td><td>Malédiction</td> 
-<td>12 MP</td><td>Vulnérabilité (x4)</td><td>Autre</td><td>min 2</td> 
-<td>Affaiblissement fort</td><td>non cumulable</td><td>200 pos</td> 
-</tr> 
  
-<tr class="Communs"> 
-<td class="race-Communs">Communs</td><td>Malchance</td><td>Sort</td><td>Malédiction</td> 
-<td>8 MP</td><td>Maladresse (x4)</td><td>Autre</td><td>min 2</td> 
-<td>Réduit précision</td><td>non cumulable</td><td>200 pos</td> 
-</tr> 
  
-<tr class="Communs"> +const equipments [
-<td class="race-Communs">Communs</td><td>Récupération</td><td>Sort</td><td>Bénédiction</td> +
-<td>4 MP</td><td>Soin (R/2)</td><td>Autre</td><td>max 1</td> +
-<td>Soigne</td><td>non cumulable</td><td>200 pos</td> +
-</tr>+
  
-<tr class="Communs"> +/* ================= COMMUNS ================= */
-<td class="race-Communs">Communs</td><td>Réflexes accrus</td><td>Sort</td><td>Bénédiction</td> +
-<td>8 MP</td><td>Protection (x4)</td><td>Autre / Soi-même</td><td>max 1</td> +
-<td>Boost défense</td><td>non cumulable</td><td>200 pos</td> +
-</tr>+
  
-<tr class="Communs"> +{name:"Arc",race:"all",slot:"weapon2h",stats:{cc:-1,ct:1}}, 
-<td class="race-Communs">Communs</td><td>Régénération accélérée</td><td>Sort</td><td>Bénédiction</td> +{name:"Armure matelassée",race:"all",slot:"body",stats:{e:1,agi:-2}}, 
-<td>10 MP</td><td>Soin (R)</td><td>Autre / Soi-même</td><td>max 1</td> +{name:"Bâton de marche",race:"all",slot:"weapon",stats:{mvt:1}}, 
-<td>Soins puissants</td><td>non cumulable</td><td>200 pos</td> +{name:"Bottes de marche",race:"all",slot:"feet",stats:{mvt:1}}, 
-</tr>+{name:"Bouclier Parma",race:"all",slot:"offhand",stats:{e:1,agi:-2}}, 
 +{name:"Fustibale",race:"all",slot:"weapon",stats:{cc:-2,ct:1}}, 
 +{name:"Gladius",race:"all",slot:"weapon",stats:{cc:1}}, 
 +{name:"Sceptre",race:"all",slot:"weapon",stats:{fm:1}}, 
 +{name:"Lance",race:"all",slot:"weapon",stats:{ct:1,cc:-1}}, 
 +{name:"Targe",race:"all",slot:"offhand",stats:{cc:1,agi:-1}}, 
 +{name:"Visière",race:"all",slot:"head",stats:{p:1,cc:-1,fm:-1}}, 
 +{name:"Cape de chasse",race:"all",slot:"cape",stats:{ct:1}}, 
 +{name:"Collier tressé",race:"all",slot:"neck",stats:{pv:5,pm:5}}, 
 +{name:"Couronne d'Adonis",race:"all",slot:"head",stats:{rm:1}}, 
 +{name:"Ceinture",race:"all",slot:"body",stats:{r:1}}, 
 +{name:"Arc long",race:"all",slot:"weapon2h",stats:{ct:2,f:-1,cc:-2}}, 
 +{name:"Targe renforcée",race:"all",slot:"offhand",stats:{cc:1,pv:10}},
  
-<tr class="Communs"> +/* ===== NOUVEAUX COMMUNS ===== */
-<td class="race-Communs">Communs</td><td>Restauration majeure</td><td>Sort</td><td>Bénédiction</td> +
-<td>12 MP</td><td>Restauration (R)</td><td>Autre / Soi-même</td><td>/</td> +
-<td>Restaure complètement</td><td>/</td><td>200 pos</td> +
-</tr>+
  
-<tr class="Communs"> +{name:"Torche",race:"all",slot:"weapon",stats:{cc:-2,f:-2}}, 
-<td class="race-Communs">Communs</td><td>Anémie</td><td>Sort</td><td>Malédiction</td> +{name:"Hache de jet",race:"all",slot:"weapon",stats:{ct:1}}, 
-<td>12 MP</td><td>Faiblesse (x2)</td><td>Autre</td><td>max 1</td> +{name:"Pierre Noire",race:"all",slot:"weapon",stats:{f:1,cc:-1}}, 
-<td>Affaiblissement sévère</td><td>non cumulable</td><td>300 pos</td> +{name:"Main-gauche offensive",race:"all",slot:"offhand",stats:{cc:2,f:-1}},
-</tr>+
  
-<tr class="Communs"> +/* ================= ELFES ================= */
-<td class="race-Communs">Communs</td><td>Bénédiction</td><td>Sort</td><td>Bénédiction</td> +
-<td>15 MP</td><td>Protection + Dextérité (x4)</td><td>Autre / Soi-même</td><td>max 1</td> +
-<td>Boost complet</td><td>non cumulable</td><td>300 pos</td> +
-</tr>+
  
-<tr class="Communs"> +{name:"Bâton du Pèlerin",race:"all",slot:"weapon",stats:{mvt:1,fm:1}}, 
-<td class="race-Communs">Communs</td><td>Cuirasse</td><td>Sort</td><td>Bénédiction</td> +{name:"Bottes Tâlroval",race:"all",slot:"feet",stats:{mvt:2}}, 
-<td>15 MP</td><td>Armure (x2)</td><td>Autre / Soi-même</td><td>max 1</td> +{name:"Cuirasse",race:"all",slot:"body",stats:{e:1,r:2}}, 
-<td>Défense élevée</td><td>non cumulable</td><td>300 pos</td> +{name:"Lance de garde Sylvestre",race:"all",slot:"weapon",stats:{cc:1,f:1}}, 
-</tr>+{name:"Sceptre de mage",race:"all",slot:"weapon2h",stats:{m:1,fm:1}}, 
 +{name:"Arc Ensorcelé",race:"all",slot:"weapon2h",stats:{ct:1,rm:2,cc:-1}}, 
 +{name:"Armure de garde Sylvestre",race:"all",slot:"body",stats:{e:2,mvt:-1},magicBlock:true}, 
 +{name:"Toge de feuillage",race:"all",slot:"body",stats:{fm:1,agi:1,pv:5}}, 
 +{name:"Marque Forestière",race:"all",slot:"neck",stats:{pm:10,r:1}}, 
 +{name:"Capuche du chasseur",race:"all",slot:"head",stats:{ct:1,r:1}},
  
-<tr class="Communs"> +// spécifique elfe 
-<td class="race-Communs">Communs</td><td>Férocité</td><td>Sort</td><td>Bénédiction</td> +{name:"Arc Elfique",race:"Elfe",slot:"weapon2h",stats:{ct:2,cc:-1}},
-<td>12 MP</td><td>Agressivité (x2)</td><td>Autre / Soi-même</td><td>max 1</td> +
-<td>Offensive renforcée</td><td>non cumulable</td><td>300 pos</td> +
-</tr>+
  
-<tr class="Communs"> +/* ================= NAINS ================= */
-<td class="race-Communs">Communs</td><td>Friabilité</td><td>Sort</td><td>Malédiction</td> +
-<td>20 MP</td><td>Fragilité (x2)</td><td>Autre</td><td>min 2</td> +
-<td>Extrêmement fragile</td><td>non cumulable</td><td>300 pos</td> +
-</tr>+
  
-<tr class="Communs"> +{name:"Cotte de mailles",race:"all",slot:"body",stats:{e:2,agi:-4}}, 
-<td class="race-Communs">Communs</td><td>Puissance du lutin capricieux</td><td>Sort</td><td>Malédiction</td> +{name:"Labrys",race:"all",slot:"weapon",stats:{cc:1,f:1}}, 
-<td>20 MP</td><td>Maladresse + Vulnérabilité (x4)</td><td>Autre</td><td>min 2</td> +{name:"Marteau de guerre",race:"all",slot:"weapon2h",stats:{f:2,cc:-1}}, 
-<td>Double malédiction</td><td>non cumulable</td><td>300 pos</td> +{name:"Targe renforcée naine",race:"all",slot:"offhand",stats:{cc:1,pv:10}}, 
-</tr>+{name:"Armure runique",race:"all",slot:"body",stats:{e:1,pm:8}}, 
 +{name:"Cape dorée",race:"all",slot:"cape",stats:{m:1,fm:1},magicBlock:true}, 
 +{name:"Solerets",race:"all",slot:"feet",stats:{mvt:1,pm:5,pv:5}}, 
 +{name:"Casque grossissant",race:"all",slot:"head",stats:{ct:2,p:-1}},
  
-<tr class="Communs"> +// spécifiques nains 
-<td class="race-Communs">Communs</td><td>Récupération supérieure</td><td>Sort</td><td>Bénédiction</td> +{name:"Bâton d'archimage",race:"Nain",slot:"weapon2h",stats:{m:2,fm:-1}}, 
-<td>10 MP</td><td>Soin (R)</td><td>Autre / Soi-même</td><td>max 1</td> +{name:"Hache runique",race:"Nain",slot:"weapon",stats:{cc:1,f:2}},
-<td>Soins complets</td><td>non cumulable</td><td>300 pos</td> +
-</tr>+
  
-<tr class="Communs"> +/* ================= GÉANTS ================= */
-<td class="race-Communs">Communs</td><td>Exténuation</td><td>Sort</td><td>Malédiction</td> +
-<td>25 MP</td><td>Vulnérabilité (x8)</td><td>Autre</td><td>min 2</td> +
-<td>Vulnérabilité (x8)</td><td>/</td><td>300 pos</td> +
-</tr>+
  
-<tr class="Communs"> +{name:"Bouclier Clipeus",race:"all",slot:"offhand",stats:{e:1,pv:10}}, 
-<td class="race-Communs">Communs</td><td>Guigne</td><td>Sort</td><td>Malédiction</td> +{name:"Masse d'arme",race:"all",slot:"weapon",stats:{cc:1,f:1}}, 
-<td>20 MP</td><td>Maladresse (x8)</td><td>Autre</td><td>min 2</td> +{name:"Hallebarde de pierre",race:"all",slot:"weapon",stats:{cc:2,f:-1}}, 
-<td>Maladresse (x8)</td><td>/</td><td>300 pos</td> +{name:"Bâton de shaman",race:"Géant",slot:"weapon2h",stats:{fm:2,pv:-5}}, 
-</tr>+{name:"Javelot lourd",race:"all",slot:"weapon",stats:{f:2,ct:-1,cc:-1}}, 
 +{name:"Broigne",race:"all",slot:"body",stats:{e:2,f:-1}}, 
 +{name:"Fétiche de shaman",race:"all",slot:"offhand",stats:{r:2,pm:5}}, 
 +{name:"Bottes incandescentes",race:"all",slot:"feet",stats:{mvt:1,r:1,pv:5}}, 
 +{name:"Médaillon hanté",race:"all",slot:"neck",stats:{cc:1,ct:1}},
  
-<tr class="Communs"> +// spécifique géant 
-<td class="race-Communs">Communs</td><td>Sauvegarde</td><td>Sort</td><td>Bénédiction</td> +{name:"Peau de granit manifiée",race:"Géant",slot:"body",stats:{m:1,rm:2,agi:-2}},
-<td>20 MP</td><td>Protection (x8)</td><td>Autre / Soi-même</td><td>max 1</td> +
-<td>Protection (x8)</td><td>/</td><td>300 pos</td> +
-</tr>+
  
-<tr class="Communs"> +/* ================= HS ================= */
-<td class="race-Communs">Communs</td><td>Virtuose</td><td>Sort</td><td>Bénédiction</td> +
-<td>20 MP</td><td>Dextérité (x8)</td><td>Autre / Soi-même</td><td>max 1</td> +
-<td>Dextérité (x8)</td><td>/</td><td>300 pos</td> +
-</tr>+
  
-<!-- ================= RACES ================= -->+{name:"Bâton de sage",race:"all",slot:"weapon2h",stats:{m:1,agi:1}}, 
 +{name:"Orbe de mana",race:"all",slot:"weapon2h",stats:{m:1,rm:1}}, 
 +{name:"Cape de mage",race:"all",slot:"cape",stats:{fm:1,rm:1}}, 
 +{name:"Armure de fourrure",race:"all",slot:"body",stats:{e:2,rm:-3}}, 
 +{name:"Ceste",race:"all",slot:"weapon",stats:{f:1,cc:1}}, 
 +{name:"Collier d'apaisement",race:"all",slot:"neck",stats:{pv:10,pm:5}}, 
 +{name:"Bottes de voleur",race:"all",slot:"feet",stats:{mvt:1,agi:1}}, 
 +{name:"Sarbacane",race:"all",slot:"weapon",stats:{ct:1,f:10,cc:-1}}, 
 +{name:"Bouclier en lianes",race:"all",slot:"offhand",stats:{cc:1,agi:1}},
  
 +// spécifiques HS
 +{name:"Manteau de feuillage",race:"HS",slot:"body",stats:{e:1,agi:2}},
 +{name:"Bottes griffues",race:"HS",slot:"feet",stats:{cc:1,f:1,pv:5}},
  
-<tr class="HS"> +/* ================= OLYMPIENS ================= */
-<td class="race-HS">HS</td><td>Dard</td><td>Sort</td><td>Offensif</td> +
-<td>3 PM</td><td>+1</td><td>Autre</td><td>min 2</td> +
-<td>Projette un dard sur l'adversaire.</td><td>/</td><td>100 po</td> +
-</tr>+
  
-<tr class="HS"> +{name:"Armure hoplitique",race:"all",slot:"body",stats:{e:1,m:1}}, 
-<td class="race-HS">HS</td><td>Aiguillon</td><td>Sort</td><td>Offensif</td> +{name:"Bouclier Ancile",race:"all",slot:"offhand",stats:{e:1}}, 
-<td>4 PM</td><td>+3</td><td>Autre</td><td>min 2</td> +{name:"Diadème",race:"all",slot:"head",stats:{r:1,rm:2}}, 
-<td>Projette un aiguillon sur l’adversaire.</td><td>/</td><td>100 po</td> +{name:"Pilum",race:"all",slot:"weapon",stats:{ct:1,f:1,cc:-1}}, 
-</tr>+{name:"Spatha",race:"all",slot:"weapon",stats:{cc:1,f:1}}, 
 +{name:"Sceptre de puissance",race:"all",slot:"weapon",stats:{m:1,pm:8}}, 
 +{name:"Lame Sainte",race:"all",slot:"weapon",stats:{cc:1,m:1}}, 
 +{name:"Tiare d'Oracle",race:"all",slot:"head",stats:{fm:1,p:1}}, 
 +{name:"Cnémides",race:"all",slot:"feet",stats:{mvt:1,rm:1,r:1}},
  
-<tr class="HS"> +// spécifique olympien 
-<td class="race-HS">HS</td><td>Flux Vital</td><td>Sort</td><td>Bénédiction</td> +{name:"Lorica",race:"Olympien",slot:"body",stats:{e:2,agi:-2}},
-<td>6 PM</td><td></td><td>Soi-même</td><td>0</td> +
-<td>Puise dans la régénération magique pour se soigner.</td><td>/</td><td>100 po</td> +
-</tr>+
  
 +/* ================= ANNEAUX ================= */
  
-<tr class="HS"> +{name:"Anneau Caprice",race:"all",slot:"ring",stats:{fm:1}}, 
-<td class="race-HS">HS</td><td>Arme Vivante *</td><td>Sort</td><td>Offensif</td> +{name:"Anneau Férocité",race:"all",slot:"ring",stats:{f:1}}, 
-<td>12 PM</td><td>+M</td><td>Autre</td><td>max 1</td> +{name:"Anneau Horizon",race:"all",slot:"ring",stats:{p:1}}, 
-<td>Ajoute des dégâts magiques à une attaque avec une arme composée de bois (pétrifié ou non). La caractéristique de touche pour ce sort est la CC.</td><td>/</td><td>300 po</td> +{name:"Anneau Prétention",race:"all",slot:"ring",stats:{ct:1}}, 
-</tr>+{name:"Anneau Souplesse",race:"all",slot:"ring",stats:{agi:1}}, 
 +{name:"Anneau Tenacité",race:"all",slot:"ring",stats:{e:1}}, 
 +{name:"Anneau Puissance",race:"all",slot:"ring",stats:{m:1}}, 
 +{name:"Anneau Finesse",race:"all",slot:"ring",stats:{cc:1}}
  
-<tr class="HS"> +];
-<td class="race-HS">HS</td><td>Taillade illusoire</td><td>Sort</td><td>Offensif</td> +
-<td>10 PM</td><td>+6</td><td>Autre</td><td>max 3</td> +
-<td>Des crocs et des griffes spectraux assaillent votre adversaire de toute part.</td><td>/</td><td>300 po</td> +
-</tr>+
  
-<tr class="Elfe"> 
-<td class="race-Elfe">Elfe</td><td>Aiguillon</td><td>Sort</td><td>Offensif</td> 
-<td>4 PM</td><td>+3</td><td>Autre</td><td>min 2</td> 
-<td>Projette un aiguillon sur l’adversaire.</td><td>/</td><td>100 po</td> 
-</tr> 
  
-<tr class="Elfe"> +// ===== INIT ====
-<td class="race-Elfe">Elfe</td><td>Flèche Aquatique</td><td>Sort</td><td>Offensif</td> +const raceSelect document.getElementById("race"); 
-<td>5 PM</td><td>+3 + effet Eau</td><td>Autre</td><td>min 2</td> +const statsDiv = document.getElementById("stats"); 
-<td> Projette une flèche composée d'eau sur l'adversaire.</td><td>effet non cumulable</td><td>100 po</td> +const baseDiv = document.getElementById("baseStats");
-</tr>+
  
-<tr class="Elfe"> +for(let r in races){ 
-<td class="race-Elfe">Elfe</td><td>Lien de Vie</td><td>Sort</td><td>Bénédiction</td+raceSelect.innerHTML +`<option>${r}</option>`; 
-<td>6 PM</td><td></td><td>Autre</td><td>max 1</td> +}
-<td>Soigne via régénération magique.</td><td>/</td><td>100 po</td> +
-</tr>+
  
-<tr class="Elfe"> +// stats UI 
-<td class="race-Elfe">Elfe</td><td>Trait Béni *</td><td>Sort</td><td>Offensif</td+for(let s in costTable){ 
-<td>12 PM</td><td>+M</td><td>Autre</td><td>min 2</td+statsDiv.innerHTML +` 
-<td>Ajoute des dégâts magiques lors d'une attaque au tir. La caractéristique de touche pour ce sort est la CT. L'attaquant fait en dégâts F+M et la cible encaisse avec E+M.</td><td>/</td><td>300 po</td+<div class="statLine"> 
-</tr>+<span>${s}</span
 +<input type="number" id="${s}" value="0" min="0"
 +</div>`; 
 +}
  
-<tr class="Elfe"> +// passifs 
-<td class="race-Elfe">Elfe</td><td>Glaciation</td><td>Sort</td><td>Offensif</td+skills.forEach(s=>{ 
-<td>8 PM</td><td>+6</td><td>Autre</td><td>max 2</td+document.getElementById("skills").innerHTML += ` 
-<td>Vous devenez froids comme l'hiver et propagez cette froideur à un ennemi proche.</td><td>/</td><td>300 po</td+<label
-</tr>+<input type="checkbox" class="skill" data-name="${s.name}"> 
 +<b>${s.name}</b><br
 +<span class="small">${s.desc}</span> 
 +</label><br>`; 
 +});
  
-<tr class="Géant"> 
-<td class="race-Géant">Géant</td><td>Aiguillon</td><td>Sort</td><td>Offensif</td> 
-<td>4 PM</td><td>+3</td><td>Autre</td><td>min 2</td> 
-<td>Projette un aiguillon sur l’adversaire.</td><td>/</td><td>100 po</td> 
-</tr> 
  
-<tr class="Géant"> +// affichage sorts 
-<td class="race-Géant">Géant</td><td>Boule de Magma</td><td>Sort</td><td>Offensif</td+spells.forEach(s=>{ 
-<td>7 PM</td><td>+3 + effet Feu</td><td>Autre</td><td>min 2</td+document.getElementById("spells").innerHTML += ` 
-<td>Lance une boule de lave en fusion sur l'adversaire, qui prend feu.</td><td>effet non cumulable</td><td>100 po</td+<label
-</tr>+<input type="checkbox" class="spell" data-dex="${s.dex}" data-prot="${s.prot}"> 
 +<b>${s.name}</b>  
 +<span class="small">(Dex ${s.dex>=0?"+":""}${s.dex} | Prot ${s.prot>=0?"+":""}${s.prot})</span
 +</label><br>`; 
 +});
  
-<tr class="Géant"> +// base stats 
-<td class="race-Géant">Géant</td><td>Régénération</td><td>Sort</td><td>Bénédiction</td> +function displayBase(){ 
-<td>6 PM</td><td></td><td>Autre</td><td>max 1</td> +baseDiv.textContent = JSON.stringify(races[raceSelect.value],null,2); 
-<td>Régénère la santé d'une cible au corps à corpsLa cible est soignée à la hauteur de la R du lanceurinflige poison au lanceur.</td><td>/</td><td>100 po</td> +
-</tr>+raceSelect.addEventListener("change", displayBase); 
 +displayBase();
  
-<tr class="Géant"> +// ===== COST ====
-<td class="race-Géant">Géant</td><td>Météore *</td><td>Sort</td><td>Offensif</td> +function calcCost(b,m1,m2,n){ 
-<td>12 PM</td><td>+effet Feu</td><td>Autre</td><td>min 2</td> +let total=0,last=b; 
-<td>Ajoute des dégâts magiques et de feu à une attaque au jet de pierre. La caractéristique de touche pour ce sort est la CT. Une pierre doit être équipée pour lancer le sort. L'attaquant fait en dégâts F+M et la cible encaisse avec E+M.</td><td>effet non cumulable</td><td>300 po</td> +for(let i=1;i<=n;i++){ 
-</tr>+if(i===1) last=b; 
 +else if(i<=3) last+=m1; 
 +else last+=m2; 
 +total+=last; 
 +
 +return total; 
 +}
  
-<tr class="Géant"> +function updateCost(){ 
-<td class="race-Géant">Géant</td><td>Souffle des cimes</td><td>Sort</td><td>Offensif</td> +let total=0; 
-<td>8 PM</td><td>+6</td><td>Autre</td><td>max 2</td> +for(let s in costTable){ 
-<td>Imprégné de la puissance de l'oragevous rugissez un flot de foudre sur votre adversaire.</td><td>/</td><td>300 po</td> +let v=+document.getElementById(s).value||0; 
-</tr>+let [b,m1,m2]=costTable[s]; 
 +total+=calcCost(b,m1,m2,v); 
 +
 +document.getElementById("cost").innerHTML="💰 PI : "+total; 
 +}
  
 +// ===== SLOTS =====
 +const slots = {
 +head:head,neck:neck,cape:cape,rightHand:rightHand,
 +leftHand:leftHand,body:body,ring:ring,feet:feet
 +};
  
-<tr class="Nain"> +function resetSlots(){ 
-<td class="race-Nain">Nain</td><td>Pic de Pierre</td><td>Sort</td><td>Offensif</td+Object.values(slots).forEach(s=>s.innerHTML="<option value=''>--</option>"); 
-<td>4 PM</td><td>+3</td><td>Autre</td><td>min 2</td> +}
-<td>Projette un pic de pierre sur l’adversaire.</td><td>/</td><td>100 po</td> +
-</tr>+
  
-<tr class="Nain"> +function fillEquip(){ 
-<td class="race-Nain">Nain</td><td>Poings de Pierre</td><td>Sort</td><td>Offensif</td> +let r=raceSelect.value;
-<td>8 PM</td><td>+8</td><td>Autre</td><td>max 1</td> +
-<td>Vos poings deviennent durs comme de la roche millénaire, que vous abattez sur vos ennemis.</td><td>/</td><td>300 po</td> +
-</tr>+
  
 +equipments.forEach((e,i)=>{
 +if(e.race!=="all"&&e.race!==r) return;
  
-<tr class="Olympien"+if(e.slot==="weapon"||e.slot==="weapon2h") rightHand.innerHTML+=`<option value="${i}">${e.name}</option>`; 
-<td class="race-Olympien">Olympien</td><td>Lame Volante</td><td>Sort</td><td>Offensif</td+if(e.slot==="offhand") leftHand.innerHTML+=`<option value="${i}">${e.name}</option>`; 
-<td>4 PM</td><td>+3</td><td>Autre</td><td>min 2</td+if(e.slot==="body") body.innerHTML+=`<option value="${i}">${e.name}</option>`; 
-<td>Projette une lame magique sur l'adversaire.</td><td>/</td><td>100 po</td+if(e.slot==="head") head.innerHTML+=`<option value="${i}">${e.name}</option>`; 
-</tr>+if(e.slot==="neck") neck.innerHTML+=`<option value="${i}">${e.name}</option>`; 
 +if(e.slot==="cape") cape.innerHTML+=`<option value="${i}">${e.name}</option>`; 
 +if(e.slot==="feet") feet.innerHTML+=`<option value="${i}">${e.name}</option>`; 
 +if(e.slot==="ring") ring.innerHTML+=`<option value="${i}">${e.name}</option>`; 
 +}); 
 +}
  
-<tr class="Olympien"+raceSelect.addEventListener("change",()=>{ 
-<td class="race-Olympien">Olympien</td><td>Imposition des Mains</td><td>Sort</td><td>Bénédiction</td+resetSlots(); 
-<td>7 PM</td><td>+3</td><td>Autre</td><td>max 1</td> +fillEquip(); 
-<td>Toucher magique pour soigner un blessé.</td><td>/</td><td>100 po</td> +autoCalculate(); 
-</tr>+});
  
-<tr class="Olympien"> +resetSlots(); 
-<td class="race-Olympien">Olympien</td><td>Lame Bénie *</td><td>Sort</td><td>Offensif</td> +fillEquip();
-<td>12 PM</td><td>+M</td><td>Autre</td><td>max 1</td> +
-<td>Ajoute des dégâts magiques lors d'une attaque de mêlée. La caractéristique de touche pour ce sort est la CC. L'attaquant fait en dégâts F+M et la cible encaisse avec E+M. </td><td>/</td><td>300 po</td> +
-</tr>+
  
-<tr class="Olympien"> +// ===== BONUS ===== 
-<td class="race-Olympien">Olympien</td><td>Soumission divine</td><td>Sort</td><td>Offensif</td> +function displayStats(select,id){ 
-<td>8 PM</td><td>+6</td><td>Autre</td><td>max 2</td+let v=select.value; 
-<td>Vous vous approchez de votre cible et déferlez un torrent d'énergie divine dans sa direction.</td><td>/</td><td>300 po</td> +let el=document.getElementById(id); 
-</tr>+if(v===""){el.innerHTML="";return;
 +let e=equipments[v]; 
 +let txt=""; 
 +for(let s in e.stats){ 
 +let val=e.stats[s]; 
 +txt+=val>0?`+${val} ${s} `:`${val} ${s} `; 
 +
 +el.innerHTML=txt; 
 +}
  
-</tbody> +const slotToStatId = { 
-</table> +head:"headStats", 
-</div>+neck:"neckStats", 
 +cape:"capeStats", 
 +rightHand:"rightStats", 
 +leftHand:"leftStats", 
 +body:"bodyStats", 
 +ring:"ringStats", 
 +feet:"feetStats" 
 +};
  
 +Object.entries(slots).forEach(([k,s])=>{
 +s.addEventListener("change",()=>{
 +displayStats(s, slotToStatId[k]);
 +checkLimit();
 +autoCalculate();
 +});
 +});
  
-<script> +// ===== LIMIT ===== 
-// Script pour le premier tableau +function checkLimit(){ 
-const select1 document.getElementById("raceSelect1"); +let count=0; 
-const rows1 document.querySelectorAll("#competencesTable1 tbody tr");+Object.entries(slots).forEach(([k,s])=>{ 
 +if(k!=="ring"&&s.value!=="") count++; 
 +});
  
-select1.addEventListener("change", () => +if(count>=3){ 
-  const chosenRace select1.value+limitWarn.innerText="Limite atteinte"
-  rows1.forEach(row => { +Object.entries(slots).forEach(([k,s])=>{ 
-    const isCommun row.classList.contains("Communs"); +if(k!=="ring"&&s.value===""s.disabled=true;
-    const isRace = row.classList.contains(chosenRace); +
-    row.style.display = (chosenRace === "Toutes|| isCommun || isRace) ? "" : "none"; +
-  });+
 }); });
-</script>+}else{ 
 +limitWarn.innerText=""; 
 +Object.values(slots).forEach(s=>s.disabled=false); 
 +
 +}
  
-<hr>+// ===== CALCUL =====
  
-<!-- ================= TABLEAU 2 : Sorts ================= --> +function calculate(){
-<h3>Gestion des compétences — Techniques Corps à corps</h3> +
-<label for="raceSelect2">Choisir une race :</label> +
-<select id="raceSelect2"> +
-  <option value="Toutes">Toutes</option> +
-  <option value="Communs">Communs</option> +
-  <option value="Nain">Nain</option> +
-  <option value="Géant">Géant</option> +
-  <option value="Olympien">Olympien</option> +
-  <option value="HS">HS</option> +
-  <option value="Elfe">Elfe</option> +
-</select>+
  
-<div class="table-container"+let activeSpells [...document.querySelectorAll(".spell:checked")];
-<table id="competencesTable2"> +
-<thead> +
-<tr> +
-<th>Race</th><th>Nom</th><th>Type</th><th>Catégorie</th> +
-<th>Coût</th><th>Bonus / Malus</th><th>Cible</th><th>Portée</th> +
-<th>Description</th><th>Cumulable</th><th>Prix</th> +
-</tr> +
-</thead> +
-<tbody>+
  
-    <!-- ===== COMMUNS ===== --> +let bestDex 0; 
-      <tr class="Communs"><td class="race-Communs">Communs</td><td>Epuisement</td><td>Technique</td><td>Contact</td><td>/</td><td><span style="color: red;">Essouflement(X/2)</span></td><td>Autre</td><td>max 1</td><td>Ne fait pas de dégâts. Jet de CC pur. Essouflement(X/2) où X est la différence des jets de dés.</td><td>effet immédiat, gain immédiat des malus, pas de statut, cumul possible</td><td>50 pos</td></tr> +let bestProt 0;
-      <tr class="Communs"><td class="race-Communs">Communs</td><td>Attaque précise</td><td>Technique</td><td>Contact</td><td>2 PM</td><td>+4 toucher, -3 dégâts</td><td>Autre</td><td>max 1</td><td>Bonus de +4 pour toucher, -3 dégâts.</td><td>/</td><td>50 pos</td></tr> +
-      <tr class="Communs"><td class="race-Communs">Communs</td><td>Attaque violente</td><td>Technique</td><td>Contact</td><td>4 PM</td><td>-6 toucher, +3 dégâts</td><td>Autre</td><td>max 1</td><td>Malus de -6 pour toucher, +3 dégâts.</td><td>/</td><td>50 pos</td></tr> +
-      <tr class="Communs"><td class="race-Communs">Communs</td><td>Croc-en-jambe</td><td>Technique</td><td>Contact</td><td>6 PM</td><td>Ralentissement(x2D2)</td><td>Autre</td><td>max 1</td><td>Ralentissement(x2D2)</td><td>non cumulable</td><td>100 pos</td></tr> +
-      <tr class="Communs"><td class="race-Communs">Communs</td><td>Manchette</td><td>Technique</td><td>Contact</td><td>2 PM</td><td>Maladresse(xX/2)</td><td>Autre</td><td>max 1</td><td>Ne fait pas de dégâts. Jet de CC pur. Si l'attaque touche, la cible aura Maladresse(xX/2) où X est la différence des jets de dés</td><td>non cumulable</td><td>100 pos</td></tr> +
-      <tr class="Communs"><td class="race-Communs">Communs</td><td>Arme infusée</td><td>Technique</td><td>Contact</td><td>8 PM</td><td>M/3</td><td>Autre</td><td>max 1</td><td>Bonus de +M/3 dégâts.</td><td>/</td><td>200 pos</td></tr>+
  
-    <!-- ===== NAINS ===== --+activeSpells.forEach(s=>{ 
-          <tr class="Nain"><td class="race-Nain">Nain</td><td>Assomoir</td><td>Technique</td><td>Contact</td><td>7 PM</td><td>+4</td><td>Autre</td><td>max 1</td><td>Ignore le casque (chance de critique)Jet basé sur CC.</td>/<td></td><td>200 po</td></tr> +let d = +s.dataset.dex; 
-      <tr class="Nain"><td class="race-Nain">Nain</td><td>Barbier</td><td>Technique</td><td>Contact</td><td>8 PM</td><td></td><td>Autre</td><td>max 1</td><td>Soigne une cible au corps à corps ( la statistique utilisée pour le soin est l'agilité du lanceur)</td><td>/</td><td>100 po</td></tr> +let p = +s.dataset.prot;
-      <tr class="Nain"><td class="race-Nain">Nain</td><td>Clé de bras</td><td>Technique</td><td>Contact</td><td>7 PM</td><td></td><td>Soi-même</td><td>0</td><td>Pare la prochaine attaque de mếlée et immobilise l'adversaire (uniquement à Mains nues).</td><td>/</td><td>200 po</td></tr> +
-      <tr class="Nain"><td class="race-Nain">Nain</td><td>Attaque Sautée</td><td>Technique</td><td>Contact</td><td>12 PM</td><td>+M</td><td>Autre</td><td>min 2</td><td>Avec une arme de mêlée, déplace immédiatement le personnage au contact de la cible et lui inflige des dégâts magiquesPour ce sort, la carac de touche est la CCL'attaquant fait en dégâts F+M et la cible encaisse avec E+M. </td><td>/</td><td>300 po</td></tr>+
  
-    <!-- ===== GÉANTS ===== --> +if(Math.abs(d) Math.abs(bestDex)) bestDex d; 
-    <tr class="Géant"> +if(Math.abs(p) > Math.abs(bestProt)) bestProt = p; 
-      <td class="race-Géant">Géant</td><td>Uppercut</td><td>Technique</td><td>Contact</td> +});
-      <td>8 PM</td><td>+3 dégâts (coup critique automatique)</td><td>Autre</td><td>max 1</td> +
-      <td>Inflige un coup critique automatique à une cible au contact : +3 dégâts sur la cible.</td><td>/</td><td>200 po</td> +
-    </tr>+
  
-    <tr class="Géant"> +let char={...races[raceSelect.value]};
-      <td class="race-Géant">Géant</td><td>Leurre</td><td>Technique</td><td>Contact</td> +
-      <td>8 PM</td><td></td><td>Soi-même</td><td>0</td> +
-      <td>Leurre la prochaine attaque magique de l'adversaire.</td><td>/</td><td>200 po</td> +
-    </tr>+
  
-    <!-- ===== OLYMPIENS ===== --> +// stats investies 
-    <tr class="Olympien"> +for(let s in costTable){ 
-      <td class="race-Olympien">Olympien</td><td>Désarmement</td><td>Technique</td><td>Contact</td> +let v=+document.getElementById(s).value||0; 
-      <td>7 PM</td><td>+4</td><td>Autre</td><td>max 1</td> +char[s]=(char[s]||0)+v; 
-      <td>Désarme l'adversaire % de chance que l'adversaire lâche son arme au sol).</td><td>/</td><td>200 po</td> +}
-    </tr>+
  
-    <tr class="Olympien"+// equip 
-      <td class="race-Olympien">Olympien</td><td>Parade</td><td>Technique</td><td>Contact</td> +Object.values(slots).forEach(sel=>{ 
-      <td>7 PM</td><td></td><td>Soi-même</td><td>0</td> +if(sel.value==="") return; 
-      <td>Pare la prochaine attaque de mêlée de l'adversaire (nécessite une arme de mêlée).</td><td>/</td><td>200 po</td> +let e=equipments[sel.value]; 
-    </tr>+for(let s in e.stats)
 +char[s]=(char[s]||0)+e.stats[s]; 
 +
 +});
  
-    <!-- ===== HS ===== --> +// ===== DÉS ===== 
-    <tr class="HS"> +let ccDice char.cc * 2; 
-      <td class="race-HS">HS</td><td>Griffes</td><td>Technique</td><td>Contact</td> +let ctDice char.ct * 2; 
-      <td>6 PM</td><td>+3 + poison + poison magique</td><td>Autre</td><td>max 1</td> +let fmDice = char.fm * 2; 
-      <td>Inflige poison + poison magique.</td><td>/</td><td>200 po</td> +let agiDice = char.agi * 2;
-    </tr>+
  
-    <!-- ===== ELFES ===== --> +// ===== VALEURS FINALES ===== 
-    <tr class="Elfe"> +let finalCC ccDice + bestDex; 
-      <td class="race-Elfe">Elfe</td><td>Frappe vicieuse</td><td>Technique</td><td>Contact</td> +let finalCT ctDice + bestDex; 
-      <td>7 PM</td><td>+2</td><td>Autre</td><td>max 1</td> +let finalFM = fmDice bestDex;
-      <td>Ignore la pièce d'armure de tronc de l'adversaire.</td><td>/</td><td>200 po</td> +
-    </tr>+
  
-    <tr class="Elfe"> 
-      <td class="race-Elfe">Elfe</td><td>Pas de côté</td><td>Technique</td><td>Contact</td> 
-      <td>7 PM + 1 Mvt</td><td></td><td>Soi-même</td><td>0</td> 
-      <td>Esquive la prochaine attaque physique en se déplaçant aléatoirement d'une case.</td><td>/</td><td>200 po</td> 
-    </tr> 
  
-  </tbody> +// ===== CT DISTANCE ===== 
-</table> +function getCTDistance(baseCT, distance){ 
-</div>+if(distance <= 2) return baseCT; 
 +return baseCT - (distance - 2) * 3; 
 +}
  
-<script> +let ct1 = getCTDistance(finalCT,1); 
-// Script pour le second tableau +let ct2 = getCTDistance(finalCT,2); 
-const select2 document.getElementById("raceSelect2"); +let ct3 getCTDistance(finalCT,3); 
-const rows2 document.querySelectorAll("#competencesTable2 tbody tr");+let ct4 getCTDistance(finalCT,4);
  
-select2.addEventListener("change", () => { 
-  const chosenRace = select2.value; 
-  rows2.forEach(row => { 
-    const isCommun = row.classList.contains("Communs"); 
-    const isRace = row.classList.contains(chosenRace); 
-    row.style.display = (chosenRace === "Toutes" || isCommun || isRace) ? "" : "none"; 
-  }); 
-}); 
-</script> 
  
 +// ===== ESQUIVE =====
  
-<hr>+let checked = [...document.querySelectorAll(".skill:checked")].map(e=>e.dataset.name);
  
-<!-- ================= TABLEAU 3 : Techniques Distance ================= --> +// ===== ESQUIVE CAC ===== 
-<h3>Gestion des compétences — Techniques Distance</h3> +// règle meilleur entre CC et AGI (dés), puis conversion jet + protection
-<label for="raceSelect3">Choisir une race :</label> +
-<select id="raceSelect3"> +
-  <option value="Toutes">Toutes</option> +
-  <option value="Communs">Communs</option> +
-  <option value="Nain">Nain</option> +
-  <option value="Géant">Géant</option> +
-  <option value="Olympien">Olympien</option> +
-  <option value="HS">HS</option> +
-  <option value="Elfe">Elfe</option> +
-</select>+
  
-<div class="table-container"> +let esquiveCAC Math.max(ccDice, agiDice);
-<table id="competencesTable3"> +
-<thead> +
-<tr> +
-<th>Race</th><th>Nom</th><th>Type</th><th>Catégorie</th> +
-<th>Coût</th><th>Bonus / Malus</th><th>Cible</th><th>Portée</th> +
-<th>Description</th><th>Cumulable</th><th>Prix</th> +
-</tr> +
-</thead> +
-<tbody>+
  
-<!-- ================= COMMUNS ================= -->+// conversion en jet + protection 
 +esquiveCAC esquiveCAC + bestProt;
  
-<tr class="Communs"> 
-<td class="race-Communs">Communs</td><td>Tir épuisant</td><td>Technique</td><td>Tir munitions</td> 
-<td>/</td><td>Essoufflement (X/3)</td><td>Autre</td><td>min 2</td> 
-<td>Ne fait pas de dégâts. Jet de CT pur. Essouflement(X/3) où X est la différence des jets de dés</td><td>Effet immédiat. Cumul possible.</td><td>50 pos</td> 
-</tr> 
  
 +// ===== ESQUIVE TIR =====
 +// règle :
 +// max entre :
 +// (3/4 CC + 1/4 AGI)
 +// (1/4 CC + 3/4 AGI)
 +// arrondi inférieur → dés → ×2 → + protection
  
-<tr class="Communs"> +let esquiveA Math.floor(char.cc * 0.75 + char.agi * 0.25); 
-<td class="race-Communs">Communs</td><td>Tir précis </td><td>Technique</td><td>Distance</td> +let esquiveB Math.floor(char.cc * 0.25 char.agi * 0.75);
-<td>2 MP</td><td>+4 au toucher, -3 dégâts</td><td>Autre</td><td>min 2</td> +
-<td>Bonus +4 au toucher, Malus de 3 aux dégâts </td><td>/</td><td>50 pos</td> +
-</tr>+
  
-<tr class="Communs"> +// passifs qui remplacent le calcul 
-<td class="race-Communs">Communs</td><td>Tir violent</td><td>Technique</td><td>Distance</td> +let esquiveStat;
-<td>2 MP</td><td>-6 au toucher, +2 dégâts</td><td>Autre</td><td>min 2</td> +
-<td>Malus de -6 pour toucher, bonus +2 dégâts</td><td>/</td><td>50 pos</td> +
-</tr>+
  
-<tr class="Communs"> +if(checked.includes("Réflexes fulgurants")){ 
-<td class="race-Communs">Communs</td><td>Tir à la cheville</td><td>Technique</td><td>Tir munitions</td> +    esquiveStat Math.floor(char.agi * 0.85 + char.cc * 0.15); 
-<td>6 MP</td><td>Ralentissement(x1D2)</td><td>Autre</td><td>min 2</td> +
-<td>Avec une arme à munitions, si la cible est touchée Ralentissement(x1D2 </td><td>Non cumulable</td><td>100 pos</td> +else if(checked.includes("Couverture")){ 
-</tr>+    esquiveStat = Math.floor(char.cc * 0.85 + char.agi * 0.15); 
 +
 +else{ 
 +    esquiveStat = Math.max(esquiveA, esquiveB); 
 +}
  
-<tr class="Communs"> +// conversion en jet 
-<td class="race-Communs">Communs</td><td>Tir handicapant</td><td>Technique</td><td>Distance</td> +let esquiveTir = esquiveStat * 2;
-<td>4 MP</td><td>Vulnérabilité (xX)</td><td>Autre</td><td>min 2</td> +
-<td>Ne fait pas de dégâts. Jet de CT pur. Vulnérabilité (xX) où X est la différence entre le jet d'attaque et de défense /3</td><td>Non cumulable</td><td>100 pos</td> +
-</tr>+
  
-<tr class="Communs"> +// protection (UNE seule fois) 
-<td class="race-Communs">Communs</td><td>Jet infusé</td><td>Technique</td><td>Jet</td> +esquiveTir += bestProt;
-<td>10 MP</td><td>M/3</td><td>Autre</td><td>min 2</td> +
-<td>Avec une arme de jet, +M/3 dmg</td><td>/</td><td>200 pos</td> +
-</tr>+
  
 +// bonus passifs
 +if(checked.includes("Fulgurance"))
 +    esquiveTir += 1;
  
-  </tbody> 
-</table> 
-</div> 
  
-<script> +// ===== ESQUIVE MAGIQUE ===== 
-// Script pour le troisieme tableau +// règle : FM en jet + protection
-const select3 document.getElementById("raceSelect3"); +
-const rows3 document.querySelectorAll("#competencesTable3 tbody tr");+
  
-select3.addEventListener("change", () => { +let esquiveFM fmDice + bestProt;
-  const chosenRace = select3.value; +
-  rows3.forEach(row => { +
-    const isCommun = row.classList.contains("Communs"); +
-    const isRace = row.classList.contains(chosenRace); +
-    row.style.display = (chosenRace === "Toutes" || isCommun || isRace) ? "" : "none"; +
-  }); +
-}); +
-</script>+
  
 +// ===== MAGIE =====
 +let jetFM = finalFM;
  
-<hr>+let sorts = ""; 
 +for(let lvl=1; lvl<=5; lvl++){ 
 +    let seuil = 6 + 6 * lvl; 
 +    let reussite = jetFM >= seuil ? "✅" : "❌";
  
-<!-- ================= TABLEAU 4 : Furtivité ================= --> +    sorts +`Niveau ${lvl} → Seuil ${seuil} | Jet ${jetFM} ${reussite}\n`; 
-<h3>Gestion des compétences — Techniques Furtivité</h3> +}
-<label for="raceSelect4">Choisir une race :</label> +
-<select id="raceSelect4"> +
-  <option value="Toutes">Toutes</option> +
-  <option value="Communs">Communs</option> +
-  <option value="Nain">Nain</option> +
-  <option value="Géant">Géant</option> +
-  <option value="Olympien">Olympien</option> +
-  <option value="HS">HS</option> +
-  <option value="Elfe">Elfe</option> +
-</select>+
  
-<div class="table-container"> +// ===== AFFICHAGE ===== 
-<table id="competencesTable4"+document.getElementById("spellBonus").innerText = 
-<thead> +"Bonus actifs → Dex: "+bestDex+" | Protection: "+bestProt;
-<tr> +
-<th>Race</th><th>Nom</th><th>Type</th><th>Catégorie</th> +
-<th>Coût</th><th>Bonus / Malus</th><th>Cible</th><th>Portée</th> +
-<th>Description</th><th>Cumulable</th><th>Prix</th> +
-</tr> +
-</thead> +
-<tbody>+
  
 +result.textContent =
  
 +"===== PERSONNAGE =====\n"+
 +"Race : "+raceSelect.value+
  
 +"\n\n===== STATS =====\n"+
 +JSON.stringify(char,null,2)+
  
- <!-- ================= COMMUNS ================= -->+"\n\n===== JET OFFENSIF =====\n"+ 
 +"\n⚔ CC : jet moyen "+ccDice+" ("+finalCC+")"
 +"\n🎯 CT : jet moyen "+ctDice+" ("+finalCT+")"
 +"\n✨ FM : jet moyen "+fmDice+" ("+finalFM+")"+
  
- <tr class="Communs"> +"\n\n===== JET DEFENSIF =====\n"+ 
- <td class="race-Communs">Communs</td><td>Exploration</td><td>Technique</td><td>Personnel</td> +"\n🛡 Esquive CAC : "+esquiveCAC+ 
- <td>Toutes les A restantes </td><td>+X P</td><td>Soi-même</td><td>/</td> +"\n🏹 Esquive tir : "+esquiveTir
- <td>Le personnage gagne Acuité visuelle (x) où x est le nombre d'actions dépensées jusqu'au prochain tour</td><td>/</td><td>50 pos</td> +"\n✨ Esquive FM : "+esquiveFM+
- </tr>+
  
 +"\n\n===== JET DISTANCE =====\n"+
 +"\n🎯 CT distances :"+
 +"\n1 case : "+ct1+
 +"\n2 cases : "+ct2+
 +"\n3 cases : "+ct3+
 +"\n4 cases : "+ct4+
  
- <tr class="Communs"> +"\n\n===== MAGIE =====\n"+ 
- <td class="race-Communs">Communs</td><td>Discrétion</td><td>Technique</td><td>Personnel</td> +"Jet FM : "+jetFM+"\n\n"
- <td>X MP, Y Mvt </td><td></td><td>Soi-même</td><td>/</td> +sorts; 
- <td>Le personnage n'apparaîtra pas sur la carte générale jusqu'à son prochain tour. X= 2*(Furtivité+1). Y = 1/2*(Furtivité+1) (voir sous le tableau)</td><td>/</td><td>200 pos</td> +}
- </tr>+
  
- <tr class="Communs"> 
- <td class="race-Communs">Communs</td><td>Camouflage (Olympien)</td><td>Technique</td><td>Personnel</td> 
- <td>X MP, Y Mvt</td><td>/</td><td>Soi-même</td><td>/</td> 
- <td>Apparaît sur la carte générale avec la Race choisie (Olympien) jusqu'à son prochain tour. X= 2*(Furtivité+1). Y = 1/2*(Furtivité+1) (voir sous le tableau)</td><td>/</td><td>300 pos</td> 
- </tr> 
-  
- <tr class="Communs"> 
- <td class="race-Communs">Communs</td><td>Camouflage (Elfe)</td><td>Technique</td><td>Personnel</td> 
- <td>X MP, Y Mvt</td><td>/</td><td>Soi-même</td><td>/</td> 
- <td>Apparaît sur la carte générale avec la Race choisie (Elfe) jusqu'à son prochain tour. X= 2*(Furtivité+1). Y = 1/2*(Furtivité+1) (voir sous le tableau)</td><td>/</td><td>300 pos</td> 
- </tr> 
-  
- <tr class="Communs"> 
- <td class="race-Communs">Communs</td><td>Camouflage (HS)</td><td>Technique</td><td>Personnel</td> 
- <td>X MP, Y Mvt</td><td>/</td><td>Soi-même</td><td>/</td> 
- <td>Apparaît sur la carte générale avec la Race choisie (HS) jusqu'à son prochain tour. X= 2*(Furtivité+1). Y = 1/2*(Furtivité+1) (voir sous le tableau)</td><td>/</td><td>300 pos</td> 
- </tr> 
-  
- <tr class="Communs"> 
- <td class="race-Communs">Communs</td><td>Camouflage (Géant)</td><td>Technique</td><td>Personnel</td> 
- <td>X MP, Y Mvt</td><td>/</td><td>Soi-même</td><td>/</td> 
- <td>Apparaît sur la carte générale avec la Race choisie (Géant) jusqu'à son prochain tour. X= 2*(Furtivité+1). Y = 1/2*(Furtivité+1) (voir sous le tableau)</td><td>/</td><td>300 pos</td> 
- </tr> 
-  
- <tr class="Communs"> 
- <td class="race-Communs">Communs</td><td>Camouflage (Nain)</td><td>Technique</td><td>Personnel</td> 
- <td>X MP, Y Mvt</td><td>/</td><td>Soi-même</td><td>/</td> 
- <td>Apparaît sur la carte générale avec la Race choisie (Nain) jusqu'à son prochain tour. X= 2*(Furtivité+1). Y = 1/2*(Furtivité+1) (voir sous le tableau)</td><td>/</td><td>300 pos</td> 
- </tr> 
  
-  </tbody> +// ===== AUTO ===== 
-</table> +function autoCalculate(){ 
-</div>+updateCost(); 
 +calculate(); 
 +}
  
 +// events stats
 +document.querySelectorAll("#stats input").forEach(i=>{
 +i.addEventListener("input", autoCalculate);
 +});
  
-  </tbody+document.querySelectorAll(".spell").forEach(s=>{ 
-</table> +s.addEventListener("change", autoCalculate); 
-</div>+});
  
-<script> 
-// Script pour le quatrieme tableau 
-const select4 = document.getElementById("raceSelect4"); 
-const rows4 = document.querySelectorAll("#competencesTable4 tbody tr"); 
  
-select4.addEventListener("change", (=> { +// passifs 
-  const chosenRace = select4.value; +document.querySelectorAll(".skill").forEach(s=>{ 
-  rows3.forEach(row => { +s.addEventListener("change", autoCalculate);
-    const isCommun = row.classList.contains("Communs"); +
-    const isRace = row.classList.contains(chosenRace); +
-    row.style.display = (chosenRace === "Toutes" || isCommun || isRace) ? "" : "none"; +
-  });+
 }); });
-</script> 
  
  
-</body> 
-</html> 
  
 +// ===== RESET =====
 +function resetAll(){
  
 +document.querySelectorAll("#stats input").forEach(i=>i.value=0);
 +document.querySelectorAll(".spell").forEach(s=>s.checked=false);
  
 +Object.values(slots).forEach(s=>{
 +s.value="";
 +s.disabled=false;
 +});
  
-**Fonctionnement de la carte sur Olympia** :  +document.querySelectorAll(".skill").forEach(s=>s.checked=false);
->1Tous les joueurs sur Olympia apparaissent en points noirs sur la carte du monde. +
-> +
->2) Dans un rayon de 15 cases autour de sa position, un joueur voit la couleur de la race des  autres personnages. +
-+
->3Si le personnage se déplace, la couleur se met à jour en fonction de la nouvelle position.+
  
-  +resetSlots(); 
-**Fonctionnement des compétences de discrétion **: +fillEquip(); 
->1Lorsque le personnage utilise la compétence "discrétion", il n'apparait plus sur la carte du monde __**jusqu'à sa prochaine activation**__. L'icone Furtivité apparait avec un décompte.  +displayBase(); 
-+checkLimit(); 
->Lors de son prochain tour, pour être de nouveau invisible sur la carte du monde, le joueur devra relancer la compétence "discrétion" (au plus tôt pour apparaitre le moins longtemps possible sur la carte du monde). +autoCalculate(); 
-+}
->2Pour éviter que ce soit trop simple de rester furtif, le coût augmente à mesure du nombre d'utilisations successives le compétence.  +
-+
->3) Utiliser une compétence de discrétion (Discrétion pour le momentajoute une charge de l'Effet "Furtivité" pour 48h qui se stack et dont la durée se réinitialise à chaque utilisation de Discrétion. Chaque charge de "Furtivité" augmente les coûts des compétences de discrétion.  +
-+
->4) Pour réinitialiser le coût des compétences de discrétion, il faut perdre l'effet Furtivité (donc ne pas utiliser de compétence de discrétion pendant 48h+
-+
->5)Avec la compétence Discrétion, __**on est invisible uniquement sur la carte globale et non sur les mini map (ville et sous plans)**__.+
  
 +// init
 +autoCalculate();
  
  
 +
 +// ===== POUSSEE =====
 +function calculatePush(){
 +
 +let F=+pushF.value;
 +let buff=+pushBuff.value;
 +
 +let E=+pushE.value;
 +let agi=+pushAgi.value;
 +let pv=+pushPV.value;
 +
 +let instability=+pushDebuff.value;
 +let stability=+pushStab.value;
 +
 +let attaque=F+buff;
 +let defense=Math.max(E+4,agi)+(pv/10)+instability+stability;
 +
 +pushResult.textContent=
 +"Attaque: "+attaque+
 +"\nDéfense: "+defense.toFixed(1)+
 +"\n"+(attaque>=defense?"✅ PUSH":"❌ FAIL");
 +}
 +
 +// ===== EVENTS =====
 +document.querySelectorAll("input").forEach(i=>i.addEventListener("input",()=>{
 +updateCost(); calculate(); calculatePush();
 +}));
 +
 +document.querySelectorAll("select").forEach(i=>i.addEventListener("change",()=>{
 +updateCost(); calculate(); calculatePush();
 +}));
 +
 +
 +// ===== INIT =====
 +updateCost();
 +calculate();
 +calculatePush();
 +
 +
 +// =====================================
 +// ENCODE / DECODE
 +// =====================================
 +
 +function encodeBuild(data){
 +    return encodeURIComponent(JSON.stringify(data));
 +}
 +
 +function decodeBuild(code){
 +    return JSON.parse(decodeURIComponent(code));
 +}
 +
 +// =====================================
 +// BUILD DATA
 +// =====================================
 +
 +function getBuildData(){
 +
 +    let data = {
 +        race: raceSelect.value,
 +        stats: {},
 +        equip: {},
 +        skills: [],
 +        spells: []
 +    };
 +
 +    // stats
 +    for(let s in costTable){
 +        data.stats[s] = +document.getElementById(s).value || 0;
 +    }
 +
 +    // équipements
 +    Object.entries(slots).forEach(([k,s])=>{
 +        data.equip[k] = s.value;
 +    });
 +
 +    // passifs
 +    document.querySelectorAll(".skill:checked").forEach(s=>{
 +        data.skills.push(s.dataset.name);
 +    });
 +
 +    // sorts
 +    document.querySelectorAll(".spell:checked").forEach(s=>{
 +        data.spells.push({
 +            dex: +s.dataset.dex,
 +            prot: +s.dataset.prot
 +        });
 +    });
 +
 +    return data;
 +}
 +
 +// =====================================
 +// APPLY BUILD
 +// =====================================
 +
 +function applyBuild(data){
 +
 +    // race
 +    raceSelect.value = data.race || "Elfe";
 +
 +    // recharge équipements race
 +    resetSlots();
 +    fillEquip();
 +
 +    // stats
 +    for(let s in costTable){
 +        document.getElementById(s).value =
 +            data.stats?.[s] || 0;
 +    }
 +
 +    // équipements
 +    Object.entries(slots).forEach(([k,s])=>{
 +        s.value = data.equip?.[k] || "";
 +    });
 +
 +    // passifs
 +    document.querySelectorAll(".skill").forEach(s=>{
 +        s.checked =
 +            data.skills?.includes(s.dataset.name);
 +    });
 +
 +    // sorts
 +    document.querySelectorAll(".spell").forEach(s=>{
 +
 +        s.checked = data.spells?.some(sp =>
 +            sp.dex == +s.dataset.dex &&
 +            sp.prot == +s.dataset.prot
 +        );
 +
 +    });
 +
 +    displayBase();
 +    checkLimit();
 +    autoCalculate();
 +}
 +
 +// =====================================
 +// EXPORT
 +// =====================================
 +
 +function exportBuild(){
 +
 +    let data = getBuildData();
 +
 +    let code = encodeBuild(data);
 +
 +    prompt("Copie ton build :", code);
 +}
 +
 +// =====================================
 +// IMPORT
 +// =====================================
 +
 +function importBuild(codeInput){
 +
 +    let code = codeInput;
 +
 +    if(!code){
 +        code = prompt("Colle le code du build :");
 +    }
 +
 +    if(!code) return;
 +
 +    try{
 +
 +        code = code.trim();
 +
 +        let data = decodeBuild(code);
 +
 +        applyBuild(data);
 +
 +        alert("✅ Build importé");
 +
 +    }catch(e){
 +
 +        console.log(e);
 +
 +        alert("❌ Code invalide");
 +    }
 +}
 +
 +// =====================================
 +// LIEN PARTAGE
 +// =====================================
 +
 +function copyLink(){
 +
 +    let data = getBuildData();
 +
 +    let code = encodeBuild(data);
 +
 +    let url =
 +        window.location.origin +
 +        window.location.pathname +
 +        "?id=simulateur&build=" + code;
 +
 +    navigator.clipboard.writeText(url).then(()=>{
 +
 +        alert("🔗 Lien copié !");
 +
 +    }).catch(()=>{
 +
 +        prompt("Copie ce lien :", url);
 +
 +    });
 +}
 +
 +// =====================================
 +// AUTO LOAD URL
 +// =====================================
 +
 +(function(){
 +
 +    try{
 +
 +        let params =
 +            new URLSearchParams(window.location.search);
 +
 +        let code = params.get("build");
 +
 +        if(!code) return;
 +
 +        let data = decodeBuild(code);
 +
 +        applyBuild(data);
 +
 +        console.log("✅ Build URL chargé");
 +
 +    }catch(e){
 +
 +        console.log("Erreur chargement URL", e);
 +
 +    }
 +
 +})();
 +
 +</script>
 +</body>
 +</html>
brouillon3.1776543435.txt.gz · Dernière modification : 2026/04/18 22:17 de nanaki