Page 1 of 1

Tables and onNPCKill

Posted: Tue Oct 27, 2020 6:14 am
by ShadowXeldron
I'm currently trying to write a Level/XP script. I have got the leveling up and all that to work using a pair of custom functions called GainXP and LevelUpb , but then it comes to actually writing I initially started off using something along the lines of this:

Code: Select all

function onNPCKill(EventObj, killedNPC, killReason)
    if killedNPC.id == 1 then
    	GainXP(1)
    end
end
GainXP is a function I made to automate the experience gaining process, along with another function, LevelUp. Since if killedNPC == x has to be typed out every single time, it's a pain to use and isn't exactly multi-level. Instead, I declared a table and a function to go with it called xpDrop, with the intention of adding xpDrop to each level's luna.lua, as well as in the singular one for the episode. However, when I try to run this code:

Code: Select all

function onNPCKill(EventObj, killedNPC, killReason)
    if xpDrops[killedNPC.id] ~= nil then
        GainXP(xpDrops[killedNPC.id])
    end
end
Nothing happens. If I run GainXP(xpDrops[x]) using the tab prompt then I do get the experience for that NPC. What is the proper way of doing this?

Re: Tables and onNPCKill

Posted: Tue Oct 27, 2020 6:41 am
by Emral
The second piece of code looks right at a glance, but it's hard to tell without seeing where xpDrops is defined. Can you hastebin the entire script?

Re: Tables and onNPCKill

Posted: Tue Oct 27, 2020 7:16 am
by ShadowXeldron
This file is named Stats.lua, separated into a seperate file keep the luna.lua a bit cleaner.

Code: Select all

xpDrops = {

}

SaveData["episode"] = SaveData["episode"] or {}
stat = SaveData["episode"]

--Set up the levelup function 

if stat.level == nil then
    stat.level = 1
end

if stat.xp == nil then
    stat.xp = 0
end

LevelUp = function(x) -- LevelUp - This grants a level. Input a minus number to make the player level down.
	stat.level = stat.level + x
end

GainXP = function(x) -- GainXP - This function grants you experience points.
    stat.xp = stat.xp + x
    if stat.xp > stat.level * 5 + stat.level then
        LevelUp(1)
    end
end

function xpDrop(NPCID, reward) -- Replace NPCID with the ID of the NPC in question and reward with the XP drop.
    xpDrops[NPCID] = reward
end

xpCheck = true

function onNPCKill(EventObj, killedNPC, killReason)
    if xpDrops[killedNPC.id] ~= nil then
        GainXP(xpDrops[killedNPC.id])
    end
end
If need be, I'll provide the luna.lua.

Re: Tables and onNPCKill

Posted: Tue Oct 27, 2020 8:36 am
by Emral
Your issue is likely that you don't define any scope anywhere. All your variables are global (including onNPCKill) so when they are redefined in other files, they are replaced (i.e. if your luna.lua has an onNPCKill, the one in this file won't run anymore). Properly scope your variables and the error should take care of itself. Also the table is empty.

Re: Tables and onNPCKill

Posted: Tue Oct 27, 2020 10:39 am
by ShadowXeldron
Okay, so I tried localizing the OnNPCKill function. Still nothing. BUT when I moved that onNPCKill function to the main luna.lua...

It works! The SMB1 koopa is declared in the luna.lua for that level, and I tried on a different level afterwards, where the SMB1 koopa wasn't defined, proving that the function works locally. I moved it back into Stats.lua, and it stopped working again. I don't mind leaving the onNPCKill function in my luna.lua.If I make either the table or onNPCkill local the script breaks again. I really don't know why it would not work in Stats.lua.

Either way, it works now and I'm not bothered one bit. Thanks!

Re: Tables and onNPCKill

Posted: Tue Oct 27, 2020 10:57 am
by Emral
You don't just localize a lunalua event. I recommend the tutorial for how to make a library:
https://wohlsoft.ru/pgewiki/How_To:_Mak ... ua_library
You need to register the event. You could also look at any basegame library for reference, since a lot of them do use onNPCKill.

Re: Tables and onNPCKill

Posted: Tue Oct 27, 2020 12:14 pm
by ShadowXeldron
Okay, it is now in library format and works perfectly fine, following the guide.

Code: Select all

--Stats.lua

--NOTE TO SELF: "stat" is Levels and Experience, "stats" marks

local stats = {} -- API Table. I don't have a clue what this does.

local xpDrops = {

}

function stats.xpDrop(NPCID, reward) -- xpDrop - Adds an enemy and its experience drop to the xpDrops. Not to be confusedd with it! Replace NPCID with the ID of the NPC in question and reward with the XP drop.
    xpDrops[NPCID] = reward
end

SaveData["episode"] = SaveData["episode"] or {}
local stat = SaveData["episode"]

--Initialize values 

function stats.onInitAPI()
    if stat.level == nil then
        stat.level = 1
    end

    if stat.xp == nil then
        stat.xp = 0
    end
    --Register onNPCKill
    registerEvent(stats,"onNPCKill","onNPCKill",false)

end

function stats.LevelUp(x) -- LevelUp - This grants a level. Input a minus number to make the player level down.
	stat.level = stat.level + x
end

function stats.GainXP(x) -- GainXP - This function grants you experience points.
    stat.xp = stat.xp + x
    if stat.xp > stat.level * 5 + stat.level then
        repeat
            stat.xp = stat.xp - (stat.level * 5 + stat.level)
            stats.LevelUp(1) --Keep going until you haven't got enough experience points
        until stat.xp < stat.level * 5 + stat.level
    end
end

function stats.onNPCKill(EventObj, killedNPC, killReason) -- Check for XP drops
    if xpDrops[killedNPC.id] ~= nil then
        stats.GainXP(xpDrops[killedNPC.id])
    end
end

return stats

Re: Tables and onNPCKill

Posted: Tue Oct 27, 2020 12:49 pm
by Emral
Little tip: If you want to access xpDrops from other files that load this library, you can replace local xpDrops with stats.xpDrops.
Another way of doing the same thing that's a little safer is to instead create a stats.setNpcXP function that does the math internally. The benefit of this method is that you can't accidentally delete everything set by other lua files, since the table is never directly accessed from outside the library file.

Glad it works now, though!

Re: Tables and onNPCKill

Posted: Tue Oct 27, 2020 12:51 pm
by ShadowXeldron
Enjl wrote:
Tue Oct 27, 2020 12:49 pm
Little tip: If you want to access xpDrops from other files that load this library, you can replace local xpDrops with stats.xpDrops.
Another way of doing the same thing that's a little safer is to instead create a stats.setNpcXP function that does the math internally. The benefit of this method is that you can't accidentally delete everything set by other lua files, since the table is never directly accessed from outside the library file.

Glad it works now, though!
Okay, Thanks!