#mod_development

1 messages · Page 129 of 1

faint jewel
#

USING THE HOST OPTION.

ancient grail
#

Its around
-23 to + 23

faint jewel
#

so yes i will set ALL user to be east coast timezone got it.

wheat kraken
#

@faint jewel try this
local current_time = os.time()
print(os.date("%c", current_time))

i test here and its works for me

ancient grail
#

Pretty much yeah haha

#

Or maybe theres a getCore() for that

wheat kraken
#

let me know if it works

ancient grail
#

You could probably ask rj to add the users timezone to the pc mod and just fetch it from there.
But thats going to be an exclusive krp mod tho

wheat kraken
#

if i paste it on debug lua console command line, works as same if it is on code right? @ancient grail
print(os.date("%c", os.time()))

wheat kraken
# wheat kraken <@201100405390835713> try this local current_time = os.time() print(os.date("%c"...

current time from user, considering timezone, and converting to am pm, instead 24h

editted:
new version, am pm string doesnt appears on pz, so you need to add it inside the if else
the easiest way is to use the local time with 24h format (stored in current_time )

function convert_c_to_12(time_string)
  local hour = tonumber(time_string:sub(12,13))
  local minute = tonumber(time_string:sub(15,16))
  local second = tonumber(time_string:sub(18,19))
  local am_pm = time_string:sub(21,22)
  
  if hour == 0 then
    hour = 12
  elseif hour > 12 then
    hour = hour - 12
  end
  
  return string.format("%d:%02d:%02d %s", hour, minute, second, am_pm)
end


local current_time = os.date("%c", os.time())
local converted_time_string = convert_c_to_12(current_time)
faint jewel
#

that STILL does not do the local time.

#

it does it +5 for me.

red tiger
#

It's UTC.

#

That's why.

faint jewel
#

and i need local.

red tiger
#

So there's no API to get local?

faint jewel
#

you can use %c

#

but you cannot format it in any way

red tiger
#

You can. String manipulation.

#

Sucks but is an option.

faint jewel
#

well of course. but the hell would i want THAT for?

#

that's what %c spits out.

#

i wish PZ used %Ec

bronze yoke
#

so use string manipulation to get the numbers out of that?

faint jewel
#

that makes it format it in the local time format

#

if %z worked i could just add or remove that as needed.

#

but of course not. they used the most minimal time formatting they could.

wheat kraken
#

print(os.date("%c", os.time()))

#

and its true the function convert_24_to_12, doesnt work

#

@faint jewel finally an working version

#

here grab it!

#
function convert_c_to_12(time_string)
  local hour = tonumber(time_string:sub(12,13))
  local minute = tonumber(time_string:sub(15,16))
  local second = tonumber(time_string:sub(18,19))
  local am_pm = time_string:sub(21,22)
  
  if hour == 0 then
    hour = 12
  elseif hour > 12 then
    hour = hour - 12
  end
  
  return string.format("%d:%02d:%02d %s", hour, minute, second, am_pm)
end


local current_time = os.date("%c", os.time())
local converted_time_string = convert_c_to_12(current_time)

#

maybe the pm string are missing because i use 24h on my os

small topaz
#

Max number of players for a multiplayer game is 100?

wheat kraken
#

how to do setVariable work to free animation on half lower of player?
like doing legs do walk animation?

setVariable(IAnimationVariableSlot var)
Set the specified animation variable slot.

plucky dirge
#

How can I know if there's a character near a certain tile? I'm using this so that if there's a character near a tile where a player right clicked, there would be an option added to the menu.

wheat kraken
#

i know that superb survivor have closest players, here the snippet:

function getClosestPlayers(player)

    local range = 15;
    local Square, closestsoFarSquare;
    local minx=math.floor(player:getX() - range);
    local maxx=math.floor(player:getX() + range);
    local miny=math.floor(player:getY() - range);
    local maxy=math.floor(player:getY() + range);
    local closestsoFar = range;
    
    local closestPlayers = {}
    
    for x=minx, maxx do
        for y=miny, maxy do
            Square = getCell():getGridSquare(x,y,player:getZ())
            if(Square ~= nil) then
                local distance = getDistanceBetween(Square,player)
                local closeobjects = Square:getMovingObjects()
                for i=0, closeobjects:size()-1 do
                    local obj = closeobjects:get(i)
                    if (obj ~= nil) then 
                        --and (self.parent.player:CanSee(obj))
                        if (instanceof(obj,"IsoPlayer") and not obj:isLocalPlayer() and (obj:isDead() == false) and (obj:getModData().isHostile ~= true) and (distance < closestsoFar) ) then
                            table.insert(closestPlayers, obj)
                        end
                    end
                end
            end
        end
    end
    
    return closestPlayers
    
end
wheat kraken
#

just change player arg to square

plucky dirge
#

Thank you!

wheat kraken
#

and need this too

#
Firetrail.getDistanceBetween = function(x1, y1, x2, y2)
    local dx = x1 - x2;
    local dy = y1 - y2;

    return math.sqrt( (dx*dx) + (dy*dy) ); --math.pow is slower 3.4x than x*x Вишня
end
fast galleon
#

kahlua gave up trying to fix locale

small topaz
#

can the command
Events.OnReceiveGlobalModData.Add(function)
also be used on server side to fetch data which are send from client via the ModData.transmit command (the latter called on client side)?

cunning canyon
#

Any way to add a property to specific sprites? Kinda like DoParam does for items? Currently mucking about with OnLoadedTileDefinitions and the SpriteManager

fast galleon
#

like the infamous light switches mod?

cunning canyon
#

ha not familiar, I'm just trying to add some air filters lol

fast galleon
#

maybe he knows more now

cunning canyon
#

I tried that earlier but wasn't seeing my properties appear in the chunk debugger

fast galleon
#

which property do you want to change?

cunning canyon
#

I want to add a new one, which I'm guessing is the problem

fast galleon
#

new as not used by vanilla?

cunning canyon
#

yes

#

I'm open to a better way of doing it, but I didn't see a way to export custom properties with the tilezed packer

fast galleon
#

Would you mind sharing your test code?

#

It shouldn't be very hard to do, you just need to add a new value to tilezed script

#

%user%/.TileZed/TileProperties.txt

cunning canyon
#

ok hell yeah, thanks for pointing me there!

fast galleon
#

TileZed/docs/TileProperties/index.html guide

cunning canyon
#

for the record this was my test code:

function SWAB_SpriteUtility.OnLoadedTileDefinitions(_spriteManager)
    _spriteManager:getSprite("swab_filters_01_0"):getProperties():Set("MyTestVal","theval",false)
end
Events.OnLoadedTileDefinitions.Add(SWAB_SpriteUtility.OnLoadedTileDefinitions)
fast galleon
#

you didn't make a new array with your value like in that snippet

cunning canyon
#

oh shoot

#

whoops

#

let me try that, it would be nice to not have to compile these values into the pack

small topaz
#

Another question about the manipulation of global ModData (i.e. the data you get by ModData.get("key")): Is it safe to manipulate them on server side and then sending the manipulated data to clients? (client should only read the data, not write)

open drum
#

good morning from Korea to fellow developers

#

🙂

#

yea... i never really figured out how ModData works... anyone knows where I can read more about it?

#

seems like many mods store their data inside it so I would like to figure it out how it works..

#

whether it stores the data permanently or is it tempral data like local variables etc

sour quest
#

Slowly getting my feet wet with Lua as I've worked with other languages except this one. This is a very noob question, but how can I get a key press / key hold in PZ?

#

I've been looking at the PZ Wiki quite a bit. So, that's been a helpful link.

#

Not exactly related to my previous question, but is it possible to test my mod while the game is still running? As in, I make a change, go back to the menu, and load my game again - will I see those changes?

worldly olive
#

Yeap because everytime the game loads the lua is reloaded

sour quest
#

Thanks! In the mean time, I'll familiarize myself more with Lua and work on the key presses.

proper linden
#

Hi there, is anyone know good mods for Foraging?

red tiger
#

I feel like my visual standards are way too high.. I feel like PlantUML isn't good enough for generating UML.

#

__>

#

Someone needs to write a UML generator using HTML & Bootstrap.

bronze yoke
clever spruce
#

What exactly is a 'loadgridsquare' function?

open drum
#

i guess it updates a chunk just by looking at the function name

bronze yoke
#

it's an event called every time a square is loaded

clever spruce
#

thank you. 🙂

small topaz
#

Thanks for the answer. I just play-tested a bit and it really seems to work (at least via host button)

bronze yoke
#

it's just that if you want it to be read from the server all the time, it makes more sense to me to just keep it as a regular table on the client - moddata is for persistence, which doesn't seem helpful here

#

it should still be moddata on the server but on the client it can just be a table

small topaz
#

For example, I start with the number 1 in the global ModData which can be read from every client. Then, after some game time, the server will replace that number by a random number. The new number should then also be read-only accessible by the clients. (This is roughly what I am doing.)

bronze yoke
#

it makes more sense to send the current number to players when they join and when it changes, and have the client store it as a variable, not moddata

small topaz
#

ah ok. This might work too (at least when in multiplayer). I currently store the current number in the client's mod data (i.e. player:getModData() ) and then update whenever the server changes something. This works in multiplayer and single player and makes the data save-game persistent in both cases.

bronze yoke
#

yeah, one downside to this approach is it needs code alterations for singleplayer

sour quest
#

What version of Lua does Project Zomboid use? I feel like knowing this will further help me accomplish what I want to do in the modding scene.

bronze yoke
#

5.1

sour quest
#

Thanks!

frank lintel
#

technically Kahlua2 :)

#

if you look in the top folder of your game you'll see all the libraries there

sour quest
#

The one titled astar?

frank lintel
#

look at the jar's in the top folder

#

org/luaj/kahluafork sorry but yeha its lua but not in C, its lua reversed engineered written in java hard to explain 1 sec there a link that gives a good explaination

sour quest
#

Interesting. I was a bit confused because I couldn't see any jars in common/ProjectZomboid... Closest things I could find for that were javax, jre, jre64, etc. All starting with j.

frank lintel
#

yeah threw me off at first too even more so Im like why didnt they just stick with <bla>

sour quest
#

That is really interesting. Maybe there's good reasoning behind it. Or, maybe they just found what was best for them and stuck with it. Who knows.

frank lintel
#

sandboxing is my guess and not having to write a whole API just for the modding? kinda avoid the mess that MC went thru? I dunno

sour quest
#

It seems to make sense in the modding regard.

#

Thank you for the link, by the way. There's a lot of goodies in there. Hopefully, the other sections get finished at some point.

frank lintel
#

yeah that indexing section is a very helpful part I was always wondering why my IDE was crying over something 0 index'd

sour quest
#

Speaking of IDEs, I already have Visual Studio on my PC. Is that decent enough for the Lua or should I use something else?

frank lintel
#

well Im a netbeans user myself but for this Im using IntelliJ

sour quest
frank lintel
#

yep apparently.

sour quest
#

I'll make a note of that. 🙂

frank lintel
#

that page explains it but yeah C/Java index 0, Lua index 1 so gotta know where its coming from

red tiger
#

VSCode babbyyyy

frank lintel
#

I didnt even try to look how well supported lua is for that.

#

Jab got any clue where sound trigger stuff is done at?

frank lintel
#

like the jumpscare when a Z catches ya offguard

red tiger
#

I think that's hardcoded?

#

Check sounds_zombies.txt

#

Maybe there?

frank lintel
#

yeah Im looking for the actual code that would call/trigger it not worried if its HC'd

red tiger
#

Oh that? yeah IIRC hardcoded to call the event name.

sour quest
#

Since I'm very new to PZ modding... Some of the things I'm currently looking into are button presses and drawing text. The reason I asked about what Lua version PZ uses is because it looks like there's a few ways to draw text in Lua. But, it'd make sense for PZ to have its own functions for drawing the text. Currently looking at media/luaexamples/ui.lua on how to do that.

frank lintel
#

yeah trying to hunt down it so maybe do some naughty since apparently surivors trigger it and the player gets slapped with teh jumpscare no reason

red tiger
red tiger
sour quest
#

Is there a way to find PZ's main-loop? As in, how do I know when / if my Lua script runs in the game?

frank lintel
#

heh...

#

1 sec

#

! (exclamation), - (minus), 0 thru 9, _ (underscore), a thru z, ~ (tilde)

sour quest
#

Just a fair warning, even though I've coded quite a bit before, I'm going to have some very stupid questions when it comes to regarding Lua for PZ.

bronze yoke
#

i'd just throw in a print

frank lintel
#

everything loaded in an order basically (thats not even all of them)

#

my first mod was literally 'LoadingOrderAcidtest' I still have a few characters that are valid I need to check

#

but so far thats the sorting order I still gotta test capital A-Z also, trying to find documentation for what characters are valid for lua filenames is basically non-existent

#

if you running in debug your .log file will tell you when its loading them but shared folder first, client second, server last.

#

heh jab found out that upper or lower dont matter A.lua and a.lua seen as same file (atleast in my IDE)

#

okay added in the few other characters that seem to be valid (seems like it does follow DOS6 file name rules. as I said upper and lower case same letter are seen the same file (at least in creating one in the ide dunno if windows allows this...)
so updated load order ! # $ % & ' ( ) - 0 thru 9 @ ^ _ backquote A thru Z { } ~

frank lintel
#

just verified also that Z still is behind an "a" so upper or lowercase irrelative.

red tiger
#

No random reference BS when loading.

#

Any code generated from PipeWrench is safe from this issue.

frank lintel
#

oh I'd give my life just for a 'main' lua file where ya can then go from there but meh if there an order I dont mind now I know it.

red tiger
#

Thanks to that solution, all Typescript import behavior handles properly.

open drum
#

hey guys, i would like to set a spawn point for each players manually at a diff. location that I desire. Where would be the best way to start? Any .class or mod I can take a look?

ancient grail
#

how is your progress on this mod

#

ill try to come up with logic
you first pick an event to be able to call when the function is triggered

ongamestart you can write where you want to set them on a file so you need getfilereader getfilewriter
then i guess on player death is the best option
ihave no idea how you are going to setup player spawn point but maybe you can modify the file the command wrote and from there you can just modify the coordinate.,. unless someone has a better idea. like menu and stuff... but basicaly you want them customizable

my brain isnt working yet i just woke up lol

#

then just teleport them when they spawn in game

#

setX
setY

#

setlx

#

setly

abstract raptor
#

yo, so like I wanna gradually shift climate colors. This just abruptly makes it change every 10 minutes

function RaveClimate(_clim)
    local ColorRed = ClimateColorInfo.new(1, 0, 0, 0.8, 1, 0, 0, 0.8)
    local ColorOrange = ClimateColorInfo.new(1, 0.5, 0, 0.8, 1, 0.65, 0, 0.8)
    local ColorYellow = ClimateColorInfo.new(1, 1, 0, 0.8, 1, 1, 0, 0.8)
    local ColorGreen = ClimateColorInfo.new(0, 1, 0, 0.8, 0, 1, 0, 0.8)
    local ColorCyan = ClimateColorInfo.new(0, 1, 1, 0.8, 0, 1, 1, 0.8)
    local ColorBlue = ClimateColorInfo.new(0, 0, 1, 0.8, 0, 0, 1, 0.8)
    local ColorIndigo = ClimateColorInfo.new(0.5, 0, 1, 0.8, 0.5, 0, 0.1, 0.8)
    local ColorMagenta = ClimateColorInfo.new(1, 0, 1, 0.8, 1, 0, 1, 0.8)
    local ColorTable = { ColorRed, ColorOrange, ColorYellow, ColorGreen, ColorCyan, ColorBlue, ColorIndigo, ColorMagenta }

    local colorIndex = 1
    function getNextColor()
        colorIndex = colorIndex + 1
        if colorIndex > #ColorTable then
            colorIndex = 1
        end
        return ColorTable[colorIndex]
    end

    function updateColors()
        local color = getNextColor()
        local globalLight = _clim:getClimateColor(0);
        globalLight:setEnableAdmin(true);
        globalLight:setAdminValue(color);
        globalLight:setModdedInterpolate(1.0);
    end

    Events.EveryTenMinutes.Add(updateColors)
end

Events.OnClimateManagerInit.Add(RaveClimate)
Events.EveryTenMinutes.Add(updateColors)

ancient grail
#

wow your code mp compat?

abstract raptor
#

Prolly?

#

it doesn't gradually change tho

#

it just kinda short cuts to the thing

#

I dunno how to make lerp to the target value

frank lintel
#

because you gotta math it to transition from one color to the next.

bronze yoke
#

i wonder if setModdedInterpolate is supposed to do that for you, though? that's what it sounds like it should do

frank lintel
#

dunno no clue just like not sure why there 8 values for color.

abstract raptor
#

cuz I want it to do rainbow

#

uwu

frank lintel
#

well when you say every 10 min, go from one color to another its just gonna cut... like a dubstep drop changing bpm.

jaunty marten
#

wow, looks absolutely crazy

red tiger
#

He lives.

jaunty marten
red tiger
#

I feel like I'm writing some kind of mock-MIT paper on ZedScript lol.

frank lintel
#

felt more like I was back at oracle and they doing a presentation to the DoD

red tiger
#

Those UMLs are literally why I'm up right now prepping UML for my work tomorrow.

#

xD

#

My boss saw em and was like "Yup. You're doing this for the meeting now."

frank lintel
#

I was lucky I was a hardware guy... but I had to still sit thru them

frank lintel
#

that and fiber optics

red tiger
#

o-ohh...

#

It's going to be fun watching people react to my UML for ZedScript when I get it all done and place them in one giant image.

jaunty marten
#

@red tiger to change my server nickname from Вишня to Vishnya I have to be Veteran Suicide

red tiger
#

I made a custom theme for PlantUML that looks like VSCode Dark Theme V1 with Ubuntu fonts.

jaunty marten
#

ubuntu fonts LUL

red tiger
#

I'd share you the current file I'm working on if I weren't under an NDA.

#

I can share you my theme because it's mine.

#

It's totally incomplete but it works for classes and objects rn.

jaunty marten
#

never worked with plantuml before so I think it's not useful for me ha-ha

red tiger
#

I might make a repo for it so someone will find it one day..

#

PlantUML is so ugly though.

#

I'll edit the hell out of it if I can get that professional shine.

jaunty marten
red tiger
#

I'm considering writing a UML "Lego-set" in Bootstrap HTML.

#

Use the power of the Interwebz

#

Hopefully all this documentation for ZedScript will help people...

jaunty marten
red tiger
#

lol

#

I could write a rich-comment solution for the editor.

jaunty marten
#

if it will help for peoples like I described ha-ha

red tiger
#

SimCity 2000 when?

jaunty marten
#

ha-ha

#

mb after will do same thing for electric cables

red tiger
#

Going to bed. Got stuffs to do.

#

cya.

jaunty marten
open drum
abstract raptor
#

bleh

#

I posted in the wrong channel

#

hahaha

#

ColorInterpolator = {}
ColorInterpolator.instance = false

function ColorInterpolator:new(_clim)
    local o = {}
    setmetatable(o, self)
    self.__index = self
    
    o.clim = _clim
    o.values = {}
    o.colorIndex = 1
    o.colorTime = 0
    o.colors = {
        { r = 1.0, g = 0.0, b = 0.0, a = 1.0 }, -- red
        { r = 1.0, g = 0.5, b = 0.0, a = 1.0 }, -- orange
        { r = 1.0, g = 1.0, b = 0.0, a = 1.0 }, -- yellow
        { r = 0.0, g = 1.0, b = 0.0, a = 1.0 }, -- green
        { r = 0.0, g = 1.0, b = 1.0, a = 1.0 }, -- cyan
        { r = 0.0, g = 0.0, b = 1.0, a = 1.0 }, -- blue
        { r = 0.5, g = 0.0, b = 1.0, a = 1.0 }, -- purple
        { r = 1.0, g = 0.0, b = 1.0, a = 1.0 }  -- magenta
    }
    
    o.interpolate = 0;
    
    return o
end

function ColorInterpolator:Init()
    local targetColor = ClimateColorInfo.new(
        self.colors[self.colorIndex].r,
        self.colors[self.colorIndex].g,
        self.colors[self.colorIndex].b,
        self.colors[self.colorIndex].a,
        self.colors[self.colorIndex].r,
        self.colors[self.colorIndex].g,
        self.colors[self.colorIndex].b,
        self.colors[self.colorIndex].a
    )
    self.color = self:registerValue(self.clim:getClimateColor(1), targetColor)
end


function ColorInterpolator:registerValue(_value, _target)
    table.insert(self.values, { val = _value, target = _target })
    return _value
end

function ColorInterpolator:OnEveryTenMinutes()
    self.colorTime = self.colorTime + 1
    
    if self.colorTime >= 10 then
        self.colorTime = 0
        
        self.colorIndex = self.colorIndex + 1
        
        if self.colorIndex > #self.colors then
            self.colorIndex = 1
        end
        
        local nextColor = self.colors[self.colorIndex]
        local targetColor = ClimateColorInfo.new(
            nextColor.r,
            nextColor.g,
            nextColor.b,
            nextColor.a,
            nextColor.r,
            nextColor.g,
            nextColor.b,
            nextColor.a
        )
        
        for k, v in ipairs(self.values) do
            v.val:setEnableModded(true)
            v.val:setModdedValue(v.val:getName() == "GLOBAL_LIGHT"  and targetColor or targetColor*self.interpolate)
            v.val:setModdedInterpolate(self.interpolate)
        end
    end
end


Events.OnClimateManagerInit.Add(function(_clim)
    ColorInterpolator.instance = ColorInterpolator:new(_clim);
    ColorInterpolator.instance:Init();
end)

Events.EveryTenMinutes.Add(function()
    if ColorInterpolator.instance then
        ColorInterpolator.instance:OnEveryTenMinutes();
    end
end)
#

I thought this would work but I keep getting an error on the line

v.val:setModdedValue(v.val:getName() == "GLOBAL_LIGHT" and targetColor or targetColor*self.interpolate)

#

Oh it's supposed to be "COLOR_GLOBAL_LIGHT"

jaunty marten
abstract raptor
#

XD

#

Dunno why I was doing it that way.

jaunty marten
ancient grail
abstract raptor
#

welp

ancient grail
#

pzBleach cheers vishnya

abstract raptor
#

still not working

jaunty marten
abstract raptor
#

I just wanted the sky to shift through rainbow colors

ancient grail
bronze yoke
jaunty marten
ancient grail
abstract raptor
#

Yeah I was able to shift colors, but like, not gradually

jaunty marten
ancient grail
bronze yoke
#

it's possible since it's dealing with colour but i'd still be surprised

ancient grail
#

Maybe you cant trigger changes from evvery10mins event

jaunty marten
#

really surprised

abstract raptor
ancient grail
#

Use OnClimateTick or something

abstract raptor
#

i just wanted to do it with the colros this time

jaunty marten
#

just try to print everything and check mb smth even didn't called

ancient grail
#

Theres an event like that i think

ancient grail
#

The whole line

#

The one inside the for loop

abstract raptor
#

here's an example of when I made it work with one color

#

and fog

#

This time I just wanted a table of colors for it to run through and not do the fog

fringe ridge
#

I am wondering something, a LOT can be translated, but can the description in a mod's mod.info file also be translated?

open drum
#
        if     Time > 48 then
        
            --local intnum = math.floor(HourSurv)
            --player:Say("You have Survived " .. tostring(intnum).. " HOURS")
            player:Say("You have survived for ".. TimeString ..  " Welcome to WURO Land")
            player:getInventory():AddItems("Base.Apple", 1)
            
            
               
            player:playEmote("salutecasual") 
            player:setX( math.floor(tonumber(7010)))
            player:setY( math.floor(tonumber(5156)))
            player:setZ( math.floor(tonumber(0)))
            player:setLx(7010)
            player:setLy(5156)
            player:setLz(0)

        else 
            player:Say("You have not survived for ".. setTime .. " days yet")
        
        end
ancient grail
#

I dont know abt that i just leave mine with almost nothing written
I only modify the other one

open drum
#

Does anyone see why my char wouldn't teleport to indicated location??

jaunty marten
#

what the hell math.floor(tonumber(7010))

open drum
#

it teleports but like.. 1 tile side where i was standing

ancient grail
#

This is missing some stuff

#

Lol yeah

open drum
jaunty marten
#

number to number
round up integer val

#

don't drink while coding hah

open drum
#

xD

open drum
ancient grail
#

Is this the whole lua file?

#

When did you trigger this

open drum
#

no

#

hold on

ancient grail
#

What is player?

open drum
#
function TeleportSpawn_OnCreate(items, result, player)
        
        
        local player = getPlayer();
        --player:setHoursSurvived(1)


        
        HourSurv = player:getHoursSurvived();
        local setTime = 2
        local Time = player:getHoursSurvived();
        local TimeString = player:getTimeSurvived();
        --local num = string.match(Time,"%d+")
        
        --if  tonumber(num) > setTime then
        if     Time > 48 then
        
            --local intnum = math.floor(HourSurv)
            --player:Say("You have Survived " .. tostring(intnum).. " HOURS")
            player:Say("You have survived for ".. TimeString ..  " Welcome to WURO Land")
            player:getInventory():AddItems("Base.Apple", 1)
            
            
               
            player:playEmote("salutecasual") 
            player:setX( math.floor(tonumber(7010)))
            player:setY( math.floor(tonumber(5156)))
            player:setZ( math.floor(tonumber(0)))
            player:setLx(7010)
            player:setLy(5156)
            player:setLz(0)

        else 
            player:Say("You have not survived for ".. setTime .. " days yet")
        
        end
    

end

#

that's the whole thing

ancient grail
#

setX and setLx idnt the same

open drum
#

they are not the same

#

??

#

actually.. i don't get the diff. b/w setX and setLx

#

what is setLx do exactly?

ancient grail
#

Put that on a var first then call it

local coordX = 7010

Thats already rounded you dont need floor

#

player:setX(coordX)
player:setLx(coordX)

open drum
#

i guess it doesn't accept int. as it's parameter

ancient grail
#

It does

open drum
#

ah?

ancient grail
#

If that coordinate actually exist that is..

#

What's your event for this?

open drum
#

onCreate

#

yea i checked the coords and it isn't the problem

jaunty marten
ancient grail
#

Check vanilla

open drum
#

i see

#

i wish debug mode has

#

search system after I open .lua files

#

so i can place breakpoints much easier

open drum
vague hedge
#

If I am coding a recipe and I want there to be multiple items as the result of the recipe, what would the code part look like?

Current code:

recipe Sell Pallet Of Copper Ingots
    {
        HCCopperingotbox,
    keep HCTradingpost,
        CanBeDoneFromFloor:true,
        Result:HC20dollarbill
               HC10dollarbill
               HC5dollarbill,
        Time:15,
        Category:Trade,
    }
worn juniper
#

then in lua/client or server folder you add the function to add the items directly in the player's inventory

ancient grail
#

Then AddItems() a bunch of time depending on how many types u want to create but if its just one thing then you just add =integer
On the script

#

Im sure Im not clear... But if you dont understand ill explain further

pallid briar
#

I want to translate this game into Arabic with whom I speak

ancient grail
#

@pallid briar

pallid briar
#

tnx

vague hedge
vague hedge
ancient grail
#

Im afk

vague hedge
#

I'll just make it give a 50 dollar bill,

#

All good

ancient grail
#

then just do Result:Base.Money=50,

#

dont need 0oncreate iof its jkust 1 type thats what i ment

vague hedge
ancient grail
vague hedge
ancient grail
#

i gues

vague hedge
#

That would probably make sense as to why my hosting file wouldn't load when I put the mod in

small topaz
#

Does anyone knows what the difference between the lua events "OnPlayerDeath" and "OnCharacterDeath" is?

ornate summit
#

Is there a limit to how far out in the world tiles can be placed?

#

Theory-crafting a way to combine multiple maps together dynamically, but it would be a lot easier if the maps could be placed anywhere in the world.

gleaming garnet
#

I am genuinely curious if the latter would work...

ornate summit
#

If the world bounds are infinite, you'd just assign each map to its own local "origin" and offset each of its tiles by that. And the origins can be as far away as needed go ensure that each map has enough space.

jaunty marten
ornate summit
#

This is less a question about creating maps and more the limitations of the game's engine.

#

Hence why I dropped it here.

jaunty marten
#

mappers knows more about map limitations than modders

#

basic logic

ornate summit
#

...what?

#

I make maps and I don't know the map limitations.

#

Because why would I need to for making buildings and tiles?

jaunty marten
ornate summit
#

Because it's more relevant here.

jaunty marten
ornate summit
#

That's your opinion.

jaunty marten
#

question about MAPS in MAPS chat

#

lol

#

stop trolling

ornate summit
#

Lolwhat

#

I'm just trying to get an answer to my question in the channel I figured it would fit best in.

worn juniper
#

simple

gleaming garnet
#

Is it not a question of the game engine limitation? I personally think the game map falls into that category

ornate summit
#

👆

jaunty marten
#

what's the problem

ornate summit
#

Look. I'm not arguing about this anymore.

gleaming garnet
#

No point in arguing any further lol. No harm asking there again either

ornate summit
#

Got a problem with me asking in this chat? Take it to a mod.

#

Anyways.

#

The idea would be to dynamically load individual maps into a new "combined" map with teleportation points to move between them, like how the basement mod works.

jaunty marten
#

anyway have a luck with asking about map in modding channel

#

have a good day

ornate summit
#

👍

#

So the mod would need to manage essentially taking map data, loading it into a different location within a separate map, and then linking up the transit points between it and all other areas.

#

I'm curious as to whether this could be done on game load, or if it would need to be a separate application.

gleaming garnet
#

I'm trying to see this in a different perspective. Would it even be possible for a modded map to not be connected to the "main" region?

ornate summit
#

I... think? There definitely are standalone maps.

#

I wonder though, do they just put their stuff super far away?

gleaming garnet
#

That would be unlikely lol

ornate summit
#

I'll have to check that out. Would be funny if that was the case.

#

Would certainly make linking them easier.

sour island
# ornate summit The idea would be to dynamically load individual maps into a new "combined" map ...

I'm all for pushing envelopes and taxing the engine, but logically it would make more sense to just manually place the maps to fit better with each-other.

Making borders or waypoints to link maps is kind of counter to how the vanilla map is setup to work - being it's handled in chunks.

Doing anything map related in real-time will be taxing to the engine/gameplay btw. Although, it might be more possible with the introduction of basements -- as they've implied they use loaded templates.

#

Dynamically generating roadways between maps would also be something you can generate once and be done with it. Nothing really beats generated-once-and-then-hand-curated @ornate summit

#

This coming from someone who doesn't know much about mapping in PZ though

chrome egret
#

Do you folks use Mod Options to allow your players to change mod settings, or are there better solutions at this point?

sour island
#

I believe Star plans to rework modOptions

#

If you prefer players to not be able to change options I made EasyConfigChucked work like that

#

But I also plan to rework that too, to offer both options

#

Soon™

chrome egret
#

Lol, well I appreciate the answer. I'd like to add options to my mod which can only be changed by the admin in multiplayer, but are configurable by players in singleplayer.

#

I understand that sandbox vars can achieve that, but I'm not confident on how to work with them, and I definitely want changing the values to be supported through the UI.

rustic garnet
chrome egret
#

Do you happen to have an example of the valueTranslation for the enum class here?

open drum
#

Ugh this is really frustrating me

#
function TeleportSpawn_OnCreate(items, result, player)
        
        
        local player = getPlayer();
        --player:setHoursSurvived(1)


        
        HourSurv = player:getHoursSurvived();
        local setTime = 2
        local Time = player:getHoursSurvived();
        local TimeString = player:getTimeSurvived();
        --local num = string.match(Time,"%d+")
        
        --if  tonumber(num) > setTime then
        if     Time > 48 then
        
            --local intnum = math.floor(HourSurv)
            --player:Say("You have Survived " .. tostring(intnum).. " HOURS")
            player:Say("You have survived for ".. TimeString ..  " Welcome to WURO Land")
            player:getInventory():AddItems("Base.Apple", 1)
            
            local X = 7010
            local Y = 5157
            local Z = 0
     
            player:playEmote("salutecasual") 
            player:setX(X)
            player:setY(Y)
            player:setZ(Z)
            player:setLx(X)
            player:setLy(Y)
            player:setLz(Z)



        else 
            player:Say("You have not survived for ".. setTime .. " days yet")
        
        end
    



end
#

why is this not working??? it won't teleport my char

#

this is what happens

#

is it because i ran this code in Client? should I use onclientcommand?

#

it worked when i was in single play or hosted a coop server but won't work on dedicated

ancient grail
#

Can share lua require share?

frank lintel
#

you mean as in like pre-load require? depenancies etc.?

ancient grail
frank lintel
#

actually good question, I mean if its something that can run for both server and client then I would think yes? not sure if server has access to everything client does (but doesnt use it or cant...)

ancient grail
#

Client cant require server server cant require client

#

Right? Iirc

frank lintel
#

well makes sense. but then you got the whole SP basically being one and the same (I think) but MP/dedicated that def makes sense client/server cant see each other.

open drum
#

just doesn't teleport

#

well it does teleport.. but just not to the given X Y Z i wrote

ancient grail
#

Paste the teleport code only on debug

#

Maybe your checkers are wrong

open drum
#

what do you mean paste the code on debug?

ancient grail
#

The lua console just paste the code without the conditions

#

Like this

getPlayer():setX(getPlayer():getX()+10)
getPlayer():setLx(getPlayer():getX()+10)

#

Then hit enter

open drum
#

oki

frank lintel
#

yeah not debug Glytch meant console.

ancient grail
#

Ye lia console

#

Lua

#

Sorry i mesed up the term

#

I cant figure out my shit either .. 😦

frank lintel
#

its okay I do the same thing till its like burned into memory

ancient grail
#

Must be painful

#

To burn something into your memory

#

Jk im just tired lol

frank lintel
#

only way I remember things cuz I look like that face all day.

ancient grail
#

fire 🧠3013bigbrain ded moodleGlytch3rSad

#

I just keep lots of snippets

frank lintel
#

more like stare at code... time for medicine... 🚬 drunk ah better.

ancient grail
#

Nice

open drum
#

well that worked

#

but still doesn't work with my mod code

ancient grail
#

Try to make an oncreate that only does say

red tiger
#

Are you okay?

ancient grail
#

Dont make it complex then if that works

frank lintel
#

or have it set the coords to your log file or say it to verify ya calculations

open drum
ancient grail
#

Why is my code alll messed up omg im about to pass out and failed my thing for the day

Im gona concentrate now .

frank lintel
#

heh I'll be at work all day thinking of this stuff...

frank lintel
#

also why I typically blast hardcore or industrial while doing this... keep me in a rhythm

ancient grail
#

ow man

#

end

#

i was just missing

#

end

#

end

#

shiiiiiz

frank lintel
#

one death, one try, every 40 seconds a script dies from a missing end block, aye!

open drum
#

still can't figure out what is wrong with my code XD i should just give up...

#

glad to know you found your error 🙂 congrats

open drum
#

Well i kinda found a hint of what the problem is..

#

If i plug in the coord. that is around my char, it works flawlessly. However if I plug in a long distance beyond the cell I am in.. it doesn't work

#

i guess ill have to load the map region first then call out this function?

fast galleon
#

see how other tp mods do it

open drum
#

yea, i guess that would help.. I wanted to solve it by myself.. but this is my limit

#

i accept my defeat Lua....

fast galleon
#

@open drum
try your command from console. There's some triggers that will stop you teleporting, I think recipe might be one of them.

open drum
#

oh really?

fast galleon
#

If that works, adjust your function to trigger on next tick

open drum
#

oh dang

#

it does work on console

#

trigger on next tick? like executing onTick ?

fast galleon
#

I think I have an example here

open drum
#

oh, thousand thanks

ancient grail
open drum
#

yea with help of you guys

#

i was able to make it work

#

thanks alot

#

the problem was that OnCreate function

ancient grail
#

👏

open drum
#

does not run teleport

ancient grail
#

congrats

open drum
#

thank you

#

coulnd't have done it without u guys

#

been struggling with this for whole day today

sour island
#

Crafting cancels movement - I think someone had a similar issue

#

A while back

#

I also had a similar issue actually - with teleporting off walking into squares

deft skiff
#

Hello. Awhile ago, I made a simple mod that removes the "rotting" parameter from food, so that it never spoils (https://steamcommunity.com/sharedfiles/filedetails/?id=2695935241). It just changes some of the .txt files, it's very straightforward. Someone asked in the comments if I could update this mod to also work on modded foods, specifically, the ones from Pomp's Items (https://steamcommunity.com/sharedfiles/filedetails/?id=2792348686). How would I go about doing that? If I grab the .txt files from Pomp's, remove the same parameters, and put it into the mod files that I upload, is it going to conflict if people don't have Pomp's installed?

sour island
#

You could parse through the scriptManager in Lua

#

Basically at the boot up you have the scriptManager look through each script and make changes you're already making. There's probably a snippet or two if you search "scriptManager" here.

sweet tide
#

whats your guys thoughts on chatgpt for helping you make mods, I tested earlier and i was so blown away it figured out how to edit UI elements and include require "ISUI/ISPanel"
require "ISUI/ISLabel"
require "ISUI/ISComboBox"
require "ISUI/ISButton"

bronze yoke
#

requiring vanilla files doesn't do anything anyway

#

using it to assist you is fine, but don't rely on it too much - the code it generates often looks fine at a glance, but is actually complete nonsense

sweet tide
#

obviously lol but it spat out this:

require "ISUI/ISLabel"
require "ISUI/ISComboBox"
require "ISUI/ISButton"

AgingMechanicUI = ISPanel:derive("AgingMechanicUI")

function AgingMechanicUI:new(x, y, width, height)
    local o = ISPanel.new(self, x, y, width, height)
    o.character = getSpecificPlayer(0)
    o.ageComboBox = ISComboBox:new(50, 50, 100, 25, o, AgingMechanicUI.onAgeComboBoxSelected)
    for i=18,80 do
        o.ageComboBox:addOption(tostring(i))
    end
    o:addChild(o.ageComboBox)
    return o
end

function AgingMechanicUI:onAgeComboBoxSelected()
    self.character:getModData().age = tonumber(self.ageComboBox:getOptionText(self.ageComboBox.selected))
end

function AgingMechanicUI:update()
    ISPanel.update(self)
    local age = self.character:getModData().age
    if not age then return end
    self:addLabel(50, 100, "Age: " .. tostring(age), 1, 1, 1, 1, UIFont.Small)
    local hairColor = self.character:getHairColor()
    if age >= 60 and hairColor ~= "gray" and ZombRand(100) < age-60+1 then
        self.character:setHairColor("gray")
        self.character:setHairDye(nil)
    end
    if age >= 80 then
        self.character:kill(nil)
    end
end

Events.OnGameStart.Add(function()
    local player = getSpecificPlayer(0)
    if not player then return end
    local age = player:getModData().age or 18
    player:getModData().age = age
    local stats = player:getStats()
    stats:setHunger(0)
    stats:setThirst(0)
    stats:setEndurance(0)
    stats:setPanic(0)
    stats:setBoredom(0)
    player:setHairDye(nil)
end)
#

ive noticed it does go a bit overboard in areas or itll just produce some random shit in other areas

#

sometimes you gotta optimize its own code and itll maybe remove the shit at times

deft skiff
#

Have never used Lua before, but I'll see what I can figure out. The other thing people have asked for on that mod is a setting to prevent food spoilage, but only in a freezer that's currently powered on. I know you can change rate of spoilage in a freezer on sandbox settings, but I've never figured out where that setting actually lives -- if I could find it, I could just set that parameter to 0 to disable spoiling, possibly.

#

Any leads on that?

bronze yoke
#

LOL at age 80 it just kills you??

sweet tide
bronze yoke
#

this is definitely the best i've seen from ai generated code in here, i haven't worked with ui extensively but it is definitely at least close to correct

sweet tide
#

the problem is people dont know how to speak to it and then blame the ai

#

its all about what you say

#

you gotta be clear and concise

bronze yoke
#

i usually see it completely making up functions and stuff

sweet tide
#
Please just output the code and a short summary```
#

this was the prompt

#

i tried chucked random ideas and wanted to see if it would do it

#

it did this at first and i was like wtf

#

so i had to tell it to do it in a for loop

#

chatgpt trying to turn into a mini yandere dev

ancient grail
#

thefuq happened to the muzzle flare

sour island
#

Going to train chatGPT to bugfix for me

ancient grail
#

Rebrand it

#

Hehe u know the name

red tiger
#

On break.

red tiger
#

Hell a range lol

#

I'm becoming less human. My proof? I thought of a fucking varargs solution to that picture before seeing it was a numeric literal range.

ancient grail
#

Ow its not

sweet tide
worn juniper
#

HE FLAMIN'

cunning kestrel
#

anyone has something on an animation state sometimes not working/ transitioning ?

#

or how to set an animation state ?

wooden lodge
#

Question, I'd like to add a random item that you can unpack (using right click / recipe) that gives you a random item from a list. How does one go about that?

#

I assume wit an OnCreate but how exactly does it work

sweet tide
# wooden lodge Question, I'd like to add a random item that you can unpack (using right click /...
-- Define a list of items to randomly choose from
local itemNames = {
  "item1",
  "item2",
  "item3",
  -- add more items to the list as needed
}

-- Define the unpacked item
local unpackedItem = {
  type = "Item",
  displayname = "Random Item",
  icon = "random_item_icon", -- replace with the path to your item's icon
  texture = "random_item_texture", -- replace with the path to your item's texture
  weight = 0.5,
  -- add other properties as needed
}

-- Define the recipe for unpacking the item
local unpackRecipe = {
  result = "Random Item",
  ingredients = {
    {"box", 1},
    -- add other ingredients as needed
  },
  -- add other recipe properties as needed
}

-- Define the function that gets called when the item is unpacked
local function unpackItem(player, item)
  -- Choose a random item from the list of item names
  local randomItemName = itemNames[math.random(#itemNames)]
  -- Give the player the chosen item
  player:getInventory():AddItem(randomItemName)
end

-- Define the OnCreate function for the unpacked item
function unpackedItem:OnCreate()
  -- Set up the unpacking recipe
  self:Use("Box")
  self:addRecipe("unpack", unpackRecipe)
  -- Set up the unpacking function
  self:setCustomContextMenu("Unpack", "unpackItem")
end

it generated this

#

try that or take parts if u need it

#

no clue if it works

ancient grail
#

Oncreate is a function that is called by item scripts

The function should be written on the server lua

To do the random thing you could

Put stuff on a table

Then use ZombRand()

Sample

SampleStuff={ "Base.Apple",
"Base.Orange",
"Base.Cherry", }

getPlayer():getInventory():AddItems(SampleStuff[ZombRand(1, #SampleStuff+1), ZombRand(8))

#

This will give you a random fruit and and a random amount

#

@wooden lodge

ancient grail
#

ZombRand()
And
ZombRandFloat()

sweet tide
ancient grail
#

It knows too much

wooden lodge
#

@ancient grail So I use this, 1:1

SampleStuff={ "Base.Apple", 
"Base.Orange", 
"Base.Cherry", }

getPlayer():getInventory():AddItems(SampleStuff[ZombRand(1, #SampleStuff+1), ZombRand(8))
``` in the media/lua/server directory and use OnCreate:SampleStuff_OnCreate

or am I being stupid
#

And which number do I need to chagne if there's more than 3 items?

ancient grail
#

You have to define it inside the oncreate function

#

Also im missong a closing ]

bronze yoke
#

most of what the ai spat out is total nonsense

ancient grail
#

After the #SampleStufd

wooden lodge
#

Yes

#

I mean I've got a oncreate file already

ancient grail
#

And a local on samplestuff declaration

Should be
local SampleStuff ={

wooden lodge
#
KaeldorConch = {
    
    "Yes",
    "No",
    "Maybe",
    "Absolutely not",
    "Definitely",
    }

function KaeldorConch_OnCreate(items, result, player)
    local roll1 = ZombRand(1,5)
    processSayMessage(KaeldorConch[(roll1 + 0)] .. "!")
    local sq = player:getSquare()
end
#

For stuff like this

#

And it works

ancient grail
#

local KaeldorConch

wooden lodge
#

I've got talking Teddy too

#

I mean it works on my dedicated server

#

Without local

humble oriole
#

Is anyone familiar with preventing players from putting items in a container for a short time?

wooden lodge
#

I want to add some random loot box tkind of thing

ancient grail
#

Yep i got that

wooden lodge
#

Just a bit confused with this now actually

ancient grail
#

How so

wooden lodge
#

So let's say

#
SampleStuff = {
    
    "Base.Apple",
    "Base.Orange",
    "Base.Cherry",
    }

function SampleStuff_OnCreate(items, result, player)
    local roll1 = ZombRand(1,3)
    processSayMessage(KaeldorConch[(roll1 + 0)] .. "!")
    local sq = player:getSquare()
end
#

What would I need toa djust here

#

I'm a bit tired too, doesn't help

bronze yoke
#
local myItems={"Base.Apple", "Base.Orange", "Base.Cherry",}

MyOnCreate = function(items, result, player)
    player:getInventory():AddItems(myItems[ZombRand(0, #myItems)+1], ZombRand(8))
end
wooden lodge
#

And what would I need to puti in the rcipe of the box?

ancient grail
#

There

wooden lodge
#
recipe Ask the Conch
    {
        KaeldorConch,
        Result:KaeldorConch,
        Time:30.0,
        OnCreate:KaeldorConch_OnCreate,
        AnimNode:Forage,
    }
#

Like for example

#

What is the onCreat called in your case?

ancient grail
#

Ye

bronze yoke
#

OnCreate:MyOnCreate

wooden lodge
#

so I could rpelace that

#

With like

bronze yoke
#

so whatever you end up renaming the function to

wooden lodge
#

Lootbox1

#

Or RandomBox

#

or whatever

ancient grail
#

Ye

wooden lodge
#

and ZombRand0 means it picks any in the list?

ancient grail
#

Its the function itself

wooden lodge
#

What does the +1 stand for?

ancient grail
#

It just generates a number

wooden lodge
#
#myItems)+1]
bronze yoke
#

zombrand is java so it counts from 0, lua counts from 1

ancient grail
#

(minimum, maximum)

wooden lodge
#

and the 8 here lua ZombRand(8)

#

Is that the amount?

ancient grail
#

By default if you put just one number

Ot will count from 0

bronze yoke
#

yeah, though now that i'm looking at it that one should be + 1 too

#

otherwise sometimes it'll try to spawn 0 items...?

wooden lodge
#

And if I have 3 items

#

and put that to 3

#

All 3 will always spawn?

#

Is that how I'm understandg it

bronze yoke
#

you'd replace ZombRand(8) with just 3

ancient grail
#

(1,3+1)

wooden lodge
#

And if I put it to 1

ancient grail
#

No thats the qty

wooden lodge
#

Only one item from the list will spawn

#

Like a random one?

#

Shit this got me more confused than it should lmfao

bronze yoke
#

oh, actually it'll spawn multiple of one item

humble oriole
#

yea, AddItems is (item, qty)

#

AddItem is (item)

ancient grail
#

Ow yeah if you dont add 1 it moght not spawn stuff
Thats what i intentionally did but if u want it to always generate stuff then just add 1,

wooden lodge
#

What if I want to make a box that contains an entire set of gear

#

Like a 100% chance to spawn every item once

#

Like a set of gear

bronze yoke
#

if you want it to pick randomly for each one it'd be better to do something like this:

local myItems={"Base.Apple", "Base.Orange", "Base.Cherry",}

MyOnCreate = function(items, result, player)
    local inventory = player:getInventory()
    for i = 1, 3 do
        inventory:AddItem(myItems[ZombRand(0, #myItems)+1])
    end
end
ancient grail
#

The. Its the same

#Gears
This returns the number of entry on the array

#

If you have 5 gears then thats 5

bronze yoke
#

for a set of items, something like this:

local myItems={"Base.Apple", "Base.Orange", "Base.Cherry",}

MyOnCreate = function(items, result, player)
    local inventory = player:getInventory()
    for i = 1, #myItems do
        inventory:AddItem(myItems[i])
    end
end
#

it'll give you one of every item in myItems

ancient grail
#

Since zombrand starts from 0 we add +1 cuz we want the last item to be on the list aswell

wooden lodge
#

If I add 20 items to thtat list

#

and it should only spawn one randomly

bronze yoke
#

if you just want it to be one item every time

local myItems={"Base.Apple", "Base.Orange", "Base.Cherry",}

MyOnCreate = function(items, result, player)
    player:getInventory():AddItem(myItems[ZombRand(0, #myItems)+1])
end
wooden lodge
#

Then I geuss it would be 1 and the 3 would be 20?

#

I don't have toa djust any numbers there?

ancient grail
wooden lodge
#

No matter if the list has 20 or 50 items?

humble oriole
#

@ancient grail did you ever figure out how to sync inventory changes from the server faster? Still hitting a wall on the DoRemove on the server side.

ancient grail
ancient grail
bronze yoke
#

inventory belongs to the client so there are no synchronisation issues there

ancient grail
#

Then ye you dont have to adjust it . O ly add or reduce stuff from list

wooden lodge
#

And it would still work without changing a variable? number?

#

It would still pick 1 item no matter how many are to be selected?

bronze yoke
#

yeah, this will work with any sized list

ancient grail
wooden lodge
#

You're awesome

#

I'm a bit tired I apologize

bronze yoke
wooden lodge
#

I appreciate it

ancient grail
humble oriole
#

I'm doing a timed action that at the end removes the item from the container, and if a player puts anything in the container for 2-3 ticks after the timed action finishes the items evaporate and a bufferoverflow error hits the log.

bronze yoke
#

arraylists are java, tables are lua

red tiger
#

tables..

#

Tables in Lua makes me cry.

bronze yoke
humble oriole
bronze yoke
#

most likely

ancient grail
red tiger
#

If you do this on the server, you must propagate the changes IIRC.

humble oriole
#

I am, that's what's annoying

frank lintel
#

That or mixing up index 0 or 1

bronze yoke
#

when they get around to making inventories fully server-side authoritative this will stop being an issue

red tiger
#

(Haven't read up yet)

red tiger
ancient grail
#

When you relogin

red tiger
#

It's very confusing that they'd make it Client-auth.

humble oriole
#
                        biowastecontainer:removeItemOnServer(item)
                        biowastecontainer:DoRemoveItem(item)
                    end
                end

                if hbg.biowaste > maxWaste then
                    hbg.biowaste = maxWaste
                end

                isohbg:sendObjectChange("containers")```
red tiger
#

Like the work will only be reversed.

ancient grail
#

Cuz the atm mod syncs

bronze yoke
#

wait, it was server auth before? so they made it server auth, then made it client auth, and now they're making it server auth again...?

bronze yoke
humble oriole
#
self.homebiogas:getContainer():requestSync()

    ISInventoryPage.renderDirty = true
#

also doing this in the timed action

#

after sending the command

red tiger
#

Been watching the game's Java code since Build 30.. IIRC inventories were server-auth until 41.

mellow frigate
ancient grail
#
if isClient() then
DoRemove(item)
end

Ithink iirc

humble oriole
#

biowastecontainer:DoRemoveItem(item)

bronze yoke
#

yeah, any mod that messes with items is totally going to break

small topaz
#

Again a mod data question: if I write smth in an item's ModData on client side via
ìtem:getModData().mydata = "something",
are those ModData then visible for other clients as well?

red tiger
ancient grail
#

Should have client check still

humble oriole
#

do I need to run the doremoveitem on both the client and the server?

ancient grail
humble oriole
#

I thought that doing it on the iso object's inventory would essentially do that

#

even if it's on the server side

ancient grail
bronze yoke
small topaz
#

thx

humble oriole
#

should I move all this logic to the timed action and send the data that I want from the items to the server?

bronze yoke
#

looks like removeItemOnServer doesn't do anything on the server

ancient grail
#

It might still work

Like what pao did
SendServerCommand from server lua
And then uddereverlyn noticed

#

We never knew you could do that

bronze yoke
#

it makes the client request the server to remove it

ancient grail
#

Call server from server

red tiger
humble oriole
#
function HBGPlungeBiowaste:perform()

    if self.homebiogas:getContainer():getAllCategory("Food"):size() > 0 then
        CBioGasSystem.instance:sendCommand(self.character,"plungeBiowaste", { { x = self.homebiogas:getX(), y = self.homebiogas:getY(), z = self.homebiogas:getZ() }})
    else
        self.character:Say(getText("IGUI_BioGas_ContainerEmpty"))
    end

    self.homebiogas:getContainer():requestSync()

    ISInventoryPage.renderDirty = true

    ISBaseTimedAction.perform(self);
end```
ancient grail
bronze yoke
humble oriole
#

I'm literally just sending the coordinates of the isoobject to the server and making that do all the work

bronze yoke
#

you can already do that... just call the function

ancient grail
#

Weird idk thats what happened

#

Let me send ss

red tiger
#

The server calling to itself to fix an issue?

humble oriole
#
            local biowastecontainer = isohbg:getContainer()
            local foodList = biowastecontainer:getAllCategory("Food")
            
            if foodList:size() > 0 then
                for v=1,foodList:size() do
                    local item = foodList:get(v-1)
                    if hbg.biowaste < maxWaste then
                        hbg.biowaste = hbg.biowaste + item:getCalories()
                        if item:getReplaceOnUse() then biowastecontainer:AddItem(item:getReplaceOnUse()) end
                        --biowastecontainer:Remove(item)
                        biowastecontainer:removeItemOnServer(item)
                        biowastecontainer:DoRemoveItem(item)
                    end
                end

                if hbg.biowaste > maxWaste then
                    hbg.biowaste = maxWaste
                end

                isohbg:sendObjectChange("containers")
                hbg:saveData(true)
            end```
#

that's the server side command

bronze yoke
#

but SendServerCommand is the one clients listen for

#

and i had a little look and servers cannot call SendClientCommand, and clients cannot call SendServerCommand

humble oriole
bronze yoke
#

it's aimed at glytch3r because what he's saying doesn't seem true at all

humble oriole
#

ok, I thought so, just wanted to confirm

bronze yoke
#

most likely someone is running code from the server folder on the client and getting confused

red tiger
ancient grail
humble oriole
#

I'm already interfacing with the container in the timed action, do I just run this in the timed action and remove the item from the client side?

ancient grail
#

Its from modding server
Feel free to join or pls join rather hehe
Links on my profile

bronze yoke
#

this seems possible

#

very different from what you were saying stressed

ancient grail
#

Not really sure if thats what happened but thats what she said idk if thats the whole case incase i misunderstood i apologize

red tiger
#

Happy BDay @tame mulch

#

Off-topic: I'm a little sad that no one has scrutinized my JSON schema for ZedScript.

#

I don't know how to interpret that. Either I'm the one setting a standard schema for ZedScript or no one has the time for it.

red tiger
#

Think of it as a skeleton for JSON.

tame mulch
red tiger
#

So for instance:

vehicles: [{
  wheels: [{
  //...
  }]
}]

when

vehicle myVehicle {
  wheel frontLeft {

  }

  wheel frontRight {

  }
}
red tiger
#

array-like or plural object-definitions are stored as arrays with property names changed to be plural.

#

deconstructed / deserialized vectors, float-arrays, string-arrays and complex objects as well.

#

It's in order to stay within the philosophy / tools used in JSON, which means that I've modified the names of some of the properties and structs in ZedScript when parsed to the JSON API.

#

This sets up my JSON -> ZedScript to produce clean results.

tame mulch
#

I don't know how to improve it)

red tiger
# tame mulch Looks good and clean!

Thanks. I'm clarifying that because there isn't a standard for the interpretation of ZedScript in JSON, I may be setting the standard if no one contests it.

#

The last thing I'd want to have on my hands is a fully written piece of software on-top of an interpretation of ZedScript as JSON that would be troublesome for others or something like that.

red tiger
# tame mulch I don't know how to improve it)

I'm not asking you or TIS to do anything. I'm asking that when you do something involving ZedScript and it involves or conflicts with my work that I'd be notified or the info be posted somewhere that I can see that.

#

That's really it.

tame mulch
red tiger
#

Did you also see my UML?

#

I did some UML work for categories for ZedScript.

#

It may be useful for you and others to visually see how blocks of properties relate to one another.

humble oriole
red tiger
#

I'm in the business of caring about these solutions. I'm spending my time making solutions so people don't fall into silly gotchas & caveats.

wooden lodge
#

So I've ran into the issue with an OnCreate script and a box that is supposed to give random items.
Whenever I try to start a game it gets stuck on the blackscreen.
As soon as I take the recipes to unpack the boxes and the function itself out of the files, it works again.

Anyone here experienced with that kind of stuff that I could send my script to to look over it?

high summit
#

Don't know where to put this so i'll use here.

I am wondering, is it possible to change the way objects look in the world, like fridges, ovens ect. ect. instead of like custom objects having it overtake a priority from the vanilla assets. I understand the regular way it works is through sheets with each individual png with 2 different directions

I want to attempt to bring 3d objects instead of having the "Deck of cards" that is zomboid.

wooden lodge
# tame mulch Send here, I will check
local Lootbox1L={"Base.Apple", "Base.Orange", "Base.Cherry",}

Lootbox1 = function(items, result, player)
    player:getInventory():AddItem(Lootbox1L[ZombRand(0, #Lootbox1L)+1])
end

local LootBoxImplantsL={"Base.KaeldorImplantPassive", "Base.KaeldorImplantAgility", "Base.KaeldorImplantCombat", "Base.KaeldorImplantCrafting", "Base.KaeldorImplantFirearm", "Base.KaeldorImplantSurvivalist", "Base.KaeldorImplantTraitremove", "Base.KaeldorImplantTraitadd",}

LootBoxImplants = function(items, result, player)
    player:getInventory():AddItem(LootBoxImplantsL[ZombRand(0, #LootBoxImplantsL)+1])
end
recipe Unpack the Lootbox
    {
        Lootbox1,
        Time:30.0,
        OnCreate:Lootbox1,
        AnimNode:Forage,
    }
    
    recipe Unpack the Lootbox Implant
    {
        LootboxImplants,
        Time:30.0,
        OnCreate:LootBoxImplants,
        AnimNode:Forage,
    }

Albion has looked over it too and said it's - I quote - 'very weird'

#

The items itself work fine and can be spawned in as well, the issue has to be somewehre in teither the script or the recipes

#

And when I remove the recipes and the script, the game loads fine, if I add them, it gets stuck at the loading screen after loading map etc. the "Click to Start" just never shows up

#

No errors and no errors visible in console either

tame mulch
rancid panther
#

is there an IsBitten thing for playerBody?

#

or how would i go about it if i want to check if someone is specifically bitten?

mellow frigate
#

Hi, is there an event triggered when sandbox options are modified ?

fast galleon
#

you can make one

mellow frigate
bronze yoke
#

BodyDamage:getNumPartsBitten() > 0 would be the easiest way

rancid panther
#

ok thanks

#

so with the latter, i could use that to check if any parts are bitten at all?

bronze yoke
#

yeah, the IsBitten()/bitten() methods need a specific body part

wooden lodge
rancid panther
#

also, how can i use rng to give someone a trait?

#

basically this comment gave me the bright idea. im sure it is possible

#

minus the RNG part, would this work?

fast galleon
rancid panther
#

how do i reopen the lua file list if i accidentally closed it?

#

ind debug

frank lintel
#

Reopen it?

rancid panther
#

yeah the file list that lets you search through files to reload lua

#

i accidentally closed it

frank lintel
#

Mean the debug window itself

rancid panther
#

no

#

within the debug window

frank lintel
#

Find the debug settings file

rancid panther
#

the right side would usually have that list and a preview of the lua file

fast galleon
rancid panther
#

it is faster to get an answer so i dont keep doing that

#

i have accidentally closed it many times and would just reload to main menu and wait for lua to reload both ways

wheat kraken
rancid panther
#

but if there's not a solution and i really do have to go back to the main menu and back into the game then i guess i will just do that

fast galleon
rancid panther
#

i see. thanks

#

that's like an alternative debug ui?

fast galleon
#

It adds some nice tools, changes some settings and fixes some debug bugs

rancid panther
#

nice

hollow lodge
#

what's the reason behind those grey outlines?

#

is it because they are rgb .png?

#

should I have them indexed with a color limit?

glass basalt
hollow lodge
#

there's none

glass basalt
#

strange

#

i guess look at the sprites of the clothing in the base game and see what their file structure looks like

#

If I want to automatically remove a part from a vehicle using code, how do I make this statement:

ISTimedActionQueue.add(ISUninstallVehiclePart:new(playerObj, part, time))

Automatically pass with .isValid()?

function ISUninstallVehiclePart:isValid()
    if ISVehicleMechanics.cheat then return true; end
    return self.part:getInventoryItem() and self.vehicle:canUninstallPart(self.character, self.part)
end

I guess my question is how do I set ISVehicleMechanics.cheat to be true?

nocturne lagoon
#

hi, guys. is this the place to show people recently published (uploaded to steam) mods, for people to know them, and maybe get some feedback?

glass basalt
bronze yoke
#

ISVehicleMechanics.cheat = true

hollow lodge
#

but vanilla icons don't have that issue

nocturne lagoon
glass basalt
nocturne lagoon
#

also, a question: how do I make the poster/preview image to appear in the right hand side of the mod page @ Workshop? for me the poster appear only in the same place images/videos appear.

glass basalt
nocturne lagoon
nocturne lagoon
#

should I put a line for the image there, like in the info.mod?

rancid panther
#

okay i got it to work without any RNG added yet. anything i can improve here before continuing?

glass basalt
glass basalt
nocturne lagoon
#

I mean this one:

glass basalt
glass basalt
rancid panther
#

i see. i noticed that too but paid no mind

#

im using Visual Studio

#

can i change it myself to highlight that?

glass basalt
glass basalt
rancid panther
#

also, i kinda just copied the immune trait info but i wanna simplify it to just give the trait on the first instance so the second function can do the immunity part

nocturne lagoon
rancid panther
#

can i just remove a bunch of stuff there or does it only work because i made it the same way i made the trait work originally?

glass basalt
nocturne lagoon
#

ok! thx! 🙂

scarlet cipher
#

Hello there. Modder new to the this server (wasn't aware of it's existence lol). The name in discord is the same as steam so let me know if I can help you with anything. I'm relatively new to this but hey, we're all learning 🤩🤝👍

rancid panther
#

and i want to make it only work when the player is bitten, rather than from any form of infection, since most ppl would just assume they got lucky if they werent infected from a scratch, for example

#

would this work in terms of simplifying, and using the bite thing albion showed earlier

glass basalt
rancid panther
#

this is my own mod, so i am rewriting it

glass basalt
#

ah I see

glass basalt
rancid panther
#
local function discoverImmunity(player)
    local playerBody = player:getBodyDamage()
    if  playerBody:getNumPartsBitten() > 0 and not player:getModData().tested then
        player:getTraits():add("Immune")
        player:getModData().tested = true
    else
        player:getModData().tested = true
    end
end

would this help to make it so they only get tested once for immunity (after i add rng)? so if they fail the immunity test it will make them not do this function anymore?

glass basalt
#

hmmm depends. when is discoverImmunity called? I would put it into the event that triggers every time the player gets hurt

#

you could set a global variable outside of the function to control it only happening once

rancid panther
#

OnPlayerUpdate

glass basalt
#

OnPlayerUpdate is wayyyyyyyy too often 😂, choose another one

#

like several times a second too often

#

ill look at the lua events, brb

rancid panther
#

it's just carryover from the immunity trait

frank elbow
# chrome egret Do you happen to have an example of the valueTranslation for the enum class here...

Did you end up getting an answer? I can check rq if not, saw the message earlier but was too busy to respond

Update: checked. The translations are derived with "Sandbox_" + valueTranslation + "_option" + index, so if you have a value of "MyOptValues" for your valueTranslation and 3 values, you'd be expected to have translations for Sandbox_MyOptValues_option1, + two more with the same prefix but ...option2 and ...option3

rancid panther
#

i was thinking i can do every couple hours so they have to wait to find out if they are immune or not

#

i know about EveryTenMinutes but im not sure what the other ones were

#

i also managed to make the bitten trait add a bandage on their body on spawn instead of putting it in their inventory

frank lintel
#

isnt there a 1 min event?

glass basalt
rancid panther
#

i wouldnt want it to happen every minute, they would know too quickly that they are immune

glass basalt
#

otherwise solo it'd be fine

#

there's also EveryHours and EveryDays

rancid panther
#

ideally, it would happen a few hours after the bite

#

i can try everyhours

fast galleon
#

maybe scale it based on sandbox option?

#

you might be dead in an hour

rancid panther
#

i'll probably add sandbox options further in the future

glass basalt
#

anyway, here's how I'd do it:

UniqueImmunityBooleanNameOrSomethingBecauseGlobal = false

local function myEventFunction()
  -- do the check
  UniqueImmunityBooleanNameOrSomethingBecauseGlobal = true
  --Events.EveryHours.Remove(myEventFunction)
  -- don't actually need the above, you'd need to figure it out how to make this trigger every time a player gets bitten. if you want, that is
end

Events.EveryHours.Add(myEventFunction)
#

for randomness, you could do local immunePercent = ZombRandFloat(1.0) and this should give a float iirc (percentage decimal form)

rancid panther
glass basalt
rancid panther
glass basalt
glass basalt
rancid panther
#

ah...

bronze yoke
#

you need to do

for i=0,3 do
    local player = getSpecificPlayer(i)
    if player then
        -- your code
    end
end
```if you want to run code on client players without having it passed from somewhere
bronze yoke
#

alternatively just local player = getPlayer() but i don't really think it's that much more work to support splitscreen

rancid panther
#

i see

glass basalt
# rancid panther ah...

but that is percentages. if you want to actually determine if they are immune, a simple binary ZombRand(2) will give either 0 or 1

#

but that's with nothing influencing it

#

other than pseudo-random code >:)

rancid panther
#

ah

#

can i put local player = getSpecificPlayer(i) for my other stuff too like the bitten trait?

frank elbow
#

I think ZombRand(1.0) would behave equivalently to ZombRand(1), since (I believe) the implementation of Lua the game uses does not differentiate between integers and doubles

#

There exists a function called ZombRandFloat, though

sour island
#

ZombRand(1) = 0 always btw

glass basalt
rancid panther
#

man...

glass basalt
#

2 it is 😂

sour island
#

There's also a ZombRand for floats iirc - the normal math.random stuff is locked out

glass basalt
rancid panther
#

i understood 1 (0) of this then 😂

sour island
#

Oh Omar mentioned it

rancid panther
#

i will try my best

sour island
#

Is float ex/inclusive? It'd be 0 to 0.9999~?

glass basalt
#

i have no clue, i don't touch random floats

#

axe moment, pog

bronze yoke
#

the thought that it could be exclusive disturbs me

frank elbow
#

I haven't used it either, but the function accepts a minimum and maximum

bronze yoke
#

your percentages will always be a little bit off what you think it's going to be...

sour island
#

zombrand is - so I'd think it would follow it's own conventions

frank elbow
#

Looks like it's inclusive

#

min + (random float in [0.0, 1.0] * (max - min)) behavior

rancid panther
#

if i have (player) up here, will my local definition of player work?

bronze yoke
#

it'll override whatever was passed to it

frank elbow
#

Yes, but it will shadow your parameter

bronze yoke
#

and i doesn't seem to be defined so in this case it won't work

rancid panther
#

ohh

#

would i put 0,3?

bronze yoke
#

getSpecificPlayer takes a number 0-3 - the snippet i posted loops through all four and runs the code if there is a player in that slot, so that the mod behaves properly in splitscreen

#

if you don't care about splitscreen you can just use getPlayer() and forget about looping, but it's really not that much extra work

glass basalt
sour island
#

I don't suppose there's an onHit event for players?

glass basalt
#

not in the base game, probably in a mod library

sour island
#

I know there's a hook for it

glass basalt
#

removed

sour island
#

not used, yeah just saw that lol

#

Seems like this is used instead

bronze yoke
#

yeah, though keep in mind it's not *just* when the player gets hit, and it gets called a LOT

sour island
#

you can check for the ID

#

"INFECTION"

frank elbow
#

There's OnWeaponHitCharacter, which may or may not be exclusive to weapons (I don't think it is)

#

But that also fires for explosives iirc & is not exclusive to players

sour island
#

Yes, this reference to infection appears to be the zombie infection

rancid panther
#

so for 1% chance i would use ZombRandFloat?

bronze yoke
#

yeah, normal infections don't deal damage so that's not a worry

sour island
#

I believe, player's infection value is zombie - indiv bodyparts' is normal infections

#

wish that'd be renamed lmao

bronze yoke
#

(they actually do very little LOL)

frank elbow
rancid panther
#

okay

sour island
#

Looking over it - that event with the "INFECTION" ID is specific to zombie infection

fast galleon
#

what I see the sandbox option is in java SandboxOptions.instance.Lore.Mortality and there's BodyDamage getInfectionMortalityDuration to get the duration

approximate commands

local percent = (getCurrentTimeForInfection - getInfectionTime ) / getInfectionMortalityDuration
percent = math.min(1,percent)
setInfectionLevel(percent * 100)
frank elbow
frank lintel
#

far as I understood it there is no body part for Z infection its the player.

sour island
#

Correct

#

bodyDamage is the object that houses alot of those values

#

if I recall correctly BodyDamage houses BodyParts which houses the indiv parts

frank lintel
#

isnt Z just a 0 - 100 scale?

sour island
#

Yes?

frank lintel
#

well I thought so as well but someone was saying apparently scalar isnt limited to that range in PZ so dunno honestly. myself right now trying to find a way to elim/limit jumpscare

#

btw does jumpscare happen in MP with(out) odd issues like ppl shouldnt be but get it?

sour island
#
public float InfectionMortalityDuration
#

It's a float - so I guess you could set it to 9999

#

but the game won't care as it's looking for >=100 = dead/dying

#

also for the mortality sandbox thing, if it's instant you lose 110 HP - max is usually 100

fast galleon
#

why do you need to set it? for remove it maybe set to -1

sour island
#

-1 is correct

sour island
#
                     var5 = (var15 - this.InfectionTime) / this.InfectionMortalityDuration;
                     var5 = Math.min(var5, 1.0F);
                     this.setInfectionLevel(var5 * 100.0F);
glass basalt
#

uhhh... trying to queue ISUninstallVehiclePart made my game freeze stressed

frank lintel
#

maybe % in numeric?

sour island
#

The game actually *100's the infection level

#

I assume it handles how much HP is lost per tick

glass basalt
#

is there anything problematic with this code? I am currently putting breakpoints & print statements to debug it:

    if vehicleArgs["WeightReduction"] then
        local vehiclePartList = {
            "M998DoorFrontLeftArmor",
            "M998DoorFrontRightArmor",
            "M998DoorRearLeftArmor",
            "M998DoorRearRightArmor",
            "WindowFrontLeft",
            "WindowFrontRight",
            "WindowRearLeft",
            "WindowRearRight",
            "DoorFrontLeft",
            "DoorFrontRight",
            "DoorRearLeft",
            "DoorRearRight",
            "TrunkDoor",
            "M998BackCover",
            }
        ISVehicleMechanics.cheat = true
        
        for _, partName in pairs(vehiclePartList) do
            local part = vehicle:getPartById(partName)
            if part then
                print("[LUVDEBUG] part "..partName.." was found")
                ISTimedActionQueue.add(ISUninstallVehiclePart:new(player, part, 1))
            end
        end
        
        if vehicleArgs["vehicleType"] == "Base.92amgeneralM998" then
            local trunkBarrier = vehicle:getPartById("M998TrunkBarrier")
            if trunkBarrier:getItemType():contains("Base.M998TrunkBarrier1_Item") then
                print("[LUVDEBUG] this M998 has a metal trunk barrier")
                -- change trunk barrier "M998TrunkBarrier"
            end
        end
        
        ISVehicleMechanics.cheat = false
    end
#

player is defined above this block

frank lintel
#

well isnt the parts list missing stuff??

#

I mean syntax wise looks good I think other then the spacing/tabs

glass basalt
#

this code is meant to remove certain parts, such as the doors and trunk from a Humvee

glass basalt
frank lintel
#

yeah it dawned on me just now. but thats all seemed off was the indenting thought ya missed an END for a sec.

glass basalt
#

ohhhhh shit I am checking vehicle, not the vehicle part I listed in the bottom lol

#

not that my code is getting to that statement though, because it keeps freezing

frank lintel
#

manually try the ISTimed line if possible?

fast galleon
#

ISVehicleMechanics.cheat = false try without it this as well

glass basalt
#

okay ill comment those lines with cheat out

#

and see

fast galleon
#

I didn't mean both lines

#

anyhow, check logs why game freezes

#

no Jab today

glass basalt
#

good news is that my list is fine, thank God

frank lintel
#

try it now with the cheat line

glass basalt
#

yeye

#

i need to first check that ISUninstallVehiclePart actually works

#

or is at least handled correctly

frank lintel
#

thats after that one line, if that line is the cause it wont matter. (sorry just took a hit)

glass basalt
#

it is still freezing 😭

#

logs have NOTHING

frank lintel
#

okay turn that back on and comment out the timed action.... 1 sec looking up the option in debug

glass basalt
#

i just want to remove parts from a vehicle ffs, why do I have to do it through a player?

#

setCondition() doesn't actually remove it

frank lintel
#

no that just sets if its good or wrecked... and inbetween

#

atleast thats what it 'says' it should be doing

#

this might help ya get some log info... debug.options.checks.slowLuaEvents

#

as for a player well thats because you are removing it. Im betting there no such thing as actual removal of parts from the car, just if they hide it or not. (and add an equal part in one's inventory when removing it...)

glass basalt
#

is this the function I want to use, or the function to look at?

#

ill try it anyways

#

...calling that didn't work, and also made some of my code not do anything :/

#

idk whats going on, might just leave this crap for later and push my update as it is

#

ISVehicleMechanics.cheat = false is not the issue though

#

its the action

frank lintel
#

yeah I see the same code in the UI stuff so yeah not that... I'd have to look up the code in ISUninstall....

#

even try using nil instead of player?

#

I mean the code gotta be there for flat out removing/hiding the parts so... now if its exposed... thats another story

glass basalt
frank lintel
#

why I said just try... cant get any worse other then throw an actual error now

glass basalt
#

no, it requires playerObj, with or without cheat enabled

frank lintel
#

so wont do nothing or blows up with a nil object

glass basalt
#

fuck it, ill run it anyway

#

ill check

frank lintel
#

might even help if it throws an error then you can find exactly where/what it doing too possibly

#

I mean to me there should be a method to hide/remove the parts without the player API wise if there isnt then I'd say needs to be added

sour island
#

the player is needed for the 'canUninstallPart' portion

#
function VehicleUtils.UninstallPart(part, chr)
    local item = part:getInventoryItem();
--    VehicleUtils.lowerUninstalledItemCondition(part, item, chr:getPerkLevel(Perks.Mechanics), chr);
    local keyvalues = part:getTable("uninstall");
    local perks = keyvalues.skills;
    local success, failure = VehicleUtils.calculateInstallationSuccess(perks, chr);
    local fail = false;
    if ISVehicleMechanics.cheat then success = 100; failure = 0; end
    if ZombRand(100) < success then
        chr:addMechanicsItem(part:getInventoryItem():getID() .. part:getVehicle():getMechanicalID() .. "0", part, getGameTime():getCalender():getTimeInMillis());
        local content = part:getContainerContentAmount();
        part:setInventoryItem(nil);
        chr:getInventory():AddItem(item);
        item:setItemCapacity(content);
        if keyvalues and keyvalues.complete then
            VehicleUtils.callLua(keyvalues.complete, part:getVehicle(), part, item);
        end
    elseif ZombRand(100) < failure and part:getCondition() > 1 then
        part:setCondition(part:getCondition() - ZombRand(5,10));
        chr:playSound("PZ_MetalSnap", false);
        fail = true;
    else
        fail = true;
    end
    local ui = getPlayerMechanicsUI(0);
    if ui and ui:isReallyVisible() then
        if fail then ui:startFlashRed();
        else ui:startFlashGreen(); end
    end
end
#

You should be able to pick-out what you need for a playerless uninstall

#

alot of lua -> java -> lua going on

frank lintel
#

shrugs no clue there should be a playerless method and I like J learned that for MC modding

sour island
#

ofcourse

#

unfortunately this probably comes down to the fact devs are developing a game and not an engine - so unless they need it or someone asks it probably doesn't exist 😅

frank lintel
#

why I said should be part of the API side if not needs to be added

sour island
#

although having less rigid methods would help scalability down the line for everyone

#

Looking at the snippet I found - I don't even think that's where part removal exsists 🤔

frank lintel
#

yeah Im betting its not exposed at all

sour island
#

unless it's calling 'uninstall.complete' from the script

glass basalt
frank lintel
#

prob exactly as you said why.. I mean what CF said relating to developing a game not engine..

#

MC never had an API... lol. it took 3rd parties to make it.

glass basalt
#

can you construct java objects in Kahlua? I want to create a new InventoryItem as InventoryItem(String module, String name, String type, Item item)