#mod_development
1 messages · Page 50 of 1
this.setMinutesStamp();
var8 = (int)((this.getTimeOfDay() - (float)((int)this.getTimeOfDay())) * 60.0F);
if (var8 / 10 != this.minutesMod) {
IsoPlayer[] var15 = IsoPlayer.players;
for(int var14 = 0; var14 < var15.length; ++var14) {
IsoPlayer var11 = var15[var14];
if (var11 != null) {
var11.dirtyRecalcGridStackTime = 1.0F;
}
}
ErosionMain.EveryTenMinutes();
ClimateManager.getInstance().updateEveryTenMins();
getInstance().updateRoomLight();
LuaEventManager.triggerEvent("EveryTenMinutes");
this.minutesMod = var8 / 10;
ZomboidRadio.getInstance().UpdateScripts(this.getHour(), var8);
}
Just stores a timestamp and runs the rest when it's elapsed
same for everyhour everyday etc
there's even everyoneminute
Meta and Helicopter events are timed in there too
That's why I don't worry too hard about optimizing
unless the method is egregious
doesn't work 
any errors?
nope
Wait
nvm
can you edit both mods' functions
to include a print
just to confirm they're running in order as expected?
ok dafuq
ah
fuck
mod b updates weight every 1 minute
not every 10
ok
that was the issue
that mod b was doing it every 1 minute
if i set mod a to do it every 1 minute too it's fine
I can do something like this, right?
if getActivatedMods():contains("DracoExpandedTraits") then
Events.EveryOneMinute.Add(checkWeight);
else
Events.EveryTenMinutes.Add(checkWeight);
end
people who use OnTick(EveryHours), I had to to mod those because of some weird lag
max carry weight is hardcoded to 50 right?
Is there anything wrong with this code to add a new context menu item? It gives me an error whenever I open the context item for the deck of cards
local function doContextMenu(item)
print("test")
end
local function onFillInventoryObjectContextMenu(player, context, items)
for i,v in ipairs(items) do
local item = v
if item:getType() == "CardDeck" then
context:addOption("Custom context option", item, doContextMenu)
end
end
end
Events.OnFillInventoryObjectContextMenu.Add(onFillInventoryObjectContextMenu)
It gives me Object tried to call nil in onFillInventoryObjectContextMenu whenever I right click a card deck, and the context menu doesn't have "Custom context option"
some of the entries in items are not inventoryItems
weird coincidence but I just added context for wearing non clothing that can actually be worn
for i,v in ipairs(items) do
item = v
if not instanceof(item , "InventoryItem") then
item = v.items[1]
end
if item:getType() == "CardDeck" then
context:addOption("Custom context option", item, doContextMenu)
end
end
as I understand it, some of the entries in items are 'stacks' when you have more than 1
Just make yours everyminute - there's very little impact
Ah it was so simple, thank you!
ye already did
can i programmatically change recipe ingredients?
like can i act on getSource() array
to do that
i can test it ofc but if someone knows already
You mean like actively change ingredients throughout the game or from the beginning?
Hi, is there any mod that can disable all recipe?
at the beginning
im just trying to remove recipes bypassing the shit system that is built into the game since that doesn't work in most situations
already setting them to hidden, setting them to require a book, and removing them from every book i can find
but they remain available
so i want to change the ingredients as a backup
adding an item that isn't available
If you add an item into the .txt file that doesnt exist it wont load any of the recipes or atleast not the button
can't do that, since overriding the text file doesn't work for recipes with multiple names
and something about the way the recipes load seems to make it a new recipe if you change too much
even if the name stays the same
since names are not unique
obsolete:true would just work were it not for that
but u can't override 10 recipes called X
<_<
at least i've had trouble anyway
i wrote an entire script to assist in removing recipes from the game but perhaps i should re-examine
Perhaps you should
Since i honestly think that removing all the recipes from the game is kinda strange
But you could make them NeedToBeLearn=true and then never make a book for them
i have to remove certain recipes for balance
from various mods
yeah that's what im doing
but it still doesn't work
the recipes just are in players' lists already and/or still available somehow in many cases
sometimes it works, sometimes it doesn't
Then maybe comment them out and upload it to the server .ini?
If you change something you most of the time need to do a server restart
lolwat
"upload it to the server ini"
i've been running a server for 4 months and modding that entire time, i know i need to restart the server 😂
Well what i said usually should work so maybe your server somehow defines the rules of logic
Cause commenting out a recipe = the recipe should not be there anymore
i can't comment out vanilla recipes
one of which i remove as well
i mean, i could
but it'd create a GIANT headache
where every update for the game
i have to update the file
already enough chaos when the game updates
Not coincidence, its just your wizardry telepathy
Yes, you can modify recipes in real time - you can edit any script in realtime
Was wondering the same when i made the WetWeight mod but str has to do something with it so i guess there are still some areas to manipulate it but not directly
Also you can override vanilla recipes by naming a recipe the same and using a param called OVERWRITE I think
if it's just to stop them being used, can't you change their ontest to return false?
Idk if recipes have an obsolete tag but you can change the Lua functions for recipes to always be invalid
Basically make a dud function always return false and assign that to the recipe
Oh Albion said it lol
i found one called "CanPerform"
and i just tried overriding that yeah
i'd love it to just not show up at all
obsolete tag does exist but doesn't work right when multiple recipes have the same name in my experience
i remove a dozen or so recipes on my server so i'd like this tool to just be a maintainable list
there is an overwrite flag too
should replace rather than add on
with override:true and obsolete:true
it works when there's one recipe
that said i last tried it in 41.71? or 41.73
been a minute.
heh
hate that recipes can have the same name internally
goes against alot of ID conventions lol
you can parse through all recipes
i do that
and apply obsolete and overwrite manually
yes?
well if you can then the docs are horrendously out of date
the ones everyone tells u to use
they only let u set like half the things
the docs are from 41.65, i doubt they added anything to recipes since then
oh you're right
obsolete is done in realtime and removes it
yes
which means it has to be there at parse-time
:|
isHidden + is.. is need skillbook whatever that one is called
if (var6.equals("Obsolete") && var7.trim().toLowerCase().equals("true")) {
this.module.RecipeMap.remove(this);
this.module.RecipeByName.remove(this.getOriginalname());
this.module.RecipesWithDotInName.remove(this);
return;
}
as u can see it only gets rid of one recipe by name :)
so that ever only picks up the first one
never impacts more
bug.
been reported a bunch
i also set it to require a skillbook
and then i go through every book in the game
and remove it from any i find
though that doesn't seem to work?
why require a skillbook?
so i can unassign it from any
cuz i didnt realize there was a way to remove it via method
until today
that way it needs a book and there is no book
:p
that works for most recipes
yeah that's what i used for the filter recipe
I would assume the hidden + isvalid would cover all bases
isvalid prevents context menu
oh i need that
i was working on a mod last night, part of which temporarily changes your clothes and stops you from changing them, and i couldn't find a way to stop them from simply ripping them apart lol
so is what u mean LuaTest
or CanPerform
dont see an IsValid in the recipe object
java.lang.String getLuaCreate()
java.lang.String getLuaGiveXP()
java.lang.String getLuaGrab()
java.lang.String getLuaTest()
void setLuaCreate(java.lang.String string)
void setLuaGiveXP(java.lang.String string)
void setLuaGrab(java.lang.String string)
void setLuaTest(java.lang.String string)
and can perform
java.lang.String getCanPerform()
void setCanPerform(java.lang.String string)
can perform
in alot of the lua files they refer to it as valid
writing it up atm
I have something similiar for tags in EHE
function obsoleteRecipesAlwaysFail()
return false
end
local obsoleteRecipes = {}
local _obsoleteRecipesFullTypes = {"Base.RecipeName"}
local obsoleteRecipes.FullTypes = {}
for _,recipe in pairs(_obsoleteRecipes) do
obsoleteRecipes.FullTypes[recipe] = true
end
function obsoleteRecipes.parse()
local SM = getScriptManager()
local allRecipes = SM:getAllRecipes()
for i=0, allRecipes:size()-1 do
---@type Recipe
local recipe = allRecipes:get(i)
if recipe and obsoleteRecipes.FullTypes[recipe:getFullType()] then
recipe:setIsHidden(true)
recipe:setCanPerform("obsoleteRecipesAlwaysFail")
end
end
end
Events.OnGameBoot.Add(obsoleteRecipes.parse)
@weak sierra
alright, I'm off
Djackz has a permadeath server
trying to represent modders
💪
also to explain ```lua
local _obsoleteRecipes = {"Base.RecipeName"}
local obsoleteRecipes = {}
for _,recipe in pairs(_obsoleteRecipes) do
obsoleteRecipes[recipe] = true
end
I like using obsoleteRecipes[recipe:getFullType()] - idk if it's optimized or what but the alternative is to for loop
and I'm too lazy to type [""]=true over and over
i am doing this lol
oops there's an issue in my snippet
u dont have to write it for ongameboot afaik btw
can just execute it right there
if its in shared
I prefer it to execute then just to be safe
the issue I spotted was that the IDs were being added to the same object housing parse()
probably not enough of an issue to break it
good luck
Hello, can't debug mods, seeing white screen. Reloading the game or the scripts not fixing it. Please help!
local hps = _player:getBodyDamage():getOverallBodyHealth(); --pos3 or pos300 stay 300 if not hurt--
local endr = _player:getStats():getEndurance(); --pos200 or pos2--
local fat = _player:getStats():getFatigue(); --neg2 or neg200 slowly getting worse--
local pan = _player:getStats():getPanic(); --neg 100 max--
local pai = _player:getStats():getPain(); --neg 200 max --
local sss = _player:getStats():getStress(); --you must be kidding, this will equal neg 0-100--
local bor = _player:getBodyDamage():getBoredomLevel(); --neg 100 max--
local hung = _player:getStats():getHunger(); --neg 100 max--
local thir = _player:getStats():getThirst(); --neg 100 max--
local wet = _player:getBodyDamage():getWetness(); --neg2-200--
local endr = endr * 2;
local hps = hps * 3;
local wet = wet * 3;
local sss = sss * 100;
local pai = pai * 2;
local pan = pan * 2;
local fat = fat * 4;
local thir = thir * 2;
local hung = hung * 2;
--1500 base trip MAX -- 1200 neg max--
local trip = 1000 + hps + endr - fat - pan - pai - sss - hung - thir - wet - bor;
if _player:IsRunning() == true then
local Roll = ZombRand(3333, 9999);
if Roll > trip then
local type = nil;
local random = ZombRand(2);
if random == 0 then
type = "left"
else
type = "right"
end
_player:setBumpFallType("FallForward");
_player:setBumpType(type);
_player:setBumpDone(false);
_player:setBumpFall(true);
_player:reportEvent("wasBumped");
__
this code should work!!! & i can swae rto you it actually did, but now it doesnt
any advice
PS: the --notes-- are old & noit updated
what's wrong with it
won't you trip every frame...?
also, you don't need to write 'local' every time you write to the variable
it's already local in that scope
I have an open bug on the forums with the same issue
are you running Linux?
ah okay that's a known issue then, cool thanks
Win 10
interesting, I didn't expect this bug to be cross-platform. should probably update the forum post with that information
do you mind doing that?
give me a second to get it
• Version? 41.78.7 • Singleplayer/Multiplayer? Singleplayer • Host or dedicated? N/A • Mods? NO • Old or new save? Old and new • Reproduction steps: Press F11 and view a file • Platform: Linux
done
idk it just wont work & i swear i have video proof it did, i had the trip rate lowered because it was "done"
now nothing
unless you changed the maths significantly i can tell there's no way this works
you roll between 3333 and 9999 for some reason, but trip can't even get that high, so you're going to trip every single time the code runs...
and trip decreases with negative modifiers, not increases, so your trip chance would go down the worse state you are in
may have just clipped them out when you copy-pasted but you're also missing several ends
I had the same issue myself. To figure out the proper encoding.
- Go to
ProjectZomboid\media\lua\shared\Translate - Open the folder for the language you want to translate to
- Open any of the localization files and check the encoding.
Note: I use a Notepad program (Notepads App) that I downloaded from the Windows App Store that can autodetect the encoding. However, regular Notepad and VSCode do not auto decode. VSCode, however, can guess what type of encoding it is and make a suggestion.
BTW, for Russian, it's Cyrillic (windows-1251)
F11 not showing text or garbled text is normal sort of
Usually it means your Lua is uber fucked
Also prints into console.txt still work
I don't know about that, I've never had an issue until 78
are you running the linux build by chance?
It's usually caused by a missing , end ( or {
oh someone alrady
Windows 10
If you've ever gotten blocks instead of letters
yeah nvm i've seen ui bugs in linux but i see albion already got to u with that
Console.txt shows the same info
Nothing wrong with my Lua (syntax-wise, anyway, I'm not omnipotent) & I still didn't see file contents in the debug menu earlier
Also @weak sierra did that code work? I didn't test it but it's pretty straight forward
i had my own code written already so i just finished adapting i
O
function nope()
return false
end
local yeeted = 0
local start = Calendar.getInstance():getTimeInMillis()
local recipes = getScriptManager():getAllRecipes()
for i = 1, recipes:size() do
local recipe = recipes:get(i - 1)
local name = recipe:getName()
recipeDisplayNameLookup[recipe:getOriginalname()] = name
if recipesToYeet[name] then
recipe:setIsHidden(true)
recipe:setCanPerform("nope")
yeeted = yeeted + 1
print ("["..modName.."] Yeeted \""..name.."\"..")
end
end
local stop = Calendar.getInstance():getTimeInMillis()
print("["..modName.."] Yeeted "..yeeted.." recipes in "..(stop - start).."ms!")```
Uh curious about the calendar stuff
it just grabs the time in ms then compares it to get a clock of how long i wasted
:p
function clock
cudda used getTimestamp
but
i was unaware of getTimestampMs at the time
Were you testing speeds?
Ive been curious about profiling Lua but I'm not that well versed
Anyone knows what libs are exposed to Lua in Zomboid?
what is the best way to identify a character in code? I know every character/player has a handful of different names and Ids, which is the easiest to retrieve, and to look up the player with? is it :getDisplayName()?
using functions like getTimeInMillis (or any other timestamp based on the calender clock) is no good for profiling, your results can change based on current system load (background processes and OS etc)
lua has a os.clock() function that reports CPU time, which is the amount of time spent on the running process (thus independent of the background stuff going on in the machine)
if i remember right, os.clock should work in kahlua (fairly certain i used it years ago profiling) but i might be wrong
absolutely not.
I noticed yesterday my file would show blank in debug without any errors, only now realised it's all my files.
seems like getGameFilesTextInput returns nil, my mods are in user/Zomboid/mods
most standard lua libs (not all functions though) except io.* stuff, for the exposed java theres alot you'd have check the decompiled source
• Version? 41.78.7 • Singleplayer/Multiplayer? Singleplayer • Host or dedicated? N/A • Mods? NO • Old or new save? Old and new • Reproduction steps: Press F11 and view a file • Platform: Linux
Oh I see... Anything to directly send network packets?
not really. the java stuff is fairly sandboxed to prevent abusive mods
that's why I checked
I just wanted to send some network packets over the loopback, need to transfer some info to an external program running on the same machine
Was wondering about a more... Clean solution than writing/reading from file
ya file io is probably the best bet for any sort of IPC (at least the simplest solution)
will this work? (to increase the weapon dmg+5 every tieme i use it )
uh no. you cant define a property outside the item block like that, nor can you do math in the property fields
its not a actual programming language of any sort. those .txt files are just basic item definitions and such. if you want to do stuff like that you'll need to use lua
does it need to be persistent?
only during a session. Just using it to store which characters are currently occupying which vehicles on the server. And also want to be able to quickly verify if the value I've been given belongs to a valid character
:getOnlineID() should be suitable then
is that a number?
yeah
i think getPlayerByOnlineID() will return nil if there isn't a player with that number
handy. If I remember what Tyrir was saying earlier, these are just small integers that also correspond to splitscreen players differently?
yeah, you know how getPlayerNum() returns a value 0-3 for local players? playerNum is essentially onlineID % 4
that should be perfect, thank you
nop
am i doing something wrong? not sure why it is not working, i litheraly just ocpi paste it
what does you print key show
i'm playing in the "-debug mode" and the code does nothing. dosen't print on the console nor adds any of the 3 items to my inventory
what folder is the media in?
try putting it into %userprofile%/Zomboid/mods
D:\SteamLibrary\steamapps\workshop\content\108600\2844113631\mods\ReworkedHeavyWeapon\media\lua\client
that seems right
I would check if my file is loaded next, with F11 and filter for test.lua
if not even 'test' is getting printed, it's not loading
oh, it works now thank you s much
mm is there a method to change a weapong dmg? so i could add +dmg every time i hit
anyone know a good substitute for 75% less loot? it’s outdated
you need to get the sledgehammer somehow, you can't just write Sledgehammer
you can use getScriptManager():getItem('Base.Sledgehammer'):getMinDamage()
@bronze yoke thank you so much
how can i go aroud this ?
getUsername
most mods use this

I haven't looked, is there a getCharacterByUsername() function?
getusername won't work with splitscreen, and i don't think they're unique on steam servers either
How do I go about adding an item of clothing to the game? I know it involves some scripting but I can't seem to find anything online about it
so far online ID has been working, but I haven't actually tested anything with other players around
afaik online id is just the best way to do this
https://theindiestone.com/forums/index.php?/topic/37647-the-one-stop-shop-for-3d-modeling-from-blender-to-zomboid/ This has been a pretty good guide, but it gets pretty sparse information wise during the scripting section
Hello and Welcome! Here you will find a concise and comprehensive guide and tutorial of making 3D models for Project Zomboid. Currently, this will mainly pertain to custom Clothing creation but may include weapon creation in the future. This will present how to create models from scratch with Ble...
Is there a way to get a bodypart's name? for example, "Head"? getName() doesnt work, unless I'll have to brute force it by adding a bunch of elseif for each bodypart to get its name
this guide is good
https://steamcommunity.com/sharedfiles/filedetails/?id=2648115890
Thanks
a tip i have that isnt in this guide is to set the scale of "dummy01" to 1 and then ctrl+a to zpply the scale and delete it
otherwise the models will be tiny in the blender scene
i think :getType():toString() will work
is this to change the current equipped weapon damage? (Ignoring the actual weapons dmg?)
nah it modifies item values
you have to first get the weapon itself
and then you can modify its max damage
the values are on wiki and if u dont trust wiki u can do print on getmaxdamage
or even better just go to debug and check the item values urself
mm can two of the same weapon have different dmg values?
each item is different so yes
damage might not save tho
you can get around this by using modData and inventory updates
mm
"LowerLeg_R"
I want it to be like the names u see in health panel like "Right Leg"
this one is to get the equiped weapon right?
you can also do Events.OnEquipPrimary.Add(functionhere)
getType():getDisplayName()
mm I need to change the critical chance of my equipped weapon without changing all of that weapon critical change on the game. should i first get my equipped weapon and then try to modify the equiped weapong variable critical chance?
object tried to call nil
imma get rid of "tostring"
nope same thing
is there a way to tell if a player, and ideally also a zombie, are attacking, and what they are attacking? I'm quite in the weeds with this one, all I can currently see is HitCharacterPacket.java but there is no way I know of to listen for packets
onplayergetdamage?
https://pzwiki.net/wiki/Modding:Lua_Events/OnBeingHitByZombie is outdated, is there any alternative hook we should be using?
u tried to call "getDisplayName" from string meta
alright so can you get me a line for it?
doesn't look like OnPlayerGetDamage is what I need
local randompart = ZombRand(0, 16);
local v = bodydamage:getBodyPart(BodyPartType.FromIndex(randompart));
this the line for selecting body part
I'm not sure about body parts buy try use :getDisplayName() instead :getType()
v:getType():getDisplayName() is what i see in the docs
yea i tried that and it gave me "tried to call nil"
:getType() returns string
how u want to call :getDisplayName()
yea that makes no sense
BodyPartType.getDisplayName(BodyPartType.FromIndex(body_part_id))
mfw string of string
stop trolling plz
ok let me try printing that (and ofc replace "body_part_id" with "randompart")
hmm, OnWeaponSwing triggers when a player attacks, but it doesn't say what they're attacking. May be able to figure it out
on items... on body part it's BodyPartType
oh shit
didn't sleep for a long time
u right
sorry for charge

can u show the code how did u use that
HaloTextHelper.addText(player, getText("UI_ETEThinSkinInjury") ..tostring(v:getType():getDisplayName()) .."!", HaloTextHelper.getColorRed());
im gonna try it with "getType()" removed now
and remove tostring
show full code with :getDisplayName
What If We Had An Mod That Can Interact with people in other servers/save that arent in the same server but you can interact with them like when they die they become an zombie but you can see the zombified player in all servers that use this mod or see peoples base and steal loot and it impacts the person gameplay and your gameplay like gunshots will can zombies for the entire save and the everyone that is using this mod soo all actions would effect everyone that is using the mod like if the build get destroyed it impacts the building in other servers too
showwww the code
local function ThinSkinnedInjury(player, damagetype, amount)
if SandboxVars.ETE.ThinSkin == false then return end
if player == getPlayer() then
local playerdata = player:getModData();
local thinskinbodydamage = playerdata.ETEThinSkinBodyDamage or {};
local bodydamage = player:getBodyDamage();
if player:HasTrait("ThinSkinned") then
for i = 0, player:getBodyDamage():getBodyParts():size() - 1 do
local b = player:getBodyDamage():getBodyParts():get(i);
if b:HasInjury() == true and tableContains(thinskinbodydamage, i) == false then
table.insert(thinskinbodydamage, i);
local randompart = ZombRand(0, 16);
local v = bodydamage:getBodyPart(BodyPartType.FromIndex(randompart));
local injury = ZombRand(1, 3);
if injury == 1 then
v:setScratched(true, true);
end
if injury == 2 then
v:setCut(true, true);
end
table.insert(thinskinbodydamage, randompart);
HaloTextHelper.addText(player, getText("UI_ETEThinSkinInjury") ..(v:getDisplayName()) .."!", HaloTextHelper.getColorRed());
v:AddDamage(30);
b:AddDamage(30);
end
end
end
end
end
dunno what u meant so heres the entire function
this errored with uh
sec
object tried to call nil in that halotexthelper line
HaloTextHelper.addText(player, getText("UI_ETEThinSkinInjury") ..(BodyPartType.FromIndex(randompart):getDisplayName()) .."!", HaloTextHelper.getColorRed());
try this out
object tried to call nil
HaloTextHelper.addText(player, getText("UI_ETEThinSkinInjury") ..(BodyPartType.getDisplayName(BodyPartType.FromIndex(randompart))) .."!", HaloTextHelper.getColorRed());
good
ya, no good. I'm not trying to tell when a character is attacked, but when a vehicle is. AFAIK there is no event for it, so I have to find another way.
I have a LUA question. When I have a function like the following:
local function myfunction(x)
local x = 1
local myparamX = "accessMyParamX"
end
Can I get the parameter x ("accessMyParamX")? Of course I can rename my local x to lx or something. But this is just for my understanding. My Google hits failed so far...
i don't understand the question
you could return it
if that's what you're asking
you can also return multiple things
local function myfunction(x)
x = 1
local myparamX = "accessMyParamX"
return x, myparamX
end
local a,b = myfunction(x)
I removed the local on x cause it's the same as the param
I'll try to describe it better...
local function myfunction(x)
local x = 1
print(x)
end
myfunction(2)
I want my funciton to print 2 instead of 1...
local x = x or 1 I suppose, although why would you make a local of the same name anyway?
It's just a question about understanding lua...
local function myfunction(x)
local x = x or 1
print(x)
end
myfunction(2)
if i correct got u
would the local be different to the param in this case?
nope
all arguments are local by default
ah, I wasn't aware but that does make sense
I mean, thats not true, arguments that are tables are not local
You're all right with your explanations... I just wasn't sure if I can access my x from parameter again if I define a local x.
ok... thx.
its entirely true, even if the arg is a table.. the variable its stored in is locally scoped
the variable is just reference, its not stored locally at all
so if I make a local x the parameter is overwrittern after that...
it's local
but values in this table aren't
yes, but you shouldn't redefine it - as it makes it less readable imo
where is stored is not important at all, the variable of the reference is scoped local
local function myfunction(x)
x = x or 1
print(x)
end
myfunction(2)
x is already in the function () so it doesnt need to be local'ed
also that way myfunction() returns 1
ik
a reference to something out of scope can't be local by definition, I have no idea what you guys are talking about, lmao
nope, 2
the reference is local and that's all that matters
Ok... thx to all...
Like I wrote it was theory... of course I don't have to "overwrite" it with local. I just hat a case where I got a player fromt the function and did:
local player = getSpecificPlayer(player)
At the end of my function I passed the player object to the next function which also did the getSpecificPlayer and failed...
u meant without args, then yea, 1
yea so whats the issue here cus i see none
This would work aslong as player was initially a number, but again, it would make things hard to read/keep track of
But your answers explained it for me...
Your absolutly right... I just asked myself if its possible or not.
if player is function arg then better to name it like player_id
does anyone know if its possible to modify the sweating system?
id like to make a mod that disables it, or something along those lines
Like I said you're all right... It was just for my understanding... 🙂
btw heres a super simple question for the future
if XYZ == true then
is the same as
if XYZ then
?
yeah
I don't think afaik, but you can create a patch, like a OnTick that can check if is sweating and set it to 0 or something like that
no
thank you i will try it out :)
love your clothes mod too!
if XYZ was equal to 3, you would get different answers from those two statements
nope
if bool then yea
if you're sure its a bool, then yes those are equivalent
mk
second statement will accept all but false/nil
thx man, I hope to work on it soon, I have some clothes that never was released
As far I've understood if it's nil... then its not the same...
nil is false, but it's not equal to false
alr then
Does anyone know why Zomboid can't read my preview image?
I was able to change the format, but it still didn't work
Are you sure that isn't preview.png.jpg?
Nope, it's definitely not that
is the image 256x256?
It is, yes
any idea why this code doesn't work as intended? I want it to turn the radio on, spit out a message, then turn it off again iff it was off to begin with. But it never turns it on. If I turn it on myself it works fine
local radio = vehicle:getPartById("Radio")
if radio then
local isOn = radio:getDeviceData():getIsTurnedOn()
radio:getDeviceData():setIsTurnedOn(true)
radio:AddDeviceText(string, 1,0,0,nil,nil,10)
radio:getDeviceData():setIsTurnedOn(isOn)
return
end
I never touched things related to radio, but it probably works as intended, but really very fast, try adding a wait between when you turn on and turn off
I assume AddDeviceText is instantaneous, but maybe its not
essentially I just want it to spit out the message whether its on or not, but not leave it on if it wasn't on to begin with
Have you tried it without the final setTurnedIsOn call? That could confirm that the issue is that it's being turned off too quickly
could you try this, If works, could confirm what I was saying
local radio = vehicle:getPartById("Radio")
if radio then
local isOn = radio:getDeviceData():getIsTurnedOn()
radio:getDeviceData():setIsTurnedOn(true)
radio:AddDeviceText(string, 1,0,0,nil,nil,10)
return
end
yeah that's where i'd start
Hey everyone! Today Im experiencing a issue where my clothing mod is causing a issue where players will be able to join a multiplayer server, but will never get to the Click To Start screen. (i.e after This Is How You Died, its a black screen.)
If anyone can help id really appreciate it 🙏
ya, if I don't switch it back off again it works
thats really weird to be honest, why would I need a delay
deltaTime things
maybe I can force it to handle the text
Were you abele to solve the issue? I once had some trouble with an png which had 64bit depth... the channels were on 16bit instead of 8... but I don't know if this could be the problem in your case...
yes but i am not tripping at 100% trip even tho this very same code used to work fine
Alright, perhaps someone can help me, I'm trying to set the pain level of the players head
currently have this local part = player:getBodyDamage():getBodyPart(BodyPartType.Head); but that doesnt work
tried several different ways but no luck
BodyPartType.FromString("Head") also didn't work
I know I could loop through the body parts, but I was hoping to be slightly more efficient
I haven't fixed it yet
Probably going to try and find a new image
I added a Localization section to the wiki's Modding page that has all the languages and encoding formats. If you guys spot an error, feel free to edit it or just mention me and I'll fix it. https://pzwiki.net/wiki/Modding#Localization
Does Zomboid hardcode one handed melee weapons to always require a lure when fishing? I'm looking for a way to make a fencing sword one handed but works like a spear when fishing
thank you very much! i always thought there should be a resource for this
does local var = require "otherfile" give you a readonly version of the variable returned by the other file?
I have one file returning a table, and another file requiring it and trying to add to it, but the original table never sees the changes
its almost like require creates a local copy instead of a reference
that should work, i'm not sure why that's happening
hmmm
well, my first file looks like this: RDWRER.lua
local RDWRER = {
Server = {
Events = {},
Commands = {}
},
Client = {
Events = {},
Commands = {}
}
}
return RDWRER
and the second does this:
local RDWRER = require "RDWRER"
local Handler = {}
function Handler.onServerCommand(module, command, args)
if not module or not command then return end
if module == RDWRER.COMMANDS then
local cmnd = RDWRER.Client.Commands[command] or RDWRER.Commands[command]
if cmnd then
cmnd(args)
end
end
end
Events.OnServerCommand.Add(Handler.onServerCommand)
RDWRER.Client.Events = Handler
return Handler
it seems so simple, but doesn't work. If I print the contents of RDWRER.Client.Events its empty
have you tried just adding RDWRER.Client.Events.onServerCommand rather than replacing events with the handler table later?
i'm not really sure why that would be different, but i'm just looking for things that are different than my own usage
local TestMod = {}
TestMod.foo = 'bar'
return TestMod
local TestMod = require 'TestMod'
TestMod.foo = 'not bar'
🤷
doing the same table replacement thing worked fine 🤷
I did
local RDWRER = require "RDWRER"
local Handler = RDWRER.Client.Events
function Handler.onServerCommand ... etc
and the RDWRER.Client.Events table is still empty
I don't get it
local TestMod = {}
TestMod.subtable = {}
return TestMod
local TestMod = require 'TestMod'
local otherTable = {}
otherTable.foo = 'bar'
TestMod.subtable = otherTable
if your application is exactly as written though, i would recommend doing things the other way around anyway
Events = require 'Handler'
I did that initially, but it caused errors since the main file is in shared, so it can't require files from server or client
oh that's your problem
wait no... (i was going to say it was 100% your problem but then i remembered that the server folder does run on the client, lol)
it might be your problem
try not doing it across two different folders, not really sure how require interacts with that
it still works for me if i do it that way though u_u
tried RDWRER.Client.Events.test = "This is test" from a different file in the same folder. Didn't work. This is strangely frustrating, lol
your exact code works for me
make sure the directories are included in your requires, or look through your log for a 'require failed'
no required failed, and no subdirectories...
and what you sent is the entire files?
I trimmed down the inside of the functions and tables to make it easier to read, but otherwise ya
are you sure the handler file is even being read? that's the only explanation i can see
ya I'm pretty sure, this is in the logs with no errors following it
LOG : Lua , 1668316394885> 349,934,383> Loading: C:/Users/***/Zomboid/mods/RDWRER/media/lua/client/RDWRER_Client_Events.lua
i even tried copying your filenames LOL and it still works perfectly
😭 🔫
to be absolutely sure, you're not checking it on the server are you?
doing it through the command console on the client in debug mode
picked client files to test this with on purpose so that this would be easy to check, lmao
I'm actually a little confused as to why I can do print(RDWRER.Client.Events) at all when RDWRER is local to its file
you need to require it first...
I didn't. And if I print it and print the version I get from requiring, they're different addresses
i don't really know what you're printing when you don't require it but you do need to require it
there's probably something messed up in another file because that gives me an outright error
I thought about that, so I checked to see if I required it anywhere else without assigning the require to a value, or if I somehow instantiated the exact same table as a global somewhere, but that doesn't seem to be the case
worth a try
local function NoodleLegs(_player)
if _player:HasTrait("NoodleLegs") then
local trip = 1000;
if _player:IsRunning() == true then
local Roll = ZombRand(8888, 9999);
if Roll > trip then
local type = nil;
local random = ZombRand(2);
if random == 0 then
type = "left"
else
type = "right"
end
_player:setBumpFallType("FallForward");
_player:setBumpType(type);
_player:setBumpDone(false);
_player:setBumpFall(true);
_player:reportEvent("wasBumped");
end
end
end
__
OK something is wrong with this new updated because
this should 100% make me trip
my old more complex code WAS working
but now even with it simplified it wont work at all
im so confused
print(RDWRER) doesn't error on a fresh boot... maybe debug mode has special powers?
Okay, the default preview.png from the ModTemplate worked
So it must've been my specific image
make sure the function is actually being called, and can you please encase your code like this when you send it here to make it easier to read
ehh if debug mode was somehow capable of printing out local variables, print(Handler) wouldn't give me nil like it does
believe me that debug mode does not have magic
at the very least because i've been in debug too
if you just try to print some random crap it'll error right? so something is definitely not local somewhere
if it's a table i mean
like print(madeup.variable)
i think any non-defined variable will just print nil
but tables should cause issues
ya, if you try index a non table it throws that error we see all day
so something's not local!
ran a "find in files" in intellij for RDWRER, I use it 51 times. Went through them one by one and they are either a reference to a local version that was required, a string containing RDWRER, or the original table, which is local to RDWRER.lua, lol
I'm going insane
can you try removing the files other than the ones you've shown me and testing it then? i'm sure the problem is elsewhere
yes, now there is no global version of RDWRER
good thing there aren't too many files, I can add them one by one and see what happens
found it
I want my item to show condition in inventory, which types do that?
Having a vehicletype in my scripts was weird
RDWRER.lua used to be called RDWRER_Base.lua, and its been sitting in the mod folder unseen because it was just an identical copy until I started refactoring everything to local. I just overwrite files when I update and forgot to delete it
the _Base version had a global RDWRER variable
dang seems java only does it for that, which is weird. I thought it pulled other stuff as well. ok, there's also clothing and handweapon.
k, guess I go custom and add 2nd bar like freshness for food. hm I can think of some fun alternatives.
@jaunty marten you are vishnya??
local random = ZombRand(1);
if random == 0 then
type = "left"
else
type = "right"
end
cuz if you return 2 then the type will be nil also im not sure if yoiu can use type as a local variable maybe change that too
it wont
crazy how the same code that worked for 24hr just randomly broke & now my base code which has nothing but the bare essential nothingness is broke too, i used them both & know they work, yet they dont now...
also seperate questions, ZombRand needs to be (1, 2000) not just (2000) in order to get a random number from it right>?
ZombRand(2) returns 0 or 1
ow yeah always forget
haha
which is why udderevelyns advice is best
zombrand(var)+1
which eliminates the 0
depends on the usage, if you're interacting with java you usually want to count from zero
my vscode is suddenly producing extra ] and ) to close stuff wtf
the function seems fine, i would make sure it is actually getting called and just throw in some prints to see what is going on
how do i turn of auto close
imean the closing constructor i think idk what its called to be honest
nvm fixed it.. wonder why it suddenly turned on.. i never installed anything new.. weird
Is it possible to spawn corpse and change their sprite
Ow i can spawn item and just dont refresh it it wont show sprite.
But it will show on the loot panel
I need to figure out how to hide it
hi, my mod changes the modData of an item that is on the ground with client-side code. That change however is not reflected on all the other clients, unless the player takes the object and put it down again. Is there a way to force the syncing of the modData?
(same thing if it's not on the player's inventory but it's on a map container)
this is what i use
local pl = getPlayer()
local sq = getPlayer():getSquare()
local x,y,z = pl:getX(), pl:getY(), pl:getZ()
local item = InventoryItemFactory.CreateItem("Base.CorpseMale");
item:setName("test");
sq:AddWorldInventoryItem(item, x,y,z);
but the thing is it doesnt show the item on ground yet
which is what i prefer for now. so you have to do the extra mile to figure that out .. goodluck
you need to send the data
isoObject:transmitModData()
that will send it to server
you might need to send it to clients after that from server, there's an event on receive moddata I think
@fast galleon thanks. The moddata is on the InventoryItem, will that be sent too?
Might aw well try it on debug
What if you first spawn the item on the inventory then drop it
that's the ugly solution: enqueue two instant actions to take the object and then place it again exactly as it was
Inventory is different indeed.
the thing is that storing the modData on the IsoObject is cumbersome and prone to errors. Also IsoObjects don't have the actual item data so it makes more sense (imho) to store everything on the InventoryItem
I can only find an event for GlobalModData (OnReceiveGlobalModData)
which one causes more lag? OnPlayerMove or OnPlayerUpdate
Update is constantly called, whereas Move only when the player actually moves
Aaaand it's up https://steamcommunity.com/sharedfiles/filedetails/?id=2888099799
Thanks to anyone that helped along the way in this past couple days. @sour island especially, I didn't need to check your mod but having a small exchange helped put some things in perspective. In the end, I had some stupid logic error in the time schedule detection 😄
How can I make a crafting recipe that needs 12 items from a category of items. like Base.Mushroom1, BaseMushroom2, ... 5 . I thought i can solve this with a Tag and a RecipeFunction. However it always requires 12 Items of the Same ItemType like eg. only Mushroom1 or only Mushroom2. It does not accept a mix of Mushrooms.
How can i solve this. Please...
@fast galleon kinda solved it by storing the same ModData that I have on the InventoryItem also on the IsoWorldObject, that way other clients will receive the ModData when calling transmitModData on the IsoWorldObject.
The only thing is that if another client pick up the item from the ground it has no chance to copy over the ModData into the InventoryItem and thus it gets lost. I've managed to exploit OnFillInventoryObjectContextMenu and OnFillWorldObjectContextMenu to copy the data if the player right clicks the item in order to grab it, but I haven't yet found anything to handle the scenario where the player uses drag&drop or the double click to take the item.
It's ugly but I think that I'm hitting a vanilla limitation here. Also vanilla objects are bugged on this regard (see notebook, sheet of paper, ... when you try to write on them while they are on the ground/inside container)
gotcha, must we a wording problem, as i can pick the trait but the trait wont function in game? its really weird but i guess that must be the case, time to scoure the rest of the files to see why this is happening
nevermind I can use OnObjectAboutToBeRemoved to copy the data from the IsoWorldObject to the InventoryItem
I have a question about loop
Is this possible
Break; return true; end
You have to put the whole thing 12x
You have no choice. But you could do the recipe using lua but i dont know how to that
Congrats man
that did not work as of yet, the item just disappears.
can i see
sure
the code
Variant 1
item Pokemon1
{
DisplayName=Pokémon #1 (Common),
Icon=pkmn_cardback,
Weight=0.01,
Type=Normal,
WorldStaticModel=01Card,
Tags = PkmnCommon,
}
item stack12common
{
Weight=0.8,
DisplayName=Pokémon Stack Common 12,
WorldStaticModel=pkmntin_stack,
Icon=pkmn_tin_stack,
}
recipe Combine stack12common
{
[Recipe.GetItemTypes.PkmnCommon]=12,
Result:stack12common,
Time:50.0,
Category:EventPokemon,
}
function Recipe.GetItemTypes.PkmnCommon(scriptItems)
scriptItems:addAll(getScriptManager():getItemsTag("PkmnCommon"))
end
Variant 2 (tested with 4 items)
item Pokemon1
{
DisplayName=Pokémon #1 (Common),
Icon=pkmn_cardback,
Weight=0.01,
Type=Normal,
WorldStaticModel=01Card,
Tags = PkmnCommon,
}
item stack12common
{
Weight=0.8,
DisplayName=Pokémon Stack Common 12,
WorldStaticModel=pkmntin_stack,
Icon=pkmn_tin_stack,
}
recipe Combine stack12common
{
[Recipe.GetItemTypes.PkmnCommon],
[Recipe.GetItemTypes.PkmnCommon],
[Recipe.GetItemTypes.PkmnCommon],
[Recipe.GetItemTypes.PkmnCommon],
Result:stack12common,
Time:50.0,
Category:EventPokemon,
}
function Recipe.GetItemTypes.PkmnCommon(scriptItems)
scriptItems:addAll(getScriptManager():getItemsTag("PkmnCommon"))
end
any idea?
If the return true is inside the loop after the break, it won't be called.
then how do i return true if it hits something?
looking at this seems that its all good.. idk why it wont work sorry
Show your code?
local MethLabTiles = MethLabTiles or {
["meth_lab_01_0"] = true,
["meth_lab_01_1"] = true
}
local checker = false
local player = getPlayer()
local cell = player:getCell()
local x, y, z = player:getX(), player:getY(), player:getZ()
local xx, yy, zz
for xx = -5, 5 do
for yy = -5, 5 do
local square = cell:getGridSquare(x + xx, y + yy, z)
local objects = square:getObjects()
for c = 0, objects:size() - 1 do
local obj = objects:get(c)
if obj:getSprite() and MethLabTiles[obj:getSprite():getName()]
then checker = true end
end
end
end
print(checker)
return checker
think it will work this way right
no need to create a break
now my problem is the way i make markers on the ground creates error but it works for somereason
ISSpawnHordeUI:addMarker(square,0.4);
You just want to return when it's true?
no when it hits something
but i fixed it before you sent a msg
and i just asked how
cuz this is how i did it
maybe you have a better way
But when checker = true, do you want to return right away or do you need to keep looping until you've gone through all objects?
i dont want to loop
ok so thats when i break
right
function NearMethTile()
local MethLabTiles = MethLabTiles or {
["meth_lab_01_0"] = true,
["meth_lab_01_1"] = true
}
local checker = false
local player = getPlayer()
local cell = player:getCell()
local x, y, z = player:getX(), player:getY(), player:getZ()
local xx, yy, zz
for xx = -5, 5 do
for yy = -5, 5 do
local square = cell:getGridSquare(x + xx, y + yy, z)
local objects = square:getObjects()
for c = 0, objects:size() - 1 do
local obj = objects:get(c)
if obj:getSprite() and MethLabTiles[obj:getSprite():getName()]
then checker = true break end
end
end
end
print(checker)
return checker
end
I'd just return true and not set the checker value
you could use goto
for i = 1, 10 do
if i == 5 then goto continue end
::continue::
end
but unfortunately it was added after 5.1
so break/return is the only way
Using goto is generally frowned upon
why ?
why?
im used to doing goto on AHK
lol double why
but ididnt know lua has it too
Can lead to spaghetti code. Typically when you use goto, you can just return out instead
anyways since i think my code works i guess ill have to prceed for the mean time hehe
ISSpawnHordeUI:addMarker(square,0.4);
idk, it just skip iterations, I mean, it skip code lines
how do i make the same shiz without error
it works
it adds the thing
and i dont know how to remove the markers too haha i can only remove if i spawn 1
1 circle i mean
function defineMethLab()
print("defining room")
local x, y, z = getPlayer():getX(), getPlayer():getY(), 0
local xx, yy, zz
local stand = getPlayer():getCurrentSquare():getRoomID()
for xx = -30, 30 do
for yy = -30, 30 do
local square = getPlayer():getCell():getGridSquare(x + xx, y + yy, 0)
if square:getRoomID() == stand then
ISSpawnHordeUI:addMarker(square,0.4);
square:getModData()['isMethlab']=true;
else
square:getModData()['isMethlab']=false;
end
end
end
end
function spawnMethTile1()
local square = getPlayer():getSquare():getAdjacentSquare(getPlayer():getDir())
local objectz = IsoObject.new(square, "meth_lab_01_00", "", false)
square:AddTileObject(objectz)
if isClient() then objectz:transmitCompleteItemToServer(); end
defineMethLab();
end
If goto is required for continue, then I guess that's fine. I come from a language where continue is built in and goto is used separately for other things.
Oh I see, yeah, each language have is own crazy things
@sour island im sorry to have to tag you... but i believe you are the only one who knows the answer to my problem
is it possible to do this
ISSpawnHordeUI:addMarker(square,0.4);
that wont return an error?
and is it possible to destroy/ remove the circles if i made bunch of em
woops nvm got it
local _square = getPlayer():getSquare()
local circle = getWorldMarkers():addGridSquareMarker("circle_center", "circle_only_highlight", _square, 0.0,0.0,1.0, true, 0.5);
local pointer = getWorldMarkers():addPlayerHomingPoint(getPlayer(), _square:getX(), _square:getY(), "arrow_triangle", 0.0,0.0,1.0, 0.6, true, 0.5);
pointer:setRenderOffsetY(0);
pointer:setStickToCharDist(130);
pointer:setAngleLerpVal(0.25);
pointer:setMovementLerpVal(0);
TestMarkers.add(circle, pointer);
Has anyone made a fixed-height replacement for these wonky ass numbers?
I am currently making an overlay and the subtle wonkiness of the irregularly tall numbers really annoys me on the 4x font size setting... Wondering if printing in a different number font is possible, or if mods replacing that font can be made or have been already.
local mark1 = getWorldMarkers():addGridSquareMarker("circle_center", "circle_only_highlight", getPlayer():getSquare() , 1,0,0, true, 0.5)
TestMarkers.add(mark1)
i cant seem to delete them lol
mark = getWorldMarkers():addGridSquareMarker("circle_center", "circle_only_highlight", getPlayer():getSquare() , 1,0,0, true, 0.5)
TestMarkers.add(mark);
mark:remove()
found the solution
can't you just return true? you don't need to break
Im not sure cuz so far theres an error on my code i cant seem to find its pointing to a luaobject ithink
So when i open the window that lets you reload stuff
It doesnt show anything
for i = 1, 10 do repeat
if i == 5 then break end
-- extra code here
until true end
not quite the same as goto, but acts like a continue.
this moves the break from the for outer loop to the repeat inner loop (which doesnt actually loop, since until true is always true.)
the downside of this method is it becomes impossible to break out of the for loop
Where do i put the return true?
Yeah, I said that earlier. Return true in the loop, return false outside of the loop. You don't need the checker value
Events.OnPlayerUpdate.Remove(isAtMethLab)
can i do this? i can do this right?
ok sir
yeah?
cool thats what im doing instead
hi, I am looking for a solution to pass the modData "keyId" of a vehicle on the server side into clients.
In my mod, we can change the vehicle ID key, and therefore, I need to pass it on to the clients. (via server)
Because this code is not working.
vehicle:transmitModData()
would you think that a vehicle part could specifically contain the keyID?
is keyId moddata? i thought it was just part of the vehicle class
if it is, you can probably just use vehicle:transmitCompleteItemToClients() - i can't be sure how that interacts with vehicles though, since they have a lot of special programming compared to most other objects
Of course, I didn't think of this sentence, I'll test that. ty
@bronze yoke Unfortunately it doesn't work..., on another of my mods, I introduce modData in the vehicles, and the clients load these mod Data, but only when loading the cell. I haven't found a way to pass nor modData nor keyID.
you can use a servercommand to set the keyid on the clients
ok, i setkeyID by server, and i sendserverCommand the keyid so clients setkeyID too, is that right? I thought about it but, good idea 😉
mm how can i change the dmg of one axe without changing the dmg of all axes?
ok so just to make sure, basically if theres no args specified, the values will be overwritten, right?
change the stat on the InventoryItem, not the Item
@bronze yoke thank i'll try
Hi guys does anyone know if there's a mod to build some sort of gun range/target practice?
hey guys, I have an issue with brita's weapons sound, as the custom ones are replaced by the regular pz sounds, anybody knows why?
not sure if this is the place to ask but does anybody know if there are any mods that add more extreme weather conditions to the game? heavier storms/rain etc.
if not is there a way to increase the chances of regular storms to happen more frequently?
hey i have a q
how complicated is it to add an item to the universal zombie loot table?
Hey if an item loads the icon on the ground instead of the fbx file referencing a model why could this be?
i was kind of curious if it would be Practical for me, someone who has no coding skills whatsoever, to make it so that zombies have a small chance to drop cassettes from my true music mod
I believe you can just add the item to inventorymale and/or inventoryfemale in Steam\steamapps\common\ProjectZomboid\media\lua\server\Items\Distributions.lua
Does anyone know how to access the old code that gave the herbalist trait from the herbalist magazine? I'm trying to make some custom magazines/items that add traits.
Does anyone have a tutorial to making armor mods? Only have a single piece in mind that can be crafted as well as it can be looted.
Do yall get all your mods from the workshop or is there another place
table.insert(ProceduralDistributions.list["inventorymale"].junk.items, 0.7 * SandboxVars.MFTEOTW.lootrarityfactorA);```
like so?
I assume that won't work since ProceduralDistributions doesn't have inventorymale
ooh okay hm
the herbalist magazine doesn't give a trait, it gives a recipe
i don't think it ever has
there's some mods that make it do that, so i would look at them
my bad - looks like it used to - but i know for sure that's code is totally gone, unless you want to download an older copy of the gmae
do i still use the table.insert function then? i'm not a coder 😅
table.insert(SuburbsDistributions["all"]["inventoryfemale"].items, 0,7);```
ah ha! thank you!
thanks, that would probably be easier
Does anyone know if OnTick isn't accessible on server?
It is accessible and usable too. It is raised 10 times per sec on server
Strange
Trying to figure out why my twitch integration mod for EHE isn't firing events properly
What are you observing?
The log shows the event is launched
but it never appears
My guess is the update isn't firing
I recently refactored it to not actually launch events but add them to the scheduler - which allows for paced integration
works in SP
but in MP 🤷♂️
Hello guys i am new to the PZ and i wanted to build my first Mod to the game someone know where i can start? i want to learn how to build one, i know Javascript 🙂
https://www.youtube.com/watch?v=N6tZujOPnDw This is a commonly recommended resource
This tutorial video will show you how to make a simple drink in Project Zomboid. I will go into the steps involved from start to finish. Read more below.
0:00 intro
1:08 Start
1:44 Searching for images to use in game
2:30 Searching for the Sound Effect
3:06 Creating mod file directory
3:54 Creating mod.info
4:34 Creating a poster
7:14 Adding ne...
@dusk sonnet thankss 😄
where can i find the section that lists vehicle textures?
not the acual textures, but the txt file or whatever that contects them to a model
nvm i found it
ive seen people talk about this before, but i don't think its been done yet, and on behalf of my rp server and the pz community other servers or just personal two man teams that want more immersion id love to commission a mod
a working pool game, 100 dollars. if you take it a step farther and work on gambling tables like poker, roulette, and maybe pinball id pay even more
@sour island I am trying to do something semi simple, get when a vanilla helicopter is active and if the player is its target, would you happen to know how I could access the vanilla helicopter to check its variables? (Eventually I will be adding support for EHE too but not yet)
getCore() and getWorld() returned nothing
Ha looking through these files, looks like I dead ended here once before 2 years ago, I suppose its still not exposed at all
helicopter isn't even exposed, yeah
sorry i didn't manage to check that until... the exact moment you worked it out yourself lol
Damn, its been years, just expose it already 
Is there a file size limit for the workshop.txt file or something?
I am running into an odd issue where a new mod is not appearing when I upload it
Just stays hidden, shows no data, shows no description
definitely sounds like a messed up workshop file
is your file so big you'd be worried about a size limit...?
i had a similar problem a long time ago, but i don't remember what it was u_u
It's pretty long
Gonna try slicing a chunk off
Dropping it in a ReadMe instead next to mods
Would that likely be okay with Steam?
Slice some off and save it to put into the actual steam description.
What exactly is in your workshop.txt file?
Hmmm that may have been it
I did two things tbh so not sure which mattered
But I cut the size down a lot, and I removed some ----------------- I was using in the description lines as text decoration.
Oh yeah
I must have JUST went over the limit
I just pasted my stuff into the window
And it pasted. I was like, okay
and then I tried to add "below" back to the text and got to "bel"
I must have legit been on the character limit
Damn, didn't realise the workshop.txt actually had a limit.
Lmao word
Whatever I actually just tried saving and it wouldn't let me
I'm done fighting it, I get it, description too long, config instructions relegated to ini
If you can find the ini, you can find the readme.
And if you can't find that, skill issue.
lol I mean I told them where it is in the desc of course.
And if they can't find it after being told where to find it, they probably shouldn't bother trying to use it 😛
Exactly.
nice, I just wanted that. Is it possible to add a check if a square is still loaded.
it's hidden?
thank you
If you want to know if a far-away square is still loaded, that is a bit outside of the scope of the mod currently, but I could look into how that is done and try to let you know if I can add something. I might be able to add a debug function for that (something where you could type PB.checkSquareLoaded(12039, 23191) in the debug console and it would tell you whether that square was loaded). It cannot tell you anything about squares you are not standing in.
I'm not sure what the relevant position, is it square you select and count from?
For trapping, they must be placed "far", if the square is loaded you catch nothing.
i'd assume relative is your position in the current cell
probably just need a check for the relative square
as for trapping, i don't think it's about whether the square is loaded, there's a range set in the global object
global objects are buggy in multiplayer though, so you might not be able to see what you caught until you unload and reload
i should probably make that fix i found into a mod or something...
what you mean?
just do updateFromIsoObject
the iso object and lua object don't get linked properly in multiplayer, or at least not always
actually, that might have just been for z>0, which doesn't really apply for traps
function STrapGlobalObject:checkForAnimal(square)
-- you won't find an animal if a player is near the trap, so we check the trap only if it's streamed
if square then
-- (note turbo) if square~=nil do a check to see if theres any hoppables near the trap, this is an exploit to make traps invincible to zombie damage.
-- when placing the trap it does check for hoppables, but a window frame could be placed afterwards.
-- when this is the case, remove bait and animals if any.
if self:checkForWallExploit(square) then
self:removeAnimal();
self:removeBait()
end
return;
end
so if square exists, it removes and skips the rest of code
guess i was wrong then
there's something weird about how the iso objects specifically for global objects load that makes it not fully there on the server, and i think only for z>0? it's quite strange, i could never find the cause, it's probably something too technical for me
I'm using that system in my mod, so if you find a bug it's good to know about it.
If you're asking about relative position, @bronze yoke is right afaik. Say you're at cell 1, 2. That's square 300, 600. If you walk 5 units to the right, your relative position would be 5, 0, but your tile position would be 305, 600.
I do not think I fully understand what you need
ok, thought this might be the case
can you add a square to measure distance from, like start and walk from point a to b
if you add the line isoObject:addToWorld() to the start of your loadIsoObject function it seems to completely fix the issue
water goes bad applies a blanket fix for it, and i'm considering releasing it separately too, as at the very least this behaviour is extremely noticeable on water barrels, and even causes a lot of vanilla bugs
addToWorld on server side?
The trouble I had with syncing indexes, I'm not messing with that for a while
yeah, the problem is on the server the iso object just isn't added to the square for some reason (it thinks it has been though), and that makes the server global object system bug out
is there a way a can check this later when I have time?
if you build a water barrel on the second floor, running :getObjectIndex() on that water barrel on the client will give you a value that's out of range for that square's object array on the server (and if you loop through the objects on the square you can verify that it is definitely not there)
this is why plumbed rain barrels don't seem to update in multiplayer, the isoObject doesn't get added to the square on the server so its properties can't be altered by the luaObject, so it only updates when you leave and return and the luaObject's values are applied directly to the isoObject again
that seems specific system problem, the event triggers before server adds the object on square so checking the index would definitely cause problem
no, i became aware of this issue because client commands regarding actions towards global objects don't work if the object is above z 0 because of it
it doesn't matter when it was loaded, on the server the object never gets added to the square at all
which file is the check in?
what check?
the index check
which index check?
i think an easy example i can give of this is in the timed action to pour out all the water in a rain barrel
local obj = self.object
local args = { x = obj:getX(), y = obj:getY(), z = obj:getZ(), index = obj:getObjectIndex(), amount = 0 }
sendClientCommand(self.character, 'object', 'setWaterAmount', args)
```when the rain barrel's z is above zero, the server always prints 'invalid object' and doesn't actually alter the water amount, because of this part of code on the receiving command
```lua
Commands.object.setWaterAmount = function(player, args)
local gs = getCell():getGridSquare(args.x, args.y, args.z)
if args.index < 0 or args.index >= gs:getObjects():size() then
print('invalid object')
end
end
it's not a matter of whether the object has been fully loaded yet or not - the object is just never added to the square at all
the object does actually get added on the server when you first build it, so it will behave perfectly until you restart the server for the first time
That sounds like the fault of building / placing logic.
Regarding the Z level, I have a weird question. Is the barrel returning isFloor() as true.
check logs on server when you build/place the barrel about index. Might need to be in debug to print them
or client logs, considering it works later
You just want an option to mark a square and automatically calculate your distance to it as you walk away?
PS @fast galleon I just pushed a patch... now when your map is open, you can mouse around and it will automatically show you the breakdown for whatever square you're mousing over.
I don't know if that's useful for what you're doing, but figured it might be.
@bronze yoke
with your technic, it work for transmit key id, I used this way on the server side (for send to all clients):
for i=0, onlineUsers:size()-1 do
local player = onlineUsers:get(i)
if player then
sendServerCommand(player,"MoreLock_setKeyIdNeiman", "true",{vehicle:getId(),ID})
end
end```
would you make like this?
I think that gonna be perfect
The sendServerCommand that specifies no player parameter will send to all clients
Also, your approach will send multiple commands to a single client that has multiple players on it (splitscreen)
Hope it saves you time!
One thing I could do pretty easily for you would be add a map feature where clicking the map shows a 4-5 second message with the x and y tile distance from your tile to the tile you clicked on the map... Would that be useful?
@hearty dew so how you do it for send of this key id for all clients?
Will I be able to understand from the given information if the getSquare returns nil?
I'd like to mark the cutoff range, so that when I walk there I can see I'm in outer zone.
Javadoc Project Zomboid Modding API declaration: package: zombie.Lua, class: LuaManager, class: GlobalObject
It just shows you location, not whether there is info in the square.
the one that has no player parameter
local module = "MoreLock_setKeyIdNeiman"
local command = "true"
local args = {vehicle:getId(), ID}
sendServerCommand(module, command, args)
Just make sure your module and command are correct
(I suspect they aren't considering their names)
that's enough, it might not be the purpose of the mod so I will hook in to add anything I might need.
For trapping, the useful information would be the type of foraging zone (deep forest, urban, etc) and if the getSquare(x,y,z) returns a square or nil
The first one is easy to see when you are there with foraging ui but the second one is not something visible.
@hearty dew ok, I was complicating the task ^^ ty that work 😉
Anyone knows how to turn a sprite into moveables
There is a sprite property that when set to true lets it function as a Moveable
IsMoveable or similar
You can see/set it in TileZed
But i need to write the lua code to pick it and drop it or is it automated
How do i add a function or moddata when a player place the item
hmm i have a question. i havent had time to look into it but. how easy is it to to check if another mod is installed ?
what i kind of want is if mod b is install do this, if not dont do this more for trying to balance stuff or create some recipes there normal wouldnt be there
is there a similar event to my idea... OnPlaceObject specifically moveables...
like how do i trigger a function as soon as i drop a specific moveable item
if getActivatedMods():contains("AuthenticZLite") then
hmm.
so that how you do it hmm.
i can see it can end up been a nasty nested code. vs if you do it as a requied hmm also woundly a "contains" call also say true if it was another mod was called AuthenticZLiteImprovedAndNewVersion right because it contain that name in the string hmm
if getActivatedMods():contains("AuthenticZBackpacks+") then --dosomething end
if getActivatedMods():contains("Authentic Z - Current") then --dosomething end
here
Hey guys with the distributions.lua
How does the value influence spawn chance here, what would 0.5 mean, compared to having 5?
table.insert(ProceduralDistributions["list"]["DishCabinetGeneric"].items, "Something.Item");
table.insert(ProceduralDistributions["list"]["DishCabinetGeneric"].items, 0.5);
I want to know if this is a value from 0-100 😛
yea i did understand what you was saying first time.. just going to be a bit complix later on..
e.g like this diagram. hmm here where i get into problem as well becuase mod c or mod d is requied to either have e | b | e but note needed. problem is if it doesnt have any of the mod it like dont add anything and it just look as a broken mod... hmm (noticed i made 2 times e mod)
also that a simplefied version of the larger project ofcause
You might want to be more specific what your trying to do @mint sphinx
That true 😅 but it's a bit hard to explain sometimes. Some og the mods i have made is just plain generic generators i have made to make something easier but i will try the import thing you said. To see if i can use it 🙂
I thought it was quantity, not spawn chance
I'm looking for a way to identify an IsoCell on serverside. The idea is to get all cells which have at least one player in it. So I've try something like the following:
local players = getOnlinePlayers()
print("onlinePlayersCount: " .. players:size())
for i = 0, players:size() - 1 do
local playercell = players:get(i):getCell()
local notFound = true
for _, v in pairs(cells) do
if v:getWorldX() == playercell:getWorldX() and v:getWorldY() == playercell:getWorldY() then
notFound = false
break
end
end
if notFound then
print("found new cell: " .. playercell:getWorldX() .. " / " .. playercell:getWorldY())
print("minX/maxX/minY/maxY: " ..
playercell:getMinX() ..
" / " .. playercell:getMaxX() .. " / " .. playercell:getMinY() .. " / " .. playercell:getMaxY() .. " / ")
print("width/height: " .. playercell:getWidthInTiles() .. " / " .. playercell:getHeightInTiles())
table.insert(cells, playercell)
end
end
The server log shows the following:
LOG : General , 1668428194235> 399’608’821> onlinePlayersCount: 1
LOG : General , 1668428194235> 399’608’821> found new cell: 0 / 0
LOG : General , 1668428194235> 399’608’821> minX/maxX/minY/maxY: 0 / 0 / 0 / 0 /
LOG : General , 1668428194235> 399’608’821> width/height: 130 / 130
So I don't get how this works. When I'm looking on https://map.projectzomboid.com I can see the cell number(s) on the left:
Map coorinates -> Cell: 41x9
You can I find something like this?
I'm not sure but i believe you can get exact cell with a divison on getX() and getY()
local y = math.floor(player:getY());
cellx = math.ceil(x/300)-1;
celly = math.ceil(y/300)-1;```
maybe without -1 if it does not round to the higher digits@blissful salmon
Hmm... Where does the 300 come from? Is this the max cell width/height?
in your exemple cell 41x9:
12435 / 300 = 41,45
2813 / 300 = 9,376666666666667
because the map have 300x300
ok, i'll try...
with math.ceil, your number will be rounded, so -1 probably necessary
or maybe just use floor then 🙂
That's spawn chance not quantity afaik? If you bumped a container distribution to 5.0 you'd see rare items way more often even if you have loot quantity set to extremely low
Ah, yes. Just reread this graphic. Thanks
That that the case, can anyone else weigh in pls ? 😄
look up
Thanks dude my bad 😄
I take that it's a percentage and the rolls give more than one shot at the RNG , if the result is the same or above it would spawn the item? Thanks
General rule is that the more items there are in the list, the more loot will appear, because to my understanding, a chance is rolled per each item whether to spawn
Fellas! Where in the PZ folder can I find all of the different sprites for world decorations?
I'm specifically looking for some billboards that I can use as guides when making my own stuff in Blender
And if i make inserts like this
--Mechanic shelf miscellaneous
table.insert(ProceduralDistributions["list"]["MechanicShelfMisc"].items, "CraftAndRefillLighters.SwanLighterFluid");
table.insert(ProceduralDistributions["list"]["MechanicShelfMisc"].items, 4);
Would it affect the whole stores loot or only for that one item, i was learning about how other mods did it and it's like this
It would only add that single item on the list. The others would be rolled as usual
Thanks dude
Bear in mind that this would increase the overall average loot amount
Yeah of course, just the one item for now 😛
Does that only works for some parameters?
I try to put my rifle into "FirearmsB41" attachments so i dont have to mess around with his items.
Adding AttachmentTypes work fine.
But i cannot make it work with "mountOn" parameters.
@fast galleon Small update. Made map font default to black because most colors are pretty hard to read on the map. This can be disabled in the config if you REALLY want the overlay to stay your chosen color on the map. Also, I added a feature where you can click the map to see the (x, y) vector from your square to the square you clicked (message fades out in a few seconds).
Nevermind...
Had to add the mod tag xP
how do i make an oncreate function success chance based
should i put it on the on test instead or onperform?
imean can perform
i would put it on the oncreate, that's where vanilla randomises things
but the thing is what im doing is the oncreate is just going to activate the poison tiles it wont give back stuff.. as the oncreate is used for multiple other recipe
onCreate has parameters for results
You can modify them at that point or even get rid of them
Actually, I'd have to confirm that
I know a few disassemble recipes have multiple results done via onCreate
How do i do this?
What if the result has =3 for example
Check the file recipecode.lua
I dont see an oncreate that has an add inventory then placed the result as the item to give
I think it's an array
Ow ok got it
Pretty sure disassemble adds multiple different types of items and its not done in the script
Yep
I could be mistaken, it's been a while since I messed with onCreate
Ayt
Amm wht about moveables
We made a tile with moveable set on it
Then an item that is type moveable
Witht he jndicated tile
But then when we pick it up it doesnt get picked up
Not if i spawn the item
Cuz as i looked at admin more tiles
It only has an item script with bunch of moveables using vanilla tiles
Basically he just made the vanilla sprites moveables instead of just having those as tiles
I cant seem to replicate this tho
Using own tiles
SOLVED! finally able to make the tile as a moveable
I've some trouble with my OnZombieUpdate so I wanted to make some prints. But they don't appear on the coop-console.txt. I use hosted on my local computer to test...
So then I tried the following in the lines of code (server directory):
local function OnZombieUpdate(zombie)
print("OnZombieUpdate")
end
if isServer() then
Events.OnZombieUpdate.Add(OnZombieUpdate)
end
shouldn't this spam my log full with "OnZombieUpdate"? Maybe I forgot something....
i don't know why that isn't working, but putting a print on OnZombieUpdate will crash your game
prints are really expensive because they involve disk operations, and OnZombieUpdate can be called hundreds of times a frame
when i did it for a similar reason, it just completely froze the game until i closed it
Rough
probably related to zombie owners and stuff
yeah i just had mine count the events and print that EveryOneMinute
when I do it on solo my computer also survived. I just wanted to test if it's really executed... But somehow I get nothing. Didn't have to kill the task.
well of course nothing bad will happen if it doesn't even work
i'm not really sure why that isn't working, i think i've used OnZombieUpdate on the server before and it was fine...
I also used it before. But since it didn't work anymore I tried to find the problem and ended with this.
Maybe I create new mod with only the lines from above and try it this way...
Hi everyone, I'm here again.
I've done some more work on my mod: https://steamcommunity.com/sharedfiles/filedetails/?id=2888099799 (shameless plug)
Added support for rain for example. however, I'm having people ask for special presets dedicated to different other cases, namely Fog and Snow (as in snowing, not just snow on the ground).
Before I start a wild goose chase on the internet... is someone aware of APIs to detect when it's snowing and when there is fog? Something like the RainManager:isRaining() for when it rains 🙂
My thought was to simply restructure the mod to offer a day/night/special preset. On the special you select what you want the trigger to be (between, raining, snowing, fog for now) so that it keeps things simple enough in terms of options instead of keep adding new tabs over tabs of options and making it complicated to understand how to give priority between snow/rain/fog/etc etc.
But before going there, I need to find the correct APIs for those events
The name of the tile should be the same as the defined
I think that solved it
Im able to craft item that i can place now then becomes a tile
My older method relied on spawning the tile it wasnt really a proper way of doing things
Since it just appear its still alot better if its a placeable thing
Which is the reason for my mods lag earlier
Well could be
Im done with the meth mod btw!
oh wow well done!
Thnx for the ideas one of your idea didnt hit me last night cuz of the lack of sleep i guess
Aiteron mentioned a solution which was what you also told me i think.. which was define the room during crafting
Instead of when placing the tile
Tho it caused alot of laggg
So i made it delayed for a bit before it defines the room
Then the onplayer move will only activate the poison effect once
And will just return if the player is being poisoned already
And yeh that solved the lag problem
Next up heroin!
Im thinking of using bandageleft arm as the AnimNode:
Ok digging around other mods I've found these two:
FOG: getClimateManager():getClimateFloat(5)
Snow: getClimateManager():isSnowing()
The snow seems pretty legit. Anyone knows if the fog is actually correct? I've no clue what that getClimateFloat does but it would make sense that it tried to check if a specific climate (index 5 in this case) is true.
looks right to me
this.fogIntensity = this.initClimateFloat(5, "FOG_INTENSITY");
you might need to check it's above a certain threshold, you can use the climate debugger to see what that should be
I've found also getClimateManager():getFogIntensity()
maybe that's the one
I had already planned to add a selectable threshold for the user for rain anyway. At this point I'll write a unified experience and allow to choose the threshold for rain, fog and snow
While I'm here, is there any source/doc that shows how to write the mod options?
I guessed the checkbox being "boolean" types but is there a type of option block for a preset of values?
Imagine I want to have a select that allow to choose between: any|slight|average|heavy in terms of intensity of the snowing/raining/fog...ging?
Also a simple link to another mod that used something like this is more than enough 😄
oh yeah, this will do exactly the same thing but is actually readable haha
for preset values, you can use enum
here's one from one of my mods:
option OccupationalClothing.WantFireman
{
type = enum,
numValues = 3,
default = 3,
page = OccupationalClothing,
translation = OccupationalClothing_WantFireman,
valueTranslation = OccupationalClothing_FiremanLevels,
}
```and the translation should be formatted similarly to this:
Sandbox_OccupationalClothing_WantFireman = "Firefighter Suits",
Sandbox_OccupationalClothing_WantFireman_tooltip = "Firefighter suits provide far more protection than other occupational clothing. Fire officers will still receive other occupation-based clothing.",
Sandbox_OccupationalClothing_FiremanLevels_option1 = "None"
Sandbox_OccupationalClothing_FiremanLevels_option2 = "Trousers (Vanilla)",
Sandbox_OccupationalClothing_FiremanLevels_option3 = "Full Suit",
in the lua, the enum sandbox option will be the same as an integer option
hey i've got a question!
is there a way to like. set up a loot table where the game only picks one item from the table, rather than adding individual items to the loot pool where it rolls for each individual items
i'm running into a problem where like, i want the game to drop one of nearly a thousand items every couple of zombie kills or so, but you simply cannot set the spawn rate low enough on items that it doesn't spawn at least one item, often 2 or more, from the set on every zombie
so i'm wondering if there's a way to like.. just tell the game 'hey, i only want ONE of these to drop if any drop at all, so pick from this list'
i'm not sure if you'd have to alter the set up for zombie corpses, but for container loot i've used a dummy item that gets replaced with a random item after the container is populated
you might have to use a different event than OnFillContainer, not sure if that gets fired on corpses or not, but the concept is the same
i don't really wanna bother you enough to walk me through that unless you want to--so instead, could i ask which mod you use that system for so i can give it a look and try to reverse engineer it on my own time? i'll give u a credit on the workshop page too, you've definitely earned it given all the help you've given me! :)
the relevant code is actually used for setting vhs data, so you wouldn't be able to use this exact code (and it has some rarity stuff in it that you might not want)
local itemList = {'Base.whatever', 'Mod.somethingElse', etc}
local function replaceDummies(_roomName, _containerType, container)
local dummies = container:FindAll('DummyItem')
for i = 0, dummies:size()-1 do
container:Remove(dummies:get(i))
local itemChoice = ZombRand(#itemList)+1
container:AddItem(itemList[itemChoice])
end
end
Events.OnFillContainer.Add(replaceDummies)
```here's what a more generic version might look like
so this would take the dummyitem and replace it with an item from the given itemList field?
yeah!
yeah any place that runs on the server is fine
gotcha! thank you so much albion, i'll give this a try :)
hope that works! ^_^
hello there
What is the vanilla use delta for propane tank in 41.78?
or where can I check the file? I just woke up and couldnt remember

