const EV_NAMES=["HP", "Atk", "Def", "SpA", "SpD", "Spe"]; var mons = JSON.parse(localStorage.getItem('mons')); if (!mons) { mons = []; } var party = JSON.parse(localStorage.getItem('party')); if (!party) { party = []; } var gameData; var opponents; var overwriting = false; fetch('js/game_data.json') .then(response => response.json()) .then(data => { setGame(data); render_party(); }) .catch(error => console.error('Error loading JSON:', error)); fetch ('js/opponents.json') .then(response => response.json()) .then(data => { setOpponents(data); render_opponents(); }) .catch(error => console.error('Error loading JSON:', error)); function setOpponents(data) { opponents = data.mons; } function setGame(data) { gameData = data; } function stash(i) { party.splice(i, 1); render_party(); } function add_to_party(i) { if (!party || party.length == 0) { party = [i]; } else { party.push(i); } localStorage.setItem('party', "[" + party + "]"); render_known(); } function render_mon(mon) { let out = "" + mon.name + ""; for (let ev=0; ev<6; ev++) { let curr = mon.current_evs[ev]; let tgt = mon.target_evs[ev]; if (curr < tgt) { out += "" + curr + "/" + tgt + "(-" + (tgt - curr) + ")" + ""; } else if (tgt < curr) { out += "" + curr + "/" + tgt + "(+" + (curr - tgt) + ")" + ""; } else { out += "" + curr + ""; } } out += ""; if (mon.pokerus) { out += "🦠"; } out += "" + render_item(mon.held_item) + ""; return out; } function edit_mon(mon_idx, return_to_party) { let mon = mons[mon_idx]; new_mon(return_to_party); document.getElementById("opponents_area").hidden = true; document.getElementById("opponent_search_field").hidden = true; document.getElementById("name").value = mon.name; document.getElementById("curr_hp").value = mon.current_evs[0]; document.getElementById("curr_atk").value = mon.current_evs[1]; document.getElementById("curr_def").value = mon.current_evs[2]; document.getElementById("curr_spa").value = mon.current_evs[3]; document.getElementById("curr_spd").value = mon.current_evs[4]; document.getElementById("curr_spe").value = mon.current_evs[5]; document.getElementById("tgt_hp").value = mon.target_evs[0]; document.getElementById("tgt_atk").value = mon.target_evs[1]; document.getElementById("tgt_def").value = mon.target_evs[2]; document.getElementById("tgt_spa").value = mon.target_evs[3]; document.getElementById("tgt_spd").value = mon.target_evs[4]; document.getElementById("tgt_spe").value = mon.target_evs[5]; document.getElementById("pokerus").checked = mon.pokerus; document.getElementById("item").value = mon.held_item; overwriting = true; } function new_mon(return_to_party) { overwriting = false; let out = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "
HPAtkDefSpASpDSpe
" + ""; document.getElementById("main_area").innerHTML = out; } function render_item(name) { let res = "No relevant item"; for (let i=0; i 0) { res += " +"; } else { res += " "; } return res + item.ev_added + ")"; } } return res; } function feed(mon_idx) { console.log("Feed"); let mon = mons[party[mon_idx]]; let item_name = document.getElementById('item').value; let item; for (let i=0; i gameData.max_ev_value) { alert("Current EV value for " + EV_NAMES[i] + " is outside the allowed range for " + gameData.name + ": (0..=" + gameData.max_ev_value + ")."); return; } total_curr_evs += current_evs[i]; } if (total_curr_evs > gameData.max_total_evs) { alert("Total current EVs are " + total_curr_evs + ", which is higher than the maximum for " + gameData.name + ": " + gameData.max_total_evs + "."); return; } let target_evs = [ Number.parseInt(document.getElementById('tgt_hp').value, 10), Number.parseInt(document.getElementById('tgt_atk').value, 10), Number.parseInt(document.getElementById('tgt_def').value, 10), Number.parseInt(document.getElementById('tgt_spa').value, 10), Number.parseInt(document.getElementById('tgt_spd').value, 10), Number.parseInt(document.getElementById('tgt_spe').value, 10), ]; let total_tgt_evs = 0; for (let i=0; i<6; i++) { if (Number.isNaN(target_evs[i])) { target_evs[i] = 0; } if (target_evs[i] < 0 || target_evs[i] > gameData.max_ev_value) { alert("target EV value for " + EV_NAMES[i] + " is outside the allowed range for " + gameData.name + ": (0..=" + gameData.max_ev_value + ")."); return; } total_tgt_evs += target_evs[i]; } if (total_tgt_evs > gameData.max_total_evs) { alert("Total target EVs are " + total_tgt_evs + ", which is higher than the maximum for " + gameData.name + ": " + gameData.max_total_evs + "."); return; } let pokerus = document.getElementById('pokerus').checked; let held_item = document.getElementById('item').value; let mon = { name: name, current_evs: current_evs, target_evs: target_evs, pokerus: pokerus, held_item: held_item, }; for (let i=0; i= gameData.affected_mons) { out += "Party is full"; } else { out += "NameHPAtkDefSpASpDSpePokérusItem"; for (let i=mons.length-1; i>=0; i--) { if (party.includes(i)) { continue; } out += ""; out += render_mon(mons[i]); out += ""; out += ""; out += ""; } out += ""; } out += "
"; out += "
"; document.getElementById("main_area").innerHTML = out; document.getElementById("opponents_area").hidden = true; document.getElementById("opponent_search_field").hidden = true; } function render_party() { let out = "

Current Party:

"; if (party.length == 0) { out += "Empty"; } else { out += ""; for (let i=0; iStash "; out += " "; out += ""; out += ""; } } out += "
NameHPAtkDefSpASpDSpePokérusItem
"; out += "
"; out += " "; out += ""; document.getElementById("main_area").innerHTML = out; document.getElementById("opponents_area").hidden = false; document.getElementById("opponent_search_field").hidden = false; } function export_data() { let save_data = { mons: mons, party: party, }; document.getElementById("opponents_area").hidden = true; document.getElementById("opponent_search_field").hidden = true; document.getElementById("main_area").innerHTML = "

Copy the contents of the following text area and save them on your device. You can paste them into the text area shown by the Import function to update your local data. Modify them in between if you like, but don't blame me if you break anything. If so, you may have to reset your browser's Local Storage.

" + "
" + ""; let field = document.getElementById("data"); field.value = JSON.stringify(save_data); field.select(); } function render_import() { document.getElementById("opponents_area").hidden = true; document.getElementById("opponent_search_field").hidden = true; document.getElementById("main_area").innerHTML = "

Paste your exported data into this field. If it wasn't modified, it should restore your state fine. If you did modify it, make sure it is still well-formated. If importing breaks your state, reset your browser's Local Storage and try to fix your data.

" + "
" + "" + ""; } function try_import_data () { let save_data = JSON.parse(document.getElementById("data").value); if (!save_data.mons) { alert("Value for 'mons' not set"); return; } if (!save_data.party) { alert("Value for 'party' not set"); return; } mons = save_data.mons; party = save_data.party; render_party(); localStorage.setItem('mons', JSON.stringify(mons)); localStorage.setItem('party', "[" + party + "]"); } function use_item(mon_idx) { let mon = mons[party[mon_idx]]; let out = "

Currently feeding

" + "" + render_mon(mon) + "
NameHPAtkDefSpASpDSpeItem
" + "" + "" + "" + "
"; document.getElementById("main_area").innerHTML = out; document.getElementById("opponents_area").hidden = true; document.getElementById("opponent_search_field").hidden = true; } function add_ev(mon, added_evs, count) { let curr = [...mon.current_evs]; let total = 0; let changed = []; for (let idx=0; idx<6; idx++) { let new_ev = curr[idx] + added_evs[idx] * count; if (new_ev < 0) { new_ev = 0; } if (new_ev > gameData.max_ev_value) { new_ev = gameData.max_ev_value; } if (new_ev != curr[idx]) { curr[idx] = new_ev; changed.push(idx); } total += new_ev; } if (total > gameData.max_total_evs) { if (changed.length == 1) { curr[changed[0]] -= total - gameData.max_total_evs; } else { let raised_evs = EV_NAMES[changed[0]]; for (let idx=1; idxHPAtkDefSpASpDSpe" + ""; for (let i=0; i" + ev_yield[0] + "" + ev_yield[1] + "" + ev_yield[2] + "" + ev_yield[3] + "" + ev_yield[4] + "" + ev_yield[5] + "" + "