#mod_development

1 messages · Page 207 of 1

agile vigil
#

addXPMultiplier is the method used by skillbooks to add their multipliers. It is destructive (e.g. if you add it after something else already did, you'll overwrite the old one) - this also means that the player could re-read a skill book to "ruin" your efforts.

I'll look at the traitMultiplier for you and see if I can find something.

limber summit
agile vigil
limber summit
agile vigil
# limber summit Yeah, that's what I was thinking about too. Like, a negative multiplier such tha...

Looks like you cannot modify the traitMultiplier.

if ((Integer)var12.getValue() == 0 && !this.isSkillExcludedFromSpeedReduction((PerkFactory.Perk)var12.getKey())) {
    var9 *= 0.25F;
} else if ((Integer)var12.getValue() == 1 && var12.getKey() == PerkFactory.Perks.Sprinting) {
    var9 = (float)((double)var9 * 1.25D);
} else if ((Integer)var12.getValue() == 1) {
    var9 = (float)((double)var9 * 1.0D);
} else if ((Integer)var12.getValue() == 2 && !this.isSkillExcludedFromSpeedIncrease((PerkFactory.Perk)var12.getKey())) {
    var9 = (float)((double)var9 * 1.33D);
} else if ((Integer)var12.getValue() >= 3 && !this.isSkillExcludedFromSpeedIncrease((PerkFactory.Perk)var12.getKey())) {
    var9 = (float)((double)var9 * 1.66D);
}
agile vigil
limber summit
agile vigil
fast galleon
#

Tiles need to be an exact size so you would need to convert the images for sure.

limber summit
agile vigil
limber summit
heady crystal
#

Why do vehicle alarms get set to false when you enter even though they're still triggering

#

🙄

sour island
heady crystal
#

There is

#

But it's false when you enter

#

So it's worthless

sour island
#

Cause it's no longer alarmed, but isAlarming should be a count down or something

heady crystal
#

That's wonky logic. It is alarmed if it is triggering

#

And I didn't find isAlarming

#

Only isAlarmed, which is a boolean, false when you enter

#

and triggerAlarm

#

Which isn't exactly what I'm looking for

#

I want to stop alarms

agile vigil
# heady crystal I want to stop alarms

Looking in the Java source it looks like two private fields are set to make the alarm go . The easiest way to stop the alarm is to remove all power from the battery.

The alarm is then checked in the next update() call.

So if you can hook into the update() function and set battery to 0, then back up to a positive value after, you'd be golden. Except.. There's no way to see if a car is currently blaring its sirens that I can see.

   public void triggerAlarm() {
      if (this.alarmed) {
         this.alarmed = false;
         this.alarmTime = Rand.Next(1500, 3000);
         this.alarmAccumulator = 0.0F;
      }
   }

   private void doAlarm() {
      if (this.alarmTime > 0) {
         if (this.getBatteryCharge() <= 0.0F) {
            if (this.soundHornOn) {
               this.onHornStop();
            }

            this.alarmTime = -1;
            return;
         }

         this.alarmAccumulator += GameTime.instance.getMultiplier() / 1.6F;
         if (this.alarmAccumulator >= (float)this.alarmTime) {
            this.onHornStop();
            this.setHeadlightsOn(false);
            this.alarmTime = -1;
            return;
         }

         int var1 = (int)this.alarmAccumulator / 20;
         if (!this.soundHornOn && var1 % 2 == 0) {
            this.onHornStart();
            this.setHeadlightsOn(true);
         }

         if (this.soundHornOn && var1 % 2 == 1) {
            this.onHornStop();
            this.setHeadlightsOn(false);
         }
      }

   }
#

this.alarmTime and this.alarmAccumulator are both private fields, so we don't have a way of reading those.

#

I suppose you could run the update() function once with 0 battery power as the user enters the car or clicks a UI button or whatever it is you want.

cedar kraken
#

Just wondering if anyone had an answer to this per chance?

icy fractal
#

Hello guys 👋 I am new to moding and I wanna learn create a simple mod for the PZ, pls if somebody can DM me, I will be grateful 🤓

torn igloo
#

Why does this have error despite the context still coming out?

        if Shop[k].name then
            tempName = " [" .. Shop[k].name .. "]"
        end

Is the debugger going crazy because of "shop" and "Shop"?

agile vigil
#

You are accessing .name here, what if Shop[k] doesn't exist?

torn igloo
#

It exist, that's why I said the context come out but it scream errors.

fast galleon
fast galleon
torn igloo
#
function: ShopContextMenu -- file: ShopContext.lua line # 34 | MOD: Shops Expanded
Callframe at: se.krka.kahlua.integration.expose.MultiLuaJavaInvoker@39630cf0
function: createMenu -- file: ISWorldObjectContextMenu.lua line # 489 | Vanilla
function: createMenu -- file: ISMenuContextWorld.lua line # 50 | Vanilla
function: createWorldMenu -- file: ISContextManager.lua line # 28 | Vanilla
function: doRClick -- file: ISObjectClickHandler.lua line # 60 | Vanilla
function: onObjectRightMouseButtonUp -- file: ISObjectClickHandler.lua line # 379 | Vanilla

ERROR: General     , 1701698380239> 25,943,847> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: attempted index: name of non-table: null at KahluaThread.tableget line:1689.
ERROR: General     , 1701698380239> 25,943,848> DebugLogStream.printException> Stack trace:
#
    for k,v in pairs(Shop.sprites) do
        local tempName = k
        if Shop.Shop1.name then
            tempName = " [" .. Shop[tostring(k)].name .. "]"
        end
        subShop:addOption(k .. tempName, worldobjects, Shop.addShop, playerNum, {v, k}) -- Expanded Modification
    end
#

My context menu shows the .name, so it very strange to have error

#

It seems to hate "k" even though the data come out without issue.

fast galleon
fast galleon
torn igloo
#

Like I have said, the tempName is filled thus is not nil as claimed.

torn igloo
#

If I hard code it with Shop.Shop1.name instead of Shop[k].name, there's no error.

agile vigil
torn igloo
#

You are right, what if Shop[k] didn't exist, I guess one of the shops indeed didn't exist. That fix it.

dry chasm
# torn igloo Like I have said, the tempName is filled thus is not nil as claimed.

Also to note, an error usually "breaks" out of such loops.
Meaning while it may add several entries, it may not add all of them due to the error.
For example 5 entries do get added, the 6th fails and 2 more are available, you'll be missing 3 in that case, most likely (depending on how code's called and all that)
So it may give the impression of actually "working", but only partially fills it

heady crystal
#

Is it not possible to fetch an item from the player's inventory server side?

deft star
#

Sorry, how do I make my 3D model lie on the ground?

errant sable
#

Anyone know of any mods that have custom UI's for anything? Trying to figure out how to display a custom interface

#

nvm, foudn one

foggy finch
#

hey, is there an Event type like event.isodoor(isopend) or something like that

#

in lua ofc

#

or like if the player press a kay on the keyboard run this?

cedar kraken
#

Tcherno :o

mellow frigate
heady crystal
#

Yeah it always returns nil

#

Aaaapparrently, cannot delete vehicle parts either

#

Not on MP

azure rivet
#

Hello, is there no way to make clothes emit lights?

errant sable
#

Anyone have any good resource on working with the UI, or a good mod to recommend to look at. I have looked at a few random ones, but they have not clarified to much.

cedar kraken
azure rivet
nova socket
#

Rate this UI kek

foggy finch
nova socket
#

I seen 7 first kek

foggy finch
nova socket
agile vigil
# nova socket sall good i was about to actually ask how to improve

Does the player already know what scrapping will give them?
What does repairing it cost?
What does it mean to fail a scrap attempt?

If these questions are already answered elsewhere, then I think the UI is just fine as-is. (I suppose you need/get the Weapon Part mentioned? But I'm having some trouble linking that to the repair and scrap buttons in my head only looking at the UI)

nova socket
#

I usually base my content on intuitive or pre-existing mechanics so people can dig into it quickly

#

Like repairing and scrapping weapons gives Gunsmith skill experience, leveling up makes you +% chance to do stuff.
its done everywhere else like that yadda yadda.

#

mechanics.. metalworking.

#

You can try it.

foggy finch
#

Nvm i found it on the wiki

foggy finch
#

litteraly what im reading

errant sable
#

Ok, can someone tell me where I am screwing up here. I have been banging my head against the wall far to long just trying to render some text in a window. I can display a panel, and other stuff, but the text is just killing me.

require "ISUI/ISUIElement"


CommWindow = ISUIElement:derive("CommWindow")

function CommWindow:initialise()
    ISUIElement.initialise(self)
end

function CommWindow:render()
    ISUIElement.render(self)

    -- Example text rendering
    local text = "Hello, World!"
    local x, y = 10, 10 -- Text position
    local r, g, b, a = 1, 1, 1, 1 -- Text color (white)
     local font = UIFont.Small -- Default small font

    self:DrawText(text, x, y, r, g, b, a, font)
end

function CommWindow:new(x, y, width, height)
    local o = ISUIElement.new(self, x, y, width, height)
    setmetatable(o, self)
    self.__index = self
    return o
end


Events.OnGameStart.Add(function()
    local myCommWindow = CommWindow:new(100, 100, 300, 200)
    myCommWindow:addToUIManager()  -- Assuming there is a method to add it to the UI manager

end)

it errors out on self:DrawText(text, x, y, r, g, b, a, font) when loading into the game....

foggy finch
errant sable
#

does lua not like x,y = 10, 10

foggy finch
#

i think its supposed to be like "x , y" = "10, 10"

rugged latch
foggy finch
errant sable
#
require "ISUI/ISUIElement"


CommWindow = ISUIElement:derive("CommWindow")

function CommWindow:initialise()
    ISUIElement.initialise(self)
end

function CommWindow:render()
    ISUIElement.render(self)

    -- Example text rendering
    local text = "Hello, World!"
    local x = 10
    local y = 10
    local r = 1
    local g = 1
    local b = 1
    local a = 1
    local font = UIFont.Small

    self:DrawText(text, x, y, r, g, b, a, font)
end

function CommWindow:new(x, y, width, height)
    local o = ISUIElement.new(self, x, y, width, height)
    setmetatable(o, self)
    self.__index = self
    return o
end


Events.OnGameStart.Add(function()
    local myCommWindow = CommWindow:new(100, 100, 300, 200)
    myCommWindow:addToUIManager()  -- Assuming there is a method to add it to the UI manager

end)

Well i just put them each on their own line, and I still get an error at self:DrawText(text, x, y, r, g, b, a, font)

foggy finch
#

okay...

#

maybe the font unless you cheked the wiki for that

errant sable
#

and why does spiffo keep waving at me and emojing my posts....

foggy finch
#

to let you know hes chekking it

#

i think

errant sable
#

Yeah the api page has UIFont.Small

#

Ive never had the equivelant of "Hello World" ever make me want to throw stuff at the wall before, in any language.

bronze yoke
errant sable
#

good to know, but still confounded as to the issue 😦

bronze yoke
#

what error are you getting?

errant sable
#

¯_(ツ)_/¯

#

Ill grab a screen shot, its erroring out in the game, and just showing that line

bronze yoke
errant sable
#

maybe im missing where it gives me more description

#

Unless im missing where it says it, it doesnt say what the problem is, jsut what line its on...

bronze yoke
#

nothing shows up in the error tab at the top left?

neon bronze
#

drawText

#

Not DrawText

errant sable
#

So, yup, that was it, drawText not DrawText

#

Also, yeah i found under one of the buttons it showed more, and was saying object tried to call nil... so I have learned something new today, and been reminded im a horrible typer and reviewer.

#

Has anyone setup any sort of intellisense for the api?

neon bronze
#

There is a community one i forgot who made it tho and the link

#

But there is one

tawdry carbon
#

i need helo installing mods
can anyone help

foggy finch
tawdry carbon
#

ill dm u

foggy finch
#

ok

#

too hard to help them

#

i was trying to help but they failed to use steam

hybrid crest
#

hey guys, a question: how to get the amount of days that passed since the start in game world?

sour island
#
getGameTime()
cedar kraken
patent holly
#

Hey, all. Wondering if anyone can help me out on this. I usually like to tinker and study until I figure it out, but I've hit a dead-end and my brain hurts lol. So I'm here, hat in hand, looking for some advice.

So, basically I'm making a spiritual successor to More Builds (with an emphasis on user customization options) and originally I had included the structure's health in the description on the context menu. "Wooden Structures have 600 health.<br>All structures receive a health bonus per level of Carpentry." obviously very easy if the structures have a predetermined health value...

But as I picked up how to integrate sandbox settings, I wanted to allow the user/admin to determine the health for themselves. I use an integer sandbox option, and everything works as intended... but I don't know how to make that integer value into text that the game can draw into a description... or if it's possible, for that matter.

For example, if the user decides wood has 212 hp, is it possible to have my description say "Wooden Structures have 212 health"? I imagine it would look something like "Wooden Structures have (SandboxVars.Compendium.WoodHealth) health" but the few things I've tried to pull that integer have been unsuccessful.

Or (given that I'd like to include this info in the description) should I just use an enumeration value and set up conditional descriptions for the option they choose (which I've done elsewhere)?

I'd really like for players in servers using the mod (who presumably didn't pick the health value) to have this info at their disposal without asking, so any help is appreciated.

verbal yew
patent holly
#

Ah, okay! Do you happen to know offhand how to make that correlate to a sandbox integer?

verbal yew
#

getText("IGUI_XP_readingspeed", yourSandboxVar)

patent holly
#

Sorry, just realized the first comment basically spelled it out lol. Long day. Thank you so much!

tawdry basin
#

Does anyone have some code I could use for getting my servers player count using the servers ip and port

gilded hawk
#

Something Big is coming either next year or end of this year 🙂

If this works, zomboid looting will never be the same

#

Very inspired by Minecraft ae2

thin bronze
#

I'm not able to see very well, what is happening

errant sable
#

anyone know how to use void DrawUVSliceTexture(Texture texture, double double1, double double2, double double3, double double4, Color color, double double5, double double6, double double7, double double8) ?

#

im assumin 4 of them are uv min and max (but is it in uv space, or pixel space?) and then there is a texture, and a color, and um... well a whole lot of other doubles i got no idea about

bronze yoke
#

public void DrawUVSliceTexture(Texture tex, double x, double y, double width, double height, Color col, double xStart, double yStart, double xEnd, double yEnd)

#

i recommend using the tis api site for this reason and not the community one

errant sable
#

Well thank you.... where did you find that so quickly?

bronze yoke
#

the tis site is technically one version behind but it's not largely relevant and the parameter names are huge

errant sable
#

Eggscellent!

#

Thank you

#

The real question is, do i set all my UI textures up as is in their files, or do I try to be efficent and set them up for nine-slice and tiling....

verbal yew
#

Guys, how to get current health from player?

#

mean like i have 40 from 100, how to get this 40?

bronze yoke
#

player:getBodyDamage():getOverallBodyHealth()

errant sable
bronze yoke
#

^u^

verbal yew
bronze yoke
#

use OnCanPerform

#

OnTest is for testing items

hidden jungle
#

Hey... so i'm having some issues debugging some errors from my mod.
what is Kahlua?
is that just base zomboid?

bronze yoke
#

kahlua is the java implementation of lua that zomboid uses

#

if you're getting a kahlua error it means you're using the language incorrectly in some way (and not e.g. a java method erroring out because of a bad argument)

hidden jungle
#

i'm completely lost.
its an error thats happening to a couple of people using my mod. i'll send it here.

#
function: MainUpdate -- file: LazoloMain.lua line # 3341 | MOD: Even More Traits

LOG  : General     , 1701758492838> 0> __mul not defined for operands in LazoloApplyGradualStatChanges
ERROR: General     , 1701758492838> 0> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: __mul not defined for operands in LazoloApplyGradualStatChanges at KahluaUtil.fail line:82.
ERROR: General     , 1701758492838> 0> DebugLogStream.printException> Stack trace:
java.lang.RuntimeException: __mul not defined for operands in LazoloApplyGradualStatChanges
    at se.krka.kahlua.vm.KahluaUtil.fail(KahluaUtil.java:82)
    at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:676)
    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:92)
    at zombie.characters.IsoPlayer.updateInternal2(IsoPlayer.java:2141)
    at zombie.characters.IsoPlayer.updateInternal1(IsoPlayer.java:1935)```
#

__mul not defined for operands??

#

it doesnt happen to me or the majority of people but its causing this person's game to essentially softlock his characters endurance because of what the code is supposed to do

bronze yoke
#

most likely something is nil

#

__mul not defined for operands means you're multiplying two things that can't be multiplied together

hidden jungle
#

ok that helps actually.
if i'm not mistaken if two mods have the same function name one of them will override the other right?

bronze yoke
#

if they are global yeah

hidden jungle
#

ok thats probably whats happening.
i have a function in my script caled Dir() which is just math.dir.
there's probably another mod that has Dir as a function that is overriding my mod

#

thats the only thing on that line that could be nil

#

is if the function returns nil

bronze yoke
#

you mentioned endurance, there seems to be a lot of mystery cases of endurance becoming nan

#

that could cause issues if you're interacting with that on that line

hidden jungle
#

the wierd thing is its not the endurance value.
its a custom value in the character's mod data that i use for gradual stat changes

#

in this instance the error is happening on PlayerData.StressChange

#

its litteraly just a line for getting the absolute value of PlayerData.StressChange for some math later in the script

bronze yoke
#

hmm yeah not much else could be going wrong

hidden jungle
#

i'm changing the funciton name and i'll push the update to him and see if that fixes it.
Dir() isn't particularly unique so its probably just getting overridden

bronze yoke
#

i'd just make dir local, it's not like other mods are gonna want to mess with it anyway

hidden jungle
#

is each lua file its own scope?

bronze yoke
#

yeah

hidden jungle
#

i was under the impression that all the lua files merged

#

oh that changes a lot of how i think about modding

bronze yoke
#

imo creating new globals is always bad and everything should always be local

hidden jungle
#

funny thing, i only recently learned that functions can be local.
almost all of my variables are local for that exact reason.

bronze yoke
#

i've been meaning to finish a resource about modules to try and get people using locals

#

functions are just variables, in lua there is rarely any special handling of types

verbal yew
# bronze yoke OnTest is for testing items
function LabRecipes_AddDirtyVials_ChmExtractLeukocytesFromBloodCells(items, result, player)    -- OnCreate
    for i = 0, items:size()-1 do
        local item = items:get(i);
        if item:getType() == "CmpFlaskWithBloodCells" then
            result:getModData().IsHaveAntibodies = item:getModData().IsHaveAntibodies()
            result:setName(result:getName().." (Infected)");
        end
    end
    LabRecipes_AddDirtyVials(items, result, player);
end

can i change result item name like this?

bronze yoke
#

yes

verbal yew
#

noice

#

thanks

bronze yoke
#

you might need to setCustomName(true) to make the name save

verbal yew
# bronze yoke you might need to setCustomName(true) to make the name save
function LabRecipes_zReTakeBloodForNextWork_OnCreate(items, result, player)        -- OnCreate
    result:getModData().IsHaveAntibodies = player:getBodyDamage():isInfected();
    player:getBodyDamage():ReduceGeneralHealth(12);
end

it's can be multi like:

result:getModData().IsHaveAntibodies = player:getBodyDamage():isInfected() or player:HasTrait("zReAntibodies")
#

?

bronze yoke
#

yeah

verbal yew
#
-- Plasma and Blood Cells
function LabRecipes_AddMoreBloodComponents_ChmDivideBloodIntoComponents(items, result, player)    -- OnCreate
    for i = 0, items:size()-1 do
        local item = items:get(i);
        if item:getType() == "CmpSyringeWithBlood" or "CmpSyringeReusableWithBlood" then
            if item:getModData().zReIsAntibodies() then
                result:getModData().zReIsAntibodies = item:getModData().zReIsAntibodies()
                result:setName(result:getName().." (Antibodied)");
             elseif item:getModData().zReIsInfected() then
                result:getModData().zReIsInfected = item:getModData().zReIsInfected()
                result:setName(result:getName().." (Infected)");
             else
                result:setName(result:getName().." (Normal)");
            end
        end
    end
    player:getInventory():AddItem("LabItems.CmpFlaskWithBloodPlasma");
    LabRecipes_AddDirtyVials(items, result, player);
end
-- Leukocytes
function LabRecipes_AddDirtyVials_ChmExtractLeukocytesFromBloodCells(items, result, player)    -- OnCreate
    for i = 0, items:size()-1 do
        local item = items:get(i);
        if item:getType() == "CmpFlaskWithBloodCells" then
            if item:getModData().zReIsAntibodies() then
                result:getModData().zReIsAntibodies = item:getModData().zReIsAntibodies()
                result:setName(result:getName().." (Antibodied)");
             elseif item:getModData().zReIsInfected() then
                result:getModData().zReIsInfected = item:getModData().zReIsInfected()
                result:setName(result:getName().." (Infected)");
             else
                result:setName(result:getName().." (Normal)");
            end
        end
    end
    LabRecipes_AddDirtyVials(items, result, player);
end
#
-- Antibodies
function LabRecipes_AddDirtyVials_ChmExtractAntibodiesFromLeukocytes(items, result, player)    -- OnCreate
    for i = 0, items:size()-1 do
        local item = items:get(i);
        if item:getType() == "CmpFlaskWithLeukocytes" then
            if item:getModData().zReIsAntibodies() then  -- Antibodied
                player:getInventory():AddItem("LabItems.CmpTestTubeWithAntibodies");
             elseif item:getModData().zReIsInfected() then  -- Infected
                if 90 > ZombRand(100) then
                    player:getInventory():AddItem("LabItems.CmpTestTubeWithAntibodies")
                else                                          -- Normal
                    player:getInventory():AddItem("LabItems.LabTestTubeDirty")
                end
             else
                if 15 > ZombRand(100) then
                    player:getInventory():AddItem("LabItems.CmpTestTubeWithAntibodies")
                else
                    player:getInventory():AddItem("LabItems.LabTestTubeDirty")
                end
            end
        end
    end
    LabRecipes_AddDirtyVials(items, result, player);
end
#

shitcoding xD

#

i hope transfer ModData from item to item working normal

terse merlin
#

hey peeps, does anyone know if anyone is working on a mod to live ping places? kinda like Call of duty these days?

quick cape
#

im curious how peeps here test their mods
how ya do it?

terse merlin
#

trial and error, i got time to waste XD

random finch
#

Anyone know how often weight it calculated? It seems to be on Update() but I always thought weight calculations were done daily. Not constant.

quick cape
#

i wonder
how does the barbed wire fence work codewise? doe zombies get hurt by barbed wire? do players and zombies receive damage the same way?

terse merlin
terse merlin
vague marsh
terse merlin
vague marsh
#

cpe haha

#

this is me most of the time

gilded hawk
#

Is there an event triggered when an Item has been moved inside or outside of a container?

neon bronze
#

You could hook into the inventory transfer action

#

But i dont think there is an event for that

gilded hawk
#

Oh well, I'm already doing that, too bad, thank you anyway

terse merlin
cedar kraken
#

Is it possible to make it so that the player is forced to walk somewhere and can’t interact in a way to interrupt the walking?

#

Like the player is forced to walk to a random location within 20 tiles and you can’t do anything until they get to their destination

cedar kraken
gilded hawk
#

Is there a way to detect or find a specific IsoObject or tile? I like, how can I search for all the campfire placed/close to my player?

neon bronze
#

Iter over all tiles in a radius around a player sadly

gilded hawk
#

Oh god 😦

#

That's going to kill performance so much

neon bronze
#

Have one tile radius!

gilded hawk
#

lol, sadly I need to find that tile in an entire building 😦

#

Do you know what this does? MapObjects.OnNewWithSprite?

neon bronze
#

Sadly no

#

But if you need a campfire found it may have some other methods since its not exactly a sprite

gilded hawk
#

Yeah I'm actually looking into that 😄

#

I Wonder if I can find how the game updates the campfires, maybe the game has a smart way of checking for specific tiles 🤔

cedar kraken
#

I had this question a few days ago but I can't recall if anyone answered it (I don't think anyone did)

Does anyone know how to create new areas where you can attach weapon mods on guns?

#

I can elaborate if needed

gilded hawk
bronze yoke
#

for most other objects you will not be able to do this

cedar kraken
#

I don't really need to figure out the actual texture and modeling part currently. For example, if you wanted to add an Underbarrel or Grip attachment slot, what would need to be done to do so? I've tried a lot but can't seem to get it to work (to be fair this was a few months ago when I tried to do this)

gilded hawk
gilded hawk
bronze yoke
#

yes, there's also a client side of it but it doesn't do much

gilded hawk
#

Great, thank you

gilded hawk
bronze yoke
#

yes, you can use that to get them by index

gilded hawk
#

Damn, it works 😮

bronze yoke
#

keep in mind that at any given time most of the objects in the system are probably unloaded so if you want to do something to the java object you need to check that

#

unless your range check guarantees it already

gilded hawk
#

Okay, thank you.

I just noticed that neither OnNewWithSprite or OnLoadWithSprite is fired when I manually place my tile, using the place item context menu

#

So, I assume that these only trigger when a new square is freshly loaded

bronze yoke
#

yeah, it's for catching specific sprites loading in, they can catch them being created in other ways

gilded hawk
#

Ah, too bad, then I need a way to manually track when this item is placed

cedar kraken
#

Is there a way to make it so you can load a revolver in one go?

#

Instead of needing to do each bullet and individually, you could just go to put the first one in and have it automatically fill them all?

#

Since I'm trying to go about this in a way that doesn't simply increase the reload speed

drifting ore
#

are you describing a speedloader?

cedar kraken
#

Correct

#

A moon clip

#

For a gun attachment mod

#

These three things

#

I'm in a bind trying to figure out how to create an entirely new attachment location for weapon modifications though 😕

#

I might go back to tinkering around on Notepad++ for now, I feel bad asking these really open-ended questions

#

Sorry about that

bronze yoke
#

i don't think there's a standard way to do this, but reloading is a timed action so you can mess with it as much as you want

drifting ore
#

someone apparently tried to make one in 2018 when they were still WIP and it completely crashed the game

cedar kraken
#

Yikes

#

Question about mod development for the more experienced people here:

How do you pick which project to tackle?
Is it better to just pick one and stick with it, or to juggle a few at once?

drifting ore
#

never juggle a few

#

you will never get anything done

gilded hawk
#

As a modder, I always suggest to start small, with one project that is doable

bronze yoke
#

i just do whatever my autism decides is really interesting right now

cedar kraken
#

I have around 6 projects, but I'm having a hard time with getting started on them. Some of them seem to be much more advanced whilst others seem more doable, yet I still struggle to get it done

drifting ore
cedar kraken
#

I write out all the stuff I need in documents, since they can also be used to communicate information to people getting the mod, but getting past that initial planning phase is... tricky

gilded hawk
cedar kraken
#

No idea where to get started on them

cedar kraken
drifting ore
#

personally I'd just stick with one you're interested in

#

the most

cedar kraken
#

The one I'm interested in the most is my ultimate project, but it's essentially the size of an entire new build

#

I have a vague idea of where to start with that one

drifting ore
#

when I was a fangame writer a reason why it stopped working was primarily because everyone had multiple tasks to write things instead of picking something specific to write (like people being designated for specific areas)

overloading yourself with work is never a good idea because especially if you're like me and ADHD, it's incredibly hard to focus or have time for something larger whenever you get to it.

cedar kraken
#

But I have 36 word documents, over half of them empty since I haven't gotten around to writing stuff down in them, all of which detail the various mechanics and things in the mod

drifting ore
#

pick the small one then work up from there personally.

cedar kraken
#

So... the mod that adds new boots and rebalances all of the other ones

#

It adds two new ones (Cowboy Boots, Military Tundra Boots) and adds more variety to all other boots at the same time

drifting ore
#

ya that'd be a good starting point

cedar kraken
#

The only other mod I've made before is a Barbed Wire Baseball bat mod

#

I don't even think I've uploaded it :/

#

I've made a lot of mod edits though

#

To the degree that a lot of them are half the original mod, half an alternate version of that mod

#

I've got to admit that finding motivation to jump back into the onerous hellgrind that is coding, is an extraordinarily difficult task lol

velvet pulsar
#

I don't find the actual writing of code that hellish, but figuring out how to interact with the barely-documented zomboid API is usually what stops me from getting anything done

cedar kraken
#

Yeah

gilded hawk
#

How can I allow a tile to rotate, but not to be picked up?

velvet pulsar
#

is there really no event for when a zombie thumps something?

rich void
#

Real artifact hunting inc.

velvet pulsar
#

ah. hrm, maybe OnObjectCollide with extra checks

#

now I forget why I was trying to find that

rich void
#

local function OnObjectCollide(character, door,IsoGridSquare,IsoThumpable,IsoWindow,IsoZombie)
-- Your code here
end

Events.OnObjectCollide.Add(OnObjectCollide)

#

Looks good!

#

Passes through the zombie object automatically, very pog

bronze yoke
#

you might have gotten confused somewhere, OnObjectCollide only passes two parameters

bronze yoke
#

yes, but also looks like a bug with how it generates the code

rich void
#

Yikes 🤧

bronze yoke
#

it seems to generate multiple parameters when one parameter has multiple types

rich void
#

I guess character and zombie are gonna be the same variable then

#

and door, gridsquare, thumpable, window?

bronze yoke
#

it returns the IsoMovingObject that is colliding into another object, and the IsoObject that it is colliding into

#

it can be any subclass of these, except some subclasses of IsoMovingObject might intentionally overwrite the function that fires the event

velvet pulsar
#

sighs.

rich void
#

Makes sense

velvet pulsar
#

'type' is overloaded heavily for this one

#

I forget what I was trying to do anyway

bronze yoke
#

oh i see what happens

#

it just uses the type for the name of parameters, and they represented multiple types as just a string with commas in it...

#

wish i'd thought to give parameters descriptions too, probably will have to go back and do that eventually

cedar kraken
#

Am I an idiot for not understanding exactly everything that’s being said in this conversation lol? I’m trying to follow to learn more but I get pretty lost 😅

#

(Sorry to interrupt by the way)

drifting ore
#

as a non modder it looks like gibberish to me lmao

velvet pulsar
#

enh, the lack of decent entry points into understanding this doesn't make anybody an idiot for not

#

I guess the upside to all of this is that my idea is probably technically possible, but if this is what it's going to take to solve the simplest part of it, dunno if I'd have the fortitude to actually finish it.

bronze yoke
#

i'm honestly unsure if thumping would fire the event

velvet pulsar
#

yeah. but actually if it fires because a zombie ran into a thing, that's good enough. I was thinking of thumping as the context, but it doesn't need to be. if it fires because you hit a zombie and it got knocked back into an object, that'd be even more realistic.

drifting ore
velvet pulsar
#

there could be a more precise event happening in java, responsible for that server console output, but not a binding that passes that version of the event to the lua side

drifting ore
#

also: would it be possible to make an effect that instantly kills the player if they're outside without clothing on? I was talking with someone a bit ago and was reading through the comments, and someone brought up they'd like a mod about a fun SCP thing where essentially sunlight kills 99% of humanity in 24 hours.

https://www.reddit.com/r/projectzomboid/s/P7QWpn995b

It sounds like a fun idea and I wonder if it would be even possible to do.

Reddit

Explore this conversation and more from the projectzomboid community

#

I know there's a few mods I think that add custom weather esk things but I don't know how abundant those are.

bronze yoke
#

yeah, you can just check every so often if the player is outdoors, if they're not wearing clothing then kill them

velvet pulsar
#

yeah, there's even the radiated zones mod that does some of that but more detailed

drifting ore
#

also making the sky and night light red to make the mod accurate to the story.

personally I have 50$ and would be down to pay someone for it, sounds like a really fun idea that could be expanded on.

drifting ore
#

Mildly cu

#

Curious*

velvet pulsar
#

well, for instance the 'official' API docs are just autogenerated javadocs with little-to-no explanation of the when, why or how of any of it

#

there's some community efforts to add some human words, like the pzwiki project or the umbrella intellisense, er, plugin? I dunno, I don't use intellisense. by comparison, by day I am a python dev, used to the frameworks I write code for being something more like Django's documentation site.

#

I get why it is this way and it's far from uncommon when it comes to modding games

bronze yoke
#

it's not exactly a plugin, we generate 'typing' files that standard lua plugins can interpret for intellisense

velvet pulsar
#

yeah, python has something kinda equivalent, where you can provide type hinting for a project that doesn't have it. but it's a language feature, not something specifically for one particular editor

bronze yoke
#

it's not a language feature but it's also not editor specific, the annotation format it uses is a common standard, just not part of the langauge itself

#

i use it with intellij's emmylua plugin, most people will be using it with luacats for vscode

velvet pulsar
#

ah. yeah, I got about as far as the umbrella setup seeming to assume the use of vscode and figured I'd just read the bindings myself. definitions? declarations. whichever. 'typings'

mellow frigate
# drifting ore also making the sky and night light red to make the mod accurate to the story. ...

you could easily do it using a red/transparent mask the same way immersive overlay and their duplicates mod works: https://steamcommunity.com/workshop/browse/?appid=108600&searchtext=overlay&childpublishedfileid=0&browsesort=textsearch&section=

Project Zomboid Spiffo's Workshop Welcome to Spiffo's Workshop, the place to find Project Zomboid mods, maps, buildings, and other things to tinker with. For our Modding Policy, click the "Learn More" Button below. Learn More

agile vigil
bronze yoke
#

you're not meant to read them, they're just meant to provide type hints

#

personally i feel the same way about the lua docs though, it interferes with the view declaration shortcut when browsing the vanilla lua

agile vigil
#

I wonder how I should set up IntelliJ to ensure "Find references" doesn't end me up in a faux-source file, then.

#

For now, I just enabled only the Java-generated Lua classes and the Event type hints, and used pzdoc for the rest - it's probably the best solution, but I wonder if I'm losing out on some type hints in the vanilla files from Umbrella.

#

(By Java-generated, I mean the Candle library)

bronze yoke
#

the lua typings aren't as great as the java ones anyway since you can't really automate that much from lua since it's not a typed language to begin with

agile vigil
#

The lua typings at least give you a heads-up of types expected and returned when you do the function call. I find it more helpful than the fully vague vanilla equivalent 😄

#

Also, is there an up-to-date tool for decompiling the Java source? I tried using the PZ-Libraries project as usual the other day, and I was unable to get it to work.

I'm still running on decompiled source I have from.. I dunno, August last year, probably.

bronze yoke
#

i like beautiful-java more

agile vigil
#

Oh that does seem very lovely.

#

I'll give this a shot tomorrow after work.

bronze yoke
#

it doesn't do too much but it renames variables by their types which is a little easier to read, and it doesn't explode on newer versions of intellij

#

the setup is still a little complex (at least if you're on windows) but not as crazy as capsid was

agile vigil
#

Both great benefits.

#

And it doesn't seem to require anything unusual to run. Just a bash interpreter and a text editor - the instructions are just a little obtuse imo 😄

bronze yoke
#

yeah, if you're familiar with those tools it should be smooth sailing

agile vigil
#

My first work environments were bash based, so I'm like a goldfish on land whenever anyone asks me to run PowerShell. I'm glad to see a bash script 😄

velvet pulsar
#

heh. I feel that way whenever I have to develop something on Windows.

#

fortunately it is entirely unnecessary for PZ

gilded hawk
#

Does anyone know why even by doing object:setSprite(spriteName) the object:getSprite():getProperties() are not updating with the values of the new sprite?

gilded hawk
#

Okay so, I almost figured it out, but the tile is spawning with the wrong properties

#
---@param object IsoObject
function LootManagerWorldMenu:toggleLootManager(object)
  local spriteName = self:getOppositeStateSpriteName(object:getSprite():getName())
  -- object:setSprite(spriteName) -- this only changes the square tile estetics, not the actual object, good to know
  local square = object:getSquare() 
  square:transmitRemoveItemFromSquare(object)

  local newObject = IsoObject.new(square, spriteName)
  newObject:transmitCompleteItemToServer();
  square:AddTileObject(newObject)
end

how, the F does the brush tool spawn this stuff 🤔

gilded hawk
#

Oookay, so doing this, just works? O.o why, whyyyyyyyy O.o

local spriteName = self:getOppositeStateSpriteName(object:getSprite():getName())
  -- object:setSprite(spriteName) -- this only changes the square tile estetics, not the actual object, good to know
  local square = object:getSquare() 
  square:transmitRemoveItemFromSquare(object)

  local tileCursor = ISBrushToolTileCursor:new(spriteName, spriteName, character)

  tileCursor:tryBuild(square:getX(),square:getY(), square:getZ())
#

Even this just works O.o

ISBrushToolTileCursor:create(square:getX(),square:getY(), square:getZ(), nil, spriteName)
#

But doing this does not work 😐 local newObject = IsoObject.new(square, spriteName)

WHYYYYYYYY

#

Oh, that's because of the placeMoveableInternal

#

🤔

#

Damn

#

Nope, nope, nope i'm not digging more than necessary, ISBrushToolTileCursor:create(square:getX(),square:getY(), square:getZ(), nil, spriteName) is good enough for me, for now at least

drifting ore
#

small tip

#

your programming doesn't have to be perfect, it just has to work.

stray willow
#

What would I need to do... to make a container that can only hold a specific item category or type in it

#

Like a toolbelt to hold 'tools' and you can't place like items outside of the category in it.

tawdry basin
#

Just a really quick question how can I see the commands that were sent to rcon

stray willow
#

Like im wanting to make a container that only car parts could fit in

#

So things with like the mechanics category

errant sable
#

how do you / can you get the current width and height of screen ?

winter thunder
#

@stray willow I can do this for you

#

Actually just learned myself, its baked into the base game code now

winter thunder
stray willow
#

SHortly yes

#

very short

#

like less then

winter thunder
#

Just so I know I am not doing something dumb... What is the method for changing an items mod data again? lmao

bronze yoke
#

item:getModData().foo = bar

quick cape
#

situation is foobar
sorry, i saw that and had to make the joke

#

also
i wonder if one could combine the functionality of a watch, CD player and portable radio into one item

like a salvaged together pip boy

next vine
#

i do have a newbie question when adding a new item in the game.
in scripts folder i have the txt with Icon =SCPaper,
in textures folder there is an icon with the name Item_SCPaper.png
why doesnt it show ingame the icon ?

tribal gull
#

Missing space after equals sign? I don't know if that's the actual reason, but that's how it's usually formatted.

errant sable
#

Is there a multi-line text editor UI component? I can't seem to find one... or am i missing a setting on something?

#

or even on that isnt multi line but does line wrap in a text area (as an input).

neon bronze
#

there is a text box

gilded hawk
#

You can set in the item.txt the AcceptItemFunction and this way you will be able to set it to what you want 😄

open river
#

Gentlemen, could you give me some advice? I finished my first mod and wanted to add it to the steam workshop, but bad luck, did I understand correctly that I need to add it through the Steamworks SDK? Or is there another way?

neon bronze
#

Can anyone drop the sandbox vars guide again?

fast galleon
open river
#

But still, thank you very much for your answer.

hot patrol
#

could anyone help me with a clothing item I am trying to get into the game. It is a full body outfit but it doesn't seem to be protecting the feet like a pair of shoes would. what do I need to change for that to work?

cedar kraken
#

(Apparently that’s what controls what body part clothing covers)

hot patrol
cedar kraken
#

Blood locations are body parts I believe?

cedar kraken
#

I may very well be wrong though. I’m not super experienced with modding 😓

hot patrol
#

I don't think so. I have it set to no holes which means the item can't even get holes in it

#

armor in question. it's one weakness, glass

cedar kraken
#

Also walking on glass checks for footwear I think. Even if you have patched socks that give defence, the lack of footwear means that it’ll cut through the socks

#

You can maybe write a Lua code to check that the player doesn’t get their feet cut if the armour is covering them?

hot patrol
#

then glass must check for something besides the blood location, yea?

cedar kraken
#

That’s what I’m thinking, but the game’s code can be so freaking cryptic and frustratingly void of certain stats

#

You’d need to find a workaround

hot patrol
#

the clothing item has it's own exclusive blody location so maybe that's it?

cedar kraken
#

I don’t think so. That just determines what clothing can’t be worn simultaneously

hot patrol
#

hmmm

#

removing can have holes did not fix it

errant sable
#

Is it possible to change the color / style of the world map?

undone tapir
errant sable
undone tapir
#

Now gib Knox 2077 plz 👉👈

quick cape
#

now i have another mod idea:
essentially a pip boy that combines a cd player, radio, and digital watch

#

also a portable tv could be interesting

errant sable
quick cape
quick cape
#

lol
cybernetics when?
cyber zeds when?
going to loose wifi, cya

errant sable
random finch
#

Anyone know why STFR replaces outfits ontick event rather than implementing zombiezones?

#

Seems like it could be an fps killer

bronze yoke
#

i wrote the current implementation and i don't really believe that a couple method calls a tick is really significant at all

velvet pulsar
#

well, looking through other mods, it seems like all of the pieces I need to implement my idea exist and can be made to work using the mod framework. the main question is whether I can pull it off before my attention span drifts elsewhere...

#

all stemming from annoyance at all of the ham radios in the game being VHF, when the tabletop one is very obviously an HF radio, which should behave quite differently

#

I got to asking "why would anybody want to be able to use a radio for two-way communication over long distances in single player?" and the obvious answer is that hams would respond to the event as they would any other emergency, by providing communications worldwide as other systems max out or fail. the radiograph system would have people trying to contact family and friends within the zone, and when that fails would start trying to recruit people within the zone to find out what happened to them. so, it's an NPC-less system for getting quests into the game, with possible rewards in the form of knowledge (recipes and skill points?) and maybe even air drops... so, way bigger than just a radio mod. maybe too big.

errant sable
#

I dig it

quick cape
# errant sable I dig it

Your kind cling to your flesh, as though it will not decay and fail you. One day the crude biomass you call the temple will wither, and you will beg my kind to save you.

But I am already saved, for the Machine is immortal...

...even in death I serve the Omnissiah.```
#

01000110 01110010 01101111 01101101 00100000 01110100 01101000 01100101 00100000 01101101 01101111 01101101 01100101 01101110 01110100 00100000 01001001 00100000 01110101 01101110 01100100 01100101 01110010 01110011 01110100 01101111 01101111 01100100 00100000 01110100 01101000 01100101 00100000 01110111 01100101 01100001 01101011 01101110 01100101 01110011 01110011 00100000 01101111 01100110 00100000 01101101 01111001 00100000 01100110 01101100 01100101 01110011 01101000 00101100 00100000 01101001 01110100 00100000 01100100 01101001 01110011 01100111 01110101 01110011 01110100 01100101 01100100 00100000 01101101 01100101 00101110 00100000 01001001 00100000 01100011 01110010 01100001 01110110 01100101 01100100 00100000 01110100 01101000 01100101 00100000 01110011 01110100 01110010 01100101 01101110 01100111 01110100 01101000 00100000 01100001 01101110 01100100 00100000 01100011 01100101 01110010 01110100 01100001 01101001 01101110 01110100 01111001 00100000 01101111 01100110 00100000 01110011 01110100 01100101 01100101 01101100 00101110 00100000 01001001 00100000 01100001 01110011 01110000 01101001 01110010 01100101 01100100 00100000 01110100 01101111 00100000 01110100 01101000 01100101 00100000 01110000 01110101 01110010 01101001 01110100 01111001 00100000 01101111 01100110 00100000 01110100 01101000 01100101 00100000 01000010 01101100 01100101 01110011 01110011 01100101 01100100 00100000 01001101 01100001 01100011 01101000 01101001 01101110 01100101 00101110 00001010 00001010 01011001 01101111 01110101 01110010 00100000 01101011 01101001 01101110 01100100 00100000 01100011 01101100 01101001 01101110 01100111 00100000 01110100 01101111 00100000 01111001 01101111 01110101 01110010 00100000 01100110 01101100 01100101 01110011 01101000 00101100 00100000 01100001 01110011 00100000 01110100 01101000 01101111 01110101 01100111 01101000 00100000 01101001 01110100 00100000 01110111 01101001 01101100 01101100 00100000 01101110 01101111 01110100 00100000 01100100 01100101 01100011 01100001 01111001 00100000 01100001 01101110 01100100 00100000 01100110 01100001 01101001 01101100 00100000 01111001 01101111 01110101 00101110 00100000 01001111 01101110 01100101 00100000 01100100 01100001 01111001 00100000 01110100 01101000 01100101 00100000 01100011 01110010 01110101 01100100 01100101 00100000 01100010 01101001 01101111 01101101 01100001 01110011 01110011 00100000 01111001 01101111 01110101 00100000 01100011 01100001 01101100 01101100 00100000 01110100 01101000 01100101 00100000 01110100 01100101 01101101 01110000 01101100 01100101 00100000 01110111 01101001 01101100 01101100 00100000 01110111 01101001 01110100 01101000 01100101 01110010 00101100 00100000 01100001 01101110 01100100 00100000 01111001 01101111 01110101 00100000 01110111 01101001 01101100 01101100 00100000 01100010 01100101 01100111 00100000 01101101 01111001 00100000 01101011 01101001 01101110 01100100 00100000 01110100 01101111 00100000 01110011 01100001 01110110 01100101 00100000 01111001 01101111 01110101 00101110 00001010 00001010 01000010 01110101 01110100 00100000 01001001 00100000 01100001 01101101 00100000 01100001 01101100 01110010 01100101 01100001 01100100 01111001 00100000 01110011 01100001 01110110 01100101 01100100 00101100 00100000 01100110 01101111 01110010 00100000 01110100 01101000 01100101 00100000 01001101 01100001 01100011 01101000 01101001 01101110 01100101 00100000 01101001 01110011 00100000 01101001 01101101 01101101 01101111 01110010 01110100 01100001 01101100 00101110 00101110 00101110 00001010 00001010 00101110 00101110 00101110 01100101 01110110 01100101 01101110 00100000 01101001 01101110 00100000 01100100 01100101 01100001 01110100 01101000 00100000 01001001 00100000 01110011 01100101 01110010 01110110 01100101 00100000 01110100 01101000 01100101 00100000 01001111 01101101 01101110 01101001 01110011 01110011 01101001 01100001 01101000 00101110

#

im not sorry
too much fun being a techpriest

errant sable
#

The question is, does anyone have any like techno pyramid tilesets? or do I need to make one for the Techpriest temples... lol

#

cause that just sounds like it should be a thing

outer crypt
#

Does anyone have an example of a working globalmoddata use? I have been trying to make one but I never get the data through in multiplayer, in solo it works perfectly. Here is an example of what I tried.

#

as I understand it you make your table, transmit it from client to server, add the onreceive to catch the data and send it out to the other clients.

#

I don't really have a device to attach the data to. My only other thought is to try and attache it to the player character itself

#

I was just hoping to make one list availible to all on the server

void cargo
outer crypt
#

It'll take a little to implement this here to try it. I see it uses the Events.OnServerCommand.Add(onServerCommand)
Events.OnClientCommand.Add(onClientCommand) functions.

#

I was under the impression that it its just a table of moddata that this might be overkill.

#

Using this as my guide through the process.

#

The idea would be to make the table and store it local as a moddata

#

local MyRadioData = ModData.getOrCreate("MyRadioData")
if #MyRadioData == 0 then
MyRadioData[1] = "sound1"
MyRadioData[2] = "sound2"
MyRadioData[3] = "sound3"
end

#

ModData.add("MyRadioData", MyRadioData)

#

then transmit it up tothe server

#

ModData.transmit("MyRadioData")

#

but that requires the Events.OnReceiveGlobalModData.Add(MyRadio_UpdatePlaylist_UpdateGlobalModData) catch command instead

quasi jewel
drifting ore
#

nice profile picture @quasi jewel

Perhaps he could help tho

winter coral
#

When porting items you don’t need to include normal maps and roughness and shit like that right ?

limber summit
# agile vigil From looking at the source, my best suggestion would be to use the `LevelPerk` e...

Is this a decent block using the AddXP event handler? I'm having trouble figuring out how to use SetTotalXP since it's only input is a float of the level and I'm not sure it's targeting the perk I want since setTotalXP seems to work from "player".XP and not "player".perks.

-- Event handler for perk xp gain
local function onAddXP(character, perk, level)
  if character:HasTrait("NoCarpentry") and perk:getId():lower() == "Woodwork":lower() then
    perk:setTotalXP(0.00)
end

Events.AddXP.Add(onAddXP)

quasi jewel
#

But who knows (besides them), they might know info on that

limber summit
#

With the code below, I have the game properly printing the before and after "levels", so i know the conditional is targetting the right thing. I just need to figure out what the line is for level = 0.00 that will set the gained xp back to 0.

function onAddXP(character, perk, level)
  print("The perk is: " .. tostring(perk:getId()))
  print("The level before is: " .. tostring(level))
  if character:HasTrait("NoCarpentry") and perk:getId() == "Woodwork" then
    level = 0.00
  end
  print("The level after is: " .. tostring(level))
end

Events.AddXP.Add(onAddXP)
bronze yoke
#

changing the parameters of an event doesn't pass them back or anything

#

events are one-way communication generally

limber summit
#

Adjusting this a bit for correct stuff like character:getXp():getXP(perk) just made a constant stream of errors from the Skill Recovery Journal Mod.

#

Lines 190 from Journal XP and 7 from Journal Write.

limber summit
bronze yoke
#

i'm saying changing them doesn't do anything

limber summit
#

So you should instead just use the event, grab variables that weren't passed but target the same things, then change that way?

void cargo
#

Oh my how did you do this?

void cargo
thin bronze
#

how would i use a item from a diffrent mod in a recipe in my mod?

bronze yoke
#

same way you use any other item

thin bronze
#

but how would i let the mod know its from another mod and not something that dosnt exist

gleaming dock
#

im trying to test my mod in game but lua loads then i just get this screen forever

#

any advice?

thin bronze
random finch
#

but, I am curious as to why you chose this type of implementation over zoning? What advantages did you see, etc

bronze yoke
#

zombies just don't always spawn through zones

#

we do use zones

#

think stories

foggy finch
#

help my code does not work, i tried seeing if i clicka numpad number it does an acction but i dont see why it does not work, im sending the github repo link were you can find the lua filehttps://github.com/thom2305/PZ-gfpw/tree/main/media/lua/client

GitHub

Mod that contains a generator for electicity and water in Project Zomboid - thom2305/PZ-gfpw

limber summit
outer crypt
#

anyone familiar with radio broadcast loops? I have the min max both at 3650 to keep them looping forever but sometimes the broadcast just stops for no apparent reason

outer crypt
limber summit
# void cargo Skill limiter does this (server folder): ```lua if level > max_skill then ...

Dunno bout replicability or scalability yet, but doing everything from command line just for testing netted success with this:

function onAddXP_nsgt(character, perk, level)
  print("The perk is: " .. tostring(perk:getId()))
  print("The level before is: " .. tostring(level))
  print(-level)
  if character:HasTrait("NoCarpentry") and perk:getId():lower() == "woodwork" then
    character:getXp():setXPToLevel(perk, 0)
    character:setPerkLevelDebug(perk, 0)
    character:update()
  end
end

Events.AddXP.Add(onAddXP_nsgt)
#

Spoke too soon. That worked when he had a bunch of skill but now that it was at 0 it ain't workin 😄 Went from 0 to .75 to 1.5. I'll keep at it.

trail lotus
#

Hey guys does anyone know what the death animation is called? like when your player lays on the floor dead.

void cargo
#

@trail lotus C:\Program Files (x86)\Steam\steamapps\common\ProjectZomboid\media\AnimSets\player\death\default.xml has Zombie_Death in it

errant sable
#

Is there a way to play one sound, and then after that one play another sound?

hidden jungle
#

i have an error saying LazoloMain.lua:3011: main function has more than 200 local variables
is that refering to the entire lua file? or the function specifically on that line?

cedar kraken
#

Dr. Lazolo, the finest mind of our generation :o

hidden jungle
#

wat

drifting ore
#

you're in the wrong channel either way

#

that be mod support

hidden jungle
#

its MY mod

drifting ore
#

oh

hidden jungle
#

wym i should be in mod support

drifting ore
#

I'm gonna be real you weren't being very specific at first

hidden jungle
#

i mean.. i kinda figured the file name gave it away?
and also the question?

hidden jungle
#

i'm lost on how to fix this, apparently i have 556 "locals" in my file acording to the find function so why is this only happening now?
and why is it only happening on some saves?
its almost like its a compatability issue.
it works fine on my normal mod testing mod list but if i load it into a full modded playthrough it gives me the 200 locals error

void cargo
errant sable
bronze yoke
#

you might have 556 but they probably aren't all in the same scope

hidden jungle
#

thats what i found on google too, aparently its a thing with lua, not specific to zomboid

#

kind of a pain in the ass because i've never had to deal with something like this before but i'll figure something out

bronze yoke
#

if i might say

#

200 locals in a single scope is likely very unnecessary

#

you can kind of compress them into one local using a table

#

but i'm not sure how you even hit this limit

hidden jungle
#

the issue isnt that its nessessary, its just practical.
i have most of my mod in a single file is how i hit it

#

the main scope for the file is what hit it, none of the individual functions have

#

its also because i just changed all the functions in the file to local following, i think your advice from the other day lmao

void cargo
errant sable
#

sorry, it uses isPlaying on the emitter, not isSoundPlaying

limber summit
#

As of rn, tested on two games and it seems to work alright.

#

This is what did it for me:

require 'NPCs/TraitFactory'
require 'NPCs/ProfessionFactory'
require 'NPCs/PerkFactory'

-- Define the NoCarpentry trait
local function NoCarpentryXP()
    TraitFactory.addTrait("NoCarpentryXP", getText("UI_Trait_NoCarpentryXP"), -8, getText("UI_trait_NoCarpentryXPdesc"), false, false);
end

-- Event handler for perk xp gain
local function onAddXP_nsgt(character, perk, level)
  if character:HasTrait("NoCarpentryXP") and perk:getId():lower() == "woodwork" then
    character:getXp():setXPToLevel(perk, 0)
    character:setPerkLevelDebug(perk, 0)
    SyncXp(character)
  end
end

-- Register the trait and event handlers
Events.OnGameBoot.Add(NoCarpentryXP)
Events.LevelPerk.Add(onAddXP_nsgt)
Events.AddXP.Add(onAddXP_nsgt)
#

No errors or conflicts as of yet. Haven't tried w/full mod load of a "normal" game i'd play.

fast galleon
#

Also the two events used, seem to be client side only.

#

So it should be safe to put it into client folder?

#

And split the profession / trait to another file in shared.

outer crypt
# outer crypt I only used the sendtoclient/server commands part of it and used globalmoddata t...

I misspoke, I set up the client server commands and that isn't helping. I set up a catch for the Events.OnReceiveGlobalModData.Add and it does get activated when I do ModData.request("MyModData") but it is not receiving any data. I checked the server logs and it shows that it got a request for a moddata table that doesn't exist. So does ModData.transmit("MyModData") need a catch on the server side? I load the table on the client before sending with ModData.add("MyModData", MyModData) and its not giving me any errors on transmit. This makes me think that the server is not getting or storing the moddata sent to it.

limber summit
#

My next question was gonna be around which "sync" functions would be best for the client/server split if it needed to happen for mp.

limber summit
#

I saw "More Simple Traits" has their setup as "functions" that require events and such are in media/lua/client while the trait definitions are in media/lua/shared/NPCs. Is that the typical way to do it?

bronze yoke
#

i don't think you really need to sync anything

#

xp is usually handled by the client anyway, i've never manually networked it

limber summit
#

Cool, hopefully it's no biggy then.

I do have another query though, from:https://github.com/MrBounty/PZ-Mod---Doc/blob/main/How to make a custom trait.md?plain=1

This block of code:

local function initTOCTraits()
    local amp1 = TraitFactory.addTrait("amputee1", getText("UI_trait_Amputee1"), -8, getText("UI_trait_Amputee1desc"), false, false);
    amp1:addXPBoost(Perks.LeftHand, 4);
    local amp2 = TraitFactory.addTrait("amputee2", getText("UI_trait_Amputee2"), -10, getText("UI_trait_Amputee2desc"), false, false);
    amp2:addXPBoost(Perks.LeftHand, 4);
    local amp3 = TraitFactory.addTrait("amputee3", getText("UI_trait_Amputee3"), -20, getText("UI_trait_Amputee3desc"), false, false);
    amp3:addXPBoost(Perks.LeftHand, 4);
    amp3:getFreeRecipes():add("Make metal hand");
    TraitFactory.addTrait("Insensitive", getText("UI_trait_Insensitive"), 6, getText("UI_trait_Insensitivedesc"), false, false);
    TraitFactory.setMutualExclusive("amputee1", "amputee2");
    TraitFactory.setMutualExclusive("amputee1", "amputee3");
    TraitFactory.setMutualExclusive("amputee2", "amputee3");
end

Events.OnGameBoot.Add(initTOCTraits);

I didn't declare variables for the trait I made and it seemed to work fine. Do you always have to declare the trait this way or is it just to made it easier to use stuff like addXPBoost() in the same function? Cuz I don't think those variables are used again anywhere.

bronze yoke
#

it's always faster and prettier to cache things rather than to call their getters repeatedly

#

usually no functional difference it's just good style and runs better

errant sable
#

can someone explain how going from useMachine to intialiseMachine below, machine somehow becomes nil in initialiseMachine, but is not nil in useMachine

function STZVendingMachine:useMachine(player, machine, vendingType)
    
    if machine == nil then
        print("Error: machine is nil in useMachine")
        return
    end

    
    STZVendingMachine:initialiseMachine(machine)

    local uiInstance = STZVendingMachineUI:getInstance()
    uiInstance:show(player, machine, vendingType)
end




function STZVendingMachine:initialiseMachine(machine)

    if machine == nil then
        print("Error: machine is nil in initialiseMachine")
        return
    end
    local modData = machine:getModData()

    if modData.vendingData == nil then
        local vendingData = {}
        vendingData.vendingType = STZVendingMachine:getVendingTypeId(machine)
        vendingData.stock = {}
        
        for idx, product in ipairs(STZVendingMachineTypeInfo[vendingData.vendingType].products) do
            local stockData = {}
            stockData.productIndex = idx
            stockData.count = 1
            table.insert(vendingData.stock, stockData)
        end
        modData.vendingData = vendingData
    end

end
dry chasm
errant sable
dry chasm
#

was actually even reading only half of it, apologies 😅

errant sable
#

The actually error is it being called again in uiInstance:show() which I used a . so whoops. But not cool the stacktrace is showing the wrong lines...

#

and that wasnt it... it still says its coming from useMachine... and its fine in useMachine and nil in initialiseMachine

bronze yoke
#

can we see the stack trace?

errant sable
#

the 194 wasn''t there last time... and 194 is an end so i dont even know what it complaining about there

bronze yoke
#

have you been live reloading this file?

errant sable
#

Like going to the main screen and reloading mods. Yes. But I have also tried closing the game, and opening again because I know sometimes reloading mods still get fubary

bronze yoke
#

oh, no i meant reloading the individual file mid-game, that should be fine

bronze yoke
#

the debugger and the game itself don't handle the mid-game file reloads great

dry chasm
# errant sable

Also the error claims you tried to call nil, not that you try to call a closure in nil.
So machine is likely not "nil" but a function you try to call doesn't exist in that object

errant sable
#

ive been going to the main screen.... every... single... time

bronze yoke
#

i don't recommend it and i never do it myself

errant sable
bronze yoke
#

if it weren't an object you'd get an attempted to index nontable error

#

so it's not the kind of object you expect it to be

errant sable
#
STZVendingMachine.vendingContextMenu = function (_player, context, worldObjects)


    local player  = getSpecificPlayer(_player);
    local object  = nil;
    local objType = nil;
    
    local objFound = false;
    local vendingType = -1;

    for _,wObj in ipairs(worldObjects) do -- find object to interact with; code support for controllers
        local square = wObj:getSquare()
        if square then
            for i=1,square:getObjects():size() do
                object = square:getObjects():get(i-1)

This is where machine is coming from, it is object here.

#

it passes a check in there for container, and gets the type of container, and if that all succeeds. object is passed context:addOption("Use Vending Machine", player, STZVendingMachine.useMachine, object, vendingType);

#

so i mean... im assuming it should have getModData() ...

bronze yoke
#

try printing machine

fast galleon
#

make object local

bronze yoke
#

it'll tell you its type

errant sable
#

yeah im doing that now... great minds think alike

errant sable
fast galleon
#

I don;t know if you break or something but it could be overwritten? This is usual with context menus

fast galleon
errant sable
#

it breaks

#

context:addOption("Use Vending Machine", player, STZVendingMachine.useMachine, object, vendingType);

#

Is this line wrong?

#

printing machine comes out wit 1

bronze yoke
#

yes

fast galleon
#

can you show the show function?

bronze yoke
#

you are passing every argument one to the left

errant sable
#

🔫

bronze yoke
#

player is self, object is player, vendingtype is machine, vendingtype is nil

errant sable
#

I looked at that thing sideways twice, but I was following other code...

#

AND, everything up until this point now was working

bronze yoke
#

i'd just drop the usage of implicit self, at least in the portions of code you've shown me you don't make any use of it

#

it makes interaction with context menus difficult

errant sable
#

context:addOption("Use Vending Machine", player, STZVendingMachine.useMachine, object, vendingType);
What is the correct order of these?

bronze yoke
#

context:addOption("Use Vending Machine", STZVendingMachine, STZVendingMachine.useMachine, player, object, vendingType);

fast galleon
bronze yoke
#

the second argument is passed as the first parameter for the function, and your function is defined with implicit self so you need to pass that before any explicit parameters

errant sable
#

🤦‍♂️ See, that was one of the things i was messing with because it kept blowing up (so im guessing the other problem was a problem also, and when i fixed that I had also broken this)

#

STZVendingMachine.useMachine = function before

bronze yoke
#

that's what i'd go with if you're not actually using self anyway

fast galleon
#

If you don't use self then you can just use them all with a dot to separate which functions are for instances and which are not as albion said before.

bronze yoke
#

imo implicit self is not really a great pattern outside of classes, it leads to this confusion and i'm sure passing around an unused self adds some overhead

errant sable
#

yea. Everywhere else ive kept it pretty straight, this one got changed because i was chasing my tail in a circle looking in the wrong place for a bug

#

Success... Buju can now be purchased again, lol.

#

Thank you both

#

very much

#

probably a sign i should goto sleep, but i realy feel like there is more bad coding decision I can make tonight still

errant sable
#

How do radius and volume impact the use of addSound. Radius makes sense.... how far the sound can be heard... but the volume... well volume would define the radius wouldnt it?

rugged latch
#

im pretty sure volume is the importance of the sound for zombies

#

like how zombies invenstigate noises

#

if they hear a door creak they dont care as long the car is running full blast right next to them

errant sable
#

Well that is what im wondering, if both exist, im sure there is some cross play

rugged latch
#

maybeee?

errant sable
#

ah ok, so volume acts like priority maybe

rugged latch
#

that was my guess

#

i can try and decipher in the source rq

errant sable
#

if you want, that would be swell

rugged latch
#

this function here seems to be whats responsible for it, if you want the nitty gritty

#

seems a tad more complex but it still seems that im assummingggg it works like how i said

#

although pretty cool it cares depending on the room or not

#

if what you actually cared about is the sounds volume if that means its louder then i can look for that lol

errant sable
#

nope, this is exactly what i was wondering. Volume is mltiplier to the base attraction determined from distances.

#

Essentially it acts like a priority where a loud sound farther away is more important than a quiet close one

rugged latch
#

its a big confusing that its swapped between radius and volume, i mean i know WHY you would want it for modularity, but i can't really think of a scenario where i would want a noise that is really short range but super loud

#

because then itd just be confusing as a player how that even works

fleet bridge
#

'"

rugged latch
#

hm?

hollow current
#

Soo my mod has a custom vehicle part. Apparently, on MP, its not being properly uninstalled, in the sense that when the timed action ends, nothing happens at all. Not sure what I missed there. Any idea?

#
            {
                items
                {
                    1
                    {
                        type = Base.Screwdriver,
                        count = 1,
                        keep = true,
                        equip = primary,
                    }
                }
                time = 300,
                skills = Mechanics:3,
                test = Vehicles.InstallTest.Default,
            }
            table uninstall
            {
                items
                {
                    1
                    {
                        type = Base.Screwdriver,
                        count = 1,
                        keep = true,
                        equip = primary,
                    }
                }
                time = 300,
                skills = Mechanics:3,
                test = Vehicles.UninstallTest.Default,
            }
            lua
            {
                create = Vehicles.Create.Default,
            }```
#

or is it simply that I need to create a custom client command for installing and uninstalling custom parts?

#

though I'd imagine the game natively handles that

#
LOG  : General     , 1701965801712> 579,469,356> VehicleCommands: no such part AirbagFrontRight```
Getting this in console as well. Script apparently not detecting the part, though not sure why considering it works just fine in Solo
fast galleon
#

Are you using lua to add the part? Is the file in client folder?

hollow current
#

Yes to both, I am using lua to add the part, and the script used to add it is in client folder

#

do i need to move the bit that adds it to server (or shared) folder?

#

That fixed it. Thanks for pointing it out!

rich void
winter thunder
#

I’ve been going crazy over trying to make this work. If anyone has any insight i would be really grateful

Basically, I need to get the items inside of a container that is in the players inventory. I am using an OnCreate function, and I can properly isolate the container. From there though, nothing I am doing is working to allow me to get just the list of items out of that container.

So, if anyone know the working code for going from inventory container -> contents, that would be really helpful Lmao

sour island
#

GetItems() ?

#

ItemContainers also have a plethora of functions - some are recursive

bronze yoke
#

if you've reached your InventoryContainer just use getInventory() to get the ItemContainer object

sour island
#

Vanilla also has a check for items not in the direct players inventory and will call a transfer function

winter thunder
sour island
#

Are you aware it's an array?

outer crypt
#

If a client is requesting globalmoddata from a server does this need to be setup SendCustomModData for the server to know what to send or is it automatic? I keep getting empty data as if there is no data on the server.

sour island
#

I spent like 3 days relearning server-centric global modData - so it's still fresh in my mind

outer crypt
#

wow, so the server can't store any table globally...

sour island
#

It can

#

You just can't rely on transmitting global modData from client to server - it gets very finnicky

winter thunder
bronze yoke
#

can we see your attempts?

#

otherwise it's kind of shot in the dark guessing what you might be doing wrong

sour island
#

What I do is keep the get or set on server entirely, and have the data sent back to clients as needed -- helps network calls too.

#

Vanilla transmit sends the entire table needlessly - and it's prone to easily overwrite stuff

outer crypt
# sour island It can

so I tried the sendclientcommand and sendservercommand with the catches on both sides to create a moddata entry to go around the transmit moddata option and it seems like everytime the moddata just evaporates

sour island
#

If you need to study something check out my ZonesAPI mod

#

I can still condense the client side stuff - but it works as a server centric table that clients can access and modify in sync

#

You can also access the data abusively if needed - for my zombie zones mod it grabs at the data every tick

#

The workaround is it's relying on the client side temporary copy

winter thunder
# bronze yoke can we see your attempts?

Yeah, I will pull it up in a min. I ended up gutting a lot of it and rewriting some things. But, just so I know-
Assuming I have gotten as far as the item container object, what would be the method to pull every item from that point?

Because I have tried like, everything from the list that seems general enough for it to work for me; getAllTag(), Items(), getItems(), getAllItems(), etc.

I’m on mobile and not looking at the codebase yet, booting up PC, so excuse me if I mistyped one of the examples lol

bronze yoke
#

getItems() is what i remember

outer crypt
#

local MyModData = ModData.getOrCreate("MyModData")
MyModData[1] = "bob"
MyModData[1] = "sam"
MyModData[1] = "sue"
ModData.add("MyModData", MyModData)

bronze yoke
#

the last call is unnecessary

#

tables are passed by reference, after you've called getOrCreate you already have the moddata table and don't need to 'add' it

outer crypt
#

okay, the add wouldn't make it disappear though, right? just overwrite it with itself

bronze yoke
#

yeah

sour island
#

What I concluded is that the modData is only saved at certain points - so using getOrCreate into a local can lead to issues where you're reloading the data before you save it.

#

You should have it stored into a referenced variable

#

After it's loaded, it's a Lua table just like any other

outer crypt
#

so if I understand that right a global UniqueModData = {} then later add and remove from that and store it in the moddata as a backup

sour island
#

When trying to get zone API to work I kept running into issues where the table would be reverting if multiple people messed with it. Idk if it was something else, but once I kept the reference stored on a module the problems went away.

#

Doesn't need to be global, just not a local in a function

bronze yoke
#

oh yeah, i would just cache the table, idk about the problems chuck was having but it just performs better and it's less ugly than calling a function every time

outer crypt
#

Okay I think I understand now and will check out that api.

sour island
#

I still plan to refactor the client side stuff to look better

#

There's a huge pitfall with clients still running code in the server folder

outer crypt
#

Not too worried about how pretty it is. lol just trying to get something to stick

sour island
#

It's mostly cause I realized I could store the data in the /server/ code for clients instead of having basically copy pasted stuff in client.

#

But I don't think commands will work in that folder - so maybe this is the way it has to be

bronze yoke
#

there is no behaviour difference between folders

outer crypt
#

Does moddata save the data when the game restarts?

bronze yoke
#

yeah

formal oasis
#

Quick question if anyones got the time; Does anyone happen to have a list of all body slots for armor? I used to have a list somewhere i've been out of pz modding for too long and lost it

outer crypt
#

okay, so using it to back up the main table might still be good if I want it to exist past a reboot

sour island
bronze yoke
#

of course

sour island
#

I figured yes, since it's running that code - it would help a bit

bronze yoke
#

the folders don't cause the lua in them to execute differently, they're just for loading

sour island
#

Well gameServer doesn't load client code

#

Which is the part that can throw people off as their "server" code executes on players

#

But not the other way around

bronze yoke
#

the folders don't behave differently from each other aside from loading, but the lua does behave differently based on whether it's being executed on the client or the server

winter thunder
#

Attempt to isolate the container item. Should work as intended...

local container = ''

for i=0,items:size() - 1 do
    local temp = items:get(i)
    if temp:IsInventoryContainer() == true then
      container = temp
    end
end

Attempting to pull the info out of the container is where it always seems to break...

containerContents = container:getItemContainer():getItems()

I used :getItemContainer() instead of :getInventory(), but they return the exact same thing. And it worked in test print()'s like:

print('Test3: ' .. tostring(container:getItemContainer():getCountTag('example')))
bronze yoke
#

what breaks? is the arraylist empty?

winter thunder
#

Yeah, containerContents keeps breaking it. If it doesnt, then it breaks when other code tries to reference containerContents

bronze yoke
#

so the error is on that line? that's really strange

winter thunder
#

Yeah, the goal is to get it to go through those items to be checked by my reference table. Actually using some code you gave me in the past for that 👉 👈

but since it is failing to pull the items, I cant iterate them to check them against my reference 😭

gleaming dock
#

nvm fixed it lol

gilded hawk
dull moss
#

afaik

torn igloo
void cargo
#

Has anyone changed out the lua interpreter for one that has standard library stuff for development? I wonder how possible it is while keeping the kahlua exports

sour island
gilded hawk
#

Alright, thank you

bronze yoke
#

i think most modders a little excessively terrified of it

#

but chances are most code can be optimised in some way to not run on tick

dull moss
#

i needed to cap player pain level at 60% and every 10 min was too slow of an update, had to do it on tick Sadge

#

i might be an idiot however cuz i completely forgot everyminute exists

#

eh its fine

bronze yoke
#

keep in mind that on longer day lengths everyminute would be too slow

dull moss
#

also true

bronze yoke
#

you can use deltas/the tick to throttle the rate at which ontick stuff actually happens

sour island
#

Indeed

bronze yoke
#

i think most modders though are wildly overestimating the impact of a couple operations a tick

sour island
#

75% of the game runs off ontick

dull moss
#

yea i got no clue how actually impactful is it OMEGALUL

sour island
#

It's mostly issues like for loop abuse on top of ontick

dull moss
#

I just assume its better not to put suff on it if you can make it on bigger interval

#

so far only hooked to ontick once and everyminute once, everything else is bigger intervals GigaChad

bronze yoke
#

it is better to avoid it, to most problems it is the worst solution

#

but it is not as bad as people make it out to be

sour island
#

When you can you should avoid it

#

That's all there is to it

dull moss
#

Glad to see you guys and girls still here and blazing, real legends in modding community ❤️

sour island
#

The more triggers they add the better cause usually people start dumping hundreds of lines in an update tick cause there's no other point to leverage off of

dull moss
#

I also recently reached 1st page of Traits category for most popular all time, something nice to share with you 2 since you helped me so much back in the day blushge

bronze yoke
#

congrats!

fleet bridge
#

is there a way to get the initial zombie health before you hit them? or to just output the damage you deal when you hit a zombie?

limber summit
#

Is there a better way to make the former code more elegent for elseif statements?

-- former
local function onAddXP_nsgt(character, perk, level)
  if character:HasTrait("Butterfingers") and perk:getId():lower() == "woodwork" then
    character:getXp():setXPToLevel(perk, 0)
    character:setPerkLevelDebug(perk, 0)
    SyncXp(character)
  end
end

-- new
local function onAddXP_nsgt(character, perk, level)
  local setCharacter(perk) = character:getXp():setXPToLevel(perk, 0)
    character:setPerkLevelDebug(perk, 0)
    SyncXp(character)
  end
  if character:HasTrait("Butterfingers") and perk:getId():lower() == "woodwork" then
  elseif -- trait 2 -- then
  elseif -- trait x -- then
  setCharacter(perk)
  end
end

gilded hawk
#

Does anyone know which event is fired right before OnGameStart?

#

I know we have OnGameBoot but It's a bit too early for me

#

So, I need an event that is on the client, that it's fired before the Java's UIManager.init();

gilded hawk
#

So, the ISInventoryPage is initialized before the OnGameStart is fired for my mod 🤔

gleaming dock
#

anyone know why a 3d model wouldnt be detected

#

its in the right place with the right name

#

and its a .fbx file

limber summit
#

For lack of a better way, it looks like this:

gilded hawk
#

Cause I think it could be simplified

errant sable
#

does lua really let the outcome of elseif cascade like that?

#

Cause that is the most cursed looking block of code I think I have ever seen

bronze yoke
#

no, it doesn't

#

each elseif is a different scope

errant sable
#

Ok, so 99% of the code is doing jack and shit

bronze yoke
#

if you're trying to do what i think you're doing you really just need to use a table

errant sable
#

That is what I was thinking as well. I presume the idea is to; for each of these if checks, if its true, it stops the xp gain

#

use perk:getID as the key into a table which contains the value for the HasTrait check

bronze yoke
#

something like this:```lua
local traitMap = {
[Perks.Woodwork] = "ToolBlamer",
[Perks.Cooking] = "Shoe",
-- etc, add the rest following that pattern
}

local function onAddXP_nsgt(character, perk, level)
local trait = traitMap[perk]
if trait and character:HasTrait(trait) then
character:getXp():setXPToLevel(perk, 0)
character:setPerkLevelDebug(perk, 0)
SyncXp(character)
end
end

cedar kraken
#

I’m curious

errant sable
#

Everything lives in A scope, but not ll scopes are the same scope

#

Code only considers things in a specific scope at a time

#

Like if you go into a house and punch everyone, you can only punch people in that house, not the neighbors house... they are different scopes

bronze yoke
#

in that case it was a bit of a misspeak and it'd be better to say each one is a separate block but basically whenever you start a new 'block' (an if statement, a do statement, a function, etc) you create a new scope, you can only access local variables from your current scope and the scope it belongs to, etc

cedar kraken
#

So a scope is the category which contains a group or certain variables, functions, arrays, etc.?

errant sable
#

And scopes can have scopes in scopes

#

Like you can only punch people in the room you are in in the house you are in

cedar kraken
#

Almost like a clade in taxonomy?

errant sable
#

¯_(ツ)_/¯

#

No idea what a clade is

cedar kraken
#

Is it possible to expand the scope of a code?

bronze yoke
#

and locals with the same name are resolved to the lowest one```lua
local foo = 5

function testFunc() -- start of block
-- foo is accessible in this block
local bar = 10
end -- end of block

-- bar is not accessible here, because it was in the scope of the testFunc block

errant sable
#

If its compiled... no

errant sable
#

if its not compiled... wel scope is jut conceptual at that point, and sure you can add new code "in scope"

#

anywher eyou want to use the word scope, you can mostly use the word "context" and it mostly generalyl effectively relays the same idea

cedar kraken
errant sable
#

No, scopes can be nested

#

And it depends on the rules of the language for the specifics on scope at times as well

cedar kraken
#

(No clue if that makes sense)

errant sable
#
for <somet stuff> do

  for <somet stuff> do
  
  
  end
end
#

Contains two scopes, the second nested inside the first

cedar kraken
#

Yeah

errant sable
#

inside the second scope, you can still access stuff from the first scope

cedar kraken
#

But what I’m talking about is different

bronze yoke
#
function testFunc()
    local foo = 5
    if something then
        -- foo is accessible here
        local bar = 10
    elseif something else
        -- foo is accessible here, but bar is not
    end 
end
errant sable
#

Perhaps use an example then, other than saying 'block'

#

What exactly you are in, in the code matters in what is refernceable from a scope and wht the scope itself is

cedar kraken
#
for <some stuff> do

    for <some stuff #1> do
  
     end

…more stuff here

  for <some stuff #2> do
 
  end
end
bronze yoke
#

the way you're encouraged to use indentation mostly represents scope (though don't rely on it to tell you, as indentation is not a language feature and you can technically indent things however you want)

cedar kraken
#

Is this correct?

errant sable
#

other languages better illustrate scope... many use { and } and while it is not the end all be all to scope, it does generally clearlly illustrate when a specific scope starts and ends

cedar kraken
#

Okey doke, that was my question, I apologize for asking it in a nebulous way 😅

#

Thank you all for the help, I appreciate it greatly

errant sable
#

All good, glad it helped

limber summit
#

hehe, watching my kid so i can't really type, but glad my shitty code ~~produced ~~ inspired such a conversation.

errant sable
#

I write stuff, think its great, and look at it a month later and I wonder who let a monkey pound its face on the keyboard

#

the only truley good code is whatever works

gilded hawk
#

So, I made a new small mod what do you guys think? Is the name "Grab non-duplicate items" correct?

It's supposed to grab only 1 item, and grab only items that you don't already have in your backpack

errant sable
#

Handy...

#

What would be handy to go along with it is if it tracked what books you picked up already as well, and you didnt pick up books you already have picked up even if they are not in your backpack

#

Im always like .... did I find <Random Skill> 4 yet.... better grab it just in case... and get back and I got 10 copies

gilded hawk
errant sable
gilded hawk
#

Does anyone remember how to show a red text above the player head?

Nevermind, found it

HaloTextHelper.addText(player, getText("IGUI_NoUniqueItemsToGrab"), HaloTextHelper.getColorRed())
errant sable
#

Is there a way to hook into when the player left clicks on things in the world? I know I can do the right click context, but I would like to pop up a particular UI when they left click on certain things..

bronze yoke
#

i'm aware of OnObjectLeftMouseButtonDown and OnObjectLeftMouseButtonUp, no idea how reliable they are

#

if they turn out weird you can work from OnMouseDown, there's utility functions to convert from screen to world co-ordinates

quick cape
#

hmm...
none of the current skills fit chemistry...
so if i want to add some chemistry stuff, id probably also need to add a chemistry skill and skillbooks, maybe even profession

limber summit
#

Is there a decent list somewhere of skill "values"? I'm trying to decide how many trait points to give for players deciding to prevent xp gain for skills. For example, I have them all at 8 right now, but I think "maintenance" should give more points than say, short blunt. I thought someone had already done that kinda work and I saw some spreadsheet they did but idk what it was. I saw it months ago though.

limber summit
quick cape
#

I honestly only thought of making it cause Im still a bit obsessed with bakelite
which is not that hard to make tbh!
sorta
you can, with the right equipment, fully synthesis it out of wood alone
and if you treat wood or woven wood fibers with its resin state, you get a pretty durable, strong and lightweight material.
not as good as other modern materials but it is easily accessible if you have the knowhow

quick cape
#

hmm...
what other fun chemistry stuff could one add...
not directly chemistry but a biogas plant as an upgrade to the composter could be neat, if you know what those have as side products, you would know its potential

crisp fossil
#

Hi guys I wanted to patch the item loot rate of a mod and I did it like this

table.insert(SuburbsDistributions["all"]["inventoryfemale"].items, "SampleItem");
table.insert(SuburbsDistributions["all"]["inventoryfemale"].items, 0);```
Is it not possible to make the drop rate to 0%? Or I'm just doing it wrong.
Edit: All I did was copy their distribution code with the same file name and location
pastel raptor
#

Hi! Could anybody help me creating a new item called infection scanner? It's like the scanner seein in the last of us part 1. If you use it on a player or on yourself, it print a sheet of paper which says if you're infected or not. Should work on MP and crafted with electricity 6. I can provide graphic.

outer crypt
#

I made a radio station based on the wordzed tool to run every hour on the hour and get the min max to 365 after creating a 24hr cycle. I have noticed that it often just stops randomly broadcasting. Power is still up but it doesn't continue. I have seen some mods that change the number of cycles the radio broadcasts run but see nothing except the min max changed. Anyone know why the broadcasts might just stop?

#

soemtimes it runs only a few broadcasts stops, other times is runs for a few days.

rugged latch
#

I uploaded a mod to the workshop unlisted, subscribed to it, restarted my game multiple times, unsubscribed and resubscribed, yet it doesn't show up? It was working last time I uploaded but when I tried to update the mod it stopped. anyone here experience this?

#

do zomboid mods from on file and workshop overwrite each other?

quiet plank
#

tf am I doing wrong here?

[08-12-23 23:59:23.497] ERROR: General     , 1702101563497> 2,222,373,503> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: Object tried to call nil in CarDoors at KahluaUtil.fail line:82..

function Recipe.GetItemTypes.CarDoors(scriptItems)
    local allScriptItems = getScriptmanager():getAllItems();
    for i,v in ipairs(allScriptItems) do
        local siName = string.lower(v:getName());
        if v:getDisplayCategory() == "VehicleMaintenance" and
            (string.contains(siName, "door") or
             string.contains(siName, "cover") or
             string.contains(siName, "hood") or
             string.contains(siName, "lid")) then
            scriptItems:add(v);
        end
    end
end
#

omg... if it's what I think it is...

bronze yoke
#

getScriptManager

quiet plank
#

yep

#

exactly that

#

facepalm

3 hours...

#

3

#

hours

#

now, does that only get called when the script is compiled/loaded or everytime the recipe is called?

bronze yoke
#

the former, they get called while the scriptmanager is 'finalising' recipes

#

if you want to disallow items conditionally you should use OnTest

quiet plank
#

I'm trying to include just certain sets of items, but as I'm testing in admin mode, none of the items that should have been grabbed were. trombone noises

#

trying to do it in the most agnostic way possible so as not to be constantly adding new lines as additional vehicles are included.

I'll look at onTest to see if it can add something to this. But I'll probably switch it to check for ItemType()

bronze yoke
#

i don't think ontest would be suitable for that usage

bronze yoke
#

yeah, that's me

quiet plank
#

I think this is the perfect thing for one of my complainers on the server. LOL

#

well, I'll take a crack at pulling the list better/cleaner tomorrow. Gonna mark this mod in my notes and do the testing tomorrow. Thanks for the responses. Hoping one day I can graduate from patching to writing.

bronze yoke
#

i hope it works for you ^_^

limber summit
#

Any help figuring out why the getText("UI_trait_(variable)") isn't properly returning the trait name or description? It works fine though.

bronze yoke
#

is the file named the same way as the vanilla one?

#

it needs to have exactly the same filename and path

#

they don't use the same loading logic most other things do so it won't overwrite or anything

limber summit
#

I'll check it out.

#

While the other file that generates the traits does just fine

#

I tried it in client and in shared/NPCs

fleet bridge
fleet bridge
sour island
#

Something like needsTransfer

fleet bridge
#

Thx. Trying to check if an item is inside an equipped container or inside a container in the char inventory

quiet plank
#

is there a way to get scriptItems by display category or some other parameter so I'm not loading the whole dictionary/table?

 local allScriptItems = getScriptManager():getAllItems()
#

FindItem?

#

but that looks like it only returns one value

#

and this is probably a stupid question - as I'm almost CERTAIN it must exist, and I've probably seen it in the docs but glossed over it at the time:
Can I load up a lua console with all the data I'm working with - like from in game, or maybe from command-line without all the UI?

verbal yew
#
 local allScriptItems = getScriptManager():getAllItems():getCategory()
#

or getDisplayCategory

quiet plank
#

cuz that would DEF save on cycles. LOL - thank you

#

so the :getDisplayCategory will return the subset of allItems with the DisplayCategory I pass?

#

or is that just going to get the DisplayCategories of all those items

verbal yew
#

get all items from parameter

quiet plank
#

cool. danke

#

sane? Any glaring mistakes?

local doorItemTypes = {}
doorItemTypes[1] = "door"
doorItemTypes[2] = "cover"
doorItemTypes[3] = "hood"
doorItemTypes[4] = "lid"

local function checkItemTypes(scriptItemType, itemTypes)
    local retVal = false
    for i,v in ipairs(itemTypes) do
        if string.contains(scriptItemType, v) then
            retVal = true
        end
    end
    return retVal
end

function Recipe.GetItemTypes.CarDoors(scriptItems)
    local scriptItems = getScriptManager():getAllItems():getDisplayCategory("VehicleMaintenance");
    for i,v in ipairs(scriptItems) do
        local itemType = v:getItemType();
        if checkItemTypes(itemType:lower(), doorItemTypes) then
            scriptItems:add(itemType);
        end
    end
end

#

hrm... and if I'm returning this for a recipe source, i don't need/want the whole scriptItem, do I? Just the ItemType

quiet plank
#

it loads clean and doesn't throw any nils , but it also still doesn't populate the list. grumble

quiet plank
#

okay, now I'm confused...

I pulled up with the mod in SP, and the source item shows up. So some other mod is getting in the way? or is there something fundamentally different between SP and MP that I have to redo/restructure that lua to accommodate?

tawdry solar
#

what causes this with a melee weapon i forgot

quiet plank
#

a model without boundary descriptions of some sort - or resizing rules. SOmething along those lines. I had it with Coavin's firearm repairs, but never got to the bottom of it

limber summit
#

Anyone have ideas about how many trait points to give for cancelling the xp on each skill?

boreal kelp
#

Hey, I am here to ask for help with my first mod. I created item and want it to be in forage item pool, but when I tried it on my own, I failed because I dont know where should I start with it. I thought u could help me?

cedar kraken
tawdry solar
#

the model size is the same as the one ingame

cedar kraken
#

Then you’ve broken the matrix. Congratulations.

#

Every winner is eligible to receive a special t-shirt on their way out

#

Did you change the extension on the model? Like is it exported as a .FBX or whatever the other one is

obsidian bronze
#

How can I import and export X file type models in Blender?

finite island
#

Hey guys, can anyone give me a hand? I have a question about my mod, I am making a mod about a short melee weapon, the damage and usefulness of the weapon are fine, but there is a problem that is that when entering a game and equipping the weapon, the 3D model does not appear. I'm sure it is in X format but if anyone knows what is causing the problem I would appreciate it. (I'm a newbie modder)

quiet plank
#

really at my wits end, here - anyone who can take a hard look at tell me what I'm missing (cuz at this point, i suspect it's something stupid-simple), I would really appreciate it. The recipe loads, but doesn't have the list from the bracketed function:

#

hrm - should make that a file instead of a block. One sec.

rugged latch
#

did that function have spaces in the name?

#

i didnt get to look at it for long

quiet plank
#

no

#

one sec

rugged latch
#

im lookin at it but ngl I'm not finding anything obviously wrong

#

although im not the most perceptive either lol

#

cool mod idea tho i gotta say

#

thats a great use for metalwelding, replace the car parts

quiet plank
#

RIGHT!?! That's what I'm saying?

The GetItemTypes is almost a straight copypasta from vanila recipecode.lua

#

but my denizens were tired of modded car parts not being processable, so I'm patching the vehicle repair overhaul mod we were using

rugged latch
#

this doesn't spit out an error right?

#

it just pretends to work?

#

yeaaaaaaaaa

quiet plank
#

nope. everything loads up clean. The recipes show up in the crafthelper. I can even salvage gas tanks (a recipe I'm not showing) because i have all the pieces for it (because the function is just returning 'nothing' as the list

#

but hey - I found a quick and dirty way to get free metal sheets for a few units of propane. LOL

#

the laws of thermodynamics would complain, but this is PZ not Oxford.

rugged latch
#

lol, im using all my brainpower right now

#

it doesn't help i haven't played around with recipes or crafting yet to have run into a similar problem

quiet plank
#

is there a way to get it to spit out debug messages in the lua?

#

I'll read logs all day. Or if I could load up a lua console on the command line? but bouncing in and out of the gui-client is... just... ugh

rugged latch
#

what i usually do is just plop print("ass1") everywhere and see which print doesn't run lol

#

and then i know where it stops at

#

not everryyyywhere

#

but where i think it might be going wrong

quiet plank
#

well, I'm not worried about it stopping. I need to see the values of things as it progresses

#

so 'print' will make it to the server.txt ?

rugged latch
#

wait

#

im not sure

#

i just put prints for the values to check what they are in that case

#

cuz sometimes you can see itll just print nil, or something completely different and it ends up being pretty obvious

#

its quick and dirty but it hasnt failed me yet

quiet plank
#

i'll give it a shot

rugged latch
#

good luck

opal pier
#

Guys is there any use for the "Comestic = True" item parameter? I didn't really understand how it works

quiet plank
#

maybe just a metaparameter for various tests/checks? what it sounds like to me. Could just as well use Tags, I would think. Dunno. Would have to grep the java code

cedar kraken
# tawdry solar fbx yeah

Might be part of the issue. .FBX has a funny scaling thing. You’ll have to change it, although unfortunately I can’t remember the exact number 😅

#

Sorry!!

#

Someone in #modeling may be able to help though

bronze yoke
# quiet plank

one error here is on line 6 you call :add on a table (should use table.insert(vmScriptItems, scriptItem)) but changing this on my end did not make it work

#

oh man i'm sleepy yeah ipairs on an arraylist doesn't work

rugged latch
#

thank god albion is here to figure it out lol

bronze yoke
#

that's a lua iterator, arraylists are java objects

#
local allScriptItems = getScriptManager():getAllItems()
local vmScriptItems = {}

-- ipairs doesn't work on an arraylist, use a numeric for like this
for i = 0, allScriptItems:size() - 1 do
    local scriptItem = allScriptItems:get(i)
    if scriptItem:getDisplayCategory() == "VehicleMaintenance" then
        -- :add is arraylist syntax, vmScriptItems is a lua table
        table.insert(vmScriptItems, scriptItem)
    end
end

local doorItemTypes = {}
doorItemTypes[1] = "door"
doorItemTypes[2] = "cover"
doorItemTypes[3] = "hood"
doorItemTypes[4] = "lid"

local function checkItemTypes(scriptItemType, itemTypes)
    local retVal = false
    for _,itemType in ipairs(itemTypes) do
        if string.find(string.lower(scriptItemType), itemType) then
            retVal = true
        end
    end
    return retVal
end


function Recipe.GetItemTypes.CarDoors(scriptItems)
    for _,scriptItem in ipairs(vmScriptItems) do
        --getItemType() should be getName()
        local itemType = scriptItem:getName()
        if checkItemTypes(itemType, doorItemTypes) then
            -- should add the item object, you were adding the type string instead
            scriptItems:add(scriptItem);
        end
    end
end
#

i didn't verify the output was correct but with a little test script in the console it did add 15 items to an empty arraylist i passed it

nocturne swift
#

how to remove IsoObject? I try to execute removeFromSquare() - it is removed, but only on the client side (I relogin to the server and it appears again)
tried removeFromWorld() doesn't work
Thank you

quiet plank
#

As soon as my power comes back I'll be testing it. And yeah, that's a difference I did not know of. Learned a few new things here, today.

opal pier
errant sable
#

What are the dimensions of the poster for a mod supposed to be?

#

I thought there was a specific size, but I checke the mods I have downloaded myself and not a single one is the same size...

errant sable
#

It can apparently be any size at all. I selected a random massive image, and it worked, but covers up half the screen in the game, lol

#

But 256 looks like that is probably what it SHOULD be to properly fit in the area alotted

opal pier
#

ooh so it's like items icons, the ideal is 32 but any size works

errant sable
#

Yes, as long as we use "works" loosely, lol

#

Like it loads... but if its not the right size there is no inherent scaling applied or anything else.

opal pier
#

I learned this the hard way, I left all the items icons in my mod with a good quality and when I launched it people warned me that they were getting too big using other mods like the Tarkov interface cry

errant sable
#

ooff

bronze yoke
#

yeah, it accepts any size

#

i think someone found the exact size of the window for it but i don't remember what it was or who

robust briar
#

Anyone know how to render and save PNGs (or jpeg or even bitmaps) of the map? I did it once by hand with screen shots and stiching them together, but that was god awful and I never want to do that again.

errant sable
robust briar
#

Helllz yeah

#

cloning the night away 🎵

errant sable
#

lol

#

They have several other goodies in their repos as well

robust briar
#

Ohhh PERFECT in C# too. My heart sings

#

Ohh nooo

#

this is like

#

the actual in game world

#

I need the map, like when you press M

errant sable
#

ohhh

robust briar
#

Like this

#

I did this one by hand, with screenshots and photoshop to stitch it together

#

but I want it BIGGER lol

errant sable
#

Hmmm, im not sure of anything that does that. As far as I know the ingmae map is generated "on the fly" from other data with the map. Im not sure of anyway you could easily get that as an image from like within a mod or anything...

robust briar
#

I am working on a web interface for my servers admins and mods to use to TP players, spawn hordes, etc.

errant sable
#

I think it might be easier to write something which parses the vanilla map files, which I believe contain all the data needed to generate these maps, and then generate them yourself

robust briar
#

Like, it shows online players already and a bunch of other neato thing, like being able to see a heatmap of all player locations

#

but I want the zoom to look less shitty

errant sable
#

That or like write a mod which automatically moves the ingame map view by a specific amount when you press a certain key, and then get some screenshot app which will auto save your screenshots. Then just quickly alternate pressing the two keys... lol

robust briar
errant sable
#

then write a little script to stitch them together, since you moved by known amounts, the stiching would be easy...

robust briar
#

then use getFileWriter and write it in

errant sable
#

Well, all that data (buildings, roads, shapes, etc) is already in the vanilla map file

#

So if that is the route you want to go, you can parse if from there instead of trying to hack pz to output it

robust briar
#

I honestly feel more comfortable hacking PZ to extract the data vs trying to rebuild the images from hand.

#

If worst come to worst, I'll build a custom PZ client to do it, but I REALLY don't want to do that lol

errant sable
#

why not just parse it from the map files?

robust briar
#

cause then I have to create my own renderer

#

and get all the colors, shapes, etc right

errant sable
#

its the same data your gonna get trying to sus it from PZ. Your not gonna get a png output out of PZ (of that particular map) unless you do screenshots

robust briar
#

Well at some point that data is converted to bitmap data and fed into an UIElement, so PZ can render it to screen.

#

if I can somehow get to that data, of the currently displayed map I can easily lua macro a quick "move X distance over, grab data, write, repeat" thing

errant sable
#

That data, if it is rendered to an image, is locked away outside of the scope of lua probably, and that is if its rendered to a image

#

it very possible (and the way I would do it) is to feed an SSBO to the shader with all the rect and color information

#

then let the shader do the culling and rendering, and then there would be no image at all anywhere but on the GPU

#

So you very much, and probably are, hunting for an image that literally doesnt exist

robust briar
#

hmmm.. that is possible. I didn't consider shaders