#mod_development

1 messages Β· Page 233 of 1

bronze yoke
#

patching that method may be necessary

red tiger
#

Good morning.

bright fog
#

"Morning"

verbal yew
# bronze yoke patching that method may be necessary
   protected float getAlphaUpdateRateMul() {
      float var1 = super.getAlphaUpdateRateMul();
      if (IsoCamera.CamCharacter.Traits.ShortSighted.isSet()) {
         var1 /= 2.0F;
      }

      if (IsoCamera.CamCharacter.Traits.EagleEyed.isSet()) {
         var1 *= 1.5F;
      }

      return var1;
   }

protected can't be patched?

bronze yoke
#

protected methods can't even be called from lua

#

so patching it wouldn't do anything

verbal yew
#

sad...

violet shell
#

No hint on a first iteration of the b42 beta on today's thurdroid. Sad 😦

red tiger
#

Did some full-on cooking this morning for Breakfast and made prep rice for dinner. =)

#

Time to do some awesome modding. :D

red tiger
#

Wow.

#

<@&671452400221159444>

lost slate
#

Cheers

red tiger
#

The content in the blog post is really good.

violet shell
#

If I want to kill a player if it uses an item, is there a way other than setting damage ?
Like player:setDead() or alike ?

#

and that would put the player in a state that he becomes a zombie (as if he died from zombies bites)

vestal gyro
#

One thing tho that maybe needs some explaining is that no matter how much I adjust the spawnrate of an item it seems to always spawn in the same amounts

echo lark
#

So i got a question, guns of 93 doesnt have compatibility in The Workshop mod, so you cant dissasemble those guns, but if you add a tag to the guns they can be used in the recipes from TW. is it possible to check for items that have the subcategory firearm and doparam a new tag to them? or is there some other easier way to achieve my goal? looking into it now, but figured maybe someone had a quick answer fo rme

thick karma
#

The variable can be anything, even nil, but you need to pass it or you'll throw error

#

And yes that function has a capital first letter for no good reason and sounds like you're killing someone else 😭

#

If you want them to become a zombie, infect them first

violet shell
#

ok so player:Kill() will work as intended ?
I was exploring also
player:setHealth(0)

thick karma
#

Cannot just call Kill() even though the param can be nil. It's Javaside and Java is strict about getting the number of fields it expects

#

I often write it as Kill(me)

#

Even though I don't define me

verbal yew
# echo lark So i got a question, guns of 93 doesnt have compatibility in The Workshop mod, s...
local function zReWeaponAdjuster()
    local items = getAllItems();
    for i = 0, items:size() - 1, 1 do
        local tags = "";
        local item = items:get(i);
        if item:getTypeString() == "Weapon" then
            if item:isRanged() then -- isAimedFirearm() i'm not sure
              tags = "Your;Tags;Here";
            end
            zReWeaponAdjuster2(item:getFullName(),"Tags",tags);    
        end
    end
end
            
local function zReWeaponAdjuster2(Name, Property, Value)
    local Item = ScriptManager.instance:getItem(Name)
    if Item then
        Item:DoParam(Property.." = "..Value)
    end
end
#

all firearms weapon be with tag

grim yarrow
echo lark
grim yarrow
#

Could the parameter be attributive? Like crediting something for the kill?

thick karma
#

The param is an IsoGameCharacter

#

So that seems a likely purpose

#

Also no idea what the point of identifying the killer would be

#

I guess scoring in PvP somehow maybe

bronze yoke
#

iirc it is something like that

#

i just use player:die() πŸ€·β€β™€οΈ

violet shell
#

If I call in a function player:Say("Blabla") and I want the "Blabla" to be stored in a translate file, how I should do that ?
I tried player:Say("UI_blablatext") and added in my lua/shared/Translate/EN/UI_EN.txt :

UI_blablatext = "This is my texte",
}```
but it doesn't work
bronze yoke
#

player:Say(getText("UI_blablatext"))

violet shell
#

ok thanks πŸ˜„

#

also, how can I have Γ© or Γ  or other accentuated characters ? because I also make a FR folder with FR files, but when I use Γ© it's bugged, even if in the vanilla files it's also accentuated characters that are used

bronze yoke
#

the file needs to be saved with the correct formatting

bright fog
#

Save it in western

#

for french

violet shell
#

this ?

bright fog
#

yup

#

Your accents might still be broken and you might need to replace them but once the file has the right encoding it should be good

violet shell
#

ok thanks

bright fog
#

However uploading directly in github seems to break it sometimes, not sure about github desktop if it breaks it too

thick karma
#

Noice

grim yarrow
# bright fog wdym by that ?

If I were to make a game which involved damage and killing, I’d use some way to tell the game what exactly killed the player or npc. So a parameter would be used in those brackets. Triggering that through a command line would throw an error if I didn’t have a default value set

#

I’m speculating, that’s all

bright fog
#

eh

verbal yew
#

i can put here custom folder, which will not be read?

bright fog
verbal yew
#

nice

violet shell
#

for a mod I used the granolabar models and textures and modified the texture to have a custom item. I would like we see the object in hands when the character is using it. It could just copy the character animation when we search in our backpack, but with the object in primary hand. Would it be a simple task to mod that or not ? (just to know if I can investigate or if I drop πŸ˜‰ )

bright fog
violet shell
bright fog
#

easy to do

violet shell
#

It's 2 different items : an "autotest" and a serynge

bright fog
violet shell
#

I have the model with a .fbx file, and a .png texture

#

I also defined the _Ground mesh

last warren
#

when the new version comes out will the mods be all down or will they work with the new version

drifting ore
#

I am currently having troubles with modding my multiplayer server so honestly idk

#

im new to this modding thing so im trying my best here.

stable yew
#

Chevalier evolution VLC πŸ˜‰

violet shell
#

Is it possible to have the player confirm an action after they got a warning ? (Example : player use a serynge, they get a warning : are you sure ? then they have to either click a box to confirm, or do the action a second time. I guess with the player modData I could do that right ?

thick karma
red tiger
#

Sounds like something that you could make as a generic action that executes an action based on a button click.

#

Oh silly me. If there's already something then yeah use that.

thick karma
#

I'm not home or I'd just post the code

#

Might be ISModalDialog can be used for that iirc

frank elbow
#

ISModalDialog, yeah

#

Ninja'd as I was typing

thick karma
#

Gaha sorry

red tiger
thick karma
#

Idr exactly the code to implement for that purpose but it's p straightforward

frank elbow
#

But I haven't been able to find it again after noticing it the first time, and I didn't make a note of it 😩 so hopefully taking a look will give a reason to track that down

#

The bug being that I believe there's somewhere that passes something like param3, param3 rather than the third and the fourth. Only a bug with respect to mods using it (probably) & presumably something less common or it would've been called out

violet shell
#

tyvm πŸ™‚ gonna dig ISModalDialog then

red tiger
frank elbow
#

Of course, maybe I'll beat you to finding wherever it's hiding πŸ˜„

red tiger
#

I'm pushing code to the live web branch for Mallet. It should be available in ~ 2 minutes. Did some fixes and improvements to the UI.

violet shell
#

So I would need to call for ISModalDialog:new(x, y, width, height, text, yesno, target, onclick, player, param1, param2) right ?

thick karma
#

Yep

red tiger
#

@frank elbow I want to take luaparse and generate my Rosetta objects like how you render Lua typings.

#

This should be a huge speed-boost for production of documentation.

thick karma
frank elbow
violet shell
frank elbow
#

Ah, so people can input a file and have a starting point?

red tiger
#

Yeah.

bronze yoke
#

oh, that reminds me

frank elbow
#

That'd be neat

bronze yoke
#

at least one ISUI class uses multiple inheritance - since derive() doesn't support that they just merge the table with a pairs loop, which means nothing we have picked that up

#

i think it was ISPanelJoypad, i wouldn't be surprised if more of the joypad ones did it too

red tiger
#

Alright. If this affects how we render Lua typings then we'll need an issue to sort this out.

frank elbow
#

That'd make sense. Does Rosetta have support for specifying multiple base types? Or would that just look like defining the return as an A, B string?

red tiger
#

I only have an extends field ATM.

#

We can modify the schema if this is something that can occur.

frank elbow
#

LuaCats supports it with the comma, so presumably just having a comma in the field would do it. May be ideal to allow an array in the schema, yeah

red tiger
#

For returns we have a string field for type.

#

It arbitrates in the web tool to make it friendlier / easier to manage.

bronze yoke
#

i'm deep in the c++ mines but i'll take a quick look to see if any other classes did it

red tiger
#

You can do this in Mallet but it requires the Custom type option.

bronze yoke
#

it makes the intellisense for the class in question nearly useless since almost all of its interface is inherited from the pairs'd class

#

and afaik the joypad classes are preferred over the non-joypad ones so we should make sure they work okay

red tiger
#

Alright. I'll keep this in mind.

bronze yoke
#

here it is```lua
ISCollapsableWindowJoypad = ISPanelJoypad:derive("ISCollapsableWindowJoypad")

-- HACK
for k,v in pairs(ISCollapsableWindow) do
ISCollapsableWindowJoypad[k] = v
end

frank elbow
#

I do remember seeing that 🀦🏾 forgot all about it

red tiger
#

Ultimately as long as the typings can render for both or all derives then we should be good.

frank elbow
#

I'm probably not going to continue with the static analysis I had going since it wasn't ideal, but if we can specify it in Rosetta LLS at least can handle it. Can't speak to the older annotation system (with the name that escapes me)

bronze yoke
#

emmylua tired

frank elbow
#

That's the one πŸ˜„ I'll see whether it handles that, I think it does

bronze yoke
#

not sure if i've mentioned it to you but we target lls exclusively now

frank elbow
#

Oh thank goodness

bronze yoke
#

emmylua fell behind lls a long time ago, the reason it was previously the 'primary' target was because it supported intellij

#

but the first 2022 build of intellij rewrote some core part of the api that means emmylua doesn't support indexing anymore, and it has never been updated to the newer system

#

so it's becoming increasingly outdated and impractical, no sense in targeting it

frank elbow
#

Hooray for things with better alternatives becoming obsolete. I hope there's at least a way to set up the language server with IntelliJ, for those who do prefer it

#

But as a loyal VS Code user that is music to my ears either way

bronze yoke
#

yeah, i'm not happy about it but i finally jumped ship a few months ago

#

there's a couple alternative lua plugins for intellij including an lls port but none of them seemed like they were in an impressive state

frank elbow
#

That's a shame, I hope the IntelliJ plugins catch up

bronze yoke
#

for those who choose to stick to older versions of intellij, the annotations are mostly cross compatible anyway

frank elbow
#

LLS has been diverging a bit more here and there lately, with stuff like exact types

#

But idt we'd need that for Umbrella anyhow

red tiger
#

Yeah..

#

emylua documentation is horrendous too.

#

So like we could actually be a good source for documentation by knowing what we can do with lls.

frank elbow
#

I remain peeved that there are some things in EmmyLua that are exclusively documented in changelogs

red tiger
#

I was okay abandoning EmmyLua before anyone else.

#

I'm a vscode guy and will push people to go there.

#

(Wrote extensions for PZ modding development in it)

thick karma
# violet shell tyvm πŸ™‚
local Example = {}

Example.completeProcess = function(target, response, param1, param2)
    if response.internal == "YES" then 
        -- do yes stuff
    else
        -- do no stuff
    end
end

Example.showConfirmationModal = function()        
    local width = 400
    local height = 120 -- Matches vanilla game exit confirmation
    local x = (getCore():getScreenWidth() / 2) - (width / 2)
    local y = (getCore():getScreenHeight() / 2)  - (height / 2)
    local text = "Are you sure?" -- Or whatever translation using getText("UI_translation_variable")
    local yesOrNo = true
    local selectionProcessingFunction = Example.completeProcess
    local player = getPlayer() -- Depends on situation; ideally call this from somewhere that provides a player object.
    local param1 = anythingYouNeedToPassToOnClickFunction
    local param2 = anythingElseYouNeedToPassToOnClickFunction

    local confirmation = ISModalDialog:new(x, y, width, height, text, yesOrNo, target, selectionProcessingFunction, player, param1, param2)

    -- Enforces size/position you chose. 
    -- :new may choose its own width and position otherwise.
    confirmation.x = x
    confirmation.y = y
    confirmation.width = width
    confirmation.height = height

    confirmation:setAlwaysOnTop(true)
    confirmation:bringToTop()
end

return Example
#

Something like this

#

Idk I may have a typo or an oversight

#

But it's close to that.

red tiger
#

Oh look: Someone who actually writes Lua modules..

#

Nice.

bronze yoke
#

i remain fiercely loyal to jetbrains ides but it went too far even for me

red tiger
#

I ran into a bug with custom types however Mallet is incredibly stable.

#

The code for it is developed in preparation for Java documentation.

#

I'm going to document Java API for PZ too.

frank elbow
#

Where was the link to the collaboration repo you'd mentioned the other day? You said it was in the intro blurb but I didn't interpret anything there as that (unless I misunderstood)

frank elbow
#

In the interest of not duplicating work you're doing

thick karma
frank elbow
thick karma
#

If you get any errors you can't solve, ping me.

violet shell
#

So, where I put that code and how I call for it ?

frank elbow
red tiger
#

One can make their own patch.

#

I will make mine.

thick karma
#

Well, depends on what you're confirming. If you're using a syringe, I would probably call it from the use function for using said syringe.

#

@violet shell

red tiger
#

My plan is to passively write documentation on my own patch and allow for people to use it.

thick karma
#

And ideally that function will have access to player

#

So you could edit what I wrote to pass player to the function showConfirmationModal

frank elbow
red tiger
red tiger
#

I plan on adding a field at the class level for documentation authors.

bronze yoke
#

my second pass on events is close to complete

#

(and has come to encompass a little more than events)

red tiger
#

The thing is that since this will be a lot of work I'd like to open up the option for people to donate or contribute money to the project.

#

I'd like to keep this FOSS and available for anyone to do.

#

This will also open up the ability to translate documentation to other languages.

#

Rosetta is solving the biggest problem plaguing PZ's modding community: Documentation.

thick karma
#

@violet shell So basically you decorate that syringe use function and you instead call the modal dialog and only call the original function if they say yes.

vestal gyro
violet shell
thick karma
#

Right... and adjust its parameters to pass anything you'll want or need to pass it.

#

You say you want to do this when you use a syringe... is that from a mod?

#

Idr if syringe use is vanilla. I cannot find any mention of syringes in vanilla.

violet shell
#

it's in my mod

#

it's a mod that adds a trait you can take that gives you 2 autotests and 1 experimental injection. All those are biocoded so only you can use it safely.

#

if you try to use an autotest not coded with your biocode, then it's wasted, if you try to use the serum that isn't yours, you have a bigger chance to die, so I want that the player confirm their choice

thick karma
#

Okay well what is the function that activates use of the injection and makes the things happen when you use the item in your mod?

violet shell
#

I use an OnCreate function in the recipe that uses the serynge

bronze yoke
#

i don't think the recipe framework will support this very well

thick karma
#

This one? Inject_Biocoded_Cure

#

I mean if the function is being called we can run it through a confirmation...

violet shell
#

yes, and if the biocode match is false, it calls WrongInjection

bronze yoke
#

you can't really catch 'about to craft something'

violet shell
#

which is not finished

thick karma
violet shell
#
        Biocoded_Cure_Exp,
        Sound:BreakAmpule,
        Time:120.0,
        Category:Health,
        CanBeDoneFromFloor:False,
        NeedToBeLearn:False,
        OnCreate:Inject_Biocoded_Cure,
        Tooltip = Tooltip_Inject_CureExp,
    }```
bronze yoke
#

yeah, you can't really make a recipe trigger something *before* you craft it, only after

violet shell
thick karma
#

That's a fair enough workaround most likely.

bronze yoke
#

oh, yeah, then just putting it in your oncreate is probably fine

thick karma
#

Just replace used items and remove the ones you'll get

violet shell
#

I'll make the recipe "Keep" the item, and make the item disappear in the function that uses it

#

to remove an item it's player:getInventory():Remove(item) ? right?

#

or player:getInventory():DoRemoveItem(item) ?

verbal yew
#
local zReBLBP = win.character:getInventory():getFirstTypeRecurse("BobbyPin")
                    local zReBLHBP = win.character:getInventory():getFirstTypeRecurse("HandmadeBobbyPin")
                    if zReBLBP then
                        zReBLBP:getContainer():DoRemoveItem(zReBLBP)
                    elseif zReBLHBP then
                        zReBLHBP:getContainer():DoRemoveItem(zReBLHBP)
                    else
violet shell
#

ok, and how I check their hands, inventory & bags/containers ?

#

I have to check both inventory & container ?

#

so it would be like that :

#
player:getInventory():getContainer():DoRemoveItem(items:get(0));```?
small topaz
# violet shell ok, and how I check their hands, inventory & bags/containers ?

You can manually check for those.

local locationList = {"Back", "FannyPackFront", "FannyPackBack"}
for _,location in pairs(locationList) do
      local bag = player:getWornItem(location)
      if bag and instanceof(bag, "InventoryContainer") then
            local container = bag:getInventory()
            -- code for removing the items (example: container:Remove(item))
      end
end      

-- check bags equipped in hands
local itemA = player:getPrimaryHandItem()
local itemB = player:getSecondaryHandItem()
local itemList = {itemA, itemB}
for _,item in pairs(itemList) do
      if item and instanceof(item, "InventoryContainer") then
             local container = item:getInventory()
             -- code for removing items
      end
end```
Only disadavantage of this approach is that it may it not work for all bags/backpacks in case players use mods which allow to carry more bags than the vanilla game does. To make it compatible with those type of mods, you could iterate through all clothing items the player wears, check whether they are a container (use ``instanceOf(clothingItem, "InventoryContainer")``) and then delete the items.
thick karma
# violet shell ```recipe Inject_Biocoded_Cure { Biocoded_Cure_Exp, Sound:BreakA...

Something like this:

local Example = {}

Example.fixInventory = function(player, confirmed)
    -- To be done.
end

Example.completeProcess = function(player, response, items, result)
    -- response.player will be playerIndex due to how vanilla ISModalDialog works.
    if response.internal == "YES" then 
        Inject_Biocoded_Cure(items, result, player)
        Example.fixInventory(player, true)
    else
        Example.fixInventory(player, false)
    end
end

showInjectionConfirmation = function(items, result, player)        
    local width = 400
    local height = 120 -- Matches vanilla game exit confirmation
    local x = (getCore():getScreenWidth() / 2) - (width / 2)
    local y = (getCore():getScreenHeight() / 2)  - (height / 2)
    local text = "Are you sure?" -- Or whatever translation using getText("UI_translation_variable")
    local yesOrNo = true
    local selectionProcessingFunction = Example.completeProcess

    local confirmation = ISModalDialog:new(x, y, width, height, text, yesOrNo, player, selectionProcessingFunction, player:getPlayerNum(), items, result)

    confirmation.x = x
    confirmation.y = y
    confirmation.width = width
    confirmation.height = height

    confirmation:setAlwaysOnTop(true)
    confirmation:bringToTop()
end

return Example
#

And change recipe to call showInjectionConfirmation instead.

#

Might honestly just want to throw that in a global module for use with recipes.

#

But regardless this should in theory do the thing

#

Again I'm not really testing, so, you know, can't guarantee it's perfect code, and lmk if you can't solve any surprise errors.

#

But it's close to what you would need.

violet shell
#

ok, I just don't understand the return Example at the end (I'm sorry, I'm mostly a selflearner/dabbler)

thick karma
#

It's just a helpful compatibility-oriented practice to return your original locals functions / variables in an accessible module at end-of-file for other modders who may someday want or need to patch what you've done.

#

If that stuff were all in lua/client/Example.lua (which to be clear would NOT be a good name for a file in practice lol), you could do

  local Example = require("Example")

to import that table from its file.

#

And then e.g. people could decorate the function that happens when people confirm the injection.

violet shell
#

ok

#

so I should put all the example bloc in a separate file, and call it with require() ?

#

showInjectionConfirmation = function(items, result, player) and
function showInjectionConfirmation(items, result, player) are the same right ? @thick karma

red tiger
#

@frank elbow I fixed known bugs I've seen for Mallet. =)

verbal yew
#

i cant overwrite client commands...

#

Vanilla:

if isClient() then return end
local ClientCommands = {}
local Commands = {}
Commands.object = {}

Commands.object.shovelGround = function(player, args)
--some stuff here, nevermind.
end

i need just overwrite this func, like do nothing

#

if isClient() then return end

local zReMS_SERVER_IJECTOR = {}

-- ClientCommands.lua (server/)
zReMS_SERVER_IJECTOR.old_Commands = {}
zReMS_SERVER_IJECTOR.old_Commands.object = {}

zReMS_SERVER_IJECTOR.old_Commands.object.shovelGround = Commands.object.shovelGround

Commands.object.shovelGround = function (...)
    -- do nothing
end

return zReMS_SERVER_IJECTOR
#

but this is not work

bronze yoke
#

if the file you're targeting is in server/ you can hook Events.OnClientCommand.Add to snipe the event handler

thick karma
violet shell
#

ok thanks

thick karma
#

Of course in this case if those functions will only ever be called by the associated global, there may never be a purpose to importing Example anywhere else. You can just leave the recipe's global trigger function in the same file as the Example module stuff, and that function will have access to that stuff.

#

But you may prefer to have a GlobalRecipeFunctions file or something in a parent folder of your mod, i.e. something like lua/client/AsilarMod/GlobalRecipeFunctions.lua and then import Example stuff for availability there

#

It's a little bit of a stylistic judgment call based on how complex you expect certain files to get, in my opinion.

bronze yoke
#
local old_add = Events.OnClientCommand.Add
Events.OnClientCommand.Add = function(handler)
    -- need some way to ensure you are actually hooking the right one
    -- since vanilla files always load in the same order you could just use a counter, call old_add until the xth one
    -- might also be able to check which file the function comes from directly using some of the debugger functions? might only work in debug

    old_add(function(module, command, player, args)
        -- do nothing if it's the module and command that triggers the function you want to delete
        if module == "Module" and command == "Command" then
            return
        end
        handler(module, command, player, args)
    end)

    -- reset it after replacing the handler so you don't yeet some random mod functions
    Events.OnClientCommand.Add = old_add
end
#

getFilenameOfClosure(handler) if it's not debug only

verbal yew
bronze yoke
#

you can stop that function from running by using this to stop the event handler if the command that triggers it is fired

#

but it is difficult to determine that you are hooking the right event handler

#

unless it is non-local

violet shell
#

I have an issue there : both files require the other one

#

because I call function Injection_confirmed (items, result, player) in both files

#

or should I place it in your second lua file, and call it InjectionRequests.Confirmed ?

thick karma
#

Also you're missing a closing " on your getText call

violet shell
#

fixed it πŸ™‚

thick karma
#

That's why all the colors are wonky in your post.

#

Also you have return Example sitting in the middle of your file

#

Definitely can't do that

violet shell
thick karma
#

Returning the local module needs to happen at the end.

violet shell
#

yeah, I was not sure what to do with the return. I'll put it at the end of InjectionRequests.lua file

thick karma
#

Also ```lua
InjectionsRequests.completeProcess = function(player, response, items, result)
-- response.player will be playerIndex due to how vanilla ISModalDialog works.
if response.internal == "YES" then
Injection_confirmed(items, result, player);
InjectionsRequests.fixInventory(player, true)
else
InjectionsRequests.fixInventory(player, false)
end
end

#

Example -> InjectionsRequests

#

I also wouldn't leave showInjectionConfirmation as a global if you're no longer calling it from recipe file.

#

Pretty much the only reason to make functions global is to make them callable from those recipes.

bronze yoke
# bronze yoke ``getFilenameOfClosure(handler)`` if it's not debug only

something like this```lua
-- this code MUST be placed in shared so that it runs before vanilla server code

local old_add = Events.OnClientCommand.Add
Events.OnClientCommand.Add = function(handler)
local originFile = string.match(getFilenameOfClosure(handler), "media/lua/(.+)%.lua$")
-- not sure what file you are trying to hook, put its full path after lua/ here
if originFile != "server/ClientCommands.lua" then
old_add(handler)
return
end

old_add(function(module, command, player, args)
    -- do nothing if it's the module and command that triggers the function you want to delete
    if module == "Module" and command == "Command" then
        return
    end
    handler(module, command, player, args)
end)

-- reset it after replacing the handler so you don't yeet some random mod functions
Events.OnClientCommand.Add = old_add

end

thick karma
#

Unless perhaps it's an easy-access function for debugging by hosts.

#

Even then you could use a triggered event to avoid that.

violet shell
#

@thick karma Shouldn't this local selectionProcessingFunction = InjectionsRequests.completeProcess have arguments passed ?

#

like local selectionProcessingFunction = InjectionsRequests.completeProcess(player, items, ...)

thick karma
thick karma
#

Very important distinction to understand.

violet shell
#

with what you just said

thick karma
#

ISModalDialog will call the actual function to produce a result here:

thick karma
#

InjectionsRequests.Confirmed(items, result, player); -> InjectionsRequests.confirmed(items, result, player)

#

(honestly I'd lose all the unnecessary ending ;)

#

(I don't like unnecessary coding punctuation personally)

violet shell
thick karma
verbal yew
#

!= - it's java?

violet shell
violet shell
verbal yew
#

nah, not working...

thick karma
#

In the example I sent back to you I made several changes I would recommend; abstractly, I would group the global functions in your file together and group the subfunctions of InjectionsRequests together, and I would make every function that does not need to be called by the recipe code (such as showInjectionConfirmation) a subfunction of InjectionsRequests

#

@violet shell

thick karma
#

No .lua

#

Your example still currently indicates you're trying to return from the middle of a file, which is not allowed.

#

(Unless it's a conditional return.)

#

(And bear in mind that conditionally returning from middle of a file stops rest of the file from ever loading.)

violet shell
verbal yew
thick karma
#

Also do you call CurePlayer from recipe or not?

#

Ahhh no

#

CurePlayer needs to move

violet shell
#

I move Cureplayer to InjectionsRequests too ?

thick karma
#

Like this

bronze yoke
thick karma
#

Also just FYI I would recommend you make all functions lowerCamelCase naming convention, personally. @violet shell

#

It's how Java does it and Lua has no standards, so unless we look to Java for standards, we just get chaos.

#

(PZ is Java-based so it is not a random choice for a source of standards here.)

violet shell
#

ok πŸ™‚

#

also, I don't understand function InjectionsRequests.completeProcess(player, response, items, result) -- response.player will be playerIndex due to how vanilla ISModalDialog works. if response.internal == "YES" then InjectionsRequests.fixInventory(player, items, true) InjectionsRequests.Confirmed else InjectionsRequests.fixInventory(player, items, false) end end

thick karma
#

Modules like InjectionsRequests get capitalized though

#

And Lua filenames tend to be capitalized throughout vanilla and in most mods.

violet shell
#

Particularly the InjectionsRequests.fixInventory(player, items, true) I though you cannot pass arguments with those functions

verbal yew
# bronze yoke been writing too much c++ πŸ˜…
local old_add = Events.OnClientCommand.Add
Events.OnClientCommand.Add = function(handler)
    local originFile = string.match(getFilenameOfClosure(handler), "lua/server/ClientCommands.lua")
    -- not sure what file you are trying to hook, put its full path after lua/ here
    if originFile ~= "server/ClientCommands.lua" then
        old_add(handler)
        return
    end

    old_add(function(module, command, player, args)
        -- do nothing if it's the module and command that triggers the function you want to delete
        if module == "object" and command == "shovelGround" then
            return
        end
        handler(module, command, player, args)
    end)

    -- reset it after replacing the handler so you don't yeet some random mod functions
    Events.OnClientCommand.Add = old_add
end

in shared, not work...

thick karma
verbal yew
#

or i should path file where call sendClientCommand(self.character, 'object', 'shovelGround', args)?

bronze yoke
#

that may be easier

verbal yew
#
local zReMS_INJECTOR = {}
-- ISShovelGround.lua (client/BuildingObjects/TimedActions/)
zReMS_INJECTOR.old_ISShovelGround = {}
zReMS_INJECTOR.old_ISShovelGround.perform = ISShovelGround.perform
function ISShovelGround:perform(...)
    self.emptyBag:setJobDelta(0.0)
    if self.sound ~= 0 and self.character:getEmitter():isPlaying(self.sound) then
        self.character:getEmitter():stopSound(self.sound);
    end
    local sq = self.sandTile:getSquare()
    local args = { x = sq:getX(), y = sq:getY(), z = sq:getZ() }
-- zRe  sendClientCommand(self.character, 'object', 'shovelGround', args)

    -- FIXME: server should manage the player's inventory
    if self.emptyBag:hasTag("HoldDirt") then
        local isPrimary = self.character:isPrimaryHandItem(self.emptyBag)
        local isSecondary = self.character:isSecondaryHandItem(self.emptyBag)
        self.character:removeFromHands(self.emptyBag);
        self.character:getInventory():Remove(self.emptyBag);
        local item = self.character:getInventory():AddItem(self.newBag);
        if item ~= nil then
            item:setUsedDelta(item:getUseDelta())
            if isPrimary then
                self.character:setPrimaryHandItem(item)
            end
            if isSecondary then
                self.character:setSecondaryHandItem(item)
            end
        end
    elseif self.emptyBag:getUsedDelta() + self.emptyBag:getUseDelta() <= 1 then
        self.emptyBag:setUsedDelta(self.emptyBag:getUsedDelta() + self.emptyBag:getUseDelta())
    end
    if ZombRand(5) == 0 then
        self.character:getInventory():AddItem("Base.Worm");
    end
    -- refresh backpacks to hide equipped filled dirt bags
    getPlayerInventory(self.character:getPlayerNum()):refreshBackpacks();
    getPlayerLoot(self.character:getPlayerNum()):refreshBackpacks();
    -- needed to remove from queue / start next.
    ISBaseTimedAction.perform(self);
end

return zReMS_INJECTOR
violet shell
#

@thick karma fixed a little issue in function InjectionsRequests.confirmed(items, result, player) body = player:getBodyDamage() if body:isInfected() then if randomChance <= 4 then player:die() elseif randomChance <= 54 then InjectionsRequests.CurePlayer elseif body:setInfectionLevel(0) end else body:setInfected(true) body:setInfectionMortalityDuration(body:pickMortalityDuration()) body:setInfectionTime(player:getHoursSurvived()) end end

bronze yoke
thick karma
#

I didn't look for other errors but that is the formatting I would use.

bronze yoke
#

the old pattern captured without the .lua but expected it for the comparison

bronze yoke
#
-- this code MUST be placed in shared so that it runs before vanilla server code

local old_add = Events.OnClientCommand.Add
Events.OnClientCommand.Add = function(handler)
    local originFile = string.match(getFilenameOfClosure(handler), "media/lua/(.+%.lua)$")

    if originFile ~= "server/ClientCommands.lua" then
        old_add(handler)
        return
    end

    old_add(function(module, command, player, args)
        -- do nothing if it's the module and command that triggers the function you want to delete
        if module == "object" and command == "shovelGround" then
            return
        end
        handler(module, command, player, args)
    end)

    -- reset it after replacing the handler so you don't yeet some random mod functions
    Events.OnClientCommand.Add = old_add
end
```full working code to cancel the function
thick karma
#

If you can't figure them out, share the stack trace in your console logs and I'll try to check on my phone if I can.

violet shell
thick karma
#

Remember console.txt for clientside errors (which yours will likely be) is in %UserProfile%/Zomboid @violet shell

violet shell
#

like : ```local BiocodedCureKitTrait = {}

function BiocodedCureKitTrait.initModData(player)
if player:HasTrait("BiocodedCureKitTrait") then
local pMod = player:getModData()
local playerName = player:getDescriptor():getForename() .. " " .. player:getDescriptor():getSurname()
local playerUsername = player:getUsername()
local randomNumber = ZombRand(9999)+1
pMod.autotest = {}
pMod.biocodedCureExp = {}
...```

thick karma
#

Wait what?

violet shell
#

ok so I should clean up the local then

thick karma
#

Wdym local stuff

#

Ohhh

#

You mean like, "local pMod"??

violet shell
#

yeah

thick karma
#

That's not what I thought you meant

#

Those are fine

violet shell
#

and local playerName, and so

#

ok

thick karma
#

Those SHOULD be local

#

Otherwise you'd be declaring a global variable named pMod (I'm not saying you should, I'm saying that if you leave off the word local, the variables will be global automatically, unless they're the descendent of a local object such as a table).

violet shell
#

I delcare it later

thick karma
#

What you should not do is this:

local BiocodedCureKitTrait = {}

local function BiocodedCureKitTrait.initModData(player)

. . .
violet shell
#

pMod.autotest = {}

#

I need my pMod to be global, is it ok to have it declared in a local {} ?

thick karma
#

Yes.

violet shell
#

fine πŸ™‚

thick karma
#

But not in the brackets like you're accidentally literally implying

violet shell
#

ok last thing to do : try to write the fixInventory function πŸ™‚

thick karma
#

You would not write this:

local BiocodedCureKitTrait = {
  pMod = {}
}

This pMod would be a local subtable of the local table BiocodedCureKitTrait

violet shell
#

is this ok to have my pMod global ?

thick karma
#

I would not personally recommend it but it's okay. If you want it to be global you just do this in the example I sent you back:

local BiocodedCureKitTrait = {}

function BiocodedCureKitTrait.addTrait()
    TraitFactory.addTrait("BiocodedCureKitTrait", getText("UI_trait_BiocodedCureKitTrait"), 2, getText("UI_trait_BiocodedCureKitTraitdesc"), false, false)
end

function BiocodedCureKitTrait.initModData(player)
    if player:HasTrait("BiocodedCureKitTrait") then
        pMod = player:getModData() -- by deleting "local" I made it global here.
#

However, for splitscreen compat, you'll want to grab whichever player mod data is currently relevant to the player using the syringe.

#

So you really don't want to just save 1 mod data table for that 1 player imo.

#

Storing it would save almost no time.

violet shell
thick karma
#

Practically speaking it would save a pointless amount of time.

violet shell
thick karma
#

I would recommend leaving pMod local and using local pMod = player:getModData() in any function that needs to access a player's mod data when you're in that function so you know you're using the right player object.

#

Grabbing that data from player object does not take long at all and if you're only doing it once when the player manually activates a task, it is a complete nonissue for performance.

violet shell
#

the data is stored in player ModData even if I don't declare it global ?

thick karma
#

Correct.

violet shell
#

damn !

thick karma
#

player:getModData() is a table that you can summon all over your files and it will give you access to the correct table.

#

And if you store it in a local variable, that is just for convenience -- the local variable still points to the exact same table

#

It's just that you can only use that variable to do so until end-of-scope (so end of function, usually, or end of loop as the case may be).

violet shell
#

ok, so I should transfer all my pMod to local. Is it the same for items modData ?

#

so I should also transfer all my iMod to local too right ?

thick karma
#

Oh yeah leave that local too.

But I think you may need to transmit item mod data to sync it. @bronze yoke can probably confirm, but you may want to do iMod:transmitModData() before adding it to your inventory. (Nope, I'm wrong.)

bronze yoke
#

no, item mod data doesn't need syncing and doesn't even have a transmit method

thick karma
#

oh okay I see never mind

#

What does need transmitModData()?

#

Just world objects?

bronze yoke
#

yeah

thick karma
#

I see.

violet shell
#
local pMod.autotest = {}``` is it correct ?
thick karma
#

No local on the 2nd one

#

It's the same case as the one I mentioned earlier where the module is already local

#

pMod is sort of like a module -- structurally, it's the same thing, just a Lua table. Practically speaking, we use modules a bit differently sometimes, but they're still just tables.

violet shell
#

ok that's what I was worried about

#

and function InjectionsRequests.confirmed(items, result, player) local body = player:getBodyDamage() if body:isInfected() then if randomChance <= 4 then player:die() elseif randomChance <= 54 then InjectionsRequests.CurePlayer elseif body:setInfectionLevel(0) end else body:setInfected(true) body:setInfectionMortalityDuration(body:pickMortalityDuration()) body:setInfectionTime(player:getHoursSurvived()) end end

#

It's better to have "body" local right ?

thick karma
#

Definitely.

#

I would never make a variable with a name as common as the word body global, as a rule of thumb.

#

If I am making something global, I do my best to give it a name no one else has used or will be likely to use.

#

Gotta get out of here but I wish you luck from there and I'll try to respond to further questions later if nobody beats me to it.

#

Tons of people here can tell you exactly what I'm telling you though so feel free to keep floating questions and just hang in there until someone sees it.

violet shell
#

and I understand far better some other code I was struggling to read

thick karma
# violet shell and I understand far better some other code I was struggling to read

Btw just in case you're unaware, I have 20+ published mods and welcome anyone interested (including you) to review their code to understand how I solved this or that problem and refactor anything you need from those mods. Just make sure you change any global module names used in my older mods, all MOD ids, and all full filenames (meaning lua/client[or shared or server]/Full/Path/And/Filename.lua needs to be unique).

uneven vessel
#

Can someone help me replicate this in a mod? I've been stuck on it for days

#

I've got the case spawning in the world just fine, but can't get the case itself to spawn the loot I want

violet shell
#

Can someone help me ?

ERROR: General     , 1714081981030> ExceptionLogger.logException> Exception thrown java.lang.NumberFormatException: For input string: "Tooltip_Inject_CureExp" at FloatingDecimal.readJavaFormatString.
ERROR: General     , 1714081981031> DebugLogStream.printException> Stack trace:
java.lang.NumberFormatException: For input string: "Tooltip_Inject_CureExp"
    at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(Unknown Source)
    at java.base/jdk.internal.math.FloatingDecimal.parseFloat(Unknown Source)
    at java.base/java.lang.Float.parseFloat(Unknown Source)
    at java.base/java.lang.Float.<init>(Unknown Source)
    at zombie.scripting.objects.Recipe.DoSource(Recipe.java:429)
    at zombie.scripting.objects.Recipe.Load(Recipe.java:409)
    at zombie.scripting.objects.ScriptModule.CreateFromToken(ScriptModule.java:285)
    at zombie.scripting.objects.ScriptModule.ParseScript(ScriptModule.java:459)
    at zombie.scripting.objects.ScriptModule.Load(ScriptModule.java:60)
    at zombie.scripting.ScriptManager.CreateFromToken(ScriptManager.java:174)
    at zombie.scripting.ScriptManager.ParseScript(ScriptManager.java:75)
    at zombie.scripting.ScriptManager.LoadFile(ScriptManager.java:147)
    at zombie.scripting.ScriptManager.Load(ScriptManager.java:758)
    at zombie.GameWindow.initShared(GameWindow.java:148)
    at zombie.GameWindow.init(GameWindow.java:1197)
    at zombie.GameWindow.mainThreadInit(GameWindow.java:576)
    at zombie.GameWindow.mainThread(GameWindow.java:489)
    at java.base/java.lang.Thread.run(Unknown Source)```
violet shell
#

Yes, but I don't understand what's the problem. Syntax in my string ?

bright fog
#

From what I read, that sounds like a wrongly used function but you'd have to show the line with the string

violet shell
bright fog
#

ha that's in a script

#

Well idk for that, I'm not familiar with script files

violet shell
#

Ok, now I have a problem in lua file πŸ™‚

#

you cannot have an elseif with ~= ?

#

I don't understand, in another mod I made earlier, I used the exact same syntax and it works fine.

echo lark
thick karma
#

@violet shell You aren't calling the functions. I overlooked how you wrote that earlier. You simply wrote their names, which leads the compiler to expect that you are going to assign them some new value, i.e., you're about to say something to the effect "A = B". The compiler communicates this to you by saying, '=' expected near elseif

#

Specifically it's observing that before elseif (right before it, i.e., near it), it expects = after InjectionsRequests.confirmationWindow

#

You should have written InjectionsRequests.confirmationWindow()*
(* okay not quite...)

#

In fact you also need the params in the parentheses. I'm pretty sure the confirmation window had params.

#

Last you sent it to me, its params were items, result, player

#

So you really should have written InjectionsRequests.confirmationWindow(items, result, player)

#

And tbh, you shouldn't even write this branch this way.

#

(lol πŸ˜… )

#

You should write it this way @violet shell:

    if iMod.biocodedCureExp.playerUsername ~= player:getUsername() or 
       iMod.biocodedCureExp.playerName ~= playerName or
       iMod.biocodedCureExp.randomNumber ~= pMod.biocodedCureExp.randomNumber then
        InjectionsRequests.confirmationWindow(items, result, player)
    else
        InjectionsRequests.confirmed(items, result, player)
    end
#

Those would be the appropriate function calls.

thick karma
#

I would expect that to be the reason for this error.

#

But maybe those comments are allowed and I've never known. Also possible.

#

In general, I would not expect Lua-style comment format to be allowed in a script.

#

And maybe -- is being interpreted as some effort to subtract something and that's how it ends up resulting in a number format exception.

thick karma
violet shell
#

Ok, but those lines are copy/paste from vanilla files πŸ˜„

#

I removed them btw

#

Ok, took all your advice, gonna test it again πŸ™‚

#
ERROR: General     , 1714085624443> DebugLogStream.printException> Stack trace:
java.lang.NumberFormatException: For input string: "Tooltip_Inject_CureExp"
    at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(Unknown Source)
    at java.base/jdk.internal.math.FloatingDecimal.parseFloat(Unknown Source)
    at java.base/java.lang.Float.parseFloat(Unknown Source)
    at java.base/java.lang.Float.<init>(Unknown Source)
    at zombie.scripting.objects.Recipe.DoSource(Recipe.java:429)
    at zombie.scripting.objects.Recipe.Load(Recipe.java:409)
    at zombie.scripting.objects.ScriptModule.CreateFromToken(ScriptModule.java:285)
    at zombie.scripting.objects.ScriptModule.ParseScript(ScriptModule.java:459)
    at zombie.scripting.objects.ScriptModule.Load(ScriptModule.java:60)
    at zombie.scripting.ScriptManager.CreateFromToken(ScriptManager.java:174)
    at zombie.scripting.ScriptManager.ParseScript(ScriptManager.java:75)
    at zombie.scripting.ScriptManager.LoadFile(ScriptManager.java:147)
    at zombie.scripting.ScriptManager.Load(ScriptManager.java:758)
    at zombie.GameWindow.initShared(GameWindow.java:148)
    at zombie.GameWindow.init(GameWindow.java:1197)
    at zombie.GameWindow.mainThreadInit(GameWindow.java:576)
    at zombie.GameWindow.mainThread(GameWindow.java:489)
    at java.base/java.lang.Thread.run(Unknown Source)```
#

Still get the issue with ToolTip @thick karma

frank elbow
#

Missing a trailing comma

thick karma
#

I wonder if that's one of those weird situations where you need the closing comma?

frank elbow
#

Tooltip = Tooltip_Inject_CureExp β†’ Tooltip = Tooltip_Inject_CureExp,

thick karma
#

Now who is ninjaing.

#

Damn ninja.

#

😭

#

I was honestly guessing but if you're sure nice.

frank elbow
#

Should be that, scripts require the trailing comma on all values

thick karma
#

So does this mean -- comments are fine in those files?

frank elbow
#

Should be, they're accepted in string files & I'd expect the same for those

violet shell
#

I added the coma, and still have an issue πŸ™‚

frank elbow
#

Different code paths so I'm not 100% certain there

frank elbow
violet shell
#

nope, but almost same trace

frank elbow
#

What's the new one?

violet shell
#

wait

#

ERROR: General , 1714086028226> ExceptionLogger.logException> Exception thrown java.lang.NumberFormatException: For input string: "Tooltip_Inject_CureExp" at FloatingDecimal.readJavaFormatString.
ERROR: General , 1714086028226> DebugLogStream.printException> Stack trace:
java.lang.NumberFormatException: For input string: "Tooltip_Inject_CureExp"
at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(Unknown Source)
at java.base/jdk.internal.math.FloatingDecimal.parseFloat(Unknown Source)
at java.base/java.lang.Float.parseFloat(Unknown Source)
at java.base/java.lang.Float.<init>(Unknown Source)
at zombie.scripting.objects.Recipe.DoSource(Recipe.java:429)
at zombie.scripting.objects.Recipe.Load(Recipe.java:409)
at zombie.scripting.objects.ScriptModule.CreateFromToken(ScriptModule.java:285)
at zombie.scripting.objects.ScriptModule.ParseScript(ScriptModule.java:459)
at zombie.scripting.objects.ScriptModule.Load(ScriptModule.java:60)
at zombie.scripting.ScriptManager.CreateFromToken(ScriptManager.java:174)
at zombie.scripting.ScriptManager.ParseScript(ScriptManager.java:75)
at zombie.scripting.ScriptManager.LoadFile(ScriptManager.java:147)
at zombie.scripting.ScriptManager.Load(ScriptManager.java:758)
at zombie.GameWindow.initShared(GameWindow.java:148)
at zombie.GameWindow.init(GameWindow.java:1197)
at zombie.GameWindow.mainThreadInit(GameWindow.java:576)
at zombie.GameWindow.mainThread(GameWindow.java:489)
at java.base/java.lang.Thread.run(Unknown Source)

thick karma
#

Hmmmm seems the same.

frank elbow
#

It may be because you have some colons where you should have =

thick karma
#

Can you share your files real quick?

#

I'll verify in some recipes.

frank elbow
#

I'd have to double-check (I don't use scripts all that often) but I think only some of those should be :

thick karma
#
    recipe HockeyMaskSmashBottle
    {
        WineEmpty/WineEmpty2/WhiskeyEmpty,
        Result:SmashedBottle,
        Time:20,
        OnCanPerform:Recipe.OnCanPerform.HockeyMaskSmashBottle,
        Tooltip:Tooltip_Recipe_HockeyMaskSmashBottle,
    }
violet shell
#

so it should be Tooltip : Tooltip_blabla ?

thick karma
#

Yep

#

The = made it expect number

frank elbow
#

Oh whoops I said that backwards

violet shell
#

ok thanks πŸ™‚

thick karma
#

Yeah, confirmed, items use =, recipes use :

violet shell
#

damn, that's so weird πŸ˜„

thick karma
#

You presumably copied tooltip from one to the other.

violet shell
#

pretty sure I did πŸ˜„

#

another issue : when I launch, everything is ok, no more error nor any stack trace, but the game don't load

#

after the loading I never get the "click to start"

frank elbow
#

Does the game hang?

#

Like "not responding"

#

If not, I'd double-check to make sure there's no error. If so, seems like a potential infinite loop

violet shell
thick karma
#

You running this in MP?

#

What's coop-console say if so

violet shell
#

yup, hosted server to start with, and when it works fine on hosted server I move to dedicated one

thick karma
#

coop-console is adjacent to that one

#

Might be more informative here

violet shell
#

in coop-console I got that :

#

LOG : Lua , 1714086218786> 1?197?927?759> Loading: C:/Users/Gusty/Zomboid/Workshop/Asilar_BiocodedCureKit/Contents/mods/Asilar_BiocodedCureKit/media/lua/server/Asilar_Biocoded_Cure_Kit.lua
LOG : Lua , 1714086218787> 1?197?927?760> Loading: C:/Users/Gusty/Zomboid/Workshop/Asilar_BiocodedCureKit/Contents/mods/Asilar_BiocodedCureKit/media/lua/server/InjectionsRequests.lua
LOG : General , 1714086218789> 1?197?927?761> luaChecksum: eae2a1aec2db491d3e37eb3e32bc4153
ERROR: General , 1714086219038> 1?197?928?011> LuaManager.getFunctionObject> no such function "onCreateAutotest"
ERROR: General , 1714086219039> 1?197?928?012> RecipeManager.LoadedAfterLua> no such function LuaCreate = "onCreateAutotest" in recipe "Use_an_Autotest"

thick karma
#

just post the whole file I mean

violet shell
thick karma
#

Some things that strike me as weird that happen near the disconnect are this:

LOG  : Network     , 1714083436868> 0> [26-04-24 00:17:16.868] > ConnectionManager: [RakNet] "disconnection-notification" connection: guid=126100832844820618 ip=90197630470637574 steam-id=76561198192785714 access="" username="peanits" connection-type="Disconnected"
LOG  : Network     , 1714083436869> 0> [26-04-24 00:17:16.869] > ConnectionManager: [disconnect] "21" connection: guid=126100832844820618 ip=90197630470637574 steam-id=76561198192785714 access="" username="peanits" connection-type="Disconnected"
ERROR: General     , 1714083438917> 0> java.nio.file.NoSuchFileException: /lua/EasyConfigChuckedServerConfigs/servertest_config
ERROR: General     , 1714083438917> 0>     at jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.deleteFile(Unknown Source)
ERROR: General     , 1714083438918> 0>     at jdk.zipfs/jdk.nio.zipfs.ZipPath.delete(Unknown Source)
ERROR: General     , 1714083438918> 0>     at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.delete(Unknown Source)
ERROR: General     , 1714083438918> 0>     at java.base/java.nio.file.Files.delete(Unknown Source)
ERROR: General     , 1714083438918> 0>     at zombie.core.logger.ZipLogs.deleteDirectory(ZipLogs.java:305)
ERROR: General     , 1714083438918> 0>     at zombie.core.logger.ZipLogs.addDirToZipLua(ZipLogs.java:264)
ERROR: General     , 1714083438918> 0>     at zombie.core.logger.ZipLogs.addZipFile(ZipLogs.java:80)
ERROR: General     , 1714083438918> 0>     at zombie.network.CoopMaster.readServer(CoopMaster.java:243)
ERROR: General     , 1714083438918> 0>     at java.base/java.lang.Thread.run(Unknown Source)

as well as these references to two hidden mods:

LOG  : Network     , 1714083054248> 0> [26-04-24 00:10:54.248] > ZNet: workshop item 2048847068 is not installed
LOG  : Network     , 1714083054259> 0> [26-04-24 00:10:54.259] > ZNet: workshop item 2579085757 is not installed
#

This also looks less than ideal at a glance and the timing makes me wonder about it:

LOG  : Network     , 1714083436867> 0> [26-04-24 00:17:16.867] > ZNet: CRakNet -> CZombienet: OnClosedConnection
LOG  : Network     , 1714083436867> 0> [26-04-24 00:17:16.867] > ZNet: OnClosedConnection: m_connectionState=6
LOG  : Network     , 1714083436867> 0> [26-04-24 00:17:16.867] > ZNet: OnClosedConnection: reason=DisconnectionNotification port=16262
LOG  : Network     , 1714083436867> 0> [26-04-24 00:17:16.867] > ZNet: CZombienet -> CZombienet: CloseConnection
LOG  : Network     , 1714083436867> 0> [26-04-24 00:17:16.867] > ZNet: CloseConnection: DisconnectionNotification (1208)
LOG  : Network     , 1714083436867> 0> [26-04-24 00:17:16.867] > ZNet: CZombienet -> CZombienet: CancelAuth
LOG  : Network     , 1714083436868> 0> [26-04-24 00:17:16.868] > ZNet: CancelAuth
LOG  : Network     , 1714083436868> 0> [26-04-24 00:17:16.868] > ZNet: CZombienet -> CZombienet : UpdateConnectionState
LOG  : Network     , 1714083436868> 0> [26-04-24 00:17:16.868] > ConnectionManager: [RakNet] "disconnection-notification" connection: guid=126100832844820618 ip=90197630470637574 steam-id=76561198192785714 access="" username="peanits" connection-type="Disconnected"
LOG  : Network     , 1714083436869> 0> [26-04-24 00:17:16.869] > ConnectionManager: [disconnect] "21" connection: guid=126100832844820618 ip=90197630470637574 steam-id=76561198192785714 access="" username="peanits" connection-type="Disconnected"
ERROR: General     , 1714083438917> 0> java.nio.file.NoSuchFileException: /lua/EasyConfigChuckedServerConfigs/servertest_config
ERROR: General     , 1714083438917> 0>     at jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.deleteFile(Unknown Source)
#
ERROR: General     , 1714083438918> 0>     at jdk.zipfs/jdk.nio.zipfs.ZipPath.delete(Unknown Source)
ERROR: General     , 1714083438918> 0>     at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.delete(Unknown Source)
ERROR: General     , 1714083438918> 0>     at java.base/java.nio.file.Files.delete(Unknown Source)
ERROR: General     , 1714083438918> 0>     at zombie.core.logger.ZipLogs.deleteDirectory(ZipLogs.java:305)
ERROR: General     , 1714083438918> 0>     at zombie.core.logger.ZipLogs.addDirToZipLua(ZipLogs.java:264)
ERROR: General     , 1714083438918> 0>     at zombie.core.logger.ZipLogs.addZipFile(ZipLogs.java:80)
ERROR: General     , 1714083438918> 0>     at zombie.network.CoopMaster.readServer(CoopMaster.java:243)
ERROR: General     , 1714083438918> 0>     at java.base/java.lang.Thread.run(Unknown Source)
violet shell
#

I have to Alt-F4 to quit the game

#

maybe it's the source of the last errors ?

#

but I still cannot enter the game.

#

must be a infinite loop somewhere ?

#

it's probably linked to Events.OnNewGame.Add(BiocodedCureKitTrait.initModData)

thick karma
#

Send me your mod real quick in DMs.

#

I'll run it locally and see.

violet shell
#

sure

#

WARN : Script , 1714087112332> 1?198?821?305> ModelScript.check> no such model "???.Autotest_KnoxInf" for Asilar_Autotest_Knox_Infection.Autotest_Knox_Infection
WARN : Script , 1714087112332> 1?198?821?305> ModelScript.check> no such model "???.Item_LabSyringe" for Asilar_Biocoded_Cure_Kit.biocodedCureExp

frank elbow
#

May want to ask Chuck how that was ultimately sorted, unless removing the unavailable mod IDs fixed it

frank elbow
violet shell
#

deleting the offending folder ? @frank elbow

#

Reverted to my vanilla code from the other mod that works, and in SP player spawns with the items as intended, but there are stuff that doesn't work (cannot open crafting UI).
In Hosted MP, it doesn't work I have to test again.

violet shell
thick karma
thick karma
#

I wonder what happens between loading map chunks and pressing start in general... Anyone know off the top what events fire there, or what files load there?

#

Actually after Loading World to be more specific...

violet shell
#

I started to add some print() almost everywhere in the trait creation lua file. gonna run 1 time to check what's happening

violet shell
# thick karma I wonder what happens between loading map chunks and pressing start in general.....

LOG : General , 1714093719777> 0> Enter BiocodedCureKitTraitOnNewGame
LOG : General , 1714093719777> 0> Enter if loop
LOG : General , 1714093719778> 0> Rudolph Ramey
LOG : General , 1714093719778> 0> Asilar
LOG : General , 1714093719778> 0> 8358
LOG : General , 1714093719778> 0> Enter for loop for 1 times
LOG : General , 1714093719779> 0> Enter for loop for 2 times
LOG : General , 1714093719779> 0> Start Create biocodedCureExp
LOG : General , 1714093719779> 0> pMod.autotest.randomNumber = 8358
LOG : General , 1714093719780> 0> pMod.biocodedCureExp.randomNumber = 8358
LOG : General , 1714093719785> 0> LuaNet: Loading...
LOG : General , 1714093719785> 0> LuaNet: Registering client listener...
LOG : General , 1714093719786> 0> LuaNet: Initialization [DONE], triggering events for 'LuaNet.onInitAdd'.
LOG : General , 1714093719852> 0> Saving GlobalModData

thick karma
#

Very confusing issue I must say.

violet shell
#

It's not the Trait creation that loops, because we go through the whole process without any problem

thick karma
#

Yeah I see that.

uneven vessel
#

i'm gonna go crazy

#

I have spent days trying to get this box to spawn loot

violet shell
#

from coop-console, last run

thick karma
#

Common

#

Not an obvious error if it's running long enough.

violet shell
#

I really don't get it

#

I'm going to try solo play at least once to check

thick karma
#

Very odd. I am gonna take a break from staring at it and try to look a little later. Kind of a lot of points of failure here and hard to say which is the issue for me without an error message to go by. I'm thinking it may be a script issue of some kind but idk at all tbh.

violet shell
#

is it possible that the missing StaticModels Omar was talking about is messing it up ?

thick karma
#

I was AFK when he said that

violet shell
#

what if I delete the static as for my previous mod

thick karma
#

I don't know about that and didn't even see that comment

#

But Omar is a G who has contributed very useful technical solutions to the mod scene so I would take his guesses as highly educated.

thick karma
#

I do not know scripts as well as some so I can't just glance at them and be sure they're all formed right, tbh... And when I want to run a function from an item historically, I often attach the function using OnFillInventoryContextMenu event rather than using recipe functions. This is somewhat fuzzy territory for me.

violet shell
#

In Solo play, with a reverted ugly code

#

also in the bugs : I cannot open the crafting UI

uneven vessel
#

i can't do it

violet shell
#

I may have found one of the issues : my crafting recipe didn't have a result

thick karma
#

I am pretty confident that the error is some disconnect between how recipes work and how you've connected the functions to them... If the Lua code itself were malfunctioning severely, I'd expect Lua stack traces or something.

violet shell
#

And I forgot a coma in imports{Base,}

thick karma
#

I just don't know for sure.

#

But my money is on issues in the scripts as the main reason game won't get to Start Game button.

violet shell
#

subsidiary question : where are the traits icons ? I can't find the vanilla ones

#

ok, now Crafting UI is working

uneven vessel
#

I just can't get things to spawn in this container

#

i'm gonna go crazy

violet shell
#

@thick karma It WORKS !!!! DAMN IT WORKS !!

uneven vessel
#

what am I doing wrong? can I not call a distribution table to an item?

#

i just want to replicate gun case function

#

I got the cases, they spawn, but no matter what I do they are always empty

violet shell
#

Anyone have some knowledge about StaticModels around ?

manic magnet
uneven vessel
manic magnet
uneven vessel
#

Let me pull it up

proven bough
#

Hey everyone. I'm doing outfits for custom zombies at the moment, and I'm wondering whether it's possible to force a zombie to wear a specific colour of item. So for instance, I want one to wear a motorcycle helmet, but specifically the red one, with no chance of spawning with the other colours. Is that possible?

manic magnet
uneven vessel
#

And it does exist in game

#

Then I have it defined in procedural generations like this

#

And it does spawn in those locations

#

But after that I can't get it to spawn the items

#

This is as far as I ever got

#

I tried a bunch of other shit with local function applyLootBoxLoot() but couldn't get it to work

proven bough
manic magnet
# uneven vessel This is as far as I ever got

I'm not familiar with loot distributions, but i would assume that is your issue, something not being connected there.

Probably not the right way to do things, but you might be able to use OnContainerUpdate in order to force spawn some items in it semi-randomly? https://github.com/demiurgeQuantified/PZEventDoc/blob/develop/docs/Events.md

(Client) OnContainerUpdate: Fires when a container is added or removed from the world.

Parameters: object - The container that was added or removed.

GitHub

Tool for generating Lua documentation for Project Zomboid events and hooks - demiurgeQuantified/PZEventDoc

manic magnet
violet shell
#

Pale Jack, you know stuff about StaticModel ? I'm struggling to finish my mod

manic magnet
#

I really messed up KATTAJ1's name... lol

uneven vessel
manic magnet
#
local function OnContainerUpdate(container)
  -- Test if container is one of your gun cases
  -- Add items to container
end

Events.OnContainerUpdate.Add(OnContainerUpdate)
#

Stupid Discord messed up my indentation. πŸ₯²

uneven vessel
#

hmmmmmmmmmmmmmmmmmmmmmmm

ancient grail
uneven vessel
manic magnet
uneven vessel
#

where do the items go?

#

Like that?

manic magnet
# uneven vessel Like that?

Well... no. You don't put your distribution list in there. Sorry. It's a little more complicated than that. Do you know how to develop in Lua?

uneven vessel
#

Not at all cate

#

Everything I do I do via reverse-engineering other mods or vanilla code

#

i've never coded in my life

#

@bronze yoke seemed to know how it works but i must've misunderstood where to put the code

manic magnet
#

I see. Give me a second.

uneven vessel
#

They gave me this thing

#

And I've tried implementing it 101 different ways but couldn't get it to work

violet shell
#

@manic magnet My issue is :
I renamed GranolaBar.fbx into myItem.fbx, and made a myItem.png changing colors and drawings on the GranolaBar.png (texture).
Then I made a model : model myItem3D { mesh = WorldItems/myItem, scale = 0.4, } item myItem { ... WorldStaticModel = myItem3D, }
And it works nicely

manic magnet
uneven vessel
manic magnet
violet shell
#

@manic magnet But when I try to add StaticModel, here what I did :
I converted GranolaBar.fbx to GranolaBar.x (using online converted), renamed it in myItem.X and adding it into models_X directory
Then added code :model myStaticItem { mesh = myItem, } item myItem { ... StaticModel = myStaticItem, WorldStaticModel = myItem3D, } But the item is not in the hand when player use it or when I equip it in primary hand

uneven vessel
#

\common\ProjectZomboid\media\lua\server\Items\Distributions.lua

manic magnet
manic magnet
uneven vessel
#

mmm yeah, it's next to the ProceduralDistributions Lua that handles the case itself spawning in the game

violet shell
manic magnet
#

Anyway, I am not certain which versions PZ does and does not support.

violet shell
#

ok thanks

manic magnet
uneven vessel
#

this distribution nonsense will be the death of me

violet shell
#

seems it's the same format, but in the converted file, I don't have template ColorRGB {} for example nor template Material {} nor template TextureFilename {}

manic magnet
violet shell
#

Good idea

manic magnet
uneven vessel
#

yeah i think so

manic magnet
uneven vessel
#

the problem is getting items to spawn in the bag

#

oh my god i did it

#

i don't know what the fuck fixed it

#

    PistolCaseMakarov = {
        rolls = 1,
        items = {
            "Base.9x18mmClip", 200,
            "Makarov", 200,
            "Base.Bullets9x18mmBox", 200,
        },
        junk = {
            rolls = 1,
            items = {
                
            }
        }
    },
}


table.insert(Distributions, 1, distributionTable);

--for mod compat:
SuburbsDistributions = distributionTable;```
violet shell
#

So, how I can have a good conversion from fbx to X ?

violet shell
#

@thick karma I converted back all the files of functions in your syntax, but I get an error I don't understand

grizzled fulcrum
#

__lt is table syntax (not the proper name but idk names) for less than, __gt is greater than etc

violet shell
#

yes, I finally found the error πŸ™‚ Changing names of stuff is always painful πŸ˜„

grizzled fulcrum
#

So whatever you're doing at InjectionsRequests.lua:54 or at Asilar_Biocoded_Cure_Kit.lua:14

#

good job!

violet shell
#

I hope it's the last one πŸ™‚

#

Yeah ! That's good now πŸ™‚ Finally, I can go to bed πŸ™‚ Thanks all for your help, and see you tomorrow for more questions πŸ˜„

proven bough
ancient grail
#

You could try and use OnZombieUpdate() or from contextmenu or something

proven bough
#

Sorry I have a mental deficiency, could you please explain like I'm five years old?

ancient grail
#

I dont think i can do that.. hmmm....
Whats your purpose for choosing specific texture? When do you want select texture

proven bough
#

I want zombie to spawn with rainbow pants

#

Okay no, hold on, let me elaborate a bit more than that

#

Just loading in to grab a screenshot so you can see what I mean...

ancient grail
#

Oh you can just look at how vanilla spawns them
OR maybe use the addhorde or something like that
Thats you spawn zed

proven bough
#

So there's a bunch of dead zombies here. I've referred to both AuthenticZ and ClothesBox for the clothing. The pants, which are from ClothesBox, are spawning in all different kinds of colours, but I want the specific rainbow pants on the south-most zombie to be a 100% guaranteed spawn, instead of having the variation of like 20 different styles. I could easily just make a unique pair of pants that only uses that texture, but is there a more efficient way using code or GUIDs or something to guarantee that?

ancient grail
# proven bough So there's a bunch of dead zombies here. I've referred to both AuthenticZ and Cl...

this is untested i just wrote this now


local yourItem = 'Base.Hat_JokeKnife'
local yourOutfit = 'HazardSuit'
function ZContext(pl, context, worldobjects)    
if not pl then return end
    local zed = nil
    if clickedSquare then zed = clickedSquare:getZombie() end 
    --zed:getInventory():contains(yourItem) 
    --zed:getWornItems():getItems()
    if zed then
        context:addOption("set texture", worldobjects, function() 
            if zed:getInventory():contains(yourItem)  then
                yourItem:getVisual():setTextureChoice(2);     
            end        
        end)
        context:addOption("set texture2", worldobjects, function() 
            for i=0, zed:getWornItems():size()-1 do
                local item = zed:getWornItems():get(i):getItem();
                if item and item:getFullType() == yourItem then        
                    item:getVisual():setTextureChoice(2);     
                end
            end
        end)
        context:addOption("give item then set texture", worldobjects, function() 
            local inv = zed:getInventory() 
            local equip = inv:AddItem(yourItem);    
            zed:setWornItem(equip:getBodyLocation(), equip);
            equip:getVisual():setTextureChoice(2);     
        end)
        context:addOption("spawn with your outfit", worldobjects, function() 
            local sq = clickedSquare
            addZombiesInOutfit(sq:getX(), sq:getY(), sq:getZ(), 1, yourOutfit, nil, true, true, false, true, 2)              
        end)
        

    end
end
Events.OnFillWorldObjectContextMenu.Remove(ZContext)
Events.OnFillWorldObjectContextMenu.Add(ZContext)


#

my syntax might all be messed up so just refer to the vanilla lua to correct it

#

those are different methods and hopefully one of em works

#

you can also iterate worldobjects
and search for movingobjects

something like this

            for i=1,square:getMovingObjects():size() do
                local obj = square:getMovingObjects():get(i - 1)
                if obj and instanceof(obj, "IsoZombie") then
ancient grail
#

so forget what i wrote so you want the game to spawn em then just define another clothing outfit

#

that contains only 1 texture

#

which will guarantee that it will spawn

#

you need an xml here
'\media\clothing'
an entry of that xml here
fileGuidTable.xml
your item.txt on the scripts folder
the model aswell
then the texture goes to the textures folder
thats basically how you create a outfit i think

#

to make em spawn you need a lua on the shared folder

require 'NPCs/ZombiesZoneDefinition'
Events.OnPostDistributionMerge.Add(function()    
    table.insert(ZombiesZoneDefinition.Army, {name = "yourOutfit", 5});
end)


#

something like that

thick karma
ancient grail
#

yoh i made an entire profession init lua thats far to shorter than any other mods you see

#

this is vanilla

#

this is mine

#

see the page lol

#

this is how i did that

#

check out how i did the mutual exclusive

function DNZ_Init.doMutualExclusive(entry)
    local result = ''
    for _, v in pairs(entry) do
        for i = 1, #v do
            for j = i + 1, #v do
                local k = v[i]
                local l = v[j]

                if TraitFactory.getTrait(k) ~= nil and TraitFactory.getTrait(l) ~= nil then 
                    if isDebugEnabled() then 
                        local toPair = tostring(k..' | '.. l)
                        result = result .. toPair .. '\n'
                    end 
                    TraitFactory.setMutualExclusive(k, l)    
                end  
            end
        end
    end
    if isDebugEnabled() then  
        Clipboard.setClipboard(result)
        print(result) 
    end
end
#

looks familliar?

#

thats from your BS table thing

#

ive been using that valuable pievce of code ever since
i owe all my table skills from that

#

@thick karma

thick karma
ancient grail
#

Was so happy when i saw no errors and checked the stats
And they were all there

Thnx so much

lofty mica
#

Hi, simple question. I've added some icons for a couple of items but they're not shown in the item list when using debug. Is there any way to fix this or am I stuck looking at the void instead of the item's icon? New icons replacing base game ones also don't show, but instead what the game uses in vanilla

bronze yoke
#

yeah, the debug item list just doesn't load icons correctly

#

i think someone wrote a patch for it if it bothers you, but it doesn't mean you're doing anything wrong

manic magnet
lofty mica
#

alright thanks

#

i figured its just the list being silly, not anything bad but it does make it harder to test my stuff

bronze yoke
#

i wasn't able to find the patch, i guess it wasn't made by who i thought it was and it wasn't easily findable on the workshop

#

but basically the debug item list uses a function that only searches the base game directory for icons, so it doesn't reflect mods at all

violet shell
#

Hi πŸ™‚ I'm still looking for help for 2 last things : convert the fbx model of GranolaBar into x file, and I'm still hardly stuck on my mod "Readwithfriends" to simulate fast forwarding time when you read in MP, simulating stats drain like Fast forward in SP. πŸ™‚ If anyone have some spare time, I'll be grateful πŸ˜„

bright fog
bronze yoke
#

my statsapi reimplements stat calculations in lua, that might be a helpful reference

violet shell
#

@bright fog because the X file doesn't exist for that item, and I used the fbx file to make my custom item,and I would like to have the item visible in hands πŸ™‚

bronze yoke
#

you don't have to use x files, the game will render fbx too

violet shell
bright fog
#

You don't need a .x file to see the item in hands

violet shell
#

I must have failed somewhere then

bright fog
#

Don't even use .x, for the sake of yourself and everyone, don't put your model files in .x

bright fog
bronze yoke
violet shell
bright fog
#

Within blender you need to add the bone and parent the model to the bone

bronze yoke
#

i won't lie, because of the scope of the project the code is somewhat dense so i didn't suggest it to you before

bright fog
#

I've never done it myself but a ton of people already did it

bronze yoke
#

i was actually working on something that needed to simulate a stat drain myself so i may add a library for that if it's useful

bright fog
#

Check out modded items that can be held in hands (vanilla files are in x and don't even bother getting those and their bones, if it's the same as animations it requires you reading the bible in fragmotion, literally)

#

(also I'm not joking about reading the bible in fragmotion, that's the only way to get access to the software)

violet shell
violet shell
bright fog
#

@sonic needle you have more detail on that ?

violet shell
#

@bright fog @thick karma I have another critical issue for my server that is going to start in a feuw hours. I'm using a mod that plays alert sounds 10 and 5 minutes before a server start, but I get an error I don't understand. Can I submit the file and error log to you ?

#

Don't bother, I made a typo error in the sandbox options I setup πŸ™‚

bright fog
#

welp

#

Didn't receive your ping somehow lol

thick karma
#

I was workin but glad you solved it.

violet shell
#

I still have issues with having staticmodel visible 😦

uneven vessel
#

@verbal yew I cracked the code on that btw thx for your help also good work on the random zombies thing I'm using it on my server now

uneven vessel
uneven vessel
#

I just swapped it innnn

verbal yew
#

AHHAHSHASHHASHAS

#

xD

uneven vessel
#

Do you know what's wrong

verbal yew
#

rly nope... i'm trying find problem but...

uneven vessel
#

Flew too close to the sun...

verbal yew
#

like first zombies updated, but not new, but should, because script start every 7 sec

uneven vessel
#

Hmmm

#

That's weird

#

Well I'd really appreciate the performance boost

#

Because I suspect the old one was incinerating my server performance

bright fog
bright fog
#

And did you verify the game cycles through your zombies ?

#

with prints too

thick karma
verbal yew
#

as i say

#

hmmm

bright fog
#

does it actually run through your function

verbal yew
#

i mean, my crawler zombies can exist and swap on new zombies

#

but sandbox setting look like broke after...

#

after after

#

xD

bright fog
#

If only you had waited for my Zomboid Forge framework haha ShibaNom

#

joking of course, you shouldn't wait to do your own stuff

#

But like my framework is the perfect code to add random zombies, and I even planned it as a mod using my framework lol

verbal yew
#

in 42 be new event

#

onzombiespawn

#

and normal randomizer setting to walk type

#

hmmm... maybe change zombie speed

#

like

#

setWalkType

bright fog
#

I fucking hope

verbal yew
#

how to look into one zombie in debug? like list of params?

bright fog
#

Give a fuck ton of tools and go use it now if you don't use it

verbal yew
bright fog
#

Look on the workshop

#

Community debug tools

violet shell
#

WARN : Script , 1714147613165> 0> ModelScript.check> no such model "???.Item_biocodedCureExp" for Asilar_Biocoded_Cure_Kit.BiocodedCure_Result
WARN : Script , 1714147613166> 0> ModelScript.checkMesh> no such mesh "Biocoded_CureExp" for Asilar_Biocoded_Cure_Kit.Biocoded_CureExp

#

what are the ??? before the model name ?

#

nevermind, it's an item than never spawns because it's only a result of a recipe that I remove on result πŸ˜„

thick karma
thick karma
#

I see them sometimes in mod support but never triggered them myself so didn't know how to.

thick karma
vestal gyro
#

so I noticed that despite making the probability quite a bit higher I haven't noticed an increase in items spawned

#

any way I can fix that?

thick karma
vestal gyro
#

I just made new saves essentially after I changed the probability and replaced the mod folder in mods

thick karma
#

Hmmm I mean the numbers tend to affect probs for me historically so I think somehow the update is getting ignored

#

Is it possible that you have two versions of your mod on your pc, perhaps one version you're subscribed to on the workshop and one in your local working folders inside Zomboid?

#

@vestal gyro This could cause Zomboid to load the wrong version of your mod and create the illusion that changes are doing nothing...

vestal gyro
#

could be

#

but I also uploaded the one with higher probability to the workshop afterwards anyways

#

I'll revisit it today or tomorrow and make sure

#

thanks tho that could be it

verbal yew
#

@bright fogdamn, i figure out my problem

bright fog
#

What was the issue ?

verbal yew
#

i change zombie and drop in moddata stuff, for not change this zombie in future

im run away, back again, all zombies just walk, because they has moddata, but sandbox setting for they drop on default

#

hmhmhhmhmh

bright fog
#

Like I told you, moddata isn't the way to go

verbal yew
#

yeah...

bright fog
#

And you need to reference zombies with the pID like I showed you

#

Do you do that ?

#

Do you use the pID ?

#

The true ID ?

verbal yew
#

nope, idk how to do this stuff

#

i see your func in math

#

but rly dont know how to work with that

#

where you recreate true ID

bright fog
#

You link an IsoZombie with info that it was updated right ?

verbal yew
#

should be

bright fog
#

Well that's your issue

#

Because an IsoZombie is dynamic and switches for a same entity when that entity gets loaded and unloaded

#

So an entity zombie will constantly swap moddata

verbal yew
#

nhmhmmh

#

nope

bright fog
#

(unless I understand wrongly how mod data is linked to a zombie)

verbal yew
#

they not swap

#

but another stats swap

#

i mean, like, moddata not reset

bright fog
#

No there's no way it doesn't swap, or else true ID would be useless

verbal yew
#

OU!

bright fog
#

@thick karma are you familiar with mod data for zombies ?

bright fog
#

Do they stay linked to the same entity ?

#

Or are moddata linked to an IsoZombie ?

verbal yew
#
local zs = getCell():getZombieList()
        local sz = zs:size()
        print("This now: " .. now)
        for i = 0, sz - 1 do
            local z = zs:get(i)
            if not z:getModData().zReRANDOMZOMBIES and not (client and z:isRemoteZombie()) then
                zRe_updateZombie(z)
            end
        end

this is IsoZombie should be

#

But as i say, when im walk away on high distance and back again - this is zombies not trigger anymore, but has defaul speed setting

#

it's mean they save moddata

#

but yep, after reloaded into game - empty moddata

bright fog
#

And I told you, don't fucking use mod data

#

Use something non persistent

#

Tbf I never use mod data on zombies

#

I use the global mod data

#

To save info about zombies

verbal yew
#

newbie in this side

#

gods it's i always should check all zombies

bright fog
#

No it's not

verbal yew
#

yep, it's yep

#

because i should recreate changed speed again

bright fog
#

It's been a while I've worked on my framework and getting back on it but I don't

#

I don't do it

#

I don't do that

verbal yew
#

for zombies, which i'm walked faraway

bright fog
#

I don't do that

#

And that issue I've encountered

#

And don't get anymore

verbal yew
#

wait...
not about moddata

#
local function zRe_updateSpeed(zombie, targetSpeed)
    getSandboxOptions():set("ZombieLore.Speed", targetSpeed)
    zombie:makeInactive(true)
    zombie:makeInactive(false)
    getSandboxOptions():set("ZombieLore.Speed", SPEED_FAST_SHAMBLER)
    zombie:getModData().zReRANDOMZOMBIES = true
    print("Updated Speed")
end
#

i'm changed for isoZombie too

#

it's should be like isoZombie

#

it's problem, yep?

verbal yew
#

AHHSAHAHS

bright fog
#

I'm telling you

#

DON'T USE MOD DATA ON ZOMBIES

#

Listen to me

verbal yew
#

You're just talking about moddata!
I'm telling you that the speed is reset, but the date mod remains.

bright fog
#

When you want to access info about a zombie entity, and I'm not talking about an IsoZombie, but an actual zombie entity which stays the same when you reload an area (save or walking area and coming back), you can't use IsoZombie, the tag you usually get

verbal yew
#

WAIT

verbal yew
#

getSandboxOptions():set("ZombieLore.Speed", targetSpeed) - i change this stuff for IsoZombie

#

but should like for zombieID

#

yep?

bright fog
#

What ?

verbal yew
#

again

#

step by step

bright fog
#

Yes you need to change for IsoZombie

bronze yoke
#

zombie moddata is not reset when the zombie is recycled

bright fog
#

What you are doing is right

bronze yoke
#

this means that when a zombie unloads, a random future zombie will inherit its moddata

bright fog
#

Exactly

#

That's what I'm saying

#

The mod data shuffles around

bronze yoke
#

because of this there's no real reason to use moddata on zombies

#

it's not just not persistent but causes false positives later on

thick karma
#

😭

bright fog
#

Yeah so use mod data linked to a trueID of a zombie with the function I sent you yesterday or whenever

verbal yew
#

I'M NOT ABOUT MOD DATA AT THIS TIME!!!

bright fog
#

Or your zombies will just be shuffled around and some will be marked as updated even tho they aren't updated

thick karma
#

Maybe (probably) I missed something, but is this a thing that makes sense?

    zombie:makeInactive(true)
    zombie:makeInactive(false)
thick karma
#

Why would you... what would be... why?

bright fog
#

That's to update the speed of zombies

thick karma
#

You have to make them inactive and then active again?

#

I seee...

bright fog
#

yup

verbal yew
#

guys guys guys

thick karma
#

Gross (sorry I'll shut up)

bright fog
# verbal yew I'M NOT ABOUT MOD DATA AT THIS TIME!!!

You mark zombies as updated with mod data, this is wrong because an entity will be marked as updated and perhaps it got updated but once you reload that area, that same entity will get a random IsoZombie class applied to it and thus not HIS mod data. So you mark zombies as updated, and others not yet but you end up shuffling these around so zombies get the wrong marks of being updated

bright fog
verbal yew
#

main problem - i swap speed for zombies - but i take this zombies like IsoZombies, here:

local zs = getCell():getZombieList()
local sz = zs:size()
print("This now: " .. now)
for i = 0, sz - 1 do
  local z = zs:get(i)
  --if not z:getModData().zReRANDOMZOMBIES  then
    zRe_updateZombie(z)
  --end
end

i transfer z in all functions, it's like isoZombies, yep?

verbal yew
#

STOP IT XD

verbal yew
#

In next function i change speed for this z with sandbox options.
This is options put info in z modData, right?

bright fog
#

What are you talking about ?

#

zombie:getModData().zReRANDOMZOMBIES = true

verbal yew
#

forgot about moddata plz

#

in this time

bright fog
#

YOU'RE LITERALLY TALKING ABOUT IT

#

WTF DO YOU EXPECT ME TO TALK ABOUT

verbal yew
#

I'm not talking about my flag

#

i mean

#

zombies in default contain info, somewhere... in ModData?! Nope? (not my flag, something like Health, Walk_Type etc)

bright fog
#

You mean like accessing the zombie stats ?

bronze yoke
#

no, vanilla does not use zombie moddata at all

#

otherwise it would encounter this same issue

thick karma
#

I think he meant that rhetorically... I think he's wondering how to persistently store data on a zombie

bright fog
#

I told you about that, in my way of doing that I check the stats of the zombies are the right one via the fields

thick karma
#

He's suggesting there must be some way

#

If I'm not misunderstanding

verbal yew
#

._.

bronze yoke
#

well vanilla just uses fields that are saved/loaded when the zombie is recycled/created, nothing you would be able to access

thick karma
#

So checking the fields as Jvla suggested is the only way?

bronze yoke
#

there isn't a simple solution for modders to persistently associate data with zombies

bright fog
verbal yew
#

I'll take zombies. I change his speed to running. (FAK MOD DATE AT THIS EXAMPLE!). I'm going far away. I'm coming back. The speed dropped to walking. Why?

bright fog
bronze yoke
#

it works but it isn't simple and wasn't discovered without great effort

thick karma
#

If I'm understanding Jvla and albion.

bright fog
bronze yoke
#

i hope future builds add an explicit unique zombie id, and reset moddata so that it can at least be safe to use

verbal yew
thick karma
#

lol they're saying this too...

#

Just... differently...

bronze yoke
#

you kept yelling at us for talking about moddata but moddata was literally the problem 😭

thick karma
#

I think you gotta slooooow down the reading, padawan. πŸ˜‰

verbal yew
#

This is what I'm trying to find out.
So I need to work with the zombie as with his ID?

bright fog
verbal yew
violet shell
#

@thick karma @verbal yew I have an issue with Recipe names translation

bright fog
thick karma
thick karma
#

Oh what a cluster

bright fog
#

I just verified it bcs I haven't worked on my mod in a while

bronze yoke
#

they're walking when you return because:
a) the zombie unloaded and reloaded, which resets their speed
b) their speed did not get set again by your code, because the moddata stopped it from running

bright fog
#

But it doesn't yeah

thick karma
#

Oh man lol what a headache

#

I'm glad I don't mod zeds.

bronze yoke
#

me too 😭

verbal yew
thick karma
bright fog
#

I just tested it again and I find my zombie with its speed again

bronze yoke
#

are you sure? the whole reason chuck had to work out the pid stuff was because they *didn't* save their speed

bright fog
#

Tho I need to verify the speed doesn't get updated anymore

bronze yoke
#

it's not something i'm personally knowledgeable about but it surprises me to hear

bright fog
#

Let me test this further

#

I need to test this in a controlled area

verbal yew
bright fog
#

That's a possible reason why I find my zombies with the speed it's supposed to have yes

#

I'll test that better

violet shell
# thick karma What's your recipe file look like?

recipe Inject_Biocoded_Cure {
keep biocodedCureExp,
Result:BiocodedCure_Result,
Sound:BreakAmpule,
Time:120.0,
Category:Health,
CanBeDoneFromFloor:False,
NeedToBeLearn:False,
OnCreate:injectBiocodedCure,
RemoveResultItem:true,
Tooltip:Tooltip_Inject_Biocoded_Cure,
}

verbal yew
#

recipe Inject_Biocoded_Cure
{

bright fog
#

lol

#

classic stuff

verbal yew
#

without space after _Cure

thick karma
verbal yew
#

okay, i think im understood all problem, it's mean i should contain somewhere zID with my param and if i get this zID again - restore speed and another suff for this zID

thick karma
#

Spaces are allowed there.

#

It's used as the English translation

violet shell
#

Damn, the _ is the problem ?

thick karma
#

@violet shell
This:

    recipe Craft Jukebox
    {
        Tsarcraft.TCBoombox,
        Tsarcraft.TCVinylplayer,
        ElectronicsScrap=10,
        SheetMetal=1,
        Screws=4,
        ElectricWire=1,
        keep [Recipe.GetItemTypes.Screwdriver],
        noBrokenItems:true,
        Result:Moveables.recreational_01_1,
        NeedToBeLearn:true,
        Time:1200.0,
        Category:Electrical,
        AnimNode:Disassemble,
        Prop1:Screwdriver,
        Sound:Dismantle
    }

Corresponds to this:

violet shell
#

Ok, spaces are converted in the recipes translation files as underscores ?

thick karma
#

Correctamundo

bronze yoke
#

there's nothing wrong with having an inline opening bracket

bright fog
#

And neither is it linked to an IsoZombie

thick karma
bright fog
#

So every zombies have their speed reset

bronze yoke
#

e.g. working recipe from my mod``` recipe Make Tap Filter {
keep Base.Scissors,
Base.WaterBottleEmpty/Base.PopBottleEmpty,
Base.Sandbag=1,
Base.Gravelbag=1,
Base.RippedSheets/Base.CottonBalls,

    Result:TapFilter,
    Category:Survivalist,
    Time:30.0,
}
thick karma
#

Except about Steam star system.

bright fog
thick karma
#

Goddamn system is trash and irredeemable

bright fog
#

Our goddess Albion only speaks the truth

verbal yew
thick karma
#

So it's optional there?

#

Wow, never would have seen that coming.

bronze yoke
#

oh that's interesting, i see i used underscores too

thick karma
#

Thanks for enlightening us. @verbal yew

bright fog
#

I need to permanently update zombie stats

#

Unless I find a way to tag a zombie respawning

#

I could do that actually

#

Keep a list of every IsoZombies in a cell around the player

#

And whenever I have a zombie update, check if the zombie is in the list, if not that means it was newly loaded in

#

So requires an update of stats

verbal yew
#

yep, that's like Random Zombies by belette work

bright fog
#

Actually that could do it but how do I check that a zombie is no longer in the list, perhaps ontick verify every zombies in a cell

#

hmm

bronze yoke
#

sounds expensive

bright fog
#

yeazh

#

Trying to think of a way to keep it minimalistic

bronze yoke
#

ever think about how many mods would be like three lines if they just had OnCreateZombie

bright fog
#

I need to have my zombie updating function run before I append the list. I can have a timer OnTick to only update the list like every 10 seconds

bright fog
#

fucking hell

#

Actually

#

Actually wait

#

Could you link a new Event to the creation of a new zombie ?

#

Like myself ?

#

Without even java modding ?

#

A java decoration ?

#

@thick karma do you think that could be doable ?

bronze yoke
#

not without java modding

bright fog
#

Yeah bcs the creation of zombie is probably not accessible

thick karma
#

Although createZombie is exposed.

bronze yoke
#

i don't know if they're ever created by lua

bright fog
#

They are not created by lua, that's for sure