brouillon10
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| brouillon10 [2026/04/29 09:53] – nanaki | brouillon10 [2026/04/29 13:54] (Version actuelle) – nanaki | ||
|---|---|---|---|
| Ligne 3: | Ligne 3: | ||
| < | < | ||
| <meta charset=" | <meta charset=" | ||
| - | < | + | < |
| < | < | ||
| - | body{font-family: | + | body { font-family: |
| - | select{margin:5px;width:250px} | + | h1,h2 { color:gold;} |
| - | .box{background:#2a2a2a; | + | .box { border:1px solid gold; padding: |
| - | button{margin: | + | select, |
| - | input{width:300px} | + | button { padding: |
| </ | </ | ||
| </ | </ | ||
| Ligne 16: | Ligne 16: | ||
| < | < | ||
| - | < | + | < |
| - | <h2>Race</h2> | + | <div class=" |
| - | <select id=" | + | Race |
| - | < | + | <select id=" |
| - | < | + | </div> |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </select> | + | |
| - | <h2> | + | <div class="box"> |
| - | + | Stats | |
| - | <select id="head"></ | + | <div id="stats"></ |
| - | <select id=" | + | </div> |
| - | <select id=" | + | |
| - | <select id=" | + | |
| - | <select id=" | + | |
| - | <select id=" | + | |
| - | <select id=" | + | |
| - | + | ||
| - | <div id="equipCount"></ | + | |
| - | + | ||
| - | < | + | |
| - | <select id=" | + | |
| <div class=" | <div class=" | ||
| - | <h2>Résultats</h2> | + | Équipement<br> |
| - | <div id="result"></ | + | Tête <select id=" |
| + | Cou <select id=" | ||
| + | Dos <select id=" | ||
| + | Main droite <select id=" | ||
| + | Main gauche <select id=" | ||
| + | Corps <select id=" | ||
| + | Anneau <select id=" | ||
| + | Pieds <select | ||
| </ | </ | ||
| <div class=" | <div class=" | ||
| - | < | + | Compétences |
| - | <button onclick="saveBuild()">💾 Sauvegarder</button> | + | <div id="skills"></ |
| - | <button onclick=" | + | |
| - | + | ||
| - | <button onclick=" | + | |
| - | <input id=" | + | |
| </ | </ | ||
| - | <script> | + | <button onclick=" |
| + | <button onclick=" | ||
| - | /* ================= RACES ================= */ | + | <pre id=" |
| + | |||
| + | < | ||
| + | // ===== DATA ===== | ||
| const races = { | const races = { | ||
| - | Elfe: | + | Elfe: |
| - | Nain:{cc:11,ct:8,f:11,e:6,agi:6,fm:10}, | + | Nain:{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} |
| - | Géant:{cc:9,ct:10,f:12,e:4,agi:7,fm:6}, | + | |
| - | Olympien:{cc:10,ct:9,f:10,e:5,agi:8,fm:7}, | + | |
| - | HS: | + | |
| }; | }; | ||
| - | /* ================= EQUIPEMENTS ================= */ | + | const costTable |
| + | cc: | ||
| + | pv:[4,2,1], mvt: | ||
| + | }; | ||
| const equipments = [ | const equipments = [ | ||
| - | {name:" | + | {name:" |
| - | + | {name:" | |
| - | {name:" | + | {name:" |
| - | {name:" | + | {name:" |
| - | {name:" | + | |
| - | {name:" | + | |
| - | + | ||
| - | {name:" | + | |
| - | {name:"Cape de chasse", | + | |
| - | + | ||
| - | {name:" | + | |
| - | {name:" | + | |
| ]; | ]; | ||
| - | /* ================= PASSIFS ================= */ | + | const skills |
| - | const passives | + | // ===== DOM ===== |
| - | {name:" | + | const raceSelect |
| - | {name:" | + | const statsDiv |
| - | {name:" | + | const skillsDiv |
| - | {name:"Duelliste",effect:(s)=>{s.cc+=2}}, | + | |
| - | {name:"Maître bretteur",effect:(s)=>{s.cc+=1}}, | + | |
| - | {name:"Inépuisable",effect:(s)=>{}} | + | |
| - | ]; | + | |
| - | /* ================= SELECT ================= */ | + | const head = document.getElementById(" |
| + | const neck = document.getElementById(" | ||
| + | const cape = document.getElementById(" | ||
| + | const rightHand | ||
| + | const leftHand | ||
| + | const body = document.getElementById(" | ||
| + | const ring = document.getElementById(" | ||
| + | const feet = document.getElementById(" | ||
| - | const race = document.getElementById(" | + | // ===== INIT ===== |
| - | const passivesSelect | + | |
| - | const slots = { | + | // race |
| - | head: | + | for(let r in races){ |
| - | cape: | + | raceSelect.innerHTML += `< |
| - | body: | + | } |
| - | right: | + | |
| - | left: | + | |
| - | feet: | + | |
| - | ring: | + | |
| - | }; | + | |
| - | /* ================= INIT ================= */ | + | // stats |
| - | + | for(let s in costTable){ | |
| - | function initEquip(){ | + | statsDiv.innerHTML += `${s} <input type=" |
| + | } | ||
| - | Object.values(slots).forEach(s=> | + | // skills |
| - | s.innerHTML = `<option value=""> | + | skills.forEach(s=> |
| + | skillsDiv.innerHTML | ||
| }); | }); | ||
| - | equipments.forEach((e, | + | // slots reset |
| - | + | function resetSlots(){ | |
| - | if(e.slot===" | + | [head,neck,cape, |
| - | slots.right.innerHTML += `<option value=" | + | sel.innerHTML = `<option value=""> |
| - | + | ||
| - | if(e.slot===" | + | |
| - | slots.left.innerHTML += `<option value=" | + | |
| - | + | ||
| - | if(e.slot===" | + | |
| - | slots.body.innerHTML += `<option value=" | + | |
| - | + | ||
| - | if(e.slot===" | + | |
| - | slots.cape.innerHTML += `<option value=" | + | |
| - | + | ||
| - | if(e.slot===" | + | |
| - | slots.feet.innerHTML += `<option value=" | + | |
| - | + | ||
| - | if(e.slot===" | + | |
| - | slots.ring.innerHTML | + | |
| }); | }); | ||
| - | |||
| } | } | ||
| - | /* ================= PASSIFS ================= */ | + | // remplir équipements |
| + | function fillEquip(){ | ||
| + | let r = raceSelect.value; | ||
| + | |||
| + | equipments.forEach((e, | ||
| + | if(e.race!==" | ||
| - | function initPassives(){ | + | if(e.slot===" |
| - | passives.forEach((p, | + | if(e.slot===" |
| - | let opt=document.createElement("option"); | + | if(e.slot===" |
| - | opt.value=i; | + | |
| - | opt.textContent=p.name; | + | |
| - | passivesSelect.appendChild(opt); | + | |
| }); | }); | ||
| } | } | ||
| - | /* ================= LIMIT ================= */ | + | // update |
| - | + | raceSelect.addEventListener(" | |
| - | function checkEquipLimit(){ | + | resetSlots(); |
| - | + | fillEquip(); | |
| - | let count = 0; | + | |
| - | let ring = 0; | + | |
| - | + | ||
| - | Object.entries(slots).forEach(([name,sel])=>{ | + | |
| - | if(!sel.value) return; | + | |
| - | + | ||
| - | if(name===" | + | |
| - | else count++; | + | |
| }); | }); | ||
| - | if(count> | + | resetSlots(); |
| - | alert(" | + | fillEquip(); |
| - | return false; | + | |
| - | } | + | |
| - | if(ring> | + | |
| - | alert(" | + | |
| - | return false; | + | |
| - | } | + | |
| - | + | ||
| - | return true; | + | |
| - | } | + | |
| - | + | ||
| - | /* ================= 2 MAINS ================= */ | + | |
| - | slots.right.addEventListener(" | + | // 2 mains |
| - | let item = equipments[slots.right.value]; | + | rightHand.addEventListener(" |
| + | let v = rightHand.value; | ||
| + | if(v==="" | ||
| - | if(item && | + | let item = equipments[v]; |
| - | slots.left.disabled | + | if(item.slot===" |
| - | slots.left.innerHTML | + | leftHand.value="" |
| + | leftHand.disabled=true; | ||
| }else{ | }else{ | ||
| - | slots.left.disabled = false; | + | leftHand.disabled=false; |
| - | initEquip(); | + | |
| } | } | ||
| }); | }); | ||
| - | /* ================= STATS ================= */ | + | // ===== CALCUL |
| + | function calculate(){ | ||
| - | function getStats(){ | + | let char = {...races[raceSelect.value]}; |
| + | let total = 0; | ||
| - | let s = {...races[race.value]}; | + | // stats |
| - | + | for(let s in costTable){ | |
| - | Object.values(slots).forEach(sel=> | + | let v = parseInt(document.getElementById(s).value)||0; |
| - | let item = equipments[sel.value]; | + | char[s]+=v; |
| - | if(!item || !item.stats) return; | + | |
| - | + | ||
| - | Object.entries(item.stats).forEach(([k, | + | |
| - | s[k]=(s[k]||0)+v; | + | |
| - | }); | + | |
| - | }); | + | |
| - | + | ||
| - | [...passivesSelect.selectedOptions].forEach(o=>{ | + | |
| - | passives[o.value].effect(s); | + | |
| - | }); | + | |
| - | + | ||
| - | return s; | + | |
| } | } | ||
| - | /* ================= CALCUL ================= */ | + | // equip |
| - | + | [rightHand, | |
| - | function ctRange(ct,d){ | + | if(sel.value==="" |
| - | if(d<=2) return | + | let e = equipments[sel.value]; |
| - | return ct-(d-2)*3; | + | for(let stat in e.stats){ |
| + | char[stat]=(char[stat]||0)+e.stats[stat]; | ||
| } | } | ||
| - | |||
| - | function dodge(cc, | ||
| - | return Math.max( | ||
| - | Math.floor(cc*0.75+agi*0.25), | ||
| - | Math.floor(cc*0.25+agi*0.75) | ||
| - | ); | ||
| - | } | ||
| - | |||
| - | /* ================= UPDATE ================= */ | ||
| - | |||
| - | function update(){ | ||
| - | |||
| - | if(!checkEquipLimit()) return; | ||
| - | |||
| - | let s = getStats(); | ||
| - | |||
| - | document.getElementById(" | ||
| - | CC: ${s.cc}< | ||
| - | FM: ${s.fm}< | ||
| - | |||
| - | CT:< | ||
| - | 1 case: ${ctRange(s.ct, | ||
| - | 2 cases: ${ctRange(s.ct, | ||
| - | 3 cases: ${ctRange(s.ct, | ||
| - | 4 cases: ${ctRange(s.ct, | ||
| - | |||
| - | Esquive tir: ${dodge(s.cc, | ||
| - | `; | ||
| - | |||
| - | displayCount(); | ||
| - | } | ||
| - | |||
| - | /* ================= COMPTEUR ================= */ | ||
| - | |||
| - | function displayCount(){ | ||
| - | |||
| - | let count=0, ring=0; | ||
| - | |||
| - | Object.entries(slots).forEach(([name, | ||
| - | if(!sel.value) return; | ||
| - | if(name===" | ||
| - | else count++; | ||
| }); | }); | ||
| - | document.getElementById(" | + | // affichage |
| - | `Équipements: | + | result.innerText = JSON.stringify(char,null,2); |
| } | } | ||
| - | /* ================= SAVE ================= */ | + | // ===== EXPORT |
| + | function exportWiki(){ | ||
| - | function saveBuild(){ | + | let txt="=== Build ===\n"; |
| - | let data = { | + | txt+=" |
| - | race: race.value, | + | |
| - | equip:{}, | + | |
| - | passives: | + | |
| - | }; | + | |
| - | Object.entries(slots).forEach(([k,s])=>{ | + | document.querySelectorAll(" |
| - | data.equip[k]=s.value; | + | txt+="* "+s.parentNode.innerText+" |
| }); | }); | ||
| - | localStorage.setItem(" | + | result.innerText=txt; |
| - | alert(" | + | |
| } | } | ||
| - | |||
| - | /* ================= LOAD ================= */ | ||
| - | |||
| - | function loadBuild(){ | ||
| - | |||
| - | let data = JSON.parse(localStorage.getItem(" | ||
| - | if(!data) return; | ||
| - | |||
| - | race.value = data.race; | ||
| - | |||
| - | Object.entries(data.equip).forEach(([k, | ||
| - | slots[k].value=v; | ||
| - | }); | ||
| - | |||
| - | [...passivesSelect.options].forEach(o=> | ||
| - | o.selected = data.passives.includes(o.value); | ||
| - | }); | ||
| - | |||
| - | update(); | ||
| - | } | ||
| - | |||
| - | /* ================= SHARE ================= */ | ||
| - | |||
| - | function generateLink(){ | ||
| - | |||
| - | let data = { | ||
| - | race: race.value, | ||
| - | equip:{}, | ||
| - | passives: | ||
| - | }; | ||
| - | |||
| - | Object.entries(slots).forEach(([k, | ||
| - | data.equip[k]=s.value; | ||
| - | }); | ||
| - | |||
| - | let str = btoa(JSON.stringify(data)); | ||
| - | let url = location.href.split("?" | ||
| - | |||
| - | document.getElementById(" | ||
| - | } | ||
| - | |||
| - | /* ================= LOAD FROM URL ================= */ | ||
| - | |||
| - | function loadFromURL(){ | ||
| - | |||
| - | let params = new URLSearchParams(window.location.search); | ||
| - | let data = params.get(" | ||
| - | |||
| - | if(!data) return; | ||
| - | |||
| - | let decoded = JSON.parse(atob(data)); | ||
| - | |||
| - | race.value = decoded.race; | ||
| - | |||
| - | Object.entries(decoded.equip).forEach(([k, | ||
| - | slots[k].value=v; | ||
| - | }); | ||
| - | |||
| - | [...passivesSelect.options].forEach(o=> | ||
| - | o.selected = decoded.passives.includes(o.value); | ||
| - | }); | ||
| - | |||
| - | update(); | ||
| - | } | ||
| - | |||
| - | /* ================= EVENTS ================= */ | ||
| - | |||
| - | document.querySelectorAll(" | ||
| - | s.addEventListener(" | ||
| - | }); | ||
| - | |||
| - | /* ================= START ================= */ | ||
| - | |||
| - | initEquip(); | ||
| - | initPassives(); | ||
| - | loadFromURL(); | ||
| - | update(); | ||
| </ | </ | ||
brouillon10.1777449203.txt.gz · Dernière modification : 2026/04/29 09:53 de nanaki
