Jump to content

Unable to check if a player has a trait.


corkscrewer

Recommended Posts

Hello! I am in the early stages of creating a mod, however, code that seems to work for OTHER mods I looked inside of to get a good idea of how modding works, does not appear to work for MY mod. What I am attempting to do is create a new trait, and print something every minute if the player has said trait. All Lua files are in the Client folder. Help would be appreciated.

 

To make the trait selectable in character creator (does so correctly)

[spoiler][code]local function initTrait()	
	local Weeb = TraitFactory.addTrait("Weeb", "Weeb", -4, "+1 long blade. Read manga or become stressed. Also become less stressed from reading it.", false, true);
		Weeb:addXPBoost(Perks.LongBlade, 1)
end

Events.OnGameBoot.Add(initTrait);[/code][/spoiler]

 

Attempting to make the trait function (errors with the error of "attempted index: hasTrait of non-table: null".

 

[spoiler][code]function traitfunctionweeb()
    if player:hasTrait("Weeb") == true then
        print("my name is spongebob")
    else
        print("my name is not spongebob")
    end
end
Events.EveryOneMinute.Add(traitfunctionweeb)[/code][/spoiler]
Link to comment
Share on other sites

I've been personally curious to learn how to add traits to Project Zomboid in a mod so I could test some ideas, and would like to learn from yourself, given my lack of familarity with the game's code.

 

That said, looking at your issue, there's a couple of vague-ish posts on other sides that mention similar errors (Stack Overflow, Steam and Github), which give not-too-helpful hints.

 

I'm not familiar with Lua specifically, but based on my own programming experience, "attempted index: hasTrait of non-table: null" would suggest to me the variable you're trying to use the 'hasTrait' to index 'isn't a table', and therefore, with no index, can only return a 'null'. A table is an item that has an index (an index can either be numerical, via an iterator, or text via a key or hash).

 

The Github link gives us a small insight, where the writer remarks their own solution was to put:

if not player then
return end

 

In your case, you need to check that when the function is being run, that player actually exists (I.E. the function is most likely being run on some sort of NPC). You most likely need to check if the current instance is actually a player. Again, I'm not familiar with Lua or Project Zomboid's code, but it would probably look something like this:

 

function traitfunctionweeb()

    if player then

        if player:hasTrait("Weeb") == true then
            print("my name is spongebob")
        else
            print("my name is not spongebob")
        end
        
    end
end

 

Or alternatively:

 

function traitfunctionweeb()

    if not player then
        return end
    end

    if player:hasTrait("Weeb") == true then
        print("my name is spongebob")
    else
        print("my name is not spongebob")
    end
end

 

Which layout you use depends on what you intend to do within the function and is entirely at your discretion. Note this is purely a guess and might be wrong in some way.

 

 

Link to comment
Share on other sites

8 hours ago, SilentLight said:

I've been personally curious to learn how to add traits to Project Zomboid in a mod so I could test some ideas, and would like to learn from yourself, given my lack of familarity with the game's code.

 

That said, looking at your issue, there's a couple of vague-ish posts on other sides that mention similar errors (Stack Overflow, Steam and Github), which give not-too-helpful hints.

 

I'm not familiar with Lua specifically, but based on my own programming experience, "attempted index: hasTrait of non-table: null" would suggest to me the variable you're trying to use the 'hasTrait' to index 'isn't a table', and therefore, with no index, can only return a 'null'. A table is an item that has an index (an index can either be numerical, via an iterator, or text via a key or hash).

 

The Github link gives us a small insight, where the writer remarks their own solution was to put:

if not player then
return end

 

In your case, you need to check that when the function is being run, that player actually exists (I.E. the function is most likely being run on some sort of NPC). You most likely need to check if the current instance is actually a player. Again, I'm not familiar with Lua or Project Zomboid's code, but it would probably look something like this:

 

function traitfunctionweeb()

    if player then

        if player:hasTrait("Weeb") == true then
            print("my name is spongebob")
        else
            print("my name is not spongebob")
        end
        
    end
end

 

Or alternatively:

 

function traitfunctionweeb()

    if not player then
        return end
    end

    if player:hasTrait("Weeb") == true then
        print("my name is spongebob")
    else
        print("my name is not spongebob")
    end
end

 

Which layout you use depends on what you intend to do within the function and is entirely at your discretion. Note this is purely a guess and might be wrong in some way.

 

 

This has prevented the error from occurring, however, the trait is pickable in character creation but vanishes for some reason when you load into the world. Thank you for this progress though.

Link to comment
Share on other sites

21 minutes ago, corkscrewer said:

This has prevented the error from occurring, however, the trait is pickable in character creation but vanishes for some reason when you load into the world. Thank you for this progress though.

I would love to help you further, however I don't know know anything about Project Zomboid's underlying code. Perhaps some rubber duck debugging will help? With me acting as the rubber duck. Explain to me, step by step, what your code actually does, walk me through it. (In doing so, you might have a realisation of an oversight in the code or spot a flaw, and I'm happy to learn how modding works.)

Link to comment
Share on other sites

22 hours ago, corkscrewer said:

This has prevented the error from occurring, however, the trait is pickable in character creation but vanishes for some reason when you load into the world. Thank you for this progress though.

I've been attempting to educate myself slowly on the modding aspects of PZ, and I've found something that may relate to your problem, although I am not sure as I don't know too much on how your code should work.

 

According to this guide, it says one surprising behaviour is that "functions called from Lua will often return Java objects", and goes on to state that "Java Arrays and Lists in particular can catch people off guard, since they are quite different from a Lua table list.". The example they give is similar to yours:

 

Quote
local known = player:getKnownRecipes() -- returns a Java List, not a Lua table.

 

Essentially, a Java Array and List use a different means of iteration, compared to a Lua table. So, it may not be the code 'doesn't find' the trait, but instead, the object may not actually be a Lua table in the first place, and thus something like

:hasTrait("Weeb")

 

May not work and it might need to be

 

Quote

:contains("some string")

But again, speculative. I am not familiar with Lua or PZ enough to say. I'm just mentioning this in-case it helps you.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...