Tables and onNPCKill

Post here for help and support regarding LunaLua and SMBX2's libraries and features.

Moderator: Userbase Moderators

ShadowXeldron
Snifit
Snifit
Posts: 232
Joined: Sun Dec 08, 2019 8:21 am
Flair: phpBB > ProBoards
Pronouns: He/Him
Contact:

Tables and onNPCKill

Postby ShadowXeldron » Tue Oct 27, 2020 6:14 am

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?

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9865
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: Tables and onNPCKill

Postby Emral » Tue Oct 27, 2020 6:41 am

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?

ShadowXeldron
Snifit
Snifit
Posts: 232
Joined: Sun Dec 08, 2019 8:21 am
Flair: phpBB > ProBoards
Pronouns: He/Him
Contact:

Re: Tables and onNPCKill

Postby ShadowXeldron » Tue Oct 27, 2020 7:16 am

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.

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9865
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: Tables and onNPCKill

Postby Emral » Tue Oct 27, 2020 8:36 am

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.

ShadowXeldron
Snifit
Snifit
Posts: 232
Joined: Sun Dec 08, 2019 8:21 am
Flair: phpBB > ProBoards
Pronouns: He/Him
Contact:

Re: Tables and onNPCKill

Postby ShadowXeldron » Tue Oct 27, 2020 10:39 am

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!

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9865
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: Tables and onNPCKill

Postby Emral » Tue Oct 27, 2020 10:57 am

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.

ShadowXeldron
Snifit
Snifit
Posts: 232
Joined: Sun Dec 08, 2019 8:21 am
Flair: phpBB > ProBoards
Pronouns: He/Him
Contact:

Re: Tables and onNPCKill

Postby ShadowXeldron » Tue Oct 27, 2020 12:14 pm

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

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9865
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: Tables and onNPCKill

Postby Emral » 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!

ShadowXeldron
Snifit
Snifit
Posts: 232
Joined: Sun Dec 08, 2019 8:21 am
Flair: phpBB > ProBoards
Pronouns: He/Him
Contact:

Re: Tables and onNPCKill

Postby ShadowXeldron » Tue Oct 27, 2020 12:51 pm

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!


Return to “LunaLua Help”

Who is online

Users browsing this forum: No registered users and 2 guests

SMWCentralTalkhausMario Fan Games GalaxyKafukaMarioWikiSMBXEquipoEstelari