//Each weapon is equivalent to 300k mana points - 600 ultimate mana potions * 500 average value, and all vocs progress their main skill at the same rate with the weapons
function submit_exercise_form() {
// Get the required field values
const currentSkill = document.getElementById("currentskill").value;
const targetSkill = document.getElementById("targetskill").value;
// Check if the fields are empty or invalid
if (!currentSkill || currentSkill.trim() === "") {
alert("Please enter your current skill level. You cannot proceed without specifying your current skill.");
document.getElementById("currentskill").focus();
return;
}
if (!targetSkill || targetSkill.trim() === "") {
alert("Please enter your target skill level. You cannot proceed without specifying your target skill.");
document.getElementById("targetskill").focus();
return;
}
// Validate that the values are numbers
if (isNaN(currentSkill) || currentSkill <= 0) {
alert("Please enter a valid current skill level (must be a positive number).");
document.getElementById("currentskill").focus();
return;
}
if (isNaN(targetSkill) || targetSkill <= 0) {
alert("Please enter a valid target skill level (must be a positive number).");
document.getElementById("targetskill").focus();
return;
}
// Check if target skill is higher than current skill
if (parseFloat(targetSkill) <= parseFloat(currentSkill)) {
alert("Your target skill must be higher than your current skill level.");
document.getElementById("targetskill").focus();
return;
}
points_main_skill_regular_weapon = 300000;
points_main_skill_durable_weapon = points_main_skill_regular_weapon * 3.6;
points_main_skill_lasting_weapon = points_main_skill_regular_weapon * 28.8;
cost_regular_k = 347.222
cost_regular_tc = 25
cost_durable_k = 1250
cost_durable_tc = 90
cost_lasting_k = 10000
cost_lasting_tc = 720
magic_skill_constant = 1600;
main_magic_constant = 1.1;
exerciseformrvalues = document.getElementById("vocation_exercise_form");
exerciseformresults = document.getElementById("exerciseformresults");
exerciseformresults.innerHTML = ""
vocation_and_type = document.getElementById("vocation").value;
currentskill = document.getElementById("currentskill").value;
currentskillpercentage = document.getElementById("currentskillpercentage").value;
if (currentskillpercentage.includes(",")) {
currentskillpercentage = currentskillpercentage.replace(",", ".")
}
targetskill = document.getElementById("targetskill").value;
loyalty = document.getElementById("loyalty").value;
IsDummy = document.getElementById("dummy").checked;
IsEvent = document.getElementById("event").checked;
vocation_constant = 1.1
if (vocation_and_type == "Paladin Magic") {
vocation_constant = 1.4
}
else if (vocation_and_type == "Monk Magic") {
vocation_constant = 1.25
}
else if (vocation_and_type == "Knight Magic") {
vocation_constant = 3.0
}
points_required = main_skill_calculation_points_required(vocation_constant, currentskill, currentskillpercentage, targetskill, IsDummy, IsEvent, 0)
regular_weapons_required = Math.ceil(points_required / (points_main_skill_regular_weapon * (1 + (loyalty / 100))))
durable_weapons_required = Math.ceil(points_required / (points_main_skill_durable_weapon * (1 + (loyalty / 100))))
lasting_weapons_required = Math.ceil(points_required / (points_main_skill_lasting_weapon * (1 + (loyalty / 100))))
regular_k_or_kk = "k"
regular_cost = regular_weapons_required * cost_regular_k
regular_cost_tc = regular_weapons_required * cost_regular_tc
if (Math.round(regular_cost) > 1000) {
regular_cost = regular_cost / 1000
regular_k_or_kk = "kk"
regular_cost = Math.round(regular_cost * 100) / 100
}
durable_k_or_kk = "k"
durable_cost = durable_weapons_required * cost_durable_k
durable_cost_tc = durable_weapons_required * cost_durable_tc
if (Math.round(durable_cost) > 1000) {
durable_cost = durable_cost / 1000
durable_k_or_kk = "kk"
}
lasting_k_or_kk = "k"
lasting_cost = lasting_weapons_required * cost_lasting_k
lasting_cost_tc = lasting_weapons_required * cost_lasting_tc
if (Math.round(lasting_cost) > 1000) {
lasting_cost = lasting_cost / 1000
lasting_k_or_kk = "kk"
}
//filling out the html after calculation
IsTCOver13900 = IsDummy = document.getElementById("tc_price").checked;
if (IsTCOver13900) {
exerciseformresults.innerHTML = "To get from skill " + currentskill + " to skill " + targetskill + ", you need to use a total of:
"
+ regular_weapons_required + " regular exercise weapons, at a cost of " + regular_cost + " " + regular_k_or_kk + ", time required: " + Math.floor(regular_weapons_required / 3.6) + " hours and " + Math.round(((regular_weapons_required * 10) % 36) * 1.667) + " minutes
"
+ durable_weapons_required + " durable exercise weapons, at a cost of " + durable_cost + " " + durable_k_or_kk + ", time required: " + durable_weapons_required + " hours
"
+ lasting_weapons_required + " lasting exercise weapons, at a cost of " + lasting_cost + " " + lasting_k_or_kk + ", time required: " + lasting_weapons_required * 8 + " hours"
}
else {
exerciseformresults.innerHTML = "To get from skill " + currentskill + " to skill " + targetskill + ", you need to use a total of:
"
+ regular_weapons_required + " regular exercise weapons, at a cost of " + regular_cost_tc + " Tibia Coins, time required: " + Math.floor(regular_weapons_required / 3.6) + " hours and " + Math.round(((regular_weapons_required * 10) % 36) * 1.667) + " minutes
"
+ durable_weapons_required + " durable exercise weapons, at a cost of " + durable_cost_tc + " Tibia Coins, time required: " + durable_weapons_required + " hours
"
+ lasting_weapons_required + " lasting exercise weapons, at a cost of " + lasting_cost_tc + " Tibia Coins, time required: " + lasting_weapons_required * 8 + " hours"
}
}
function main_skill_calculation_points_required(vocation_constant, currentskill, currentskillpercentage, targetskill, IsDummy, IsEvent, skill_offset) {
current_skill_total_points = total_skill_points_at_given_level(1600, vocation_constant, parseInt(currentskill) + 1, skill_offset)
points_to_next_skill = points_to_next_skill_level(1600, vocation_constant, parseInt(currentskill), skill_offset) * (currentskillpercentage / 100)
target_skill_total_points = total_skill_points_at_given_level(1600, vocation_constant, targetskill, skill_offset)
total_points_needed_for_target = (target_skill_total_points - (current_skill_total_points - points_to_next_skill))
// / (1 + (loyalty / 100))
if (IsEvent) {
total_points_needed_for_target = total_points_needed_for_target / 2
}
if (IsDummy) {
total_points_needed_for_target = total_points_needed_for_target / 1.1
}
return total_points_needed_for_target
}
function points_to_next_skill_level(skill_constant, vocation_constant, skill, skill_offset) {
exponent = Math.pow(vocation_constant, skill - skill_offset)
total_points = skill_constant * exponent
return total_points
}
function total_skill_points_at_given_level(skill_constant, vocation_constant, skill, skill_offset) {
exponent = Math.pow(vocation_constant, skill - skill_offset)
total_points = skill_constant * ((exponent - 1) / (vocation_constant - 1))
return total_points
}
function submit_exercise_form_spend() {
// Get the required field values
const weaponCount = document.getElementById("weaponcount_spend").value;
const currentSkill = document.getElementById("currentskill_spend").value;
// Check if the number of weapons field is empty or invalid
if (!weaponCount || weaponCount <= 0) {
alert("Please enter a valid number of weapons. You cannot proceed without specifying how many exercise weapons you want to use.");
document.getElementById("weaponcount_spend").focus();
return;
}
// Check if the current skill field is empty or invalid
if (!currentSkill || currentSkill.trim() === "") {
alert("Please enter your current skill level. You cannot proceed without specifying your current skill.");
document.getElementById("currentskill_spend").focus();
return;
}
// Validate that the current skill value is a number
if (isNaN(currentSkill) || currentSkill <= 0) {
alert("Please enter a valid current skill level (must be a positive number).");
document.getElementById("currentskill_spend").focus();
return;
}
// If validation passes, proceed with the calculation
calculate_skill_gain_from_weapons();
}
function calculate_skill_gain_from_weapons() {
// Get form values
const vocationAndType = document.getElementById("vocation_spend").value;
const weaponType = document.getElementById("weapontype_spend").value;
const weaponCount = parseInt(document.getElementById("weaponcount_spend").value);
const currentSkill = parseFloat(document.getElementById("currentskill_spend").value);
const currentSkillPercentage = parseFloat(document.getElementById("currentskillpercentage_spend").value);
const loyalty = parseFloat(document.getElementById("loyalty_spend").value);
const isDummy = document.getElementById("dummy_spend").checked;
const isEvent = document.getElementById("event_spend").checked;
const isTCOver13900 = document.getElementById("tc_price_spend").checked;
// Exercise weapon skill points (same as in original function)
const pointsMainSkillRegularWeapon = 300000;
const pointsMainSkillDurableWeapon = pointsMainSkillRegularWeapon * 3.6;
const pointsMainSkillLastingWeapon = pointsMainSkillRegularWeapon * 28.8;
// Costs
const costRegularK = 347.222;
const costRegularTc = 25;
const costDurableK = 1250;
const costDurableTc = 90;
const costLastingK = 10000;
const costLastingTc = 720;
// Determine weapon type and points
let weaponPoints, weaponCostK, weaponCostTc, weaponTime;
if (weaponType === "Regular") {
weaponPoints = pointsMainSkillRegularWeapon;
weaponCostK = costRegularK;
weaponCostTc = costRegularTc;
weaponTime = weaponCount / 3.6; // hours
} else if (weaponType === "Durable") {
weaponPoints = pointsMainSkillDurableWeapon;
weaponCostK = costDurableK;
weaponCostTc = costDurableTc;
weaponTime = weaponCount; // hours
} else if (weaponType === "Lasting") {
weaponPoints = pointsMainSkillLastingWeapon;
weaponCostK = costLastingK;
weaponCostTc = costLastingTc;
weaponTime = weaponCount * 8; // hours
}
// Calculate total points gained (with loyalty bonus)
let totalPointsGained = weaponCount * weaponPoints * (1 + (loyalty / 100));
// Apply modifiers (reverse of the original calculation)
if (isEvent) {
totalPointsGained = totalPointsGained * 2; // Double event doubles the points
}
if (isDummy) {
totalPointsGained = totalPointsGained * 1.1; // Private dummy gives 10% bonus
}
// Determine vocation constant
let vocationConstant = 1.1;
if (vocationAndType === "Paladin Magic") {
vocationConstant = 1.4;
} else if (vocationAndType === "Monk Magic") {
vocationConstant = 1.25;
} else if (vocationAndType === "Knight Magic") {
vocationConstant = 3.0;
}
// Calculate current skill total points
const currentSkillTotalPoints = total_skill_points_at_given_level(1600, vocationConstant, Math.floor(currentSkill) + 1, 0);
const pointsToNextSkill = points_to_next_skill_level(1600, vocationConstant, Math.floor(currentSkill), 0) * (currentSkillPercentage / 100);
const currentSkillEffectivePoints = currentSkillTotalPoints - pointsToNextSkill;
// Calculate new total points after using weapons
const newTotalPoints = currentSkillEffectivePoints + totalPointsGained;
// Find the skill level that corresponds to these total points
const newSkillLevel = find_skill_level_from_points(1600, vocationConstant, newTotalPoints);
// Calculate costs
let costK = weaponCount * weaponCostK;
let costTc = weaponCount * weaponCostTc;
let costUnit = "k";
if (Math.round(costK) > 1000) {
costK = costK / 1000;
costUnit = "kk";
costK = Math.round(costK * 100) / 100;
}
// Format time
let timeDisplay;
if (weaponType === "Regular") {
const hours = Math.floor(weaponTime);
const minutes = Math.round((weaponTime % 1) * 60);
timeDisplay = hours + " hours and " + minutes + " minutes";
} else {
timeDisplay = Math.round(weaponTime) + " hours";
}
// Calculate precise current skill level
const preciseCurrentSkill = Math.floor(currentSkill) + ((100 - currentSkillPercentage) / 100);
// Display results
const exerciseFormResults = document.getElementById("exerciseformresults_spend");
const skillGain = newSkillLevel - preciseCurrentSkill;
if (isTCOver13900) {
exerciseFormResults.innerHTML = "Using " + weaponCount + " " + weaponType.toLowerCase() + " exercise weapons will give you:
" +
skillGain.toFixed(2) + " skill levels
" +
"You will go from skill " + preciseCurrentSkill.toFixed(2) + " to approximately skill " + newSkillLevel.toFixed(2) + "
" +
"Cost: " + costK + " " + costUnit + "
" +
"Time required: " + timeDisplay;
} else {
exerciseFormResults.innerHTML = "Using " + weaponCount + " " + weaponType.toLowerCase() + " exercise weapons will give you:
" +
skillGain.toFixed(2) + " skill levels
" +
"You will go from skill " + preciseCurrentSkill.toFixed(2) + " to approximately skill " + newSkillLevel.toFixed(2) + "
" +
"Cost: " + costTc + " Tibia Coins
" +
"Time required: " + timeDisplay;
}
}
function find_skill_level_from_points(skill_constant, vocation_constant, total_points) {
// This function finds the skill level that corresponds to a given total points
// We need to solve for skill in the equation: total_points = skill_constant * ((vocation_constant^skill - 1) / (vocation_constant - 1))
// Rearranging: vocation_constant^skill = (total_points * (vocation_constant - 1) / skill_constant) + 1
// Then: skill = log_vocation_constant((total_points * (vocation_constant - 1) / skill_constant) + 1)
const logBase = (total_points * (vocation_constant - 1) / skill_constant) + 1;
const skill = Math.log(logBase) / Math.log(vocation_constant);
return skill;
}