#mod_development
1 messages · Page 17 of 1
Wouldnt that have problems with the tags though?
Or am I mistaken
Because the original code has no tag checks
yes, but let's focus on unborking the regular stuff first
Fair point
get it working first, add features later
Battery Insertion still isnt working even with that method
It's not doing anything, not even printing
local oldTestInsert = Recipe.OnTest.TorchBatteryInsert
function Recipe.OnTest.TorchBatteryInsert(sourceItem, ...)
print("Can insert battery: "..tostring(oldTestInsert(sourceItem, ...) and sourceItem:GetModData().batteryRemoved))
return oldTestInsert(sourceItem, ...) and (sourceItem:getModData().batteryRemoved)
end
hold on, does it offer you the option to do the insert?
Nope
sounds to me like you have a syntax error
probably never actually loaded the lua code successfully
perhaps
Actually, no.
It still loads the Recipe.OnCreate.TorchBatteryRemoval()
Though because of the nature of lua, it could've error'd in the line.
Lua is a per-line language rather than a compiling one so
heh, that's not actually how it works
lua compiles to bytecode
compile-time errors and runtime errors are two different things
anyhow, did you restart the game or just use F11 and hit reload?
I'm in debug, so I just slapped reload lua.
yeah, that isn't going to work now that we wrap the original function
Ah I see
you need to quit to main menu and load it
Wait, you mean restart as in completely restart or?
Because Reset Lua is only on my title screen.
quit to main menu
just quit, load game back up
that's all you need to do, nothing else
all lua gets reloaded upon loading a save
does the option to insert the battery show up?
Nope
but nothing happens when you click it?
Doesn't show up to begin with
I can remove a battery juuuust fine
But inserting one is the devils work apparently
well, if the print statement isn't happening, it isn't executing
Yeup
do you have all the code in a single file?
OK, so it's not a syntax error, otherwise you wouldn't be able to remove
yeup
simplify the print to just print("yes it executed")
at least we've reduced it to the simplest possible first statement
Maybe it's more recipe wonk..?
why would it be, you didn't try to override the recipe for battery insertion, right?
Dont believe so, but I mean like, what if its somehow wonking out some other way
And they wrote nothing else.
sod it, zip up the mod and send it
lemme try one thing rq and see if it magically works
ok
I doubt it but gonna check anyways
Sometimes the stupid stuff works the best
Okay yea, nada.
I'll send it over rq
gimme a bit
👌
so um
@quasi kernel look at your lua script, specifically lines 21 and 28
see a problem?
no no, disregard
they're different
so, now that the OnTest function just returns true regardless, does it at least show you the menu item?
n
You'd think it would but nope
Even then, it should still print the "Yes, we've executed" line before returning
welp, let's see what I get
it's not possible you have any lingering copies of code that overwrites the same function is it?
If there was, you'd see it in the file.
I mean in another mod
Does it work on your end or something?
I haven't made any other mods, the only potential problem would be Backpacks and Sleeping Bags, but even then Insert Battery was working fine earlier with it present
And they use their own Insert Battery function instead of overriding
TorchBatteryInsert_TestIsValid = Recipe.OnTest.TorchBatteryInsert
yeah, my theory here is that we're quite possibly too late to redefine it
So we have to make a new function is what I'm guessing
And make it so the vanilla recipes use that instead
But wait, wouldn't that mean the other definitions wouldn't work..?
TorchBatteryInsert_OnCreate = Recipe.OnCreate.TorchBatteryInsert
TorchBatteryInsert_TestIsValid = Recipe.OnTest.TorchBatteryInsert
TorchBatteryRemoval_OnCreate = Recipe.OnCreate.TorchBatteryRemoval
TorchBatteryRemoval_TestIsValid = Recipe.OnTest.TorchBatteryRemoval
your own definitions will of course work, I suspect it's the base ones that we can't override - also, I just looked, I think those are legacy
the base game recipes directly hit Recipe.OnTest.TorchBatteryInsert
You mean the TorchBatteryInsert_OnCreate is legacy?
I don't see any refs to it anywhere so it could be
yeah, so basically, if you call Recipe.OnTest.TorchBatteryInsert() from the lua console box, it runs fine
which means the recipes code directly obtains the function ref when the recipes are loaded and saves it, making the attempted override do nothing
ah it's not that bad, I have a theory I'm testing
Which also means there's less mod compatibility since we'd have to override 3 recipes instead of 1

Then again, I have doubts anyone is gonna modify "Insert Battery into Rubber Duck"
And even if they do, they can just use my mod
Wait, isn't it possible to go through the recipes and determine which ones are using the old method and manually set them to the new one?
nah, something looks a bit screwy here
the game does implement an internal cache of functions
but it shouldn't have already cached that function
because nothing should have driven it to test for the recipe being valid
secondly, even with that... I still can't insert the battery if we don't override the insertion code
what in the world-
yeah, I reckon the source item is getting left in some indeterminate state
Maybe its because of use in remove battery..?
maybe destroying and re-creating it is a good idea.
nah, it's not the item actually
Then what do you reckon?
You mean this one?
module BetterBatteries
{
{
imports Base
}
recipe Remove Battery
{
Torch/HandTorch/Rubberducky2/[Recipe.GetItemTypes.BatteryItem],
Result:Battery,
Time:30,
OnTest:Recipe.OnTest.TorchBatteryRemoval,
OnCreate:Recipe.OnCreate.TorchBatteryRemoval,
StopOnWalk:false,
}
}
no, I mean in the game
if you open the recipes menu, all the battery insertion recipes are missing
what about the other recipes?
are they intact?
oh my god wait
it overwrote the entire freaking recipes file
it deleted every recipe there EXCEPT for remove battery

The only exceptions being the recipes in their own designated files
Maybe it's because I named it recipes.txt?
lemme try..
it's because it was named recipes.txt wasnt it
yep
ah
alright, patched that
testing it rq
even with the incorrect import it still has all the correct recipes back which is welcome
correct, it won't
So will we just have to modify the original recipe to use our new method?
not new method but
nah, just leave it
nobody will really care, you basically always use the right click menu anyway
what does need to change is that it ONLY matches on the tag
since the original will serve the purpose for vanilla items
you say that but uh
there's two right clicks is what I mean
its recognizing both
and users wont know which one is the patched one
We may need to modify the original recipe
I'm modifying the vanilla items to use this new system as well so

crap
there's two removes and all the recipes are gone again-
wait nvm
it decided to add the old recipes script for some reason
lovely
Okay yeah, two remove batteries show up in the context menu still
as intended
Progress nontheless
Would be nice to figure out how to make it one, but one step at a time yesyes
my worst nightmare came back
we have to use destroy
oh well, it's hacky but it works i guess
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
@quasi kernel ^
thank
It might still need to use destroy though because of the keep / use limitations on Drainables
But ill check first
(Mostly because you can't remove a dead battery from a flashlight which is the whole point of this trouble)
considering it should be consulting our own OnTest, hopefully not
AFAIK, the original reason this didn't work was because the game's OnTest checked for this, now it doesn't
it doesn't consider the flashlight to be a valid item since its getuseddelta is 0 as a drainable
so it wont show it as being a valid object to use in crafting
This was the whole reason I wanted to go with the "empty flashlight" approach by duplicating existing lights and making empty counterparts
Either we do the destroy method which could potentially confuse users, or we do the empty flashlight approach which is messier code-wise but looks cleaner user-end wise
nah, something's not quite adding up here, I don't see anything in the java code imposing a restriction
Trust me, I already checked for hours on both ends, something is in there and I just can't find it.
I'll see
Closest lead I got to the lua end of things was the "ISInventoryPaneContextMenu"
SInce it checks for recipes on the java side in RecipeManager
Line 272
It has validity checks in there somewhere
Not on the lua end, the java end.
Which we can't modify without mod distribution problems.
I'm starting to think the empty counterparts may be the way to go
Then we can just check recipes if they use a flashlight and add their empty counterpart to the recipe instead
I know im insane but I have my partially not insane moments sometimes
Now that I think about it, wouldnt empty flashlights actually add more compatibility for some recipes?
Since an empty flashlight wouldnt be valid in, say, a flashlight suppressor.
Because of the same exact limitation we hit.
yes, that's why I said it's better not to create a new item
Nono I mean like
The seperate item could replace the old recipes
Because in the old recipes, if the flashlight has 0 usedelta, it can't be used for the same limitation.
However with this sytem, it can be used regardless.
In fact, it'd actually save you the battery.
We can loop through the recipes, determine if each source is part of our tag, if it is then remove it and replace it with its empty counterpart
We'd create the empty counterparts dynamically first though
The benefits I feel like would outweight the costs in this type of system
A) No weird bar showing up in the item when it's empty
B) Users are no longer forced to use a battery when constructing an item with a flashlight.
C) Would actually provide us more structure to base around our own "Remove Battery" and the like recipes.
Plus this shouldn't interfere with mods.
They'd, again, have to explicitly opt into the mod by adding the tag.
Am I insane or is this making sense
I need to check
oh boy, no no, there's no need for this
No matter which safehouse options are enabled/disabled, it seem players that aren't admin, moderator, safehouse owner, or on safehouse perm list, then they cannot pull up a right-click context menu in the area that the safehouse exist - like at all. It's dependent on where they click, not where they stand.
It seems the only server setting that relies on this occurring is to enable safehouses for players. None of the other safehouse settings mattered after a process of elimination.
This means everyone experiences this issue on MP server?
I say issue bc there are checks for other context menu entries that check for safehouse options that aren't even reached due to not being able to use the context menu at all. Wherever that part of it is handled, and it doesn't seem to be in ISWorldObjectContextMenu.lua.
you're running a 100% unmodded server?
100%
file a bug on the forums
Oli, what should we do then? I kinda like the empty counterpart solution, even if it's a bit complicated.
Shouldnt I be able to pinpoint the source of the issue if I were pro?
@quasi kernel one sec, got the working code
If I did that, i could make a mod to fix the issue and file the report
that would entirely depend on whether the bug lives in Lua or Java
either way, report the bug.
@quasi kernel https://pastebin.com/ngxcWeKi
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Anything related to pvp purposes seems slow to get to 😛
at the very least, someone in the community will either test to confirm, or deny what you are experiencing
@quasi kernel oh, one caveat, we need to move the recipe into Base
Alright, I'll do that Oli. Thanks for the suggestions.

I know it's stupid, but if this continues to not work as expected, can we attempt my route?
Yes, it's more complicated, but that also gives me more opportunity to learn.
well, I had insertion working
removal works fine
just gotta work the kinks out of the final step
Removal is working fine for me but not insertion
tweaked it a tiny bit rq to change it from getPlayer to use the provided player vari
oh, heh, seems the game got rather upset about me readding the item
it corrupted the inventory
Okay, so dupe the item instead..?
oh thank god
Ive just been using the debug saves lol
been spamming mall cuz why not
changed unpack to table.unpack since unpack was deprecated
Reloading lua and testing
Insert still doesnt work
yeah, but something's off with the batteries
if you look at their energy level, it's some stupid wrong value
Batteries are popping out as expected on my end
They just aren't being recognized as a valid component for god knows what reason
if I look at it in detailed view in inventory, it reports 10/100001 (0%)
that does not seem right
and I might know why
yeah, I do
the OnTest function is called, in turn, for each input ingredient
so we have to make an exception for batteries
function Recipe.OnTest.TorchBatteryInsert(sourceItem, ...)
return ((oldTestInsert(sourceItem, ...) or sourceItem:hasTag("BatteryItem")) and sourceItem:getModData().batteryRemoved) or sourceItem:getType() == 'Battery' or sourceItem:hasTag("Battery")
end```
sorry, wrong var name
there
Well, it works, I can't complain.
Admittedly a little disappointed I couldnt explore the more complex route, but hey I can do that another time.
this avoids the mess of separate items
this is the cleanest
it's also the least intrusive
This has the tag support too which is nice
only thing left to do is a bit of cleanup so that the insertion recipe is unified and it's done
Oh yeah, and somehow fix the remove battery-
currently it won't quite work properly if you use the vanilla recipe, you'll end up with a dupe flashlight
yeah
er, I meant remove battery recipe, yes
tysm for your help btw
np
it's an interesting idea, and makes the game a bit more realistic than having magically vapourising batteries
Ah ha! Someone else with the same issue
https://www.reddit.com/r/projectzomboid/comments/ric17k/multiplayer_rightclick_context_menu_issues/
3 votes and 6 comments so far on Reddit
But I'm gonna finish this one first
Probably gonna hit the hay for now, I'll look into things more tomorrow
nyoooom
Anyone know of a solid radio mod that allows players to use TC (not global) on specific channels? Creating an RP server.
why do you still need to do this? I thought using destroy keyword fixed things?
I don't think it would help since unless doing some funky business saving the name strings of the recipes, the dictionary won't persist through saves, so you would still need to generate it everytime you join the game. besides I really don't think its as much of a time saver as you think
you're quite far behind the state of play, that's all done and dusted
if you mean getting colored test, you can add these tags to modify the text. here is an example, where I modify the description to be red, if you don't have the item needed
if beehive_count > 0 then rgb = "<RGB:1,1,1>"
else rgb = "<RGB:1,0,0>" end
tooltip.description = tooltip.description.."<LINE>"..rgb..string.format("%s: %i / 1", "Beehive", beehive_count)
does PetrolCan;1 not work?
Anyone know of any mods that make it so you don't get scratches on feet?
hi guys, anyone knows where the vanilla padlock info are? I would like to apply the padlock to another object that is not a wooden crate
can i add action anim to a recipe in the .txt file or does that need to be done in lua?
AnimNode:RemoveGrass this is an example
AnimNode:RipSheets, RemoveGrass, Disassemble,
others I don't know 😂
oh gracias wasn't sure i could just add them to the txt, Thanks!
wanted that ripsheets one
does it only work for specific types?
HaloTextHelper.addText(player, getText("ProxInv_Force_Selected").." "..(ProxInv.isForceSelected and "ON" or "OFF"), HaloTextHelper.getColorGreen())
For some reason this prints "ProxInv_Force_Selected", instead of the localized text
Any suggestions why?
UI_EN = {
ProxInv_Force_Selected = "Prox Inv: Force Selected",
}
I awaken, time to figure out the magic that is trying to override a vanilla recipe
@quasi kernel isn't that what I sent you? I edited a vanilla recipe with code
You added onto it, not so much override
I need to completely modify it to change from keep to destroy, and also include support for a tag.
ah I see what you mean
yeah I just added another source to a keep
still the same kind of idea though
Just gotta figure out how to flip it from keep to destroy and I'll be golden
just delete the keep source that matches your criteria and then add a destroy right?
That's what I'm thinking
That way I can progressively empty the keep, then just add it to destory instead
Gotta figure out how to do that precisely but I can't imagine it's hard
function EditRecipes()
local allRecipes = getScriptManager().getAllRecipes()
for ri = 0, allRecipes:size() - 1 do
local recipe = allRecipes:get(ri)
local recipeSources = recipe.getSource()
local recipeResults = recipe.getResult()
for rsi = 0, recipeSources:size() - 1 do
local source = recipeSources:get(rsi)
local sourceItems = source.getItems()
local result = recipeResults:get(0)
if result:getFullType() == "Base.Battery" or result:hasTag("Battery") then
for sii = 0, sourceItems:size() - 1 do
local sourceItem = sourceItems:get(sii)
if sourceItem:isKeep() then
sourceItem:setKeep(false)
sourceItem:setDestroy(true)
end
end
end
end
end
end
I think this'll work?
@cyan basalt what do you think
i was originally discussing with someone who kept insisting you couldn't use units of gas - i haven't tried to and assume it works fine, was trying to make a point to them
they said "there's no such thing as 'Gas=1'"
apparently they were talking about propane, which.. also can be done that way
they apparently apparently meant "there's no tag system group for propane"
which was very much not the words that they were using or the examples they were using

I dont think my funny code works
function EditRecipes()
local allRecipes = getScriptManager().getAllRecipes()
for ri = 0, allRecipes:size() - 1 do
local recipe = allRecipes:get(ri)
local recipeSources = recipe.getSource()
local recipeResults = recipe.getResult()
for rsi = 0, recipeSources:size() - 1 do
local source = recipeSources:get(rsi)
local sourceItems = source.getItems()
local result = recipeResults:get(0)
if result:getFullType() == "Base.Battery" or result:hasTag("Battery") then
print("result is a battery.")
for sii = 0, sourceItems:size() - 1 do
local sourceItem = sourceItems:get(sii)
local fullSourceType = sourceItem:getFullType()
if fullSourceType == "Base.Rubberducky2" or fullSourceType == "Base.Torch" or fullSourceType == "Base.HandTorch" or sourceItem:hasTag("BatteryItem") then
print("Valid item")
print(fullSourceType)
if sourceItem.isKeep() then
sourceItem.setKeep(false)
sourceItem.setDestroy(true)
end
end
end
end
end
end
end
It's bad yes but I just want something functional first
im not sure what ur going for with changing source item to destroy rather than keep
do we ever destroy the flashlight?
Have to
Drainable limitation
Can't remove batteries from a flashlight with 0 use delta
Unless it's destroy
Yes
And also adding back the flashlight
ok so the thing about recipe modification if we/you-and-whoever havent gone over this
u wanna do it in shared
not at runtime
whats the issue with the code?
u CAN do it at runtime but only if nothing has instantiated the recipes
same with any scripts
yeh
it'll run before anything in client/server then
MOST shared code will not interfere
but be aware if something else for some reason messes with recipes it could
very unlikely to mess with battery removal recipes tho without being a problem in the first place in code
lol
good luck
🤞🏻
It only runs on OnGameStart
agony
recipe stuff belongs in shared regardless
that's where the vanilla recipecode.lua is
Also do it onGameBoot
if anything
it should technically NOT* need an event at all
I personally use onGameBoot but I think scripts are parsed preBoot anyway
so when Lua gets read anything not included in a function is ran
Ah, figured.
I'll still hook it into onGameBoot cuz why not
Unless you'd advice otherwise, I'm still new to this all hehe
there wouldn't really be a benefit on being 'first' to modify a code tbh
So just don't hook it to the event and leave it alone?
Or wait
Nvm I'm dumb
Blehh
just use OnGameBoot
I think more modders should modify scripts on the fly / use the tag system
so kudos 👍
---Forces a numerically keyed list into a type=true table, Allows for: 'if list[key] == true' checks.
function EHE_Recipe.convertNumericListToKeyedTable(list,table) for _,value in pairs(list) do table[value]=true end end
EHE_Recipe.typesThatCanOpenBoxes = EHE_Recipe.typesThatCanOpenBoxes or {}
---Sub-mod authors will have to use the following function to add more types
EHE_Recipe.convertNumericListToKeyedTable(
{"Base.IcePick","Base.HandScythe","Base.MeatCleaver","Base.LetterOpener","Base.Katana","Base.Scalpel","Base.GardenFork",}
,EHE_Recipe.typesThatCanOpenBoxes)
EHE_Recipe.additionalTagChecks = EHE_Recipe.additionalTagChecks or {}
EHE_Recipe.convertNumericListToKeyedTable(
{"Screwdriver","DullKnife","SharpKnife","Write","ChopTree","CutPlant","Scissors","Fork","Spoon"}
, EHE_Recipe.additionalTagChecks)
local ran = false
---Scans through every item, checks for types listed above as well as additional tag checks - avoids redundant tags
function EHE_Recipe.addCanOpenBoxesTagToTypesThatCan()
if ran then return else ran = true end
---Adds "CanOpenBoxes" tag to scripts for type
local allItems = ScriptManager.instance:getAllItems()
for i=0, allItems:size()-1 do
---@type Item
local itemScript = allItems:get(i)
local itemFullName = itemScript:getFullName()
local tags = itemScript:getTags()
local addCanOpenBoxesTag = EHE_Recipe.typesThatCanOpenBoxes[itemFullName]
local tagString = ""
for ii=0, tags:size()-1 do
---@type string
local tag = tags:get(ii)
if EHE_Recipe.additionalTagChecks[tag] then addCanOpenBoxesTag = true end
tagString = tagString..tag..";"
end
if addCanOpenBoxesTag then itemScript:DoParam("Tags = "..tagString..";CanOpenBoxes") end
end
end
Events.OnGameBoot.Add(EHE_Recipe.addCanOpenBoxesTagToTypesThatCan)
example of something I do in EHE
the stuff at the top is just cause I'm lazy / don't like to type so much
but it you notice any function calls left in the file - like: EHE_Recipe.convertNumericListToKeyedTable( gets ran as the Lua is read/defined
because I need those lists defined for other functions to work - that would be the only case you'd want stuff fired on lua load
What are you trying to get out of the code btw?
Back sorry
Okay so, I'm essentially trying to convery flashlight recipes into my new recipe type since flashlights cannot have their batteries taken out at 0 usedelta due to drainable crafting limitations
The solution was to turn the "remove battery" into a destroy recipe type that simply just gave back the flashlight in the OnCreate method
I originally wanted to do a more complex system, but I was advised against it
@sour island Sorry for the ping, just wanting to get your attention

np, I muted this server a long time ago lol
Valid
I originally wanted to go with a more roundabout method that functioned more similarly to how Smokin' Joe did his Military Flashlight where it had an "empty" counterpart to the original flashlight classified as a normal item
so you want to be able to remove empty batteries basically?
But I was told that may be too intrusive so something like this works better
Basically yea
Because the whole idea is you could recharge them with a hand crank im gonna make
So batteries are less a "one and done" and kinda finite to something more long-term
Plus it'd increase their overall viability since I don't see many people going out of their way to level up electrical specifically to modify items to use batteries
Why don't you modify the "remove battery" recipe directly?
It doesn't override
It adds onto
If I do it via script it just adds another remove battery recipe which is ugly
I mean ratehr than look for matching results/keeps/etc
you can just parse for the actual recipe's name
I can do that?
yeah
Oo!
What would i have to do to edit the map of the game like put in zones for other players to see on the map
Show me your ways o wise modder
the recipe object has a 'getName'
yeah
you're looping through them anyway - and checking for alot more
recipes can also share names
so don't add a break for "optimization"
Figured because of funny mods
Yesyes
items use displaynames for translations, recipes use originalname for untranslated
Very good to know
I'm just using vscode
I don't know if you can decompile/annotate in vscode
Like I have IntelliJ lying around
I have a decompiled version with me too
That's the only reason I've gotten as far as I have

yeah but this lets you annotate it into Lua
So it would look more like this..?
function EditRecipes()
print("Editing recipes..")
local allRecipes = getScriptManager().getAllRecipes()
for ri = 0, allRecipes:size() - 1 do
local recipe = allRecipes:get(ri)
local recipeSources = recipe.getSource()
local recipeResults = recipe.getResult()
if recipe.getOriginalName() == "Remove Battery" then
print("Remove battery recipe found")
for rsi = 0, recipeSources:size() - 1 do
local source = recipeSources:get(rsi)
local sourceItems = source.getItems()
for sii = 0, sourceItems:size() - 1 do
local sourceItem = sourceItems:get(sii)
if sourceItem.isKeep() then
sourceItem.setKeep(false)
sourceItem.setDestroy(true)
end
end
end
end
end
end
gotta use recipe : getOriginalName()
oop
no spaces, just emphasizing the colon
Oh I see
you could try to support tags but then you'd have to work-backwards again
and you never know
someone could make a recipe "bang batteries on flashlight"
and that'd get picked up if you rely on the ingredients
Pfft fair
you could string.find "remove" and "battery"/"batteries"
but then you're finding 3 times for each recipe
is your screen black or missing UI?
the recipe might have scuffed
try opening the craft menu
what's the whole error?
usually it shows the cascade - ISButton may have been the end
Should I use pastebin or something for this-
Callframe at: playUISound
function: onMouseUp -- file: ISButton.lua line # 55 | Vanilla
ERROR: General , 1661534155205> ExceptionLogger.logException> Exception thrown java.lang.reflect.InvocationTargetException at NativeMethodAccessorImpl.invoke0 (Native Method).
ERROR: General , 1661534155205> DebugLogStream.printException> Stack trace:
java.lang.reflect.InvocationTargetException
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.LuaJavaInvoker.call(LuaJavaInvoker.java:188)
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.UIManager.update(UIManager.java:809)
at zombie.ui.UIManager.debugBreakpoint(UIManager.java:1796)
at se.krka.kahlua.integration.expose.MethodArguments.assertValid(MethodArguments.java:120)
at se.krka.kahlua.integration.expose.LuaJavaInvoker.call(LuaJavaInvoker.java:186)
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.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.GameWindow.enter(GameWindow.java:752)
at zombie.GameWindow.mainThread(GameWindow.java:490)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException: Cannot invoke "fmod.fmod.FMODSoundEmitter.playClip(zombie.audio.GameSoundClip, zombie.iso.IsoObject)" because "this.uiEmitter" is null
at zombie.SoundManager.playUISound(SoundManager.java:219)
... 31 more
Fair
I rebooted the game and it does this right before the funny title screen
Same goes for Reset Lua
Is it possible to override a single moodle picture instead of overriding entire texture pack?
agony
any getters/setters for java functions need : afaik
zombie/ui/MoodlesUI.java you can use getInstance I would guess after that it would be modifying the array?
oh it's not held in an array
It's enum...
not sure if media/ui/Moodles/Moodle_Bkg_Bad_1.png would work tho
I'll try, thanks)
The game get's weird with inventoryItem's and trying to use overwriting filenames
but it's intentional, moodles might work
This would suggest moodle sprites aren't from the sprite pack tho
I guess the rest are in .pack
Or these aren't even used - which is true for most of media/
it's actually getOriginalname

force of habit capitalizing on my part
nvm, it was you
Force of habit

It seems it doesnt like the isKeep()
Regardless of if I use : or .
Oh wait, I need to supply a string
wait no- there's two isKeeps.
One is in Source and the other in Recipe
there's 3 isKeep()
doesn't seem like you have to parse through source items
- item objects don't have a iskeep
oh a source's item array is strings
that's probably why it borked
but the source itself has isKeep - so keep doing what you're doing
IT WORKS
IT MADE A RANDOM ERROR SOMEWHERE BUT IT WORKS
THANK. YOU.
Found the error
It was old code in the other script

Now I can actually start working on the main function of the mod that isn't battery packs-
Then I can work on my other mod idea!1
I don't think it's quite mod compatible yet, but that's okay
It's all I could've wished for
Alright, time to sprite a battery crank
👍
Which one do you figure I should base it off of?
The small one would be neat, would just be a matter of sizing it up a bit to actually be capable fo fitting a battery comfortably
But the big one is also interesting
Bump. I made a bug post. Having an issue finding where the right-click context menu check takes place for safehouses. I talked to someone about it yesterday. We concluded it didn't exist then I realized that the other checks wouldn't be taking place if there wasn't a check.
seems like the first would be more fitting the time period
You could try #old_techsupport but if you posted a bug report that's all there kind of is to do
Well, my main goal is to make a mod to bypass that check.
It has to exist. Looked through both LUA & Java.
so what exactly is the issue?
if you're not allowed in safehouses then you can't right click at all?
Is there any way to get zombies to have new animations?
Seems like something they'd fix quickly
then again if it's someone else's safehouse does it matter much?
Guys, I'm trying to do a TimedAction here, but it's always giving an error on the same line. I put all the correct information I would say. The error is on this line:
ISTimedActionQueue.add(FazerCafeNaCafeteira:new(playerObj, cafeteira, cafe))
How could I resolve this?
I'd imagine so, I've seen a mod do it before.
Right, this may have been the way the game works for a while. Most likely pre-B41. But, there are checks for what context menu options appear for safehouses. So, it also seems unintended.
When you enable trespassing players can walk around in your base.
Thoughts?
looks good! glad you got your stuff working too
They replace the animations, i mean like really add new ones, for like new actions and stuff
Okay, what would be the best way to go about making a hand crank that slowly increases battery charge and exertion?
You could make a recipe that makes you get fatigue and have it take a really long time maybe i dont know how it works very well yet
or if you can make a recipe that fatigues
Can someone help me?
I needed to get and delete a specific item in my inventory, how do I get the item and delete it?
If you find an ingame trashcan you can use that, you can also in steam settings for the game put in -debug and right click the item and delete it, then remove -debug from the start settings. I might be misinterpreting though
player:getInventory():FindAll('item') should give you all instances of items in a java.util.ArrayList<InventoryItem> according to the javadoc
@sour island I hate to be a bother, but I have a question as to how the best way to handle a cranking action would be
I'm thinking one way would be to have an "insert battery" recipe if the battery isn't full, then just add a recipe that only uses the battery crank if it's battery isn't full that sets up a connection to EveryTenMinutes or something similar, then the battery would add a corresponding charge every 10 minutes according to strength and exertion, as well as add exertion.
Then if the player runs, hits the max charge of the battery, or otherwise becomes too tired to continue operating, it removes the connection and ends the action (?)
Not sure how possible that is but it's an idea
recipes have alot of lua hooks
onperform, ontest, etc
but making it a timed action is also a good idea
I abused crafting for a looped action and it breaks with more traits/quick worker
so I don't recommend that lol
a recipe initiating a timed action
I really want it to be a timed thing so it's just a magical "ha I have a battery not"
oncreate is another lua hook for recipe
onperform is akin to start
ontest is done every tick the recipe action is being taken
oncreate is when the recipe is complete
Alright, I see.
oncreate is what I would use, to initiate a timedaction
which you'll have to instance for your own purpose
That'll be new
if that's not something you're used to there's a timed action API
I'm open to learning, so I wouldn't mind creating a new instanced timedaction
I just have no idea how they work
(There's a lot of new things to me in modding seeing as this is my first mod, apologies)
you can look up files in the media/lua with action is their name
there's a particular way to instance lua "objects"
Metatables?
but after that each of the functions are inherited
yeah
you can then define your own function for that instance and call back to it's parent
via overwriting
I'm somewhat familiar with metatables, not too familiar, but familiar enough to understand they're basically lua's ways of being objects
So you're saying the "parent" TimedAction file would have all the functions n junk
tbh I'm mostly self taught but the way I understand it is - everything in Lua is a table - which offer alot of flexibility
And the TimedAction:new() would function as the object we use to do funny stuff
yes
Since TimedAction:new() would create our metatable with refs to the functions
I see
but you can/may have to define a :new() for your new type of timed action
Ye I figured
as far I know the API should still be valid
probably should be something integrated into the base game files tbh
but that would defeat the flexibility
Well, that explains basic setup, but how would I do loops / event connections in that type of file while being able to calculate the "time remaining"?
Because there's no "set" amount of time it'll take, it varies greatly.
Cuz we're relying on strength, exertion, and the actual starting charge.
timed actions can be looped
indefinitely
there's an isValid() function to control it
Hm, I see
Was just about to do that hehe
Thank you! You okay if I ask more questions if I get any?
I don't wanna be a bother so
Figured I'd ask

sure
Anyone know if there is a mod out that that makes the UI size larger for the higher resolutions?
do you mean icons or just fonts?
Did you try changing the font size?
i just did again, realized i didnt hit apply last time, thank you lol
if you want to try new font styles, you can try my fonts https://steamcommunity.com/sharedfiles/filedetails/?id=2847178486
ill take a look, currently disabling then enabling all of my mods one at a time because of conflicts tho
good luck
Does anyone know why zomboid does not like when custom professions use custom traits that have custom recipes attached to them
I feel like the code just fails to fail some times
well, you haven't given any scenarios or errors to debug. I've never seen such things have issues, unless you're mixing a bunch of questionably written mods together
also, posting screenshots of text? shame on you
nah i could not get it to work just adding it to my text file with AnimNode:RipSheets, or AnimNode = RipSheets,
Is there an event for vehicle collision?
Good evening.
/**
* Triggered when the texture of a vehicle part is changed after being damaged.
*
* @param character The player who's driving the vehicle.
*/
export type OnVehicleDamageTextureListener = (character: IsoGameCharacter) => void;
I think this is the closest you'll get.
I don't think it'll fire for every damage instance.
I already tried OnVehicleDamageTexture and it doesn't even seem to trigger at all
Hmmm
I just went through the core code for vehicles and it's the only thing I'm seeing atm.
Might be a feature that's either planned or needs to be suggested.
What you could do @heady crystal is write an update method and check vehicles. It'd be somewhat dirty but possible to make your own checker.
I wish
I can't do that I am afraid, I have no idea how vehicle damage is even implemented
Doesn't affect my bikes for some reason and I couldn't find out why
I think it's VehiclePart that stores damage, much like BodyPart does for IsoGameCharacter.
Yeah but the parts don't get damaged on collision that's the thing
Hmm yeah.
If no one else has ideas on how to detect collision damage, maybe this is worth suggesting.
Only the engine seems to be damaged
I'm looking for a few mods on the workshop that people extend or has API to write Typescript typings. If anyone can suggest mods for this, it'd help. Thanks.
Are TimedActions in the client side?
I believe so? I know code for it is in the client folder but I'm not sure if it's exclusive.
The only shared file I see for TimedActions is ISBaseAction
I guess for consistency it's safer to handle it in the client folder
Yeah
Ok so better question, where do I find the sound files so I can choose one for my crank-
If you need to update the server in any way, you can always send a client command.
nvm I may be stupid
Media/Scripts
Have fun
There's a lot of files
Oh, I found it in Media/sound
Oh you meant the actual sound files lol
I believe I just need to find a suitable file and get its name so I can use it, right?
I only looked at it once so I can't remember if they are all perfectly named
If you want to use default sound files you need to check the name they specify in a txt file
For instance BuildMetalStructureWallFrame
This is in Media/scripts/sounds_player.txt
Yeah that seems like a better bet
A lot of these sounds seem outdated / unused in the folder
does anyone know why an item i've added to the game through crafting only is bugging out and disappearing when i move it from bag to inventory or vice versa, but comes back after a while/when i leave the area?
there is no error it just doesnt work
I take it all the sounds are in sound banks.
No. media/sound/
You have the option to put .ogg or .wav files in this folder. Use the relative path from that folder to your file and add it as sound objects in script files.
Nono I dont wanna add a sound, I wanna re-use an existing one
You can extract audio from fmod banks.
My sound skills ain't great, so either we're re-using one in the game or we're going to freesound

It requires a tool.
I take it that it'd be easier to just add my own sound at that point
It's an option.
Can I upload an image here for the question?
careful you might get criticized for uploading photos here
png and jpeg scares people
oh I see
🦕
I made a trading mod that uses recipes
{
GardenSaw/Saw/BucketEmpty/TirePump/GardeningSprayEmpty/PipeWrench/Paintbrush/Jack/WateredCan/TinOpener/LugWrench/Scissors,
keep ATTS.Barcodereader,
Result:Money=18,
Time:80.0,
Category:Zamazon Trading,
}
But When I selected the saw to sell. It sells Scissors first instead of saw.
Um so I want to make it sell the selected item first. Is there any way to prevent selling random items?
is there a basic intro guide for merging or creating mods? I want to combine More Traits and Dynamic Traits Sauce Edition into one more for myself.
what do you mean by "combine"
well combine them into one so I can tweak both mods and maybe improve or add things and make sure they're compatible.
or should I just tweak them individually, would probably be easier.
sounds to me like you haven't yet looked at how a mod is actually structured
maybe he's new to modding and maybe you're being a dick about it
I'm unsure if there's a direct guide, but process varies greatly.
how am I being a dick?
If you're able to get the source files for both mods (which isn't that difficult to be honest), you can look into merging necessary code and the like.
if you understand how mods are structured, it becomes self-evident how you would merge them
you gonna help him understand or are you just gonna be a dick to be a dick?
I would like to know if it is possible to manipulate world events.. such as blackout for example. Can anyone let me know?
as in, when they happen?
thanks, I'll peruse the forums a bit more.
Not exactly.. something like turning the power back on after the blackout
well, there's getWorld():setHydroPowerOn(true/false)
I see, is it possible to retrieve the current power status? If you are in blackout for example
yeah, IsoWorld has getHydroPowerOn
Thanks! you are a god
water is a bit more crappy, you basically have to "edit" the WaterShutModifier sandbox option to be longer than the number of game nights that have passed
Is water separate from energy?
yeah, water sources consult the sandbox option I just mentioned
you could of course just set it to a massive value when you want it on, and a tiny one when you want it off
And do you know if there is a possibility of activating the energy of a single city for example?
Okay, tks
possible yes, but the only way I can think of is to create an invisible tile that's an instance of IsoGenerator
and I'm not entirely sure you can prevent the emitter sound
and of course, you've got to go around and spawn instances of the moveable at various locations
I'll do a little study. Thank you very much.
actually, you could iterate over tiles and call setHaveElectricity() - though from looking at the code, I'm not entirely confident it'll actually work once it's been set to false
test it and see
Interesting. I will analyze
is there a way to call a function whenver a specific item is pickup or dropped on the floor?
how do i write that little code?
i need this for multiple mods
to give an example
i want to create items that are only useful for specific players(cant be stolen or worn by others)
i want to be able to despawn that item whnever the player dies or transfer it somewhere else if possible
thank you
i know a way to be able to make an invisible generator
but this by glitching and not modding
You know lua yeah?
you can use the generator trailer
turn it on
and despawn it
newbie
is there an onPickup()
or onDropItem() or similar?
you can hook ISInventoryTransferAction
ibelieve i should put this on onplayer update right?
see media/lua/client/TimedActions/ISInventoryTransferAction.lua
Good idea
thnx thnx @calm depot
downside is you cant remove the noise
or undo this
the generator trailer mod is a hack; it drops a generator under itself
what mods are u working on right now @calm depot
currently, none
I believe the noise will be the last of the problems
Anyway thank you. you helped me a lot
no problem 🙂
I must figure out the magic that is timed actions
They will make my hand crank very epic once I figure it out, but it's weird trying to understand some of it
I don't have animator talent so I'm just using the default loot anim, though I might switch to craft
As for sound, I have 0 clue how to hook a sound in but I'll figure it out!1
timed actions go into a queue
Nono I know that much
a good example to examine would be any of the vanilla carpentry ones
And they use metatables with supplied function info on the new()
since they have both an anim, an item and sound
I'm looking at the generator ones which use both
I just dunno if hooking to a vanilla sound is the same as hooking to a modded sound
Generator one uses a gas can animation which I switched to Loot temporarily, will be Craft later
Sound I'm worried about tho
it's just rudimentary metatable usage to somewhat simulate having a class instance
I also need to find the difference / activation scenarios of some of the functions
And also possibly investigate a loop because it doesn't have a wait which worries me because of the nature of loops without waits in vanilla lua
the basic principle is, create a table of functions, your new() will create a fresh table with its metatable having an __index that points to your functions table
No I know that
I just don't know what function ISActionName.perform() or anything similar does
Like I don't know what triggers it
it doesn't have a wait because you define the amount of time it takes and you will be called back when that amount of time has elapsed
What if it's dynamic though? Will I just wait forever until the action is done?
what if what's dynamic?
The time it takes to charge a battery.
It's not static like 5 seconds.
It varies based on the start charge, exertion, strength, etc
you set the maxTime value on the instance, it's always dynamic
The action is supposed to complete if the user runs (which is already has support for because of how they're set up in vanilla code), if it reaches 1 used Delta, or if the user becomes too exerted to use it
Ohh
MaxTime is just the maximum time that can be spent on the action?
If so, couldn't I just make that math.huge and let the logic handle it..?
no, it's a bit of a shite name, once you hit max time, the operation completes
Oh
So how do I make it so it changes based on my variables-
Will I just calculate a "base time" and run off of that?
you can set the maxTime when the action is instantiated
Formula would be vaguely something like chargePerTick * (strength * strengthModifier) * (exertion * exertion modifier)
if you also have an update() function, I believe it's called every tick
you can manipulate the progress as you wish from there
Oh I can adjust maxTime even after it's instantiated?
It might cause the bar to shift forwards a bit quickly at points but that's a sacrifice I'm willing to make for accuracy
yeah, the base class has a setCurrentTime function too
actually, now that I think of it, I think maxTime is just an idiom they use in the vanilla game
the actual "meat" of progression is handled by calling setCurrentTime in your update callback
I see
So maxTime is kinda redundant in something like this
Unless I'm mistaken
No wait, it'd still be used
if you're just deriving from ISBaseTimedAction then yeah, it's irrelevant to you
I am I think
you can make your derived class work however you wish
I'd recommend reading the ISBaseTimedAction file
Alright, I might need some advice as to how to set it up properly tomorrow, cuz I'm gonna be going to bed for now, but yeeee
And ye I def will
Funny 11PM hours
Thank you once again my friend
any time
She's giving me a table with nothing inside
Never mind, I got it here.
Now, how do I delete this item?
I tried here and I couldn't
could you show me an example?
how about instead, you show your failing code
just wanted to leave a big THANKS for this! works flawlessly! ❤️
oh, yay, time to learn new software lol
er, where did you get the model from then?
well that is the default game model
ive just made the sawed off DB shotgun one handed
well, what the game considers one handed
i'll see if i can figure out simple 180 degree rotation of a model first
if this is only messing up during an anim, like reloading, then it won't work
if it's just when aiming, then you should be fine
seems to reload just fine, its just aiming and holding in hand that are upside down
oh, how do i open an X file in blender?
I believe your options are to either use a horribly old version of blender, or find something to convert it to FBX
though actually, before you go down the conversion route, you should probably check with someone if the game will load an FBX for a weapon model
I would hope so, but you never know
import
oh, thanks
hopefully the converter you used did it correctly - still, it might have scaled to be huge, or incredibly tiny
well it was smaller than the default cube, but idk what scale it should be anyway
there seems to be a simple scale number input so worst case scenario i brute force it with trial and error
seems fine - I'd focus on getting the game to use the FBX you have before trying to apply any modifications to it
so, the game doesn't seem to want to use FBX, but it also doesn't seem to be loading my rotated model, or if it is, its not actually causing the in game model to be rotated
did you apply the transformation you made before exporting it
there's a modelling tutorial on the forum if you don't know what that means
is there simply an "apply" button i need to click?
no
Has anybody tough about project zomboid in 3D
alright then, which forum do i find this tutorial on?
haha i know but i ment like a mod fo PZ
is it even possible
anything is "possible"
it would require an extensive rewrite of the game
not to mention the entire team of level and artwork designers you'd need for a 3D map
so i applied the transform but still nothing changed
are you sure it's actually loading your changed file?
try mutilating it drastically and see if you at least see the mutilation
bend the barrel 90 degrees or whatever
i make it thicc
well, its working now, but the model is the size of a fucking cruise ship
i had not been restarting, i had been just relaoding the save, i thought since it reloaded lua it would've worked
nah, for 3D models, I've found it incredibly unreliable
ah, ok
I restart the whole game if I don't see an expected change
ok, just the flipped model in now, lets see if it works after a restart
it was rotated 90 degrees off so i fixed that and changed the scale to 0.1 to see if its a more appropriate size
correct angle, but still too big and the textures are fucked
are you scaling it down in Blender or game config?
scaling in blender, should i be using game files to do it?
no
do it all in blender
just keep scaling it down till it works
now that I recall, I had to do this for Bicscalibur
and I now also recall that I was able to use an FBX for the weapon model just fine
although maybe that's because it's a melee weapon, though that would be silly
i'll try again with FBX, since i hadn't been game restarting
ok, fbx is working, now to do rotations again
better to decompile the code
Like this right
function GiveXP_MetalWelding(recipe, ingredients, result, player)
player:getXp():AddXP(Perks.MetalWelding, 10);
end
yeah, although you could also have determined that by grepping for AddXP in lua/client and filtering by the word metal
So that would look like.. this?
as in: grep -R AddXP client |grep Metal
I dont understand this, where would this go?
that's a shell command
lol, no
just a general skill that's good to have when you need to find something in the game's codebase
Is there a general method for adding xp to any skill without writing a function for it?
like AddXP(Perks.MetalWelding, 10)?
I mean, you can structure your code however you want
you can write a one-liner if you wish
getPlayer():getXp():AddXP(...)
Feel like i could be duplicating something that already exists, could it all be inline here/
OnGiveXP:GenericAddXP(Perks.Crafting, 10)
Without adding a line to the lua
if you're writing a recipe, yes, you can make the recipe give XP
there are several recipes in the game that do this
I was following the wolf github guide but didnt work for me
I don't know what that is, just poke through scripts/recipes.txt
I'ma take it that my recipe needs to be in Base module
See if it try this for examle from the Make Stake recipe
module names are essentially arbitrary; the purpose of Base is for vanilla stuff to go in it
Ill look more into it
hint: the problem is probably not that line
Ill try it out now, think i might have had an extra ,
module ISSRecipesMod {
imports {
Base
}
recipe Craft Empty Lighter
{
BlowTorch=1,
Aluminum=1,
ScrapMetal=2,
RippedSheets=1,
keep [Recipe.GetItemTypes.WeldingMask],
Result:EmptyLighter,
Sound:PutItemInBag,
Time:30.0,
OnGiveXP:Recipe.OnGiveXP.MetalWelding10,
}
recipe Refill Empty Lighter
{
EmptyLighter=1,
PetrolCan/PetrolPopBottle/WhiskeyPetrol/WinePetrol/WaterBottlePetrol=1,
Result:Lighter,
Time:50.0,
Category:Survivalist,
}
}
looks fine, although as a matter of taste, I'd put refilling in the General category
Ok now we're in business, thanks again for help and ill change the category 😄
oh actually, while I'm at it, don't match on petrol containers like that
use [Recipe.GetItemTypes.Petrol]
otherwise, you're undermining the whole tagging system
Lemme try that
So like this?
recipe Refill Empty Lighter
{
EmptyLighter=1,
[Recipe.GetItemTypes.Petrol],
Result:Lighter,
Time:50.0,
Category:General,
}
Just 1 is perfect