#mod_development

1 messages · Page 42 of 1

weak sierra
#

however, i need to introduce checks for the vehicle spawning

#

is there already a vehicle there? is it water? if it's water it should be a boat, etc..

#

if there's already a vehicle there it should pick a new spot

#

at present i am thinking of restructuring this and taking the vehicle-to-spawn out of the equation and doing that at spawntime, picking from boat or vehicle depending on if the zone is water

#

(to avoid having to reject zones due to this)

#

the clients pick the first random spot to take load off the server, but i think the server will end up placing subsequent random spots into the queue

#

this could potentially lead to a loop of checking and rejecting in a row if enough chunks are loaded

#

anyone have any thoughts on how to do that any cleaner?

bronze yoke
#

is there an elegant way to get player from online id on the server? getPlayerByOnlineId seems to be client-only
EDIT: no idea what i was going on about here, getPlayerByOnlineId exists on the server too

weak sierra
#

what is an online id

#

lol

#

usually we go by steam id or username

#

depending on whether account or broader to the player

bronze yoke
#

well there's no getplayerbysteamid either, and i was worried about whether usernames were unique

weak sierra
#

loop thru em and check yeah

#

:P

#

or

#

loop through them periodically and build a table

#

keyed to steam id or whatever

bronze yoke
#

and specifically i wanted this to work with splitscreen, they'd probably share a username/steam id

weak sierra
#

i dont even know how people access splitscreen

#

coop button i guess

#

ive never touched it 😂

hearty dew
#
--[[
    Gets all players matching a predicate. The default predicate is all players that aren't dead.
    
    Usage example:
    local all_living_players = albionUtils.getPlayers()
    local all_players_named_bob = albionUtils.getPlayers(function(p) return p:getDisplayName() == "bob" end)

    Notes:
    getNumActivePlayers:
    - Singleplayer: number of local players in client (including all split screen players)
    - Client: number of local players in client (including all split screen players)
    - Server: 1, but getSpecificPlayer() calls always return nil on server
    
    getOnlinePlayers:
    - Singleplayer: nil
    - Client: lists all players (including split screen players)
    - Server: lists all players (including split screen players)
    
    getConnectedPlayers: trash. only seems useful for working with scoreboard?
    - Singleplayer: 0
    - Client: only updates when a player manually open scoreboard, but lists all players then
    - Server: 0
]]
albionUtils.getPlayers = function(predicate)
    local result = {}
    predicate = predicate or function(player)
        return not player:isDead()
            -- and player:getCurrentSquare() -- Will filter out players sufficiently far from client that their square isn't loaded
    end
    if not isClient() and not isServer() then
        -- singleplayer
        for i = 0, getNumActivePlayers() - 1 do
            local player = getSpecificPlayer(i)
            if player and (predicate == true or predicate(player)) then
                table.insert(result, player)
            end
        end
    else -- multiplayer
        local onlinePlayers = getOnlinePlayers()
        for i = 0, onlinePlayers:size() - 1 do
            local player = onlinePlayers:get(i)
            if player and (predicate == true or predicate(player)) then
                table.insert(result, player)
            end
        end
    end
    
    return result
end
local onlineID = 10
local players = albionUtils.getPlayers(function(p)
  return onlineID == p:getOnlineID()
end)
  if players[1] then ...

Note that'll only work in multiplayer I think bc getOnlineID() doesn't work in single player

#
LOG  : General     , 1666902398797> isServer=false name=SonjaMaples onlineid=0
LOG  : General     , 1666902398803> isServer=false name=RafaelaBonilla onlineid=1

Oh, I guess there is an online ID returned by getOnlineID() in single player, so that should work on either

#

online IDs aren't persistent afaik, btw

#

between game loads

bronze yoke
#

oh thank you!

#

i wasn't planning on using them for persistence, so that's fine

weak sierra
#

tyrir goes all out sometimes

#

:)

#

now write the overhaul of the vehicle respawn code for me pls lmfao

#

i've had no ADHD meds for over a month this is killing me

#

ima go take some old ones i think, better than nothing

#

<_<

gilded hawk
#

I'm still waiting for mine

#

Does mod options allow to use use sliders? Like the ones in the screenshots?

shadow vault
#

So for the "They Knew" mod, does the zomboxivir Ampule completely cure it when your bitten?

young edge
#

yes, but there are other mods which act as a suppressant instead

#

they share a similar name

hearty dew
gilded hawk
#

Okay, I guess I will use mcm then 🤔

hearty dew
#

.

hearty dew
gilded hawk
#

So, I made a mod that everytime you get a random crit, you hear the TF2 Crit sound

local function onHit(attacker, target, weapon, damage)
    local isDoneByThePlayer = (target:getObjectName() == "Zombie" and attacker:getObjectName() == "Player")
    local isCrit = attacker:isCriticalHit();
    if not isDoneByThePlayer or not isCrit then
        return
    end

    print('TF2CritSound!')

    getSoundManager():PlaySound("TF2CritSound", false, 5):setVolume(1);
end

Events.OnWeaponHitCharacter.Add(onHit);
#

But with this code the sound plays in both speakers and has no location, how can I make that the sound is played from the location of the zombie I just hit?

hearty dew
#

If target is an IsoGameCharacter, might try the playSound() method on it. If memory serves, it will pass the IsoGameCharacter x/y coords to the sound emitter (which I'm assuming will handle stereo sounds, but I have no idea)

frosty estuary
#

How zombie toughness work? It increasethe zombie health or it reduces the damage, and if so, by how much it reduces on each toughness option?

hearty dew
hearty dew
# frosty estuary How zombie toughness work? It increasethe zombie health or it reduces the damage...
        if (SandboxOptions.instance.Lore.Toughness.getValue() == 1) {
            this.setHealth(3.5f + Rand.Next((float)0.0f, (float)0.3f));
        }
        if (SandboxOptions.instance.Lore.Toughness.getValue() == 2) {
            this.setHealth(1.8f + Rand.Next((float)0.0f, (float)0.3f));
        }
        if (SandboxOptions.instance.Lore.Toughness.getValue() == 3) {
            this.setHealth(0.5f + Rand.Next((float)0.0f, (float)0.3f));
        }
        if (SandboxOptions.instance.Lore.Toughness.getValue() == 4) {
            this.setHealth(Rand.Next((float)0.5f, (float)3.5f) + Rand.Next((float)0.0f, (float)0.3f));
        }
#

Just health it looks like

#

Thought there was a strength option (or something?) for damage

hearty dew
#

Yea, it's strength that affects offense. For example, here it affects how many zombies are needed to do drag downs

safe silo
#

What type of time interval events can I use?

I know of Events.OnGameTick and Events.EveryOneMinute but is there others?

hearty dew
#

pzwiki has a list of them. idk how up to date it is though

#

The usual ones are OnTick, OnTickEvenPaused, EveryOneMinute, EveryTenMinutes, EveryHour, EveryDay... That's all that come to mind

#

There are a few other tick events, one specifically for rendering, one for climate

safe silo
#

OnTick wouldn't it take a huge performance hit?

#

I'm looking to check when a generator is turned off it should also turn off my item attached to it. Currently just checking if the tile the item is on has square:haveElectricity() == false, turn it off.
I'm sure there are better ways to do this though, but I assume if it checked each tick might be extreme

hearty dew
#
t={}; for i,j in pairs(Events) do table.insert(t,i) end; table.sort(t); print(table.concat(t,"\n"))```
hearty dew
safe silo
#

Aight one minute it is then

hearty dew
safe silo
#

I don't know actually

hearty dew
#

not event, but something to hook into, a function call for example

thick karma
#

@hearty dew I just tried it, and I think it requires me to disable anticheat type 12.

safe silo
gilded hawk
#

It seems like it still plays the sound from the character

safe silo
#

how do i get the square if I have the x, y, z?

hearty dew
gilded hawk
# gilded hawk It seems like it still plays the sound from the character

This seems to work tho

local function onHit(attacker, target, weapon, damage)
    local isDoneByThePlayer = (target:getObjectName() == "Zombie" and attacker:getObjectName() == "Player")
    local isCrit = attacker:isCriticalHit();
    if not isDoneByThePlayer or not isCrit then
        return
    end

    print('TF2CritSound!')

    getSoundManager():PlayWorldSoundImpl("TF2CritSound", false, target:getX(), target:getY(), 0, 0, 20, 1, false);
end

Events.OnWeaponHitCharacter.Add(onHit);
hearty dew
ruby urchin
gilded hawk
hearty dew
gilded hawk
safe silo
gilded hawk
thick karma
#

It worked! @hearty dew I just got done testing with 2 different clients on a local server. They ate me and ignored the yogi!

#

I got it on video as proof of the fact that right after I died I got kicked on a type 5 violation! And also of my success! 🤪

ruby urchin
thick karma
#

I wonder what type 5 is and why it didn't trigger until I died...

gilded hawk
#

Boh, this thing does not seem to work, I tried getSoundManager():PlayWorldSound("TF2CritSound", target:getSquare(), 0, 10, 1, true) but sound still seems to not work as stereo

hearty dew
#

Are any sounds in the game directional/stereo? I don't play with stereo so I never noticed if that's a thing

gilded hawk
#

Most of them are, helicopter, zombies, gunshots

hearty dew
#

Are those random events directional (wolf howl, gunshot/scream in distance)? Those go through the AmbientStreamManager if I recall correctly

drifting ore
#

Quick mod question guys. I'm having a bug where mods are like, missing segments of a model

#

Example image, STALKER overcoat is missing the legs

frosty estuary
# hearty dew ```java if (SandboxOptions.instance.Lore.Toughness.getValue() == 1) { ...

I was asking cause I'm trying to increase the melee damage when using a item I am making. For that I'm using onhitingcharacter event that give me the hit damage. But after several logs and then digging the source code, I found out that this damage the event give me it's not the final damage that is reduced from zombie health, several other operations occurs like multipliers from weapon skil for example and a final 0.15 multiplier for melee weapon, if I get this correct. So is that another method that I can call to inflict this extra damage that take account all those multipliers too?

#

I was just taking this hit damage setting zombie health minus the extra damage, but that's happening to be too high than I thought, because it's seems the final damage pass through all those multipliers

undone crag
drifting ore
#

Like the armband doesn't end up in the right spot or whatever

undone crag
#

What u mean dawg?

drifting ore
#

Like running STALKER outfits, the oxygen tank and stuff are clipped by everything and have sections missing

#

So I imagine it isn't the mod itself doing that, although it could

#

Like something is interfering

undone crag
#

Do you mean you downloaded the mod and it was doing that?

drifting ore
#

I feel like I see it happen with Shark's stuff too

#

So I wonder if its a settings issue somewhere

undone crag
#

Maybe you have a mod that overwrites mask image files that are referenced by mods.

drifting ore
#

Yeah I just thought it was by item, not something overwritten

undone crag
#

Does it happen with base game non-mod things too?

drifting ore
#

No, it doesn't seem to happen with base items

jade chasm
#

hey guys how do I enable upgrades on my firearm mod? I have the modelweaponparts in the item file but there is no upgrade option

bronze yoke
#

took a look at the mod myself - doesn't look like a masking issue to me, if i compare my game to the screenshot the clothing models are literally just smaller in the screenshot

drifting ore
#

With all the female clothes

undone crag
jade chasm
undone crag
#

maybe

#
local something1 = InventoryItemFactory.CreateItem(item_full_type) --makes a copy of the item so that you can get what weapons it can attach to. that's all the item copy is needed for here and it should disappear by itself soon.
local something2 = something1:getMountOn(); --gets the list of weapons it can attach to
local something3 = ScriptManager.instance:getItem(item_full_type) --gets the script item, which is the item template the game uses to create items from which you can edit

Then some more code to turn the list of weapons into a string and then add to the string and then apply the string back to the script item.

#

Do you know Lua or a coding language?

jade chasm
#

not really lol. I also don't know enough about the actual game structure itself to do much yet. kind of just putting together mods that are based on my interests in modelling and balancing items. I appreciate the help here!

#

would I throw this into the lua/items folder then yeah? or can I just throw this into the item file?

jade chasm
undone crag
#

This might work for that.

local function something()
    local attachment_full_type_array = {"base.hey", "base.hail", "base.hello"}
    for i,attachment_full_type in pairs(attachment_full_type_array) do
        local something1 = InventoryItemFactory.CreateItem(attachment_full_type)
        local something2 = something1:getMountOn();
        local something3 = ScriptManager.instance:getItem(attachment_full_type)
        local something4 = "MountOn ="
        for j = 1,something2:size() do
            something4 = something4 .. " " .. mountOn:get(j-1) .. ";"
        end
        newString = newString .. " someMod.AK47;"
        something3:DoParam(newString)
    end
end
Events.OnGameBoot.Add(something)

Except you have to list each attachment in attachment_full_type_array instead of things like hello. This should go in a lua file. media\lua\client should be fine.

#

Also, farewell.

manic barn
#

i was wondering if anyone knew which mods these are related to?

bronze yoke
#

the OS- ones are from more occupations

empty cove
#

how do one create a horizontal scrolling panel?
i tried using double ISPanel for scroll frame + content but it didn't work plus rendering content outside of frame's width

#

first row is the scroll panel while the other is using vanilla grid

#

do i need to write new ui components using stencil rect?

vivid imp
#

Anyone knows what´s the proper encoding of the translation txt files for russian?

hearty dew
#
$ file ProjectZomboid/media/lua/shared/Translate/RU/*
ProjectZomboid/media/lua/shared/Translate/RU/Challenge_RU.txt:         ISO-8859 text, with very long lines (446), with CRLF line terminators
ProjectZomboid/media/lua/shared/Translate/RU/ContextMenu_RU.txt:       ISO-8859 text, with CRLF line terminators
ProjectZomboid/media/lua/shared/Translate/RU/DynamicRadio_RU.txt:      ISO-8859 text, with CRLF line terminators
ProjectZomboid/media/lua/shared/Translate/RU/EvolvedRecipeName_RU.txt: ISO-8859 text, with CRLF line terminators
ProjectZomboid/media/lua/shared/Translate/RU/Farming_RU.txt:           ISO-8859 text, with CRLF line terminators
ProjectZomboid/media/lua/shared/Translate/RU/GameSound_RU.txt:         ISO-8859 text, with CRLF line terminators
ProjectZomboid/media/lua/shared/Translate/RU/IG_UI_RU.txt:             ISO-8859 text, with very long lines (487), with CRLF line terminators
ProjectZomboid/media/lua/shared/Translate/RU/ItemName_RU.txt:          ISO-8859 text, with CRLF line terminators
#

The vanilla russian translation files are ISO-8859 it seems

#
$ cat ProjectZomboid/media/lua/shared/Translate/RU/language.txt
VERSION = 1,
text = Russian,
charset = Cp1251,
#

CP 1251 is also known as Windows Cyrillic.

vivid imp
#

I don't know how to change the encoding, tried a lot of encodings, but I get some gibberish every time
Not sure if it is VSCode

ancient grail
#

I have a mod idea but its beyond my ability to mod..
To be able to build containers with distrib
So that items spawns

#

Watch daddy dirks youtube tutorial. Thats where i learned

fast galleon
#

@thick karma
is it ok to pm you with question about controller support?

#

could you make a guide with best practices for controleers

#

I am adding some context options and cursor.

hearty dew
#
-- client-side
local function clientSideFunc(task)
  -- ...
  task.yield()
  -- ...
  task.wait(500)
  return 2
end

local function fn(task, player)
  local result = task.awaitFunction(clientSideFunc)
  print(result) -- => 2

  local remoteResult = task.awaitRemoteCommand("MyModule", "myCommand", 5, player)
  print(remoteResult) -- => 100
  -- etc
end

local task = createTask(fn).start(currentPlayer)
-- Do some other things ...
-- server-side
function MyModule.myCommand(task, arg, player)
  for _, p in pairs(getNearbyPlayers(player)) do
    task.awaitRemoteCommand("MyModule", "otherCommand", "arg", p)
  end
  print(arg) -- => 5
  return 100
end

@thick karma @astral dune Would something like that make sense / be useful? If so, any ideas to improve it?

I can't really think of contexts in pz modding where awaitFunction would be useful?

vast nacelle
#

Maybe useful as a generic utility when an action being done affects another player until the action is complete.
I certainly wouldn't mind an awaitFunction used to decorate Medical Check to hold the stupid patient in place while administering medical care... 😒
The await could also act as a timeout in the case of something happening to the person doing the action (e.g. actor getting Thanos snapped) without needing the actor to notify the awaiting player that whatever they were awaiting was disrupted for whatever reason.
So something like Await("MyModule", "DoThisUntil", "untilArgs", "ThisIsCalled", timeout)

blissful salmon
#

I'm looking for a way to play a directional sound only hearable by the local player and not the others. Does anybody has an idea? I'm currently playing around with the SoundEmitter stuff. But no luck so far.

ancient grail
#

You just have to create left and right panned audio tho

#

I think theres a way to play UI audio

blissful salmon
ancient grail
#

Idk man. Its just an idea of where u might find leads hopefuly it helps

blissful salmon
#

ok, thx... I check if I can find something.

thick karma
grim rose
#

applyMedication = function ()
player:getBodyDamage():seColdStrength(player:getBodyDamage():getColdStrength() - 20);
player:Say("I feel bit better")
end

#

anyone have idea why it doesn't work

#

player:getBodyDamage():seColdStrength(player:getBodyDamage():getColdStrength() - 20); this part gets error in debug

thick karma
grim rose
#

thanks

vast nacelle
#

np

grim rose
#

after i fix it my character does not get lowered cold sickness nor says "i feel bit better"

#

yet the script happens

frosty estuary
#

Hi. I'm trying to increase some melee damage on zombie. Right now using the OnWeaponHitCharacter(player, target, weapon, damage) envent to get the damage and reduce some extra damage from target health via target:setHealth(target:getHealth() - damage/2). But what happens is, for example:

Just debuging to see what happens, the given damage by the event is 1.7. But when I log the target health before and after the attack the health reduces only 0.250 for example (I think this is because this damage it's not the final damage that is reduced from the zombie health, several multiplier occurs after the event)
Is there a way I can get this final damage, the one that is actually reduced from zombie health? Or right now, this event is the only way?

ancient grail
#

finally was able to remove items on the ground

local inv = getPlayer():getInventory() 
local sq = getPlayer():getSquare() 
  for i=0, sq:getObjects():size()-1 do
 if instanceof(sq:getObjects():get(i), "IsoWorldInventoryObject") then
local item = sq:getObjects():get(i)
sq:transmitRemoveItemFromSquare(item);
item:removeFromWorld()
item:removeFromSquare()
end
end
ISInventoryPage.renderDirty = true;
ISInventoryPage.dirtyUI();
inv:setDrawDirty(true);

but its not yet a perfect script it throws error and sometimes it doesnt delete all
can someone ppls help improve the snippet

ancient grail
#
local zombie = square:getZombie()
if zombie then
zombie:Kill(playerObj)
frosty estuary
ancient grail
#

ah iwouldnt know,,.. havent tried it

frosty estuary
#

And because this damage the event give me looks like it's not the final one, if I use the way I said, the increase will be much higher than the 50% I want....

vast nacelle
# ancient grail finally was able to remove items on the ground ```lua local inv = getPlayer():ge...

I think it throws an error because "sq:getObjects():size()-1" is the size of the list before you altered it by removing items. So 'i' increments against a list that is no longer the same size, eventually calling for an item out of the bounds of the item list.
Maybe try "local item = sq:getObjects():get(0)" so you are always getting whatever is at the top of the list "sq:getObjects():size()-1" times.

ancient grail
tardy wren
#

Ive also seen that for iterating a shrinking list, you can start from the top, as in i=sq:getObjects():size()-1 and till i>0

vast nacelle
# ancient grail what you said is hard to digest for me... lol ill try

Say you have a list {A, B, C}
Size will tell you there are 3 items in there
So your for loop will run 3 times with i = 0 then 1 and then 2.
But you are removing items from the list each time.
So the first run would be list.Get(0) which is 'A'.
But after you remove 'A' from the list, the list is now {B, C} while the for loop will still run two more times with i continuing on to 1 and 2.
So the next loop will be list.Get(1) which is 'C' instead of the 'B' you expect.
And the third iteration of the for loop will ask for the third element of a list that only has { B } so it'll error out.

ancient grail
#

ahh3

#

so how do i use for key, value

#

instead

#

which @summer rune suggested

thick karma
#

E.g., I use this:

-- Util
function showMeContents(someTable)
    for key, value in pairs(someTable) do print(key) end
end

To see the keys of those mysterious table objects that have fields that aren't documented in any obvious public way to my knowledge

ancient grail
#

ill try thnx

#
 for key, value in pairs(getPlayer():getSquare():getObjects()) do print(key) end



#

right?

#

i think its cuz of the table im trying to get the items from

#

getPlayer():getSquare():getObjects()

#

isnt really a container

thick karma
#

You wouldn't use pairs on getPlayer():getSquare():getObjects() afaik, because you're accessing Java methods and receiving Java objects when you make calls to getPlayer() and its methods

#

You want the items on a specific square?

thick karma
#

Actually, wait, your goal is to remove all of the items in a single square? @ancient grail

#

Can you clarify?

ancient grail
#

yes

#

but the thing im looping from is the getObjects which also containes non worldinventoryitems

#

if instanceof(sq:getObjects():get(i), "IsoWorldInventoryObject")

#

so i had to do this

#

If theres an array for only worldinventoryobject on the tile the player is stepping on then thats the solution

kind fossil
#

Hello this is the mod Keep that Radio ON! Lite I would like to patch it so when you don't hold your talkie walkie, it would shut down the microphone so you can only listen to people talking in the talkie and only be able to talk on the talkie if you are holding it in your hands
Do you have an idea about what to do?

thick karma
#

Also, @ anyone who can answer this, how does split screen work for keyboard users in Zomboid? If someone is playing on keyboard, how does the game know which player pressed the key during keyboard events? I'm wondering if I fire a function on a key event that loops through until getNumActivePlayers, will it apply to all the local players whenever someone using a keyboard presses a key? (Not the desired effect... would prefer function to affect only the player who pressed the key.

#

The joypad stuff lets me get the calling player directly from self... That's super convenient. Stuff like OnPlayerMove also guarantees that I have the right player. But OnTick and OnKeyStartPressed and such seem dangerous

#

(for split screen)

#

Never mind, just saw Indie Stone confirm that lack of support for KBM splitscreen is a fundamental Windows issue afaik... so thankfully I can ignore that I hope.

ancient grail
#

I will when i get back to it. Thnx!

fast galleon
#

I've seen a lot of overwriting functionshere lately and remembered somebody was using the triggerevent command before / after certain function, instead of hooking/decorating. Can't remember where it was unfortunately.

#

Was thinking of updating some of my old code.

thick karma
#

What are you trying to update?

fast galleon
# thick karma What are you trying to update?

I know snake's modpack breaks my inventory transfer hook for example. I haven't checked what he does, but I thought I'd go back and update my hooks. I am going to rename the file for sure, not sure what else I'll do.

thick karma
#

I see. I am sure there are a variety of conflicts that can arise from attempting to hook / overwrite the same functions in different ways. When I overwrite, I am trying to make sure that I only reference globals that I have declared in my own class or locals of the overwrite function, and that seems to prevent my double-overwrite of JoypadControllerData.onPressButtonNoFocus from causing any problems (just an example of something I am currently double-overwriting without generating any errors / exceptions).

thick karma
#

Anyone know what causes a Type 5 or Type 12 error? Or are these still a total mystery, and we just disable the ones that seem necessary for our mods to work???

#

It seems to trigger intermittently during my respawn or immediately after respawning...

kind fossil
dusk sonnet
#

I'm familiarizing myself with Lua coming from C#. Looking at Distributions.lua specifically:

items = {
         "BandageDirty", 1,
         "BeerCanEmpty", 2,
}

How does this get parsed? From my current understanding, 1 isn't automatically associated with "BandageDirty", it's just a standalone value in the table.

kind fossil
ancient grail
kind fossil
#

crap :c

vast nacelle
dusk sonnet
thick karma
# kind fossil Hello this is the mod `Keep that Radio ON! Lite` I would like to patch it so whe...

At a glance, this sounds more difficult than just examining this file alone. The key code that was modded to make the walkie talkie work while unequipped appears to be this:

    --if self.deviceData and self.deviceType=="InventoryItem" then        -- conveniently turn off radio when unequiped to prevent accidental loss of power.
    --    self.deviceData:setIsTurnedOn(false); 
    --end   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!REMOVED to allow radio to remain turned on while not equipped in hand!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
kind fossil
#

Yes the command that is activated when you unequip the talkie is put in comment

thick karma
#

Unfortunately, as you can see, the code just decides whether to turn the radio on or off

#

It doesn't seem that there are separate states for "canHear" and "canTalk"

#

It's just on or off

kind fossil
#

we could replace self.deviceData:setIsTurnedOn(false); with the command to turn off microphone

kind fossil
thick karma
#

So the game may have some internal ability to set the mic on or off independently of the receiver, or it may not, but either way it does not seem to be in that file

kind fossil
#

D:

thick karma
#

The game could simply use the same variable

kind fossil
#

why is it always so complicated for VOIP BononairTriste

ancient grail
#

try item:setActivated()

thick karma
#

e.g. ```
if isOn
activateMic()
activateSound()
end

#

That would be one variable responsible for both

#

That said, there likely are unique functions

ancient grail
#

or that

thick karma
#

For activating the reception vs. speaking.

#

So you would have to go into the file that determines how the walkie talkie hears or talks and see when exactly those commands get sent, and how

#

I do not know where that is

#

I am speaking abstractly

kind fossil
#

So strange it's not part of that file that is defining walkies

#

yes yes

kind fossil
thick karma
#

Well I did not read every single line, but I searched that file for "equip", and only that one example showed up

#

So there is no obvious place where the equipped state of the walkie is being checked like that

#

Hmm

kind fossil
#

At least I would like to turn off the microphone when you unequip the talkie, if we have to turn back on the mic when getting it again in hands it's okay

#

and we have the line for unequip

thick karma
#

Hold on

#

Here we go

#

This is the breadcrumb so-to-speak @kind fossil :

function ISRadioWindow:createChildren()
    ISCollapsableWindow.createChildren(self);
    local th = self:titleBarHeight();

    --self:addModule(RWMSignal:new (0, 0, self.width, 0 ), "Signal", false);
    self:addModule(RWMGeneral:new (0, 0, self.width, 0), getText("IGUI_RadioGeneral"), true);
    self:addModule(RWMPower:new (0, 0, self.width, 0), getText("IGUI_RadioPower"), true);
    self:addModule(RWMGridPower:new (0, 0, self.width, 0), getText("IGUI_RadioPower"), true);
    self:addModule(RWMSignal:new (0, 0, self.width, 0), getText("IGUI_RadioSignal"), true);
    self:addModule(RWMVolume:new (0, 0, self.width, 0), getText("IGUI_RadioVolume"), true);
    self:addModule(RWMMicrophone:new (0, 0, self.width, 0), getText("IGUI_RadioMicrophone"), true);
    self:addModule(RWMMedia:new (0, 0, self.width, 0 ), getText("IGUI_RadioMedia"), true);
    self:addModule(RWMChannel:new (0, 0, self.width, 0 ), getText("IGUI_RadioChannel"), true);
    self:addModule(RWMChannelTV:new (0, 0, self.width, 0 ), getText("IGUI_RadioChannel"), true);

end```
#

It adds these children

#

One of which is RWMMicrophone

#

That keyword does not appear anywhere else in the file, so I'm guessing it's its own class in its own file somewhere else.

#

Okay, @kind fossil , looks like that RWMMicrophone has a mute state:

function RWMMicrophone:new (x, y, width, height)
    local o = RWMPanel:new(x, y, width, height);
    setmetatable(o, self)
    self.__index = self
    o.x = x;
    o.y = y;
    o.background = true;
    o.backgroundColor = {r=0, g=0, b=0, a=0.0};
    o.borderColor = {r=0.4, g=0.4, b=0.4, a=1};
    o.width = width;
    o.height = height;
    o.anchorLeft = true;
    o.anchorRight = false;
    o.anchorTop = true;
    o.anchorBottom = false;
    o.fontheight = getTextManager():MeasureStringY(UIFont.Small, "AbdfghijklpqtyZ")+2;
    o.muteState = false;
    return o
end
kind fossil
#

OH INSANE

#

that's so good

thick karma
#

This suggests that if you can access the RWMMicrophone object, you can just go:

mic.muteState = true

when the player puts away the walkie.

#

And that MAY work

#

IF that variable gets checked before the walkie listens to you

#

Yeah I assume that is getting checked... I dunno I'll look around

kind fossil
#

thank so much

#

i'll share that with my team thank you

thick karma
#

No

#

Looks like that's a no go

#

Because here

#
    if self.deviceData then
        self.muteState = self.deviceData:getMicIsMuted();
        if self.muteState then
            self.muteButton:setTitle(getText("IGUI_RadioUnmuteMic"));
        else
            self.muteButton:setTitle(getText("IGUI_RadioMuteMic"));
        end
    end
end```
#

It uses that variable internally and overwrites it with then result of getting the mic state from the device data

kind fossil
#

so we can't alter the variable?

thick karma
#

We can, sure, pointlessly

kind fossil
#

fck

thick karma
#

But it's calling this with the deviceData

kind fossil
#

so the mod can't be possible?

thick karma
#

Hope is not lost, just gotta keep thinking @kind fossil

#

So when you grab the deviceData object off the microphone as it does in setMuteButtonText() above when it says self.deviceData, you get that Java class back... sort of. You get access to it functions, at least. getMicIsMuted is a Java-side function that is clearly exposed to the Lua (or the Lua couldn't be calling it here)

#

deviceData will contain a function: setMicIsMuted​(boolean boolean1)

#

I'm like 99% sure that's the function you would need to call.

kind fossil
#

damn maybe we can find something

thick karma
#

so, it would basically be microphone.deviceData:setMicIsMuted(true) when you pocket it, or false when you retrieve it.

kind fossil
#

exactly

#

that's the concept

thick karma
#

How exactly to acquire microphone properly depends on where and how you hook it

#

At a glance, self.deviceData appears to be available in that first class you posted.

#

So perhaps, instead of the commented-out part here...

    --if self.deviceData and self.deviceType=="InventoryItem" then
    --    self.deviceData:setIsTurnedOn(false); -- Turns it off.
    --end 

try...

    if self.deviceData and self.deviceType=="InventoryItem" then
       self.deviceData:setMicIsMuted(true); -- Mutes it.
    end
#

Then wherever you find setIsTurnedOn when you pull it out, change it to setMicIsMuted(false) instead.

#

You following?

kind fossil
#

I'm sharing screenshots to the team but yeah i get it

thick karma
#

Cool, let me know if you can't figure it out from there, I feel like those are the keys

kind fossil
#

not a dev myself but studied IT for 2 years so I understand what it means

#

i think so

#

i'll try in solo

thick karma
#

Good luck!

kind fossil
#

thank you so much

thick karma
#

I'm not sure where setIsTurnedOn(true) actually happens, but honestly you might not even need to mod that, because I would imagine / hope that turning it on twice in a row is designed to be safe.

#

So if you just design it to stay on in your pocket, I'm guessing that's good

#

You could add a condition based on a Mod Option to either turn it off or just turn off the mic at the same entry point above @kind fossil

kind fossil
#

Yeah not bad

#

IT WORKED

#

OMG

blissful salmon
#

Can I cast nil to a IsoObject in lua? I want to call e method which takes 3 diffrent objects as the second parameter and I want to call the one with IsoObject and it should be null in java.

bronze yoke
gilded hawk
#

Is there any JS/React dev in here?
I'm looking for help with a small zomboid modding related PWA

tardy wren
#

Anyone know how I can get my hands on the enum Item.Type?

#

I need to compare against it(See if an item is of type food)

bronze yoke
#

i know i just did this but i forgot where u_u let me see if i can find it

tardy wren
#

oki

ruby urchin
blissful salmon
# blissful salmon Can I cast nil to a IsoObject in lua? I want to call e method which takes 3 diff...

I circumvented the problem by getting a square at the coordinates I have. To pass nil as an IsoObject (if possible) would still be the better solution. The code I'm using now is:

local soundEmitter = getWorld():getFreeEmitter(soundX, soundY, 0)
proxySoundSquare = getSquare(soundX, soundY, 0) -- Hack because I would like to pass the IsoObject nil parameter to playSoundImpl()
local soundId = soundEmitter:playSoundImpl("ZombieDemonScream", proxySoundSquare)
soundEmitter:setVolume(soundId, 0.90)

Passing the square overwrite the exact coordinates I pass when getting the FreeEmitter.

bronze yoke
#

couldn't find it, maybe i misremembered, but i did something similar, see if just ItemType.Clothing (or whatever) is exposed, and if not try ItemType:valueOf('Clothing')

tardy wren
#

oh, so ItemType, and not Item.Type

#

Nope, ItemType.valueOf doesn't work

bronze yoke
#

could you not just do instanceof(item, 'Food')?

tardy wren
bronze yoke
#

instanceof

tardy wren
#

like, just a function call instanceof?

#

It doesn't seem to work for me

bronze yoke
#

as part of an if statement i mean

tardy wren
#

Okay..

It seems I broke something else, hold upo

#

Right, fixed it

tardy wren
#

All my items are a food, but they failed the check

#

Wait no

#

I can't

#

I'm operating on Items, not InventoryItems

fast galleon
bronze yoke
tardy wren
#

That should work!

#

Shame I can't compare against an Enum, would be faster

ancient grail
thick karma
#

Cool!

astral dune
tardy wren
#

Is there a flag for running in debug mode?

bronze yoke
#

isDebugEnabled()

tardy wren
#

I see... How about for server admins trying to bugfix their online lists?

bronze yoke
#

what do you mean?

tardy wren
#

if the mod is ran on a server

#

can you run debug mode in multiplayer?

ancient grail
#

Yes

tardy wren
#

Ah, okay. I'll leave some debug mode logging then

#

Since I'm doing an autopatcher, wanna give people some way to check what gets caught

steep copper
#

hi, i try to create a mod on project zomboid, i wanna make possible to cook an existing item (here bucket of paint) and when it's cooked, its transformed in a new item (color pigments)

#

I don't really know how to do this

tardy wren
ancient grail
#

Yep u just have to put

if isDebugEnabled() then
print("somestuff")
end
tardy wren
#

Does anyone know if daysFresh equal to 1000000000 means that item doesn't have the property set at all and is therefore not perishable?

thick karma
#

Idk sorry... you could print it in-game and see if it's going down for a particular item

#

If it's going down I would imagine it eventually spoils?

tardy wren
#

Can I do that in admin tools or something?

thick karma
#

If you launch with -debug you could open your debug console, use your player object to get your inventory, use your inventory to grab an item, and print its daysFresh. That is an item property right?

#

I don't see it on the Java side so it might be a lua property that you'll have to go digging for.

#

Probably somewhere in an item's data.

bronze yoke
#

huh? it is on the java side

tardy wren
#

Item calss

thick karma
#

Ahaaaaa

#

@bronze yoke It's DaysFresh

tardy wren
#

not InventoryItem. Item

thick karma
#

Doh

bronze yoke
#

yeah if you're looking generally for something, if you type all lowercase it won't try to be case sensitive

tardy wren
thick karma
#

Both Lua and Java commands to a degree can be launched from the console

thick karma
#

tmk calling a Lua function that forwards straight into a Java function

#

So essentially you're calling the IsoPlayer (Java class's) Say method, which it inherits from other classes it extends.

tardy wren
#

oh god

thick karma
#

You could also write, yourUncle = "Nobody", and then bobIsYourUncle = function() yourUncle = "Bob" end, and then bobIsYourUncle(), and verify that Bob is in fact your uncle now with print(yourUncle)

#

That's all Lua

bronze yoke
#

the console basically just follows the same rules as .lua files

tardy wren
#

Great

thick karma
#

Exactly. It counts as its own little scope

tardy wren
#

I barely know Lua

thick karma
#

It remembers variables, functions, etc while you're in-game

weak sierra
#

LOG : General , 1666974611430> 564,894,782> [UdderlyVehicleRespawn] Running command "RemoveAndSpawnRandomVehicleSomewhere" for player "UdderlyEvelyn".
LOG : General , 1666974611430> 564,894,782> [UdderlyVehicleRespawn] Removing vehicle "Base.VAZ07" as 6999.47998046875, 7554.5 for player "UdderlyEvelyn" to spawn replacement.
LOG : General , 1666974611431> 564,894,783> UDDTST: Zone Specs: 5x3 at 10971, 9447 to 10976, 9450, center: 10973, 9448.
LOG : General , 1666974611431> 564,894,783> -----------------------------------------
STACK TRACE

Callframe at: getOrCreateGridSquare
function: SpawnVehicle -- file: UdderlyVehicleRespawn_Server.lua line # 54 | MOD: Udderly Vehicle Respawn Testing
function: SpawnRandomVehicleSomewhere -- file: UdderlyVehicleRespawn_Server.lua line # 93 | MOD: Udderly Vehicle Respawn Testing
function: RemoveAndSpawnRandomVehicleSomewhere -- file: UdderlyVehicleRespawn_Server.lua line # 120 | MOD: Udderly Vehicle Respawn Testing
function: Add -- file: UdderlyVehicleRespawn_Server.lua line # 83 | MOD: Udderly Vehicle Respawn Testing

ERROR: General , 1666974611432> 564,894,784> ExceptionLogger.logException> Exception thrown java.lang.IllegalArgumentException at NativeMethodAccessorImpl.invoke0 (Native Method).

#
function UdderlyVehicleRespawn.SpawnVehicle(vehicleToSpawn, spawnX, spawnY, spawnFacing, playerUsername)
    local squareToSpawnAt = getCell():getOrCreateGridSquare(spawnX, spawnY, 0)
    if squareToSpawnAt:getChunk() ~= nil then --It's loaded, try to spawn it now.
        if UdderlyVehicleRespawn.TestSquare(squareToSpawnAt) then --If it's not occupied, spawn vehicle.
            vehicleToSpawn = vehicleToSpawn or UdderlyVehicleRespawn.GetRandomVehicleScriptForSquare(squareToSpawnAt)
            print("[UdderlyVehicleRespawn] Spawning \""..vehicleToSpawn.."\" at "..spawnX..", "..spawnY.." for player \""..playerUsername.."\".")
            addVehicleDebug(vehicleToSpawn, spawnFacing, nil, squareToSpawnAt)
        else --It's occupied, try another recursively.
            local centerOfRandomZone = UdderlyVehicleRespawn.GetCenterOfZoneSomewhere()
            UdderlyVehicleRespawn.SpawnVehicle(nil, centerOfRandomZone.x, centerOfRandomZone.y, centerOfRandomZone.facing, playerUsername)
        end
    else --It's not loaded, throw it in the backlog.
        print("[UdderlyVehicleRespawn] Could not spawn vehicle at "..spawnX..", "..spawnY.." for player \""..playerUsername.."\" because the selected square had no chunk, adding to backlog for later.")
        UdderlyVehicleRespawn.AddVehicleSpawnToBacklog(vehicleToSpawn, spawnX, spawnY, playerUsername)
    end
end```
#

54 is the second line

tardy wren
#

oh no it's my boss

weak sierra
#

it's literally failing to get a grid square

#

ive never seen this fail

#

it can be unloaded and thus have nil chunk

#

but i've NEVER seen it just throw illegal argument exception

#

the only arguments are x, y, z

#

i dont see how it can be illegal with args of 10973, 9448, 0

#

esp when this same function operates fine when called from a different source

#

a nearly identical one

#
UdderlyVehicleRespawn.CommandHandlers["SpawnRandomVehicleSomewhere"] = function(player, args)        
    local centerOfZoneToSpawnIn = UdderlyVehicleRespawn.GetCenterOfZoneSomewhere()
    UdderlyVehicleRespawn.SpawnVehicle(centerOfZoneToSpawnIn.x, centerOfZoneToSpawnIn.y, centerOfZoneToSpawnIn.facing, player:getUsername())
end

UdderlyVehicleRespawn.CommandHandlers["SpawnVehicleSomewhere"] = function(player, args)
    local vehicleToSpawn = args["vehicleToSpawn"]
    local centerOfZoneToSpawnIn = UdderlyVehicleRespawn.GetCenterOfZoneSomewhere()
    UdderlyVehicleRespawn.SpawnVehicle(vehicleToSpawn, centerOfZoneToSpawnIn.x, centerOfZoneToSpawnIn.y, centerOfZoneToSpawnIn.facing, player:getUsername())
end```
#

only difference is it adds a specific vehicle script

#

i require help

#

please :|

#

spent hours last night

thick karma
# tardy wren I barely know Lua

FYI, you could also grab a single Lua table object and dump its keys (to see what can be accessed inside of it) with a function like this:

BS = {}

BS.reveal = function(someTable)
    for key, value in pairs(someTable) do print(key) end
end

I needed this to get at the details of your joypad's focus object (JoypadState.players[self.player+1].focus) and the contents of a table named items that I was retrieving from somewhere mysterious to me.

bronze yoke
weak sierra
#

oh thank god please

#

enlighten me to my fuckup

bronze yoke
#

the earlier one is passing x into vehicleToSpawn

weak sierra
#

i am blind to this

#

ohh

#

is the arg order wrong

#

looks

bronze yoke
#

yeah

#

vehicleToSpawn is the first argument

weak sierra
#

function UdderlyVehicleRespawn.SpawnVehicle(vehicleToSpawn, spawnX, spawnY, spawnFacing, playerUsername)

#

yeah

#

oh

#

thank you so much

#

hugs

#

i spent 4 hours last night

bronze yoke
#

of course ^u^

weak sierra
#

boutta cry that u figured it out so easy 😂

tardy wren
#

Eve, go to bed now

thick karma
#

Good eye @bronze yoke

weak sierra
#

no i gotta go have a daytime

tardy wren
#

no, sleep

weak sierra
#

i sacrificed today's sleep

#

in the name of modding

tardy wren
#

SLEEP

weak sierra
#

i sletop

#

from

#

3am to uh

#

8? 9?

#

idk

#

7?

thick karma
#

@weak sierra Omg so many nights recently trying to make these mods less of an embarrassment to my effort

weak sierra
#

whatever

#

im fine

#

the coffee will kick in

bronze yoke
#

yeah i've been getting like 5 hours recently, sleep sucks

thick karma
#

Sleep is stupid fuck sleep

weak sierra
#

same, ~3yo daughter + modding + just bad sleep out of the box

#

i want them magic future pills that replace sleep

thick karma
#

You should make a mod so we need less sleep! @weak sierra

weak sierra
#

if u find the hook to mod IRL u let me the fuck know

tardy wren
#

Then we can hook an existing mod

#

Now I have a problem...

weak sierra
#

wat is problem

thick karma
#

Yes, I have never heard of this "problem". What is this?

tardy wren
#

I know that some items define ReplaceOnRotten

weak sierra
#

problem is when "this is fine" dog

tardy wren
#

But some don't

thick karma
#

/russianaccent

weak sierra
#

check nil

tardy wren
#

I wanna check if the item has?

weak sierra
#

anything not exist will not error but return nil

#

due to nature of lua

#

and tables

tardy wren
#

so instead of the get function, I just try to access it directly?

weak sierra
#

something.x = nil is same as something {}

thick karma
#

if (item.ReplaceOnRotten) then youAreGood() end @tardy wren

weak sierra
#

then something.x

#

and no x

weak sierra
#

local x = something.x

tardy wren
#

Ah... I've been using the getFunctions

weak sierra
#

if x == nil then --[[do stuff]] end

tardy wren
#

and it failed on me because Item isn't a Food

weak sierra
#

wait r u talking about fields

buoyant sky
#

Is it currently not possible or just way to hard to add Custom Events like Annotated Houses?

weak sierra
#

uh

#

yeah for fields

#

get functions hould just return nil

#

usually

#

if not there

#

but u can use reflection to access field directly

#

if public

#

(reflection in here is limited)

tardy wren
#

okay this aint a field

#

it a method

weak sierra
#

methods can be nil

#

if u access them without calling them

#

they are variables that hold code basically

#

u can manipulate them same way aso ther variables

#

everything in lua is a table

#

exception being kahlua has userdata objects for java objects

#

which are.. kinda

#

half-tables

#

kahlua is the java<->lua implementation

thick karma
#

@tardy wren Are we talking about a Java object with a Java method or a Lua table with a Lua function?

tardy wren
#

Java Java

weak sierra
#

diakon is new and learning by thrusting self into modding

#

for context

#

he is helping with my server's modding, very appreciated

#

even small things taken off my plate cowHeart

tardy wren
weak sierra
#

my plate is a semi truck

thick karma
#

What class? @tardy wren zombie.scripting.objects.Item?

tardy wren
#
        local item = scriptManager:FindItem(recipe:getResult():getFullType())
        if item:getTypeString() == "Food" then
            --if isDebugEnabled() then
            --getDaysFresh seems to return 1000000000 for unspoilable items. Same for getDaysTotallyRotten 
            print("Jarred Food Adjusted: ",item)
            --end
            
        end
        
    end
#

For nuw just printing stuff

bronze yoke
#

yeah, for whatever reason, there's no replaceOnRotten field

tardy wren
#

there is ReplaceOnCooked

weak sierra
#

me tryna manage my plate

#

"it's ok it moves"

#

"there's still space on top"

bronze yoke
#

if item:getReplaceOnRotten() then probably works though

weak sierra
#

either u are using it wrong

#

or

#

they did something weird

#

sometimes things dont work like they should

tardy wren
#

I imagine because I'm calling on an Item

#

Whereas getReplaceOnRotten is a function in Food

weak sierra
#
   public String getReplaceOnRotten() {
      return this.replaceOnRotten;
   }```
#

this is the java

#

it's uh

#

simple

#

and no it's on item

#

there's no superclass

#

they just redundantly reuse it

#

like Thing on rimworld (he comes from rimworld modding)

tardy wren
#

okay maybe I screwed up in copying the text over again

#
29            print("Jarred Food Adjusted: ",item:getReplaceOnRotten())
#
STACK TRACE
-----------------------------------------
function: JarredFoodAdjuster.lua -- file: JarredFoodAdjuster.lua line # 29 | MOD: Jarred Food Spoilage Adjuster

ERROR: General     , 1666975740502> 254 499 348> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: Object tried to call nil in JarredFoodAdjuster.lua at KahluaUtil.fail line:82.
ERROR: General     , 1666975740502> 254 499 348> DebugLogStream.printException> Stack trace:
java.lang.RuntimeException: Object tried to call nil in JarredFoodAdjuster.lua
    at se.krka.kahlua.vm.KahluaUtil.fail(KahluaUtil.java:82)
    at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:973)
    at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163)
    at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980)
    at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1782)
    at se.krka.kahlua.integration.LuaCaller.pcall(LuaCaller.java:76)
    at se.krka.kahlua.integration.LuaCaller.protectedCall(LuaCaller.java:117)
    at zombie.Lua.LuaManager.RunLuaInternal(LuaManager.java:559)
    at zombie.Lua.LuaManager.RunLua(LuaManager.java:505)
    at zombie.Lua.LuaManager.RunLua(LuaManager.java:491)
    at zombie.Lua.LuaManager.LoadDirBase(LuaManager.java:334)
    at zombie.Lua.LuaManager.LoadDirBase(LuaManager.java:261)
    at zombie.network.GameServer.doMinimumInit(GameServer.java:1405)
    at zombie.network.GameServer.main(GameServer.java:684)
LOG  : General     , 1666975740506> 254 499 352> -----------------------------------------
STACK TRACE
-----------------------------------------
#
            --if isDebugEnabled() then
            --getDaysFresh seems to return 1000000000 for unspoilable items. Same for getDaysTotallyRotten 
            print("Jarred Food Adjusted: ",item:getReplaceOnRotten())
            --end
            
        end
``` Gonna try this?
#

They are all Foods

bronze yoke
#

yeah, the problem is diakon is operating on Items, and getReplaceOnRotten() is from Food, which extends InventoryItem

tardy wren
#

yeah

#

But Food seems to be an actual item in the inventory?

thick karma
#

I'm trying to figure out how to get a Food from that r.n. and failing @bronze yoke

tardy wren
#

There's no way to go from Item to Food

#

I can get the Item from Food

#

but not the opposite

bronze yoke
#

you could create an instance of the item and check for it there

thick karma
#

What about getDaysFresh()?

tardy wren
#

It's in Item

#

But I need to check for ReplaceOnRotten

#

Adjusting jarred foods

thick karma
#

You're getting an Item with FindItem.... did that call not work?

#

Ohhh

#

I see.

#

I thought you wanted days until rotten for some reason

tardy wren
#

Rugged Recipes has "fermenting" as its preparation, and I need to go down that tree

weak sierra
#

thank you albion, saved me many hours of blindly not seeing that mistake potentially

#

lol

#

Q: anyone know why i can't retrieve the field "public IsoDirections dir" from vehiclezone via reflection?

#
UdderlyVehicleRespawn.GetViaReflection(zone, "public IsoDirections dir")```
#
--Reflection Wrapper

UdderlyVehicleRespawn.ReflectionCache = {}

function UdderlyVehicleRespawn.GetField(obj, fieldString)
    local cachedValue = UdderlyVehicleRespawn.ReflectionCache[fieldString]
    if cachedValue == nil then
        local num = getNumClassFields(obj)
        local idx = nil
        local zones = nil
        for i=0, num-1 do
            local field = getClassField(obj, i)
            if tostring(field) == fieldString then
                UdderlyVehicleRespawn.ReflectionCache[fieldString] = field
            end
        end
    end
    return UdderlyVehicleRespawn.ReflectionCache[fieldString]
end

function UdderlyVehicleRespawn.GetViaReflection(obj, fieldString)
    return getClassFieldVal(obj, UdderlyVehicleRespawn.GetField(obj, fieldString))
end

--End Reflection Wrapper```
#

everyone has their own reflection wrapper to make it comfy lol

#

zone is filtered down to vehicle zones only

#

btw if anyone is unfamiliar with routine caching of things, take a look at how i use a table there to reduce repeated checks to a very fast keyed lookup

#

can make your mods much faster in some cases

tardy wren
#

Well, my thing hopefully runs only once on startup

#

hopefully

weak sierra
#

yeah if it's run-once it doesn't matter

#

depends on the case

#

tho if it adds significantly to loadtime u cud communicate the precalculated server data to the client in some cases

#

rather than recalculate it

#

again depends

tardy wren
#

EVe

#

I'm trying to find what a jar of pickes rots into

weak sierra
#

Jar of Pickles (Rotten) is usually a good bet

#

and it might be the same item

#

just with a different name display calculated

tardy wren
#

no, it's a separate item

weak sierra
#

ur sure?

tardy wren
#
    item JarredPicklesUnready
    {
        DisplayCategory     = Food,
        Type                = Food,
        DisplayName            = Jar of Brining Pickles,
        Weight                = 2,
        Icon                = JarOfPickles,
        DaysFresh            = 0,
        DaysTotallyRotten    = 7,
        StaticModel         = CanClosed,
        WorldStaticModel     = JarFoodLeeks_Ground,
        ReplaceOnRotten     = RuggedRecipes.JarredPicklesReady,
    }
#

Pretty sure

weak sierra
#

that's unready

tardy wren
#

yes

weak sierra
#

meaning prior to being ready

#

not rotten

tardy wren
#

that's what is crafter

weak sierra
#

ok so this one rots into the ready

tardy wren
#

yes

weak sierra
#

which means u wanna ignore this one

#

and edit the ready version

#

or u just lengthen the fermentation time

tardy wren
#

yes

weak sierra
#

yeh

tardy wren
#

But I need to get the ready version

weak sierra
#

so.. read from ReplaceOnRotten

tardy wren
#

I grab by being crafted from a jar and a lid

#

Okay

#

Let's see

weak sierra
#

i assume opening the jars returns jars?

tardy wren
#

yes

weak sierra
#

so

#

u can test for that on the way out

#

this progressively gets messier

tardy wren
#

yes

weak sierra
#

i would still suggest reverting to a simple "put in item ids for those u wish to up the stat on"

tardy wren
#

because that's two passes on the recipes

weak sierra
#

or one pass with two heuristics and separate lists

#

and then correlation

tardy wren
weak sierra
#

sunk cost fallacy

#

u spent another whole day when u cudda retooled last night

#

but

#

:p

tardy wren
weak sierra
#

that can't be normal

#

are u reading from the item or the recipe

tardy wren
#

From the item

#

print("Jarred Food Adjusted: ",item, item.ReplaceOnRotten)

weak sierra
#

Item or InventoryItem

tardy wren
#

Item

weak sierra
#

f

#

that shud be right

#

oh

tardy wren
#

I can't get InventoryItem from Item

weak sierra
#

ur doing dot syntax

tardy wren
#

...?

#

:?

weak sierra
#

that may or may not work

#

use the getter

#

but

#

u alrady triedd that

#

didnt u

tardy wren
#

yes

#

that's what falls me

#

there is a getter for the replaceoncooked in Item

#

which returns a list of strings

bronze yoke
#

if InventoryItemFactory is exposed, you could use InventoryItemFactory:CreateItem() and then use the getter

tardy wren
tardy wren
#

And not the specific instance of the item I created?

bronze yoke
#

you can then use :DoParam() on the script to change the script, you just need the instance to actually get the value

#

oh there's actually an InstanceItem() on Item

#

it takes a string though, idk what that's expecting

tardy wren
#

O_O

#

@weak sierra can ya take a peek?

bronze yoke
#

just read through it, var1 is optional

tardy wren
#

Oh, okay

#

Hmm...

bronze yoke
#

idk what it does but every use of it first checks if there even is one

thick karma
#

I don't know what good those will do you but you can inspect if you want

tardy wren
#

Thanks

bronze yoke
#

oh i think it might be to do with items that have multiple colour variations

tardy wren
#

ah, okay

thick karma
#

Looks like you can instantiate a Food() with an Item() but I don't know about doing that from Lua

bronze yoke
#

the string sets which variation to instantiate somehow

thick karma
#

Looks like the first 3 inputs needed for an InventoryItem are

this.module = var1;
this.name = var2;
this.type = var3;
bronze yoke
#

it might not be the best idea to post these full decompilations, as it does sort of break the tos

thick karma
#

Oh my bad.

#

Well uh grab em while they exist @tardy wren 😛

tardy wren
#

uhhh

#
STACK TRACE
-----------------------------------------
Callframe at: InstanceItem
function: JarredFoodAdjuster.lua -- file: JarredFoodAdjuster.lua line # 29 | MOD: Jarred Food Spoilage Adjuster

paź 28, 2022 7:17:48 PM zombie.Lua.LuaManager RunLuaInternal
SEVERE:  java.lang.RuntimeException
paź 28, 2022 7:17:48 PM zombie.Lua.LuaManager RunLuaInternal
SEVERE: java.lang.RuntimeException: 
paź 28, 2022 7:17:48 PM zombie.Lua.LuaManager RunLuaInternal
SEVERE: at InstanceItem
at JarredFoodAdjuster.lua:29```
#

I don't think I can do this

bronze yoke
#

i've never seen an error like that 😟

tardy wren
#

the game just gave up on me lmao

#

do I go yell at teh devs to add me my getter?

bronze yoke
#

there might still be a way to do it, but yeah, it's strange that there isn't one, it might be an oversight

tardy wren
#

Eve mentioned going backwards

#

finding what items/recipes give me a jar

#

But yes, that is two loops

#

one through items, one through recipes

bronze yoke
#

ah, i see

#

you still need to pass an argument

tardy wren
#

oh

#

So just empty string?

bronze yoke
#

in my console, InstanceItem(nil) worked

#

but InstanceItem() didn't

tardy wren
#

My anger grows

bronze yoke
#

i guess the java is strict about how many arguments you give it

tardy wren
#

Sha,e it doesn't define a default

#

Okay, I can actually get the item from this

#

This is what I needed

#

LOG : General , 1666977912895> 256 669 409> Jarred Food Adjusted: Item{Module: KnoxCooking, Name:PineSyrupFerment, Type:Food} KnoxCooking.PineSyrupReady

#
            print("Jarred Food Adjusted: ",item,inventoryItem:getReplaceOnRotten())
#

albion you deserve a Zombiexivir

bronze yoke
#

let's gooo

tardy wren
#

yay

#

now... Do I futureproof by going recursive on this?

#

or into a loop like a sane person

#

As in someone makes several stages of fermentation

#

nah

#

wait, should I worry about cleaning up my trash?

bronze yoke
#

what do you mean?

tardy wren
#

my variables

#

memory cleaning

#

more importantly

#

I fucked up

bronze yoke
#

as long as they're locals, the memory will be freed when the code leaves its scope

tardy wren
#

Ah

#

I wrote them local in the... uhh...

#

Global?

#

tldr, when my file ceases to execute, it will clean up?

#
print("HEREBEITEMS")
local scriptManager = ScriptManager.instance
local recipes = scriptManager:getAllRecipes()
for i=0, recipes:size() - 1 do
    local recipe = recipes:get(i)
    local recipeSource = recipe:getSource()
    local foundAJar = false
    local foundALid = false
    for j=0, recipeSource:size()-1 do
        if recipe:getCategory() ~= "Cooking" then
            break
        end
        local recipeItem = recipeSource:get(j):getItems()
        if recipeItem:contains("Base.EmptyJar") then
            foundAJar = true
        end
        if recipeItem:contains("Base.JarLid") then
            foundALid = true
        end
        if foundAJar and foundALid then
            break
        end
    end
    if foundAJar and foundALid then
        local item = scriptManager:FindItem(recipe:getResult():getFullType())
        if item:getTypeString() == "Food" then
            --if isDebugEnabled() then
            --getDaysFresh seems to return 1000000000 for unspoilable items. Same for getDaysTotallyRotten
            local rottenReplace = item:InstanceItem(nil):getReplaceOnRotten() --I need to do this to get ReplaceOnRotten, ugh    
            if rottenReplace ~= nil then
                item = scriptManager:FindItem(rottenReplace)
            end
            print("Jarred Food Adjusted: ",item)
            --end
            
        end
        
    end
end```
#

Like that's my code so far

bronze yoke
#

scriptManager and recipes won't, but there's a little workaround for that

tardy wren
#

put them in a function?

bronze yoke
#

if your code is only meant to run once you can just start it with do and end it with end and that makes it its own scope

tardy wren
#

ah, nice

#
Jarred Food Adjusted:     Item{Module: Base, Name:CannedTomato, Type:Food}
Jarred Food Adjusted:     Item{Module: Base, Name:CannedCarrots, Type:Food}
Jarred Food Adjusted:     Item{Module: Base, Name:CannedPotato, Type:Food}
Jarred Food Adjusted:     Item{Module: Base, Name:CannedEggplant, Type:Food}
Jarred Food Adjusted:     Item{Module: Base, Name:CannedLeek, Type:Food}
Jarred Food Adjusted:     Item{Module: Base, Name:CannedRedRadish, Type:Food}
Jarred Food Adjusted:     Item{Module: Base, Name:CannedBellPepper, Type:Food}
Jarred Food Adjusted:     Item{Module: Base, Name:CannedCabbage, Type:Food}
Jarred Food Adjusted:     Item{Module: Base, Name:CannedBroccoli, Type:Food}
Jarred Food Adjusted:     Item{Module: SapphCooking, Name:CannedEggs, Type:Food}
Jarred Food Adjusted:     Item{Module: KnoxCooking, Name:PineSyrupReady, Type:Food}
Jarred Food Adjusted:     Item{Module: KnoxCooking, Name:AcornFlourLeached, Type:Food}
Jarred Food Adjusted:     Item{Module: RuggedRecipes, Name:ReadyBerryWine, Type:Food}
Jarred Food Adjusted:     Item{Module: RuggedRecipes, Name:ReadyKvass, Type:Food}
Jarred Food Adjusted:     Item{Module: RuggedRecipes, Name:FermentedKentuckyKimchi, Type:Food}
Jarred Food Adjusted:     Item{Module: RuggedRecipes, Name:CannedCucumber, Type:Food}
Jarred Food Adjusted:     Item{Module: RuggedRecipes, Name:JarredPicklesReady, Type:Food}
Jarred Food Adjusted:     Item{Module: RuggedRecipes, Name:JarredSauerkrautReady, Type:Food}
#

I got my items

#

Now to multiply their values properly

#

Here's the third hard part

thick karma
thick karma
#

Nice one

bronze yoke
#

😇

tardy wren
#

It creates an instance of the item... Which I can scrape for its values I need

#

Then got back to Item

#

I was looking for a way to create the InventoryItem from the item but I just couldn't find any

#

okay, now for something simple

thick karma
tardy wren
#

How can I round to the nearest whole number?

bronze yoke
#

math.floor() rounds down, math.ceil() rounds up

tardy wren
#

no math.round()?

#

I'll be generous then

bronze yoke
#

a way to do this is to do math.floor(num + 0.5)

tardy wren
thick karma
#

Would Lua let you add a function to math? @bronze yoke

math.round = function(num)
  return math.floor(num + 0.5)
end
``` @tardy wren
bronze yoke
#

i don't see why it wouldn't, but it's probably not good practice

thick karma
#

Booooooo 😉

tardy wren
#

I am now curious what happens if my mod pushes the days fresh above 1000000000

thick karma
#

I mean definitely you would be told not to do so in a lot of classes, but ultimately if it works, it works. And in general Lua doesn't seem to get mad when we overwrite other existing built-in libraries, right? I could name a variable math, right?

tardy wren
#

I don't need to

bronze yoke
#

yeah, my guess is that you absolutely could do that

#

but it's such a tiny shortcut

thick karma
#

Plus, doesn't math just deserve a round?

thick karma
bronze yoke
#

to be fair, math.ceil is just math.floor(num+1)... 🤔

thick karma
#

LOL really?

bronze yoke
#

well i don't know the code, but functionally

thick karma
#

I thought you meant they wrote it that way

bronze yoke
#

so putting a round in there is basically the same thing as having both of those functions in the first place

thick karma
#

I see

#

I mean, I value being succinct when I am writing something often.

hearty dew
tardy wren
#

you think math.floor works by casting to int?

bronze yoke
thick karma
#

Totally totally

#

that would be more polite

gilded hawk
#

Mx figured out that being hit by a car is more enjoyable than figuring out 3d audio 💯

thick karma
#

Just in case some other asshole like me wants to do something to math.round 🙂

bronze yoke
#
static int math_min (lua_State *L) {
  int n = lua_gettop(L);  /* number of arguments */
  lua_Number dmin = luaL_checknumber(L, 1);
  int i;
  for (i=2; i<=n; i++) {
    lua_Number d = luaL_checknumber(L, i);
    if (d < dmin)
      dmin = d;
  }
  lua_pushnumber(L, dmin);
  return 1;
}


static int math_max (lua_State *L) {
  int n = lua_gettop(L);  /* number of arguments */
  lua_Number dmax = luaL_checknumber(L, 1);
  int i;
  for (i=2; i<=n; i++) {
    lua_Number d = luaL_checknumber(L, i);
    if (d > dmax)
      dmax = d;
  }
  lua_pushnumber(L, dmax);
  return 1;
}

they don't work that way :(

gilded hawk
#

But I'm making a PWA to easily edit and preview the workshop.txt which is quite cool since today I'm stuck at home alone shrug

bronze yoke
#

oh that'd be super useful

thick karma
#

That would be nice a.f. @gilded hawk

tardy wren
#

PWA?

thick karma
#

So tired of duping description=

gilded hawk
hearty dew
thick karma
#

Well, that's okay, I'm addicted to sugar...

#

Wait.

thick karma
#

Is it okay?

gilded hawk
tardy wren
#

Yay, my mod seems to work

hearty dew
ancient grail
ancient grail
hearty dew
ancient grail
bronze yoke
tardy wren
#

Bruh I'm entering the game for the first time ever to test it lmao

bronze yoke
#

but no, it doesn't work that way anyway

tardy wren
#

I didn't even hook up the sanbox options yet

hearty dew
tardy wren
#

Oh hey I'm a sledgehammer now

bronze yoke
#

it's in c

ancient grail
#

ow where did my sledgehammer go? owell

hearty dew
#

@tardy wren re: how to enable debug mode server-side

tardy wren
thick karma
#

Alright... @bronze yoke ? Haha I need a whiz on this one... You found the last miracle solution I needed for the halo notes, maybe you'll solve this one. I need access to zombie.input.Mouse, which afaik is exposed to the Lua here:

#

If it's exposed to the Lua, I feel like the Lua must act on that object SOMEWHERE (or why bother?) but I just cannot for the life of me find a single reference to it.

hearty dew
#

Might check if it has a getInstance static method or static field

#

if so, you could do Mouse.instance or Mouse.getInstance()

#

if you have my inspect function, you can use that to see what's available, Burryaga.inspect(Mouse)

thick karma
hearty dew
#

I'd have to check the java code, but that's possible

thick karma
#

What's your inspect function do? I don't think I've seen that one.

bronze yoke
#

hold on i'm playing toontown lol

thick karma
#

Hey no stress, lol, if I modded in a hurry I'd have burst into flames years ago

bronze yoke
#

LOL true

thick karma
hearty dew
#
----------  table  ----------
table 0x148767608 {
    [class] => (userdata) class zombie.input.Mouse <
               .          <METATABLE> => table 0x789091424 {
               .                         .   [__index] => table 0x682936769  ** PRUNED. Max depth reached **
               .                         }
               >
    [getX] => function 0x1615348194
    [getY] => function 0x410340176
    [isButtonDownUICheck] => function 0x1932879786
    [isButtonDown] => function 0x2101433036
    [renderCursorTexture] => function 0x1596218327
    [getXA] => function 0x1832494248
    [getYA] => function 0x904496786
    [setCursorVisible] => function 0x1120495057
    [isCursorVisible] => function 0x1070490812
    [initCustomCursor] => function 0x535993097
    [isRightPressed] => function 0x1716933491
    [isLeftPressed] => function 0x1865962885
    [loadCursor] => function 0x597632858
    [getWheelState] => function 0x675203827
    [UIBlockButtonDown] => function 0x2082982220
    [isLeftDown] => function 0x1369325360
    [isLeftReleased] => function 0x190937006
    [isLeftUp] => function 0x1440111971
    [isMiddleDown] => function 0x393843516
    [isMiddlePressed] => function 0x926832988
    [isMiddleReleased] => function 0x929207314
    [isMiddleUp] => function 0x1354296024
    [isRightDown] => function 0x184771456
    [isRightReleased] => function 0x1320304389
    [isRightUp] => function 0x1834213573
    [setXY] => function 0x2057976221
    [update] => function 0x1780832811
    [poll] => function 0x892340861
    [bLeftDown] => true
    [bLeftWasDown] => false
    [bRightDown] => false
    [bRightWasDown] => false
    [bMiddleDown] => false
    [bMiddleWasDown] => false
    [m_buttonDownStates] => (userdata) [Z@471791d6
    [lastActivity] => (userdata) 1666983399932 <
                      .          <METATABLE> => table 0x1826238072 {
                      .                         .   [__index] => table 0x745457098  ** PRUNED. Max depth reached **
                      .                         }
                      >
    [wheelDelta] => (userdata) 0 <
                    .          <METATABLE> => table 0x431509976 {
                    .                         .   [__index] => table 0x1658513944  ** PRUNED. Max depth reached **
                    .                         }
                    >
    [UICaptured] => (userdata) [Z@5f4eb1d5
    [new] => function 0x97812323
}
bronze yoke
#

setCursorVisible 👀

thick karma
#

Wait

#

Is that during runtime?

bronze yoke
#

only one way to find out!

thick karma
#

Did you pass it a Mouse object?

#

How did you use that function

thick karma
#

haha

#

Mouse.instance was a no go @hearty dew

hearty dew
#

so no instance, no

thick karma
#

Is there a place to read the command console output log? I just dumped _G

bronze yoke
#

it probably just goes into console.txt, right?

thick karma
#

honestly idk I assumed that was for errors, checking now @bronze yoke

#

Ugh look how it taunts me

#

I wonder...

#

OMFG

#

Daaamn

#

It's ignoring me 😭

bronze yoke
#

i can't find any references at all in vanilla lua

thick karma
#

Mouse.setCursorVisible(false) just ignores me 😭

#

it exists and just says no 😭

#

No errors.

bronze yoke
#

probably because it's not grabbing any specific instance

thick karma
#

Fair but usually wouldn't that throw some kind of error? I thought Java doesn't like accessing instance methods statically...

#

Maybe it's in a pcall

#

Or whatever

#

And just failing and ignoring it

bronze yoke
#

the java seems to use it that way too...

thick karma
#

Damn you're right

#

Just searched it

#

ooooooof

#

Tyriiiiiiiiir lmfao

#

Ah shit I have been betrayed by Java again

#

Mouse.setCursorVisible(false), damn you! Mouse.setCursorVisible(false)!

hearty dew
#

If it's a function on Mouse, it is a static method (generally)

#

instance methods would be on the metatable (__classmetatables has references to those if you can't get an instance otherwise)

bronze yoke
#

i've got some bad news for you

thick karma
#

It knows the function exists but cannot use it

bronze yoke
#

the reason this isn't working is because setCursorVisible is set to true every frame

thick karma
#

Where?

bronze yoke
#

player update

thick karma
#

In Lua?

#

Or Java?

bronze yoke
#

java

thick karma
#

That might be okay

hearty dew
thick karma
#

I think that I AM calling it and it IS working

#

But what albion said is defeating the purpose

hollow flint
#

hello, do people here use capsid? I only get this error when using jdk 8

> Process 'command 'C:\Program Files\Eclipse Adoptium\jdk-8.0.345.1-hotspot\bin\java.exe'' finished with non-zero exit value 1
bronze yoke
#

sorry, it's not player update doing it, it's logic() in GameWindow

#

player update was something else

#

oh i did it

thick karma
bronze yoke
tardy wren
#

You know what I just realized

#

My script runs on game startup

thick karma
#

I just figured it out similarly lmfao @bronze yoke

tardy wren
#

I can't use Sandbox settings to customize it

thick karma
#

I cannot screenshot it because my cursor is gone and my controller stole focus lmao

bronze yoke
#

hehe i'm glad we worked that one out

thick karma
#

But I added my event to player update

#

because you told me it happened on player update

#

And it worked too

#

Omfg you're a genius

#

This is like the icing Dawn of the Zed

bronze yoke
#

every player update while you're aiming it sets cursor visible to false, so my guess is that the only way to hide the cursor is to hide it every frame

thick karma
#

I needed this so much you don't even know

tardy wren
#

Albion really is a jenuous

bronze yoke
#

hehe ^u^

tardy wren
#

Now, genius, help me solve my conundrum

#

How can I make my mod adjustable

thick karma
#

Omfg albion you hero

bronze yoke
#

put it on an event that happens after sandbox loads but before items are spawned, i think OnInitGlobalModData is a valid option

tardy wren
#

So I put all my code into a function, and I add that function into said event?

thick karma
#

I knew if it was possible y'all would get me there. Thanks for your input as well, @hearty dew , it helped a lot

bronze yoke
#

yeah!

tardy wren
#

Alright, thanks!

#

I guess that leaves hooking it up

tawdry solar
#

still having touble

thick karma
#

ALBIOOOOOOOOON

#

AHHHHHH

#

It's so amazing

#

DIE CURSOR!

#

AHHHH PROPER UI HIDING HAS ARRIVED

bronze yoke
#

hehe i'm glad you're happy with it

thick karma
#

Now I just need to resist the extreme urge to push this update right now without testing it 😭

bronze yoke
#

tbh i don't test nearly enough

tawdry solar
bronze yoke
#

shoutout to that time when i updated my literacy mod and accidentally made books completely unreadable; nobody even complained about it, i just happened to notice a week later

tawdry solar
#

ty

bronze yoke
#

i have an insanely huge update for this mod finished but i've been putting off writing the strings for it for like two months LOL

fast galleon
#

regarding reading, I want books that give multiplier to more levels but I don't know how to balance it.

thick karma
bronze yoke
#

well as long as you do the most basic testing that won't happen to you lol

tawdry solar
bronze yoke
#

oops yeah i did sort of imply that

tawdry solar
#

yeah

#

still geat mod

#

love the idea

#

is it like fast reader overtime

bronze yoke
#

yeah sorta, you can get a lot faster than that but the xp is pretty hard to get after a certain point

tawdry solar
#

ah sick

#

is it fixed?

bronze yoke
#

yeah it's working perfectly right now

tawdry solar
#

if so thats a good mod for my server

#

ah sick

bronze yoke
#

and of course it's super customisable so if you don't like the balance you can just change it lol

tawdry solar
#

oh sick

blissful salmon
#

I post the whole solution of my zombie sound stuff when I finished this part of mod.

tawdry solar
#

for a workshop id do i make a folder like this

tawdry solar
#

ill watch the vid to find out

thick karma
tawdry solar
#

huh?

thick karma
#

One sec

#

Explaining

tawdry solar
#

ty

thick karma
#

Check a workshop folder for another working mod and copy how it does its workshop info file, but leave out the id line entirely.

#

Then, when you upload your mod for the first time, Steam will edit that file and automatically assign you an id

tawdry solar
#

i dont understand

thick karma
tawdry solar
#

what

thick karma
#

Open that

tawdry solar
#

ok

blissful salmon
# gilded hawk Interesting

So far I calculate the direction of a zombie who is sreaming and make a near proxy square to play the sound.

thick karma
#

Change relevant info, and delete the id line

#

In workshop.txt it says id=2872643350

tawdry solar
#

???

#

wha

thick karma
#

Unzip the folder I just send you, and look at workshop.txt in the folder

#

Change title, description, tags

tawdry solar
#

i got smth similar to it

bronze yoke
#

the file structure looks like Zomboid/Workshop/ModName/Contents/mods/ModName/mod.info

thick karma
tawdry solar
bronze yoke
#

you've probably just been working in the mods folder right?

thick karma
#

Check the directory structure in my zip

thick karma
#

You need to move your mods folder into the directory structure that my zip uses

tawdry solar
thick karma
#

The setup of folders

tawdry solar
#

oh...

#

i just realised

thick karma
#

You need Mod Name > Contents > mods > everything you already have

tawdry solar
#

the base i used

thick karma
#

Yeah grab what's in mods

#

And put it in the mods I just mentioned

tawdry solar
#

ight

#

so i put my mods into your files?

thick karma
#

You'll see the pattern if you flip through the zip I sent

#

Just delete all my files.

#

Hold on

tawdry solar
#

apart from the workshop txt right

thick karma
#

What's your mod's name?

#

In your mods folder?

tawdry solar
#

stella atro

thick karma
#

Just put your files in the folders were in before.

tawdry solar
#

oh sick ty

thick karma
#

Edit your descriptions and notice where I set your name and mod id and such

#

Overwrite poster.png and preview.png or people will think you're making a mod about reading while you move

tawdry solar
#

tysm

thick karma
#

The .pngs you use have to be exactly the right size, btw

#

So be careful

tawdry solar
#

yeah

#

ight

thick karma
#

If you make them in Gimp and flatten them and export with default settings as .png, you should be good

#

But make sure you flatten

tawdry solar
#

alr

thick karma
#

I didn't once, image wound up slightly misformatted, and nobody could install my mod

#

Even though it was exactly the same resolution in 2D

bronze yoke
#

that was ridiculous

thick karma
#

So... make sure you flatten

tawdry solar
#

why do i need 2 dis lines

#

i need 1 at most

thick karma
#

2 description lines?

tawdry solar
#

can i delete this

thick karma
#

Yes

tawdry solar
#

ight

#

this alr?

thick karma
#

I was only pointing out that if you want to say things in, say, 2 or 3 paragraphs, you need more description= tags

tawdry solar
#

ty

thick karma
#

Yes

tawdry solar
#

what abt id

thick karma
#

Again, you do not add one

#

It adds it for you

tawdry solar
#

ah

#

alr

fast galleon
thick karma
#

Just upload your mod to Steam after you get your pictures sorted

thick karma
fast galleon
#

put it either later when uploading and it populates

#

when you got to upload there's a button put description

tawdry solar
#

i need to test it a bit how can i use it ingame?

fast galleon
#

or just format on steam and ignore the file

thick karma
#

Ohhhh

#

I see what you're saying

#

You're saying it's unnecessary to have the description in the workshop.txt

#

because game lets you write it

tawdry solar
thick karma
#

Yeah, I could just keep a separate text file and copy-paste my description into the box when I upload

fast galleon
#

there's 3 options
a) workshop.txt
b) before upload there's a button
c) steam

thick karma
fast galleon
#

b autopopulates the file

tawdry solar
#

before that

#

i just need to see it ingame

thick karma
#

to see it in game you turn the mod on in MODS in the main screen.... idk if I understand your question