As another component of my game I wanted to create a new popup window for Skills, now I have the window aspect mostly working but I'm trying to figure out an issue with variable scoping when by referencing through to another function and I tried various methods but JS seems to be very confusing when it comes to this compared to other languages I know and use regularly so I created this example to debug but I'm not getting much further at the moment so I came for help.
My variable availableSP doesn't want to be updated beyond the call to increaseSkill(), and also for some weird reason my "INT" skill (or any 1st entry in the skills[] array) cannot be found by my array search function arrayObjectIndexOf().
Any ideas what I'm doing wrong please?
data.js
"use strict"
createItem("me", PLAYER(), {
loc: "lounge",
skillpoints: 4,
intelligence: 1,
strength: 1,
stamina: 1,
magic: 1,
synonyms:['me', 'myself'],
examine: "Just a regular guy.",
})
createRoom("lounge", {
desc:"The lounge is boring, the author really needs to put stuff in it.",
})
createItem("SkillWindow", {
alias: "Skill Window",
loc: "lounge",
hereVerbs: ["Interact"],
examine: "A tool for upgrading your skills",
interact: function () {
msg("<a href=\"javascript:void(0);\" onclick=\"skillsUpgrade(w.me.skillpoints)\">Upgrade</a>")
},
})
const skills = [
{
name: "INT",
desc: "Intelligence",
title: "Your character's intelligence level",
currentValue: 0,
maxValue: 0,
skillIncrement: 1,
skillPointsAdded: 0
},
{
name: "STR",
desc: "Strength",
title: "Your character's strength level",
currentValue: 0,
maxValue: 100,
skillIncrement: 1,
skillPointsAdded: 0
},
{
name: "STA",
desc: "Stamina",
title: "Your character's stamina level",
currentValue: 0,
maxValue: 100,
skillIncrement: 1,
skillPointsAdded: 0
},
{
name: "MAG",
desc: "Stamina",
title: "Your character's stamina level",
currentValue: 0,
maxValue: 0,
skillIncrement: 2,
skillPointsAdded: 0
}
]
let availableSP = 4
function skillsUpgrade() {
console.log("Available Skill Points Before - " + availableSP)
for (let skill of skills) {
switch (skill.name) {
case "INT":
skill.currentValue = w.me.intelligence
break;
case "STR":
skill.currentValue = w.me.strength
break;
case "STA":
skill.currentValue = w.me.stamina
break;
case "MAG":
skill.currentValue = w.me.stamina
break;
}
console.log("Skill " + skill.name + " Old Value - " + skill.currentValue)
increaseSkill(skill.name, 1, availableSP)
console.log("Skill " + skill.name + " New Value - " + skill.currentValue)
console.log("Available Skill Points After - " + availableSP)
}
}
function increaseSkill(sSkill, skillpoint, availableSP) {
var iSkillIndex = arrayObjectIndexOf(skills, sSkill, "name");
if (iSkillIndex < 1) {
// Something went wrong
console.log("Skill " + sSkill + " not found in skill list")
return false
}
else {
console.log("Skill " + sSkill + " found in skill list")
}
var skill = skills[iSkillIndex]
skill.skillPointsAdded += skillpoint
skill.currentValue += (skill.skillIncrement * skill.skillPointsAdded)
availableSP--
console.log("Available Skill Points Inside - " + availableSP)
// Update the array again
skills[iSkillIndex] = skill
}
function arrayObjectIndexOf(myArray, searchTerm, property) {
for (var i = 0, len = myArray.length; i < len; i++) {
if (myArray[i][property] === searchTerm)
return i;
}
return -1;
}
You're passing availableSP
as an argument to the function increaseSkill
. This creates a local variable named availableSP
which starts with the same value as the one outside the function.
At the start of the increaseSkill function, you also have:
if (iSkillIndex < 1) { // Something went wrong
Note that the first item in an array has index 0 - so this will treat the first item in the array as an error. You probably wanted if (iSkillIndex < 0) {
Doh, I'm so used to languages being able to handle by ref with local versions of the same variable name, I'll try to remember that. Also thanks for the array fix too.