#mod_development

1 messages · Page 177 of 1

open drum
#

when i typed it in on console ingame

worn girder
#

Okay, so technically this isn't a direct modding question, per se, but...

I'll start with what, in a perfect world, I would like to do, and then maybe we can see what can be done, if anything, to achieve that.

What I'd like to do: Use a telnet client (Specifically, Mudlet, though I can use a different one if necessary) to intercept the messages written to 'server-console.txt', so that I can use Regex triggers to initiate/automate certain admin commands and track data independently, among other things.

I have done similar with 7 Days to Die, on a server where I served as the in-house modder for almost two years, so I'm not completely inept. I just can't seem to figure out how to do it with PZ, or to even confirm if it is possible in the first place.

#

I'm using Bisect Hosting, and they have a terminal/console on their site that essentially has the output I want, so, on some level, I know it is possible. I'm just struggling to figure out how to get that information through my telnet client.

tardy wren
worn girder
#

Hmm, perhaps. I've been banging my head against this for like 14 hours straight now, so that's probably a 'tomorrow' project 😛

tardy wren
#

I don't know if there's a way to change where zomboid outputs its console. There may be some linux OS stuff, but I am unaware of those

worn girder
#

now I'm wondering if I'm just going about this all wrong, and if it might just be easier to set up custom server commands through the chat box itself...

worthy sparrow
#

I have a crazy project idea, live server map on a website?

frank elbow
#

I assume the question mark is asking if it's possible/feasible (?)

#

If so, it is possible & its feasibility depends on how comfortable you are creating a website + a mod to send updates (or a program running on the same machine as the server, but a mod would be more straightforward)

elder stream
#

Easily done in python and a $2 vps - can provide guidance if needed

#

Flask / SimpleHTTPServer etc

elder stream
worthy sparrow
#

Wesbite isn't a problem at all, just getting the raw data (username, x,y coordinates) for me might be difficult since i have no idea how I can get the data

frank elbow
#

Are you trying to do it via a mod or an external program?

#

Are you aiming to, rather

worthy sparrow
#

mod for a server would be neat since its super easy to setup

frank elbow
#

Then that would be fairly trivial

worthy sparrow
#

but an external program has more flexibility

elder stream
#

External should be resilient against updates if you’re only posting user data and map data

frank elbow
#

That way would require reading the game data, which is entirely possible but idr how often the coordinates update. It's in binary

frank elbow
worthy sparrow
#

But like its possible to save all of the data into a file?

#

using just lua

frank elbow
#

Yes

#

See also: getFileWriter

worthy sparrow
#

I guess making a post request using lua could also work but i have no idea if its possible

frank elbow
#

We can't make POST requests unfortunately

#

GET requests are possible though

elder stream
#

Rip

worthy sparrow
#

Well.. could work with GET too

#

wanky af but you can pass parameters to GET request

frank elbow
#

Only thing you can control is the url params

worthy sparrow
#

that is enough

#

damn that is possible

frank elbow
#

This is likely obvious, but there are security considerations to think about, considering people will be able to look at the mod source

#

Security in this case just meaning ensuring users can't spoof their location or the locations of others

worthy sparrow
#

that gave me some concerns

#

but its definitely doable

worthy sparrow
#

What do you recommend instead?

bronze yoke
#

the modfilewriter only has a use maybe for development tools, any completed mod should use the regular filewriter

worthy sparrow
#

alright

frank elbow
#

Does it write to the mod directory? I couldn't remember

bronze yoke
#

the modfilewriter writes to the mod directory, which means in multiplayer the checksum fails

worthy sparrow
#

ohh..

hollow lodge
#

is there any guide to code zombie outfits?

#

or should I just reverse engineer some mod out there

mellow frigate
#

use player:getPlayerNum() instead of player

#

also set all your variables local please, I'm still hurt with people using globals for no reason in the "Item incident"

bronze yoke
#

in general everything should always be local, there's very rarely any reason to go global

dark wedge
#

Is there a way to get the translated recipe name similar to getText("Recipe_Clean_Bandage")? Doing that gives "missing translation", but it is a valid translation string in Recipes_EN.txt. The way I see it in the game is getting the recipe from the ScriptManager and just getting the name from there, but hoping there's a more direct way.

ruby belfry
#

Do you guys now how I can make a map?

#

I’d love to make an expansion mod

crystal oar
ruby belfry
#

Alright ty

#

I’ve mapped on L4D2 before, and it can’t get any more difficult than that

#

So it’s worth a shot lol

crystal oar
#

anyone else got any resources for getting started in map making?

dark wedge
#

Check the pins in #mapping too. Some good resources there.

ruby belfry
#

Thank you!

mild venture
#

what is difference beetween ItemContainer:DoAddItem(InventoryItem) and ItemContainer:AddItems(InventoryItem, 1) . And DoAddItemBlind what is it?

nimble yarrow
#

you can specify how many, using AddItems. not sure about blind.

dark wedge
#

DoAddItem and DoAddItemBlind are the same thing in my decompiled Java and run self.AddItem(item). likely something kept for legacy reasons

mild venture
#

Thanks

#

there's more! addItem and AddItem and AddItemBlind. I'm in shoke

nimble yarrow
#

Not sure. The "Do" prefix could mean immediately, as opposed to a request that is carried out in a few frames, or something.
Or it could act as a "TryAddItem" type of function, where it performs various checks first, under the hood.

like dhert said, I'm pretty sure all 6 functions do the same thing.

bronze yoke
#

most weird naming is because of non-english devs

mellow frigate
#

I am interested in understanding what m_Scalar and m_Scalar2 parameters do in AnimSets xml files and when they can be used. I fear the manual RE is gonna be too much for me poor soul so any cue is welcome.

mild venture
hasty horizon
#

are there any mods some of the more experienced people in this channel recommend to look at the code to learn from? i tried poking my nose into the docs and my brain was just rejecting whatever i was reading

nimble yarrow
#

Anyone familiar with ProceduralDistributions?

I'm working on a mod that adds new items to school lockers. The items don't seem to be affected by the loot rarity.
Setting my world's loot to Insanely Rare, then searching the West Point school lockers, I find ~50 of the new items
(now that I think about it, maybe modded items need to be classified as 'Other', so that the world's loot rarity sandbox settings work).

Because the world's loot rarity sandbox settings dont work, I decided to adjust the ProceduralDistribution numbers!
adjusting the ProceduralDistribution, I change the value from 1.0 to 0.00000000001.
Checking the lockers with Debug - LootZed, the modded items, indeed, have a E-10% chance to spawn (0.00000000001%), great!
I search the school again, and I still find ~50 of the new items. wtf?

I even changed the ProceduralDistribution value to 0.0% chance to spawn. Checking LootZed, yes. 0% chance to spawn.
...but the school lockers were filled with the new items. What is going on??

bronze yoke
#

yeah, i've never heard an explanation why that makes sense to me but values low enough for it to start displaying with scientific notation don't seem to work properly

nimble yarrow
#

yeah, i'd prefer to not use floats/doubles this small...
But playing zomboid on insanely rare loot settings, a pencil or piece of paper goes from 50% to 0.5%.
so assuming my item needs to be much more rare than a pencil, I feel like I have no choice but to drop into scientific notation. hmmm,

bronze yoke
#

if you want spawn chances even lower than is supported, you need to use custom spawning/deletion logic using the onfillcontainer event (which is fired on the server only when a container is populated by the loot generator)

nimble yarrow
#

I might be able to sidestep the issue entirely, if I can assign an 'item type' to the modded items?
Looking at the loot rarity sandbox settings, there is non-canned food, ammo, medical, survival essentials, mechanics, literature, other.
maybe the problem, is that these items are none of the above... as a result, they are never set to Insanely Rare. ?

bronze yoke
#

i would assume other is automatically assigned

#

i know i've never manually assigned one

stone garden
#

i just wanted an friend (( this why i beg :(

#

i feel sad lonely and etc

#

in irl

crystal oar
tawdry moss
tawdry solar
#

craz

hasty horizon
#

can i attach a Lua function to an items variable value, in a similar way to how you can have a recipe give XP? like if i make an Icecream as a food item, and the player has a trait that interacts with that, like 'Sweet Tooth' or something, id want the UnhappyChange of the item to be different. Or is there a different approach on how to go about it?

bronze yoke
#

no, the workaround most people use for that is to hook the eating action and perform the checks then

#

you'd also have to hook the tooltip if you want it to show the trait affected value

#

it may be something that should have an api made because it's so common

hasty horizon
#

wdym by hook? like having a check if a player did an action per frame/update?

bronze yoke
#

no, you take the vanilla function and add your own code around it

#

eating is fully lua so you can just edit the functions

#
local old_foo = foo
function foo()
    print("bar")
    old_foo()
end
```this redefines a function named foo to fire modded code before/after it without having to overwrite the file or the function entirely
#

old_foo stores the original version of the function, so when you redefine foo you just need to call old_foo before or after (or in the middle) of your code for it to run the vanilla code

#

it's a powerful way of editing any lua behaviour, and sometimes java behaviour

hasty horizon
#

so its kind of like in java using inheritance in a way? like a Super call to the original objects constructor

bronze yoke
#

yeah sort of

#

you can also just redefine a function outright, but saving the original into a variable and then calling it allows for multiple mods to edit the same function (since they'd just stack on top of each other based on load order)

hasty horizon
#

ill have to take a look at how the game does the eating code then to see how to implement my stuff. would i be able to edit base foods in the same way if i redefine the section? so like a base Chocolate Bar for the same sweet tooth perk

bronze yoke
#

yeah, the way i've seen someone do it is basically

#

(pseudocode, no idea what the correct syntax would be for this exact application)```lua
local old_perform = ISEatFoodAction.perform
function ISEatFoodAction:perform(...) -- perform in a timed action is the one that handles successfully completing it, so i assume eating is done in there
local original_hunger = self.item:getHungerChange()
if self.item:getFullType() == "Base.ChocolateBar" then
self.item:setHungerChange(original_hunger * 2)
end

old_perform(self, ...)

self.item:setHungerChange(original_hunger) -- change it back so it doesn't actually change the stats of the item

end

hasty horizon
#

so basically your editting the item temporarily? would i have to worry about an approach like that for a server?

bronze yoke
#

shouldn't matter as long as you change it back

hasty horizon
#

ok ok, good to know, is the javadoc the best resource to see all the different Lua functions? or has someone written it in different words somewhere else?

bronze yoke
#

the javadoc only has the interface to the java portion of the game, if you want to see the lua stuff most people just go through the code themselves

#

if you're using a decent ide you can add the game's lua folder as a library to your project to get intellisense for that stuff

crystal oar
#

oh man when i finally got umbrella working, it was magical

hasty horizon
#

i do use Intellij, is there a guide to set that up?

bronze yoke
#

i'm not sure but i can quickly show you since i use it too

#

file -> project structure
global libraries
plus sign at the top left to add a library, pick Lua Zip Library and then navigate to your game's lua folder (usually in Steam/steamapps/common/ProjectZomboid/media/lua/)

#

i think it adds it to your current project automatically but from now on all you have to do to add it to new projects is to go back to this screen, right click the library and add to modules

hasty horizon
#

woot its working thanks!, is there a way to figure out what functions do what? or is that a guess based on name thing

bronze yoke
#

pretty much :( if you use umbrella you can get intellisense for java stuff as well, and i think it makes the intellisense for lua a bit better

#

there's a project in progress that will allow modders to contribute documentation for both sides, but it's not ready yet

hasty horizon
#

Ah is that the umbrella discussion going on in this channel?

bronze yoke
#

the lua stuff is a little limited but the java intellisense is fantastic

#

there's instructions on how to clone the repo properly there, then you just need to add it as a library like you did with the lua folder

hasty horizon
#

ok, ill do that, thanks!

#

hopefully i won't have to ask as much questions with all this setup now lmao. i know a good bit of java but its just a question of equating everything in my brain and my brain being stubborn

#

30 seconds into coding and my brain is already feeling confused about the no curly brackets and semi colons .-.

hollow lodge
tawdry moss
#

it is a medic feature

#

paramedic only

#

the first aid centric occupations are getting some unique bonus to incentivize taking them for something that you cant replicate simply by levelling first aid

hasty horizon
#

does anyone know how the TraitFactory method works to add a trait? i get the first field being the name of the trait, but examples i see have a getText(the name that appears in client i believe?), an integer, another getText(teh description in client i believe?), and a boolean. im not sure how the getText functions work as they don't seem to have a filepath?, then theres the integer and boolean that idk what they do

sour island
#

getText() grabs the translations string matching the ID

#

you can supply a raw string temporarily if you're just testing stuff out (as in get rid of getText())

hasty horizon
#

ok that makes sense, what do the integer and boolean do? i would have thought the integer would be like "placement in the perk menu" but there seems to be a few of them in this mod im referencing for it that has the same number, and the boolean always seems to be false

#

oh wait

#

wait

#

is it the points it adds

#

if thats the case then that makes sense, but i still dont know about the boolean

#

some of the traits in the MainCreationMethods.lua seem to have both a false and a true even

hasty horizon
novel barn
#

Also, I'm surprised the wiki points to an external github repo. I was going to edit it but obviously I can't.

sour island
#

oof - you can supply a PR technically if it's on github

novel barn
#

Yeah that's just more work. :/

hasty horizon
#

mood

novel barn
#

I've reached out to pzwiki_editing to see how they want to handle it. There's also a section labled Occupations, Traits and Skills that's completely empty. I might just copy the github info into a new wiki page and link it in this section. I just hate having duplicate information with no real gain.

tawdry moss
#

hey so i want a timed action to require a specific item, adding a new treatment to the first aid system got me wanting to blow my brains out because i can't figure out how to tell the game what item to look for.

the specifics of first aid are probably not relevant to figuring out how to make a time action require gunpowder to show up when prompted so how to i make a timed action look for a specific item

tame mulch
#

Or what exactly you want to do?

tawdry moss
#

i want to add cauterizing wounds with gunpowder

#

seal them shut and remove infection but add a bad burn

#

cant get a new option to appear in first aid menu tho

autumn temple
#

this moodleframework just hates me, I am setting up the thresholds like the framework tells me to, but it keeps making Bad4 use its default value of 0.1 instead of 8, which breaks the whole thing

#

ive been messing with it for three days, ive had multiple friends look at it, none of us can figure out whats wrong

shadow pumice
#

Anybody know how to make fireworks into pz? I know nothing bout coding...

hasty horizon
hasty horizon
novel barn
# autumn temple this moodleframework just hates me, I am setting up the thresholds like the fram...

I haven't worked with the moodle framework at all so I probably can't help. However I'm curious how you're reloading the lua files when you want to test again? Are you backing out of the loaded game entirely and reloading from the main screen? Or are you reloading in the debug screen? If you're only reloading in the debug screen be aware that reloading just loads an additional copy of the lua and doesn't overwrite the first. You might be getting the result you want and then your original code is overwriting it. I don't actually know if there's a order to which copy of the file executes first.

bronze sand
#

Quick question, could your API be used to limit the amount of boredom sending text in chat while in Multiplayer gives you?

autumn temple
#

wot

novel barn
bronze sand
#

Kinda broken
The idea is that there would be a limit to how much boredom can be reduced by sending text, not just reduce the amount of boredom points per message.

autumn temple
#

reloading lua gave me issues earlier so ive just been restarting my game for the past few changes

#

the code should just be like this. because values is (0.1, 0.2, 0.3, 0.4, 0.6, 0.7, 0.8, 0.9)
I set it up so on a scale from 0 to 10.0, the negitive moodles should appear, level 1 at 2.0, level 2 at 4.0, level 3 at 6.0 and level 4 at 8.0

#

but negitive level 4 decides to use the default value of 0.1, so it appears on loading a new game, and disappears when level 1 gets hit at 2.0

#

so for some reason my negitive level 1-3 is working. but negitive level 4 is not

hasty horizon
#

are you able to get the negative level 4 value if you set the value directly to 0 with the :setValue instead of using testStat?

#

im not the most familiar with lua, but the way your describing it makes me think that maybe the or statement when you declare testStat is picking the wrong value?

#

idk

autumn temple
#

this is the TestStat made with the help from Albion

novel barn
#

Okay I'm starting to see what's going on here. Still looking over it.

#

Does TestStat get initialized with a value or is it just zero?

hasty horizon
#

^, maybe testStat is returning null/nil/whatever lua calls it

autumn temple
bronze yoke
#

the api is mostly a reimplementation of the java Stats update, and it looks like boredom was moved to BodyDamage at some point, so the small bit left that i reimplemented doesn't actually do anything

#

(and needs to be removed since you get double idle boredom in its current state)

#

the BodyDamage stats are slowly being assimilated (i have a panic reimplementation done for the next minor version), i can do boredom next if that's something you're interested in

bronze sand
#

I mean, it's something I think should be patched up

#

Just sending many messages in chat to get rid of boredom makes all items that are meant to be used for it kinda pointless

#

So I propose a limit to it, instead of just removing the feature
Maybe a cooldown as well

bronze yoke
#

i honestly didn't know that was a thing, the api will be able to sort that out once boredom comes under its scope (for real this time)

hasty horizon
bronze yoke
#

i'm looking at boredom and it looks like it'll be more complex to reimplement than panic was, but probably not impossible

novel barn
#

I checked the workshop page for the moodle framework and it specifies values range from 0 to 1. However @autumn temple said they "set it up so on a scale from 0 to 10.0". Duckling, you confirmed this works the way you expect it to for every value but bad4?

#

0.0 <= myNewMoodleValue <=1.0

autumn temple
autumn temple
#

the default threshold for bad4 being 0.1

hasty horizon
autumn temple
#

hm, let me try that

#

making it start at 1 then going to 11 just makes the issue happen at 1.1

hasty horizon
#

hmm

#

on the modData.TestStat + 0.1, if you change the 0.1 to another value, will it still do it on the 0.1?

#

like a 0.05

autumn temple
#

hm ya it gave it to me before it even hit 0.1

#

ignore the error, i kept it there purposely so I know when the moodles change

#

which ya it applies right at 0.01

nimble yarrow
#

sorry for this question. I write C#. lua is gibberish to me. trying to concat a varaible and a string. googling this provides unclear examples.

player:Say(ZedCount .. "Zombies nearby")

--edit: or maybe
player:Say(ZedCount, "Zombies nearby")

--edit: or maybe
player:Say(string.formatted , ZedCount, "Zombies nearby")
novel barn
#

I actually have a hopefully quick question myself. I'm currently leveraging InstanceItem to pull all existing values from items into a copied version of said item. For example I can get a bag's capacity, weight reduction, etc. with this code. But I can't get the runSpeedModifier from an item I KNOW has one.

    local item = getScriptManager():getItem("Bag_FoodCanned")
    local instance_item  = item:InstanceItem(item:getFullName())
    local instance_capacity = instance_item:getCapacity() --works, comes from InventoryContainer
    local instance_weight_reduction = instance_item:getWeightReduction() --works, comes from InventoryContainer
    local instance_metal_value = instance_item:getMetalValue() --works, comes from InventoryItem
    local instance_RSM1 = instance_item:getRunSpeedModifier() --DOESN'T work, comes from InventoryItem.Clothing
    local instance_RSM2 = instance_item.Clothing:getRunSpeedModifier() --DOESN'T work

Does anyone have any clue why my getRunSpeedModifier() lines are throwing errors?

novel barn
#

I just tried it and it makes the game unhappy. I'm looking into it

hasty horizon
autumn temple
#

ya there is a 2nd way to do it that is just a bunch of if, elseif statements but i dont know if that will let me disable the good moodles

#

which the mod I am testing for I only want negitive moodles

bronze yoke
#

it actually doesn't have a runspeedmodifier - they don't work anyway so you wouldn't know, but that field is being ignored since its type (InventoryContainer) doesn't have any handling for it

#

if you've ever noticed that bags don't get dirty properly this is also why, bags aren't clothing even though they pretend to be

hasty horizon
#

okmyownquestionrealquick, when i make a trait, do i need to specify a filename/filepath, or similar? or does the game look in a specific folder for a file that contains the name of the perk added?

#

i can't tell how some of these other trait mods do it

bronze yoke
#

the trait name is usually a getText() call that references a translation string in lua/shared/Translate/EN/UI_EN.txt

hasty horizon
#

like when you create a character/look at your characters traits how each of the traits have an icon

bronze yoke
#

oh yes, it looks for media/ui/Traits/trait_TRAITNAME.png

nimble yarrow
bronze yoke
#

yeah, oddly enough

hasty horizon
#

strange its not divisible like 8

bronze yoke
#

it's so strange i had to go check even though i'd already made one 😅

nimble yarrow
#

afaik images are commonly a power of 2, for compression reasons. but 18x18 doesnt really need to be compressed, right? 😛

novel barn
# bronze yoke it actually doesn't have a runspeedmodifier - they don't work anyway so you woul...
module Base
{
    item Bag_FoodCanned
    {
        DisplayCategory = Bag,
        Type = Container,
        DisplayName = Duffel Bag,
        ClothingItem = Bag_FoodCanned,
        CanBeEquipped = Back,
        WeightReduction    =    65,
        Weight    =    1,
        Capacity    =    18,
        Icon    =    Duffelbag,
        OpenSound   =   OpenBag,
        CloseSound   =   CloseBag,
        PutInSound   =   PutItemInBag,
        RunSpeedModifier = 0.95, ------------------------------------------------<<<<<<
        CanHaveHoles = false,
        ReplaceInSecondHand = Bag_DuffelBag_LHandTINT holdingbagleft,
        ReplaceInPrimaryHand = Bag_DuffelBag_RHandTINT holdingbagright,
        WorldStaticModel = DuffelBag_Ground,
    }

This is from the official game file ProjectZomboid/media/scripts/newBags.txt. I'm guessing this value is there for future proofing then, in case they do add a runspeedmodifier to more types of items? This is literally the first item in the file.

novel barn
bronze yoke
#

oh... huh

#

i'm correct that it does not get added to the instance

#
    private float calcRunSpeedModByBag(InventoryContainer inventoryContainer) {
        float float1 = inventoryContainer.getScriptItem().runSpeedModifier - 1.0F;
#

good thing that got me to double check

#

it just grabs it from the script

novel barn
#

Ahh I'm slowly learning how to read (what I believe) are the java docs. I could definitely benefit from some java experience. I wasn't sure how getCapacity() and getMetalValue() were both working despite me not specifying where they were coming from. I'm assuming the methods have been inherited from up the line. getCapacity() works because the item is of class InventoryContainer. getMetalValue() works because the InventoryContainer extends InventoryItem (which has a declared method named getMetalValue())

bronze yoke
#

that's right!

novel barn
#

My OOP is POOP

hasty horizon
novel barn
hasty horizon
#

the dog or car examples are apt, but idk maybe because its not the most applicable i had a hard time with it at first

novel barn
#

Like, I get the concept of inheritance but only when it's pointed out to me. 😂

#

I just have very limited exposure to OOP so it's just something I need to spend more time doing

bronze yoke
#

i had a similar experience

hasty horizon
#

i think the latest example of me using it was in my 2d lightcasting project i had an abstract Light class, and a Pointlight class that extends from Light

#

and the light class had the boring getters and setters

dark wedge
hasty horizon
#

idk how big this will show up in discord tho, but i think this salad bowl icon ain't toooo bad?

#

oh hell thats TOINY

bronze yoke
#

you shouldn't need to do that

#

the operator converts to string anyway

novel barn
bronze yoke
novel barn
# bronze yoke

why did mine fail... that's exactly what I was doing 😦

dark wedge
#

It will fail if its nil

#

and other things

#

you are correct, in most cases it will work if its an integer. doing tostring() will guarantee you get a string though.

dark wedge
novel barn
#

OHHH I had declared zedCount as local.. I forget that when you do that in the command console it's just lost to the void after you hit enter

bronze yoke
#

yeah, every line is its own environment

hasty horizon
novel barn
#

well I'm sharing this anyway because I'm proud of how fast I was able to write it. I had it written (but forgot to reload lua when I was testing it) before the question was answered. 😦

nimble yarrow
#

thank you @ albion, Collide, dhert 😉

bronze yoke
#

three kinds of people...

nimble yarrow
hasty horizon
#

das a lot of zombies

nimble yarrow
#

shoot. maybe I need chunk, not cell?

novel barn
#

"nearby"

nimble yarrow
#

well, nearby just a string.

    local Zeds = getCell():getZombieList()
    local ZedCount = Zeds:size()
bronze yoke
#

cell should be correct

#

the IsoCell is the entire loaded area

#

IsoChunks are 10x10 square areas

novel barn
#

Sorry I was just trying to make a joke about your search size.

nimble yarrow
#

lol

novel barn
#

was going to add a gif of Dr. Evil doing airquotes but I took too long, posted the wrong one, and decided to die with my shame instead of fixing it.

bronze yoke
#

LOL

nimble yarrow
#

getting a car stuck horizontally in a hallway fits with my 16x zombie pop

hasty horizon
#

woot another icon i drew that i don't immediately go "oof" at

novel barn
hasty horizon
#

danke

#

i think a part of the reason i like em more than usual is i don't use solid black as the outline color

#

if i need an outline i was using a slightly darker version of the color the thing is

bronze yoke
#

i've come to peace with my programmer art

hasty horizon
#

i don't do baaad art in general, im just kind of perfectionist in a way? and i don't have a drawing pad

#

like i drew these two with a mouse, but my pixel art is kinda rough

#

abused the hell out of the splatter brush on gimp

novel barn
#

the tools are there for tooling /shrug

bronze yoke
#

i'm a strong believer that any modded content should fit perfectly in vanilla, so i am perfectionist to a degree, but i have to accept that art just isn't my focus and it's not worth it

hasty horizon
#

fair fair

novel barn
bronze yoke
#

for my bigger projects i'll find someone to commission, otherwise it doesn't really matter if my trait icon is an off-looking recolour of a vanilla one

hasty horizon
#

if i realllly need to i have an artist friend i could bug, but i dun wanna be that guy

novel barn
#

This was the trait icon for my last mod called House Fire Survivor. It took me an hour and this was my 5th attempt

bronze yoke
#

looks good!

hasty horizon
#

^ ye

novel barn
#

I think so too. It was the only one I didn't hate. The rest were bad. 🙃

hasty horizon
#

it helps us that the trait icons are so small cause then it hides imperfections

bronze yoke
#

thank god for our obnoxiously small ui

nimble yarrow
#

@bronze yoke my picture above, debug-zombie population shows 8854, but "nearby" is 3304, meaning 5550 are 'simulated'. is there any way to include simulated zeds in the size of getCell():getZombieList():size()?

(unless getCell is different than IsoCell, then in that case, would i type... IsoCell():getCell() ?

dark wedge
#

i've been trying to combine vanilla icons to make some actions for my context radial. so far the results have been good enough imo. zoomed in a bit for visibility

bronze yoke
novel barn
bronze yoke
#

that UI is oddly implemented in java, and the place it gets that count from doesn't seem accessible

novel barn
#

I'm 100% joking, but you could instead do "At least 3304 zombies nearby"

#

It's not wrong. It's just not right.

hasty horizon
#

if you got the amount of nonsim zombies, and the total amount of zombies

#

couldn't you just

#

take the total - nonsim

#

and boom?

bronze yoke
#

we don't know how to get the total amount

nimble yarrow
#

total requires me to be running in debug mode

hasty horizon
#

ah

#

whats the context of this btw? if its for the player to know the amount, you could write a little more code to keep track of seen/heard zombies rather than just all the ones nearby?

sour island
bronze yoke
nimble yarrow
#

Maybe it's possible. I just don't know how 😮

sour island
#

Not a plug-n-play snippet

bronze yoke
#

can you tostring a field when it isn't exposed?

sour island
#

uhh...

#

in this case the field was exposed, just without a getter

#

Not sure about unexposed fields

bronze yoke
#

yeah, but the field object

#

if this is tested then the answer is yes

sour island
#

This is something I employ in a mod

bronze yoke
#

i wouldn't've expected tostring to play nice with an object that isn't exposed

sour island
#

you can also set fields in debug mode - for extra fun

nimble yarrow
bronze yoke
#

it's an arraylist, so its methods are going to be listed on java's site - you can get there just by clicking arraylist

sour island
#

getter refers to a method/function to get a field

#

getZombieList is a getter for zombie list

#

The context of the discussion seemed to imply there was a field that had information you wanted - but I think I misread

nimble yarrow
#

I see, so ArrayList size(), and all the other methods are listed on the docs oracle site, nice.

hasty horizon
#

any idea why it don't like my line 13?

#

the file that its erroring is in my lua/client

#

the line its self is if its too small: "Events.OnGameBoot().Add(addTatersTraits);"

#

the local function on top of that function call is:
"local function addTatersTraits()
local Vegetarian = TraitFactory.addTrait("Vegetarian", "Vegetarian", -4, "Penalizes eating meat", false, false)
local Carnivore = TraitFactory.addTrait("Carnivore", "Carnivore", -6, "Penalizes not eating meat", false, false)
local Cannibal = TraitFactory.addTrait("Cannibal", "Cannibal", -6, "Allows to eat human flesh", false, false)
local SweetTooth = TraitFactory.addTrait("SweetTooth", "Sweet Tooth", 1, "Bonus to eating sugary items", false, false)
end"

bronze yoke
#

Events.OnGameBoot.Add(addTatersTraits)

#

the () tries to call Events.OnGameBoot as a function, but it isn't one

hasty horizon
#

🤦 i didn't notice i wrote () out of habit

#

danke

hasty horizon
#

whats a way of printing to the ingame console? i realize at some point im going to have to resort to my tried and true "random print statement to see when my code borks" methodology andi wanna be ready

#

i tried print("oi") and that didn't seeeeem to do anything

bronze yoke
#

that's correct

hasty horizon
#

thats correct in that print is the way to do it or thats correct in that it doesn't do anything?

bronze yoke
#

print is the way to do it

hasty horizon
#

ok

#

hmm,

local old_perform = ISEatFoodAction.perform
function ISEatFoodAction:perform(...)
local original_hunger = self.item:getHungerChange()
print("aoi")
if self.item:getFullType() == "Base.Chocolate" then
print("boi")
if player:HasTrait("SweetTooth") then
print("oi")
end
end
old_perform(self, ...)
end

when i ate a chocolate bar, none of the prints went off in the command consoles output log

#

also, is there a way to do categories of items, like sweets in general in one if statement, or do i gotta do it for all sweets

bronze yoke
#

depends if the game keeps track of what items are sweets

hasty horizon
#

also i might be dumb, the lua file i created with the function in it wasn't even in the modfolder 😓

nimble yarrow
#

@hasty horizon check this out

hasty horizon
nimble yarrow
#

its for discord lua formatting

hasty horizon
#

o

#
---i see
#

so i did the

function ISEatFoodAction:perform(...)
    print("aoi")
    if self.item:getFullType() == "Base.Chocolate" then
        print("boi")
        if player:HasTrait("SweetTooth") then
            print("oi")
        end
    end
    old_perform(self, ...)
end

and line 13 is that player:HasTrait, if im reading that stacktrace right its saying that the function call returns null? SweetTooth should be correct since i was able to use setMutualExclusive on it in another file. this was how i created it:

local SweetTooth = TraitFactory.addTrait("SweetTooth", "Sweet Tooth", 1, "Bonus to eating sugary items", false, false)
nimble yarrow
#

just to check,

if not player:HasTrait("SweetTooth") then
print("oi, you don't even have it")
return
end
hasty horizon
#

the console didn't bring up the print

#

im trying it with Sweet Tooth rather than SweetTooth to see if that changes anything

#

nah that didn't work either

nimble yarrow
#

but this is line 13 ???

if player:HasTrait("SweetTooth") then
hasty horizon
#

Yes

nimble yarrow
#
if not player then
print("oi, you don't even have player")
return
end
hasty horizon
#

I tried that. It still errored on the code before that, and did not print out either. Unless it stops reading the file once it errors

nimble yarrow
#

also, you asked 10 hours ago,

are there any mods some of the more experienced people in this channel recommend to look at the code to learn from? 

edit: not that i'm 'experienced', but check out dynamic traits by peppercat, i used it as a coding reference for my first mod, very useful to browse around the lua scripts
https://steamcommunity.com/sharedfiles/filedetails/?id=2459400130

#

yeah it will stop, can you move the debugs up, before the error

dark wedge
hasty horizon
#

I'll try both when I'm available tomorrow, I gotta keep a sleep schedule rip.

#

I'll also take a look at the mod

nimble yarrow
#

Maybe i'm getting closer?

--this works, but it only returns ~half of the zeds in the cell, as can be seen in the Zombie Population debug tool
getPlayer():Say(getCell():getZombieList():size() .. " zeds nearby")
 
--possibly something here? returns 0
getPlayer():Say(getWorld():getSpawnedZombieZone():size() .. " zeds nearby")

--possibly something here? causes error
getPlayer():Say(getWorld():MetaCell():zombieCount() .. " zeds nearby")

--possibly something here? causes error
getPlayer():Say(zombie.popman.ZombiePopulationManager():radarCount() .. " zeds nearby")

--possibly something here? causes error
getPlayer():Say(getPlayer():getGameCharacterAIBrain():getCloseZombieCount() .. " zeds nearby")
neon hedge
#

hey guys, how do i open console in the left down corner again? bc i accidentally closed it

novel barn
#

Wow. I found it on accident... @neon hedge press the tilde key. On most standard (english) keyboards it's above the tab key.

neon hedge
#

ty

#

I found out you can also change it in the control settings

novel barn
#

huh. yeah there it is. good to know! Thank you!

mellow frigate
#

Hello, is there a reason for 'keyBinding' to be in shared ? My half brain would have put it in client side only. Am I missing something ?

novel barn
mellow frigate
novel barn
#

I'm having some trouble getting my one mod to successfully fetch a file from another mod despite requiring it. This fails to print DoD_TestHelpers.foo. I have the following code/files:

--Contents\mods\DuffelsOfDirtItemBuilder\media\lua\client\DoD_BagExtractor.lua
local DoD_TestHelpers = require("DuffelsOfDirt/DoD_TestHelpers")
print(DoD_TestHelpers.foo)
--EOF ------------------------------------------------------------
--Contents\mods\DuffelsOfDirt\media\lua\client\DoD_TestHelpers.lua
local DoD_TestHelpers = {}
DoD_TestHelpers.foo = "barbarbarbarbar"
return DoD_TestHelpers
--EOF ------------------------------------------------------------

This previously worked when the two files were in the same directory but now that I've moved DoD_BagExtractor.lua out, it throws a fit. DuffelsOfDirt is a requirement for DuffelsOfDirtItemBuilder. The mod folder is named DuffelsOfDirt. The modinfo file lists the mod ID as DuffelsOfDirt. I'm not really sure what else the string could possibly need to be. Does anyone have any thoughts or advice?
Update: Capitalization error. Update Update: It was not, in fact, a capitalization error 😢

novel barn
#

That also fails

mellow frigate
#

sorry then for the noise

novel barn
#

I'm trying it again. It hasn't failed yet.

#

I... what? It works now. I must have typed something in wrong. I just spent an hour and a half using the right solution and somehow getting the wrong answer. Thank you @mellow frigate!

novel barn
#

Why does it not require DuffelsOfDirt though? I'm also requiring a few other files like so

local TestFramework = require("TestFramework/TestFramework")
local TestUtils = require("TestFramework/TestUtils")

And these require TestFramework to be explicitly declared.

#

Oh. I answered my own question. These are in a folder.... client/TestFramework/TestFramework.lua.

#

🤦

mellow frigate
# novel barn 🤦

In software engineering, rubber duck debugging (or rubberducking) is a method of debugging code by articulating a problem in spoken or written natural language. The name is a reference to a story in the book The Pragmatic Programmer in which a programmer would carry around a rubber duck and debug their code by forcing themselves to explain it, l...

worldly stone
#

Hello guys, I'm a developer newly into Lua and zomboid modding. I want to make a mod that allows players to place and create a heat source in the world in multiplayer.

Can I get a basic example of how to handle the mod data if it's not too complex? Basically I want to make sure the heat source is there for all the players even if they logged in after it was place.

It doesn't have to be actual working code, just need a rough idea of the good practice.

Thanks! spiffo

mellow frigate
worldly stone
stone garden
#

know but i want an modder friend

mild venture
#

Hi! What is InventoryItem:getRegistry_id() ? What is registry in general?

brave ruin
#

Hello, if I make a weapon and put "NeedToBeLearn:true" Can I put this recipe into a magazine that is already in the game, if so how?

autumn temple
#

@hasty horizon ok so from looking more into my problem yestarday. it appears that all the bad thresholds are being overwritten not just bad4. but the good thresholds are not being overwritten at all.

mellow frigate
#

I'm sure plenty of you are PZ car specialist in there 😄 How do I get access to the window associated to a passenger seat ? I was hopping to get the equivalent of BaseVehicle.getPassengerDoor for the window but I do not find it. Also I need to distinguish a door with a window from a door without a window.

verbal yew
#

inv:AddItems("LabItems.LabSyringeReusable", 1);
ZombRand can be added into this code?

#

like inv:AddItems("LabItems.LabSyringeReusable", ZombRand(0, 1));

mellow frigate
#

local windowPart = VehicleUtils.getChildWindow(door) -- got it

verbal yew
#

guys? ^^'

autumn temple
#

ok so moodleframework is giving me anyother problem, to where the moodle is updating every tick, and violently shaking. instead of updating/shaking when the moodle gets changed. how would I go about preventing or slowing down when the moodle updates?

dark wedge
#

I'm about halfway through the ISWorldObjectContextMenu (though it doesn't look it in practice) and assigning icons to actions in the radial: all the water/fuel interactions, toggling items on, etc., are working. There are some things I'm just not going to be able to assign an icon without further overriding the base game though...

wet sandal
#

This looks nice

#

On M/KB I'm indifferent, but this would be huge if I'm playing on a Steam Deck or controller

mellow frigate
autumn temple
#

Ok thanks

nimble yarrow
#

can i reload lua from inside debug game, or do i need to quit to main menu and press blue button on bottom right?

bronze yoke
#

you can reload files from the f11 menu, but keep in mind that it doesn't 'undo' the original execution of the file (so if you changed something outside of the file's environment like overwriting a function, it won't undo that)

#

generally i just reload the save to avoid issues

#

lua reloads if you load a save with different mods, so i just disable my mods on the main menu and reload the save

nimble yarrow
#

works perfectly, thanks!

#

i've been alt+f4ing each time i delete a colon or something, this will help 😛

crystal oar
#

i forget, do you make your character before or after click to start?

bronze yoke
#

before

crystal oar
#

great so OnGameStart is when you click to start right?

bronze yoke
#

roughly

crystal oar
#

but definately after character creation?

bronze yoke
#

yeah

crystal oar
#

thanks

trim mist
#

How does a character get dirty?

#

I wish I could like. Roll them through mud or sth

#

running through trees isn't really getting me anywhere lol

bronze yoke
#

it seems mostly random

#

there's random chance of gaining dirt while moving, running, sprinting, while hot, while standing in a puddle, and while in trees

#

you can see the logic in IsoGameCharacter.updateDirt, which is called during its per-tick update

trim mist
#

sigh

#

i've added dirt via the visual parts cheat on the health menu

#

find it kind of odd the avatar's back is squeaky clean but whatever lol

hasty horizon
hasty horizon
#
local sweets = {
    ["Base.PopBottle"] = TRUE,
    ["Base.Pop" ] = TRUE,
    ["Base.Pop2" ] = TRUE,
    ["Base.Pop3" ] = TRUE,
    ["Base.JuiceBox" ] = TRUE,
    ["Base.Cereal"] = TRUE,
    ["Base.Biscuit" ] = TRUE,
    ["Base.CakeBlackForest"]  = TRUE,
    ["Base.LicoriceBlack"]  = TRUE,
    ["Base.CakeSlice"] = TRUE,
    ["Base.Candycane"] = TRUE,
    ["Base.CandyPackage"] = TRUE,
    
}

function ISEatFoodAction:perform(...)
    if self.character:HasTrait("SweetTooth") then
        local func = sweets[self.item:getFullType()]
        if (func) then
            ---some code here
        end
    end
end

so the game doesn't keep track of what is and what isn't a sweet, i was going to do a switch statement but from my googling, Lua does not have those. am i correct in this being functionally the same? each food item is going to have the same thing done to them

trim mist
#

oh hey! I'm doing something quite similar in my mod. I decided on tagging each item at the beginning of the game

nimble yarrow
#

you can probably remove CandyPackage.

mellow frigate
hasty horizon
#

how do i go about adding the tag and checking for it?

hasty horizon
mellow frigate
#
inventoryItem:hasTag('Sweet')--read the tag on InventoryItem instance```
#
scriptItem:DoParam('Tag=Sweet')--write the tag on Item instance (e.g. OnGameStart)```
trim mist
# hasty horizon how do i go about adding the tag and checking for it?
AnthroTraitsUtilities.AddItemTagToItemsFromFile = function(path, tag)
...
AnthroTraitsMain.ATOnInitWorld = function()
...
local OriginalEatPerform = ISEatFoodAction.perform;
ISEatFoodAction.perform = function(self)
    -- code to run before the original
    OriginalEatPerform(self);
    -- code to run after the original
    ATM.DoVoreModifier(self.character, self.item, self.percentage)
end
...
AnthroTraitsMain.DoVoreModifier  = function(character, foodEaten, foodPercentEaten)
...
AnthroTraitsMain.ApplyFoodTypeMod = function(modifier, character, foodEaten, percentEaten)

https://github.com/badonnthedeer/AnthroTraits/

GitHub

A mod for Project Zomboid that adds anthro-themed traits for player characters, and integrates with mods that provide furry player models. - GitHub - badonnthedeer/AnthroTraits: A mod for Project Z...

mellow frigate
trim mist
#

Taking a look at my repo and the listed functions should help you out!

#

I listed them in order of implementation

#

and here's an example file. I listed it in the root of my mod folder

hasty horizon
trim mist
#

at the minimum, yeah. @mellow frigate would using DoParam('tag=sweet') append the tag or overwrite them?

trim mist
#

pog. good to know

mellow frigate
hasty horizon
#

is it because the bottle can be refilled or something?

mellow frigate
mellow frigate
hasty horizon
#

you said Base.PopBottle does not exist?

mellow frigate
#

I did. in lua there is no object called Base.PopBottle.

#

There is an item instance (of the java type Item) whose parameter "FullType" is "Base.PopBottle".

hasty horizon
# mellow frigate Base.PopBottle does not exist afayk. ```lua local scriptItem = getScriptManager(...

i c, so could i make a table, then do a for loop for the amount of items in that table, using the value at each position? idk how to write it in lua rn but in java something like:

String[] sweets = "chips", "chips2", "chips3";
scriptItem script; //assuming scriptItem can be used as the object for this example
for (int a = 0; a < sweets.length; a++) {
  if (sweets[a] != null) {
    script = getScriptmanager():getItem(sweets[a]); //however you would grab that equiv in java
    script:DoParam('Tag=Sweet');
  }
}
#

or could i just leave scriptItem as scriptItem = getScriptManager() then later do scriptItem:getItem?

mellow frigate
#

yes for the idea

#

But you are writing (mixed) Java code, and in your mod you will probably use lua instead

hasty horizon
#

ik i wrote it in a different language, i just know more java and i thought it would get my idea acrossed better

#

i was going to write the equivalence of it in lua

crystal oar
#

local trait = TraitFactory:getTrait(item) is giving me trouble, item is a string that has had leading and trailing spaces removed, but the debugger says i am passing two arguments to it

#

and it def doesn't like the code, throws an error when i boot it up

hasty horizon
#

have you printed out the item string to make sure its actually sending what you think its sending?

crystal oar
#

i was, let me do that again

#

looking for Nutritionist seems like that should find the trait right?

#

but instead i get ```java.lang.RuntimeException:
at se.krka.kahlua.integration.expose.MethodArguments.assertValid(MethodArguments.java:123)
at se.krka.kahlua.integration.expose.LuaJavaInvoker.call(LuaJavaInvoker.java:186)
at se.krka.kahlua.vm.KahluaThread.callJava(KahluaThread.java:182)
at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:1007)
at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163)
at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980)
at se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1812)
at se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:66)
at se.krka.kahlua.integration.LuaCaller.protectedCallVoid(LuaCaller.java:139)
at zombie.Lua.Event.trigger(Event.java:64)
at zombie.Lua.LuaEventManager.triggerEvent(LuaEventManager.java:65)
at zombie.gameStates.IngameState.enter(IngameState.java:737)
at zombie.gameStates.GameStateMachine.update(GameStateMachine.java:145)
at zombie.GameWindow.logic(GameWindow.java:298)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.GameWindow.frameStep(GameWindow.java:765)
at zombie.GameWindow.run_ez(GameWindow.java:681)
at zombie.GameWindow.mainThread(GameWindow.java:495)
at java.base/java.lang.Thread.run(Unknown Source)
LOG : General , 1688600999284> 0> -----------------------------------------
STACK TRACE

Callframe at: getTrait
function: DoctrineOnGameStart -- file: DoctrineForcer.lua line # 10 | MOD: Doctrine```

wet sandal
#

getTrait is static

#

call it via . instead of :

#

@crystal oar

crystal oar
#

thanks

wet sandal
#

Code coverage go brrrr

crystal oar
#

now player:getTraits():add(trait) is tripping me up, and again on nutritionist

wet sandal
#

Only notable oddity is that add does not take a trait object. It wants the name.

crystal oar
#

ah so i should pass item not trait

#

thanks for the help so far, i feel like we are making good progress on this

#

so it seems to not like traits with spaces in the name, Trait not found! Thick Blood Trait not found! Axe Man

hasty horizon
#
local sweets = {
    ["Base.PopBottle"] = TRUE,
    ["Base.Pop" ] = TRUE,
    ["Base.Pop2" ] = TRUE,
    ["Base.Pop3" ] = TRUE,
    ["Base.JuiceBox" ] = TRUE,
    ["Base.Cereal"] = TRUE,
    ["Base.Biscuit" ] = TRUE,
    ["Base.CakeBlackForest"]  = TRUE,
    ["Base.CakeStrawberryShortcake"] = TRUE,
}


local function addTags()
    local scriptItem = getScriptManger()
    local func
    for i=0, #sweets, 1 do
        func = sweets[i]
        if func then
            scriptItem:getItem(sweets[i]):DoParam('Tag=sweet')
        end
    end
end

does this function work the way i want it to? (apply the tag sweet to the item), i ran it in the game and the function is my most iffy part of it, with the other part being:

#
require('NPCs/MainCreationMethods')
local old_perform = ISEatFoodAction.perform

function ISEatFoodAction:perform(...)
    if self.character:HasTrait("SweetTooth") then
        if inventoryItem:hasTag('sweet') then
            print('oi')
        end
    end
    old_perform(self, ...)
end
#

heck thats taller than i meant, uh ill shorten that table

#

in game, it didn't seem to do anything, it didn't error however.

wet sandal
#

The format of the sweets table is incorrect for how you are looping

#

tables are key/value maps, the keys in your table are the item names, but your loop uses indexes

hasty horizon
#

also i seem to be wrong about it not erroring, i just didn't update my mod folder

wet sandal
#

Reformat sweets like this:

#
local sweets = {
    "Base.PopBottle",
    "Base.Pop",
    "Base.Pop2" ,
    "Base.Pop3" ,
    "Base.JuiceBox" ,
    "Base.Cereal",
    "Base.Biscuit" ,
    "Base.CakeBlackForest",
    "Base.CakeStrawberryShortcake",
}
#

Also, start your loop at 1, not 0

#

Lua be like that

hasty horizon
#

would i then have to change anything about the function addTags or the eat function besides the loop at 1?

wet sandal
#

I think it should be good with just those changes.

hasty horizon
#

aye aye captain, ill report back once i do those changes

crystal oar
#

any idea why my code doesn't like traits with spaces in the name? ```function DoctrineModDataLoaded()
local list = SandboxVars.Doctrine.DisabledPerks
if list then
for item in string.gmatch(list, "[^;]+") do
item = item:match("^%s*(.-)%s*$") -- Trim leading and trailing spaces
print("looking for ", item)
local trait = TraitFactory.getTrait(item)
if trait then
print("Disabling ", item)
trait:setRemoveInMP(true)
else
print("Trait not found! ", item)
end
end
end
end

Events.OnInitGlobalModData.Add(DoctrineModDataLoaded)```

#

it finds nutritionist fine, but for example axe man makes it sad

hasty horizon
#

i think in the code, axe man they format as one word?

crystal oar
#

oh no

#

i'll give that a shot

hasty horizon
#

Axe man is the visual trait name for UI's

crystal oar
#

i wonder if it's going to be fussy about the case

wet sandal
#

Wrote a test write quick

#

every single trait contains no whitesapce

#

EXCEPT

#

Out of Shape

crystal oar
#

😭

wet sandal
#

Will most definitely be fussy about the case

#

One sec, I'll export this list for you

hasty horizon
#

just skim through

#

(the expand wont show all the lines rip)

wet sandal
crystal oar
#

thanks

#

out of shape y u be so different form the rest?

#

fml lol

hasty horizon
#

out of shape is out of the shape of the other traits

wet sandal
#

and Very Underweight

hasty horizon
#

you can just test for out of shape/very underweight seperately, then do a generic case for the rest?

trim mist
#

@mellow frigate can I DM you a question about Moodle Framework?

wet sandal
#

I suck at reading regex, but I think the code is already handling everything fine. Looks like ; is the delimeter and only leading/trailing whitespace is getting removed.

hasty horizon
#

theres sites online that let you test regex on them if that helps

sleek hull
#

How does one get an instance of another class?

Specifically trying to get an instance of InventoryContainer.class in zombie.inventory.ItemContainer so I can use getItemsFromCategory(String str)

sleek hull
#

Lua

hasty horizon
wet sandal
#

I think you want ItemContainer, not InventoryContainer

#

ItemContainer is a inventory itself.
InventoryContainer is an InventoryItem with an associated ItemContainer, like a backpack

sleek hull
wet sandal
#

As for getting an instance of an inventory, what inventory are you looking to search?

#

i.e.
The player's inventory
A backpack
A nearby fridge

sleek hull
#

I'm more looking for a list/table/array of all clothing items, such as
local clothingArray = getItemsFromCategory("Clothing")

neon hedge
#

hey guys, where can i find vitamins model name? couldnt find it anywhere

wet sandal
#

Ah, that function is not for that. Its for searching an existing inventory by category.

sleek hull
#

Is there a function that would return all items categorized as "Clothing"?

If not how would I go about even sifting through the items to find those categorized as such?

wet sandal
#

There is a global getAllItems() which will return a list of every Item in the game.
I'd say search through that once on load and and save the results for later.

nimble yarrow
#

when code is in the... root of the lua file, they are ran when the game starts, or i guess, when you Reset Lua
(if that makes sense).

I want to use sandbox options, but that happens after the lua reset, so my code never gets to see my sandbox bools, etc.

I think I need to move my code out of the root, and into a function -- a function that's called when an Event happens, such as 'start game', or whatever that event is.

i'll look up all the info myself, but is this thought process correct?

wet sandal
# neon hedge hey guys, where can i find vitamins model name? couldnt find it anywhere
item PillsVitamins
    {
        DisplayCategory = FirstAid,
        FatigueChange    =    -2,
        Weight    =    0.2,
        UseDelta    =    0.1,
        Type    =    Drainable,
        UseWhileEquipped    =    FALSE,
        DisplayName    =    Vitamins,
        Icon    =    Vitamins,
        Tooltip = Tooltip_Vitamins,
        StaticModel = PillBottle,
        WorldStaticModel = Vitamins_Ground,
        Medical = TRUE,
    }

and

model Vitamins_Ground
    {
        mesh = WorldItems/Vitamins,
        scale = 0.4,
    }
hasty horizon
#

off topic, but when i do this line of code when i overwrite the ISEatFoodAction

print(self.item:getTags())

it seems to return that there is no tags the item has. is this the correct way of going about getting the tags? and is self.item:hasTag also correct? or do get and has have to be capitalized?

wet sandal
#

@hasty horizon
When do you call addTags()?

hasty horizon
#

i add it in with Events.OnGameBoot

wet sandal
#

I'm not familiar with how items tagging works. So I can't offer much else...

hasty horizon
#

and the lua file that the addTags is in is the first file in the Server folder, while the ISEatFoodAction overwrite is 3rd

wet sandal
#

@hasty horizon
The format for tags is actually:
Tags = BluePen;Pen;Pencil;RedPen;Write

#

From the Crayons item ^

hasty horizon
wet sandal
#
local function addTags()
    local scriptItem = getScriptManger()
    local func
    for i=0, #sweets, 1 do
        func = sweets[i]
        if func then
            local item = scriptItem:getItem(sweets[i])
            local existingTags = item:getTags()

            local newTagString = "Tags = sweets"
            for i = 0, existingTags:size() - 1 do
                local tag = existingTags:get(i)
                newTagString = newTagString .. ";" .. tag
            end

            item:DoParam(newTagString)
        end
    end
end

This might work?

novel barn
# sleek hull Is there a function that would return all items categorized as "Clothing"? If n...

Notloc already answered your question by suggesting getAllItems(), but I figured I'd share a snippet of my code since I've been doing literally this for the past few weeks anyway. This will build a list of all clothing items for you.

function getAllClothing()
    local all_items = getScriptManager():getAllItems()
    local clothing_list = {}
    print("getting all clothing:")
    print(all_items:size())
    for i = all_items:size() - 1, 0, -1 do
        local item = all_items:get(i)
        local item_type = tostring(item:getType())
        if item_type == "Clothing" then
            table.insert(clothing_list, item)
        end
    end
    for _,clothing in pairs(clothing_list) do
        local clothing_name = tostring(clothing:getName())
        print("clothing name is: " .. clothing_name)
    end
    return clothing_list
end
hasty horizon
wet sandal
#
function Tests.updateTags()
      local item = ScriptManager.instance:getItem("Base.Axe")

      local existingTags = item:getTags()

      local newTagString = "Tags = sweets"
      for i = 0, existingTags:size() - 1 do
          local tag = existingTags:get(i)
          newTagString = newTagString .. ";" .. tag
      end

      item:DoParam(newTagString)

      TestUtils.assert(item:getTags():contains("sweets"))

      local invItem = InventoryItemFactory.CreateItem("Base.Axe")
      
      TestUtils.assert(invItem:hasTag("sweets"))
      TestUtils.assert(invItem:hasTag("CutPlant"))
      TestUtils.assert(invItem:hasTag("ChopTree"))

      print(invItem:getTags():toString())
  end

This test is passing in my test framework

hasty horizon
#

so when im looping through the items in my list to add the sweet tag to, i would pass that string into this function to use for the item variables getItem?

#

or is your function just a proof of concept

wet sandal
#

The most recent code I posted is just to prove that the method works and retains the items original tags.

hasty horizon
wet sandal
#

@hasty horizon
sweet vs sweets

hasty horizon
#

goddammit

#

lets see if it works now lmao

wet sandal
#

Your code is failing when I test it, one sec

#

Ah!

#

getScriptManger -> getScriptManager

hasty horizon
#

yeah when i hopped in and ate 1/4th a chocolate bar it printed out [] twice that time

#

man, my typos are killing me

wet sandal
#

I highly recommend an IDE with Lua Language Server setup.

hasty horizon
#

i thought i did have it set up, i followed what Albion had here like, yesterday or the day before?

#

im using Intellij with the games lua library attached

#

and umbrella

wet sandal
#

Hmm, I use VS Code with Umbrella, the getScriptManager typo was underlined yellow for me

hasty horizon
#

weird

#

also another weird thing, the print("oi") is printing out []?

wet sandal
#

Nah, that would be the print(self.item:getTags())

#

[] is empty list

hasty horizon
#

no i removed the getTags print

#

when i had them both in , they both printed out []

wet sandal
#

You're hot reloading?

hasty horizon
#

i exitted out fully, then replaced the mod

wet sandal
#

Zero chance print('oi') prints []

hasty horizon
#

ik, but it seems to be. ill see if putting a print statement in another spot prints it out or if my game is cursed

#

my mod might be made on an ancient indian burial ground for all i know

#

well i have this now:

function ISEatFoodAction:perform(...)
    print("boop")
    if self.character:HasTrait("SweetTooth") then
        print("doop")
        if self.item:hasTag("sweets") then
            print("oi")
        end
    end
    old_perform(self, ...)
end
#

and it printed out [], then boop, then doop

#

so idk whats happening

wet sandal
#

what item you eating?

hasty horizon
#

chocolate

#

right below crisps4 in my list

#

i realized the Eat.lua i had was named Tatos instead of Taters, so i switched it to taters, and now the [] is gone, but it doesn't recognize that the lollipop has a sweets tag .-. (changing the name changed the order of files in the folder)

sleek hull
#

Now I just need to iterate through the clothingList and figure out a way to determine how 'comfy' each piece of clothing is, but that is a problem for another day

#

My best guess for that though is going to more or less just be "what material is it made from? (cloth/denim/leather/none)" and/or "where is it equipped (head/torso/feet/etc)"

wet sandal
#

I know invItem:getFullType() will give you Module.Name format.
If thats still something you need to work around.

#

Yea, heuristically assigning comfiness is a good start.
It will be hard to match hand crafted quality, but you support mod items this way.

sleek hull
#

I fixed that part, an InventoryItem objects getName() returns the display name, but an Item object returns it in Module.Base form by the look of it

sleek hull
#

For what Im doing at least, I think generically:

  • light clothes (tank tops/tshirts/shorts/underwear) being comfy
  • heavier clothing (anything leather) being pretty uncomfy
  • bags & footwear being very uncomfortable

will probably suit my needs, at least for now

hasty horizon
# wet sandal ```lua function Tests.updateTags() local item = ScriptManager.instance:get...

so i tried:

local item = ScriptManager.instance:getItem("Base.Chocolate")
    local existingTags = item:getTags()
    local newTagString = "Tags = sweets"
    for i = 0, existingTags:size() - 1 do
        local tag = existingTags:get(i)
        newTagString = newTagString .. ";" .. tag
    end
    item:DoParam(newTagSTring)
end

just ditching the list currently to try to get at least ONE item to work. unless im misunderstanding something, i got spirits in my code.

bronze yoke
#
local item = ScriptManager.instance:getItem("Base.Chocolate")
item:getTags():add("MyTag")
#

no need to use doparam or complicate things like this

bronze sand
#

Hi
I'm still a bit puzzled about this

#

The Pick Axe has a chance to kill zombies in a single hit, making it useful for close-quarters combat.

#

There doesn't seem to be anything special surrounding the Pick Axe's critical attack, is the "killing zombies in a single hit" just a result of it having a very high (or just high enough) Critical Multiplier or there is something else going on?

hasty horizon
# bronze yoke ```lua local item = ScriptManager.instance:getItem("Base.Chocolate") item:getTag...

so i put that in

function addTags()
    local item = ScriptManager.instance:getItem("Base.Chocolate")
    item:getTags():add("sweets")
end
Events.OnGameBoot.Add(addTags);

and heres my hook

function ISEatFoodAction:perform(...)
    print("boop")
    if self.character:HasTrait("SweetTooth") then
        print("doop")
        if self.item:hasTag("sweets") then
            print("oi")
        end
    end
    old_perform(self, ...)
end

when i get in game and eat some chocolate, it doesn't seem to get to the "oi" print statement. is self.item:hasTag not the correct way to do this?

bronze sand
# bronze sand There doesn't seem to be anything special surrounding the Pick Axe's critical at...
    {
        MaxRange    =    1.6,
        WeaponSprite    =    PickAxe,
        MinAngle    =    0.65,
        Type    =    Weapon,
        MinimumSwingTime    =    3.0,
        KnockBackOnNoDeath    =    TRUE,
        SwingAmountBeforeImpact    =    0.002,
        Categories    =    Axe,
        ConditionLowerChanceOneIn    =    20,
        Weight    =    3,
        SplatNumber    =    3,
        PushBackMod    =    0.3,
        SubCategory    =    Swinging,
        ConditionMax    =    13,
        MaxHitCount    =    2,
        DoorDamage    =    35,
        IdleAnim    =    Idle_Weapon2,
        SwingAnim    =    Bat,
        DisplayName    =    PickAxe,
        MinRange    =    0.61,
        SwingTime    =    3.0,
        HitAngleMod    =    -30,
        SplatSize    =    5,
        KnockdownMod    =    2,
        SplatBloodOnNoDeath    =    TRUE,
        Icon    =    PickAxe,
        RunAnim    =    Run_Weapon2,
        TwoHandWeapon = TRUE,
        BreakSound  =   BreakWoodItem,
        TreeDamage  =   35,
        MetalValue = 120,
        CriticalChance    =    25,
        CritDmgMultiplier = 9,
        MinDamage    =    1,
        MaxDamage    =    2.2,
        BaseSpeed = 0.8,
        DamageCategory = Slash,
        DamageMakeHole = TRUE,
        AttachmentType = BigBlade,
        Tags = DigPlow,
    }```
bronze yoke
hasty horizon
tawdry moss
wet sandal
hasty horizon
#

wait, big chance i might be dumb

#

im testing in a single player world

#

my script is in server-

bronze yoke
#

no, don't worry

#

server runs in singleplayer

hasty horizon
#

ok

bronze yoke
#

it even runs on the clients in multiplayer

#

if your script messes with timed actions, it should be moved to client though - timed actions are client and that one actually is client/singleplayer only, so it'll cause errors on the server

hasty horizon
#

ok good to know

bronze yoke
hasty horizon
bronze yoke
#

oh!!! it's in server right?

hasty horizon
#

ye

bronze yoke
#

the server folder is dumb, move it to shared

#

i forgot about this, the server folder doesn't load until you enter a game

#

which is after ongameboot fires

wet sandal
#

debugMode feature?

bronze yoke
#

maybe only in debug yeah

#

i was thinking it did that but when i tested it it didn't, but that was a while ago and i don't remember if i was specifically testing if it did that in debug or if it did that normally

wet sandal
#

I do specifically mean, entering, not leaving, the main menu.

hasty horizon
#

and the traits.lua is in server

bronze yoke
#

ongameboot is upon first reaching the main menu

#

it also fires after lua resets

hasty horizon
#

woo it fired the Oi finally

#

moving it to shared did work

#

but it strangely didn't print out to console either way, the addTag

bronze yoke
#

do you mean the in-game console or console.txt? the in-game console doesn't appear by the time that code runs

hasty horizon
#

how do i get to the console.txt?

bronze yoke
#

it's in your Zomboid folder

hasty horizon
#

ok it did print to that, good to know

#

thank ya again albion

bronze yoke
#

of course ^_^

hasty horizon
#

now to do the batch adding the tags i had before now

winter thunder
#

anyone have a simple guide on how to use the DoParam function?

bronze yoke
#
-- get the item object
local item = ScriptManager.instance:getItem("Module.ItemName")
-- set an item parameter exactly like you would in an item script
item:DoParam("Parameter = Value")
winter thunder
#

Can you change multiple parameters in the single function?

hasty horizon
#
local function addTags()
    local item
    for i=1, #sweets, 1 do
        item = ScriptManager.instance:getItem(sweets[i])
        item:getTags():add("sweets")
    end
end

the item:getTags():add() seems to be throwing me errors here. i looked at the console.txt after adding a print(sweets[i]) and it gets to crisps in my list before it goes and says "attempted index: getTags of non-table: null"

LOG  : General     , 1688616075451> Base.PopBottle
LOG  : General     , 1688616075451> Base.Pop
LOG  : General     , 1688616075451> Base.Pop2
LOG  : General     , 1688616075452> Base.Pop3
LOG  : General     , 1688616075452> Base.JuiceBox
LOG  : General     , 1688616075452> Base.Cereal
LOG  : General     , 1688616075452> Base.Biscuit
LOG  : General     , 1688616075452> Base.CakeBlackForest
LOG  : General     , 1688616075452> Base.LicoriceBlack
LOG  : General     , 1688616075452> Base.CakeSlice
LOG  : General     , 1688616075452> Base.Candycane
LOG  : General     , 1688616075452> Base.CakeCarrot
LOG  : General     , 1688616075452> Base.CakeCheesecake
LOG  : General     , 1688616075452> -------------------------------------------------------------
attempted index: getTags of non-table: null
#

did i mess up some syntax or not understand how lua loops?

bronze yoke
#

it didn't find an item for one of them

mellow frigate
bronze yoke
#

? isn't sweets a table

wet sandal
#

Yea it is

hasty horizon
#
local sweets = {
    "Base.PopBottle",
    "Base.Pop",
    "Base.Pop2",
    "Base.Pop3",
    "Base.JuiceBox",
    "Base.Cereal",
    "Base.Biscuit",
    "Base.CakeBlackForest",
    "Base.LicoriceBlack",
    "Base.CakeSlice",
    "Base.Candycane",
    "Base.CakeCarrot",
    "Base.CakeCheesecake",
    "Base.Crisps",
    "Base.Crisps2",
    "Base.Crisps3",
    "Base.Crisps4",
    "Base.Chocolate",
    "Base.Painauchocolat",
    "Base.CakeChocolate",
    "Base.ChocolateChips",
    "Base.CookiesChocolate",
    "Base.DoughnutChocolate",
    "Base.CinnamonRoll",
    "Base.CookieChocolateChip",
    "Base.Cupcake",
    "Base.DoughnutPlain",
    "Base.DoughnutFrosted",
    "Base.MuffinFruit",
    "Base.Icecream",
    "Base.ConeIcecream",
    "Base.Icing",
    "Base.DoughnutJelly",
    "Base.Lollipop",
    "Base.Marshmallows",
    "Base.MintCandy",
    "Base.Modjeska",
    "Base.CookiesOatmeal",
    "Base.Peppermint",
    "Base.CookieJelly",
    "Base.LicoriceRed",
    "Base.CakeRedVelvet",
    "Base.CookiesShortbread",
    "Base.Smore",
    "Base.CakeStrawberryShortcake",
}
bronze yoke
#

i recommend having a nil check in there just because items might get removed by TIS and you don't want that to break your mod, but in this case there's probably just a typo in one of your item names

hasty horizon
#

nil check would be smart, but i had copy pasted the ID's from the wiki is the strange thing

bronze yoke
#

if it's case sensitive, CakeCheesecake should be CakeCheeseCake

mellow frigate
#
local function addTags()
    local item
    for i=1, #sweets, 1 do
        item = ScriptManager.instance:getItem(sweets[i])
        if item then
            item:getTags():add("sweets")
        else
            print ('Unknown Item '..sweets[i])
        end
    end
end
bronze yoke
#

i've never run into a case difference so i don't know if it is

wet sandal
#

This is the incorrectt name

#

Base.CakeCheesecake

#

Its the only one

#

oh

#

Albion fastest gun in the west

bronze yoke
#

🤠

hasty horizon
#

it did turn out to be case sensitive

#

for the cake

#

i guess thats an edit for the wiki tho, they had that as the item id

#

now to tag up anything i think'll be relevant for features i plan to add

the features i plan to add you might ask?

idk. i didn't think i'd get this far.

#

what is the way to get the happiness/unhappiness an item gives? i tried doing self.item:getUnhappinessChange() but the console gave me an error

#

also related: how can i see the functions available to use on items like this, so i know what i can/can't get?

trim mist
#

okay, so, this is relating to an issue I'm having in a paid commission:

ZombRand(0,1) always seems to return 0. Is this because ZombRand is exclusive? I just want it to create a decimal

bronze yoke
#

the upper limit is exclusive, use zombrandfloat

trim mist
#

huh! the more you know.

bronze yoke
#

since lua isn't a typed language and tis don't use any annotations we don't really have an easy way of detecting these for the typing generator

hasty horizon
#

i put that in, and it still doesn't seem to want to kick in it seems

#

also when i was first learning java, i was annoyed by having to declare a type, but now with lua its the opposite for reasons like that it seems lmao

bronze yoke
#

when you've used a language that doesn't have it you understand why you have it

hasty horizon
#

are there any other ways to get the intellisense to kick in? when i put in the : the list that shows up is random stuff in the file like the https from the emmylua generated header, the else keyword, ect

#

with a pencil icon leading each entry

bronze yoke
#

it seemed to work for me

hasty horizon
#

maybe my umbrella isn't properly installed or something?

bronze yoke
#

Food is red and italic, that means it can't find the type

hasty horizon
#

hmm

bronze yoke
#

you should get this

hasty horizon
#

so i have the games lua file, and umbrella as libraries, and i use the emmylua plugin, am i missing anything?

bronze yoke
#

that should be right

#

to be sure, you've got umbrella down here?

hasty horizon
#

wait maybe the fact its in a zip

bronze yoke
#

the folders don't have >s, are they empty?

#

oh, did you download a zip from github? i'm not actually sure if that handles submodules correctly

hasty horizon
#

ye i downloaded it from github, its what showed up on google for me, did you download it a different way?

#

also wait what, the download i got from github, the candle, events and lua folders are empty 💀

#

i guess thats what you meant but not handling submodules

bronze yoke
#

so the way umbrella works is that it's just a collection of other projects that have their own github repos, and submodules let us do that and easily update them and stuff

#

i wrote events, jab wrote candle, and omar wrote lua

hasty horizon
#

so its a metaphorical umbrella of projects

#

i accept the pun

bronze yoke
#

exactly!

#

but it seems to have complicated installation more than we wanted

hasty horizon
#

could you three just make a joint github account then and just every time you commit to your own project, also commit to the umbrella?

bronze yoke
#

this is the way we use it

hasty horizon
#

i don't know too much about github, my own account i just use as a way to truck code between my desktop and laptop, when i click on code and go under Clone, do i just copy/paste the https link into the terminal or something in intellij?

wet sandal
#

Ok, do you have git?

#

I assume not?

#

And are you on Windows?

hasty horizon
#

i have git bash installed, and i am on windows

wet sandal
#

perfect

#

Open git bash where you want to put the Umbrella folder

#

run this command to get the files
git clone https://github.com/asledgehammer/Umbrella.git

hasty horizon
#

ok i got it opened there, ill do that

wet sandal
#

I assume you don't have ssh setup?

#

If you do, use this instead:
git clone git@github.com:asledgehammer/Umbrella.git

hasty horizon
#

well the first one was sent before i saw the second, but the search bar says i do have ssh

#

so now i do the step 6?

wet sandal
#

cd Umbrella

#

then step 6

hasty horizon
#

there we go! danke

bronze yoke
#

maybe we should investigate ways to make this a bit less manual

hasty horizon
#

maybe a script of some kind to automate it?

bronze yoke
#

i wonder if we could get a github action to make a release after every push

wet sandal
#

A release would be easier for people.

hasty horizon
#

i should probably make an effort to understand git/github more, i only really use push/pull myself

#

and commit

wet sandal
#

git goes insanely deep, but honestly, I only use a handul of commands on an average day:
git status
git add *
git commit -m "message"
git reset
git checkout branch-name
git checkout -b new-branch-name

novel barn
hasty horizon
hasty horizon
bronze yoke
#

intellij's git integration has covered everything i've needed to do

novel barn
hasty horizon
#

its like my cs teacher said, fully featured IDEs can be a bit of a crutch lmao

wet sandal
#

Return to monke (notepad)

bronze yoke
#

if it's not a crutch why use it

novel barn
hasty horizon
#

sorta offtopic but kinda on topic of crutches, i try very hard to not use chatGPT, the only times i've used it is "i got a coding question that my google skills can't seem to find an answer to, and i don't want ot be crucified on stack overflow"

#

ive had some very rude answers on SO

#

if i do get code from gpt, i rewrite it and get myself to understand it first

bronze yoke
#

i just google, and if google doesn't have the answer it's impossible

novel barn
#

I haven't tried chatGPT for code yet. I need to get around to it just to see what it spits out. Also I'm exclusively a lurker on SO for that reason. A few weeks ago I stumbled across two opposing answers to a simple question and one of them ended up creating a seperate post complaining about it... I'm here to fix my bugs, not deal with politics.

hasty horizon
#

like one project i had to dip into linear algebra and the wiki, the coding train video i got the idea from, and a commonly accepted java solution for it all had different formula

bronze yoke
#

stack overflow is pretty famous for that

novel barn
#

I recently saw a job posting that was asking for a stack overflow account link. I just noped out of that app.

bronze yoke
#

LOL

wet sandal
#

I've never posted on stack, too scary

hasty horizon
#

my account can't ask anymore questions on the main site because either my questions get ignored, removed, or don't get answers that solve the problem im having (this one is probably my bad when i explain, but still)

#

zomboid modding is my escape from this project though: https://github.com/Potat-OS1/lightsGPU. i was redoing my intro to java final, and feature crept to hell. i wanted a lighting system but my code was getting messy so i kept making different projects to try to keep my head on straight, to later on maybe add it as a library or something and this is the one attempt where the FPS isn't sub 10 on my desktop

#

it uses ray casting to get the hard shadow, then uses a few shaders to soften it

#

im procrastinating doing beam lights and cone lights

#

also the performance is still kinda bad? idk if im just not allocating resources correctly but on a 3060 and 12 core cpu it runs at 30~ fps at 900x900 res 💀

novel barn
#

That reminds me of how I play PZ on the road... My laptop isn't good enough to play at a decent framerate fullscreen so I play windowed mode. 💀

hasty horizon
#

r i p

novel barn
#

In Louisville I make the window even smaller...

hasty horizon
#

when i lived in a dormroom for a while i didn't bring my main monitor, and i thought my old pc was getting slow

my monitor i brought was 30hrtz, the main monitor i used before that was 60hrtz

#

when i would play MC i would get nausiated from quickly breaking/placing blocks because of how the refreshrate lined up with my fps

novel barn
#

I get a little motion sickness playing Rocket League when my framerate dips to like 40... so I completely understand.

hasty horizon
#

certain games its just a lil too rough playing sub 60

#

which is weird cause growing up id be like "oh heck ya 10 frames"

#

but now my pc can run this at 80-100~ frames

bronze yoke
#

i remember when 30 was the target...

hasty horizon
#

i need to get back to that mc world eventually, still haven't finished that base. that pic wasn't even recent it was back in december or something

novel barn
#

I was starting to write an AHK script that would automine a chunk at a time. I was getting into optical character recognition etc but I dropped it pretty quickly. Maybe I'll go back to that one day.

#

I quit because the OCR wasn't reliable enough to consistently tell me what block I was looking at

hasty horizon
#

for MC?

#

nowadays you could do some wild stuff with redstone that idk if a script like that would be prudent

#

you can make tunnel bores and just chug along with that, or world eaters

novel barn
#

yeah it was more of a challenge to see if I could do it in autohotkey

hasty horizon
#

fair fair

novel barn
#

wanted something for my portfolio

hasty horizon
#

maybe it would have a better time recognizing it if you had a torch in your offhand?

#

and used something like optifine to create light when you hold a torch

novel barn
#

I was reading from the debug screen so the text was always fully lit

hasty horizon
#

ah

novel barn
#

but the OCR couldn't 100% tell me that an 8 was an 8 and not a B

hasty horizon
#

maybe if you saved a section of the screen as an image, then filled anything that wasnt the color of the letters to black, so it would have a clearer image?

#

like use a threshold or whatever the operation is called

novel barn
#

maybe. But that's not tonight's problem. 🙃 tonights problem is filling all these duffel bags with dirt

hasty horizon
#

man discord gotta up its emoji game, brown square was the best i could come up with

novel barn
#

I actually have a PZ modding question to get this channel back on topic. I have the following code which breaks claiming __concat not defined for operands: item type is and Container

local item_type = item:getType()
print("item type is " .. item_type)

but it works when I do

print("item type is " .. tostring(item_type))

Why do I have to explicitly convert a string to a string for concat to succeed?

#

I've been just... avoiding this... for weeks but I'm curious why it behaves this way.

bronze yoke
#

is item an InventoryItem or an Item?

novel barn
#

I believe it's just an Item.

bronze yoke
novel barn
#

yep that one

bronze yoke
#

that's not a string

novel barn
#

I'm now seeing that but I can't determine what it IS.

bronze yoke
#

it's an Item.Type

hasty horizon
novel barn
#

oh I think I'm getting it now

#

The class has created its own type called Item.Type?

bronze yoke
#

you can use getTypeString if you need the string

#

Item.Type is just an enum of the possible types

novel barn
#

I know I'm in over my head when I have to google "what is an enum"

hasty horizon
#

simple, enums are enums.

#

enumsaid

novel barn
#

Ohhhh I get it now. 😂

#

I'll read up on this but thank you for clarifying!

hasty horizon
#

but ye ive used enums in the past to basically have more complicated primitive types, which i thiiiink is how you can use them? you can have methods inside em

#

cause enum comparison is less costly than string comparison

#

(at least what i was told)

novel barn
#

Once again I did a silly because I had assumed Item:getType would be the same type as InventoryItem:getType

bronze yoke
#

that one is frustrating

#

an InventoryItem's type is its Item's name

novel barn
#

But if IS were to refactor that they would probably break 95% of mods now. Or maybe that makes perfect sense to someone more experienced than me.

hasty horizon
#

so your saying that despite not playing league of legends, i cannot escape the spaghetti

novel barn
#

fun fact: printing several thousand lines of data to the console is likely to crash the game 👌

bronze yoke
#

prints are basically the slowest thing you can possibly do

novel barn
bronze yoke
#

yeah, as long as prints don't end up released it's fine

novel barn
#

this code specifically is to build the item list and will never be deployed as a mod. It turned out to produce 4000 lines so I'm glad I wrote tools to do it rather than doing it by hand.

bronze yoke
#

merging them all into one single print is surprisingly much much faster than printing multiple times

novel barn
#

Ohh sorry no my data isn't being printed. I was just printing along the way to debug. I'm using the filewriter to literally build the item file.

#

anyway my item builders have finally reached a point where I can start testing that everything works. Thanks, everyone, for always having an answer and being willing to share it! Good night all!

tawdry moss
#

you ever wish you could just smack someone through the first aid menu? im adding that ability :)

abstract raptor
#

Making a simple distributions maker.

autumn temple
#

@mellow frigate thanks again, I figured out my problem, I accidentally had an extra line that would set the value, so both lines kept trying to overwrite eachother, causing a endless loop of updates

rich void
#

Hey guys, anyone got any experience using the LineDrawer class? I'm trying to add some visual representations for a rectangle but having some difficulty calling addrect or drawrect?

here's kinda the function I'm trying to create, any help would be appreciated, also, I'm new here so henlo 😄 👋

function drawZoneBorder()
local x1, y1 = 10899, 10143 -- Top-left corner
local x2, y2 = 10943, 10112 -- Bottom-right corner

LineDrawer.addRect(x1, y1, x2, y2, 255, 0, 0, 255) -- Red rectangle
end

rich void
mellow frigate
# rich void Hey guys, anyone got any experience using the LineDrawer class? I'm trying to ad...

you need to convert from iso (world) to screen (display) ```lua
local x1Iso = 10899 --West
local y1Iso = 10143 --South
local x2Iso = 10943 --East
local y2Iso = 10112 --North
local player = getPlayer() --maybe use another player source if you have it at hand
local playerNum = player:getPlayerNum() --there are cases player will be nil and this will crash
local isoZ = getPlayer():getZ()
local x1 = isoToScreenX(playerNum, x1Iso, y1Iso, isoZ);
local y1 = isoToScreenY(playerNum, x1Iso, y1Iso, isoZ);
local x2 = isoToScreenX(playerNum, x2Iso, y2Iso, isoZ);
local y2 = isoToScreenY(playerNum, x2Iso, y2Iso, isoZ);

rich void
slow star
#

Hey everyone. Im a game asset artist and not much of a coder. Recent obsession has been zomboid and I wanted to contribute what i can to this game has taken over my spare time.
My specialty is unconventional out there rigging and animation but im decent at character creation
I wanted to make up some abomination style special infected with some unique animations. Kind of thinking left 4 dead special infected in regards to unique animations and different models and skeletons.

Trying to keep my post short. Is this possible? I have seen some asset swapping of zombies but animations look the same. Would I need to use a base zomboid character skeleton?

Second any one like the idea and willing to help insert these into the game? As mentioned. Not a coder. I can supply all the models and animations. Just need some one who knows what they are doing.

hollow lodge
#

can somebody give me a hand on spawning outfits on zombies?

#

both vanilla and mod items

mellow frigate
short urchin
#

Looking at making a comparability patch for AuthenticZ and some of the backpacks in Britas. Any recommended guides to help me get started?

trim mist
#

albion just wanted ask you about this really quick

#

about said same (paid) mod i've been asking about here and there

#
player:getBodyDamage():setFoodSicknessLevel(DirtinessSickness.getNewFoodSicknessValue(player));
#

This gets overwritten every frame. Not sure why. I'd really rather not poison players with this mod lmao

#

that's the only way i've made people sick successfully before

rich void
#

yo man, I'm pretty big noob but I'd suggest using the getter first for the player sickness level

local sickness = player:getBodyDamage():getFoodSicknessLevel();

you can then reference that in the setter

player:getBodyDamage():setFoodSicknessLevel(sickness + 0.1)

#

If u wanna be spicy you can use a temporary on-tick function to iterate the sickness level up an even smaller value on each tick but that may not be relevant at all in your case @trim mist hope this is helpful

bronze yoke
trim mist
#

oop sorry

trim mist
trim mist
#

when i assign it, it takes and prints correctly. Next time it runs it says 0

#

In my mind that means it's being overwritten like other sickness functions do

bronze yoke
#

if it's every hour, if it's not a *huge* amount of food sickness it's just going to fall back down

trim mist
#

i set it to .9

bronze yoke
#

food sickness is 0-100

trim mist
#

FFFFFFFFFFFFF

#

thank you

rich void
#

Kekw it's always something dumb eh

sour island
#

Some of the stats are 0-1 some are 0-100. Some are reversed.

#

Zombie HP is 0-200 😄

hollow lodge
#

how can I alternate between two or more pieces of cloth on an outfit?

#

<!--Metalworker-->
<m_MaleOutfits>
<m_Name>MG_Metalworker</m_Name>
<m_Guid>945a39c9-8c11-4eea-aece-7a4ef60dfc5d</m_Guid>
<m_Top>false</m_Top>
<m_Pants>false</m_Pants>
<m_AllowPantsHue>false</m_AllowPantsHue>
<m_AllowTopTint>false</m_AllowTopTint>
<m_AllowTShirtDecal>false</m_AllowTShirtDecal>
<m_AllowPantsHue>false</m_AllowPantsHue>

#

<m_items> <!-- Metalwelder Gloves Grey -->
<itemGUID>5e59171e-14b1-4a90-b050-2800da20f337</itemGUID>
</m_items>
<m_items> <!-- Metalwelder Gloves Orange-->
<itemGUID>8f058f89-cbae-418e-8a7a-02ee98edd2ff</itemGUID>
</m_items>

#

I tried using <probability>0.15</probability> but it didn't work

bronze yoke
#

🥳 🥳

slow star
sleek forum
#

i'm trying to create a really simple mod that adds a screwdriver as a valid can opener but it does not seem to load and I can't figure out why.

This is my mod structure:

~/Zomboid/mods/CanOpenerMod λ find . . ./poster2.png ./poster.png ./icon.png ./mod.info ./media ./media/lua ./media/lua/server ./media/lua/server/ExtraCanOpeners.lua ./poster3.png

ExtraCanOpeners.lua code:

Events.OnGameBoot.Add(function() Recipe.GetItemTypes.CanOpener = function(self, scriptItems) scriptItems:addAll(getScriptManager():getItemsTag("CanOpener")) addExistingItemType(scriptItems, "Screwdriver") end end)

It doesn't even show in the lua debugger as a script, but it is selected in the mod menu.
Anyone have a clue or direction?

#

the console.log does say that it loads it

bronze yoke
#

addExistingItemType is a local function, you can't call it from another file

sleek forum
#

ahh

#

it makes sense thanks

bronze yoke
#

on the client, the server folder only loads when you start loading into a game, which is after ongameboot

#

so code on that event will never run

sleek forum
#

good to know, got it working with some troubleshooting!

tawdry moss
#

how many ticks are in an in game day

bronze yoke
#

it varies

#

ticks aren't a set amount of time

abstract raptor
#

I've done it... now I must rest.

#

It's not pretty but it works

#

will modding senpai notice me now

abstract raptor
sleek forum
#

nice, would be cool if you can import too

abstract raptor
#

import what?

#

🤔

#

I could probably add that

abstract raptor
sleek forum
#

I'm assuming once you close and open the generator all your previous data is lost?
it would be nice if you could open the generated file so that all your previously set values are shown inside the generator again

bronze yoke
#

human readable numbers would be nice too

sleek forum
#

so that you can make adjustments, or add more or remove

bronze yoke
#

i'm not sure exactly what formula gets the actual spawnchance from the number you put in, but lootzed must know it

abstract raptor
#

I haven't yet cracked what's rare or more -- it seems in all containers the chance is much lower and usually a float -- where as on the procedural list the chance is an integer that ranges from 1 - 6 ish

abstract raptor
sleek forum
#

you could write the data in any format you'd like

bronze yoke
#

you can regex them back out, but i'd say just use a json

abstract raptor
#

Alright gonna make some improvements ; thanks for your suggestions! really!

#

I'm gonna add the ability to save and load and the ability to import items from a script

sleek forum
#

awesome 🙂

nimble yarrow
#

is ZombRand inclusive?
edit: or maybe that depends on if it returns an int or a double? i'll look around on the wiki

bronze yoke
#

if it's an int, the upper limit is exclusive

#

the lower limit is always inclusive

nimble yarrow
#

sounds good

#

can i tell lua, that my local is an int or float? or does it 'become' one of those two things, when assigned to something?

bronze yoke
#

it becomes one of those when it's passed to java

#

lua just considers all numbers of type 'number'

#

(internally of course they're still represented by java types but that's not really important)

nimble yarrow
#

Is there a better way to write this, or is this fine?

local waterMax = ZombRand(0,51)
waterDispenser:setAmount(ZombRand(0, waterMax));

local waterTainted = ZombRand(0,2)
if waterTainted == 0 then
  waterDispenser:setTainted(true);
else
  waterDispenser:setTainted(false);
end
#

(maybe 3 zombRand is not performant)

bronze yoke
#

what's the purpose of rolling twice for the setAmount? is waterMax going to be used somewhere else too?

nimble yarrow
#

oops, yeah, no reason.

bronze yoke
#

from what jab told me, ZombRand uses a needlessly high quality random number generator so it can be a little slow

#

stylistically i prefer ZombRand(51) when the lower limit is zero but i'm sure other people would prefer it the other way for consistency or clarity or something

naive goblet
#

If you really wanted to minimize ZombRand calls I suppose you could call it once as waterMax = ZombRand(101) and if >50, set tainted and amount = waterMax-51 … ?

nimble yarrow
#

ah, for sure.

bronze yoke
#

amount = waterMax % 51

#

that would save some repetition

nimble yarrow
#

yeah modulus could work, but that requires my neurons to fire for a second when i see that operator.
i was also checking to see if lua could use the ternary operator
waterTainted = 0 ? setTainted(true) : setTainted(false)
and it looks like you can, maybe like this: "condition and true or false"
but i'm new to lua, and not the greatest programmer, i'll just be verbose and write it all out plainly. with comments 😛

bronze yoke
#

that's right!

bronze yoke
nimble yarrow
#

for sure. like you said, its gonna be turned into javascript anyways lol

jaunty marten
nimble yarrow
#

waterDispenser:setTainted(ZombRand(0,2) == 0)
okay, so if ZombRand returns 0, the expression 0==0 is true, water will be tainted. else not tainted.
makes sense. i wouldnt have thought to replace a bool with a conditional statement that returns bools.
as i said, not the best engineer over here. thanks tho

jaunty marten
jaunty marten
# abstract raptor

he meant what when u exporting .lua file then u can import this file back to ur program

#

or import any other distribution .lua file

abstract raptor
#

people do distributions in all sorts of different ways

#

That probably wouldn't work if it's expecting a certain format

jaunty marten
#

if someone doing it by strange way - it's none of your business

abstract raptor
#

I could probably support opening a lua file that you've generated but

#

Not reading other distribution tables

jaunty marten
#

yea, at least u have to support reading .lua files that was generated by ur program

sleek forum
#

@abstract raptor that looks handy!

#

it would be ideal to read the same lua file, but this works too

abstract raptor
#

I'm working on getting it to parse a lua file as we speak

jaunty marten
#

@abstract raptor btw

#

u forgot to add scrollbar

tawdry solar
#

how would i make a gun bolt action

#

like this

nimble yarrow
#

3 hours ago you said "I've done it... now I must rest."
I take it you're done resting lol...

bronze yoke
#

nothing is ever done drunk

sleek forum
#

grouping in particular

jaunty marten
#

not all lua regular expressions can be represented by same way in other regular languages

bronze yoke
#

isn't it written in python though

nimble yarrow
bronze yoke
#

if it's local you can't

jaunty marten
bronze yoke
#

the tool they want to use regex for?

jaunty marten
#

idk

bronze yoke
#

i would be shocked if it was lua

jaunty marten
#

archive have no files with python*.dll so I think smth else but python

abstract raptor
#

guh i knew adding items from lua was gonna be a headache lol

bronze yoke
#

i thought i saw python source files in one of her videos, might be mixing something up

abstract raptor
#

at least it's not breaking everything

#

yeah I can't get it to parse this lua file

#

I feel like if you didn't save your just sol lol, I added saving so that's a thing.

naive goblet
#

are clothing items that you can wear in more than one way, like hoodies (up/down), represented as multiple items or something? i'm trying to modify the item properties to make an 'enchanted' item but it doesn't seem to work properly on things like hoodies because it's not registering on both the hood up and hood down

abstract raptor
#

just released the new version

naive goblet
#

and when i wear it either way, it reverts back to just "hoodie" whereas the "gloves of dexterity" are working fine

abstract raptor
#

I think this is a decent start

#

I also rearranged the window and made it scrollable

#

oh noooo ... import from script only adds the first item unhappy

#

fixed it

#

it's kinda hilarious when you import a vanilla item script, the print just shows you every single item

tawdry solar
#

anyone got code for a single shot bold action rigle

#

rifle

jaunty marten
jaunty marten
abstract raptor
#

Bleh. I will probably add it later.

hasty horizon
#

so weird error. it works, but it throws that error to the console. line 22 is the self.item:setUnhappyChange(original_happiness) line. eating multiple sweets shows it does revert to its previous value, and i tried a couple different sweets and they seemed to have their tag added

#

so basically: code doing what its supposed to, but threw error anyways

#

doesn't bring up the debug menu, but does have the red box int he corner

nimble yarrow
#

i have an idea. try this. i would be surprised if this doesn't fix it.

#
    if self.character:HasTrait("SweetTooth") then
        self.item:setUnhappyChange(original_happiness * 1.0)
    end
hasty horizon
#

i replaced 21-23 with that, (which you were correct line 22 is third from bottom) and this time it actually brought up the debug menu when it errored, though its not giving the full stack trace

nimble yarrow
#

well, the error was java.lang.illegalargumentexception, meaning 'original_happiness' was an inappropriate argument to be sending into the setUnhappyChange function.

(but the game didn't mind line 14 and 16... which is why I recommended the * 1.0)

hasty horizon
#

i figured it was when i got the error, but its strange how it was working despite being angry

nimble yarrow
#

is setUnhappyChange a default PZ function, or something you made?

hasty horizon
#

default

bronze yoke
#

lua functions can't have illegal arguments

nimble yarrow
#

maybe just modify the unhappiness directly, instead of using the base setUnhappyChange function?

heres how PepperCat does it in the DynamicTraits mod

function DTdecreaseUnhappyness(player, unhappyness)
    local currentUnhappyness = player:getBodyDamage():getUnhappynessLevel();
    player:getBodyDamage():setUnhappynessLevel(currentUnhappyness - unhappyness);
    if player:getBodyDamage():getUnhappynessLevel() < 0 then
        player:getBodyDamage():setUnhappynessLevel(0);
    end
end

these seem to use regular PZ methods
https://zomboid-javadoc.com/41.65/zombie/characters/BodyDamage/BodyDamage.html

hasty horizon
#

so i decided to print out the type, and it returned Nil. so what im going to assume is: because i declared what original_happiness is inside an if statement, Lua doesn't remember the variable when the if statement ends?

#

so ill try declaring it outside of it

#

and see if i still get the error

nimble yarrow
#

is the bottom if supposed to be an else? or... if not has trait?

nimble yarrow
#

but yeah, it looks liek the var was out of scope

hasty horizon
#

the bottom was supposed to be resetting the value back to normal after usage. var did seem to be out of scope cause its working now

jaunty marten
#

u can put local original_happiness before if statement and remove local on 12 line

#
function ISEatFoodAction:perform(...)
    local original_happiness
    if self.character:HasTrait("SweetTooth") then
        ---@type Food
        self.item = self.item
        original_happiness = self.item:getUnhappyChange()
        if self.item:hasTag("sweets") then
            self.item:setUnhappyChange(original_happiness * 1.2)
        else
            self.item:setUnhappyChange(original_happiness * .8)
        end
    end
    old_perform(self, ...)

    if self.character:HasTrait("SweetTooth") then
        self.item:setUnhappyChange(original_happiness)
    end
end
hasty horizon
#

its strange tho how it was reverting to its original value even though the variable was out of scope though

abstract raptor
hasty horizon
#

is there any functional difference between using self.character:whateverfunction and using getPlayer()? i was looking at the more simple traits mod and they tend to use local player = getPlayer(); then whenever they need something like if they have a trait, if their running, ect they use it on the player variable

#

if there isn't, i don't seem to know what type to use to get umbrella to give me the same functions as getPlayer()