Project Zomboid

Project Zomboid

Plushie Bombs
Profession Creation Bug (With Potential Fix Provided)
I was running this mod in a collection with the mod "Occupations Expertises & Balance" and got an error about the mod not being able to properly obtain professions, with the code in question that throws the error being the following:


local function initOEProf() ProfessionFactory.addProfession("unemployed", getText("UI_prof_unemployed") , "profession_unemployed", 8); local doctor = ProfessionFactory.getProfession('doctor'); if not OE_isTraitInList(doctor:getFreeTraits(), "surgeon") then doctor:addFreeTrait("surgeon"); end



The error that the game throws when these two mods are run together is as follows:
`attempted index: getFreeTraits of non-table: null function: initOEProf -- file: OccupationsExpertisesTraits.lua line # 153 | MOD: Occupations Expertises & Balance java.lang.RuntimeException: attempted index: getFreeTraits of non-table: null at se.krka.kahlua.vm.KahluaThread.tableget(KahluaThread.java:1689) at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:641) at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163) at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980) at se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1812) at se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:66) at se.krka.kahlua.integration.LuaCaller.protectedCallVoid(LuaCaller.java:139) at zombie.Lua.Event.trigger(Event.java:64) at zombie.Lua.LuaEventManager.triggerEvent(LuaEventManager.java:65) at zombie.core.Core.ResetLua(Core.java:4186) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) at se.krka.kahlua.integration.expose.caller.MethodCaller.call(MethodCaller.java:62) at se.krka.kahlua.integration.expose.LuaJavaInvoker.call(LuaJavaInvoker.java:198) at se.krka.kahlua.integration.expose.MultiLuaJavaInvoker.call(MultiLuaJavaInvoker.java:60) at se.krka.kahlua.vm.KahluaThread.callJava(KahluaThread.java:182) at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:1007) at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163) at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980) at se.krka.kahlua.vm.KahluaThread.pcallBoolean(KahluaThread.java:1924) at se.krka.kahlua.integration.LuaCaller.protectedCallBoolean(LuaCaller.java:104) at zombie.ui.UIElement.onMouseUp(UIElement.java:1228) at zombie.ui.UIElement.onMouseUp(UIElement.java:1183) at zombie.ui.UIElement.onMouseUp(UIElement.java:1183) at zombie.ui.UIManager.update(UIManager.java:816) at zombie.GameWindow.logic(GameWindow.java:262) at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71) at zombie.GameWindow.frameStep(GameWindow.java:765) at zombie.GameWindow.run_ez(GameWindow.java:681) at zombie.GameWindow.mainThread(GameWindow.java:495) at java.base/java.lang.Thread.run(Unknown Source) `


I'm not too familiar with Project Zomboid modding in particular, but reading through the code, my guess is that the issue stems from the way the recipes are added to the Engineer profession prematurely within the lua/shared/~.PlushieBomb_Tweaks.lua file. On line 55, the "patchProfessionCreation()" function is ran outside of any other functions, causing the function to execute sooner than its supposed to. Changing the mod load order doesn't remedy this issue at all, but moving the function call to be inside of the Events.OnInitGlobalModData.Add() function in the same file solves the issue for me and stops throwing errors.



This is what the ~.PlushieBomb_Tweaks.lua file looks like for me after I implemented this hacky fix:

local function patchProfessionCreation() local original = BaseGameCharacterDetails.DoProfessions BaseGameCharacterDetails.DoProfessions = function () original() local engineer = ProfessionFactory.getProfession("engineer") engineer:getFreeRecipes():add("Craft Plushie Bomb") engineer:getFreeRecipes():add("Craft Plushie Bomb Dummy") end Events.OnGameBoot.Remove(original) Events.OnGameBoot.Add(BaseGameCharacterDetails.DoProfessions) end Events.OnInitGlobalModData.Add(function (newGame) local Util = require "PlushieBomb_Util" local sm = getScriptManager() local so = SandboxVars.PlushieBomb -- !! THIS LINE IS THE ONE THAT GOT MOVED !! patchProfessionCreation() local function mip(item) -- item:DoParam("TriggerExplosionTimer=" .. (so.TimerDuration * 40)) -- item:DoParam("ExplosionRange="..so.ExplosionRange) -- item:DoParam("ExplosionPower="..so.ExplosionRange) -- if so.Fire then -- end end local function hr(name) local recipe = sm:getRecipe(name) recipe:setIsHidden(true) recipe:setCanPerform("returnFalse") end if Util.Plushies:isEmpty() then hr("PlushieBomb.Craft Plushie Bomb") else for i = 0, Util.Plushies:size() - 1 do local ft = Util.Plushies:get(i):match("%.(.+)") local item = sm:getSpecificItem("PlushieBomb." .. ft) if item ~= nil then mip(item) else print(string.format("PlushieBomb: item %s does not exist",ft)) end end end if Util.DummyPlushies:isEmpty() then hr("PlushieBomb.Craft Plushie Bomb Dummy") else mip(sm:getItem("PlushieBomb.Dummy")) end end)


...which completely fixes the error on my side. No errors get thrown from either the Plushie Bombs mod or the Occupations Expertise & Balance mod when this version of the ~.PlushieBomb_Tweaks.lua file is used instead, at least for me. I haven't hopped into a new save to make sure the Engineer profession still gets the recipes for the Plushie Bombs in this instance, but in theory this shouldn't cause any differences at all whatsoever assuming that the patchProfessionCreation() function is safe to call under the Events.OnInitGlobalModData.Add() function.



Other mods that rely on the ProfessionFactory.getProfession() function would also break from the current live version of the Plushie Bombs mod if I'm understanding the code correctly, so this fix should theoretically solve any other compatibility issues that would arise with other profession mods. Sorry if my wording is kind of weird at points, writing this on 3 hours of sleep but I'm hoping this helps you guys out in some way! C':
< >
Showing 1-2 of 2 comments
the grim weeper 6 May, 2024 @ 3:25pm 
Tested my first fix and turns out it doesn't properly add the bomb recipe to the player's crafting recipe list when you choose to start as Engineer, but with the following changes to the code the mod no longer throws errors AND still gives Engineer players the recipe:
local function patchProfessionCreation() local original = BaseGameCharacterDetails.DoProfessions BaseGameCharacterDetails.DoProfessions = function () original() local engineer = ProfessionFactory.getProfession("engineer") engineer:getFreeRecipes():add("Craft Plushie Bomb") engineer:getFreeRecipes():add("Craft Plushie Bomb Dummy") end Events.OnGameBoot.Remove(original) Events.OnGameBoot.Add(BaseGameCharacterDetails.DoProfessions) end local function addEngineerRecipes() local engineer = ProfessionFactory.getProfession("engineer") engineer:getFreeRecipes():add("Craft Plushie Bomb") engineer:getFreeRecipes():add("Craft Plushie Bomb Dummy") end Events.OnInitGlobalModData.Add(function (newGame) local Util = require "PlushieBomb_Util" local sm = getScriptManager() local so = SandboxVars.PlushieBomb --patchProfessionCreation() local function mip(item) -- item:DoParam("TriggerExplosionTimer=" .. (so.TimerDuration * 40)) -- item:DoParam("ExplosionRange="..so.ExplosionRange) -- item:DoParam("ExplosionPower="..so.ExplosionRange) -- if so.Fire then -- end end local function hr(name) local recipe = sm:getRecipe(name) recipe:setIsHidden(true) recipe:setCanPerform("returnFalse") end if Util.Plushies:isEmpty() then hr("PlushieBomb.Craft Plushie Bomb") else for i = 0, Util.Plushies:size() - 1 do local ft = Util.Plushies:get(i):match("%.(.+)") local item = sm:getSpecificItem("PlushieBomb." .. ft) if item ~= nil then mip(item) else print(string.format("PlushieBomb: item %s does not exist",ft)) end end end if Util.DummyPlushies:isEmpty() then hr("PlushieBomb.Craft Plushie Bomb Dummy") else mip(sm:getItem("PlushieBomb.Dummy")) end end) Events.OnGameBoot.Add(addEngineerRecipes); Events.OnCreateLivingCharacter.Add(addEngineerRecipes);

This version just adds a new function that reuses the existing code to add the Plushie Bomb recipes to the engineer profession's recipe list, and then tells the game to call that function when the game boots up or when a player spawns in (?) via the OnGameBoot and OnCreateLivingCharacter events respectively.

I haven't rigorously tested these changes yet, but I tested it in a new singleplayer save as Engineer and the recipes get added without throwing any errors; since no major code is changed, this in theory shouldn't cause any new bugs to arise as the only code that got changed was the code that handled how the recipes are added to the Engineer profession. Worst case scenario, if this version of the script causes any errors, it should easily be fixed by just adding the "addEngineerRecipes" function to more events as opposed to just the OnGameBoot and OnCreateLivingCharacter events; I just chose these events in particular because it is how the Occupations Expertises & Balance mod decides to handle occupation-related code as well.
Poltergeist  [developer] 8 May, 2024 @ 1:01am 
From what you posted, it seems that you need to fix the other mod and the other author needs to upload the fix.

It should patch the vanilla function like this mod does otherwise it doesn't work in all cases where you go to character creation menu.



Otherwise you can add a check when a new player is created and teach them the recipe.
Last edited by Poltergeist; 11 May, 2024 @ 3:39am
< >
Showing 1-2 of 2 comments
Per page: 1530 50