#mod_development

1 messages ยท Page 521 of 1

thin hornet
#

something like that

slow sparrow
#

well the world is running and I'm logging these in Events.EveryTenMinutes on the server, it stays 0

thin hornet
#

mhm

slow sparrow
#

I messed up, sorry. My test player died and I didn't notice. ๐Ÿคฆโ€โ™‚๏ธ

opal wind
# thin hornet mhm

hey man, could you give me a hand with this lua? i model for a long time but just started messing with lua... i want to make this Glove here (Hand body location) to give +4 Strenght when equiped, the code dont give errors but im missing something here because it dont give the bonus:

#
local function PowerGlovesEffect()
  local player = getPlayer()
  local perkLevel = player:getPerkLevel(Perks.Strength)

    if player:getClothingItem_Hands() == "Wiz_BatgirlGloves" then
      local modifier = 4;
        for i = 1, modifier do
          player:LevelPerk(Perks.Strength)
        end
      end
  end```
thin hornet
#

might want to try :setPerkLevelDebug(Perks.Strength, perkLevel + 4);

opal wind
#

replacing player:LevelPerk(Perks.Strength) ?

thin hornet
#

yeah thats the only method i found

opal wind
#

thanks i will try

#

hum but them i need to remove the local modifier no?

#

also i think i would also need a else (not equiped), set -4, or each time i equip will stack +4 no?

thin hornet
#

yeah

#

you have to revert might also have to save the XP values somewhere to adjust it and not reset the player xp also considering the xp gained while equipped

opal wind
#

hum but why he would gain XP when it add strenght?

thin hornet
#

in the code they seem to use this way

getPlayer():getXp():setXPToLevel(Perks.Strength, val);
getPlayer():setPerkLevelDebug(Perks.Strength, val)
thin hornet
opal wind
#

hum so i have to set for both? lol sorry im very noob on lua started couple days ago

thin hornet
#

Lets say

  1. im str level 5
  2. i need 30,000 xp point to level up
  3. i have 1000/30000 already.
  4. i equip the item, your script add 4 levels.
  5. now it show that i need 150,000 xp to level up.
    Just make sure the 1000 xp point he had already and any xp gained while equipped, is not lost
opal wind
#

huuum

#

im loading here with that first simple one you pass me to see if works

#
local function PowerGlovesEffect()
  local player = getPlayer()
  local perkLevel = player:getPerkLevel(Perks.Strength)

    if player:getClothingItem_Hands() == "Wiz_BatgirlGloves" then
      
        
          setPerkLevelDebug(Perks.Strength, perkLevel + 4);
        
      end
  end```
slow sparrow
thin hornet
#

great

thin hornet
#

also where do you call PowerGlovesEffect()

opal wind
thin hornet
#

what event you call this from? -> XXXXXXX

opal wind
#

lol no that is the part i dont know

thin hornet
#

you probably want to call this when equipping and unequipping the item

opal wind
#

yeah, but i dont know how to write that line lol

#

and this part i need lua local newLevel = 5; ?

thin hornet
#

Add this into a client script, and replace Base.PowerGloves for your item Module.ItemName


-- Hook into the equip weapon action
-- Check if the item that was equipped is your powerglove
-- Add the strength perk level
local ISEquipWeaponAction_perform = ISEquipWeaponAction.perform;
function ISEquipWeaponAction:perform(...)
    ISEquipWeaponAction_perform(self, ...);

    if self.item:getFullType() == "Base.Wiz_BatgirlGloves" then
        print("Equipping Wiz_BatgirlGloves")
        -- add strenght perk levels
        local currentLevel = self.character:getPerkLevel(Perks.Strength);
        local currentStrengthXP = self.character:getXp():getXP(Perks.Strength);

        self.character:getXp():setXPToLevel(Perks.Strength, currentLevel + 4);
        self.character:setPerkLevelDebug(Perks.Strength, currentLevel + 4);

        -- save current xp for when unequipping later
        self.item:getModData().strengthXPbeforeEquipping = currentStrengthXP;
    end
end

-- Hook into unequip action
-- Check if the item that was unequipped is your powerglove
-- Remove the strength perk level
local ISUnequipAction_perform = ISUnequipAction.perform;
function ISUnequipAction:perform(...)
    ISUnequipAction_perform(self, ...);

    if self.item:getFullType() == "Base.Wiz_BatgirlGloves" then
        print("Unequipping Wiz_BatgirlGloves")
        -- remove strenght perk levels
        local currentLevel = self.character:getPerkLevel(Perks.Strength);
        local currentStrengthXP = self.character:getXp():getXP(Perks.Strength);

        self.character:getXp():setXPToLevel(Perks.Strength, currentLevel - 4);
        self.character:setPerkLevelDebug(Perks.Strength, currentLevel - 4);

        -- restore last xp + gained xp after
        local xpGainedWhileEquipped = Perks.Strength:getTotalXpForLevel(currentLevel) - currentStrengthXP;
        local strengthXPbeforeEquipping = self.item:getModData().strengthXPbeforeEquipping;
        self.item:getModData().strengthXPbeforeEquipping = nil; -- reset the modData

        -- set the current xp
        self.character:getXp():AddXPNoMultiplier(strengthXPbeforeEquipping + xpGainedWhileEquipped);
    end
end

#

This is gonna need a little bit more code cause this will reset any xp gained before and after which is a problem.

opal wind
#

oh because it brings back to a certain level i see

thin hornet
#

yeah

#

you could save the info into the item modData to restore it and calculate the new xp gained into it

#

also idk if there is a better way of doing this without all this code thats just something i came up with real quick

signal frost
#

I'm currently working on a mod that will replace an existing clothing item with an extra feature.
My current assumption is that:
clothing_jackets will get pulled in at some point in time when the client/server launches
I want to find the item I intend on replacing, remove it from the collection and add mine back in instead (effectively overriding the base version)

Is this assumption correct/best practice? Ideally I'd like to modify as little as possible for compatibility purposes

opal wind
#

function: perform -- file: ISUnequipAction.lua line # 63
function: perform -- file: Wiz_BatgirlGloves.lua line # 24

LOG : General , 1644312565448> bugged action, cleared queue zombie.characters.CharacterTimedActions.LuaTimedActionNew@26dbc6df
LOG : General , 1644312571431> -------------------------------------------------------------
attempted index: sound of non-table: null

LOG : General , 1644312571431> -----------------------------------------
STACK TRACE

function: perform -- file: ISUnequipAction.lua line # 63
function: perform -- file: Wiz_BatgirlGloves.lua line # 24

ERROR: General , 1644312571432> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: attempted index: sound of non-table: null at KahluaThread.tableget line:1689.
ERROR: General , 1644312571432> DebugLogStream.printException> Stack trace:

small topaz
#

Hi! I am trying to add text descriptions to a mod so that they can easily be translated to other languages. I tried using constructuions like local text = "UI_myCustomText" or local text = getText("UI_myCustomText") and then defining the actual text in a txt file in /lua/shared/Translate/EN/UI_EN.txt via UI_myCustomText = "here is my text". i had no success so far. does anyone knows how to introduce custom UI_something strings properly into game? thanks!

thin hornet
opal wind
#

ah cool i will give it another shot

thin hornet
#

its not completed too

opal wind
#

ty

opal wind
thin hornet
#

did you replace the item type in the code example to fit your item?

#

if self.item:getFullType() == "Base.PowerGloves" then

opal wind
#

ye

thin hornet
#

try add a print and see if it run at all

opal wind
#

if self.item:getFullType() == "Wiz_BatgirlGloves" then

thin hornet
#

you need to add the module

opal wind
#

my mod ID?

thin hornet
#

your script item.txt

#

it start with a module

opal wind
#

i never use them i think

thin hornet
#

show me the script txt file that add your gloves

opal wind
#

module Base
{
}

#

its liek this

#

i got 150 items lol

thin hornet
#

then Base.Wiz_BatgirlGloves

opal wind
#

kk

mild berry
#

Got a question on how TV scheduling works. I wanna mod a TV guide into the game. You know, the ones from back then when you had to get a Magazine to know whats on TV.

Are the schedules there actual schedules randomly generated. Or does the game randomly decide what show to broadcast when a set broadcasting time is met?

thin hornet
opal wind
#

item Wiz_BatgirlGloves
{
DisplayCategory = Accessory,
Type = Clothing,
DisplayName = Batgirl Gloves,
ClothingItem = Wiz_BatgirlGloves,
BodyLocation = Hands,
BloodLocation = Hands,
Icon = Wiz_BatgirlGloves,
ScratchDefense = 15,
BiteDefense = 10,
Weight = 0.1,
Insulation = 0.5,
WindResistance = 0.5,

    WorldStaticModel = GlovesLong_Ground,
}
thin hornet
#

your item in the txt file is already inside the module Base {}

#

@opal wind you could use a different module name

}```
#

This way it would prevent some mod conflict

opal wind
#

i know, i just tested and its not adding the bonus yet

#

hard stuff lol

mild berry
signal frost
#

Where are mods I downloaded from the workshop saved, so I can look at examples?

thin hornet
#

@signal frost here
C:\Program Files (x86)\Steam\steamapps\workshop\content\108600

signal frost
#

Life saver, thank you

thin hornet
#

@opal wind

actually i had errors lol I used this instead of self

#

-- Hook into the equip weapon action
-- Check if the item that was equipped is your powerglove
-- Add the strength perk level
local ISEquipWeaponAction_perform = ISEquipWeaponAction.perform;
function ISEquipWeaponAction:perform(...)
    ISEquipWeaponAction_perform(self, ...);

    if self.item:getFullType() == "Base.Wiz_BatgirlGloves" then
        print("Equipping Wiz_BatgirlGloves")
        -- add strenght perk levels
        local currentLevel = self.character:getPerkLevel(Perks.Strength);
        local currentStrengthXP = self.character:getXp():getXP(Perks.Strength);

        self.character:getXp():setXPToLevel(Perks.Strength, currentLevel + 4);
        self.character:setPerkLevelDebug(Perks.Strength, currentLevel + 4);

        -- save current xp for when unequipping later
        self.item:getModData().strengthXPbeforeEquipping = currentStrengthXP;
    end
end

-- Hook into unequip action
-- Check if the item that was unequipped is your powerglove
-- Remove the strength perk level
local ISUnequipAction_perform = ISUnequipAction.perform;
function ISUnequipAction:perform(...)
    ISUnequipAction_perform(self, ...);

    if self.item:getFullType() == "Base.Wiz_BatgirlGloves" then
        print("Unequipping Wiz_BatgirlGloves")
        -- remove strenght perk levels
        local currentLevel = self.character:getPerkLevel(Perks.Strength);
        local currentStrengthXP = self.character:getXp():getXP(Perks.Strength);

        self.character:getXp():setXPToLevel(Perks.Strength, currentLevel - 4);
        self.character:setPerkLevelDebug(Perks.Strength, currentLevel - 4);

        -- restore last xp + gained xp after
        local xpGainedWhileEquipped = currentStrengthXP - Perks.Strength:getTotalXpForLevel(currentLevel);
        local strengthXPbeforeEquipping = self.item:getModData().strengthXPbeforeEquipping;
        self.item:getModData().strengthXPbeforeEquipping = nil; -- reset the modData

        -- set the current xp
        self.character:getXp():AddXPNoMultiplier(Perks.Strength, strengthXPbeforeEquipping + xpGainedWhileEquipped);
    end
end

im testing, i will correct it

signal frost
#

Do lua files automatically run if in the correct folders?

#

Or do they need to be added to some list somewhere

opal wind
#

thank you!

thin hornet
signal frost
#

Okay, great

#

That's a bit janky but I'm glad it's that easy hahaha

thin hornet
#

Global objects
scriptA:

myGlobalObject = {}

scriptB:

require 'scriptA'
print( type(myGlobalObject) )

Not Global object
scriptA:

local myObject = {}:
return myObject; -- file can return an object

scriptB:

local myObject = require("scriptA")

signal frost
#

require is some kind of import I take it

thin hornet
#

require will simply ensure that the required file is proccessed before the caller

signal frost
#

Ah nice

thin hornet
#

a good practice is to use directory name into your mod.
client: media/lua/client/MyModClient/myFile.lua
server: media/lua/server/MyModServer/myFile.lua
shared: media/lua/shared/MyModShared/myFile.lua

then you can require them like this
require 'MyModClient/myFile'
require 'MyModServer/myFile'
require 'MyModShared/myFile'

this will prevent lua file with same name and path to be overwritten or conflict

signal frost
#

So media/lua/xxx/ is considered the root as far as require is concerned?

#

xxx being server or client, whichever is relevant

thin hornet
#

yeah require ignore the media/lua/client|server|shared

#

so having a file with same name in client and server would be confusing i believe

cold burrow
#

Konijima
Can i take your time too, while you are here? :)

Is it possible to add additional context menu button for weapon?
And...how?

signal frost
#

Yeah that makes sense

signal frost
cold burrow
thin hornet
#

@cold burrow

this would look like this

local function functionToCallOnItem(item)

end

local function OnFillInventoryObjectContextMenu(player, context, items)
    for _, _items in ipairs(items) do
        if instanceof(_items, "HandWeapon") then
            local option = context:addOption("Context option title", _items, functionToCallOnItem);
            break;
        else
            for j, item in ipairs(items) do
                if instanceof(item, "HandWeapon") then
                    local option = context:addOption("Context option title", item, functionToCallOnItem);
                    break;
                end
            end
        end
    end
end
Events.OnFillInventoryObjectContextMenu.Add(OnFillInventoryObjectContextMenu);
cold burrow
#

I looking for a way to add context button to weapon and then while this button clicked -> pass function.

signal frost
thin hornet
#

np

signal frost
thin hornet
#

The way i like to make my mods, it to separate and return my object and require them when needed.
I find nested structure to be messy on massive scale
I also like to use the fewest global possible

#

classes and object that can used both by client and server are in my shared such as utilities class, or table of data, data map etc.

cold burrow
thin hornet
#

the equipWeapon act exactly as that

#

its just they named it this way

bitter frigate
#

with type 2 diabetes that's absolutely correct!! there is an important difference between type 1 and type 2 diabetes, beside the first being principally found in adolescents - type 1 diabetes is also called insulin dependant diabetes. in it, your pancreus stops making insulin altogether. you cannot survive without insulin. your cells cannot get energy from the food you eat without insulin, and you eventually starve to death, even though you eat. the hp loss at high and low blood sugars is meant to represent the acute danger present in extreme cases of hyper and hypoglycemia, where coma and seizure become increasing potentialities. while i believe it's possible to simulate a coma in zomboid, the effect would be the same as character death, and so i think the hp damage function works acceptably in this instance.

traditionally the wasting would happen over a prolonged period of time, while the pancreus still sporadically made insulin. this mod essentially "takes place" years AFTER diagnosis, when the wasting would be circumvented by a more immediate coma.

that SAID ive considered making a type 2 diabetes mod as well, specifically to capture the fact that while potentially debilitating, one could live for years with persistantly high glucose, but thats putting the cart before the horse a bit, since type 1 and type 2 are very different diseases

cold burrow
# thin hornet the equipWeapon act exactly as that

While i trying to equip for example sneakers or pants, it's not working.
simple example just to test:

local ISEquipWeaponAction_perform = ISEquipWeaponAction.perform;
function ISEquipWeaponAction:perform(...)
    ISEquipWeaponAction_perform(self, ...);

    print("eq")
end


local ISUnequipAction_perform = ISUnequipAction.perform;
function ISUnequipAction:perform(...)
    ISUnequipAction_perform(self, ...);

    print("uneq")
end

But works while i trying to equip something in hands.

#

Still really good to know how to hook timed actions. It's a gem for me. :D

thin hornet
#

oh that would probably be the action ISWearClothing

cold burrow
#

Will try to test it right now. :)

#

It works.

thin hornet
#

๐Ÿฅณ

slate stag
#

Guys what are the best mods for beginners?

thin hornet
cold burrow
# thin hornet <@!238089957795692544> this would look like this ```lua local function functio...

Really sorry to bore you, i have no idea why, but i can't make it works.

local function functionToCallOnItem(item)
    print("This is a print from function")
end

local function OnFillInventoryObjectContextMenu(player, context, items)
    for _, _items in ipairs(items) do
        print(items) -- <-- Returns table
        print(_items) -- <-- Returns table

        if instanceof(_items, "HandWeapon") then
            print("table _items") -- <-- Returns nothing
            local option = context:addOption("Context option title", _items, functionToCallOnItem);
            break;
        else
            for j, item in ipairs(items) do
                print(items) -- <-- Returns table
                if instanceof(item, "HandWeapon") then
                    local option = context:addOption("Context option title", item, functionToCallOnItem);
                    break;
                end
            end
        end
    end
end

Events.OnFillInventoryObjectContextMenu.Add(OnFillInventoryObjectContextMenu);
thin hornet
#

@cold burrow its because OnFillInventoryObjectContextMenu param items can be an item or a table of selected items from the inventory pane.

cold burrow
#

How's game defines that is "HandWeapon"? Maybe i could use something like SubCategory = Firearm?

thin hornet
#

you can check the item how you want, you could actually replace "HandWeapon" to "InventoryItem" and then check for other values on the item if you need more specific

thin hornet
#

when you select an item in the inventory, sometime you might select a single item or a group of items, so that why we have to check for both case

cold burrow
thin hornet
#

when selecting the first red square it return all items in that stack.
when selecting the second red square it return that item itself.

#

well actually it's a little more complex than how i describe it

cold burrow
#

ooooh

thin hornet
#

You can add error(items); at the top, whent he debuger open with the error you can browse the data

local function OnFillInventoryObjectContextMenu(player, context, items)
  error(items)
#

this willl help visualize how its structured

#

like just double click it and it will go inside the table

cold burrow
sinful idol
#

Does anyone have a way for resetting zombie modData whenever the game object is reused? There's no OnZombieReset callback I can use.

thin hornet
sinful idol
thin hornet
#

in SP it might be -1 i think

thin hornet
sinful idol
bronze arch
#

Hey anyone know anything about the autotsar trailer mod? I finally found a camper van, is there supposed a texture on the "switch seat" menu?

sinful idol
#

I think the OnlineID suggestion would work though ๐Ÿ™‚

bronze arch
#

with like a diagram of the trailer, like how a car is

thin hornet
gilded hawk
#

I'm looking into making BritaWeaponPack an optional requirement for my mod. How can I detect if the game has Brita loaded?
I was thinking about check if one of the custom globals of GunFighters exists

signal frost
gilded hawk
#

๐Ÿ‘€

#

Dude you absolute genius โค๏ธ

signal frost
#

Hahaha I'm just recycling code that Konijima sent me an hour ago

gilded hawk
#

Good anyway

signal frost
#

good luck

gilded hawk
#

Konijima POG

#

Thanks man

#

I have like 30 min of lunch break to try and make it work

#

I assume I need to check for Brita since it's the mod ID

signal frost
#

Yeah, looks that way

#

It seemed odd that it would just be Brita, but I think you're right

gilded hawk
#

ChikaShrug

name=Brita's Weapon Pack
id=Brita
poster=preview.png
description=New weapons added
require=Arsenal(26)GunFighter
signal frost
#

Yeah I think you're on the money

#

2200148440 is Brita too, if you need that

drifting ore
#

Work like a charm, thx again

slow sparrow
#

anyone know how to get a player's favorite weapon in Lua?

drifting ore
# slow sparrow anyone know how to get a player's favorite weapon in Lua?

This is the function use in the vanilla game

ISCharacterScreen.loadFavouriteWeapon = function(self)
    self.favouriteWeapon = nil;
    local swing = 0;
    for iPData,vPData in pairs(self.char:getModData()) do
        for index in string.gmatch(iPData, "^Fav:(.+)") do
            if vPData > swing then
                self.favouriteWeapon = index;
                swing = vPData;
            end
        end
    end
end
#

should be able to be easily modify it

slow sparrow
#

I thought getModData would relate to... mods

drifting ore
#

The game uses it for something because it's mostly data sticking to the player

#

But I thought that too at first

slow sparrow
#

I see, now I wonder what else is hiding in there

#

thanks a lot!

hollow drum
#

How can I make a "normal" item have a lower "equipped" weight? It seems they aren't impacted by this, and to get that effect I have to make it a "drainable" or some other type of item.

drifting ore
slow sparrow
#

ok I'll have a look

drifting stump
#

is my game bugged or am i going mad

#

if i get the players inventory on the server its empty

drifting ore
drifting stump
#

im sending a client command

#

and on receive i use the player arg

#

ive also tried getting by num or id

drifting ore
#

Are you sending the player object?

drifting stump
#

it sends by default but yes ive tried manually sending

drifting ore
#

For my mod I send player:getOnlineID() on the client side to the server side and then use local otherPlayer = getPlayerByOnlineID(onlineID) on the server side

drifting stump
#

thing is the object is there no matter how i get it

#

i can do getUsername() and it shows the right one

drifting stump
#

getInventory() gives an empty array

drifting ore
thin hornet
#

i mean you dont have to send anything

#

sendClientCommand will send the player no matter what

drifting ore
#

It's an other player

#

not the local one

thin hornet
#

mmk in that case that make sens

drifting ore
#

And how do you get the inventory?

drifting stump
drifting ore
#

Ok well except with the online ID as I showed you, I don't know. If you have the player object on the server, getInventory() should work. Maybe the inventories are not accessible from the server, no idea

drifting stump
#

as i said i tried it

drifting ore
#

Maybe try getPlayerInventory(playerNum).inventoryPane.inventoryPage.backpacks

#

It's how I gett all backpacks that the player wear. I know that in inventoryPage there is an other tables that backpacks with items from inventory

drifting stump
#

why would there be a self

drifting ore
#

It's just a copy past

thin hornet
#

you can easily get all players with local players = getOnlinePlayers(); on the server
it return an ArrayList of IsoPlayers

#

now for the inventory, i suspect the player inventory is transmitted only when the player is being saved.

#

been looking though the source but can't find anything special to get a player inventory from the server.

drifting stump
#

i even saw vanilla code getting the inventory on the server

thin hornet
#

alot of code in the server directory are actually running on the client

#

like recipe code etc

#

idk why tho

#

Try adding item to the player inventory from the server and see if it "transmit" it to your client player

drifting stump
#
print(getOnlinePlayers():get(0):getInventory():getItems())
thin hornet
#

getOnlinePlayers():get(0):getInventory():AddItem("Base.Axe")

#

check if that at least reflect to the client for the inventory being empty i feel there is something that need to be requested

drifting stump
#

didnt receive the item

thin hornet
#

i dont think the game send all item to the server instantaneously. It must have a buffer cause sometime we transfer hundred of items

drifting stump
#

but it did add the item to the inventory

thin hornet
#

i think the game will transmit the actual player only when "saving" before closing or when client quitting

#

not sure just theories

drifting stump
#

reconnecting to try

#

nope still dont have the axe

#

it was successfully added to an inventory

#

but not the characters

thin hornet
#

what do you want to do with the inventory from the server?

drifting stump
#

edit item properties on the server side

thin hornet
#

can i have a use case, like an example

drifting stump
#

in this specific case i need to set mediadata

#

not like i can get to that since the inventory is empty

thin hornet
#

when does that happen, user action? timer?

drifting stump
#

atm on click i send a client command

drifting ore
#

Why not change it on the client side ?

drifting stump
drifting ore
#

You can use obj:sendObjectChange("state")

#

Like if you change the sprite of an item
obj:sendObjectChange("sprite")

drifting stump
#

ill test that but id still like to know whats happening with the inventory

drifting ore
#

It's just that you can't get it on the server side

#

To avoid sending to much data

thin hornet
#

sendObjectChange seem to be for isoObject

drifting stump
#

the server has to be storing the inventory else on connect you wouldnt have anything

drifting ore
thin hornet
#

i think he is talking about InventoryItem

#

Im lacking info to understand properly

drifting ore
#

Mmmmm yeah make sens

drifting stump
#

indeed there is sendObjectChange checked the docs

drifting stump
#

on received client command get players items

#

everything else can be ignored ive commented any other code out to test

thin hornet
#

well getting the items on server seem to not work so you gonna have to figure an other way probably

#
  1. what do you click?
  2. send commend to set item data?
  3. Item is in player inventory or container?
  4. Changing media data is it a vhs or something like that?
  5. What is the player and other player suposed to see
drifting stump
#

click a key literally just OnKeyPressed

#

yes the item is in the players inventory

#
  1. and 4) irrelevant to this since i cant even get the items
#

might be an issue with my server globalmoddata isnt even persisting

sinful idol
#

Would anyone know why I can't access certain properties through lua? Whenever I do


local function handleZombieUpdate(zombie)
    if zombie:isAlive() then
        print(zombie.speedType)
    end
end

It says speedType is nil, but the debugger says the correct value (i.e. 2). Is that intentional?

drifting ore
#

Can I add custom fonts ?

small topaz
#

does anyone know how to get the slot index of a worn holster via lua code? (is an integer.)

drifting stump
drifting ore
#

To get it getPlayerHotbar(playerNum)

thin hornet
sinful idol
cold burrow
#

Is there any way to get item custom properties?
Like foo = bar?

thin hornet
cold burrow
thin hornet
#

not sure what you mean by "custom"

#

and are you talking about InventoryItem class?

cold burrow
# thin hornet not sure what you mean by "custom"

If i add something to item in scripts or lua, like:

local item = ScriptManager.instance:getItem("Base.ExampleItem")
if item then
  item:DoParam("foo = bar")
end

How could i get value for foo property?

faint jewel
#

foo is bar man... FOO IS BAR!

cold burrow
#

It's not required atm actually, but it would be nice to know.

#

To add/read custom properties.

quasi geode
thin hornet
quasi geode
#

well short version, when you add custom properties into the the scripts .txt, it gets added to a 'defaultModData' table (a field in Item.class)..when a item spawns as a InventoryItem instance, all those custom key/values get transferred to the item's modData table
since the unspawned script item has no get/set method for the defaultModData table, have to take a more hackish route to get it

#

but as mentioned before (few lines down from that pasted message) that was more proof of concept code then anything. it could do with some cleaning and optimization

thin hornet
#

nice to know ty

small topaz
# drifting ore To get it `getPlayerHotbar(playerNum)`

at the lua event OnNewGame the command getPlayerHotbar(playerNum) seems to call a nil value although the slot index for the holster is already defined (I added the holster as a custom clothing to the character before the game starts)

drifting ore
#

Does UTF-8 is ok for chinese ?

drifting ore
weary matrix
drifting ore
#

It's in UTF-8 in the vanilla game and my mod but someone told me that it's not working. Wait maybe not in my mod

small topaz
# drifting ore OnNewGame the player is not create yet

the slot index is already there and is 2 in my case OnNewGame. i can work with it and attach a weapon at this event which works fine. could go on and simply hardcode "2" but I am afraid this might not so good for stability....

thin hornet
#

might not be a good solution for respawning new character in mp, my bad..

quasi geode
# drifting ore OnNewGame the player is not create yet

player is technically created already in OnNewGame. the IsoPlayer instance is one of the arguments to the event callbacks (IsoPlayer and IsoGridSquare)..though i'm not sure if its fully spawned in until after the event is called

drifting ore
#

Ok mb

small topaz
#

np ๐Ÿ˜‰ any idea might be helpful!

#

point is: since the holster already has a slot index at this event, i would be surprised if there isn't any "smooth" way to call it somehow

edgy wharf
#

I still need help with this. Day 3 of staring at it trying to figure out what is wrong.

#

so basically at this line: local weaponPerkLvl = ACAC.getPerkLevel(_player, ACAC.currentWeapon)
** I think ACAC.currentWeapon errors out due to calling nil**

Object tried to call nil in OnWeaponSwing

I've also had it say this about the same line:

Object tried to call nil in Unknown

#

It's something to do with the categories being wrong, maybe? Because it throws this error with every weapon type.

#

**I've tried changing ACAC.currentWeapon to **

        ACAC.OnEquipPrimary(_player, "HandWeapon")
    end

And

        ACAC.OnEquipPrimary(_player, _item)
    end

Both of these changes break the code entirely.

warm sequoia
sinful idol
#

@warm sequoia I think there are already mods that do that for deaf (requires hearing aids) and nearsighted/farsightedness (requires glasses and autozooms you in/out)

#

I think hydrocraft adds them but there are other lighter options as well

warm sequoia
#

oooh, if you ever find some links to those let me know

sinful idol
quasi lichen
#

How do I go about removing the clipping issue, and the random added gray tile underneath anything placed down in Tile mode?

undone crag
#

Oh, maybe that glitch is fixed or only happens in specific situations.

undone crag
opal wind
drifting ore
opal wind
#

u know any mod with attachments for Firearms with .fbx i could look?

#

the attachment is flooting about 5m above the char lol

undone crag
#

I do not knonw any. You could adjust the attachment point on the weapon's model but that could be problematic if the attachment is the problem.

fiery pecan
#

hi there. Relatively new modder here (about half a year's experience with clothing mods/vehicle skins, no models).
So anyways, when I try to run "sendObjectChange()" in my code, it works in SP, but MP (Specifically the local server, from the host menu), returns with " sendObjectChange() can only be called on the server" How would I fix this?

undone crag
#

You could use this #mod_development message
The person who posted this got client and server the wrong way around somewhere though, which took me more than a few tests to find out. :c

fiery pecan
#

ah, thankies

indigo kiln
#

Please advise:
I've got a stupid question. I can't get custom wheels to spawn. What am i doing wrong?
Wheel model is in place, but it doesnt spawn for some reason. The error is definitely in the script, using other version it works...

I've lifted the template from vanilla station wagon, sadly seems like all vanilla cars have the same wheels so i cant steal that code too... I have the custom wheel template, and i have my custom models declared. What am i missing?

opal wind
undone crag
#

ยญ ยฏ_(ใƒ„)_/ยฏ

zealous pebble
#

Ey if I wanted to make a really small weapon mod that adds two items how would I go about that. I'm bad at art assets but then again the game isn't about art.

drifting ore
#

Is there an event for when the player quit ?

zealous pebble
#

I mean I could make it into a larger mod but i want to start with this.

#

Also is most of the modding just text files or no

undone crag
opal wind
#

both are .fbx

undone crag
#

I have not had that problem and I have not had to fix it. :\

opal wind
#

you made your guns .x?

#

also you see that attachment name on the side there? that name must be the same as the 3rd/4th or the 1st/2nd on the weapon file?

#

ModelWeaponPart = Base.WizGunLightsmall Base.WizGunLightsmall wizgunlight wizgunlight,

undone crag
#

I have tried .x and .fbx but I have not tried .fbx attachments.

#

Something the same name as something on the weapon file?

opal wind
#

?

#

i dotn get it lol

dark solar
#

needs more big red arrows i think

opal wind
#

LOL

#

hey mr_anon i think i found the thing, since its .fbx i think its a scale thing, messes around with all the attachment positions

#

i will make a test here

undone crag
#

(deleted)

opal wind
#

yes? lol

#

its my first name, what about it?

undone crag
#

Dese ppl de doxing they/themselves tfw

#

Just wait for me to reupload your mod so that you give me your full address muahahahahaha

opal wind
#

im getting closer

#

so it was the scale; .fbx are x100 smaller, now the scale is right

#

i think nobody did .fbx weapons with attachments yet

#

im a pionner here lol

opal wind
#

mother of GOd...

#

i did not needed debug mod tool at all

#

was just the scale thing and the position is this

#

attachment wizgunlight
{
offset = 0.0000 0.0000 0.0000,
rotate = 90.0000 0.0000 0.0000,
}

#

just 1 rotation

#

.fbx need to scale the weapon part to scale = 0.0.1 (this info will be usefull for all who make .fbx gun/attachments)

#

now all i need to do is making the light turn On lmao

opal wind
#

guys is this here right? i need to put the key name in () ?

#
if (keyNum == getCore():getKey(KEY_COMMA)) then```
undone crag
#

In lua, you can use a boolean thing without brackets around it.

green venture
#

Is it possible to spawn a weapon preloaded with ammo?

fiery pecan
#

I might be just dumb though

fair frost
thin hornet
# fiery pecan I might be just dumb though

Client Script

local function OnServerCommand(module, command, args)
  if module == "myModule" then
    if command == "myCommand" then
      print("Recieve command " .. command .. " from server!")
    end
  end
end
Events.OnServerCommand.Add(OnServerCommand);

sendClientCommand("myModule", "myCommand", { test = 1 });

Server Script

local function onClientCommand(module, command, playerObj, args)
  if module == "myModule" then
    if command  == "myCommand" then
      print("Recieve command " .. command .. " from " .. playerObj:getUsername() .. " client!")
      sendServerCommand("myModule", "myCommand", args); -- send command to all clients
      sendServerCommand(playerObj, "myModule", "myCommand", args); -- send command to this client only
    end
  end
end
Events.OnClientCommand.Add(onClientCommand);
#

Note: sendServerCommand doesnt work in single player.
Solution:

local function sendServerCommandToAll(module, command, args)
  if not isClient() and not isServer() then -- is single player
    triggerEvent("OnServerCommand", module, command, args);
  else
    sendServerCommand(module, command, args);
  end
end
local function sendServerCommandTo(playerObj, module, command, args)
  if not isClient() and not isServer() then -- is single player
    triggerEvent("OnServerCommand", module, command, args);
  else
    sendServerCommand(playerObj, module, command, args);
  end
end
fiery pecan
sour nova
winged delta
#

Is it possible to increase the character limit when adding notes on maps, by modding the game?

errant gale
#

Does getPlayerIndex() work in solo? I tried it and the game returns an error code.

deep belfry
#

Hey modders... Is there any existing server options, debug settings or something to log or retrieve player stats, zombie bites in multiplayer? I'd like to be able to retrieve more information about players on the server for a discord bot to react to, but I don't see any logging of bites or stats in any db or bin file

fiery pecan
#

I assume you'll want the code snippets?

undone crag
thin hornet
#
playerObj:getPlayerNum() 
IsoObject.getPlayerIndex() --  actually is static and return the assumed player object index if found.. not sure what that mean exactly

both return the same playerIndex

thin hornet
# fiery pecan guess I'll explain what I'm trying to do. In essence, I've been writing code to ...

zombie\iso\IsoObject.java

   public void sendObjectChange(String var1) {
      if (GameServer.bServer) {
         GameServer.sendObjectChange(this, var1, (KahluaTable)null);
      } else if (GameClient.bClient) {
         DebugLog.log("sendObjectChange() can only be called on the server");
      } else {
         SinglePlayerServer.sendObjectChange(this, var1, (KahluaTable)null);
      }

   }

// got a couple overload
public void sendObjectChange(String var1, KahluaTable var2)
public void sendObjectChange(String var1, Object... var2)
fiery pecan
#

here's hoping I can learn the answer to my dilemma from that...

round zenith
#

Is there an easy way to have it so that when you spawn a car it either has the key in it or gives you a key via Lua?

fiery pecan
#

Don't know how to use it tho

thin hornet
#

same command used for the cheat that give you the car key

#

also check client\DebugUIs\ISSpawnVehicleUI.lua for spawning

pine tree
#

I wrote 4500 lines of code today in just under 30 minutes!

thin hornet
#

Real question is, did it work first try?

#

if so then have a couple cake Item_CakeBlackForest Item_CakeRedVelvet Item_CakeStrawberryShortcake

pine tree
#

I was just adding items to a store mod that I have, I guess I didnt hand write them but instead used Notepad++ functions to turn 604 lines of code into 4554! Should be more as I need to add a couple more lines

#

to each item

thin hornet
#

Okay then i think you also deserve a burger Item_Burger

small topaz
# drifting ore It's in UTF-8 in the vanilla game and my mod but someone told me that it's not w...

in case anyone is interested: my current workaround is to attach weapons by modifying the vanilla function ISHotbar:refresh() and append some code to it. In this function, the slot index is easily available. btw, a question to everyone: is appending code to a vanilla function considered a somewhat "safe" way when it comes to overwriting issues and compatibility with other mods? to append code, I always use constructions like this:

willow estuary
#

Yeah, looks like you have a handle on the standard good method for modifying vanilla functions.

small topaz
#

thx for feedback! very helpful to learn from experienced modders how to do things in a proper way to minimize risk of bugs/instability/incompatibility

pine tree
#

hnnnnng finally finished

thin hornet
#

@small topaz if you want to improve it a little bit

local ISHotbar_refresh = ISHotbar.refresh;
function ISHotbar:refresh(...)
  ISHotbar_refresh(self, ...);
  
end

I use the real name with _ . (this is personal preference)
I use ... in case TIS decide to add parameter in the future that would ensure that any new parameters would still be passed.
Other than that you got it

small topaz
#

thx for the hint! i'll use it!

thin hornet
#

Anyone know whats the correct path/naming to place new trait texture icon?
media/ui/Traits/trait_mytrait.png think i got it

cinder rune
#

I'm using the true music mod but recently i'm getting ATA_Bampers template error when trying to host but it was working fine a few days ago, anyone know what's up? Tried unsubbing and redownloading mods, reinstalling zomboid, everything works fine if i disable true music so it's deffo just that mod or the mods it requires to work (TCC and Tsarlibrary)

thin hornet
cinder rune
#

my bad lol

river tree
#

Having an issue at the moment with removal of a sprite from an IsoObject... Can't figure it out for the life of me:

require('luautils');

local function onGroundCleanupCommand(module, command, player, args)
    if module == 'GroundCleanup' then
        if command == 'GroundCleanupCommand' then
            local sq = getCell():getGridSquare(args.x, args.y, args.z)
            
            if not sq then return end
            
            for i = 0, sq:getObjects():size() - 1 do
                local object = sq:getObjects():get(i);
                if object:getName() == "Generic" then
                    local attached = object:getSprite()
                    if object:getName() ~= nil then
                            local sprite = attached:getName()
                            if (luautils.stringStarts(sprite, "d_generic_1")) then
**                                object:RemoveAttachedAnim()**
                                object:transmitUpdatedSpriteToClients()
                        end
                    end
                end
            end
        end
    end
end

I'm getting an exception on line

object:RemoveAttachedAnim()

that states:
Callframe at: RemoveAttachedAnim()

#

(This specific tile) Trying to target the d_generic_1_23 sprite

small topaz
#

does anyone knows what maximal value for dirtyness of clothing is?

gilded hawk
#

I was wondering, is there a mod that makes the loot of the ||secret military base west of the Knox Prison|| good?
If not, how can I make it myself? with loot that can respawn

narrow urchin
#

Does anyone know if addZombiesInOutfit in MP works, or simply spawning zombies in MP? They seem to despawn right away.
Another question - is there any way to clear zombies from specified area?

drifting ore
weary matrix
drifting ore
#

Workshop\ModTemplate\preview.png is a gif for him

weary matrix
#

You mean you tried to use a gif and it's not working?

drifting ore
#

I can't, when I click on "create or update items", then choose the mod, then click next I get an error "There is no preview.png file in the folder you chose. A 256x256 PNG preview image is required for all workshop items"

#

But I want preview.png to be a gif

willow estuary
#

Try changing the image file suffix to png instead of gif?

drifting ore
#

I tried, it's doesn't move. It's just a png now

#

Maybe not, a guide on google seem to say the same thing as you

willow estuary
drifting ore
#

"The preview.png file could not be read. The format appears to be invalid."

#

New error

willow estuary
#

Maybe a hacked client is the trick? ๐Ÿ˜„

drifting ore
#

Mmmm, no idea but what annoying, I wanted a gif for my mod

faint jewel
#

Step 1: Make a .gif preview file using a software like photoshop.
It has to be under 1 MB file size for this to work.

Step 2: Put the preview.gif you exported in the About folder of your mod

Step 3: Change/Rename the file extension of your preview.gif to preview.png

drifting ore
#

That's exactly what I did. I imagine that the format of my gif is not the right one

vivid flare
#

why not just save a png

#

ohh i see

#

maybe try apng

thin hornet
#

Utilities class to help make mods work in SP and MP together more easily:

With this you can simulate your networked mod into a SP environment.
This help for developing networked mod in SP for faster testing, until ready to test on a server.

Add the Utilities.lua into your lua/shared directory to access it from both client and server scripts.

To import it in file that you need:
local Utilities = require("Utilities")

If you see improvement or have a bug let me know, hopefully that help you guys.

Part 1

---@class Utilities
local Utilities = {};

--- [SHARED]
--- Return true if game is single player
---@return boolean
function Utilities.IsSinglePlayer()
    return not isClient() and not isServer();
end

--- [CLIENT]
--- Return true if client is admin or single player + debug mode
---@return boolean
function Utilities.IsClientAdmin()
    return (isClient() and isAdmin()) or (Utilities.IsSinglePlayer() and isDebugEnabled());
end

--- [CLIENT]
--- Return true if the client is admin or moderator
---@return boolean
function Utilities.IsClientStaff()
    local playerObj = getPlayer();
    return Utilities.IsClientAdmin() or (playerObj and playerObj:getAccessLevel() == "Moderator");
end

--- [SERVER]
--- Return true if the IsoPlayer is admin or single player + debug mode
---@param playerObj IsoPlayer
---@return boolean
function Utilities.IsPlayerAdmin(playerObj)
    return (Utilities.IsSinglePlayer() and isDebugEnabled()) or (playerObj and playerObj:getAccessLevel() == "Admin");
end

--- [SERVER]
--- Return true if the IsoPlayer is admin or moderator
---@param playerObj IsoPlayer
---@return boolean
function Utilities.IsPlayerStaff(playerObj)
    return (Utilities.IsSinglePlayer() and isDebugEnabled()) or playerObj and (playerObj:getAccessLevel() == "Admin" or playerObj:getAccessLevel() == "Moderator");
end
#

Part 2

--- [CLIENT]
--- Send a command from the client to the server
---@param _module string
---@param _command string
---@param _data table
function Utilities.SendClientCommand(_module, _command, _data)
    if isClient() or Utilities.IsSinglePlayer() then
        sendClientCommand(_module, _command, _data);
    end
end

--- [SERVER]
--- Send a command from the server to a specific client
---@param _targetPlayerObj IsoPlayer
---@param _module string
---@param _command string
---@param _data table
function Utilities.SendServerCommandTo(_targetPlayerObj, _module, _command, _data)
    if isServer() or Utilities.IsSinglePlayer() then
        if Utilities.IsSinglePlayer() then
            triggerEvent("OnServerCommand", _module, _command, _data);
        else
            sendServerCommand(_targetPlayerObj, _module, _command, _data);
        end
    end
end

--- [SERVER]
--- Send a command from the server to all clients
---@param _module string
---@param _command string
---@param _data table
function Utilities.SendServerCommandToAll(_module, _command, _data)
    if isServer() or Utilities.IsSinglePlayer() then
        if Utilities.IsSinglePlayer() then
            triggerEvent("OnServerCommand", _module, _command, _data);
        else
            sendServerCommand(_module, _command, _data);
        end
    end
end

--- [SERVER]
--- Send a command from the server to all clients in range
---@param _x number
---@param _y number
---@param _z number
---@param _distanceMin number
---@param _distanceMax number
---@param _module string
---@param _command string
---@param _data table
function Utilities.SendServerCommandToAllInRange(_x, _y, _z, _distanceMin, _distanceMax, _module, _command, _data)
    if isServer() or Utilities.IsSinglePlayer() then
        if Utilities.IsSinglePlayer() then
            triggerEvent("OnServerCommand", _module, _command, _data);
        else
            local players = getOnlinePlayers();
            if players then
                for i = 0, players:size() - 1 do
                    local targetPlayer = players:get(i);
                    if Utilities.IsPlayerInRange(targetPlayer, _x, _y, _z, _distanceMin, _distanceMax) then
                        sendServerCommand(targetPlayer, _module, _command, _data);
                    end
                end
            end
        end
    end
end

--- [SHARED]
--- Return true if the IsoPlayer is in range
---@param _x number
---@param _y number
---@param _z number
---@param _distanceMin number
---@param _distanceMax number
---@return boolean
function Utilities.IsPlayerInRange(_playerObj, _x, _y, _z, _distanceMin, _distanceMax)
    if not _playerObj then return false; end
    local x2, y2, z2 = _playerObj:getX(), _playerObj:getY(), _playerObj:getZ();
    local currentDistance = IsoUtils.DistanceTo(_x, _y, _z, x2, y2, z2);
    return (currentDistance >= _distanceMin and currentDistance <= _distanceMax);
end

return Utilities;
thin hornet
dark finch
#

Hi everyone, is there a clothing mod that lets u wear any clothes at start but excluding the armor and backpacks

round zenith
thin hornet
#

no you dont have to be in the car to get the key with the debug option this command is exactly the same

#

but you need the reference to the vehicle yes

round zenith
#

@thin hornet if I have just spawned the car is there an easy way to check for it near me and get its reference, or alternatively force the player into the car?

thin hornet
#

@round zenith is the car spawned nearby the player?

round zenith
#

directly under them

#

it spawns where the player is

modest yarrow
#

local vehicle = playerObj:getVehicle() if not vehicle then vehicle = playerObj:getUseableVehicle() end if not vehicle then vehicle = playerObj:getNearVehicle()

#

found that in ISVehicleMenu.lua

round zenith
#

@modest yarrow @thin hornet TY TY TY it worked!

#

function CarCrafting_OnCreate(items, result, player)
addVehicle("CarNormal")

local vehicle = player:getVehicle()

if not vehicle then
vehicle = player:getUseableVehicle()
end
if not vehicle then
vehicle = player:getNearVehicle()
end
sendClientCommand(player, "vehicle", "getKey", { vehicle = vehicle:getId() })
end

#

now time to rewrite the method to handle way more values instead of just a single one.

unborn radish
#

anybody know why my shading is showing up over the damage overlays?

leaden dew
#

Guys, hello there!
How I can patch the workshop mod by other workshop mod?

willow estuary
leaden dew
willow estuary
leaden dew
willow estuary
leaden dew
#

Trying to Google it a week already

willow estuary
leaden dew
#

โ€œSeparated by a commaโ€โ€ฆ Then I do it right.

willow estuary
zealous pebble
#

so i wanted to do a smallish mod, idk how hard or easy it would be, i wanted to add a profession and a two items, It would be fencing instructor (to keep it simple for now) and two swords in the game, the catch is that the two swords aren't sharp they are practice swords, one is a poly longsword made of plastic, and the other would be a steel feder long sword, they would do blunt damage as they arent sharp. i used to do longsword fencing till i couldnt do it anymore for personal reasons so this would be a fun mod to add

#

also adding the practice helment i used and the padded jackets that i wore would be awesome

#

it was basically a cloth gambeson but for the sport

#

the real question is why hasnt anyone added baseball knee pads

#

easy and makes sense.

unborn radish
#

hella stuck on this

quartz badge
#

How would i make 556 mags and ammo spawn at gun stores for my mod

#

I also want to make a larger 9mm magazine, but i feel like it would be out of place to have a โ€œ9mm Magazineโ€ and a โ€œ30 Round 9mm Magazineโ€ and might confuse people

cold burrow
quartz badge
#

Oh, i was presuming i could make multiple guns use one magazine

cold burrow
quartz badge
#

I also want to make it so the 223 rifle has an internal magazine so i can use the 223 magazine for a different gun

cold burrow
quartz badge
#

I however have no coding experience so iโ€™m going to figure it out as i go

cold burrow
quartz badge
#

Oh i have modelling skills

#

Thatโ€™s why i want to make the mod

#

Hereโ€™s something i made a while ago, but i could do the pz style pretty well

cold burrow
quartz badge
#

You just have to keep doing it and over time you get better and learn tricks, thatโ€™s how i did it

#

Practice doesnโ€™t make perfect it just makes better

cold burrow
#

Also, is it hand painted model?

quartz badge
#

Itโ€™s not textured at all, just solid colors with lighting

#

Every detail is modeled

quartz badge
#

Thank you

#

Im gonna model some of the guns i want to add

faint jewel
quartz badge
#

I didnt make that for pz

#

Its just an example of my capability

faint jewel
#

oh i know. just looking ahead lol

quartz badge
#

I havent actually modeled anything for PZ yet

cold burrow
quartz badge
#

Here are some lower poly guns

#

I got a feeling i will

#

I'll update you guys on my progress

frank elbow
#

I don't know much about guns but those look v nice

quartz badge
#

Thanks

drifting ore
#

e11 blaster with max aiming

edgy wharf
cold burrow
nimble spoke
edgy wharf
#

local weaponPerkLvl = ACAC.getPerkLevel(_player, ACAC.currentWeapon)

#

At this point I think I'd be better off just making my own mod that determines the max amount of zeds hit based on strength level. Maybe this is just too advanced for me.

drifting ore
nimble spoke
#

so, make sure the variable is set, add a line before that one _player:Say(tostring(ACAC.currentWeapon)) just to check whay is going on. If the player ever says nil, you know that is probably the issue

edgy wharf
#

_player:Say(tostring(ACAC.currentWeapon)) What does this do?

nimble spoke
#

the player should "speak" in a text above his head whatever is stored as the weapon

modest yarrow
#

or do error(ACAC.currentWeapon)

#

that should break and give you the stack

edgy wharf
#

Okay ace I will try that out.

#

Thank you both.

nimble spoke
#

if you have a proper weapon stored in that variable I'd say check the whole ACAC.getPerkLevel again

edgy wharf
#
    local categories = _weapon:getCategories()
    for i = 0, categories:size()-1 do
        local s = categories:get(i)
        if        s =="Axe"         then return _player:getPerkLevel(Perks.Axe)
        elseif s =="SmallBlunt" then return _player:getPerkLevel(Perks.SmallBlunt)
        elseif s =="Blunt"         then return _player:getPerkLevel(Perks.Blunt)
        elseif s =="SmallBlade" then return _player:getPerkLevel(Perks.SmallBlade)
        elseif s =="LongBlade"     then return _player:getPerkLevel(Perks.LongBlade)
        elseif s =="Spear"         then return _player:getPerkLevel(Perks.Spear)
        elseif s =="Improvised" then return -1
        elseif s =="Unarmed"     then return -1
        end
    end
    if s ~= nil then
        print("S+ MOD ERROR: Weapon type not found:", s)
    end
    return -1
end```
#

This is the function for getPerkLevel

#

If it equals nil then it should print that there's a mod error in the console.

#

But it doesn't.

#

At least, not that message.

nimble spoke
#

double check the perk names, they could return nil if there's a typo or anything wrong with them

edgy wharf
#

Yeah it's across the board though for every category

#

I will double check in the API though.

cold burrow
#

How's hard to add new one attachment point PartType to engine? Like currently we have Canon, Scope, RecoilPad, e.t.c.

willow estuary
cold burrow
#

That's really, really sad.

nimble spoke
drifting stump
drifting ore
#

Lua is both really great

edgy wharf
#

@nimble spoke the mod throws the error in the loading screen when I'm continuing a game.

drifting ore
#

And the biggest headache

edgy wharf
#

Any thoughts on that?

#

Full stack log:

#
function: ongamestart -- file: DebugScenarios.lua line # 147

LOG  : General     , 1644437664184> Object tried to call nil in unknown
ERROR: General     , 1644437664190> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: Object tried to call nil in unknown at KahluaUtil.fail line:82.
ERROR: General     , 1644437664190> DebugLogStream.printException> Stack trace:
java.lang.RuntimeException: Object tried to call nil in unknown
    at se.krka.kahlua.vm.KahluaUtil.fail(KahluaUtil.java:82)
    at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:975)
    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:130)
    at zombie.iso.IsoWorld.init(IsoWorld.java:2688)
    at zombie.gameStates.GameLoadingState$1.runInner(GameLoadingState.java:260)
    at zombie.gameStates.GameLoadingState$1.run(GameLoadingState.java:217)
    at java.base/java.lang.Thread.run(Unknown Source)
LOG  : General     , 1644437664191> -----------------------------------------
STACK TRACE
-----------------------------------------
function: null -- file: LotsaZombies.lua line # 40
function: ongamestart -- file: DebugScenarios.lua line # 147```
nimble spoke
#

that's a different error

#

might want to check and fix that one first

edgy wharf
#

Yeah this one I've been getting more of than the other. It's weird.

#

I got the other one once and was working on fixing it, and now every time since then I get this one instead.

#

Wait would this just be from scenarios?

#

I am loading into a new scenario.

nimble spoke
#

looks like it is related to debug scenarios

edgy wharf
#

Maybe I should try in a new game?

nimble spoke
#

yeah

bitter frigate
#

can anyone recommend any mods that add moodles? i'm trying to reverse engineer the process to create my own

sour nova
#

maybe check the alcoholism mod?

quartz badge
#

First model ive made for PZ, trying to maintain the style

sour nova
#

ItemValueTable["Base.TrapBox"] = 0.00; ItemValueTable["Base.TrapCrate"] = 0.00; ItemValueTable["Base.BookTrapping1"] = 1.00; ItemValueTable["Base.BookTrapping2"] = 1.00; ItemValueTable["Base.TreeBranch"] = 0.00; ItemValueTable["Base.Trout"] = 0.00; ItemValueTable["Base.HandShovel"] = 2.00; ItemValueTable["Base.TunaTin"] = 1.00; ItemValueTable["Base.PaintTurquoise"] = 0.00; ItemValueTable["Base.TVDinner"] = 0.00; ItemValueTable["Base.Remote"] = 0.00; ItemValueTable["Base.Tweezers"] = 1.50; ItemValueTable["Base.Twigs"] = 0.00; ItemValueTable["Base.Twine"] = 1.50;

instead of doing this for every item

#

Basically wondering if there's a table or enumeration I can access with all the items in the game.

unique barn
#

anyone know how to fix world dictionary error

zealous pebble
#

where should i start for modding

#

any good tutorials or whateverr

chrome agate
#

I have been trying to mod food categories; I have "Better Sorting", but it creates only "Food - (non)perishable" and drinks and I would like too more like something that's on PZwiki - "Proteins, Games, Fish, Vegetable, Fruit, Grains, ..." possibly with better sorting on cooking utensils and acutally useful items (pots, bowls); so I started to experimentally to understand the load process from the snippets and similar mods and don't quite understand how this loads. What's difference between onGameStart vs onGameBoot events and what (more like when/where) happens when I do some commands in the lua script? Also my impression is that all the categories mods are quite incompatible? At leasst I

#

at least I didn't managed to load my categories alogside better sorting; like I would like to override this my mod being the last, but just can't get it to work. I wonder - have anyone experimented in this areas, are there some good tutorials I'm missing?

nimble spoke
sinful idol
#

@chrome agate decompile the java classes, that should tell you a lot in terms of what the functions do

sinful idol
chrome agate
sinful idol
chrome agate
# sinful idol maybe better sorting is overriding your mod somehow still?

yeah, there's something weird going on I can't understand; I mean I know lua only from like week experimenting with PZ so it's kind of rough start, but it would seem that while there's a mod that handles this transparently (TweakItems API) very few of the mods actually use this and they instead copy-pasted the code snippets with their own onGameBoots and whatnots and it seem to be all around the place

nimble spoke
#

@chrome agate Why would you expect 2 categorization mods to be compatible when they're trying to take control over the same thing?

chrome agate
sinful idol
#

have you managed to change the category of normal items? have you managed to change the category without better sorting?

chrome agate
#

I understand the conflict (like messing with one thing) but I'm using TweakItemAPI so it's rather simple like

...ItemTweakerAPI require boilerplate "if tweakerApi; require; else return; end"

TweakItem("Base.Apple", "CategoryName", "Fruits")
nimble spoke
willow estuary
#

This is all that is required to add/change display categories. Just this.

  1. a lua file in server or shared directories with this lua code
local item = ScriptManager.instance:getItem("Base.Money")
if item then 
    item:DoParam("DisplayCategory = Money")
end
  1. A IG_UI_EN.txt file in \media\lua\shared\translate\EN with this in it
IGUI_EN = {
    IGUI_ItemCat_Money = "Money",
}

That's all it takes. Just that. Nothing else. No Item Tweaker required.

#

Just make sure all of your new categories are in the IG_UI_EN.txt file. Add as desired for other languages in other directories, but if they don't have a file it'll default to the English version.

chrome agate
#

that's it; TweakItem mod has it's own instance that keeps map of "ItemToChange"->"newName", it collects this from all mods and applies it with its own onGameBoot handler (the idea I guess is that this happens only once collectively for all mods); but probably for some B40(??) compatibility, every mod has own onGameBoot and it seems to mess things up?

#

yeah those files for UI ItemCat I have, this part works

chrome agate
willow estuary
chrome agate
#

can this be done in-game? like are display categories dynamic like this? for example if I'd had a "change it all now" button in-game

willow estuary
#

You.... ....could do that, but that's significantly more complicated than "just use this code and it will work"?

chrome agate
#

I have it in client, so this MP-wise this will show up only for individual players with the mod installed?

#

how is it done? I saw DoParam around, I think this pushes something into Java part of the game?

willow estuary
#

In MP all clients and the server need to have identical versions of the same mods (unless checksum is disabled, which is a terrible idea)
There's no such things as client-side-only mods in PZ.

chrome agate
#

ok, shared/ it is then

small topaz
#

not really sure but i think the mod folders "client", "server" and "shared" (or better: their names) are not related to multiplayer-singleplayer stuff.... but other people here know more about this...

willow estuary
#

They are, and it's best to put everything in the shared folder unless you know a good reason otherwise or such.

#

If you follow how vanilla lua does it, it should work, but when in doubt use shared.

small topaz
#

ok... didn't know this.... thanks for the info. my current strategy was to put luas in the folder where the functions they modify are located. for example, when a mod modified a vanilla function located in client, i simply put my modded file into the mod's client folder

quasi geode
#

thats generally good policy, if your modifying something in client, go in client as well...just as a general rule most things should go in shard if its something both client and server will need
theres a load order that happens with the files...shared are loaded first, then client, then finally server...if its in MP the server doesnt actually load anything in client

#

which is why clientside stuff like UI, context menus and timed actions belong there

small topaz
#

ok. good to know!

#

could this lead to problems if i define a global variable in shared which should also be used in client? should be safe if shared stuff is loaded first...

quasi geode
#

accessing a global in client that was defined in shared is fine, accessing one defined in server could lead to problems (depending on when you try to access)

#

accessing one in server that was defined in client will fail in MP situations (for the actual server anyways)

#

i generally have my mods define a global table with in shared all the functions/data thats accessed from both client and server

drifting ore
#

how 2 make spawn mod in secret compound

small topaz
# drifting ore how 2 make spawn mod in secret compound

here is one way you could try: in your mod folder create a new folder CustomSpawnpoints (for example) and put it to the directory media/maps. in this folder, add a lua which defines your new spawnpoints. also add a txt file called map.info and this should contain the line "title= my spawnpoints" and i think a second line "lots=Muldraugh, KY" could do it...

#

without quotation marks

#

you could also check the mod folder for "Occupied Louisville" for example or other spawn point mods and see how they define the new spawnpoints. there quite a lot of them

drifting ore
#

would the secret lab be a safehouse? aka no zombies would spawn there?

#

i want to do a rp where you're one of the dick scientists that started it all

small topaz
drifting ore
#

bazz89? more like based89
ty

small topaz
quasi geode
small topaz
#

best thing is probably if i do it right now asap...

cinder crow
#

Has anyone done any communication out from lua to another process (websocket/tcp/etc?)

low yarrow
# quartz badge

Nice! You got the shapes of it pretty well.
Also the vertice count is solid, not too high poly and details where they are needed.

#

Is that a Dragunov tho? I really want to play with such a gun

quasi geode
quartz badge
#

Its less polys than the M16

#

OH

#

I thought you were talking about the AK i made

#

Those werent made for zomboid, i made them maybe 4 months ago

cinder crow
low yarrow
quasi geode
quartz badge
wicked sphinx
#

Anyone know the name of the mod that allows you to claim vehicles?

sour nova
#

In ScriptManager.class there is a public method called getAllItems, can I call this from a lua script?

viscid elbow
#

Anyone have a clue as to why the server is never receiving this command? Other commands in my mod are being received just fine.

local function OnGameTimeLoaded()
  print("sending command from gametime event")
  sendClientCommand(getPlayer(), 'myModule', 'myCommand', {})
end

Events.OnGameTimeLoaded.Add(OnGameTimeLoaded)

the message shows up in the log, and no errors appear

quasi geode
ornate flax
#

Can anyone point me to an example of how to create a simple mod that adds traits? I simply want to add traits that give skill levels, that's all.

viscid elbow
#

Found this one because it's when LuaNet is initialized, so my log looks like

[09-02-22 16:51:07.375] LOG  : General     , 1644450667375> 40,562,037> LuaNet: Loading....
[09-02-22 16:51:07.375] LOG  : General     , 1644450667375> 40,562,037> sending command from gametime event

I'll see if maybe I can get the character creation ones to work

ornate flax
#

i'm looking at the lua files in the base game and there is only one file with *trait* in it, and it's for the GUI

viscid elbow
ornate flax
#

i'll have a look, thanks

viscid elbow
#

From my Better Lockpicking Fixes:

local nimblefingers2 = TraitFactory.addTrait("nimblefingers2", getText("UI_trait_nimblefingers"), 3, getText("UI_trait_nimblefingersDesc"), false)
nimblefingers2:addXPBoost(Perks.Lockpicking, 2)
BaseGameCharacterDetails.SetTraitDescription(nimblefingers2)

3 is the cost, false means it's not an occupation-only trait

ornate flax
#

ah, excellent... i can work with this. Thanks again

viscid elbow
#

There's a bit of nuances with MP though.

  1. That code needs to go in the shared folder.
  2. You will need to overwrite the base game's recalculation of traits in order for them to apply correctly when making a new character after dying. (code below) This one also affects singleplayer.
local OldDoTraits = BaseGameCharacterDetails.DoTraits

local function CreateTraits()
  --create trait(s) here from code above
end

local function DoTraits()
  OldDoTraits()
  CreateTraits()
end

BaseGameCharacterDetails.DoTraits = DoTraits
ornate flax
#

oh ok...

quasi geode
# viscid elbow Found this one because it's when LuaNet is initialized, so my log looks like ```...
      public static void sendClientCommand(String var0, String var1, KahluaTable var2) {
         if (GameClient.bClient && GameClient.bIngame) {
            GameClient.instance.sendClientCommand((IsoPlayer)null, var0, var1, var2);
         } else {
            if (GameServer.bServer) {
               throw new IllegalStateException("can't call this function on the server");
            }

            SinglePlayerClient.sendClientCommand((IsoPlayer)null, var0, var1, var2);
         }

      }

it wont work until GameClient.bIngame is true. that doesnt get set true til a few lines before OnTick event fires for the first time

viscid elbow
#

Thanks! I'll see about using OnTick then deregistering it on the first tick then.

quasi geode
#

thats what i do when i need to fire on connection

viscid elbow
#

Nice it works!

sour nova
#

I need access to the API, I'm struggling looking through decompiled classes

wide burrow
#

Anyone know a mod to spawn any item???

fiery pecan
#

Debug mode works fine?

sour nova
quartz badge
#

Where can you find the item icon textures

wide burrow
sour nova
#

if you have it active just right click anywhere and you should see the cheat menu

wide burrow
#

Ok got it thanks sm

viscid elbow
#

Anyone have experience using global mod data or GameTime.instance:getModData?
I've tried using both to simply store 4 string values, but the values either aren't being saved or loaded (can't tell which)

round zenith
#

Anyone know the lua code to remove an item from someones inventory someone previously indicated it was palyer:getInventory():Remove("ITEM NAME") but that doesnt seem to work

thin hornet
#

@round zenith i dont think server and other clients have access to someone inventory. But the server could send a command to the targeted player and ask to remove the item if its found.

tranquil jackal
#

Am I able to write my own radio stations and add them in

round zenith
#

@thin hornet is that not what the code would be achieving? --> player:getInventory():Remove("ITEM NAME")

thin hornet
#

I mean the code playerObj:getInventory():Remove("ITEM NAME") would only work if called in that player's client.

#

other clients cannot remove someone else inventory items (i believe)
i dont even think the server can either

#

the server would have to transmit a command to the specific player and tell him to remove it, and then that client receive the command and execute it

round zenith
#

I have the code being called in this lua file when the user craft something, according to what you are saying it sounds like it should work then?

thin hornet
#

crafting recipe are placed into server/ dir, but are not executed from the server (mp)

tranquil jackal
#

Like

#

Make my own

round zenith
#

@tranquil jackal ya so just modify what they did in there code and you can

tranquil jackal
#

Ok

#

Thank yoy

#

You

round zenith
#

np

thin hornet
#

some stuff into lua/server/ are still clientside (it seem)

#

you crafting recipe should work, can you post the code maybe something is wrong into it

round zenith
#

no crafting recipe works fine

#

recipe Sell 25 Pearls for Masterson Horizon
{
Pearls=25,
keep WalkieTalkie4/WalkieTalkie5/HamRadio1/HamRadio2/HamRadioMakeShift,

     Result:MastersonHorizon,
     Time:10.0,
     Category:Trading,
     OnCreate:CarCraftingMH_OnCreate,
}
#

Lua code

#

function CarCraftingMH_OnCreate(items, result, player)
addVehicle("SmallCar02")

  local vehicle = player:getVehicle()
 if not vehicle then
     vehicle = player:getUseableVehicle()
 end
 if not vehicle then
    vehicle = player:getNearVehicle()
  end
  sendClientCommand(player, "vehicle", "getKey", { vehicle = vehicle:getId() })
  **player:getInventory():Remove("MastersonHorizon")**

end

#

item definition

#

item MastersonHorizon
{
Weight = .01,
DisplayName = Masterson Horizon + Keys,
icon = MastersonHorizon,
Type = Normal,
}

#

everything works as intended but removing the item after the car spawns as I want the car to show in the image for the recipe

thin hornet
#

isnt that item the result item of the recipe?

#

if so it is added officially to the inventory only after OnCreate is called

round zenith
#

oh damn, is there a way around that so that its called afterCreate?

thin hornet
#

yeah

#

add RemoveResultItem = true

#

try that in the recipe script.txt

#

this will prevent the result item to be added after the recipe is completed

round zenith
#

recipe Sell 25 Pearls for Masterson Horizon
{
Pearls=25,
keep WalkieTalkie4/WalkieTalkie5/HamRadio1/HamRadio2/HamRadioMakeShift,

     Result:MastersonHorizon,
     Time:10.0,
     Category:Trading,
     OnCreate:CarCraftingMH_OnCreate,
     RemoveResultItem = true,
}
#

that didnt appear to work when i just tested it

thin hornet
#

according to zombie\inventory\RecipeManager.java

public static InventoryItem PerformMakeItem(Recipe var0, InventoryItem var1, IsoGameCharacter var2, ArrayList var3) {
line 151

if (var6.equals("RemoveResultItem")) {
   this.removeResultItem = var7.trim().equalsIgnoreCase("true");
}

line 681

if (!var0.isRemoveResultItem()) {
     return var9;
} else {
     return null;
}
round zenith
#

@thin hornet to confirm this goes in the recipe code not the lua?

thin hornet
#

seem ok

round zenith
#

isRemoveResultItem = true and RemoveResultItem = True didn't work

#

also tried IsItemDestroyed

thin hornet
#

RemoveResultItem = true

#

idk from the source code thats what i would expect it to do. It should return null and then in ISCraftingAction it shouldnt add the item.

round zenith
#

If that doesn't work in the source code is there a method for AfterCreate?

thin hornet
#

nope

#

List of recipe possible field:

Override
AnimNode
Prop1
Prop2
Time
Sound
Result
OnCanPerform
OnTest
OnCreate
AllowDestroyedItem  <-- not used anywhere *useless* became -> NoBrokenItems
OnGrab              <-- looks like this one useless too
needtobelearn
category
RemoveResultItem
CanBeDoneFromFloor
NearItem
SkillRequired
OnGiveXP
Tooltip
Obsolete
Heat
NoBrokenItems
StopOnWalk
StopOnRun
round zenith
#

@thin hornet lolol

#

I figured it out

#

ready for this

#

its going to make you rage at human error

#

its not RemoveResultItem = True,

#

its RemoveResultItem:True,

thin hornet
#

D:

#

ah right

#
if (var2[var4].contains(":")) {
               String[] var5 = var2[var4].split(":");
#

my bad missed that one lol

round zenith
#

ya I missed it because you showed me Java and I got happy because I love Java

#

cool now I can push a few 1000s more lines of code to update the currency mod I have. TY!

thin hornet
#

np

sour nova
#

Weapons and WeaponTools have a "ConditionLowerChanceOneIn" attribute... anyone know how I access this in a lua script?

next glacier
#

anyone can help me

#

I'm trying to make a mod that increases washing time

#

and optimizes water u sage

#

it keeps throwing out the error

#
ERROR: General , 1644477266685> ExceptionLogger.logException> Exception thrown se.krka.kahlua.vm.KahluaException: ISWashClothing.lua:6: unexpected symbol near `10` at LexState.lexerror line:278.
ERROR: General , 1644477266685> DebugLogStream.printException> Stack trace:
se.krka.kahlua.vm.KahluaException: ISWashClothing.lua:6: unexpected symbol near `10`
fierce tapir
#

Hello guys ! I'm looking for a 3D modder/designer who would have the time to help me develop a mod around trailers or trucks plus trailers. I am available in PM

thin hornet
next glacier
#

like 6? what does that mean

thin hornet
#

ISWashClothing.lua:6 tell you that the error is on line 6 of that file i believe

#

im tired i type bad right now lol

next glacier
#

should i send whole code here

#

or would that be bad idea

#

or a screenshot

#

function ISWashClothing.GetRequiredWater(item)
    local filth = (bloodAmount+dirtamount)/2
    if (filth > 10) then
        return 10
    else
        return filth / 20
    end
end

function ISWashClothing:new(character, sink, soapList, item, bloodAmount, dirtAmount, noSoap)
    local o = {}
    setmetatable(o, self)
    self.__index = self
    o.character = character;
    o.sink = sink;
    o.stopOnWalk = true;
    o.stopOnRun = true;
    o.item = item;
    o.maxTime = ((bloodAmount + dirtAmount) * 1);
    if o.maxTime > 100 then
        o.maxTime = 100;
    end
    o.soaps = soapList;
    o.noSoap = noSoap;
    o.forceProgressBar = true;
    if character:isTimedActionInstant() then
        o.maxTime = 1;
    end
    return o
end```
#

ive changed the filename now

#

but the output error still says ISWashClothing

fair frost
thin hornet
#
require ("ISWashClothing");

function ISWashClothing.GetRequiredWater(item)
    local filth = (bloodAmount+dirtamount)/2  

bloodAmount and dirtamount are not known here

next glacier
#

ah

thin hornet
#

you should add em in the :new()

o.bloodAmount = bloodAmount;
o.dirtAmount = dirtAmount;
#

oh never mind

#

might want to add Filth as a parameter

#

since that method is not an instance method but is a static one

next glacier
#

sorry, quite new to lua

#

so we set o.filth here instead of bloodAmount and dirtAmount and add filth to new()

thin hornet
#

wait are you overwritting ISWashClothing?

next glacier
#

yes

#

should I not? or am I doing this wrong

thin hornet
#

yeah wait ill show you

#

Example for a static method:

local ISWashClothing_GetRequiredSoap = ISWashClothing.GetRequiredSoap; -- store the original function
function ISWashClothing.GetRequiredSoap(item)
  local vanillaRequiredSoapValue = ISWashClothing_GetRequiredSoap(item); -- call the original to know the original value
  local resultValue = 10;
  -- do your stuff
  return resultValue; -- return your overwritten value
end

Example for an instance method:

local ISWashClothing_perform = ISWashClothing.perform; -- store the original method
function ISWashClothing:perform(...)
  -- do your stuff before
  ISWashClothing_perform(self, ...); -- call the vanilla method
  -- do your stuff after
end

Example for a constructor method:

local ISWashClothing_new = ISWashClothing.new; -- store the original constructor
function ISWashClothing:new(character, sink, soapList, item, bloodAmount, dirtAmount, noSoap, ...)
  local newObj = ISWashClothing_new(self, character, sink, soapList, item, bloodAmount, dirtAmount, noSoap, ...);
  -- do your stuff to the constructed obj
  return newObj;
end
next glacier
#

so could the reason why it outputs that error

#

is I havent actually been replacing the code

#

and its sitting on top of the vanilla values

thin hornet
#

yeah

next glacier
#

wow thanks

#

this will take a while to understand

thin hornet
#

The method i show we call it "Hooking"

#

The way you did first was litteraly overwritting (which is bad for mod and game update compatibility)
we all did that mistake when we started

next glacier
#

for storing original contstructor can I use something shorter?

#

or must it match

thin hornet
#

it doesnt have to, its just how i choose to do it for making it readable, to know what it is.

next glacier
#

for example
local washcloth_new = ISWashClothing.new;

thin hornet
#

you can do that its just less clean in my opinion

#

for me i want to know what object and what method it hook. its more specific/clean if i use the same names

next glacier
#

yeah, good reason

#

so by calling original value, do we still have to do o.bloodamount (or o.filth)

thin hornet
#

also if you dont need the param for the constructor
Example for a constructor method:

local ISWashClothing_new = ISWashClothing.new; -- store the original constructor
function ISWashClothing:new(...)
  local this = ISWashClothing_new(self, ...);
  -- do your stuff to the constructed obj
  this.inventory = this.character:getInventory();
  return this;
end
#

you dont need to pass the bloodamount and dirtamount to the constructor of that action

#

What do you want to do exactly

next glacier
#

Since I made a variable "filth", i want to use filth instead of bloodAmount+dirtAmount

thin hornet
#

sorry gotta be like this local ISWashClothing_new = ISWashClothing.new; no ()

next glacier
#

woops

thin hornet
#

you want to change the time it take and the amount of water it use right? thats all?

next glacier
#

yea

thin hornet
#

so all you need to do is simple

next glacier
#

not longer than 100 time but linearly based on the amount of dirt and blood

thin hornet
#

you need to change the maxTime

#

and the GetRequiredWater method

next glacier
#

with water
not more than 10 water, but proportionally based on dirt and blood

zenith smelt
#

Is there a good way to play sound from a player that will stick to the player?

thin hornet
#
--- To overwritte the time needed to wash this item
local ISWashClothing_new = ISWashClothing.new;
function ISWashClothing:new(character, ...)
    local this = ISWashClothing_new(self, ...);
    this.maxTime = 100; -- the time you want
    if this.character:isTimedActionInstant() then
      this.maxTime = 1; -- for when instand action cheat is enabled
    end
    return this;
end

a new function to calculate the filth:

local function CalculateItemFilth(item)
    local bloodAmount = 0
    local dirtAmount = 0
    if instanceof(item, "Clothing") then
        if BloodClothingType.getCoveredParts(item:getBloodClothingType()) then
            local coveredParts = BloodClothingType.getCoveredParts(item:getBloodClothingType())
            for j=0, coveredParts:size()-1 do
                local thisPart = coveredParts:get(j)
                bloodAmount = bloodAmount + item:getBlood(thisPart)
            end
        end
        if item:getDirtyness() > 0 then
            dirtAmount = dirtAmount + item:getDirtyness()
        end
    else
        bloodAmount = bloodAmount + item:getBloodLevel()
    end
    
    return bloodAmount + dirtAmount;
end

and a hook for the amount of water:

local ISWashClothing_GetRequiredWater = ISWashClothing.GetRequiredWater;
function ISWashClothing.GetRequiredWater(item)
    local filth = CalculateItemFilth(item);
    return 10 / filth --- or what ever calculation you want
end
#

so that allow you to add the two value that you wanted and change the maxtime as you need

#

i dont think you need the blood amount here

next glacier
#

I dont need to re-calculate blood and dirt

#

sorry im lagging quite a bit

#

internet

#

I thought it was a bit simpler

thin hornet
#

you need to recalculate it cause its not available inside the GetRequiredWater function

#

its pretty simple

next glacier
#

cant I getInstance or equivalent?

thin hornet
#

the whole script look like this

-- function to calculate an item filth, same script used in vanilla
local function CalculateItemFilth(item)
    local bloodAmount = 0
    local dirtAmount = 0
    if instanceof(item, "Clothing") then
        if BloodClothingType.getCoveredParts(item:getBloodClothingType()) then
            local coveredParts = BloodClothingType.getCoveredParts(item:getBloodClothingType())
            for j=0, coveredParts:size()-1 do
                local thisPart = coveredParts:get(j)
                bloodAmount = bloodAmount + item:getBlood(thisPart)
            end
        end
        if item:getDirtyness() > 0 then
            dirtAmount = dirtAmount + item:getDirtyness()
        end
    else
        bloodAmount = bloodAmount + item:getBloodLevel()
    end
    
    return bloodAmount + dirtAmount;
end

-- this one we overwrite cause anyway it just return a constant
function ISWashClothing.GetRequiredWater(item)
    local filth = CalculateItemFilth(item);
    if filth > 10 then
        return 10
    else
        return filth / 20
    end
end

--- To overwritte the time needed to wash this item
local ISWashClothing_new = ISWashClothing.new;
function ISWashClothing:new(character, sink, soapList, item, bloodAmount, dirtAmount, noSoap)
    local this = ISWashClothing_new(self, character, sink, soapList, item, bloodAmount, dirtAmount, noSoap);
    local filth = bloodAmount + dirtAmount;
    this.maxTime = 100 / filth; -- the time you want
    if this.character:isTimedActionInstant() then
      this.maxTime = 1; -- for when instand action cheat is enabled
    end
    return this;
end
next glacier
#

btw i am unsure

#

is 100 max blood and 100 max dirt?

#

dirt+blood = 200?
hence my 20 divisor

thin hornet
#

i have no idea, try printing it out

next glacier
#

this still overwrites without using the throwaway_new?

thin hornet
thin hornet
#

and as you can see its used multiple time
so the way we did it will work consistently everywhere that function is used

zenith smelt
thin hornet
next glacier
#

so overall this is everything

thin hornet
#

i use Visual Code

next glacier
#

Was hoping I could dive into mod options today

#

curve steeper than i thought

#

esp not much examples of modoptions

quick pine
#

is there a modding tutorial for intermediate programmers?

next glacier
#

im comparing my code to the code of another mod using modoptions

thin hornet
zenith smelt
next glacier
thin hornet
#

without local it will be global

#

which will clutter the global environment (would overwrite it if it existed and would set it and make it accessible in any other code)

zenith smelt
#

I saw this
"Flickering mod sounds"
When I play a sound on my player, it will wobbles from one ear to the other.
This will be fixed in the next patch?;

thin hornet
#

its the 3D sound that make it like that

next glacier
#

so once i delete that and add local to filth

#

its all good right

#
function ISWashClothing:new(character,...)
    local this = ISWashClothing_new(self,...)
    local filth = CalculateItemfilth(item);
    this.maxTime = filth / 2;
    if this.maxTime > 100 then
        this.maxTime = 100;
    end
    if character:isTimedActionInstant() then
        o.maxTime = 1;
    end
    return this;
end```
thin hornet
zenith smelt
#

Thanks okay

next glacier
#

because i have no clue what this is

#

still there

#

idk whats wrong rly

thin hornet
#

try checking with console.txt in your documents/Zomboid directory

#

error will be explained better

next glacier
#

Exception thrown se.krka.kahlua.vm.KahluaException: ISWashClothing.lua:6: unexpected symbol near 10 at LexState.lexerror line:278.

#

but a line 278 does not exist

#

wot

#

DebugLogStream.printException> Stack trace:
se.krka.kahlua.vm.KahluaException: ISWashClothing.lua:6: unexpected symbol near 10

#

LOG : Lua , 1644497120746> Loading: E:/SteamLibrary/steamapps/workshop/content/108600/2748768980/mods/BetterWashing/media/lua/client/ISWashYourself.lua
WARN : Lua , 1644497120746> LuaManager.RunLua> recursive require():

#

hold on brb toile

thin hornet
#

place your script into a sub directory
media/lua/client/BetterWashing/here
try to reload the game too

#

also your require is wrong and useless in this case
should be this if you really want it
require "TimedActions/ISWashClothing"

#

mods will always load after the vanilla scripts so thats why i say its useless in this specific case as most vanilla script are global

next glacier
#

oh so you dont really need require? i thought it called for values in a different file but guess not.

thin hornet
#

require would ensure its loaded first

#

but your mod will 100% load after vanilla scripts

#

mods that require other mod need to check if the other mod is active and then require what it needs.
cause mods will have different load order

faint jewel
#

mods l.oading mods to load mods while modding modded mods that can be modded by mods?!

next glacier
#

I see. I used some other mod as a base because I didnt understand lua

#

they just copy pasted the code inside ISReadingBook

#

so I copied the method

thin hornet
#

i gotta go to store will be back shortly

faint jewel
#

modception!

zenith smelt
#

getEmitter():playSound plays different soudns on all clients if there are more than 1 sound files defined for 1 sound eevent

#

Interesting to know

#

Using clip to define multiple files

#

Also it gets muffled by walls ๐Ÿ˜ฎ

next glacier
#

ok i think other file has it

unborn radish
#

i dont think i showed it here

next glacier
#

ModOptions.lua:48: 'end' expected (to close 'function' at line 34) near <eof>

nimble spoke
#

Check everything above that function

next glacier
#

ah i get it now

#

different file

radiant hound
#

hey lovely mod people! I started to look into modding, and I was wondering, does anyone know if the limits on how far away a player can look (move the camera away) in Aim Mode can be set/get with Lua functions?

I would like to play with reducing / increasing it (I know if I increase I might run into a scenario in which you are looking further away but the chunks aren't loaded, but step by step)

If not, does anybody know which class is related to this behaviour? I'm looking at the IsoCamera class but I don't understand if the vector used for this is FakePos or offVec or I'm looking in the wrong place

next glacier
#

anyone with experience

#

with ModOptions

thin hornet
radiant hound
next glacier
#

the vanilla camera by default quite looks unfriendly

#

I have a great mod suggestion in mind but too advanced for me

#

not sure if possible

#

better blocks occlusion

#

this exists

#

but its more important on this side, but doesnt happen

radiant hound
#

yeah I see

thin hornet
#

i do hope the object and walls occlusion is fixed eventually, its really weird to see through wall with home-made building.

next glacier
#

yea and well its making it transparent on the wrong side

radiant hound
#

so with CCTV test, you mean you wanted to be able to temporarily move the player Camera to the position of the surveillance Camera?

thin hornet
#

@radiant hound yeah

radiant hound
#

that sounds neat, but yeah, can see how it'd be hard

thin hornet
#

I dont recall exactly what was the issues i had its been a while

#

something like the player become invisible and the fog of war not loading

radiant hound
#

ok but do you know which variables / functions were related to moving the Camera away?

next glacier
#

also i prefer the occlusion method to be left

#

center = unoccluded

#

right = current occlusion

#

left = preferred method

radiant hound
#

ideally I "just" want to increase the amount of distance the player can look away while in Aim Mode, rather than have the Camera fixed somewhere else in potential conflict with player actions, as in your CCTV case

radiant hound
next glacier
#

fixing other side to not occlude at all

next glacier
#

because you are behind

radiant hound
#

sorry I'm a bit dense with visuals, I think i'd need to see all the cases with player positions (but don't bother on making it to show me, I'm not skilled enough atm to do anything in that area anyway xD)

next glacier
#

looking for sledgehammers

#

and takes you a long time to find what is blocking your way

small topaz
#

hi! does it matter whether I create new folders in the lua/shared (or in lua/client or lua/server) directory and put my .lua files in there? is this safe? or is there a possibility that this might cause problems?

next glacier
#

mod options file should be in client only

#

everyone will be able to set it in multi

thin hornet
small topaz
#

ok... so answer is, creating new folders within shared, client or server is safe...? (presupposed that the new folders in client for example only contain functions which belong to the client side ofc)

next glacier
#

if modified in any way

#

might give up for tonight

thin hornet
#

@small topaz

lua/client/MyMod/ClientScript.lua  ---> require("MyMod/SharedScript")
lua/server/MyMod/ServerScript.lua  ---> require("MyMod/SharedScript")
lua/shared/MyMod/SharedScript.lua

example with both client and server requiring stuff from the shared

next glacier
#

thanks for the help @thin hornet cool guy

quartz badge
#

Does anybody know why the 223 magazine exists? No gun uses it

#

The gun that would use it has an internal magazine

thin hornet
cold burrow
quartz badge
#

also, is there a .x exporter for blender

cold burrow
#

Probably for everything, but i didn't test it.

quartz badge
#

I was watching a tutorial on how to make a firearm mod and it said to use .x

#

so im not sure on whether or not FBX is the way to go

cold burrow
cold burrow
quartz badge
#

Oh ok

dark finch
#

Someone needs to make a special infected mod. Would love to see screamers, spitters tanks, ect as a possibility

#

How possible would that be?

quartz badge
#

My mods gun is oversized, and no matter what i do it wont change

#

Nvm

drifting ore
#

i'd like to commission a mod, pls dm me for more details

inland crater
dark finch
faint jewel
#

$50 a pop and i got chu LOL

dark finch
faint jewel
#

the hell. you want custom special zombies?

faint jewel
#

there's already a special zombie mod.

dark finch
#

do they actually have separate models and function alot like l4d?

faint jewel
#

no, they are weorse. so much worse.

dark finch
#

in a good way?

faint jewel
#

yes and no.

robust sandal
#

So, I was thinking about a Negative Trait..

Zombie Fetish.

You have a % to randomly take off your pants around zombies.

fiery pecan
#

hello there. I have yet another coding question:
With sendServerCommand, how would I use it? would this work?

            GetZedOutfit = GetZedList:get(i):getOutfitName();
            GetZed = GetZedList:get(i);

sendServerCommand("STR", "GetZed:sendObjectChange(GetZedOutfit, {})", {});```
I'm mainly confused as to what "commandName" pertains to. Do I point it to a function?
#

I'm new to the whole Multiplayer/server data stuff

quartz badge
#

How would one make another ammo type

#

If anyone knows i could use some help

nimble spoke
dark finch
#

Question how exactly can the tank be killed? Hitting it enough or only bullets? All i got from a youtube vid was โ€œmust me killed in unconventional waysโ€

nimble spoke
#

yep, that's right, unconventional ways work. Direct weapon damage only works if it is a critical, sneaky stab with knives or I think runnning attack with spears? Never tested that one

#

But in sandbox mode you can set it to take normal damage if you want

viscid elbow
#

Anyone know how to save mod data to the server? From what I can tell, the server just doesn't save any mod data whatsoever.

quartz badge
#

How do you make custom ammo types

#

I need to make a new ammo type for my gun mod but idk how

viscid elbow
nimble spoke
#

Use ModData.Transmit(key)

#

or ModData.Request(key)

viscid elbow
#

Even if I never want such data to be sent to a client?

nimble spoke
#

If you don't want it to be sent to the client create it in the server and never transmit

viscid elbow
#

That's what I'm doing

#

It just doesn't load in the server, because the server apparently doesn't save mod data.

cold burrow
#

You prob talking about 7.62?

quartz badge
#

Yeah

nimble spoke
#

It is a complex thing to work with though. I had to summon higher powers for a detailed explanation

viscid elbow
nimble spoke
fiery pecan
#

this conversation's getting me thinking... How would I make a server run something like... dressInPersistentOutfit("EMSLouisville"); sendObjectChange('GetZedOutfit', {}); reloadOutfit();?

#

instead of the client

cold burrow
# quartz badge Yeah
module Base
{

  /* First step -  create bullets */
  item Bullets762mm
  {
    DisplayCategory = Ammo,
    Count    =    5,
    Weight    =    0.01,
    Type    =    Normal,
    DisplayName    =    9mm Rounds,
    Icon    =    40calAmmoBox,
    MetalValue = 1,
    WorldStaticModel = 9mmRounds,
  }

  /* Second step - create ammo box
  item Bullets762mmBox
  {
    Weight    =    0.2,
    Type    =    Normal,
    DisplayName    =    Box of 9mm Bullets,
    DisplayCategory = Ammo,
    Icon    =    HandgunAmmoBox,
    MetalValue = 30,
    WorldStaticModel = HandGunAmmoBox,
  }

  /* Third step - create magazine that uses your bullets */
  item 762mmClip
  {
    DisplayCategory = Ammo,
    CanStack    =    FALSE,
    Weight    =    0.2,
    Type    =    Normal,
    DisplayName    =    9mm Magazine,
    Icon    =    BerettaClip,
    MaxAmmo = 15,
    AmmoType = Base.Bullets762mm,
    StaticModel = GunMagazine,
    GunType = Base.Pistol, <-- here should be your gun
    WorldStaticModel = Gun_Magazine_Ground,
  }

  /* One of the last steps - add new magazine to your weapon */
  item AK47
  {
    AmmoType = Base.Bullets762mm,
    MagazineType = Base.762mmClip,
    AmmoBox = 762mmBox <-- actually idk what is that
  }
}

You also need to add a recipe to open your bullet box.

quartz badge
#

Where would i make a recipe?

cold burrow
#

it's just a script, something like that.

  recipe Open Box of .223 Ammo
  {
    223Box,

    Result:223Bullets=8,
    Sound:PutItemInBag,
    Time:5.0,
  }

  recipe Place .223 Ammo in Box
  {
    223Bullets=40,

    Result:223Box,
    Sound:PutItemInBag,
    Time:5.0,
  }

But swap 223 to yours ammo

#

This recipe from
...\Steam\steamapps\common\ProjectZomboid\media\scripts\recipes.txt

quartz badge
#
{   
    item 762bullets
    {
        DisplayCategory = Ammo,
        Count    =    60,
        Weight    =    0.025,
        AlwaysWelcomeGift    =    TRUE,
        Type    =    Normal,
        DisplayName    =    .762 Ammo,
        Icon    =    762bullets,
        MetalValue = 1,
        WorldStaticModel = RifleAmmo,
    }

    item 762box
    {
        DisplayCategory = Ammo,
        Weight    =    1.2,
        AlwaysWelcomeGift    =    TRUE,
        Type    =    Normal,
        DisplayName    =    Box of .762 Bullets,
        Icon    =    762ammo,
        MetalValue = 40,
        WorldStaticModel = RifleAmmoBox,
    }

    item 762clip
    {
        DisplayCategory = Ammo,
        CanStack    =    FALSE,
        Weight    =    0.2,
        Type    =    Normal,
        DisplayName    =    .762 Magazine,
        Icon    =    BerettaClip,
        MaxAmmo = 30,
        AmmoType = Base.762bullets,
        StaticModel = GunMagazine,
        GunType = Base.ak47,
        WorldStaticModel = Gun_Magazine_Ground,
    }

    recipe Open Box of .762 Ammo
    {
        762box,

        Result:762bullets=60,
        Sound:PutItemInBag,
        Time:5.0,
    }

        recipe Place .762 Ammo in Box
    {
        762bullets=60,

        Result:762box,
        Sound:PutItemInBag,
        Time:5.0,
    }
}```
#

Is this a good script?

#

Im so happy this actually works

#

How could i make a gun that has an internal magazine but is not bolt action

weary crypt
quartz badge
#

I already figured it out

weary crypt
#

I feel like I'm doing something wrong, I'm trying to increase the mag size of a weapon in a mod by 1 shell but changing the ClipSize or MaxAmmo value doesn't actually change anything in game. Is there something obvious I'm not seeing?

quartz badge
cold burrow
weary crypt
cold burrow
#

After you change something.

#

Or looks like it's not working too. :)

weary crypt
#

I double checked that the values were still what I changed them to and they were but it kept generating or being spawned as the original value.

unborn radish
cold burrow
#

I'm not sure, but could be that this value maybe was overwritten in lua somewhere in mod? Which i found pretty strange.

#

What mod you also talking about @weary crypt, i could check.

weary crypt
#

Vanilla Firearms Expansion, specifically I'm trying to revert a change it makes to the vanilla shotgun of reducing it's internal shell capacity from 5 to 4.

cold burrow
#

Any chance that this value was overwritten by another mod? idk

weary crypt
#

I don't know what to tell you

cold burrow
#

I have idea, can i dm you VFE_weapons.txt and you just replace it?

weary crypt
#

Sure

cold burrow
#

It's weird af.

weary crypt
#

๐Ÿค”

#

This really doesn't make sense

cold burrow
#

Just to make sure.

  1. Do you place it in ...\Steam\steamapps\workshop\content\108600\2667899942\mods\VFE\media\scripts?
  2. Maybe any other mods on that affects this value?
weary crypt
#

The only two mods active here are VFE and Cheat Menu

#

Actually wait a sec

#

I think I figured it out.

cold burrow
#

What was that?

weary crypt
#

Need to confirm first

#

Yep figured it out. I only glanced at the filepath at first but I realized I was in the local copy of the mod instead of the one you posted

drowsy rapids
# unborn radish WIP

while I don't know of the exact year of origin of this vehicle, an idea of PZ happeing in "ye olde times" would be very neat ngl

also lovely model

weary crypt
#

I was in \SteamLibrary\steamapps\common\ProjectZomboid\steamapps\workshop\content\108600\2667899942\mods\VFE\media\scripts

#

Thank you for the help, I appreciate it.

cold burrow
#

Well, glad that you figure it out.

weary crypt
#

I had a feeling it was something simple I was missing.

cold burrow
quartz badge
#

How would i make my custom guns use the vanilla attachments