<!DOCTYPE html>
<html>
<body>
<div id="currentLevel">
<label id="lvllabel">Current Level:</label>
<input id="lvl" type="number" min="1" max="25" step="1" value=1 oninput="lvlChanged()">
<button onclick="reset()" type="reset">Reset</button>
</div>
<div id="stats">
<label for="STR" class="statLabels">STR:</label>
<input id="STR" type="number" min="3" max="20" step="1" value=5 oninput="statChanged('STR')">
<br>
<label for="DEX" class="statLabels">DEX:</label>
<input id="DEX" type="number" min="3" max="20" step="1" value=5 oninput="statChanged('DEX')">
<br>
<label for="AGI" class="statLabels">AGI:</label>
<input id="AGI" type="number" min="3" max="20" step="1" value=5 oninput="statChanged('AGI')">
<br>
<label for="CON" class="statLabels">CON:</label>
<input id="CON" type="number" min="3" max="20" step="1" value=5 oninput="statChanged('CON')">
<br>
<label for="PER" class="statLabels">PER:</label>
<input id="PER" type="number" min="3" max="20" step="1" value=5 oninput="statChanged('PER')">
<br>
<label for="WIL" class="statLabels">WIL:</label>
<input id="WIL" type="number" min="3" max="20" step="1" value=5 oninput="statChanged('WIL')">
<br>
<label for="INT" class="statLabels">INT:</label>
<input id="INT" type="number" min="3" max="20" step="1" value=5 oninput="statChanged('INT')">
<br><br>
<label id="splabel">Stat Points balance: </label>
<label id="statpoints">5</label>
</div>
<div id="skills">
<label for="GUNS" class="skillLabels">Guns: </label>
<input id="GUNS" type="number" min="0" step="1" value=0 oninput="skillChanged('GUNS')">
<label id="effGUNS"></label>
<label id="balanceGUNS"></label>
<br>
<label for="THROWING" class="skillLabels">Throwing: </label>
<input id="THROWING" type="number" min="0" step="1" value=0 oninput="skillChanged('THROWING')">
<label id="effTHROWING"></label>
<label id="balanceTHROWING"></label>
<br>
<label for="CROSSBOWS" class="skillLabels">Crossbows: </label>
<input id="CROSSBOWS" type="number" min="0" step="1" value=0 oninput="skillChanged('CROSSBOWS')">
<label id="effCROSSBOWS"></label>
<label id="balanceCROSSBOWS"></label>
<br>
<label for="MELEE" class="skillLabels">Melee: </label>
<input id="MELEE" type="number" min="0" step="1" value=0 oninput="skillChanged('MELEE')">
<label id="effMELEE"></label>
<label id="balanceMELEE"></label>
<br>
<label for="DODGE" class="skillLabels">Dodge: </label>
<input id="DODGE" type="number" min="0" step="1" value=0 oninput="skillChanged('DODGE')">
<label id="effDODGE"></label>
<label id="balanceDODGE"></label>
<br>
<label for="EVASION" class="skillLabels">Evasion: </label>
<input id="EVASION" type="number" min="0" step="1" value=0 oninput="skillChanged('EVASION')">
<label id="effEVASION"></label>
<label id="balanceEVASION"></label>
<br>
<label for="STEALTH" class="skillLabels">Stealth: </label>
<input id="STEALTH" type="number" min="0" step="1" value=0 oninput="skillChanged('STEALTH')">
<label id="effSTEALTH"></label>
<label id="balanceSTEALTH"></label>
<br>
<label for="HACKING" class="skillLabels">Hacking: </label>
<input id="HACKING" type="number" min="0" step="1" value=0 oninput="skillChanged('HACKING')">
<label id="effHACKING"></label>
<label id="balanceHACKING"></label>
<br>
<label for="LOCKPICKING" class="skillLabels">Lockpicking: </label>
<input id="LOCKPICKING" type="number" min="0" step="1" value=0 oninput="skillChanged('LOCKPICKING')">
<label id="effLOCKPICKING"></label>
<label id="balanceLOCKPICKING"></label>
<br>
<label for="PICKPOCKETING" class="skillLabels">Pickpocketing: </label>
<input id="PICKPOCKETING" type="number" min="0" step="1" value=0 oninput="skillChanged('PICKPOCKETING')">
<label id="effPICKPOCKETING"></label>
<label id="balancePICKPOCKETING"></label>
<br>
<label for="TRAPS" class="skillLabels">Traps: </label>
<input id="TRAPS" type="number" min="0" step="1" value=0 oninput="skillChanged('TRAPS')">
<label id="effTRAPS"></label>
<label id="balanceTRAPS"></label>
<br>
<label for="MECHANICS" class="skillLabels">Mechanics: </label>
<input id="MECHANICS" type="number" min="0" step="1" value=0 oninput="skillChanged('MECHANICS')">
<label id="effMECHANICS"></label>
<label id="balanceMECHANICS"></label>
<br>
<label for="ELECTRONICS" class="skillLabels">Electronics: </label>
<input id="ELECTRONICS" type="number" min="0" step="1" value=0 oninput="skillChanged('ELECTRONICS')">
<label id="effELECTRONICS"></label>
<label id="balanceELECTRONICS"></label>
<br>
<label for="CHEMISTRY" class="skillLabels">Chemistry: </label>
<input id="CHEMISTRY" type="number" min="0" step="1" value=0 oninput="skillChanged('CHEMISTRY')">
<label id="effCHEMISTRY"></label>
<label id="balanceCHEMISTRY"></label>
<br>
<label for="BIOLOGY" class="skillLabels">Biology: </label>
<input id="BIOLOGY" type="number" min="0" step="1" value=0 oninput="skillChanged('BIOLOGY')">
<label id="effBIOLOGY"></label>
<label id="balanceBIOLOGY"></label>
<br>
<label for="TAILORING" class="skillLabels">Tailoring: </label>
<input id="TAILORING" type="number" min="0" step="1" value=0 oninput="skillChanged('TAILORING')">
<label id="effTAILORING"></label>
<label id="balanceTAILORING"></label>
<br>
<label for="TCONTROL" class="skillLabels">ThoughtControl: </label>
<input id="TCONTROL" type="number" min="0" step="1" value=0 oninput="skillChanged('TCONTROL')">
<label id="effTCONTROL"></label>
<label id="balanceTCONTROL"></label>
<br>
<label for="PSY" class="skillLabels">Psychokinesis: </label>
<input id="PSY" type="number" min="0" step="1" value=0 oninput="skillChanged('PSY')">
<label id="effPSY"></label>
<label id="balancePSY"></label>
<br>
<label for="META" class="skillLabels">Methathermics: </label>
<input id="META" type="number" min="0" step="1" value=0 oninput="skillChanged('META')">
<label id="effMETA"></label>
<label id="balanceMETA"></label>
<br>
<label for="PERSUASION" class="skillLabels">Persuasion: </label>
<input id="PERSUASION" type="number" min="0" step="1" value=0 oninput="skillChanged('PERSUASION')">
<label id="effPERSUASION"></label>
<label id="balancePERSUASION"></label>
<br>
<label for="INTIMIDATION" class="skillLabels">Intimidation: </label>
<input id="INTIMIDATION" type="number" min="0" step="1" value=0 oninput="skillChanged('INTIMIDATION')">
<label id="effINTIMIDATION"></label>
<label id="balanceINTIMIDATION"></label>
<br>
<label for="MERCANTILE" class="skillLabels">Mercantile: </label>
<input id="MERCANTILE" type="number" min="0" step="1" value=0 oninput="skillChanged('MERCANTILE')">
<label id="effMERCANTILE"></label>
<label id="balanceMERCANTILE"></label>
<br>
<br><br>
<label id="skplabel">Skill Points balance: </label>
<label id="skillpoints">120</label>
</div>
<div id="emptyspace"></div>
<script>
function lvlChanged() {
calcStatPoolBalance();
calcSkillPoolBalance();
checkSkills();
}
function checkSkills() {
statChanged("STR");
statChanged("DEX");
statChanged("AGI");
statChanged("PER");
statChanged("CON");
statChanged("WIL");
statChanged("INT");
}
function statChanged(s) {
var ability = getVal(s);
if (s == "STR") {
calcSkillChange(ability, "MELEE");
}
if (s == "DEX") {
calcSkillChange(ability, "THROWING");
calcSkillChange(ability, "MELEE");
calcSkillChange(ability, "LOCKPICKING", synergy("MECHANICS", 10),
synergy("TRAPS", 10));
calcSkillChange(ability, "PICKPOCKETING");
calcSkillChange(ability, "TRAPS", synergy("MECHANICS", 10), synergy(
"LOCKPICKING", 10));
}
if (s == "AGI") {
calcSkillChange(ability, "DODGE", synergy("EVASION", 10));
calcSkillChange(ability, "EVASION", synergy("DODGE", 10));
calcSkillChange(ability, "STEALTH");
}
if (s == "PER") {
calcSkillChange(ability, "GUNS");
calcSkillChange(ability, "CROSSBOWS");
}
if (s == "INT") {
calcSkillChange(ability, "HACKING", synergy("ELECTRONICS", 10));
calcSkillChange(ability, "MECHANICS");
calcSkillChange(ability, "ELECTRONICS");
calcSkillChange(ability, "CHEMISTRY", synergy("BIOLOGY", 10));
calcSkillChange(ability, "BIOLOGY", synergy("CHEMISTRY", 15));
calcSkillChange(ability, "TAILORING");
calcSkillChange(ability, "MERCANTILE", synergy("PERSUASION", 20));
}
if (s == "WIL") {
calcSkillChange(ability, "TCONTROL", synergy("PSY", 10), synergy(
"META", 10));
calcSkillChange(ability, "PSY", synergy("TCONTROL", 10), synergy(
"META", 10));
calcSkillChange(ability, "META", synergy("TCONTROL", 10), synergy(
"PSY", 10));
calcSkillChange(ability, "PERSUASION", synergy("MERCANTILE", 20));
calcSkillChange(ability, "INTIMIDATION", synergy("PERSUASION", 10));
}
calcStatPoolBalance();
}
function skillChanged(s) {
checkSkills();
calcSkillPoolBalance();
}
function synergy(skill, bonus) {
var val = parseInt(getVal(skill));
return Math.floor(val * (parseInt(bonus) / 100));
}
function calcSkillChange(ability, skill, bonus1, bonus2) {
if (skill == "MELEE") {
var str = parseInt(getVal("STR"));
var dex = parseInt(getVal("DEX"));
ability = Math.max(str, dex);
}
var val = calcSkillBonus(parseInt(ability), parseInt(getVal(skill)));
var maxSkillVal = 15 + ((parseInt(getCurrentLevel()) - 1) * 5);
if (val < maxSkillVal) {
var synBonus = 0;
if (bonus1 > 0) {
synBonus = synBonus +bonus1;
}
if (bonus2 > 0) {
synBonus = synBonus +bonus2;
}
var withSyn = val + synBonus;
if (withSyn >= maxSkillVal) {
val = maxSkillVal;
} else {
val = withSyn;
}
}
if (val > 0) {
setCnt("eff" + skill, "(" + val + ")");
var balance = calculateSkillBalance(getCurrentLevel(), getVal(skill));
setSkillBalance("balance" + skill, balance);
} else {
setCnt("eff" + skill, "");
}
}
function calcStatPoolBalance() {
var level = getVal("lvl");
var lvl_stats = 35 + 5 + Math.floor(parseInt(level) / 4);
var balance = lvl_stats - parseInt(getTotalAssignedStats());
setBalance("statpoints", balance);
}
function calcSkillPoolBalance() {
var level = getCurrentLevel();
var total_pool = ((parseInt(level) - 1) * 40) + 120;
var balance = total_pool - parseInt(getTotalAssignedSkills());
setBalance("skillpoints", balance);
}
function calculateSkillBalance(lvl, val) {
return ((parseInt(lvl) - 1) * 5 + 15) - parseInt(val);
}
function setSkillBalance(id, val) {
if (val < 0) {
document.getElementById(id).style.color = "red";
if (val != 0) {
setCnt(id, "[" + val + "]");
} else {
setCnt(id, "");
}
} else {
document.getElementById(id).style.color = "black";
setCnt(id, "");
}
}
function setBalance(id, val) {
if (val >= 0) {
document.getElementById(id).style.color = "black";
} else {
document.getElementById(id).style.color = "red";
}
setCnt(id, val);
}
function calcSkillBonus(ability, skill) {
ability = parseInt(ability);
skill = parseInt(skill);
if (ability > 4) {
return Math.floor((1 + ((ability - 4) * 0.085)) * skill);
}
if (ability < 4) {
return Math.floor((1 - ((4 - ability) * 0.1)) * skill);
}
return skill;
}
function reset() {
setVal("lvl", 1);
document.getElementById("STR").value = 5;
document.getElementById("DEX").value = 5;
document.getElementById("AGI").value = 5;
document.getElementById("CON").value = 5;
document.getElementById("PER").value = 5;
document.getElementById("WIL").value = 5;
document.getElementById("INT").value = 5;
setBalance("statpoints", 5);
resetSkill("GUNS");
resetSkill("THROWING");
resetSkill("CROSSBOWS");
resetSkill("MELEE");
resetSkill("DODGE");
resetSkill("EVASION");
resetSkill("STEALTH");
resetSkill("HACKING");
resetSkill("LOCKPICKING");
resetSkill("PICKPOCKETING");
resetSkill("TRAPS");
resetSkill("MECHANICS");
resetSkill("ELECTRONICS");
resetSkill("CHEMISTRY");
resetSkill("BIOLOGY");
resetSkill("TAILORING");
resetSkill("TCONTROL");
resetSkill("PSY");
resetSkill("META");
resetSkill("PERSUASION");
resetSkill("INTIMIDATION");
resetSkill("MERCANTILE");
document.getElementById("skillpoints").style.color = "black";
setCnt("skillpoints", 120);
}
function resetSkill(s) {
document.getElementById(s).value = 0;
setCnt("eff" + s, "");
setCnt("balance" + s, "");
}
function getTotalAssignedSkills() {
return parseInt(getVal("GUNS")) + parseInt(getVal("THROWING"))
+ parseInt(getVal("CROSSBOWS")) + parseInt(getVal("MELEE"))
+ parseInt(getVal("DODGE")) + parseInt(getVal("EVASION"))
+ parseInt(getVal("STEALTH")) + parseInt(getVal("HACKING"))
+ parseInt(getVal("LOCKPICKING"))
+ parseInt(getVal("PICKPOCKETING")) + parseInt(getVal("TRAPS"))
+ parseInt(getVal("MECHANICS")) + parseInt(getVal("ELECTRONICS"))
+ parseInt(getVal("CHEMISTRY")) + parseInt(getVal("BIOLOGY"))
+ parseInt(getVal("TAILORING")) + parseInt(getVal("TCONTROL"))
+ parseInt(getVal("PSY")) + parseInt(getVal("META"))
+ parseInt(getVal("PERSUASION")) + parseInt(getVal("INTIMIDATION"))
+ parseInt(getVal("MERCANTILE"));
}
function getTotalAssignedStats() {
return parseInt(getVal("STR")) + parseInt(getVal("DEX"))
+ parseInt(getVal("AGI")) + parseInt(getVal("CON"))
+ parseInt(getVal("PER")) + parseInt(getVal("WIL"))
+ parseInt(getVal("INT"));
}
function getCurrentLevel() {
return getVal("lvl");
}
function getVal(id) {
return document.getElementById(id).value;
}
function setVal(id, val) {
return document.getElementById(id).value = val;
}
function setCnt(id, val) {
return document.getElementById(id).innerHTML = val;
}
</script>
<style>
.statLabels{
display: block;
float: left;
width: 50px;
}
.skillLabels{
display: block;
float: left;
width: 110px;
}
input {
width: 50px;
}
#currentLevel{
background-color:black;
color:white;
text-align:center;
padding:5px;
}
#stats {
height: 700px;
float:left;
margin-right:200px;
padding:10px;
}
#skills {
float:center;
padding:10px;
}
#emptyspace {
float:left;
padding:10px;
}
</style>
</body>
</html>