#mod_development

1 messages ยท Page 64 of 1

bronze yoke
#

it says override for those files even though it shouldn't

#

that's normal

dull moss
#

I was about to say, that's pretty much every single mod that uses sandbox options

#

looks fine to me

#

hm

#

I guess I could try disabling mods that create sandbox options in bunch see if it fixes issue

#

but idk

#

this is plain stupid why would a sandbox error in one mod fuck up my page

sour island
#

Any strack traces?

dull moss
#

no errors

sour island
#

Odd

cloud hatch
#

so whos gonna make a christmas tree mod

#

i was thinking about modeling + texturing some presents

#

it would be cool if you could wrap the thing you want with wrapping paper and you had to unwrap it to get whatever it was out of it

#

instead of it being a container

#

kind of like how the MRE's work i guess?

bronze yoke
#

that shouldn't be too difficult

cloud hatch
#

idk how to do any coding stuff but

#

if i model some presents n wrapping paper things would someone be down to make it for christmas

#

we have to have a zomboid christmas

bronze yoke
#

i've been a bit busy recently, but i do love christmas...

sour island
#

Super Weird Helis has a Santa Clause event - triggers on real life Christmas week and in-game Christmas at a higher rate

#

Forgot about it - can't wait to get bug reports for extra events lol

bronze yoke
#

i think it can be done pretty simply, i'm sure i could find time to write it

cloud hatch
#

im gonna model like 5 diff shaped boxes

#

w textures

#

ill just use some royalty free seamless textures and slap em on with a ribbon texture

#

the hardest part is gonna be modeling the ribbon

#

LOL

#

Shitty Ribbon

wet sandal
#

Honestly, for Zomboid's style and camera distance, you're basically done

dull moss
#

Found the culprit. Somehow these 40 lines of code fuck it up.

local fn_false = function()
    return false
end

--require "ISUI/ISUIElement"
--ISUIElement.getKeepOnScreen = fn_false

--ISPanel>ISItemsListTable
--ISPanel>ISPlayerStatsUI

local NORMAL = {'ISCollapsableWindow', 'ISPanelJoypad', 'ISWindow', 'ISPanel',
    'ISDebugPanelBase','ISDebugMenu'}
local ERRORS = nil

for _,v in pairs(NORMAL) do
    --require('ISUI/'..v)
    if _G[v] then
        _G[v].getKeepOnScreen = fn_false
    else
        ERRORS = ERRORS or {}
        table.insert(ERRORS, v)
    end
end

------------ EXCEPTIONS ------------

local fn_true = function()
    return true
end

local EXCEPTIONS = {'ISVehicleDashboard','ISToolTip','ISTextEntryBox',
    'ISContextMenu','ISChat','ISInventoryPage',}

for _,v in pairs(EXCEPTIONS) do
    if _G[v] then
        _G[v].getKeepOnScreen = fn_true
    else
        ERRORS = ERRORS or {}
        table.insert(ERRORS, v)
    end
end


if ERRORS then
    for _,v in ipairs(ERRORS) do
        print('ERROR in WindowsEverywhere: module "' .. v .. '" not found!')
    end
    error('WindowsEverywhere has to be fixed!')
end```
#

from this mod

#

it has 1 lua file

#

fuck I really liked that mod

cloud hatch
#

if you saw the UV texture for this thing youd think im the worst person alive

faint jewel
#

i bet

cloud hatch
wet sandal
#

Lol, I love it

faint jewel
#

HEATHEN

wet sandal
#

I have no clue how to effectively UV map

spiral sparrow
wet sandal
#

Throwing together another QoL mod, just passed the proof of concept point

bronze yoke
#

ooh lovely

cloud hatch
#

im gonna find some cute lil seamless textures

#

hopefully the UV isnt a pain in my ass when i change the shape

#

since its still technically a cube

spiral sparrow
wet sandal
#

Order of the hotbar

spiral sparrow
#

Ooooh.

wet sandal
#

back is always first by default

#

Main challenge right now is ensuring compatibility with Weapon Condition Indicators. Ties my hands a bit in what I can do.

thick karma
#

Is there a function of the context menu options that allows you to add a function to the "back" command sent from a gamepad upon choosing to back out of the context menu? he asked, fully expecting crickets but hoping to be wrong...

wet sandal
#

Looks like there is a fairly clean point to add custom code

#
function ISContextMenu:onJoypadDown(button)
    if button == Joypad.AButton then
        if self.mouseOver > 0 and self:getIsVisible() then
            --print("calling option : " .. self.options[self.mouseOver].name);
            -- we call the function if we have one
            local option = self.options[self.mouseOver]
            if option ~= nil and option.onSelect == nil  and option.subOption ~= nil then
                local subMenu = self:getSubMenu(option.subOption)
                subMenu.mouseOver = 1;
                if self:isOptionSingleMenu() then
                    subMenu.mouseOver = subMenu.mouseOver + subMenu:getDefaultOptionCount()
                    self:displaySubMenu(subMenu, option)
                else
                    setJoypadFocus(self.player, subMenu)
                end
            elseif option ~= nil and option.onSelect ~= nil and not option.notAvailable then
                ISContextMenu.globalPlayerContext = self.player;
                self:closeAll();
                option.onSelect(option.target, option.param1, option.param2, option.param3, option.param4, option.param5, option.param6, option.param7, option.param8, option.param9, option.param10);
            end
        end
    end

    -- HERE VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
    if button == Joypad.BButton then
        --[[
        if self:isOptionSingleMenu() then
            if self.parent then
                self:displayAncestor(self.parent)
                return
            end
        end
        --]]
        self:closeAll()
    end
end
#

You could instantiate your context menu instance then override this bit

bronze yoke
#

it freezes for ~20 seconds when you try to use the recipe to load every item in the game for this preview ๐Ÿ˜Ÿ

#

wrap present > all is also a funny button to have

#

maybe i won't use a recipe after all ๐Ÿ˜…

thick karma
faint jewel
#

thems a lot of big type words, and i'm gonna take them as offense.

bronze yoke
#

OnObjectRightMouseButtonDown

#

just watch out, it might not pass the object you want

faint jewel
#

oh?

#

hmm

#

is there an up rather than down?

thick karma
#

Trying

Jumper.onContextMenuJoypadDown = ISContextMenu.onJoypadDown
function ISContextMenu:onJoypadDown(button)
    Jumper.onContextMenuJoypadDown(self, button)
    if button == Joypad.BButton then
        if self.parent then
            self.parent:setVisible(false)
        end
        self:setVisible(false)
    end
end
#

So right after it does its original stuff I try to setVisible(false) on the parent and itself

#

Yet the deepest context menu survives ๐Ÿ˜ญ

#

For some reason this bug does not exist for KBM users

#

I need to look into what happens differently when clicking off context menu vs. hitting B-button.

#

Something is missing for gamepad users (as usual ๐Ÿ˜ญ)

faint jewel
thick karma
#

(Also tried right before original function, no dice)

#

Bahahaha @wet sandal

#

Super hacky fix

#

But I got it workin on that breadcrumb

#

For laughs:

#
-- Context Menu Fix

Jumper.onContextMenuJoypadDown = ISContextMenu.onJoypadDown

function ISContextMenu:onJoypadDown(button)

    Jumper.onContextMenuJoypadDown(self, button)

    if button == Joypad.BButton then
        
        for index = 1, #Jumper.categoryMenus do

            if Jumper.categoryMenus[index]:isVisible() then
                Jumper.categoryMenus[index]:setVisible(false)
            end

            Jumper.categoryMenus[index] = nil

        end
        
    end

end
#
-- Category Menu Fix From Hell

Jumper.categoryMenus = {}

-- World Context Menu Options

Jumper.bringingBuddies = false

Jumper.addCategoryLocation = function(player, menu, category)

    local categoryMenu = menu:getNew(menu)

    Jumper.categoryMenus[#Jumper.categoryMenus + 1] = categoryMenu

    . . . 

end
#

Tysm for spotting that function.

#

โค๏ธ

wet sandal
#

Nice!

#

Almost done my mod, just gotta add proper support for blank slots in the middle (they get shoved to the right side no matter what right now)

dark arch
true vault
#

Is there a way to load additional recipe files, only if a sandbox bool is checked/true? I know how to create the options, and read the values, however I don't know how to make the Lua function add the file(s) containing the additional models, recipes, items, etc if said value is true.

thick karma
#

Rubber Ducky solved it, feel free to skip these messages.

DEPRECATED: Okay, y'all, I'm increasingly suspicious the problem is, as usual, me. So the deal here is that all these menu functions and submenu functions work just swimmingly as long as you navigate straight to them and activate them...

Jumper.addCategoryLocation = function(player, menu, category)
    local categoryMenu = menu:getNew(menu)
    Jumper.categoryMenus[#Jumper.categoryMenus + 1] = categoryMenu
    menu:addSubMenu(menu:addOption(category), categoryMenu)
    for index, location in ipairs(Jumper.connections[category]) do
        local locationMenu = menu:getNew(menu)
        menu:addSubMenu(categoryMenu:addOption(location.name), locationMenu)
        local jumpText = "Jump"
        if SandboxVars.Jumper.canBringBuddies then jumpText = "Solo Jump" end
        locationMenu:addOption(jumpText, player, 
            function() 
                Jumper.bringingBuddies = false
                Jumper.jump(player, location.name, location.category)
                categoryMenu:setVisible(false) 
            end
        )
        if SandboxVars.Jumper.canBringBuddies then
            locationMenu:addOption("Group Jump", player, 
                function()
                    Jumper.bringingBuddies = true
                    Jumper.jump(player, location.name, location.category)
                    categoryMenu:setVisible(false) 
                end
            )
        end
        locationMenu:addOption("Rename", player, 
            function()
                Jumper.RenameLocationPanel:setCategory(category)
                Jumper.RenameLocationPanel:setLocation(location.name)
                Jumper.RenameLocationPanel:open()
                if Jumper.joypad(player:getPlayerNum()) then
                    JumperKeyboard.show(
                        player:getPlayerNum(), 
                        Jumper.RenameLocationPanel.textEntry, 
                        Jumper.joypad(player:getPlayerNum()), 
                        "Location", true --> renameMode
                    )
                else
                    Jumper.RenameLocationPanel.textEntry.javaObject:focus()
                end
                categoryMenu:setVisible(false)
            end
        )
        locationMenu:addOption("Forget", player, 
            function() 
                Jumper.forgetLocation(player, location.name, location.category)
                categoryMenu:setVisible(false) 
            end
        )
    end
    categoryMenu:addOption("Remember Current Location", player, 
        function()
            Jumper.LocationPanel:setCategory(category)
            Jumper.LocationPanel:open()
            if Jumper.joypad(player:getPlayerNum()) then
                JumperKeyboard.show(
                    player:getPlayerNum(), 
                    Jumper.LocationPanel.textEntry, 
                    Jumper.joypad(player:getPlayerNum()), 
                    "Location"
                )
            else
                Jumper.LocationPanel.textEntry.javaObject:focus()
            end
        end
    )
    categoryMenu:addOption("Rename Current Category", player, 
        function() 
            Jumper.RenameCategoryPanel:setCategory(category)
            Jumper.RenameCategoryPanel:open()
            if Jumper.joypad(player:getPlayerNum()) then
                JumperKeyboard.show(
                    player:getPlayerNum(), 
                    Jumper.RenameCategoryPanel.textEntry, 
                    Jumper.joypad(player:getPlayerNum()), 
                    "Category", true --> renameMode
                )
            else
                Jumper.RenameCategoryPanel.textEntry.javaObject:focus()
            end
        end
    )
    categoryMenu:addOption("Forget Entire Category", player, 
        function() 
            Jumper.forgetCategory(player, category)
        end
    )
end
#

However, if I navigate to the 3rd level deep menu items, (Category > Location > Jump, e.g.), and then I press Left on the D-Pad, it skips from Jump-level to Category-level focus. The problem is that (A) this is not proper vanilla behavior for D-Pad left from 3rd to 2nd level of the world context menu, and (B) this leaves a misleading highlight on the 2nd level context option until you press D-Pad Right followed by D-Pad Left to trip the 2nd to 1st level transition, which is working correctly (which of course many people would never think to do, given the misleading visual cue about what is actually selected).

#

I feel like I must be doing something subtly wrong going from menu (the main level where I add a Category Name) to the first submenu (a Location in my code) to the second submenu (options to Jump, forget a Location, etc.).

#

I must not be linking them the way vanilla needs them to be linked but I just can't see why not.

#

Wait... could it be this?

local locationMenu = menu:getNew(menu)

Should it be this?

local locationMenu = categoryMenu:getNew(categoryMenu)
#

Omg that was it?

#

Thank you, Sir Ducky.

true vault
#

๐Ÿฆ† the duck method always works >.>

quasi kernel
#

The duck always prevails.

prisma gale
#

Have created item with OnEat = 123ABC , but no context menu appears for using item, any help

ancient grail
#

@viral karma @bronze yoke @astral dune @thick karma
Thank you for the support. Got the radar working ๐Ÿ™‚

ancient grail
trail lotus
#

RADAR RADAR RADAR RADAR

#

i can't wait to see it be used wanna see some tickets MUHAHHA

bronze yoke
prisma gale
neat prairie
#

Hey ya'll whats the best way to automate server restarts to update mods? sorry if this gets asked allot.

true vault
# neat prairie Hey ya'll whats the best way to automate server restarts to update mods? sorry i...

A mod like one of these:
https://steamcommunity.com/sharedfiles/filedetails/?id=2844315442
https://steamcommunity.com/sharedfiles/filedetails/?id=2779169728

Plus a batch file that auto-restarts the server when it's closed. The mod will gracefully crash the server when the specified conditions are met (personally our community server uses the first one), such as updated mods were detected, and, noone is logged onto the server. The batch file will restart the server binary once it closes.

faint jewel
#

this is getting too deep ๐Ÿ˜ฆ

trail lotus
#

its so sexc

#

i can't wait to use it

neat prairie
#

@true vault Thank you, been trying to find a way without using RCON, just something simple.

true vault
# neat prairie <@275129919598755840> Thank you, been trying to find a way without using RCON, j...

As an example, the .bat file would look something like:

:start
@echo off
echo Starting Server
@setlocal enableextensions
@cd /d "%~dp0"
SET PZ_CLASSPATH=java/istack-commons-runtime.jar;java/jassimp.jar;java/javacord-2.0.17-shaded.jar;java/javax.activation-api.jar;java/jaxb-api.jar;java/jaxb-runtime.jar;java/lwjgl.jar;java/lwjgl-natives-windows.jar;java/lwjgl-glfw.jar;java/lwjgl-glfw-natives-windows.jar;java/lwjgl-jemalloc.jar;java/lwjgl-jemalloc-natives-windows.jar;java/lwjgl-opengl.jar;java/lwjgl-opengl-natives-windows.jar;java/lwjgl_util.jar;java/sqlite-jdbc-3.27.2.1.jar;java/trove-3.0.3.jar;java/uncommons-maths-1.2.3.jar;java/commons-compress-1.18.jar;java/
".\jre64\bin\java.exe" -Djava.awt.headless=true -Dzomboid.steam=1 -Dzomboid.znetlog=1 -XX:+UseZGC -XX:-CreateCoredumpOnCrash -XX:-OmitStackTraceInFastThrow -Xms16g -Xmx16g -Djava.library.path=natives/;natives/win64/;. -cp %PZ_CLASSPATH% zombie.network.GameServer -statistic 0 %1 %2
cls
timeout /t 30 /nobreak
goto start

Change the -Xms16g and -Xmx16g to whatever is appropriate for your own server.

trail lotus
#

@faint jewel how will people get the truck driver role?

faint jewel
#

it's an actual PROFESSION now.

#

like burglar and police.

trail lotus
#

ahh well what if some one want's to change professions ๐Ÿ˜ฆ

#

itll limit the server a bit don't you think?

faint jewel
#

well we need a mod for that then.

neat prairie
faint jewel
#

a profession board. where they can rechoose their profession.

trail lotus
#

lmao i think we should just let anyone be able to do it. if they buy it and don't have a truck then boom they are sol LOL

#

jk the profession board would be cool

true vault
neat prairie
#

I'll give it a go, the batch I was playing with would open the steamCMD updater then launch

#

The startserver.bat

true vault
#

Alright, so still looking if anyone can answer this:

Is there a way to load additional recipe files, only if a sandbox bool is checked/true? I know how to create the options, and read the values, however I don't know how to make the Lua function add the file(s) containing the additional models, recipes, items, etc if said value is true.

However, I also now need to know how to pull a sandbox option from the server, so the client can see if something is enabled or not.

Coincidentally, they're actually for two different things/options >.>

faint jewel
#

i aint put it in yet, could make it a server option... "only truckers can truck" XD

bronze yoke
#

as for conditional recipes, you can either create the recipe entirely through lua if it's enabled, or create it in the script and use some lua to yeet the recipe if it's disabled

finite owl
#

What's the motivation for only loading the recipes based on sandbox vars? Couldn't you just control whether players know the recipe using Lua?

bronze yoke
#

if the recipe is meant to be learned, this becomes very complicated, but yeah that is my preference

#

a mod of mine has a conditional recipe and i just set it to need to be learned when it's disabled

#

but i helped a server with removing an recipe from vanilla in a way that should be compatible with that too

finite owl
#

Seems to work nicely ๐Ÿ˜

#

(That's an AutoTsar bear bus bullbar installed on the front of a Filibuster Rhymes' RV)

bronze yoke
#

i'm glad that worked for you!

finite owl
#

Frankensteining different vehicle mods together isn't what I was planning on doing, but now that I can... ๐Ÿ˜

faint jewel
#

questions, can you change a vehicles whole script while driving it?

#

just for... reasons.

finite owl
#

Yeah, some way to refresh a vehicle's script during play would make debugging much faster, too. Like, I can modify the script object using Albion's technique, but it doesn't appear to update on the vehicle.

#

Actually, I seem to recall seeing a BaseVehicle method which applies the script to itself, need to go fishing...

bronze yoke
#

it was before my time helping them, but stfr used to swap vehicle scripts instead of using skins and it caused a whole bunch of issues

faint jewel
#

i want to change a vehicle to ANOTHER vehicle.

bronze yoke
#

it wasn't the right way of doing things in the first place so i never investigated if those issues could be mitigated

#

but there will at the very least be complications

faint jewel
#

I HAVE A GIMMICK VEHICLE THAT SOUNDS FUN. leave me alone lol.

wet sandal
#

No

fast galleon
#

Is it possible to set vehicle to not colide and not visible in any way?

What about changing wheels animation?

faint jewel
#

what are you trying to do?

fast galleon
#

I might mess with the idea of house on legs.

faint jewel
#

maybe some better art lol

agile vigil
finite owl
agile vigil
#

Hell yeah! Even if it is just the RV, sharing the code might make it possible for others to extend it to more vehicles and create a proper Mad Max style Zomboid experience ๐Ÿ˜„

finite owl
#

I'm not sure how the AutoTsar author would feel about it though. The ATA Bear Bus mod and TsarLib mods would need to be dependencies of any mod this experimentation might grow into, but given that the armoring up is kind of the schtick of the ATA mods, they might not be happy about it being applied to other vehicles.

#

But first things first, seeing if it's even possible is fun ๐Ÿ™‚

agile vigil
#

Absolutely. They have their own Discord channel if you wish to ask them directly about permission to post your mod publicly ๐Ÿ™‚

wet sandal
#

Its done zombie

agile vigil
#

That is pretty damn neat.

#

Would it be possible to add a Mod Options toggle to 'lock' the bar so you don't accidentally drag n' drop anything? ๐Ÿ™‚

wet sandal
#

The same request I got for the inventory containers version

#

Why did i not see this coming

agile vigil
#

Hahah ๐Ÿ˜„

wet sandal
#

Good call

agile vigil
#

I haven't played online in a tick, is the inventory containers one compatible with MP? I remember an earlier version of the same thing that didn't play well.

wet sandal
#

should be, i do store the mod data in the items, but i key off the playername/username

#

so should work as expected online

#

I only did theory for the MP support

#

But im yett to get a bug report relating to MP

agile vigil
#

Awesome. Slowly preparing a modlist for our group to return to online play when build 42 drops next year. I saw your mod yesterday and genuinely thought it wasn't possible for it to work in MP (due to that other mod in the past).

We'll have a lot of new players, and features like this are just great QoL we saw other new players last 'season' ask about.

#

I'll make sure to report it if we find something ๐Ÿ˜›

wet sandal
#

Haha thanks!
Nothing annoys me more than someone commenting:
"It doesn't work"

#

Refuses to elaborate

#

Leaves

agile vigil
#

Yeaaahh, I get that. Modding is rough sometimes. I just discovered that I managed to get 1000+ subs on my bait tooltips mod in the past 4 months, but 0 comments. Do people like it? Hate it? There's people who favourited it, but does that mean it is in a good state?

People never say a word ๐Ÿ˜„

rancid panther
#

i cant seem to figure out how to give a custom profession a free custom trait using profession framework

#

do i need the profession file to require the trait file in order to pull from it?

finite owl
#

setScript only seems to add or replace parts though, not remove them.

#

So if you setScript to a script without some parts that were in the previous script those parts would probably stay around

faint jewel
#

well if you get a chance to test it.

#

i need it to happen while IN it too.

finite owl
#

I'm sitting in the car when I hit F11 and reload my script, so that much seems to work fine.

#

(In the driver seat)

#

Yeah, it can't remove parts.

#

Or rather, setScript doesn't. There might be some other way to remove parts.

manic relic
#

quick question

#

when making a custom hoodie that has the Hood up or down option

#

do I need to add a second line in the fileGuidTable.xml?

#

cause there are 2 new models

#

the model with the hood up

#

and one with the hood down

ancient grail
faint jewel
#

is it possible to add an outline to a vehicle?

ancient grail
#

Never looked at the codes yet. But u might want to check just to be sure

ancient grail
faint jewel
#

huh?

ancient grail
#

Ow this is mod chat thought i was reading servers chat lol

faint jewel
#

lol

faint jewel
agile vigil
rancid panther
#

laughing to myself at how they spelled Appetite in the game's code

#

it's probably so deeply ingrained in there that they have to keep it at this point

ancient grail
agile vigil
#

It'd make sense for servers and collections, I think, which seems to constitute a modest amount of mod subscriptions in general ๐Ÿ™‚

ancient grail
#

You can probably do a lua code that does that if conditions arent met
And it will say this server is using an illegal modpack .
Then when they come online players will die horribly
Perhaps a mod util that does that if you are not using the real id . And other modders would require that if they eant their code to be safe against ilegal modpackers

#

Or perhaps a function that disables auto updates from mods
Besides the reason for people doing modpacks is cuz the update thing
If our mods has feature to not recieve updates when sandbox turned off then that might reduce the number of theft

ancient grail
rancid panther
#

can i make a trait using profession framework and redefine it with the basic code to add things the framework doesnt have?

ancient grail
#

@fast galleon i tagged u on a tech support thread. Check it out its your mod

finite owl
#

Huh - so unrecognised fields in an item's script definition get put into the item's modData, eh? I'm not sure if that's neat or ugly...

ancient grail
#

Thats useful . I know some nods that used that. I tried it too with booleans its something veryuseful.
Why would u think its ugly to have more control over script items?

#

This is how xyberviri made carwannas pinkslip be able to send multiple args too

finite owl
#

Well, I said I wasn't sure ๐Ÿ™‚ I guess it's just that if you make a typo on a real field, your misspelled field name will end up in modData.

ancient grail
#

I mean its iseful in temrs of having that extra container of data

finite owl
#

Yeah, I guess.

ancient grail
#

Aswell as enabling flexibility between lua and the txt

fast galleon
ancient grail
#

Down side eould be confusion to modders ehos only begining to learn the script items

finite owl
bronze yoke
dull moss
modern dune
#

hi all i am trying to write a simple mod to listen to some game events, but I can't find a guide on how to actually create a Lua script for them. Like for example if I want to listen to the EveryOneMinute function, what do I have to name the file in media/lua?

#

is there some FAQ or something for lua scripting & event listening? the docs are pretty sporadic from what i can find (which i understand way)

dull moss
modern dune
#

yes, exactly

#

can i just call the lua file anything and just listen to EveryTenMinutes?

#

or does it have to have a specific name

dull moss
#

lua file preferably something specific to your mod so other mod don't repeat it

#

(example there)

modern dune
#

ok thanks

#

is there any way to log stuff to a console or something?

dull moss
#

ofc you can rename function name to something better

#

print(<your stuff here>);

modern dune
#

where does it get logged?

dull moss
#

in console.txt

#

also in-game there's lua log

#

if you in debug mode

modern dune
#

so anything print() should appear in the in-game console in dev mode yeah?

bronze yoke
#

yes, aside from when the console isn't visible (main menu, loading)

modern dune
#

this console seems pretty jank

#

im trying to scroll up and down it slides around like its on ice or something

fast galleon
dull moss
#

I see

#

thanks

modern dune
#

so i have my script media/lua/client/CartoLog.lua, with this inside:

#

local function CartozoidEveryOneMinute()
print("CartozoidEveryOneMinute executing!");
end

Events.EveryOneMinute.Add(CartozoidEveryOneMinute)

#

but i dont see anying in the in-game dev console

#

am i missing something really obvious?

#

in-between, i hit the "reload lua" button on he main menu as well

neon bronze
#

are you sure that event exists? I cant find anything about it on pz api site

fast galleon
#

Reloads will not add function to events

neon bronze
#

reloads should just reload the file, right?

fast galleon
#

Nevermind, reload main menu

#

I'm gonna go with: is your mod enabled

modern dune
#

for some reason it appears as "unnamed mod", even though i filled out mod.info, but yes

neon bronze
#

but you wrote everyoneminute?

modern dune
fast galleon
#

EveryOneMinute is a valid event, it has a triggerEvent

neon bronze
#

huh, there aint one on the api site

modern dune
#

oh haha im dumb

#

VS code was working in a different folder than i thought

#

it is working now

bronze yoke
#

and this is an outdated javadoc anyway

neon bronze
#

Well it worked for me for some time but guess im gonna have to decompile stuff myself

#

Thanks for notifying though

bronze yoke
#

you should decompile, but the javadoc is still useful

dull moss
#

Question about errors. So let's say my lua file throws error in a function. Will the function be interrupted? Or will it keep running after? For example

if SandboxVars.MoreTraitsDynamic.GraverobberDynamic == true and not player:HasTrait("graverobber") and player:getPerkLevel(Perks.Scavenging) >= SandboxVars.MoreTraitsDynamic.GraverobberDynamicSkill and player:getZombieKills() >= SandboxVars.MoreTraitsDynamic.GraverobberDynamicKill then
    player:getTraits():add("graverobber");
    MTDapplyXPBoost(player, Perks.Scavenging, 1);
    HaloTextHelper.addTextWithArrow(player, getText("UI_trait_graverobber"), true, HaloTextHelper.getColorGreen());
end
-- Antique Collector
if SandboxVars.MoreTraitsDynamic.AntiqueCollectorDynamic == true and not player:HasTrait("antique") and player:getPerkLevel(Perks.Scavenging) >= SandboxVars.MoreTraitsDynamic.AntiqueCollectorDynamicSkill then
    player:getTraits():add("antique");
    MTDapplyXPBoost(player, Perks.Scavenging, 1);
    HaloTextHelper.addTextWithArrow(player, getText("UI_trait_antique"), true, HaloTextHelper.getColorGreen());
end

if there's error in 1st if, will it stop executing this function or will it keep going after?

bronze yoke
#

it will be interrupted

#

well it depends where the error is

#

iirc it interrupts your current scope, so if it's inside an if it'll continue with the others, but if it's in the if statement itself the file will stop executing

dull moss
#

shiet

modern dune
#

The "OnGameStart" takes no parameters. How can I get the player and their save information at that moment?

dull moss
#

getPlayer()

modern dune
#

just that? no namespace or anything?

dull moss
#

and wdym by save information

bronze yoke
#

it's likely better to use OnCreatePlayer in your situation

#

that passes a player object

modern dune
#

ah wait but does that only execute when the player is first created? or does the player also get "created" when a game is loaded?

bronze yoke
#

yeah it's every time the object is created

modern dune
#

so "created" in the context of the game session

bronze yoke
#

if you need to avoid this, generally you just set a moddata on the player

modern dune
#

i would like to get the folder in which all their data is saved

#

world and all

blazing pier
#

I am making a mod that let's you predict the weather.
(Once you learn how an have the equipment tho its not always 100% correct)

Tho ik some servers use commands to modify the weather for events and stuff so it breaks what I did.

Is there a way to remove the edit weather commands?

fast galleon
#

call it an act of God, go with it

#

maybe it's better to make those two compatible?

blazing pier
#

It breaks what I do if you manually change the weather lol

fast galleon
#

are you not just predicting the weather?

modern dune
blazing pier
# fast galleon are you not just predicting the weather?

It pretty much lines up weather events. So for the month it will trigger snow on the 13th, rain on 22nd etc etc (random weather examples)
And it does it for each 3 months it regenerates a cycle.

That's where it pulls the prediction from.

But say I go in and say "boom tropical storm command" it fucks with the weather all ready que up for the months.

#

Basicly makes all predictions wrong till next time it regenerates

bronze yoke
modern dune
#

i want to add a file to it which will track certain events over time

#

in between saves as well

#

so if you quit, then come back the next day, it will continue adding

bronze yoke
#

inbetween saves?

#

you can probably just write cross-save data like that to the lua cache directory

blazing pier
#

^

bronze yoke
#

and if it's save specific you should just use global mod data

modern dune
#

what do you mean by global mod data

fast galleon
bronze yoke
#

global mod data is basically a bunch of tables that saves with the save file

#

you can put anything you want in there, except objects and functions

modern dune
#

is there a general guide on that?

#

or does it mean to just save the data in the mod folder on the filesystem

bronze yoke
#

off the top of my head, local modData = ModData.getOrCreate('String Key, probably use the name of your mod')

#

this will give you a regular lua table, either empty or including anything you added to it before

#

you don't need to do anything special to save it so long as the table comes from here

modern dune
#

OnCreatePlayer's PlayerIndex param is null?

bronze yoke
#

that shouldn't ever happen

modern dune
#

i tried appending it to a string and java complains that it is trying to append a null value

ancient grail
#

So im learning about homing,markers,arrows and all that kinds of highlighting stuff

But my problem is i have to delete them within the same function
What if iwant to delete it on a diffrent function?

#

If anyone has tried playing with em

bronze yoke
#

can you print it? i can't see why it would be null

modern dune
#

oh wait shit, it's failing down in the EveryTenMinutes, for which there is no parameters haha

fast galleon
ancient grail
#

Can it be moddata?

fast galleon
#

It can(temporarily?), but I think they don't save so I would use something else

ancient grail
#

How exactly do i put it on a table
Like
table.insert(tablevar, markervar)
Or
tablevar['marker']=markervar

fast galleon
#

Are the function in same lua file?

ancient grail
#

Idk why.. if only theres a way to getPlayer():getMarker() em

fast galleon
ancient grail
#

So i should re trigger them incase they didapear

#

Like player dc or something

fast galleon
#

Java array with markers doesn't save, if you want them to appear after restart you need to set them again.

bronze yoke
#

if they're meant to persist you should save some data about them in global mod data

#

like their x,y or something, whatever you need to reconstruct them

fast galleon
ancient grail
#

Well all i need is if the player comes incontact with the sq it deletes the markers
And if a certain period of time the player didnt make it i have a manual delete function

This is for skizots mod
The delivery thing

#

Im helping em with the arrows thats all
I have written the code but it failed

fast galleon
#

Does the job save somewhere? You can add a savedMarker to it and check if it exists or need to add one

ancient grail
#

Cuz its a delivery thing and when time is expired its mission failed or something

So i need to be able to remove it.
I have done this before but i used delayed timer

modern dune
#

so i cannot use playerIndex in OnCreatePlayer because I believe that PlayerIndex is relative to the session, i.e. it will always be 0. But when I call player:getName(), I just get nil. Is there some special trick to accessing the Java object's getters that im not aware of?

bronze yoke
#

playerindex is always 0-3, it's clientsided

ancient grail
#

getOnlinePlayers()

modern dune
#

yeah i need something persistent

bronze yoke
#

getName() isn't really a character thing so it doesn't really do anything on them, even though they technically have the method

#

do you need it to differentiate different characters played by the same player after they died or is just the actual player enough?

modern dune
#

has to differentiate between different characters

bronze yoke
#

there's no vanilla way to differentiate them, but it's pretty simple

modern dune
#

this is single player only

bronze yoke
#
if not modData.StarlitUUID then
    modData.StarlitUUID = getRandomUUID()
end
```from one of my mods
#

i put this on OnCreatePlayer, it creates a character unique identifier

#

modData is from IsoPlayer:getModData()

modern dune
#

is getRandomUUID() built-in somewhere or does it have to be defined?

bronze yoke
#

it's part of the java global object

#

you can just call it like that

modern dune
#

so this should work, right?

#
local function CartozoidOnCreatePlayer(playerIndex, player)
    print("CartoZoidOnCreatePlayer executing");
    playerModData = IsoPlayer:getModData();
    if not playerModData.CartozoidUUID then
        playerModData.CartozoidUUID = getRandomUUID()
    end
    print("CartozoidUUID:");
    print(playerModData.CartozoidUUID);
#

BTW i dont know how to format as code

bronze yoke
#

```lua
-- code
```

modern dune
#

ah, thanks

#

oh shite i think i see it now

bronze yoke
#

it should be player:getModData()

modern dune
#

yea

bronze yoke
#

i wrote IsoPlayer since i don't know what your variable is going to be called

modern dune
#

ok yeah now its working

#

thanks for helping me through the initial bumbling steps

bronze yoke
#

of course ^^

modern dune
#

is there any way to add UI elements to the home screen somehow?

dull moss
#

if I have following ModData structure

function ETInitialize()
    player = getPlayer();
    player:getModData().ExplorerTrait = player:getModData().ExplorerTrait or {};

    player:getModData().ExplorerTrait.OldCell = player:getModData().ExplorerTrait.OldCell or {};
    player:getModData().ExplorerTrait.OldCell.X = player:getModData().ExplorerTrait.OldCell.X or 0;
    player:getModData().ExplorerTrait.OldCell.Y = player:getModData().ExplorerTrait.OldCell.Y or 0;
    player:getModData().ExplorerTrait.OldCell.ExploredTiles = player:getModData().ExplorerTrait.OldCell.ExploredTiles or {};

    player:getModData().ExplorerTrait.CurrentCell = player:getModData().ExplorerTrait.CurrentCell or {};
    player:getModData().ExplorerTrait.CurrentCell.X = player:getModData().ExplorerTrait.CurrentCell.X or 0;
    player:getModData().ExplorerTrait.CurrentCell.Y = player:getModData().ExplorerTrait.CurrentCell.Y or 0;
    player:getModData().ExplorerTrait.CurrentCell.ExploredTiles = player:getModData().ExplorerTrait.CurrentCell.ExploredTiles or {};
end```
#

and I wanna dump old cell and replace it with new cell

#

Do i need to do this

function dumpOldCell()
    player = getPlayer();
    player:getModData().ExplorerTrait.OldCell = player:getModData().ExplorerTrait.CurrentCell;
    player:getModData().ExplorerTrait.OldCell.X = player:getModData().ExplorerTrait.CurrentCell.X;
    player:getModData().ExplorerTrait.OldCell.Y = player:getModData().ExplorerTrait.CurrentCell.Y;
    player:getModData().ExplorerTrait.OldCell.ExploredTiles = player:getModData().ExplorerTrait.CurrentCell.ExploredTiles;
end```
or this is enough
```lua
function dumpOldCell()
    player = getPlayer();
    player:getModData().ExplorerTrait.OldCell = player:getModData().ExplorerTrait.CurrentCell;
end
#

Aka

bronze yoke
#

the shorter one is enough

dull moss
#

ty

modern dune
#

how do you get the player's current position? i have tried like 5 different ways and all of them return nil

#
    print("Player is at: ")
    player = getPlayer();
    current = player.current;
    print(current);
#

as well as

dull moss
#

funny that u asked

modern dune
#
    player = getPlayer();
    print(player.x);
    print(player.y);
dull moss
#

Im doing exactly that right now

#
playerX = math.floor(player:getX());
playerY = math.floor(player:getY());
print("Player pos: x"..playerX ..", y: "..playerY)
modern dune
#

ahhh of course

#

because .current is protected

#

its been so long since i wrote in a language that makes you actually think about access lmao

#

ive become such a python monke

dull moss
#

be like me, think about nothing and just write stuff

bronze yoke
#

you can't really grab fields most of the time

#

there's some weird reflection stuff you can sometimes do but you usually don't need to bother with it anyway

modern dune
#

theyre being all proper with their getters & setters

#

so i actually want to ultimately dump a lot of this data to a file, does anyone know what is the working directory that lua is executing in?

#

i tried some stuff off stackoverflow that is supposed to tell you the working dir but it didnt seem to work

prisma gale
#

anyone have any knowledge around scripting in meds that can give some points, having a nightmare of a time with making a painkiller that actually works

dull moss
#

i'd recommend checking big trait mods. there are few negative perks out there that add pain to character

#

i'm fairly sure you can remove same way

#

don't know myself though, haven't dug in pain stuff

agile vigil
#

Updating my bait trap mod to also show what you can catch with each trap type.

I wanted to ask if people could think of any neat / useful additions I could make to this simple tooltip mod?

dull moss
agile vigil
dull moss
#

oh thats cool

modern dune
#

maybe remove the word "dead"

#

i guess you are probably using the entity name itself

#

but it is a bit odd

tardy wren
#

Would it only be shown when you have both a valid bait and a trap in your inventory?

agile vigil
#

(It's Mutie's Bait Tooltips on the workshop)

I am using the item name, because that's what we have access to in the code. This means it is localised depending on what language you have selected.

#

It is currently always shown, but I am working on:

  • Using Mod Options to add a modifier key (e.g. hold Shift for extended tooltips)
  • Using SandboxVars to limit it to certain skill level (e.g. Trapping 6+), a specific trait/occupation, or to requiring a magazine.
agile vigil
modern dune
#

yes thats a good point#

agile vigil
tardy wren
#

I haven't done any trapping yet, mainly due to the lack of bait...

agile vigil
#

I can recommend foraging for insects. Crickets, grasshoppers, and cockroaches can be used in stick traps to catch birds.

You can also find Worms through farming, or by furrowing soil with a trowel.

modern dune
#

does anyone have any idea why i cannot write to a file in the lua function here?

#
fileDescriptor = io.open("carto.txt", "a");
fast galleon
modern dune
#

shit

#

ok well i thought that might be the case, i guess it makes sense, too easy to do nefarious stuff

#

then does anyone have an idea of how i might be able to dump accumulated data on a character via its modData to a file some other way?

#

like is it possible to access the modData from outside of PZ?

agile vigil
#

If this is just for debugging you could write it to the console and check your logs?

dull moss
#

anyone with bigrain here? Don't wanna spend next 10 min being pepega. If I want to grab 20x20 square around player, is this correct?

playerX = math.floor(player:getX());
playerY = math.floor(player:getY());

playerCellX = math.floor(playerX / 300);
playerCellY = math.floor(playerY / 300);

scoutedAreaMinX = math.max(playerX - 10, playerCellX * 300);
scoutedAreaMaxX = math.min(playerX + 10, (playerCellX + 1) * 300);
scoutedAreaMinY = math.max(playerX - 10, playerCellY * 300);
scoutedAreaMaxY = math.min(playerX + 10, (playerCellY + 1) * 300);

or did I mess up signs in last 4 lines?

modern dune
#

no its meant to be a core feature

#

i want to allow the player to export data about their character that has been accumulated over the course of their run

fast galleon
#

@modern dune
Maybe you can find something here

#

I know chuck and burryaga also write to files

bronze yoke
#

local fileWriter = getFileWriter(filename, createIfNull, append)

#

filenames are relative to Zomboid/Lua/

fast galleon
#

yeah, you can also search vanilla for filewriter filereader calls

modern dune
#

i think my mod may not be possible then

#

i wanted to continuously grow a list of player positions & various significant events so that it could be visualized on a canvas of the world map afterwards

#

but if i cannot actually dump the data then...

bronze yoke
#

you can dump the data with what i just mentioned

modern dune
#

oh wait sorry i had not scrolled apparently

bronze yoke
#

i wrote a little thing that collects statistics for a server and writes them to a json file, that's pretty similar to what you're trying to do

#

so it's definitely possible

modern dune
#

yes indeed, ok that brings my motivation back haha

#

the dev from that seems to have open sourced everything related to its development

bronze yoke
#

yeah, i've seen a couple servers that actually run their own server maps

agile vigil
#

Oh heavens.

fast galleon
#

there's also a getModFileWriter if you'd prefer to write into a mod folder, wonder if that works

modern dune
bronze yoke
#

should be like

local fileWriter = getFileWriter('test.txt', true, false)
fileWriter:write('whatever')
fileWriter:close()
modern dune
#

thought i tried that, maybe i buggered it up somehow

#

ah it doesnt like relative paths

#

thats a bit annoying

#

ok well i guess its going in ./Lua then

bronze yoke
#

you can use subdirectories, but you can't escape the lua folder

dull moss
#

Any lua professionals?

size = 3;
scoutedAreaMinX = math.max(playerX - size, playerCellX * 300);
scoutedAreaMinY = math.max(playerX - size, playerCellY * 300);
scoutedAreaMaxX = math.min(playerX + size, (playerCellX + 1) * 300);
scoutedAreaMaxY = math.min(playerX + size, (playerCellY + 1) * 300);
print("Allowed area in this cell. From x="..scoutedAreaMinX..", y="..scoutedAreaMinY.." to x="..scoutedAreaMaxX..", y="..scoutedAreaMaxY);
for x = scoutedAreaMinX, scoutedAreaMaxX do
    print("Working on x="..x);
    for y = scoutedAreaMinY, scoutedAreaMaxY do
        print("Working on y="..y);
        cantor = (x + y) * (x + y + 1) / 2 + x;
        print ("Got Cantor: "..cantor);
        --table.bininsert(player:getModData().ExplorerTrait.CurrentCell.ExploredTiles, cantor);
    end
end

Why doesn't it reach "working on y"?

bronze yoke
#

well yeah if you use a different filewriter you can get yourself sandboxed to a different folder

modern dune
#

hey i'll take it

#

half an hour ago i thought i was not even possible

bronze yoke
#

there's also a sandbox file writer, which writes to Zomboid/Sandbox Presets/ but there isn't a reader for it lol

fast galleon
#

lol

#

usually mods that write into mod folder are weird, I uninstall them and when I decide to check them out again the data is gone, lol

dull moss
#

bro does lua nested for loop only allows 1 line in it?

bronze yoke
#

no

modern dune
#

ok, well thank you very, very much @bronze yoke, my proof of concept is complete

#

and also to others like @fast galleon and @dull moss

dull moss
#

I mean all I did is told you how to get player X and Y, but yw ๐Ÿ˜„

modern dune
#

well you showed me the one way i didnt try then lol

#

so on a more theoretical level, what do you guys think would be interested events that should be logged during a playthrough that a player might like to see on the map postgame?

#

obviously movements every 10m, zombie kills

dull moss
#

player movement heatmap would be nice

modern dune
#

i was thinking like "first time aquisition" of various special items, like sledgehammer, antique oven, generator, etc.

modern dune
bronze yoke
#

make sure it isn't a negative size

dull moss
#

hm

#

bruh I'm r-word

#

LOG : General , 1671394323433> Allowed area in this cell. From x=11128, y=11128 to x=11134, y=6900

fast galleon
#

you use playerX in areaY

dull moss
#

yes

#

certified dented moment

#

btw checked 4 times

dull moss
#

as you can see I'm very keen on details

#

how would one get size of an array?

player:getModData().ExplorerTrait.CurrentCell = player:getModData().ExplorerTrait.CurrentCell or {};
player:getModData().ExplorerTrait.CurrentCell.X = player:getModData().ExplorerTrait.CurrentCell.X or 0;
player:getModData().ExplorerTrait.CurrentCell.Y = player:getModData().ExplorerTrait.CurrentCell.Y or 0;
player:getModData().ExplorerTrait.CurrentCell.ExploredTiles = player:getModData().ExplorerTrait.CurrentCell.ExploredTiles or {};
/some code here/
print("Size of Explored Tiles array: "..table.getn(player:getModData().ExplorerTrait.CurrentCell.ExploredTiles));

doesn't work

bronze yoke
#

#player:getModData().ExplorerTrait.CurrentCell.ExploredTiles

dull moss
#

oh right

#

forgot its obsolete now

bronze yoke
#

you should bring moddata into the local space, and maybe some of these other tables too

dull moss
#

hm

bronze yoke
#

calling the java for every one of these operations is going to be pretty inefficient

dull moss
#

top part is called only on game load

#

Events.OnGameStart.Add(ETInitialize);

modern dune
#

is there an event for pickup up an item?

bronze yoke
dull moss
#

elaborate what you meanpls

#

this is how things are rn

#

I only access mod data few times

#

exception is writing stuff into it

bronze yoke
#

hmm might be a waste if that's the whole function

dull moss
#

wdym

#

where can I optimize

bronze yoke
#

oh no i meant my optimisation would be kind of unnecessary

dull moss
#

ye

#

If i'd call it at least 2-3+ times I'd do it

bronze yoke
#

i'd still recommend bringing the moddata into the local space but the full thing is not needed

dull moss
#

but i call it like once

dull moss
#

I initialize it once game load

#

so there are no nils

#

why would i bring it afterwards into function that runs every minute

bronze yoke
#
local modData = player:getModData()
modData.ExplorerTrait = modData.ExplorerTrait or {}

modData.ExplorerTrait.OldCell = modData.ExplorerTrait.OldCell or {}
local OldCell = modData.ExplorerTrait.OldCell
OldCell.X = OldCell.X or 0
OldCell.Y = OldCell.Y or 0
OldCell.ExploredTiles = OldCell.ExploredTiles or {}

modData.ExplorerTrait.CurrentCell = modData.ExplorerTrait.CurrentCell or {}
local CurrentCell = modData.ExplorerTrait.CurrentCell 
CurrentCell.X = CurrentCell.X or 0
CurrentCell.Y = CurrentCell.Y or 0
CurrentCell.ExploredTiles = CurrentCell.ExploredTiles or {}
```this is what i was thinking of, but i didn't know that was the entire usage of those tables in that function
dull moss
#

I'm probably not getting something (barely any lua experience) but that seems generally unnecessary

bronze yoke
#

it's just prettier

dull moss
#

Istn moddata soupposed to be accessed via getModData

#

if I want to edit it

bronze yoke
#

yes, but getModData is a java function

#

it's slow

dull moss
#

yea but if i want to edit the data

bronze yoke
#

storing it in a local variable behaves exactly the same

dull moss
#

oh

#

wait

bronze yoke
#

lua tables are passed by reference not by value

dull moss
#

OH

#

yo ok i didnt know that one

#

time to rewrite all my mods hyperloaf

#

MORE SPEED

bronze yoke
#

also please make variables like this local, the names are kind of generic so this could easily cause problems with other mods, and global variables are just slower anyway

dull moss
#

wait

#

arent variables local by default

bronze yoke
#

no... :(

dull moss
#

BRAH

#

time to rewrite a bunch of shit

#

yea I thought they are local by default

bronze yoke
#

if you want to keep your mods accessible to patching, you can keep everything in your mod that would be in the global namespace in a local table and return that table at the end of the file

dull moss
#

that sounds like effort

bronze yoke
#

like this

local Mod = {}

Mod.GlobalVariable = value
function Mod.Function(parameters)
    local variablesInsideOfFunctionsDontNeedToUseTheTable
end

return Mod
```it's not too necessary though
dull moss
#

so If I have something like this

player:getModData().KillCount = player:getModData().KillCount or {};
local categoryKills = 0;
if player:getModData().KillCount ~= nil and player:getModData().KillCount.WeaponCategory ~= nil then

I can make it like this

player:getModData().KillCount = player:getModData().KillCount or {};
local KillCount = player:getModData().KillCount;
local categoryKills = 0;
if KillCount ~= nil and KillCount.WeaponCategory ~= nil then
#

?

bronze yoke
#

yeah

dull moss
#

cool, gotta refracture 800 lines of code despairge

agile vigil
#

Could someone save me a few minutes of looking around. When I'm using client-side code is there a quick way to get data about the current character? Specifically, I want to check a skill level.

bronze yoke
#

getPlayer():getPerkLevel(Perks.PerkName)

agile vigil
#

Thank you โ™ฅ

dull moss
#

to erase array i just = {} ?

fast galleon
modern dune
#

new fun envelope-pushing question: os is apparently also not implemented in kahlua, right? so is there an equivalent that i can get the actual unix timestamp with?

#

or some other way measure "real-world" time?

bronze yoke
#

timestamp is implemented

#

be careful when doing this when bringing tables into the local space

#

when you do that to a table, you erase that specific reference, the table isn't removed unless every reference to it is removed

modern dune
bronze yoke
#

i use that one myself

bronze yoke
#

the opposite is also true, but for moddata what's important is that you do modData.table = nil, not just a local reference to it

dull moss
#

ye got it this way, thx

        player:getModData().ExplorerTrait.CurrentCell.ExploredTiles = {};```
#

Just to clarify one more time, this is the same, right?

#

(and yes i made player local. noticed it after posting LULW )

dull moss
#

I need to use actual getModData, right?

#

so I can't replace

function dumpOldCell(playerCellX, playerCellY)
    local player = getPlayer();
    player:getModData().ExplorerTrait.OldCell = player:getModData().ExplorerTrait.CurrentCell;
    player:getModData().ExplorerTrait.CurrentCell.X = playerCellX;
    player:getModData().ExplorerTrait.CurrentCell.Y = playerCellY;
    player:getModData().ExplorerTrait.CurrentCell.ExploredTiles = nil;
    player:getModData().ExplorerTrait.CurrentCell.ExploredTiles = {};
end```
with
```lua
function dumpOldCell(playerCellX, playerCellY)
    local player = getPlayer();
    local ExplorerTraitData = player:getModData().ExplorerTrait;
    ExplorerTraitData.OldCell = ExplorerTraitData.CurrentCell;
    ExplorerTraitData.CurrentCell.X = playerCellX;
    ExplorerTraitData.CurrentCell.Y = playerCellY;
    ExplorerTraitData.CurrentCell.ExploredTiles = nil;
    ExplorerTraitData.CurrentCell.ExploredTiles = {};
end
#

Or is it fine?

#

looks like its fine so gonna leave it at that

#

ye it looks 10 times better

rustic grove
#

if I wanted to grab like, a refrigerator model for size reference in blender, anyone know where that particular file would be? I see the media folder with other models but like oven, stove etc seem to be evading me atm ^_^

faint jewel
#

they aren't models, they are sprites

rustic grove
#

that explains a lot, thanks ^_^

faint jewel
#

there ya go.

prisma gale
#

am i right in saying you can have multiple 'item' files rather than 1 huge file

fast galleon
#

or 1 file with items, models, etc

#

Just make sure those files use unique names

dull moss
#

track in which cell player is and what was the previous cell
successfully write function that dumps old cell and shifts current cell into slot of old cell in modData when player enters new cell
try to add a function that swaps current cell and old cell around if player enters previous cell
it starts swapping them every time main function is ran

#

My head actually starts to hurt at this point kekwait

sour island
#

What's the function look like

dull moss
#

at this point I should scratch everything and start all cells shenanigans' over

sour island
#

What's the point of this btw?

#

Explorer trait?

dull moss
#

Yes

sour island
#

Is the previous cell relevant?

dull moss
#

Wdym

sour island
#

Why is the previous cell tracked

dull moss
#

oh

sour island
#

And why only two, previous and current

dull moss
#

Cuz I want to track if player explored at least x% of a cell (I grab 20x20 tiles around player every minute) and add them to list of tiles explored in cell. Full cell is 90k so if I make it like 30% I hope it should be fine-ish performance-wise. And I track only 2 to not jam every single visited cell in there.

#

if i hit my 30% explored I mark cell as explored

sour island
#

Ah

dull moss
#

and dont count shit in it anymore

sour island
#

So you can only trigger explored if you stay in the cell for the 30%

dull moss
#

yes, and i wanna save info about prev cell if player is wondering around cell edge

#

and jumps between them

#

ideally i would save last 4

#

in case player is on intersection

#

but idk

#

i think 2 should be fine

#

hm

#

maybe i should switch to 4

#

would make stuff easier

#

probably

#

i dont have to bother with swapping shit around then

sour island
#

I don't see why tracking any number of cells would be that much of an issue tbh

#

Especially if you have a cut off %

dull moss
#

I got no clue how to access them

sour island
#

Are you listing every square?

dull moss
#

Wdym?

sour island
#

How are you tracking how much of a cell is explored?

#

You said add tiles

#

Like isosquares?

#

X,Y of all the squares?

dull moss
#

nah im using cantor pairing function

#

to turn x and y into 1 number

#
local size = 3;
local scoutedAreaMinX = math.max(playerX - size, playerCellX * 300);
local scoutedAreaMinY = math.max(playerY - size, playerCellY * 300);
local scoutedAreaMaxX = math.min(playerX + size, (playerCellX + 1) * 300);
local scoutedAreaMaxY = math.min(playerY + size, (playerCellY + 1) * 300);
print("Allowed area in this cell. From x="..scoutedAreaMinX..", y="..scoutedAreaMinY.." to x="..scoutedAreaMaxX..", y="..scoutedAreaMaxY);
for x = scoutedAreaMinX, scoutedAreaMaxX do
    for y = scoutedAreaMinY, scoutedAreaMaxY do
        local cantor = (x + y) * (x + y + 1) / 2 + x;
        --print ("Got Cantor: "..cantor);
        table.bininsert(ExplorerTraitData.CurrentCell.ExploredTiles, cantor);
    end
end
print("Size of Explored Tiles array: "..#ExplorerTraitData.CurrentCell.ExploredTiles);
#

my reason is that then i can have sorted array

#

and checking if cell is already there would be fast

#

cuz i dont have to check each cell that is scattered

#

in my array

#

I have a list of sorted numbers that I can insert into

#

much faster

#

Allowed area = area in this cell

#

so it doesnt grab tiles from other cells

#

i think it's pretty smart way of approaching this problem

sour island
#

It is

dull moss
#

cuz of fast insert

#

Ok I just need to figure out how to store all cells visited then

#

didnt really do a lot of moddata and tables stuff in lua

#

so that's why initially i wanted just to do 2 cells

sour island
#

Cells have a world x/y afaik

#

You could store them as keys to a table with their explorer info

dull moss
#

how can one create a table with any kind of identifier? Let's say I have modData().Data = {}. Is there any way I can add sub-tables into that table with identifier generated mid-code execution. For example, I want to add a table into it that I can later find by identifier 19823854

bronze yoke
#

keying by x % 300, y % 300 should work

dull moss
#

table with keys? lemme google that

sour island
#

A = {a={}}

#

A.a = {}

#

For concated keys -- A = {[x.."|"..y]} the bar is to clarify between the xy

dull moss
#

so something like this?

local data = getPlayer():getModData().MyMod or {};
local key = --<some math function that creates a unique key>--
data.key = {};
dull moss
#

that shit is so good

finite owl
#

data[key] = {}

dull moss
#

cool, will try

sour island
#

The brackets let you use strings with spaces too

dull moss
#

will know for future

#

I'll use cantor to get unique number so my cell list can be sorted

#

even more speed

#

So something like this?

function ETInitialize()
    local player = getPlayer();
    player:getModData().ExplorerTrait = player:getModData().ExplorerTrait or {};
    local ExplorerTraitData = player:getModData().ExplorerTrait;
    ExplorerTraitData.Cell = ExplorerTraitData.Cell or {};
end

function addNewCellToList(x, y)
    local player = getPlayer();
    local ExplorerTraitData = player:getModData().ExplorerTrait;
    local cantor = (x + y) * (x + y + 1) / 2 + x;
    ExplorerTraitData.Cell[cantor] = {};
    ExplorerTraitData.Cell[cantor].ExploredTiles = {};
    ExplorerTraitData.Cell[cantor].IsExplored = false;
end
bronze yoke
#

strings with full stops too, useful for keying by item types and stuff

finite owl
dull moss
dull moss
finite owl
#

Rather than repeating the Cantor calculation in multiple places, I'd create a function your code uses, something like getKeyForCoordinates(x, y) which does it there, and then use it throughout. DRY and all that.

modern dune
#

this is more of a lua-specific question but does anyone know why this crashes, complaining that "Object tried to call nil in OnZombieDead"?

#
        if next(cartozoidDeadZombies) == nil then
            -- Lua is 1-indexed
            local deadZombieIdx = 1;
#

cartozoidDeadZombies is defined as a global variable in the OnCreatePlayer function as such:

#
cartozoidDeadZombies = {}
bronze yoke
sour island
#

Yeah, keyed tables don't need to be for'd through

sour island
modern dune
#

๐Ÿคทโ€โ™‚๏ธ

sour island
#

Hmm, might be an old Lua thing maybe?

#

Is your table keyed?

#

If there aren't defined keys it defaults to numeric order, and you can use #

finite owl
#

PZ uses Kahlua, which is a Java implementation of Lua which doesn't implement everything. I think it's somewhere around Lua version 5.1?

sour island
#

I think it's 5.3?

#

Lua is up to 5.8(??)

modern dune
#

although i guess maybe i dont need to

bronze yoke
#

why not just table.insert?

modern dune
#

i thought you had to explicitly define the key in lua

#

can i just say like "myTable.insert("foo")" and it becomes {1: "foo"}?

thick karma
# sour island I think it's 5.3?

I don't know the answer, but I learned the disappointing way that Lua added goto in 5.2 and we do NOT have that basic feature, so I would suspect our Kahlua is <5.2

sour island
#

If no keys are provided it's numeric

modern dune
#

hmm maybe i dont need to be so pedantic about the keys then

#

if i say this: cartozoidDeadZombies = {zombie}

bronze yoke
#

no keys means numeric

modern dune
#

does this mean that it will now be a table with a single element mapping 1 -> zombie?

thick karma
#

If you get nil that was the issue

finite owl
#

I think it's an associative array either way; you can either use explicit keys, or use implicit incrementing integer keys.

sour island
#

You can leave the list[n]=zombie

#

From what I read insert is stupidly costly

#

But then you'd have to be more mindful when you're adding values

thick karma
#

Yep, gotta implement that if you want it. ๐Ÿ˜ญ Imagine how I feel using i.e. breaking repeat until true instead of goto.

#

Don't think I can implement goto very easily haha.

#

Only sadness awaits me

modern dune
#

this is my first time using lua in any amount of depth

#

ive dicked around with it for very minor stuff at work but nothing substantial

dull moss
#

same bro

thick karma
#

That would be more code right?

#

repeat until true happens once with no further input... A while would need a control variable and usually another line for editing it, plus the word end in Lua I assume

sour island
#

Not sure I try to stay away from while lol

thick karma
#

while(control) ... control = false end vs. repeat until true

#

I believe those would have the same result

#

But yeah Fenris_Wolf taught me that trick... You can break one iteration of a for loop if you go
for ... do repeat ... possible break ... until true end

#

The break breaks the repeat instead of the for loop so you can skip code made for certain players in a player loop with less nesting

#

Using stuff like if shitty(player) then break end

#

If I wrote the defecation mod, that would be a function.

dull moss
#
function ETInitialize()
    local player = getPlayer();
    player:getModData().ExplorerTrait = player:getModData().ExplorerTrait or {};
    local ExplorerTraitData = player:getModData().ExplorerTrait;
    ExplorerTraitData.Cell = ExplorerTraitData.Cell or {};
end

function addNewCellToList(cellKey)
    local player = getPlayer();
    player:getModData().ExplorerTrait = player:getModData().ExplorerTrait or {};
    local ExplorerTraitData = player:getModData().ExplorerTrait;
    ExplorerTraitData.Cell[cellKey] = {};
    ExplorerTraitData.Cell[cellKey].ExploredTiles = {};
    ExplorerTraitData.Cell[cellKey].IsExplored = false;
    print("Successfully added cell with key "..cellKey);
    print("Current total cell count: "..#ExplorerTraitData.Cell);
end

why it doesn't show proper cell count?

LOG  : General     , 1671404799934> Successfully added cell with key 2246
LOG  : General     , 1671404799934> Current total cell count: 0
thick karma
#

What index cellKey did you test?

#

@dull moss

dull moss
#

wdym?

thick karma
#

Did you just add one value to test?

dull moss
#

ah

thick karma
#

To index 0? Or what

dull moss
#

it's every minute. there should be at least 1 cell.

function ETInitialize()
    local player = getPlayer();
    player:getModData().ExplorerTrait = player:getModData().ExplorerTrait or {};
    local ExplorerTraitData = player:getModData().ExplorerTrait;
    ExplorerTraitData.Cell = ExplorerTraitData.Cell or {};
end

function addNewCellToList(cellKey)
    local player = getPlayer();
    player:getModData().ExplorerTrait = player:getModData().ExplorerTrait or {};
    local ExplorerTraitData = player:getModData().ExplorerTrait;
    ExplorerTraitData.Cell[cellKey] = {};
    ExplorerTraitData.Cell[cellKey].ExploredTiles = {};
    ExplorerTraitData.Cell[cellKey].IsExplored = false;
    print("Successfully added cell with key "..cellKey);
    print("Current total cell count: "..#ExplorerTraitData.Cell);
end

function ETLocationUpdate()
    local player = getPlayer();
    local playerX = math.floor(player:getX());
    local playerY = math.floor(player:getY());
    local ExplorerTraitData = player:getModData().ExplorerTrait;

    local size = 1;
    local scoutedAreaMinX = playerX - size;
    local scoutedAreaMinY = playerY - size;
    local scoutedAreaMaxX = playerX + size;
    local scoutedAreaMaxY = playerY + size;
    for x = scoutedAreaMinX, scoutedAreaMaxX do
        for y = scoutedAreaMinY, scoutedAreaMaxY do
            local cellX = math.floor(x / 300);
            local cellY = math.floor(y / 300);
            local cellKey = cantorKeyGenerator(cellX, cellY);
            if ExplorerTraitData.Cell[cellKey] == nil then
                addNewCellToList(cellKey);
            end
            local tileKey = cantorKeyGenerator(x, y);
            print ("Got tileKey: "..tileKey);
            table.bininsert(ExplorerTraitData.Cell[cellKey].ExploredTiles, cellKey);
        end
    end
end

Events.OnGameStart.Add(ETInitialize);
Events.EveryOneMinute.Add(ETLocationUpdate);
#

in my test it should've been 2

#

cuz 1 you start in

#

and then i wondered into a new one

sour island
#

What's add cell to list?

dull moss
#

if statement

#

inside double for loop

#

if cell with this key doesnt exist i add it

thick karma
dull moss
#

oh u mean code

#

yea slightly above

#

was able to squees in last msg

sour island
#

You can't # a non numeric keyed table

#

One of the caveats

dull moss
#

non-numeric meaning?

sour island
#

You can set up a sister table with numeric keys to cellkeys for values of order matters - but it shouldnt

sour island
dull moss
#

but it is numeric

#

key is a number

sour island
#

Has to be in order starting with 1 afaik

dull moss
#

ah

sour island
#

You don't need to iterate through the cells

#

It's faster if you just tug on the list with the key

#

Set the key if nothing returns

#

If order does matter you have to set another table

dull moss
#

I actually wanted to have my Cell table sorted

#

idk if its possible

sour island
#

I don't think sorting would provide any value in this case?

#

But if you need it you have to use another list as a reference

dull moss
#

well worlds is 50x50 cells

#

so i guess if its unsorted it wouldnt matter much

#

wait it doesnt matter at all

#

cuz im inserting value via the key

sour island
#

Yes

#

The list can be massive, and it shouldn't matter if you're not iterating

dull moss
#

yea

#

also it's gonna be like 100 cells max anyway

#

by that point character has to earn trait 100%

thick karma
#

I will take a closer look in a little bit but hard on my phone. Generally make sure your tables are actually indexing from 1 onward for # to work properly... I sometimes think I've done this right but accidentally revert to every other language's mindset... In Lua, I like adding to existing table of stuff like this:

stuff = {}
stuff[#stuff + 1] = nextStuff```
dull moss
#

hm, ok, how do i then check if my data is in order PepeThink

thick karma
#

This ensures that a new table begins indexing at 1 in a repeatable pattern

dull moss
#

i know i'll do everytenminute event that will dump all cells and tiles in for loop in console KekW

modern dune
#

indeed i was overcomplicating my code a lot

#

because i was actively refusing to bother to learn how tables work in lua

sour island
#

List1 = {a,b,c,d}
List2 = {a=apple, b=banana, c=carrot, d=durian}

dull moss
#

is there any actual way of checking moddata?

#

besides print

sour island
#

You venndiagram the tables to so speak, and use one for order and the other for values

modern dune
thick karma
#

๐Ÿ˜‚

sour island
#

List2 if for'd won't produce the same order everytime

#

Fun fact

modern dune
#

so its like a python list and a dictionary at the same time

#

somebody looked at python and thought "you know what would make this better? MORE AMBIGUITY"

thick karma
#

Or they're accessing it using pairs, which apparently doesn't guarantee order

sour island
#

Yes pairs doesn't get order and ipairs loses keys

#

But I don't think it maintains order either

thick karma
#

Oof

dull moss
#

is there a way to iterate through list of my cells stored in modddata? ones with keys?

#

ExplorerTraitData.Cell[cellKey] this stuff

#

I wanna go through all cells

#

that are there

sour island
#

For I=0 in pairs(list) do

dull moss
#

cheers

sour island
#

You can add to a counter in each iteration - but the order isn't guaranteed

thick karma
#

for index in pairs(list) do ... end should be fine right? @sour island

dull moss
thick karma
#

Idtyn i = 0

#

For that kind of loop

dull moss
#

how can I grab cell key?

thick karma
#

If it starts at 1 at least

#

Index = key

sour island
thick karma
#

For value, for key, value in pairs(list)

sour island
#

Also I think I mistyped, I don't think you can do i=0 and pairs lol

thick karma
#

Haha I didn't know

sour island
#

K,V in pairs() is right

dull moss
#

so something like this?

function ETDataDump()
    local player = getPlayer();
    player:getModData().ExplorerTrait = player:getModData().ExplorerTrait or {};
    local ExplorerTraitData = player:getModData().ExplorerTrait;
    for value, key in pairs(ExplorerTraitData.Cell) do
        print("Cell #"..key);
        print(" has "..#ExplorerTraitData.Cell[key].ExploredTiles.." explored tiles");
    end
end
thick karma
#

I hadn't seen it like that

#

For k in pairs will work though

#

I've used it

#

,v optional

sour island
#

Is it? Hmm

#

I usually do _,V or K,_

thick karma
#

I'm almost positive but feel free to run a quick debug console test and check

#

When indexing from 1

#

I saw it in someone else's code before I adopted it

#

And immediately preferred

sour island
thick karma
#

Because for me , _ makes me vomit

sour island
#

I do it to get rid of IDE warnings

#

And I try not to use single letter vars

buoyant crane
#

hello i was wondering if anyone could help me figure out how to run a dedicated server with mods or let me know if its something that is possible for pz friends and i cant seem to wrap our head around the cmd part of it due to lack of guides just looking for a point in the right direction. Also is this the right subchat for this question?

dull moss
#

print("Cell #"..key)

thick karma
#

I doubt it covers every conceivable nuance of opening and forwarding your ports correctly, so that step will inherently take some personal troubleshooting based on your network setup

#

I connected to my own server using localhost (127.etc.)

#

Wouldn't work for online so at that step good luck haha

dull moss
buoyant crane
#

ok ill go through this guide thoroughly if i have any follow up question that do you mind me @ you and seeing if its something you can still help with? if its not a hassle lol

thick karma
# dull moss <:sadge:780599777342783508>

This works in lua online console in my phone... i would compare with yours for which major difference is failing you.

stuff = {}

stuff[1] = "Hello"
stuff[2] = "World"

for key in pairs(stuff) do

   print(key)

end
#

Ohhh wait I see @dull moss

#

You wrote value, key

#

It's key, value

dull moss
#

I jsut copied what i was told

thick karma
#

Reordering that will not change the order in which you receive variables

dull moss
#

I'll test

thick karma
#

P sure Chuck and I said key, value lol

#

Don't know who told you value, key

#

But order is crucial there

thick karma
#

Note that will only work if ExplorerTraitData.Cell is a table, and only so stuff if it's nonempty. If it's nil, pairs may throw an exception. Pretty sure it will

thick karma
dull moss
#

yea its just to test if it puts data in and stuff

#

for value for key

#

i thought it means first is value

thick karma
#

But I see the confusion... i began by saying "For value," to indicate the format used if you WANT the value.

dull moss
#

ah

thick karma
#

But my capitalization was a strong hint

#

๐Ÿ˜†

dull moss
#

yes but you miss the fact that im a pepega

thick karma
#

I admit that was not the clearest I could have said that
... However if you HAD copy-pasted what I said, a very different error would have occurred

#

Haha

#

Just saying

#

Nw though glad you have it now

dull moss
#

very cool

LOG  : General     , 1671407781934> Successfully added cell with key 2381
LOG  : General     , 1671407781934> Successfully added cell with key 2451
LOG  : General     , 1671407784417> Successfully added cell with key 2382
LOG  : General     , 1671407789401> Cell #2314 has 1 explored tiles
LOG  : General     , 1671407789402> Cell #2246 has 263 explored tiles
LOG  : General     , 1671407789402> Cell #2313 has 119 explored tiles
LOG  : General     , 1671407789402> Cell #2381 has 6 explored tiles
LOG  : General     , 1671407789402> Cell #2451 has 3 explored tiles
LOG  : General     , 1671407789403> Cell #2382 has 9 explored tiles```
sour island
#

๐Ÿ‘

dull moss
#

now setting explore range to something real, like 10 (instead of 1 like it was before)
Kpog this is looking nice

LOG  : General     , 1671407886885> Cell #2246 has 263 explored tiles
LOG  : General     , 1671407886885> Cell #2313 has 509 explored tiles
LOG  : General     , 1671407886886> Cell #2381 has 1064 explored tiles
LOG  : General     , 1671407886886> Cell #2451 has 255 explored tiles
LOG  : General     , 1671407886886> Cell #2382 has 278 explored tiles```
thick karma
#

Ayyy look at that

#

Vn vn

dull moss
#

I'm still not sure how performance-hungry this is, any recommendations on how to test it?

thick karma
#

Many people here seem to use os.clock()

astral dune
#

the long number preceding the print is a timestamp afaik

thick karma
#

Interesting, seems entirely possible it's in seconds.

astral dune
#

this is where I saw it mentioned, but blair didn't say what unit it's in. Could conceivably by ms, I have no idea how slow the print function is

#

apologies for pinging you blair, I forgot to hit the button

dull moss
#

nClock = os.clock(); throws error sadge

#

so I'm trying to add cells that explored with currently grabbed cells into an array

#
local size = 10;
    local scoutedAreaMinX = playerX - size;
    local scoutedAreaMinY = playerY - size;
    local scoutedAreaMaxX = playerX + size;
    local scoutedAreaMaxY = playerY + size;
    local lastUsedCellKeys = {};
    for x = scoutedAreaMinX, scoutedAreaMaxX do
        for y = scoutedAreaMinY, scoutedAreaMaxY do
            local cellX = math.floor(x / 300);
            local cellY = math.floor(y / 300);
            local cellKey = cantorKeyGenerator(cellX, cellY);
            table.bininsert(lastUsedCellKeys, cellKey)
            if ExplorerTraitData.Cell[cellKey] == nil then
                addNewCellToList(cellKey);
            end
            local tileKey = cantorKeyGenerator(x, y);
            table.bininsert(ExplorerTraitData.Cell[cellKey].ExploredTiles, tileKey);
        end
    end
    for i in lastUsedCellKeys do
        if #ExplorerTraitData.Cell[lastUsedCellKeys[i]].ExploredTiles >= 10000 then
            ExplorerTraitData.Cell[lastUsedCellKeys[i]].IsExplored = true;
            HaloTextHelper.addTextWithArrow(player, "Cell explored", true, HaloTextHelper.getColorGreen());
        end
    end```
#

but

#

I obviously fail

#

did I use last for loop correctly?

#

oh I need to use i,v

#

and then use v instead of i

#

I think

astral dune
#

you need to use pairs ipairs or your own iterator to run that for loop

#

also, table.bininsert doesn't exist

dull moss
#

it is, it's my own function

#

ok, fixed

#

ty for pairs help

#
for i, v in pairs(lastUsedCellKeys) do
    if #ExplorerTraitData.Cell[lastUsedCellKeys[i]].ExploredTiles >= 10000 then
        ExplorerTraitData.Cell[lastUsedCellKeys[i]].IsExplored = true;
        HaloTextHelper.addTextWithArrow(player, "Cell #"..lastUsedCellKeys[i].." explored", true, HaloTextHelper.getColorGreen());
    end
end
astral dune
#

np

dull moss
#

If I have following line in function, local lastUsedCellKeys = {};, every time function is called it's gonna make fresh empty array, right? I don't need to manually empty it, ye?

astral dune
#

yes

dull moss
#

cheers

vast nacelle
#

How are item distribution chances calculated?
I had thought it was [ItemChance]/[Summation of the chances of all items in the list] = [% Chance per item roll]
But that really doesn't seem to be the case.
I added an item to the GunStoreDisplayCase list which has a summation of 178 before anything is added by mods.
So I set my item to 31 which should give it around a ~15% chance per roll if it worked like I thought it did.
With 4 rolls, I'd expect LootZed to show at most 40%.
Yet my item had a 99.9% chance in LootZed.

sour island
#

Each chance is roughly out of 100

#

There's alot of math but it kind of comes out to /100

#

Each roll is just multiple runs of the same %

#

It's not a weighted list if that's what you were wondering

vast nacelle
#

Alright.
So can a list roll "nothing" then? Like if say everything was set to 0.001? Or does some item have to win the roll?

sour island
#

It's all independent afaik

dull moss
#

also there's lower limit on %

faint jewel
#

fun goofy question time!

sour island
#

Yeah, I recall that -- the less loot mods actually trim off rolls

faint jewel
#

it is possible to change the players model at run time?

#

so i could change them from a player model to a zombie model to a custom model etc?

sour island
#

You can give an hidden item to be worn

#

I think that's how peach does his unique models

faint jewel
#

well i want it to be on the players themselves.

#

i want to make variants of the men and women models to be fat for instance. and just edit the bone structure to do so.

dull moss
#

^

#

on the boundry

#

@vast nacelle

vast nacelle
#

Thanks, Chuck and MusicManiac.

sour island
#

His fat zombies are special costumes with clothes

faint jewel
#

i think outside the box lol... i'll figure something out lol.

sour island
#

It would be a lot of work I imagine for devs to implement

#

I'm not familiar with bone rigging and stuff

faint jewel
#

nah i have an idea of how to accomplish it. lol

#

it's easy lol

sour island
#

With being able to wear any clothes?

faint jewel
#

yeah, if i edit the skeletons on the base model, it will use the normal animations and will scale the clothes to match the new body

sour island
#

Hmm

#

But then you're stuck with those as the base model?

faint jewel
#

that's why i wanna know if it's possible to change them dynamically

#

so if you get to a certain weight it changes them to a new base model.

sour island
#

I'm still waiting for dynamically applied model for items

barren fox
#

Anyone know the name of the item that can be wear like a fanny pack but has a capacity of 4. I donโ€™t know the mod from which that item comes from.

drifting ore
opal rivet
#

Are they like Done?

#

Like tired from zombeing?

sour island
#

They're unionizing

drifting ore
opal rivet
#

I see poor them

ruby urchin
#

LoadGridsquare event get crash?

dapper geode
#

Hi, just wanna ask about where I can find vanilla loot/item respawn script?

ancient grail
thick karma
#

The scripts defining individual items are in a few places, but that's how they spawn

#

anything in media/scripts with items in the name probably has some item definitions afaik.

thick karma
#

Anyone know the function for toggling model visibility? Can it even be done in Lua?

#

I believe the option's default key is F3 and called Toggle Models Enabled if that helps.

#

Okay I think it's done via ModelManager.instance.bDebugEnableModels = !ModelManager.instance.bDebugEnableModels; ... wonder if this is exposed.

#

Mmmm seems not but maybe I'm reading it wrong... will check in game to be sure.

#

Booo, nil.

thick karma
#

When you Faction.getPlayerFaction(player) on two players with the same faction, will factionA == factionB, or do I need to get their names or something to make the equivalence work?

ruby urchin
#

SNIPPET: load Lua file and get _ENV

---Load a lua file.
---@param p1 string
---@param p2 string
self.loadLuaFile = function (p1, p2)
    local file = getModFileReader(p1, p2, false)

    if file then
        local script, err = loadstream(file, "@".. p1 .."/".. p2);
        local _ENV = {};

        if not script then
            print(err);

            return;
        end

        for k, v in pairs(_G) do
            _ENV[k] = v;
        end

        setfenv(script, _ENV);
        script();

        return _ENV;
    end
end
--config.lua
Config = {};
Config.MAX = 10;
---example.lua
local Config = Utils.loadLuaFile('Dogs', 'media/lua/config.lua')['Config'];
print(Config.MAX);
dapper geode
bronze yoke
#

if you want to add moddata to all of an item, add it as a parameter on the item

#

if it's a custom item just add it to the script, else

local item = ScriptManager.instance:getItem('Module.ItemName')
if item then
    item:DoParam('ModDataName = value')
end
```which makes that item default with getModData().ModDataName = value
faint jewel
#

i need a script that i can run once that will place a bunch of tiles in specific places and SAVE THE DAMNED THINGS. so they dont keep getting deleted.

bronze yoke
#

add your objects on loadgridsquare

faint jewel
#
function checkTileSpawns(sq)
    local x, y, z = sq:getX(), sq:getY(), sq:getZ();
    if #JobBoardTileSpawns.toSpawn > 0 then
      for i = #JobBoardTileSpawns.toSpawn, 1, - 1 do
        local tileSpawn = JobBoardTileSpawns.toSpawn[i];
        if x == tileSpawn.x and y == tileSpawn.y and z == tileSpawn.z then
          local sname = tileSpawn.Tile
          local object = IsoObject.new(sq,sname)        
          sq:AddTileObject(object);        
          object:getSprite():setName(sname);
          tileSpawn.spawned = true;
          local signData = object:getModData();
          signData.loc = tileSpawn.loc;
          --object:getModData() = signData;
          object:transmitCompleteItemToServer()
          object:transmitModData()
          --table.remove(JobBoardTileSpawns.toSpawn, i);
        end
      end
    else
      Events.LoadGridsquare.Remove(checkTileSpawns);
    end
end```
thick karma
dapper geode
dapper geode
bronze yoke
#

i can't quite recall, but i think it was previously spawned items, so long as ModDataName hasn't been set already

smoky meadow
#

guys how to spawn a magazine with all it's bullet's inside

pearl pasture
#

Would it be possible to make a mod for zombies to spawn without limbs

thick karma
#

Anyone know the cleanest way off the top to expand this for multiple sound variations, given jump1-8.ogg in the appropriate folder?

module Jumper {
    imports {
        Base
    }
    sound Rifting
    {
        category = Player,
        clip
        {
            file = media/sound/jump.ogg,
        }
    }  
}
#

Do I really just need to make 8 separate sounds?

#

Guessing maybe so... ew...

faint jewel
#

is tyhere a way to make something run when you open a ui?

thick karma
#

You could make an ISPanelJoypad UI with an :open function @faint jewel

#

And do anything you want when you open it

fast galleon
thick karma
#

Key to proper open is to setVisible(true) and addToUIManager while you're in there, then

#

Point of that is that UI toggles will not find your UI in the active UIs and thus turn them on at inappropriate times if your UI is not in the UI manager when it's closed.

thick karma
#

I couldn't find an example in vanilla

#

or is it

file = {
  ...,
  ...,
  ...
}
fast galleon
#
    sound MaleZombieCombined
    {
        category = Zombie,
        clip
        {
            event = Zombie/Voice/MaleA,
        }
        clip
        {
            event = Zombie/Voice/MaleB,
        }
        clip
        {
            event = Zombie/Voice/MaleC,
        }
    }
thick karma
#

Ahhh

#

And it randomly chooses a clip or what?

#

Automatically based on any number of clips?

fast galleon
#

I imagine so

thick karma
#

Well I'll give it a shot, seems interesting.

#

@fast galleon Nailed it

#

Ty

#

Code looks a lot neater this way lmao

agile vigil
#

Look at that fancy colour coding based on how strong this bait is!

ancient grail
#

possible to mod a rotating png images ?

#

i cant think of any vanilla thing that rotates an image

viral karma
finite owl
#

How visible to the Lua side of things are meta events? I'm wondering with RV Interior if we could do some sort of slight-of-hand to mitigate the fact that the player inside a vehicle interior is way outside of the map. Like, if we detected that a meta event has occurred targeting a player that's inside, manually trigger the same event in the outside world (if in MP and that part of the world is loaded) or generally stir up the zombies outside the vehicle when the player inside next exits/that part of the world is loaded up again.

faint jewel
#

WEEEEEEEEEEEEEEEE

ancient grail
#

i guess not

#

gj

faint jewel
#

i did!

ancient grail
#

how did u do it

faint jewel
#

i screamed a lot.

ancient grail
#

did u use math.atan2()?

faint jewel
#
function DistanceToTarget(x,y) 
    local player = getPlayer()
    local distancetoplayer = IsoUtils.DistanceTo(player:getX(),player:getY(),x,y);
    return math.floor(distancetoplayer);
end

function AngleToTarget(x,y) 
    local player = getPlayer()
    local AngleFromPlayer = setAngleFromPoint(x,y)
    return math.floor(AngleFromPlayer);
end

function setAngleFromPoint(x,y)
    local player = getPlayer()
    if(x and y) then
        local radians = math.atan2(y - player:getY(), x - player:getX()) + math.pi
        local degrees = ((radians * 180 / math.pi + 270) + 45) % 360 -- add 45 deg because of the isometric view? or idk for some reason i need to
    
      return degrees;
    end 
end
drifting stump