#mod_development
1 messages Β· Page 85 of 1
almost
I think you need to add
ClothingItemExtraOption = Wallet_WearPocket,```
to your wallet item
where `Wallet_WearPocket` is tied to a definition in `media/lua/shard/Translate/[Your Language]/ContextMenu_[YourLanguage].txt`
```ContextMenu_[YourLanguage] = {
ContextMenu_Wallet_WearPocket= "Put in Pocket",
}```
Obviously you can customize the ContextMenu define to what you want.
because you're currying the params, you'll need to capture the function into a table and then table.insert your additional arguments
e.g.
local args = {func1()}
table.insert(args, otherArg)
func2(unpack(args))```
you don't need to do this if the function call is the last thing in the argument list
e.g. func(0, func1()) will work, but func(func1(), 0) will not
ok so that does work, however i get an Error upon clicking to equip it
i dont have a ClothingItem defined so that throws an error, can you set world items as clothing items?
ok nvm just found out that is the worldmodel
so i took the fannypack ones
doesnt make sense, but i dont want to make a new one
@vast nacelle thx for your help along the way
Based on the Holster which also doesn't actually show anything.
media/clothing/clothingItems/WalletMod.xml:
<clothingItem>
<m_MaleModel></m_MaleModel>
<m_FemaleModel></m_FemaleModel>
<m_GUID>85f7b7e8-e395-46ff-a6cf-cf73089ab993</m_GUID>
<m_Static>false</m_Static>
<m_AllowRandomHue>false</m_AllowRandomHue>
<m_AllowRandomTint>false</m_AllowRandomTint>
<m_AttachBone></m_AttachBone>
<m_BaseTextures>emptytexture</m_BaseTextures>
</clothingItem>```
media/fileGuidTable.xml:
```<?xml version="1.0" encoding="utf-8"?>
<fileGuidTable>
<files>
<path>media/clothing/clothingItems/WalletMod.xml</path>
<guid>85f7b7e8-e395-46ff-a6cf-cf73089ab993</guid>
</files>
</fileGuidTable>```
oh nice can i just call up WalletMod in the ClothingItem?
Yes
@neon bronze Just need to add the files where I listed the paths
And put clothingItem = WalletMod, in your wallet item
should lua files added by a mod show up here? mine won't show up when i search it and i'm not even sure if it's running
You can search there for your files names but if you had an error pre loading screens, most likely they have not initialised
oh okay that was probably the case, just realized i had a capitalization error
thanks
hey all! I was experimenting with ChatGPT and asked it to create a project zomboid mod for a wind turbine, and it actually created a whole bunch of code that seems at first sight pretty legit, but when comparing it to the actual documentation seems.. well not entirely imaginary, it's somehow somewhat based on how the game does things, and written in lua, but I don't think the definitions and the like are in the right spots :P here's the code if anyone's curious: https://git.dragonhive.net/anthropy-zefnoly-collabs/zomboid/windturbines/-/blob/main/windturbine.lua
I did however want to further try figure out how to make this mod work; do people think it's feasible at all to build such a thing? Is there even a concept of wind in the game, or would I just have to make it a static thing? A friend of mine also made a nice basic model that could be used as windturbine so I got the assets covered I guess, although not sure how to put it in the game
how can you get a thumpable object through its id?
Hey y'all. I'm new to modding PZ and struggling with getting my test mod working. It shows up in the modlist, but is most def not firing in game when enabled.
The screenshot shows the mod's location and the content. Could someone let me know what obvious thing I'm doing wrong?
any errors or anything in the log?
None that are related. I'm tailing the log while the game runs, lemme check to see if the mod is even loading rq.
Your lua files need to be in one of the following directories:
lua/client - for clients
lua/server - for server
lua/shared - code will be available on both.
You have stuff in lua/Mods/ProjectTarkov
I figured it was something like that. I couldn't find a consistent tutorial for what the file structure should actually look like.
nice, game does have wind intensity you can use.
is there a function that returns the corresponding text for these unique ids that look like
text = "RM_1de8b503-994e-42f5-b589-cc9a0260cded"
it looks like they correspond to keys in different translation files
Is possible to call admin commands from a LUA mod server side?
that's awesome, that's definitely something I could use. I'm first going to try and put everything in the folder structure as it should be for project zomboid mods, try see if the code does anything at all .. I have no idea how to define buildable things yet, I'm entirely new to modding this game hehe, though I do know a fair bit of other code and made mods for other games like space engineers before
that lua does almost nothing
yeah i had a look and like
it's cool that it has the overall structure in there but it doesn't really do anything
yea thought so, though it seems to define its base functionality, but it's probably missing a lot of other stuff that's required to make it work
its definitely lua, wouldn't give any errors i can see but wouldn't do anything
it definitely doesn't have any conception of pz
it just assumes what might be there and how things might work
it's a mod for a theoretical game
could be useful if you need an algorithm for something that can be generic though
yea that's what it does when it doesn't have the right info, but it did pick lua, and if I compare the lua it does seem to have a few of the same functions as I saw in some other code, although not nearly as much as in other files
You may be able to inform ChatGPT about how a PZ mod should be structured. Doing that in a concise input will be hard, but it is probably doable.
You would need to do that before requesting that it generate lua for you.
yea I might be able to explain it to chatGPT, it remembers things in its conversation, though it's hard to keep coherent because it'll sometimes overwrite things or hallucinate in other ways
Yep, I had it running a pared down D&D game the other night, but it took a couple hours of figuring out a good input that got it to do things like request die rolls from players.
right now I'm just trying to figure out how it would have to work though, I could always instruct chatGPT once I do know but I'd have to learn it first :P
gonna look at this steam powered generator mod, might be a good example for how to implement custom power generators in the game https://steamcommunity.com/sharedfiles/filedetails/?id=2762648316&searchtext=generator
does anyone knows what the "setWorldTexture" command does and how to use it? It can be found here: https://zomboid-javadoc.com/41.65/zombie/inventory/InventoryItem.html#setWorldTexture(java.lang.String)
Javadoc Project Zomboid Modding API declaration: package: zombie.inventory, class: InventoryItem
Is mod data used for mod data in general or can you store data specific to a player as well?
I do not know, but have you tried using getWorldTexture() to see what string it returns, then using the setter to change it?
I'm reading through the documentation online, on the forums
but I don't understand which methods / functions to use for a specific person and which for a global variable that the entire mod needs to use
I'm experimenting with a basic code in vsc, so far no luck
getPlayer().getOrCreate('BarricadedWorld')
I know this looks like legit trash probably but I'm on like the 5th try to learn how to use it π€£
i imagine it's the texture when the object is on the ground
or maybe when it's being held
if it can just be set on the item and isn't tied to the script it might be just when the item doesn't have a model, otherwise i'd be surprised it doesn't use the script no matter what
Maybe this'd work. It's actually a method (learnt the difference recently)
So instead of what I posted above, just use getPlayer():create("TableExample")
i think you're a bit confused about how moddata works
Probably lol
the ModData object is for moddata that isn't tied to a specific object - we usually call it global mod data
e.g. local modData = ModData.getOrCreate("ModName") if you need to store data that isn't tied to an object, for example i have a mod where water becomes unsafe to drink after some time and i store the time it should go bad in global mod data
for an object (such as an IsoPlayer) just use local modData = object:getModData()
Is there a way to reload lua without restarting PZ?
run pz in debug mode (launch parameter -debug) and there should be a reload lua button on the main menu
reloading your save should reload lua too
Hmm. So if I understand correctly.. the first part I do. So global mod data like you said is for things that the entire mod will have and use, not just a player.
local mod data, I use getModData and I assume it'll return a table I can modify?
Since I don't see any methods in the docs that will allow me to directly modify it within
getModData() returns a completely normal lua table
Is it the same one I put in? Like, if I put one with 2 keys called "name" "lastname" and I add it to a player. I return it, will it still have the same keys?
oh right yeah wanted to ask that as wel, how to asign a table to the player
like you can't put a table 'into' moddata
since I only see get or has
Just checked it. It is somewhat mysterious but probably related to the icon of the item.
the 'has' methods are a bit mysterious since all objects that can have moddata do
that explains why my if function always returned true even though I never asigned mod data to a player....
i had a look, and there's only one valid world texture in the entire game, so it's definitely an old system
replacing the moddata would be undesirable anyway, since you'd wipe everything every other mod has added to it
good point
ya... I didn't find any call of this command in the vanilla code. So probably outdated...
Another question: Is it possible to put different items in one stack in the inventory?
Or will they stack automatically if they have the same displayname??
you want to do things like
local modData = player:getModData()
modData.myValue = 5
modData.anotherValue = "string"
I totally tried something like isoObject:getModData() = nil at some point
if you're only referencing it once you can also just do player:getModData().myValue = 5, you can think of getModData() as a totally ordinary lua table reference
Ahh I see, so modData is just a variable that will help me access the entire mod data of the player, and the keys are what follows after the dot
@bronze yoke your thumbsup means: yes, same display name -> same stack?? (sry for interrupting your chat)
that's right
No my bad razab I was interrupting yours
(and as a totally ordinary lua table reference, replacing it or nilling it only does that to your reference, not to the original table which the java is using)
Thank you all of you for your patience and support
Man I wish I could do like a personal pin for myself in chats
Instead of for everyone
I learn so much stuff here
nono, it's fine! π
you can right click -> copy message link and keep a list somewhere
Dayum! Yeah I'll use my personal empty server for that
that's gold! Just learned another thing! π
Oh Albion btw, can I accidentally overwrite someones data by using the same key? Or is it specific to my mod?
you can, it's just a table, nothing fancy
you can add your own subtable if you're worried
like ```lua
modData.myModName = {}
modData.myModName.key = myValue
That's useful, thank you vm
Is all that data clientside? Do I have to ping pong it to server and back to another client to share with them?
of course you should check if your subtable already exists before creating it or you'll override it
it's usually clientside
Interesting
but there's an object:transmitModData() to send it to everyone else
Hmm. Does that return their mod data and you can store it in a function, global one, to let everyone access it or does it take an input for whom to send it to
Not really getting that part
it just sends it all to everyone when you call it
Ohhh I just reread it abobe
Above what you said
Since I asigned a local variable called modData to someone, I can use that variable again perhaps to get the same keys and data to show to someone else?
I'm known for complicating things so might be just me being a dumbass again π€£
i'm not really sure i understand the question
For example, you have
Player one has in their moddata their age
How would I access it and send that info for a 2nd player to obtain
Using transmit data
local player = getPlayer()
player:getModData().age = 25
player:transmitModData()
So in what variable does it store for another player to use?
Like, I did transmit data. Now I do another function where for example
Say:("the other player is " .. variable .. " years old")
in their moddata
:Say("the other player is" .. player:getModData().age .. " years old")
Yeah so I would still have to send their ID to the server and back to client, to obtain their player object right?
Since clientside I can't write player = getPlayerByID () without knowing their ID
if you can't see the other player to grab them in some other way, then the player object won't exist on the client and you won't be able to use its mod data
Aha, okay I think I got you now
i may be misremembering, but there might be a special case where player moddata doesn't even need to be transmitted...?
i think that was inventory items actually
my first mod is actually coming along so far 
twitch is such a pain the in the bottom some times...
does anyone happen to know how I can get the current wind speed in my serverside lua files? or where I should look in the docs for this kinda info
It's not a lot, but thx for helping me figure out how to get started y'all. Def. got some good first steps.
I think I can use _forecast:getWindPower() but I'm not entirely sure if I have to require/import anything specific for that
Do you not have access to ClimateManager ?
I'd imagine that's what's responsible for actually handling all the active climate stuff.
You should be able to use getClimateManager() to return the object. Store that to a local var and then use getWindPower() to return the float.
oh neat, I didn't realize that-- thank you! that's very useful
I didn't test it btw. Just going off what info the class docs have. π
this looks very useful, idk how I didn't find that javadoc before
do you happen to know what kind of scale getWindPower() is? I also see GetWindSpeedKph(), but I'm not sure what kind of values to expect in either of those functions
I'd bet that the float is between 0 and 1, and that getWindSpeedKph() converts it into a player readable format.
Just based on what I've experienced with PZ's server settings.
yea that would make sense, and a float from 0 to 1 would be nice to work with as power generation multiplier
Anyone happen to know of any superfunction the game uses to decide when your player cannot continue walking forward for any reason?
Might be a dumb question, but as I'm still learning, figured I'd ask..
With Lua, can you chain functions together? For example:
obj:func1()
obj:func2()
obj:func3()
Can that instead be written as:
obj:func1():funct2():func3()
sure, only if the function return class
Okie doke, thanks. 
local bc = RadioBroadCast.new("GEN-"..tostring(ZombRand(100000,999999)),-1,-1);
does anyone know what would happen if there was a collision in what I presume is meant to be a unique value here? the "GEN-"..tostring(ZombRand(100000,999999)) part, i mean
is there a way to store data persistent to a world, and not specific to a player? i searched this channel and i see a lot of people using player:getModData() but i think that is saved in reference to a specific player
oh perfect, thank you!
hello, i just wondering can someone make brita weapon pack skins.. and if so what must i do and i need to do so
Do you want to edit the textures of the weapons? I don't know exactly how Brita's mod is structured but there is might be a folder /media/textures/WorldItems in the mod's folder. This might contain the weapon skins as .png files. As a first try to edit them, you can just paint on these .png files with some image editor (for example GIMP but basic painting could in fact already be done with microsoft paint or something like that).
maybe an unanswerable question, but are these ids associated with recorded media something that's expected to change in new versions of the game? it appears like they're generated externally
i'm looking for a unique value associated with different recorded media so that i can reliably save it and load it again
they shouldn't change, else existing items would become invalidated (afaik)
ah okay, thank you
Ugh... got autowalking working only to realize that the way game does directional changes during Walk-to commands does not smoothly transfer when jogging / sprinting.
Also, how to trigger sprint during autowalk on gamepad is a mystery because the cancel function overwrites that button. 
π
And afaik the walk-to command isn't made to play nicely with directional changes, hence their decision to cancel-and-restart the action on each new click in ISWalkToCursor, so I don't think I can work around that too easily. Maybe I should just try to figure out how to send key & button presses instead. If that's even feasible.
yes basically i want to edit the texture and maybe respawn the particular weapon name and skin with the weapon name and skin name i know maybe that i need to make some proceduralspawn for the said weapon and skin for this to be work
and also want to make my mod is dependable to brita mod can i do that ?
how can I access map tiles? or if it's any easier, I want to be able to see the contents of containers in explored areas (boxes, mailboxes, etc.) is this doable?
I only can't figure out how to get the containers themselves, I can see how I'd read the items if I had a reference to them
local objects = getSquare(x, y, z):getObjects()
local container
for i = 0, objects:size() do
local obj = objects:get(i)
if obj:getContainer() then
container = obj:getContainer()
break
end
end
if container then
-- do things to the container
end
```something like this can work
you can grab the square by whatever other method you want, and technically a square can have multiple containers on it if you need to account for that
that looks like exactly what i need, thanks again
Is there a way to always walk to a specific side with walkadj? like if I always wanted to walk to the east side of a tile to interact with it?
why not just walk to the tile to the east?
is there a walkto instead of walkadj?
i'm pretty sure walkadj is just a proxy for the timed action
ISWalkToTimedAction:new(character, square)
objects:size() - 1
Don't go out of bounds.
thanks again to Alree, and big time to Commander, who's tile property cheat sheet was literally the only thing that helped me figure this out
https://steamcommunity.com/sharedfiles/filedetails/?id=2918886125
in your mod.info file, add the line
require=Brita
(afaik, "Brita" is the mod ID for Brita's Weapon pack; in any case, you have to put the mod ID after the "require=")
thank you sir
is there an event for when items are transferred to or from a container? or do I have to override some part of ISInventoryTransferAction
@ Timed Action
yeah, you probably didn't look at the mod I said...
AutoMoveTo by Tchernobill
@ running
if only there was a command like...
getPlayer():toggleForceRun()
and a command to set option to keep running after you start running
getCore():setToggleToRun(true)
so like
there's no way to force an item to be a specific tint or texture when it appears on a zombie, right?
this is what i was told but i'm just absolutely confirming before i complain about how silly it is lol
@fast galleon when find i sent you dm
Its abt the sandbox thing
hmmm
it cant be this easy π
player:getTraits():add("trait")
well now im kinda lost... never thought it would work at 1st try...
print ("------------------------- traits -------------------")
for i=0,TraitFactory.getTraits():size()-1 do
local trait = TraitFactory.getTraits():get(i);
table.insert(alltraits, trait)
end
print ("------------------------- traits -------------------")
for _,v in ipairs(alltraits) do
print(v:getLabel());
end```
can anyone tell me what im doing wrong since i get duplicate traits in the table?
LOG : General , 1673865832280> Unlucky
LOG : General , 1673865832280> Unwavering
LOG : General , 1673865832280> Vagabond
LOG : General , 1673865832280> Very Underweight
LOG : General , 1673865832280> Wakeful
LOG : General , 1673865832280> Wakeful
LOG : General , 1673865832280> Weak
LOG : General , 1673865832280> Weak Stomach
LOG : General , 1673865832280> Weak Stomach
LOG : General , 1673865832280> Well-Fitted
You cant get traits that are mutual
Like you can get unlucky and lucky at the same time
Thats causing the error
@pulsar heath
local alltraits = {}
local writer = getFileWriter("alltraits.txt", true, false)
print ("------------------------- traits -------------------")
for i=0,TraitFactory.getTraits():size()-1 do
local trait = TraitFactory.getTraits():get(i);
table.insert(alltraits, trait)
end
print ("------------------------- traits -------------------")
for i,v in ipairs(alltraits) do
local trait = TraitFactory.getTrait(v:getLabel())
print (v:getType())
writer:writeln("Label: " .. v:getLabel() .. "Type: " .. v:getType())
end
writer:close()
easier printing the type ( internal name )
and using that instead of the label
less margin for errors i think
and now i see why some appear 2 times
in the file generated i have
Label: Baseball PlayerType: BaseballPlayer
Label: Baseball PlayerType: BaseballPlayer2
hmmm... now to figure out whats the difference between the 2...
its working i think, but i really need to figure out why some traits have the same label for 2 types
idont understand what that means
Label: Thick Skinned Type: ThickSkinned
Label: Thick Skinned Type: ThickSkinned2
Label: Thin-skinned Type: Thinskinned
Label: Thin-skinned Type: Thinskinned2
you get the internal name of the trait with getType() right?
and the label with getLabel()
thats the result when i iterate the whole table of traits in traitfactory
some trait labels are the same for two differnt trait types
ill figure something out later... now i need to get the duration of a game day from the settings
looks like you got the profession framework installed there. traits with the '2' suffex are 'profession' versions of normal traits. costless profession only (unselectable). same label
ahhhh, it is installed but not enabled
Label: Thick Skinned Type: ThickSkinned2 looks like it is
damn it it is... i thought i had turned it off b4 starting a new save for testing
@quasi geode thanks for helping me out
anyone can tell me how to get the day length from the settings?
never worked with the game settings... time to do some more reading i guess
zombie.sandboxoptions is for all saves including the default modes right?
im guessing even the default modes are a sandbox ( preconfigured )
pretty much. they're just presets. getSandboxOptions():getDayLengthMinutes()
yeah as i thought, thanks once again
ok, now just need to update the app, and change the json string and all done... never thought this would be done in a morning... now to the car events...
yoyo whatcha doing
ye thats a simple add and remove
after add launch event
that will tickdown
save moddata on how much is left to tickdown
in case of player leaving and reconnecting
thats very pro like π
if when reconnecting timeleft is above 0 then add event that ticksdown
but no need for that much, its part of the integration mod
ah
so i just need a timer function or something like that
no need to persist on disconnect
i mean
if you add trait and they disconnect
your timer wont be there next time they reconnect
yeah i know
so they'll keep trait perma

and nobody wants to keep that
and now you killed my last brain cell
gimme 2 min
what do i do if my game broke.. i cant connect to anything with debug on but if its off its able to connect
this is both no steam and steam
and i have verified alot of times already
@pulsar heath Can't you just reset traits every time to original one every time a player connect ?
@golden sparrow never tried to clear
i've thought about it but doesnt it clear all the traits?!
No idea how the trait framework works but I guess you could have them registered in GlobalModData or something
function TraitCheck()
if modData.traitAbcTimeLeft > 0 then
modData.traitAbcTimeLeft = modData.traitAbcTimeLeft - 10;
if modData.traitAbcTimeLeft < 0 then
player:getTraits():remove("abc");
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_abc"), true, HaloTextHelper.getColorGreen())
modData.traitAbcTimeLeft = 0;
end
end
if modData.traitXyzTimeLeft > 0 then
modData.traitXyzTimeLeft = modData.traitXyzTimeLeft - 10;
if modData.traitXyzTimeLeft < 0 then
player:getTraits():remove("abc");
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_abc"), true, HaloTextHelper.getColorGreen())
modData.traitXyzTimeLeft = 0;
end
end
if modData.traitAbcTimeLeft == 0 and modData.traitXyzTimeLeft == 0 then Events.EveryTenMinutes.Remove(TraitCheck) end;
end
function addNegativeTrait()
if not player:HasTrait("abc") then
player:getTraits():add("abc");
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_abc"), false, HaloTextHelper.getColorRed())
modData.traitAbcTimeLeft = 69;
Events.EveryTenMinutes.Remove(TraitCheck);
Events.EveryTenMinutes.Add(TraitCheck);
end
end
function initializeNegativeTwitchTraits()
if modData.traitAbcTimeLeft > 0 or modData.traitXyzTimeLeft > 0
Events.EveryTenMinutes.Remove(TraitCheck);
Events.EveryTenMinutes.Add(TraitCheck);
end
end
Events.OnCreatePlayer.Add(initializeNegativeTwitchTraits);```
@pulsar heath
damn you are the man
in HaloTextHelper.addTextWithArrow(player, getText("UI_trait_abc"), true, HaloTextHelper.getColorRed()) true or false indicates where arrow points
false - down, true - up
so when obtaining negative you wanna do red arrow up
positive green up
and so on
the timeleft is counted in minutes? or seconds?
TraitCheck should remove itself once timer is done no ?
the list of ppl i have to give credits to in the mod will be longer than the mod code π
there, fixed
problem that you have to do that if stuff foe every trait since u want to keep count on how much time for each trait left
u could make a table
yeah... i actually thought about doing it externaly so that i can manage it easier
since i already have a app working as middleman for the game and twitch
was thinking maybe, do the timers in the app
and simplify the code in the mod
just need to make a few changes to the json string the mod reads created by the app
but your aproach is more professional
and less dr frankenstein, plus im learning more and more stuff from the help i get here
and learning is always good π
instead of making a bunch of ifs in function TraitCheck() you can have table
yea
hmmm game time is a float right?
Why is my debug broken
π
lemme sse how i track time
since if one day ingame is 60 m, 5 m wuold be 0.083 hours in game? or around that value i think
@ancient grail youre not the only one with that problem... so i dont use -debug π
cheat menu lua interpreter for code testing
and when its server related, i have my own dedicated server
do u want to track IRL time or in-game time?
just because i cant solve the debug problem
well if i track ingame time i have to convert it to realworld time
unless there is a way to track realworld time in game
no clue about IRL
anyway, 5m would be around 0.083 hours in game time
just need to make a function to convert it based on the day lenght in the settings
but as for tracking how long something would last you can literally just make a timestamp in modData and then increase it every minute
doesnt seem that hard
by timestamp i dont mean actual time i mean literally an integer number
that you increase every minute
so basicly a counter
What if the debug is broken for all of us
ye
if counter = x then remove the trait
How the fuq do i mod without debug?! Amazing you are able to do that @pulsar heath
Thats impossible for me
wdym without debug
in my case i use the batch to launch the game and the realtime log in a cmd box
#mod_development message @dull moss
But youd dont have the commands
Like type and enter
hold on
When did yours broke
mine broke with the last update
dunno, been away for like 9 months
when i got back the game updated to the current version
and debug just doesnt work for me
either crashes the game
Fair enough
or when it runs cant connect to nothing or nobody can connect to the host i create with -debug
so i just gave up after verifying files a bunch of time
redownloading the game
running it without any mods
trying with nosteam
whatever ppl suggested i tried... still broken so i found an alternative
Yeah but the alternative you use is just like a tail
Its not really something u can use to send lua console commands
That will work right
yes you do
oops
wrong reply
yes you do
why do you think i was pestering you about traits?
do you run dynamic submod?
π
Im confused
havent tried it yet tbh
Tell him yes otherwise he might ignore you hehe

the dynamic submod
its on the server
unfriended blocked reported
Haha
but not on my sp saves

my last sp save is from november last year
Wrong answer β
sir we're in 2023
i know

i managed to not have time to play pz from 2021 nov till around 3 months ago
havent updated any of the mods i use, since i've been busy with mine π
He knows
im just trolling cuz idk ehat to do with my life
How do i mod without debug? Tell me
But ye, if you like submod try our fresh, brand-new cola drink, only 0.99 cents per bottle, try Evolving Traits World, it makes base game perks dynamic and stuff, and much more interesting to get than just get X levels. Well, some of them, at least
@ancient grail i havent found anything i couldnt do with this interpreter mod
throw me something you wanna do and ill test it
No 
Whats interpreter mod
Linksies
Ok ill check it
and it was either using the chead mod lua interpreter or, loading... error... main menu... editing code, loading... error... main meniu
No dice. Tried those while autowalk is active. May work in KBM mode but definitely does not respond in gamepad mode so I still need to find a workaround for that.
Also, the mod you mentioned does not support changing directions with the movement controls while automoving. It just lets you tap into vanilla MoveTo... Click to choose a new destination.
this way i just type in the code i wanna try
and get the results without needing to reload the save everytime i mess things ups ( and i do mess things up a lot π )
its not perfect, but its better than nothing
Theres alot of cheat menu which 1
hold on, ill just zip the one i use
Sure
if shows in red in the mod list but it still works
dang it forgot my coffe... brb
forgot the https ... but the browsers are smart...
So i was curious about how much time i need to spend on doing something to get/remove traits with help of dynamic traits.
player:getModData().DTagoraClaustroCounter = player:getModData().DTagoraClaustroCounter + 1;
elseif not player:isOutside() and player:HasTrait("Claustophobic") then
player:getModData().DTagoraClaustroCounter = player:getModData().DTagoraClaustroCounter + 1;
Do you guys know how often this +1 is being added or would i need to bring more functions from this lua?
I thought that this +1 is being added either every tick or every second
but i'm not sure
@dull moss this one is for you
Those commands work as expected under two conditions: the destination is not changing, and you are playing with KBM. Neither of those conditions can be guaranteed by the mechanism I am trying to create.
but didnt you got it working yesterday?
and the issue you had was to change direction?
Global variables still know what the value was even after server restart?
its the same as running the code from a lua file inside the mod folder
so anything you can do in the mod
you can do on that interpreter
Have you zipped it?
yup
rar'ed it
π
so @dull moss
if not player:HasTrait("abc") then
player:getTraits():add("abc");
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_abc"), false, HaloTextHelper.getColorRed())
modData.traitTimers["abc"] = 69;
Events.EveryTenMinutes.Remove(TraitCheck);
Events.EveryTenMinutes.Add(TraitCheck);
end
end
and
for traitName, timeLeft in pairs(modData.traitTimers) do
timeLeft = timeLeft - 10;
if timeLeft <= 0 then
player:getTraits():remove(traitName);
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_"..traitName), true, HaloTextHelper.getColorGreen())
modData.traitTimers[traitName] = nil;
else
modData.traitTimers[traitName] = timeLeft
end
end
if next(modData.traitTimers) == nil then
Events.EveryTenMinutes.Remove(TraitCheck)
end
end
something like this?!
I did get it working... for walking
I didn't know Project Zomboid also uses Lua
Not for jogging or running
and this
if modData.traitAbcTimeLeft > 0 or modData.traitXyzTimeLeft > 0
Events.EveryTenMinutes.Remove(TraitCheck);
Events.EveryTenMinutes.Add(TraitCheck);
end
end
oh my bad
Jogging and running have two issues re. the auto-move system:
First, they have to be manually activated after choosing destination
Second, they don't work while gamepad active.
You cannot toggle jog / run either by console command (getPlayer():toggleForceRun(), getCore():setToggleToRun(true)) or by button while automoving on gamepad
maybe check the code from superb survivor or something and see if theres anything there that can help you?
it has to use something for the pathing of the npcs it creates right?
I bet it just uses MoveTo
If you are moving an NPC, you have no need to continuously update its destination mid-movement.
Same as AutoMoveTo... if you are clicking around, you have no need to continuously update destinations based on player walking states.
Also, the run function can be started automatically for KBM click-to-movers.
and i thought i chose something difficult to do...
function addNegativeTrait()
if not player:HasTrait("abc") then
player:getTraits():add("abc");
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_abc"), false, HaloTextHelper.getColorRed())
modData.traitTimers["abc"] = 69;
Events.EveryTenMinutes.Remove(TraitCheck);
Events.EveryTenMinutes.Add(TraitCheck);
end
end
function TraitCheck()
for traitName, timeLeft in pairs(modData.traitTimers) do
timeLeft = timeLeft - 10;
if timeLeft <= 0 then
player:getTraits():remove(traitName);
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_"..traitName), true, HaloTextHelper.getColorGreen())
modData.traitTimers[traitName] = nil;
else
modData.traitTimers[traitName] = timeLeft
end
end
if next(modData.traitTimers) == nil then
Events.EveryTenMinutes.Remove(TraitCheck)
end
end
function initializeNegativeTwitchTraits()
if modData.traitAbcTimeLeft > 0 or modData.traitXyzTimeLeft > 0 then
Events.EveryTenMinutes.Remove(TraitCheck);
Events.EveryTenMinutes.Add(TraitCheck);
end
end```
I honestly might not be able to do it at all. If the code that decides to stop me from running with gamepad during moveto is Javaside, it's game over.
My mod has very little purpose for KBM people... they can already just click around, which is pretty easy.
I mean autowalking is okay
But feels a little bit depressing to publish Autowalk for controller
because controller players just can't have nice things lol
At this point I'm just lost, I always use this mod and change directions without any issues and still keep running without any issues, just by pressing F1.
You might be run about start try to run, I used that command on a key press.
Because the running functions work differently on KBM π¦
π
but you do have walk to with a controller right?
No lmao
They disable it
I could enable that
But it's not very useful
I mean perhaps the move-to using the map would be useful with gamepad
I could consider that
but still
Not the desired goal at all π¦
I used the forced run while already in a walk to function if that helps.
I assumed and tested that way, but thanks. π¦
With no gamepad connected, it works
you could do a simple one, using walk to or a similiar method and add some checking to if the player presses the dpad or whatever ( never played pz with a controller )
With gamepad connected, borkery.
if its left dpad turn left update the walk to to a point a few cells ahead or whatever it is
like... make a loop with a pre set distance
and listen for controller inputs
if its left turn left for the amount of time the pad was pressed and update the walk to point
if its down dpad cancel the move to
simple stuff like that
dunno...
I actually do set the target a few cells of whatever I am and listen for controller inputs... the problem is if you don't change direction, you quickly reach a point where you need to pick a new destination.
Also, this doesn't change that I cannot run during the automove on gamepad, which is a more significant issue
only if you reach the point set to move
so check the distance left for that point
and when its almost there add some more distance
until canceled
You cannot
You have to create a new destination
@ this
You can't do that.
?
so you cant create a loop that checks if youre reaching the destination set, and if you are set another destination x distance ahead?
and inside that loop listen for controller inputs?!
Did you see the straf action, which moves the player in a circle in combat stance?
i've seen the walk to make the char stop and start running again whenever i set a new walk to point in the middle of the current one
so that is a problem
I can. I do this actually.
But it doesn't let you ADD to your current destination
You literally have to stop the action and replace it with a new one
You have to literally start a command to reach a new dest
In vanilla, the way automove works is this... on click, it does this:
ISTimedActionQueue.clear(player)
ISWalkToAction.new(player, location)
Every time you click during WalkTo, game does that.
Changing the path of the action is not a thing afaik.
you create a new path when you need one, or you continue on the old one
No I didn't look at that
I see commands for isStrafing but none for setting it... not sure how game handles strafing tbh.
It's in the mod
This mod has some kind of combat strafing? https://steamcommunity.com/sharedfiles/filedetails/?id=2591232239
@fast galleon I see... not helpful but thanks for trying. He picks 4 points in a circle on the player's position and just uses walkto behavior
I'm sure that function ultimately calls the function I'm using.
Actually no
That function just gives you access to Walkto
It activates the cursor
It doesn't fire the actual walking
trying to find the actual fucntion that handles the walking
Your click during that state fires the walking
It's here:
function ISWalkToCursor:create(x, y, z, north, sprite)
local square = getWorld():getCell():getGridSquare(x, y, z)
ISTimedActionQueue.clear(self.character)
ISTimedActionQueue.add(ISWalkToTimedAction:new(self.character, square))
end
and not a timed action
It's in a building action*
ISWalkToCursor = ISBuildingObject:derive("ISWalkToCursor")
ill try to explain what im thinking
When you click to "build", it "creates" the path
thats a timed action, but im trying to get ( in the source code )
to the actual function that the timed action executes
to see if it can be used oustide of the timed action
if its exposed or not
because if you use a timed action you cant change the values for the action itself since the action if bein' performed i guess
but, if its a non timed action you can kinda work around it...
I'll just share my code for whoever wants to give this more precise thought:
Automove = {}
Automove.lead = 3
Automove.paused = {}
Automove.next = function(player)
local location = player:getSquare()
local direction = player:getForwardDirection()
local target = Location.new(
player:getX() + Automove.lead * direction:getX(),
player:getY() + Automove.lead * direction:getY(),
player:getZ()
)
local destination = getSquare(target:getX(), target:getY(), target:getZ())
if not Automove.blocked(location, destination) then
return target
end
end
Automove.blocked = function(location, destination)
return location:isSomethingTo(destination) or location:isBlockedTo(destination) or location:isWallTo(destination) or
location:isWindowTo(destination) or location:isWindowBlockedTo(destination) or location:isDoorTo(destination)
end
Automove.begin = function(player)
if not player then player = getPlayer() end
if not player:isAlive() then return end
local move = AutomoveAction:new(player)
move.autoMovement = true
move.disableProgressBar = true
ISTimedActionQueue.add(move)
end
Automove.beginAgain = function()
local nobodyWaiting = true
for playerIndex = 0, getNumActivePlayers() - 1 do repeat
local player = getSpecificPlayer(playerIndex)
if not (player and player:isAlive() and Automove.paused[player]) then break end
nobodyWaiting = false
if not player:pressedMovement(false) then
Automove.paused[player] = nil
Automove.begin(player)
end
until true end
if nobodyWaiting then
Events.OnTick.Remove(Automove.beginAgain)
end
end
Automove.manhattan = function(location, destination)
local xDiff = math.abs(location:getX() - destination:getX())
local yDiff = math.abs(location:getY() - destination:getY())
local zDiff = math.abs(location:getZ() - destination:getZ())
return xDiff + yDiff + zDiff
end
-- Automove Action
AutomoveAction = ISBaseTimedAction:derive("AutomoveAction");
function AutomoveAction:isValid()
if self.player:getVehicle() then return false end
return getGameSpeed() <= 2;
end
function AutomoveAction:update()
if (self.player:pressedCancelAction()) then
self:forceStop()
return
end
local location = Location.new(self.player:getX(), self.player:getY(), self.player:getZ())
if Automove.manhattan(location, self.origin) > 0.75 then
ISTimedActionQueue.clear(self.player)
Automove.begin(self.player)
return
end
self.result = self.player:getPathFindBehavior2():update();
if self.result == BehaviorResult.Failed or self.result == BehaviorResult.Succeeded or
self.player:pressedMovement(false) then
self:sleep()
return
end
end
function AutomoveAction:sleep()
self:forceStop()
Automove.paused[self.player] = true
Events.OnTick.Add(Automove.beginAgain)
end
function AutomoveAction:start()
self.goal = Automove.next(self.player)
if self.goal then
self.player:getPathFindBehavior2():pathToLocation(self.goal:getX(), self.goal:getY(), self.goal:getZ())
end
if self.disableProgressBar then self.action:setUseProgressBar(false) end
end
function AutomoveAction:hold()
--print ("AutomoveAction: Pathfind cancelled.")
self.player:getPathFindBehavior2():cancel()
self.player:setPath2(nil);
end
function AutomoveAction:stop()
--print ("AutomoveAction: Pathfind cancelled.")
ISBaseTimedAction.stop(self);
self.player:getPathFindBehavior2():cancel()
self.player:setPath2(nil);
end
function AutomoveAction:perform()
--print ("AutomoveAction: Pathfind complete.")
self.player:getPathFindBehavior2():cancel()
self.player:setPath2(nil);
ISBaseTimedAction.perform(self);
if self.onCompleteFunc then
local args = self.onCompleteArgs
self.onCompleteFunc(args[1], args[2], args[3], args[4])
end
end
function AutomoveAction:setOnComplete(func, arg1, arg2, arg3, arg4)
self.onCompleteFunc = func
self.onCompleteArgs = { arg1, arg2, arg3, arg4 }
end
function AutomoveAction:new(player)
local o = {}
setmetatable(o, self)
self.__index = self
o.player = player
o.character = player
o.stopOnWalk = false
o.stopOnRun = false
o.maxTime = -1
o.pathIndex = 0
o.goal = player:getSquare()
o.origin = Location.new(player:getX(), player:getY(), player:getZ())
return o
end
Here is where I currently pick a new path periodically to allow player to walk "forever" (until the pathfinder fails basically)
if Automove.manhattan(location, self.origin) > 0.75 then
ISTimedActionQueue.clear(self.player)
Automove.begin(self.player)
return
end
I restart the process every time I get far enough from the origin so that it always keeps finding a new path instead of coming to a stop, if possible.
I could probably make it autorun for KBM but I am salty about not knowing how to do it for gamepad
(the true primary use case)
.... never used a controller... isnt the keyboard available as well even if using a controller?
no
They lock keyboard input
And certain things do not work in the KBM way while joypad is active
This is one
Presumably because they thought nobody with joypad would use MoveTo
(And we wouldn't, tbh)
But we might want to hack into it for our own purposes dag nabbit
isnt there a similar fucntion with the controller?
Hahaha bruh I couldn't even hide my UI when I started this game on controller
So, no
Lots of similar things missing in controller support
the weird thing is... my old version of the mod used keypresses
(I added the UI one)
to trigger events
and a few of the streamers that used it played on a controller
and it still worked
so thats confusing to me
if the keyboard is locked it shouldnt get the keypress sent
It's possible they bound keyboard keys using Steam
If the mod has no gamepad shortcuts
Oh
Umm
never even thought about it
Yeah I dunno
I'd recommend using ETW instead of DT

i just send virtual keypresses
Well when I press WASD while gamepad connected, I do not walk around
neither did they
So SOME keys at least are disabled.
but when pressing the keys assigned to the mod to trigger events on the keyboard they did nothing
sending the keypress using touch portal
they would trigger the events
so im confused
think so, you'll have to check how table works, i like messing them up
Okay actually some KB stuff is not disabled I was mistaken
It just disables certain movement related things, some options in the context menu
Can anyone give me an example on how to remove certain items from the game or to block them from spawning (both in containers and on zombies) ?
But it does prevent running toggle using that function
And that function goes to Java so I don't think I can fix it
@dull moss i ended up with this code, but just changed it in notepad++ havent tested it yet so it will prolly error out the first time i try but its a start
function addNegativeTrait(trait)
if not player:HasTrait(trait) then
player:getTraits():add(trait);
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_abc"), false, HaloTextHelper.getColorRed())
modData.traitTimers["abc"] = 69;
Events.EveryTenMinutes.Remove(TraitCheck);
Events.EveryTenMinutes.Add(TraitCheck);
end
end
function TraitCheck()
for traitName, timeLeft in pairs(modData.traitTimers) do
timeLeft = timeLeft - 10;
if timeLeft <= 0 then
player:getTraits():remove(traitName);
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_"..traitName), true, HaloTextHelper.getColorGreen())
modData.traitTimers[traitName] = nil;
else
modData.traitTimers[traitName] = timeLeft
end
end
if next(modData.traitTimers) == nil then
Events.EveryTenMinutes.Remove(TraitCheck)
end
end
function initializeNegativeTwitchTraits()
if modData.traitAbcTimeLeft > 0 or modData.traitXyzTimeLeft > 0 then
Events.EveryTenMinutes.Remove(TraitCheck);
Events.EveryTenMinutes.Add(TraitCheck);
end
end```
so thats why my mod worked π
'cause i had no support for controller in the mod never even thought about it
They probably did this: Use contextual menu option "Move To Here" on map
thanks but i don't want to
That would be available to gamepad people presumably @pulsar heath
And it would "work" in that they could walk places automatically
But a gamepad user would have no way of running
doesnt it allow to alter the walk state like in the keyboard walk to?
No
Lmao
It blocks it
The exact same commands that work for KBM
are blocked during joypad play
I have tried sending them via debug during automovement
I can trigger run during automove in KBM just fine.
Using commands
hold on... it has to be a wway to change the walk state in the controller
that would just make action invalid? 
-1 means it doesnt have a pre set time to end
then use mod without documentation 
many timed actions are -1
that means the action takes as long as the animation or something like that
or until it runs the full code of the cycle... dunno just guessing
Vanilla for comparison @fast galleon :
--
function ISWalkToTimedAction:new (character, location, additionalTest, additionalContext)
local o = {}
setmetatable(o, self)
self.__index = self
o.character = character;
o.stopOnWalk = false;
o.stopOnRun = false;
o.maxTime = -1;
o.location = location;
o.pathIndex = 0;
o.additionalTest = additionalTest;
o.additionalContext = additionalContext;
return o
end
I see, I've done negative but not -1 and they cancelled.
I see, must be hardcoded.
well i need a break and to take care of lunch... almost 14h
The only way the move action ends is by reaching a success or failure state @pulsar heath
No timing at all tmk
sucess by reaching the destination or failure by canceling or no path ?
Right
im still thinking that it should be possible to change the destination of the action created
If you can find a way to change the path dest without resetting the path, β€οΈ
ill mess around with that after lunch
there has to be way...
in the worse case scenario ill end up pulling my hair out
but ill give it a try, not that i know more than you about this subject ( know a lot less ) but youll never know... stupid ppl can do smart things by chance π
I can dip out of the TimedAction just fine, but when I return to it, it continues trying to get to its last unreached path.
So e.g. autowalking left, I would take manual control, walk right, and then let go of manual control, and it would automatically start autowalking left again.
presumably because the old path was still stored
And it wanted to get there
it would go back to the original pre set destination
I know, and I was changing the destination and it was ignoring the new one.
hmm
Using self.character:getPathFindBehavior2():pathToLocation(self.location:getX(), self.location:getY(), self.location:getZ());
(That's the vanilla version)
But pathToLocation determines where you go afaik
update moves you along that path
what if just for testing purposes
when you set a destination that creates a timed action correct?
ok but there is a timed action that's created
The destination setting and update behavior seems to be accessible outside of timed actions, but I'm not sure how well it works outside of them. Couldn't get it to fire correctly.
and that timed action has the destination path etc in it right?
if theres info stored, it can be changed
have you tried canceling the timed action containing the destination etc
and creating a new one
inside a loop and see how it behaves?
man im starving... be back in a few
You did this server or client side ?
Client
But the initial setting of the destination was also client, and works using an identical command... Also, the command I use to repath works when I cancel the old path as vanilla does.
So I'm not inclined to suspect that being client is the issue.
Sure, but in Java there is such a thing as protected and private. So, yeah, stuff can be changed, but the among of hackery required to change it is the question
I want to release this as a Lua mod for ease of end use
I mean, that's what my code above essentially does. Just a slow loop of doing that.
On Javaside they call stuff like player:MoveUnmodded(player:getForwardDirection()), but that doesn't work Lua side π¦
What kind of data does a client get from server before they create character / during character creation.
does anyone know where I can find the files related to zombie clothes ?
to edit spawn chances
clothing.xml
?
found it, thanks
editing the probability should be enough right ?
Does adding an UpdateLocation function to ISWalkToTimeAction not work?
self.character:getPathFindBehavior2():pathToLocation(x, y, z);
end```
And then storing the WalkTo action you create somewhere to update as needed
I haven't tried wrapping self.character:getPathFindBehavior2():pathToLocation(x, y, z); in an "UpdateLocation" function, but I have tried that in my update function to no avail.
are you sure your update triggers?
Yes
I need help:
How do I make this work
local ducttape = player:getInventory:AddItem("Base.DuctTape");
ducttape:setUseDelta(0.5);
I want to spawn a drainable item with half or quarter of its delta used. Where am I making a mistake ?
dang, this really works for me 
It is used to cancel the action when pressing buttons, running into walls, finding an unreachable path, etc.
So I know it works
Because it does all those things
ALso
I use update presently to build the new path
And that works.
setUseDelta - How much is used each time Use() is called
setUsedDelta - How much has been used up <--- You want this one
Thanks.. I'll try it out rn β€οΈ
I'm gonna try setData again, maybe I used it wrong last time.
When you create a custom UI, determine the X and Y coordinates where it appears... what does that actually mean? Like, the axis. Does it mean where the middle of the UI will be, where the bottom right corner will start rendering and all the others from there or something else?
I'm having difficulties adding for example a combo box in the middle of the UI. I asign them the same X,Y values yet there's on 2 completely different ends of the screen
Top left
parent is for screen, children for parent. Top left, yeah.
That's odd, wonder why it gets set so far away then
the combo box x, y must be relative to the panel's x, y
Not matching
hmm, relative as in x - 50 for example?
So if you want combo box in top-left corner of a panel at 400, 400, set combo's x, y to 0, 0
oh shit
That's what Poltergeist tried to tell you btw, more concisely.
That means because it's relative, it sets the X Y of the main panel and then from the main panel, additional X Y what I was doing
That's why it was appearing so much to the right lmfao
Indeed
Tried using setData, no dice.
if Automove.manhattan(location, self.origin) > 0.75 then
-- ISTimedActionQueue.clear(self.player)
-- Automove.begin(self.player)
self.goal = Automove.next(self.player)
if self.goal then self.player:getPathFindBehavior2():setData(self.goal:getX(), self.goal:getY(), self.goal:getZ()) end
return
end
At that point in my loop, the commented code makes me continue walking forward (as long as possible.... the uncommented replacement causes me to stop as soon as I call setData on the new position.
Ow about this. If you set 1 of em it will auto set the other one?
all = {
bin = {
rolls = 4,
items = {
"BandageDirty", 1,
so in theory, if I change the bandage value from 1 to 0 and upload this as a mod, the edited item should not spawn right ?
thanks
Not via that item location category at least
If there is an all category I'm guessing it's a small chance of finding that anywhere, but there may be other places where you have alternate chances that might also need to be 0'd
e.g. in a medical cabinet
no I took the whole file, edit it in its entirety and upload that as a mod
well I am only removing some things
Is that ProceduralDistributions?
distributions and ProceduralDistributions
and clothing.xml as well, I changed the probability of any clothing to 0
I see. Well that may not work as expected if you just duplicate the Distributions file
Issue is this:
Distributions = Distributions or {};
this:
local distributionTable = {
and this:
table.insert(Distributions, 1, distributionTable);
So what's going on here is you have a global table and you're adding a local subtable to it
So if you remade this entire file as a mod and ran it again
It would not overwrite Distributions (which is honestly good compatibility-wise because you would probably break other people's modded items), and so Distributions would still contain distributionTable as its first element.
Wait
No it wouldn't
You would insert your own distributionTable as the first element
The original would be second element
No idea if that would cause exceptions
But it would likely cause mod incompatibility
If it's same name/path, the original won't run though.
Oh okay
I see, I dont run a whole lotta mods though
yeah it is
Is your mod purely for personal use?
yup
Fair enough... Well, if you want to change all in Distributions.lua, I BELIEVE you might consider trying it this way for mod compatibility:
Distributions[1].all.bin.items[2] = 0
That would of course be hardcoded
You could also use Distributions[1].all.bin.items to get the index of BandageDirty and then change the index right after BandageDirty
That is what needs to be done... the index after BandageDirty needs its value changed.
@drifting ore
Also, this is more efficient than replacing the entire table... haha.
But if it's for personal use, your call how compatible you want it to be
local dirtyBandageProbabilityIndex = 0
for index = 1, #Distributions[1].all.bin.items do
if Distributions[1].all.bin.items[index] == "BandageDirty" then
dirtyBandageProbabilityIndex = index + 1
break
end
end
if dirtyBandageProbabilityIndex > 0 then
Distributions[1].all.bin.items[dirtyBandageProbabilityIndex] = 0
end
@drifting ore
(renamed target to dirtyBandageProbabilityIndex for clarity)
I believe that would do it.
Haven't tested
Wait, I thought mods always load after vanilla? Does vanilla look for mods that redefine its base files before loading its base files?
it runs a check of everything and prints mod a overwrites file b
Oh cool
then it starts loading
Well crap.
If I would've known that I would've released one of my bugfixes as a vanilla file overwrite lol
Instead of wasting people's time double-loading.
if somebody overwrites a vanilla file, it's not guaranteed to be loaded
when a mod needs it
Understood
So I will not go back and adjust my habits then lmao
"Hey guys, I have this great new update that should beak all of the mods alphabetized before M, have fun!"
Might need help with one more function:
function OnCreate_Example(items, result, player)
for items:get(i):getType() == "FilledBaggie" then
if items:get(i):getUsedDelta() == 1/0.75/0.5 then
result:setUsedDelta(items:get(i):getUsedDelta()-0.25);
elseif items:get(i):getUsedDelta() == 0.25 then
?????result:Remove?????;
player:getInventory():AddItem("EmptyBaggie"); --here I'd like to remove the result and spawn an "EmptyBaggie" item insted, so is there a replace function or whatever.. can you help me?
I'd like to remove the result entirely.. setting its usedDelta to 0 doesn't replace it as it should with an EmptyBaggie but leaves it with 0 and it can be used again as if it had 0.25 and not 0..
Or to make this question simpler.. how do I make a recipe that gives no result
They have different uses so the other is not called when one is set.
setUseDelta sets how much will be drained whenever Use is called on the item. Essentially its deciding your Max Amount of Uses for a drainable.
setUsedDelta is how you directly control how much is left without calling Use().
So say you have a Drainable with a UseDelta of 0.2.
The Item has 5 uses at max.
If you call setUseDelta(0.1), that item now has 10 uses at max.
If you have an item with a UseDelta of 0.2 and a UsedDelta at 0, you will see 5/5 uses remaining on the item.
If you set UsedDelta to 0.66, you will have ceiling(UsedDelta/UseDelta) uses remaining, i.e. 0.66/0.2 = 3.3 which rounds up to 4 uses.
If your item has a UseDelta of 0.25, you just need to call result:Use().
If your item is at 0.25 or less, the game will handle deleting the item from their inventory.
So easy.. again..
Thanks π
Just in case result script need the next line
ReplaceOnDeplete: EmptyBaggie,
Wait, what is this recipe doing?
Both the input and result are FilledBaggies?
If you are just using up a bit of the filled bagge, you don't need this OnCreate at all.
Having
{
FilledBagge=1,
result: Something,
}```
and having the ReplaceOnDeplete like Polt said will handle giving an empty baggie when its depleted without custom recipe code
As the '1' in this instance in recipes is just a Use, not the whole item.
Well I made that recipe to avoid food consumption functions of vanilla, so I can modify the amount of used contents and use custom animations with AnimNode variables.
So I made it a recipe to snort cocaine.
If I set a normal recipe with ReplaceonUse and then Result: , (leaving an empty space) I get EXACTLY what I want but it shows a red error box every time because of a missing result.
So in order to avoid error box appearing, I put in a Result:Cocaine (which is the same item used in the recipe) and then used a OnCreate to remove the crafting item and adjust the results usedDelta. Complicated Ik.. but I didn't know how to leave a Result: blank and not get Errors
So that is why I'm asking.. is it possible to not get any result and go through with it without getting error pop-ups
Ah, in that case set the result as your FilledBaggie but add this line to the recipe, RemoveResultItem:true,
Didn't know that existed.. RemoveResultItem..
Thanks a lot
Is there a full list of usable functions for recipes and items (such as OnCreate, RemoveResultItem, AnimNode, NeedtoBeLearn, Sound, Time, CanbeDoneFromFloor etc. etc.)? Where could I find the list to help me with future modding?
just wanted to ask, whats the difference between isDebug() and isDebugEnabled()? They seem to me to do the same thing
@LuaMethod( name = "isDebugEnabled", global = true )
public static boolean isDebugEnabled() { return Core.bDebug; }
``````java
@LuaMethod( name = "getDebug", global = true )
public static boolean getDebug() { return Core.bDebug || GameServer.bServer && GameServer.bDebug; }
Thank you for this, although since I do not know any coding it does feel easier to just edit the entire file even if it takes a while
so isDebugEnabled() just returns wherether the client has Debug on and getDebug returns that or if the server has Debug enabled
thats what i understand under Core.bDebug
yes
is isDebug the same as getDebug? I dont seem to see that command written anywhere but maybe im blind aswell
isDebug is for javastuff afaik, where do you see it being used?
Yes my debug is back its just cu of a flaw with my code
thought it was like isclient
for the name logic... everytime i get isSOMETHING is a boolean
the opposite or paired function to isClient is isServer
i know just giving and example... everything isXXXX that ive found so far is usually a boolean
and... why i thought it was a boolean
I don't think isDebug is even exposed though - so where did you see it getting used?
i didnt, he did
i think im just being schizo i cant find it anywhere aswell
local isDebug = getDebug()
inside my mod, how did you find it
by the end of the month ill be saving a few β¬ thanks to zomboid modding...
perhaps they had to give it another name due to isDebug being a thing in java
no need to cut my hair... will be bald
due to pulling my hair out
trying to figure some stuff out π
also unrelated to this: does TIS have a stance on moded java files which you wrote yourself?
there's a ToS that's been updated recently
hmmm but i think i got it... just need to ajust the timer bit
function addNegativeTrait(trait)
if not player:HasTrait(trait) then
player:getTraits():add(trait);
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_abc"), false, HaloTextHelper.getColorRed())
modData.traitTimers[trait] = 69;
Events.EveryTenMinutes.Remove(TraitCheck);
Events.EveryTenMinutes.Add(TraitCheck);
end
end
function TraitCheck()
for traitName, timeLeft in pairs(modData.traitTimers) do
timeLeft = timeLeft - 10;
if timeLeft <= 0 then
player:getTraits():remove(traitName);
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_"..traitName), true, HaloTextHelper.getColorGreen())
modData.traitTimers[traitName] = nil;
else
modData.traitTimers[traitName] = timeLeft
end
end
if next(modData.traitTimers) == nil then
Events.EveryTenMinutes.Remove(TraitCheck)
end
end
function initializeNegativeTwitchTraits()
if modData.traitAbcTimeLeft > 0 or modData.traitXyzTimeLeft > 0 then
Events.EveryTenMinutes.Remove(TraitCheck);
Events.EveryTenMinutes.Add(TraitCheck);
end
end
2.6. Hidden / Unexpected Content. Any hidden or unexpected content and/or messages made in updates to mods that are not flagged on the Steam Workshop description / pages or isnβt evident in the mod itself must have attribution VISIBLE as to where (and from whom) said content has originated.
π€ So I could argue I don't know what 'XYZ Server Settings' include...
π§
Maybe make these local or stick them in a module. TraitCheck is super generic and could have collisions on some other mod. πΆβπ«οΈ
ill just change the name of the functions to reflect the naming logic i use
function TWE_addNegativeTrait(trait)
if not player:HasTrait(trait) then
player:getTraits():add(trait);
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_abc"), false, HaloTextHelper.getColorRed())
modData.traitTimers[trait] = 69;
Events.EveryTenMinutes.Remove(TraitCheck);
Events.EveryTenMinutes.Add(TraitCheck);
end
end
function TWE_TraitCheck()
for traitName, timeLeft in pairs(modData.traitTimers) do
timeLeft = timeLeft - 10;
if timeLeft <= 0 then
player:getTraits():remove(traitName);
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_"..traitName), true, HaloTextHelper.getColorGreen())
modData.traitTimers[traitName] = nil;
else
modData.traitTimers[traitName] = timeLeft
end
end
if next(modData.traitTimers) == nil then
Events.EveryTenMinutes.Remove(TraitCheck)
end
end
function TWE_initializeNegativeTwitchTraits()
if modData.traitAbcTimeLeft > 0 or modData.traitXyzTimeLeft > 0 then
Events.EveryTenMinutes.Remove(TraitCheck);
Events.EveryTenMinutes.Add(TraitCheck);
end
end
Should add negative be removing and adding traitcheck?
TWE = Twitch Events... so even i now where it comes from
tbh i dont know...
the original code wasnt mine and even if i dont see why its doing that
beggers cant be choosers
it works... so im happy
π
alright
but it makes some sense it does that
since is triggered from outside the game
i guess its to avoid overlaping or something like that
also, to clarify about making those local - if they're not called anywhere else they don't have to be global
using global since my testing IDE is a bit ... unregular
They both have the thing that prevents sledging
and its a var shared between 2 mods i have
still figuring out how to share the values between them without using a global
Are you familiar with require = ""
yes i am
but if the var is local
ill have to make the function return a value
and change the code of the old mod
plus the way im testing the code, require sometimes fails
so a global var always works
---FILE 1 = lua/client/myStuff.lua
local module = {}
function module.func1() end
function module.func2() end
return module
``````lua
---FILE 2 = lua/client/myOtherStuff.lua
local myModule = require "myStuff"
local function thing()
myModule.func1()
end
You can use require to return a single table
basically making a file a module/package
It's the same thing as using require - loading blocks of Lua - but keeping it local
has the benefit of not needing to name stuff super long and unique names π
Only started using it recently, myself
dang it... now i have to rewrite the code again... but thats really nice to know
Are you asking how to achieve that?
The basement mod disables Sledging basement walls using the map, not lua afaik.
I see
does anyone have a list of the attachment configurations (such as "Blade on Back") for items attached to zombies?
You can decorate this function to have custom blocks on destroying tiles though
function ISDestroyCursor.canDestroy(self, object)
local origReturn = oldDestroy(self, object);
if ~origReturn then
--- Your own check, setting origReturn to false if you need to protect something
end
return origReturn;
end```
No, I don't think so
This file is where those are defined and has all of the ones in the base game
C:\Program Files (x86)\Steam\steamapps\common\ProjectZomboid\media\lua\shared\Definitions\AttachedWeaponDefinitions.lua
thank you very much!
hmm so ill have to get the path of the mod folder and return it to my app
shared/NPCs/AttachedLocations lua is where they are created
hmm
it seems like i have the right attachment location and that there's not a separate one like i thought there might be
but for some reason my zombies spawn with the rifle across their back despite wearing a bag
something like this i guess?
-- convert real-time (in minutes) to in-game time by dividing by the day duration
local inGameTime = realTime / dayDuration
return inGameTime
end```
though maybe i'm misremembering and zombies that have both guns and bags always spawn like this, and zombies don't have the 'beside bag' back slot like players do
ok noted
I see "rifle on back with bag"
ooh lemme try that
actually a number of them ... "with bag"
ooh i was looking where cosmicb linked which was AttachedWeaponDefinitions
i didn't realize you hadn't both sent me the same file like i thought you did
I haven't used these before, only the ones from the other file cosmicB pointed out.
i'll try on back with bag, because i swear i HAVE seen zombies with weapons in the proper positions before next to bags
does editing the values is clothing.xml file affect zombie clothing zones ?
so for example if I set it all to zero, there will be no construction crew zombies
No. clothing.xml only defines the clothing pieces zombies will wear.
If you want to edit where zombies will spawn with which outfits, you should look at ZombiesZoneDefinition.lua:
C:\Program Files (x86)\Steam\steamapps\common\ProjectZomboid\media\lua\shared\NPCs\ZombiesZoneDefinition.lua
ah thank you
I am basically trying to remove all clothing as I am running shadow zombies mod and it really doesnt fit in
Then you can create a lua file that starts with:
ZombiesZoneDefinition = {};
As that will forcefully delete previous ZombiesZoneDefinition entries.
Then you can fill it with your shadow zombies.
hmm, what if I just edited the zonedefinitions all to 0 ?
will that replace them automatically or just there will be nothing spawning ?
Nothing spawning.
It actually might be better to do something like
for zoneName,zoneDefinition in pairs(ZombiesZoneDefinition)
zoneDefinition =
{
NakedZombie = {
name="Naked",
chance=100,
}
}
end```
This will replace all zombie spawns with your naked zombies
thank you very much
cosmicB more like cosmicG
but I dont think this is the solution, as shadow zombies is a zombie retexture
so basically only skin is changed and I want to remove all clothing to reflect that
then you'll need to do this and make an outfit that has no clothes, then replace the skin texture
if i understand correctly anyway
the skin texture is already replaced, it works as intended
its just my addition to it is all
right--so now what you need to do is make an 'outfit' that has no clothes, and replace all other outfits with it
is the point
yup
and this is how you do that
mb someone know how to get in-house light source obj without light switcher obj to remove first one? found nothing useful in pz source
Anyone know if there's a variable specific to IsoPlayer to determine play-time? I'm trying to flag new characters without using onCreate
getTimeSurvived() uses gameMinutes hmm
theres no such you have to create one
player:getHoursSurvived()
ughghg
i have had no luck modding the house alarm sound
it seems the "HouseAlarm" in the script files is a completely different sound entirely that isn't used
It wouldn't surprise me if most if not all of the sounds the game actually uses are kept in the .bank files instead of loose oggs and wavs
that returns the total time ( year, month, day, hours )
i use it in my stats mod
in my last save ( used for testing ) it would return 2 days, 19 hours
ok traits events are done...
back to the car events... can only stall the engine...
trying to figure out how to trigger a flat tire
you can mod the sounds via the scripts
i've managed to change other sounds but the burglar alarm in particular is tricky for some reason
bad joke: it wouldnt be an alarm if it was easy to tamper with π
good point
Can anyone help me on how to make sure some items dont spawn at all ?
I've edited the entire distributions and proceduraldistributions files and loaded it as a mod but that did not work
Though thank you @vast nacelle your trick did the job
Post your solutions here so that new modders can search for this message and see the solution
This will remove a given item from pretty much every spawn list:
RemoveItemFromDistribution(SuburbsDistributions, "YourModule.YourItemType", nil, true);
RemoveItemFromDistribution(VehicleDistributions, "YourModule.YourItemType", nil, true);
RemoveItemFromDistribution(ProceduralDistributions.list, "YourModule.YourItemType", nil, true)```
Thank you, will try it
He was actually thanking me there for this that's a bit above.
#mod_development message
kind assist
Also if anyone has a link to a proper modding guide, that'd be very welcome π
will do, thanks!
mycar = player:getVehicle()
for i = mycar:getPartCount()-1,0,-1 do
local part = mycar:getPartByIndex(i)
local cat = part:getCategory() or "Other"
local item = part:getId()
end
what am i doing wrong...
i get the vehicle object
is there, i can start and stop the engine using the vehicle object
but cant get the parts...
yea i manually checked when looking for the screwdriver sound, and there are a ton of sounds not located there or in subfolders that i saw
Indie Stone hear my cries... please let gamepad users toggle jog/sprint using keyboard shortcuts so that mods of the Move To function can allow joypad users to jog/sprint while automatically moving to a location. I am guessing pinging you is blasphemy, but I really hope one of you sees this. If there is a boolean flag requiring my gamepad to be disconnected in order to jog or run during an autowalk action in the Java code, please, please, please delete that flag.
I am losing my mind on this final step... I'm guessing that it's in the Java madness somewhere, though I don't know where. I feel like I've checked every obvious place in the Lua.
well got to print the parts name...
mycar = player:getVehicle()
print("------ mycar ---> " .. tostring(car))
for i = mycar:getPartCount()-1,0,-1 do
local part = mycar:getPartByIndex(i)
local cat = part:getCategory()
local item = part:getId()
if item ~= nil then
print(item)
end
end```
Seems like movement on joypad is highly Javaside since I don't even have obvious Lua access to L2, R2, or the joysticks...
Have you checked out JoypadManager.class
as well as media/lua/shared/JoyPad/JoyPadSetup.lua
Alexa start running
Does joystick force you to keep run button pressed while running? Just curious.
Not really.
Endlessly.
Well I'll be damned.
Wait is it exposed?
Seems not π
JoypadManager.Joypad is exposed
Even if it had been exposed, I see no way to use it to fire a button
mycar = player:getVehicle()
print("------ mycar ---> " .. tostring(car))
if mycar ~= nil then
for i = mycar:getPartCount()-1,0,-1 do
local part = mycar:getPartByIndex(i)
local cat = part:getCategory()
local item = part:getId()
if item ~= nil then
print(item)
if item == "TireFrontRight" then
player:Say("setting front right tire condition to 0")
part:setCondition(0)
end
end
end
end
it changes the condition but the tire doesnt "die"
When I type print(JoypadManager), I get nil...
When I type print(JoypadManager.Joypad), I get errors.
What am I missing?
Oh onPressedβ
I bet I could call its onPressed with playerIndex, button
Or the other way
But regardless I can't figure out how it's exposed if that is indeed the case...
What about disabling vehicle distrib
The Joysticks and R2/L2 look to be available with:
getControllerAxisValue(controller, AXIS)
I found these in: lua/client/ISUI/ISControllerTestPanel.lua
Hmmm I will investigate that @dark wedge
R2/L2 are considered axis as they give a value of 0-1 depending on how much they are pressed, instead of a button
I see. Makes sense. Question remains... is whatever the R2 signal does to trigger sprinting on gamepad Lua-accessible... Gonna go check ISControllerTestPanel now
Do you mean removing an item from spawning in vehicles or removing a specific vehicle from the spawn pool?
dude pz has super tires
Oof I think this file is purely for testing that inputs work
Don't know how to remove a vehicle
So it doesn't have any connection between e.g. triggers and jogging
and still... the tire doesnt blow or comes out like it happen to me when i changed tires and forgot to put air in it
Nor does it explain why jogging/sprinting is blocked on gamepad during WalkTo (which remains my key barrier to happiness in life in general)