#mod_development
1 messages · Page 27 of 1
yes exactly
the bottom function's commented code is working but it detects it within the player square, whereas ideally it should be detected within the right click square
I think the worldObjects function parameter contains the objects in the square the user clicked on? Just a hunch
I think this is the solution somehow but I am not able to comprehend how to put it to use correctly
lemme check
yes, the world objects are the object on the tile as tyrir says
you should be looping through that list instead
Returns an error, here's what print(worldobjects) prints, and here's the code
Events.OnFillWorldObjectContextMenu.Add(function(player, context, worldobjects)
local playerObj = getSpecificPlayer(player)
for i = 0, worldobjects:size() - 1 do
local object = worldobjects:get(i)
if instanceof(object, 'IsoGenerator') then
generator = object
end
end
if generator then
if generator:isActivated() then
local playerInv = playerObj:getInventory();
local option = context:addOption("Recharge Jumpstarter", worldobjects, BatteryJumpstarter.onJumpstarterRecharge, generator, player);
end
end
end)```
What error does it provide?
ArendamethUtils = ArendamethUtils or {}
ArendamethUtils.printR = function(t, depth)
if not depth then
depth = 1
end
local printR_cache={}
local function subPrintR(t, indent, depth)
if depth == 0 then
print (indent, 'max depth reached')
return
end
if (printR_cache[tostring(t)]) then
print(indent.."*"..tostring(t))
else
printR_cache[tostring(t)]=true
if (type(t)=="table") then
for pos,val in pairs(t) do
if (type(val)=="table") then
print(indent.."["..tostring(pos).."] => "..tostring(t).." {")
subPrintR(val,indent..string.rep(" ",string.len(tostring(pos))+8), depth - 1)
print(indent..string.rep(" ",string.len(tostring(pos))+6).."}")
elseif (type(val)=="string") then
print(indent.."["..tostring(pos)..'] => "'..val..'"')
else
print(indent.."["..tostring(pos).."] => "..tostring(val))
end
end
else
print(indent..tostring(t))
end
end
end
if (type(t)=="table") then
print(tostring(t).." {")
subPrintR(t," ", depth)
print("}")
else
subPrintR(t," ", depth)
end
print()
end```
```lua
ArendamethUtils.printR(worldObjects)```
As an aside, this might be a little more helpful in the future to you than just printing out the table address :)
(but since this is a java object, it might not be terribly useful in this scenario)
hmm I'll give this a go, thanks!
That screenshot doesn't contain the error message. I haven't used the debug UI much, so not sure exactly where it places the error. Perhaps clicking the Errors button up top? If not, the error message should appear in console.txt
I'm guessing size() is nil (i.e. it isn't actually a java enumerable)
oops sorry
there
Mm, that's just the callstack without the error message
honestly im not sure where to find the error message, Lua/Java are more confusing than I thought they'd be lol
I used to work mainly with Python so I am kinda new to how this works
But if the error is this, worldObjects maybe it is a normal lua table, and you just need to iterate over it like a lua table instead of a java enumerable
Yea, that's probably what your error is. I see in other lua source code it is just a lua table rather than a java enumerable. So try iterating over it like:
for _,worldObject in ipairs(worldObjects) do
-- use worldObject
end```
function ISWorldObjectContextMenu.getWorldObjectsInRadius(playerNum, screenX, screenY, squares, radius, worldObjects)```
Also I see this function which might be handy for what you are doing
i'll try that in a min
for _,worldObject in ipairs(worldObjects) do
local object = worldobjects:get(i)
if instanceof(object, 'IsoGenerator') then
generator = object
end
end
end```
is that correct?
No, don't need to get :get(). That's for calling into java to get objects from a java enumerable
for _,worldObject in ipairs(worldObjects) do
if instanceof(worldObject, 'IsoGenerator') then
generator = worldObject
end
end
end```
gonna give it a go, thanks so much!
Make sure the capitalization of worldObjects is right to match your function parameter. I might have capitalized the O on accident
Well it works, except that the option is now being shown whether i press on the generator or not
Events.OnFillWorldObjectContextMenu.Add(function(player, context, worldobjects)
ArendamethUtils.printR(worldobjects, 5)
Can you try printing out the worldobjects like that to see what you are iterating over?
Well, you have two IsoGenerators, it looks like 😅
that's weird, im sure i only have one spawned
lemme double check
yup definitely one
idk why its being printed twice
when I picked it up, it didn't print any generators at all
Not exactly sure why it is in the list twice. But as long as both are removed when the character removes it, I wouldn't be too concerned by that.
Otherwise, it detects when the generator exists correctly now?
Something's wrong with it, it detects the generator exists no matter where I click. I'll give it a recheck now
oki quick question
so, i was checking the source code of another mod
it does something similar
Does that printed out list of worldobjects change depending on whether the tile you click on has different objects? Or if your player moves around? I'd mess around with it a bit to see what changes, unless someone has more familiarity with how this list is populated
local generator
Events.OnPreFillWorldObjectContextMenu.Add(function(player, context, worldobjects)
local isSteamGen = _G.generator and (_G.generator:getModData().water or _G.generator:getSprite():getName():find('steamgenerator_01'))
if isSteamGen then
generator = _G.generator
_G.generator = nil
end
end)``` This is how the modder defined the generator. It's a custom object though. Can this be used to get the vanilla generator?
and yes, the list changes based on where I am standing
but somehow that is doesn't affect the context menu
ye it just keeps detecting it wherever i press
Has there been any other Prosthetic mods besides The Only Cure?
I don't think so. I don't see why it would be necessary to put the generator object into a global variable like that, and move it back and forth between the global variable and local variable. Not sure what the author was up to by doing that
hmm I'll try to fiddle around with it a bit more, although im not sure why the code is behaving like that
that ^
doRClick in ProjectZomboid/media/lua/server/ISObjectClickHandler.lua has the logic for creating the worldobjects list
the IsoGenerator probably fits two of those conditionals that insert the object into worldobjects
e.g. the first one, which checks if it is seen by the player, and I'm guessing also the thumpable check since IsoGenerator implements the thumpable interface
so that's probably why it is in the list twice
hmm still doesn't explain why it keeps showing wherever i click
Yea, I'm wondering if generators do that for any square they power? I'm unsure
this is what shows when i press any tile away from the generator
and that's when pressing on the generator tile itself
Oh, so that's as I'd expect. But the code is detecting a generator in the 1st case too?
You mean when I am clicking a tile that doesn't contain the generator?
Oh, make the generator variable local lol
yep
It needs to be local in the scope of the function that finds the generator. If you want to keep it local to the file scope, you can save it as such if you prefer as well
Can you paste the function? I can show what I mean
lemme upload to pastebin
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
require 'ISUI/ISWorldObjectContextMenu'
ISWorldObjectContextMenu.fetchSquares = {}
local BatteryJumpstarter = {}
--local generator = nil; -- I'd remove this. It isn't being used currently, and you should be able to pass it between functions as a parameter.```
```lua
Events.OnFillWorldObjectContextMenu.Add(function(player, context, worldobjects)
ArendamethUtils.printR(worldobjects, 5)
local playerObj = getSpecificPlayer(player)
-- Added a local variable generator that is set to nil so that if the loop finds a generator, it will be changed from nil to the object. Because it was in the file scope before, the value of the variable persisted between calls to this function
local generator = nil
for _,worldObject in ipairs(worldobjects) do
if instanceof(worldObject, 'IsoGenerator') then
generator = worldObject
end
end
--for i = 0, worldobjects:size() - 1 do
--local object = worldobjects:get(i)
--if instanceof(object, 'IsoGenerator') then
--generator = object
--end
--end
if generator then
if generator:isActivated() then
local playerInv = playerObj:getInventory();
local option = context:addOption("Recharge Jumpstarter", worldobjects, BatteryJumpstarter.onJumpstarterRecharge, generator, player);
end
end
end)```
Just out of curiosity: what exactly are you trying to achieve? Adding a new option to the right-click menu for a generator?
My guess is he has a jumpstarter inventory item that he wants to be able to charge using the generator. Then presumably use the jumpstarter on vehicle batteries?
oo i see what you mean now. So basically its better to declare the variable within the function if I have no use for it outside the function
Yes, that's exactly the whole idea of the mod
and that's what I am trying to achieve right now
aaand what you did just worked
wow
it now detects it only actually within the generator tile and not other tiles
Yea, generally it is better to limit the scope of variables to only where they are needed to avoid situations like this where a variable from a broader scope surprises you :)
Thank you so much for the time! Sorry for taking so much of it lol
never thought a variable mistake would be so problematic lol
ive spent upward of 5 hours before due to a single bracket or an improperly capitalized letter
particularly with scripts, but sometimes with lua, that is the nature of modding this
I'm missing something very basic I think. How do I get moddata to persist between reloads?
on what
a vehicle
yes
are you transmitting the moddata?
as far as I understand it, its only being handled on the server side, can you elaborate?
whenever you set moddata it has to be transmitted
with
transmitModData()
to force synchronization
there are a few objects that can't persist moddata though like items
so if I getModData(), add something to it, then transmitModData, it should work?
yes
in cases where you can't get the moddata to synchronize properly though there's also transmitFullObject (not sure of name)
something like that
more expensive but more likely to work if you encounter a scenario where you ever have trouble
void transmitCompleteItemToClients()
void transmitCompleteItemToServer()
void transmitModData()
void transmitUpdatedSpriteToClients()
void transmitUpdatedSpriteToClients(UdpConnection connection)
void transmitUpdatedSpriteToServer() ```
transmitting didn't seem to work, hmm
and ur sure it's being set/retrieved properly?
the code is painfully simple, just trying to get a proof of concept going
if data.touched == nil then
character:Say("New Vehicle", 0.0, 1.0, 1.0, UIFont.Small, 60.0, "radio")
data.touched = 1;
vehicle:transmitModData();
else
character:Say("Old Vehicle", 0.0, 1.0, 1.0, UIFont.Small, 60.0, "radio")
end```
looks like the vehicle respawn mod im working on lol
for vehicles u have to store the moddata on a part
not the vehicle itself
and it should be a part that is not able to be uninstalled
so u have to make assumptions and/or make a static list/mapping
is the engine a "part" in this context?
I'm only worried about vehicles that have engines so that's ok, trailers and stuff I can safely ignore
my goal is to flesh out the engines so they have actual parts, I find the "Spare Engine Parts" mechanic very boring
exactly
even if someone uses that mod that makes engines replaceable
it'd travel with the part
if you are doing stuff serverside, it should be automatically saved. and you should probably be doing that stuff serverside anyways so that any changes that are done also happen for other players
driving skill and moretraits expert driving will be pretty directly incompatible, but I'll deal with that when something works
whats the easiest way to get a hold of a reference to the engine part?
you just need to do the extra logic to transmit that info to clients when they need it
ya, when the ui comes into play I imagine I'll have to transmit something
yeah, depending on the application of the mod, its worth thinking about how to transmit info to minimize how often it happens, but that you are also doing it when the info is needed.
vehicle:getPartById("Engine")
for example in some stuff, where info is only visible when examined, I make the client send a command to the server, to transmit the info to the client for the UI, but some other stuff which visually changes, I had to transmit whenever the change happened to make sure it's immediately visible to the player
some objects can't save moddata tho, like vehicles and items, even though they have methods for it
you can store it there but it won't persist
ya, I noticed there wasn't a setModData(data) but there was a saveTable(data), but it didn't work, haha
should work on the parts though don't they?
yes that was what i told them to do
or maybe they don't. aren't they technically inventoryitems
when you say you can't store data on an item, how would you attach metadata to an item? Is there another way?
I wonder what type of object the vehicles are then
you store it in a table
keyed to the item id
you can store it on the player or in globalmoddata or elsewhere
like, globally? ah
BaseVehicle
I suppose I could do the same with the vehicles, they have an ID too. But it makes more sense to attach it to the engine if this works
almost all objects by default have a moddata, which you can get using :getModData()
not all things that support that support persisting it under the hood
its because most objects inherit from the isoobject class
the two things I need it to 😤
huh? inventoryitems definitely save their moddata
they do in MP, the clients just have their own moddata tmk
set it on the client -> transmit -> relog -> gone
maybe I need to investigate it more to verify, because I have alot of things using the moddata on inventoryitems, and they are working perfectly fine in MP
thats how the timetracker works, and that is definitely working in MP
there's a backpack attachment saving mod and it lead to items despawning because the moddata for them was removed on relog
there were two problems there
they were doing it in server instead of shared
and then the moddata wouldn't persist because it was on InventoryItem
so you could drop your backpack and put it back on
and it'd work
but if you drop it and relog and put it on
nope
where the code runs is just which folder its in, right?
pretty much
attaching this to the engine isn't working so far, maybe I'll try putting it in the shared folder
poke at the Valhalla Aegis mod
the engine part, whatever it is, doesn't have a transmitModData() method
it has a vehicle claiming system
and it stores the vehicle moddata on a "mule part"
which is whatever part is not removable that it finds from its list of such parts first
engine is the fallback
if it makes it thru the list that's the last entry
so presumably the engine should work
i expect so yes
I just need to figure out what I'm missing
had to find it through the dependencies of a mod made by a familiar sounding dev
your right, I was thinking about worldinventoryobject, which does inherit from isoobject
😂
whereas the inventoryitem just inherits from a java object
yeah it's a shame because storing arbitrary data on an inventoryitem would be super damn useful
same with vehicles
it's irritating to have to work around such straightforwardly expectable behavior not being there
that is really strange though. why on earth does it have all the moddata related functions, if it doesn't even function as moddata
wasn't the whole point of the moddata on all isoobjects so that people stopped using gametime for storing everything
anyone remember where they moved the workshop mod folders too? lol
Steam apps for workshop downloads
steam/steamapps/workshop/content/108600/
thats the one
The convo on persisting moddata serverside brings up a question I've had.. What are reasonable places to store client-side data specific to a user e.g. items the player marks in some manner in the context of a client-side mod, or modded UI configurations?
I'm serializing to json and storing in getModFileWriter(), but that seems odd to store it inside the mod's folder in some sense.
no
Mainly I like to think of anything a player could cheat with should be server sided, if you want players to share it, etc. 🙂
yea, I would agree with that
Was curious if the pz api provides something to save client side data though since that's what I'm working with atm
Honestly not sure, haven't tried yet
I think if you save it on the player object, that might persist, because I think that goes onto the player save rather than the world save. not sure though
well, looks like valhalla uses something called sendClientCommand to handle the actual saving of info, but I don't know where that goes. Looks like it may be a global function but I can't tell what it does
it's just clothing
that works to trigger a event from client to server side
yes. I was able to finally track down what was fired by that
in the end its the same function I've been trying to use BaseVehicle.transmitPartModData(part) but it hasn't been working, lol
Yeah, I did notice that you can make your own "creatures?" if you do the proper skeleton and animation transformations
the furry community is gonna be ecstatic
im guessing though that it doesn't work in MP though, since you can't make new isoplayers
or do you have some work around for that?
the dog i mean, i guess the animations still work if you wear them on your player
lmao, I hope finish this fast to starting to a hunting mod (of course if build 42 is not released first)
Not sure, never I tried create a IsoPlayer on MP, even this is my first time creatin a IsoPlayer
but first I will prioritize SP
yeah, that sort of thing has been a long dream for me to implement for the hydrocraft hunting, since it was still using old stuff from like b38 time.
but I unfortunately don't know much about animations and modelling
I need a lot of anims to create, like walk, turn and many variants
it looks really great tho!
and I think once NPCs come to vanilla you can probably use that work as I assume IS will add more infrastructure to let modders add creatures
I assume they will make a new generic object for the animals
I wonder if ita possible to make books function like radio stations where sentences pop up as your read the books.
Maybe grab descriptions for books in a database and apply them to the books
does anyone know why mods from workshop won t show on in game host server?
i added them in mods list
What do the modders here think about using character textures with resolution 512x512 instead of the default 256x256? Are there any down sides like unexpected graphic glitches or severe performance issues (assuming the game runs on an average pc)?
Is it possible for the server-side LUA to call the / commands such as /addxp etc? I see SendCommandToServer() used along these lines in the vanilla LUA but I get an exception when calling it from the server itself (I presume it's meant to run in the context of one of the connected clients, as all the examples are for client-side LUA?).
Id suggest looking in the skill books, i know when you try reading a skill book thats below your level your character keeps saying they already know it. Might be a good place to start
@drifting ore Hello there, I have a quick question. May I use your code as a inspiration and as a model to learn from while coding my own multiplayer mods (in the beginning copy some of your lines until I figure out how to use that style of coding for me own MP mods)
Any modders or people who have played the Cherbourg map.
Is there Like a way to get a map that u can view by pressing Your key bind to open the map. Instead of wondering around endlessly not knowing where you are or how close to the Edge of the map you are
you need to enable the minimap in the sandbox settings
There are also examples in the vanilla code where player:addXP is called on server side. One example is in recipecode.lua, function Recipe.OnCreate.RipClothing. On the first look, I don't see anything special which need to be done in addition but not 100% sure...
Thank you. I was wonder if it was possible to avoid calling the LUA methods themselves and just issuing the commands like an admin but to be fair it isn't that much different to make some custom implementations of my own.
I’ve done that but it doesn’t show up as any buildings around me. That’s why I am curious if there is a code or setting or something I can change to make that the game pulls out the Cherbourg map instead of locking you in the top left corner of the KY map
Is there a mod that updates weapon durability that is compatible with Britas?
can someone with my mods friend me pls
coavins weapon repair or something messes with weapon durability and has a brita patch
Anyone know where I can find where the range values for Shout/Whisper are set?
Also, does anyone know if a broken crafted spear has its own definition in Base? I saw in the Sandbox Options that there's a setting to remove items from the world after 24 hours and I want to add broken spears to that list so I don't have to waste time putting them in zombies.
would anyone have a detailed guide as to how to set up timed actions and put them in use -- including mechanic window timed actions which show progress inside the vehicle parts window and then show a success/failure flashing bar?
new to modding, do i need to learn lua and only then start learning modding?
depends on what ur doing and how much prior programming experience you have
java and python basics pretty much
u can probably pick up lua as you go if you're even vaguely competent at those
learn from others' mods as examples
aight thanx, but knowing it would be good i think
ofc
Hello! I am trying to set up a timed action
function BatteryJumpstarter.onJumpstarterRecharge(worldobjects, generator, player, item, remainingUses, fuel)
BatteryJumpstarter_GeneratorTimedAction:start()
--generator:setFuel(fuel-remainingUses)
--item:setUsedDelta(1)
end```
This is a function that is called on context option press, which starts a timed action
function BatteryJumpstarter_GeneratorTimedAction:start() -- Trigger when the action start
print("Action start");
self.character:faceThisObject(self.generator)
end```
this is the timed action function. For now, im trying to keep it simple, so I am trying to make the player face the generator
however the generator object is not being passed from the first function to the second. What exactly is it that I am doing wrnog?
I figured out i need to call the variables first. Here's edited code
function BatteryJumpstarter.onJumpstarterRecharge(worldobjects, generator, player, item, remainingUses, fuel)
ISTimedActionQueue.add(BatteryJumpstarter_GeneratorTimedAction:new(player, generator))
--generator:setFuel(fuel-remainingUses)
--item:setUsedDelta(1)
end```
```lua
function MyTimedAction:new(character, generator) -- What to call in you code
local o = {};
setmetatable(o, self);
self.__index = self;
o.character = character;
o.playerObj = getSpecificPlayer(character);
o.maxTime = 30; -- Time take by the action
if o.playerObj:isTimedActionInstant() then o.maxTime = 1; end
return o;
end```
```lua
function BatteryJumpstarter_GeneratorTimedAction:start() -- Trigger when the action start
print("Action start");
--print(self.playerObj);
self.playerObj:faceThisObject(self.generator);
end```
I am getting an error at if o.character:isTimedActionInstant() then o.maxTime = 1; end and not really sure why
Which mod ?
Fixed that as well, but i think I am starting the timed action incorrectly. Printing player on :start() returns nil
with the current code, in the replied message, the game throws hundreds of errors at me within seconds
Trying to make a professions mod using professions framework and I'm getting this error, any idea what could be causing it?
https://i.imgur.com/BNbms7U.png
Is it possible to add options to the ISWorldObjectContextMenu.createMenu context object? Any examples of mods that do this?
Can you get the error messages? They are in Zomboid/console.txt in your home directory, if you can't find them in the debug UI
function: tick -- file: ISTimedActionQueue.lua line # 75 | Vanilla
function: onTick -- file: ISTimedActionQueue.lua line # 188 | Vanilla
LOG : General , 1664190629518> Object tried to call nil in tick
ERROR: General , 1664190629518> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: Object tried to call nil in tick at KahluaUtil.fail line:82.
ERROR: General , 1664190629518> DebugLogStream.printException> Stack trace:
java.lang.RuntimeException: Object tried to call nil in tick
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.pcallvoid(KahluaThread.java:1812)
at se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:66)
at se.krka.kahlua.integration.LuaCaller.protectedCallVoid(LuaCaller.java:139)
at zombie.Lua.Event.trigger(Event.java:64)
at zombie.Lua.LuaEventManager.triggerEvent(LuaEventManager.java:92)
at zombie.gameStates.IngameState.updateInternal(IngameState.java:1664)
at zombie.gameStates.IngameState.update(IngameState.java:1373)
at zombie.gameStates.GameStateMachine.update(GameStateMachine.java:101)
at zombie.GameWindow.logic(GameWindow.java:297)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.GameWindow.frameStep(GameWindow.java:764)
at zombie.GameWindow.run_ez(GameWindow.java:680)
at zombie.GameWindow.mainThread(GameWindow.java:494)
at java.base/java.lang.Thread.run(Unknown Source)
LOG : General , 1664190629518> -----------------------------------------
STACK TRACE```
@signal frost Yes. This code from yesterday does that. Essentially, you need:
function myCallbackFunction(worldobjects, other, parameters, go, here)
-- do fancy stuff with parameters
end
function myEventHandler(player, context, worldobjects)
context:addOption("Option text", worldobjects, myCallbackFunction, other, parameters, go, here);
end
Events.OnFillWorldObjectContextMenu.Add(myEventHandler)```
My hunch from that error message is that ISTimedActionQueue.lua on line 75 is calling a function on your timed action object that doesn't exist. Can you check what ISTimedActionQueue.lua does on line 75 to check?
Missing tick function, I'm guessing from the error message?
function ISTimedActionQueue:tick()
local action = self.queue[1]
if action == nil then
self:clearQueue()
return
end
if not action.character:getCharacterActions():contains(action.action) then
print('bugged action, cleared queue ', action.Type or "???")
self:resetQueue()
return
end
if action.action:hasStalled() then
self:onCompleted(action)
return
end
end```
line 75 is
if not action.character:getCharacterActions():contains(action.action) then
Incredible, will I have access to all of the variables that belong to ISWorldObjectContextMenu?
The ones created in ISWorldObjectContextMenu.fetch?
Can you paste the error message? It should be in Zomboid/console.txt in your home directory
I copied my timed action code from here, maybe its outdated and missing a function? i am not sure
The only cure-- it is the one that I've seen so far that works for editing other-player's stats through HealthPanel.
It'd be even better if you could give me a quick rundown of the core of its functions that send the command to the other player-- but I assumed you wouldn't wanna be bothered with that, so its easier for me to ask for permission to grab the mod and do some work on it until I learn the right way to use those functions myself.
It gives your event handler player, context, and worldobjects as parameters.. Everything that's passed to triggerEvent near the end of ISWorldObjectContextMenu.createMenu. But the variables in fetch look to all be retrievable from those
So ISTimedActionQueue:tick calls two functions on that line, action.character:getCharacterActions():contains(action.action).
action is a variable to the current action object in the queue (presumably an instance of the one you are creating). What is the value of the character key in the instance of your timed action object you've created and added to the timed action queue?
If it is nil, that'd explain that error message
I think this is it?
Yea, that's a lua syntax error in PZRPS8Professions.lua near line 46
character is basically the player, passed from here
function BatteryJumpstarter.onJumpstarterRecharge(worldobjects, generator, player, item, remainingUses, fuel)
ISTimedActionQueue.add(BatteryJumpstarter_GeneratorTimedAction:new(player, generator))
--print(player);
--print(getSpecificPlayer(player));
--getSpecificPlayer(player):faceThisObject(generator);
--BatteryJumpstarter_GeneratorTimedAction:new(player, generator)
--BatteryJumpstarter_GeneratorTimedAction:start()
--generator:setFuel(fuel-remainingUses)
--item:setUsedDelta(1)
end```
Here's what print(player) and print(getSpecificPlayer(player)); return respectively
Missing a closing } perhaps
maybe lemme test it and i'll get back to you
For organisation of the code, i've placed the relevant functions from each file here
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
So throughout the vanilla lua source, sometimes they use the player number (an integer) as the value for player variables. Other times, they use the actual IsoPlayer object. It may be that in this instance the ISTimedActionQueue code expects character to be IsoPlayer, rather than the player id. It certainly can't be player id bc they call action.character:getCharacterActions() on it :)
Send me a dm of what you want to do and I will check later
To figure out what to do, I'd look at another ISTimedAction class or its usage to see what it does
ISTimedActionQueue.add(BatteryJumpstarter_GeneratorTimedAction:new(getSpecificPlayer(player), generator))
that should fix it, right?
Possibly. Let me see how other TimedActions function
I'll give it a go
ProjectZomboid/media/lua/client/ISUI/ISInventoryPaneContextMenu.lua: ISTimedActionQueue.add(ISDrinkFromBottle:new(getSpecificPlayer(player), waterContainer, useLeft * percentage));```
So, yea, looks like self.character is set to the IsoPlayer object in other ISTimedActions
okay ye that definitely fixed it, quick question tho. Is there a built-in function to make the player walk towards an object, in this instance, the generator?
I thought self.character:faceThisObject(self.generator); would do it but it actually makes him just face it
instead of walk towards it
Yea, there is one that other ISTimedActions related to windows uses
sec
Oh, I was thinking of this
if not luautils.walkAdjWindowOrDoor(_player, targetSquare, _window) then
which is probably not what you want, heh
there is a luautils.lua file with that. Possibly has something more appropriate
choosing "Turn Off" at the generator makes the character walk to it first before actually turning it off, I'll trying to find the source code of that
Is there a function in the game that behaves the way you want this action to function with how it walks the player to the target? If so, looking into what it does might be useful
yea, there ya go
for profession framework can you not have modded clothes or does that not matter
lua variables must start with a letter or _
That's probably the issue
Nm, this is table constructor syntax
the body location for those overalls is literally 010 so what should i do lol
like
it's worth a shot
okay so
ISWorldObjectContextMenu.onActivateGenerator = function(worldobjects, enable, generator, player)
local playerObj = getSpecificPlayer(player)
if luautils.walkAdj(playerObj, generator:getSquare()) then
ISTimedActionQueue.add(ISActivateGenerator:new(player, generator, enable, 30));
end
end```
I assume the luautils line is the pathfinding line
however i think that is not all. What is the "enable" and the "30"?
function ISActivateGenerator:new(character, generator, activate, time)
local o = {}
setmetatable(o, self)
self.__index = self
o.character = getSpecificPlayer(character);
o.activate = activate;
o.generator = generator;
o.stopOnWalk = true;
o.stopOnRun = true;
o.maxTime = time;
if o.character:isTimedActionInstant() then
o.maxTime = 1
end
return o;
end```
Is activate used anywhere in ISActivateGenerator? My guess is it is used to determine whether the player enables or disables the generator when using it, but just a guess from the name :p
ah yes that right
yea, it looks to be so. That's how the luautils.walkAdjWindowOrDoor functions, so I'd imagine it to be similar
I'll try setting it up in the same way
hmm that's weird, the game throws an error in the corner but doesn't show the debug menu, nor can I see any errors in the console
do i need to add some kind of a require line to use luautils?
Not likely. luautils.lua would loaded by the time those functions are called
They'd be loaded before "Click To Start" when the world loads
if luautils.walkAdj(playerObj, generator:getSquare()) then
ISTimedActionQueue.add(BatteryJumpstarter_GeneratorTimedAction:new(playerObj, generator))```
that's the only thing I added to the code lol
removing the if function gets rid of the error
adding it removes the context option in the first place
The little red error square pops up, but you see no errors in console.txt?
yea
👀
missing the closing end?
well there are errors but not related, lemme search throughly
... yes i was missing the end for the if 🤦♂️
why can't Lua be simple like python. No semicolons. No ends. just good indentation
sighs
yess that does the pathfinding
I think the rest should be relatively easy to set up. Thanks so much!
o.maxTime = 30; -- Time take by the action
how long is the 30
because that's obviously not seconds
Not sure. I don't see where maxTime is being used in lua. From what I do see where it is set, however, it looks like tenths of seconds (30 would be 3 seconds, I think?) and it is used to give an upper limit to how long an action takes e.g. if you have high skill the maxTime would be lowered
I see. that makes sense, thanks!
if i want to increase max weight from 22 to 25 what do i have to edit here, someone please help me
With what traits and strength do you have 22?
strong back in soto mod
it used to be 30 but the author changed it to 22
strong back only adds 2 iirc?
i want it to be 24 or 25
I'm trying to work out what you have that gets you to 22. Base is 8. strong back adds 2. Then there is some amount you get from strength level too
Anyhow, you could try setting the base to whatever you prefer after the end in that screenshot
you meant change 13->15 or any number, right?
end
player:setMaxWeightBase(player:getMaxWeightBase() + 3)
end
yea, can do that too
Maybe something else is setting the maxweightbase elsewhere, or you don't have "AliceSPack" mod activated?
Shouldn't have to restart, no
Oh, you'd have to reload the game, yes. But don't need to delete the world and recreate it.
Where do I add this line?
Why not ask creator of the mod?
Me for example lol
idk where and who is he
You using only SOTO?
ya
You need next strings
are you the author
Yes
Weight is very stupid . You need to change numbers in string after AlicePack == false
This is my first time editing mods for this game
Change line 268
nah
im not using lua
Hey, how do you do the artwork for textures for traits/occupations? Was curious bc I wanted to make a few traits myself
how do I stop a function when an if condition is true?
if condition then
return
end```
local sumDelta = 0
function BatteryJumpstarter_GeneratorTimedAction:update() -- Trigger every game update when the action is perform
local currentDelta = self.item:getUsedDelta()
self.item:setUsedDelta(currentDelta+0.02)
sumDelta = sumDelta+0.02
if sumDelta >= 0.2 then
sumDelta = 0
return
end
print("Action is update");
end```
like so?
yea
Thanks!
I just draw them by myself with hands. Nothing special.
You can use any graphic editor or even online ones
Where can I find a list of all PZ sounds to play? (alongside their previews, if possible)
ProjectZbomoid/media/sound it appears
thanks!
hmm I am trying to find a specific sound, specifically the one that plays when you fail to hotwire a vehicle. Can't find it within the files, any idea about its name?
could u guys help me? i am looking for two commands.
(1) how to spawn a zombie
(2) make that zombie (only that zombie) chase a player
function ISHotwireVehicle:start()
self.sound = self.character:getEmitter():playSound("VehicleHotwireStart")
end
That perhaps?
i believe the spawning the zed is easy but to chase a particular player idk..
Probably, I'll check in a minute. What does getEmitter() do? What's the difference between
self.character:getEmitter():playSound("VehicleHotwireStart")
and
self.character:playSound("VehicleHotwireStart")?
getSoundManager():PlayWorldSound("ZombieSurprisedPlayer", getPlayer():getSquare(), 0, 10, 10.0, false);
addSound(getPlayer(), getPlayer():getX(), getPlayer():getY(), getPlayer():getZ(), 350, 50);
this is what i use to activate the jumpscare
i believe you can just type this on the console and it will work
yea, I am just searching for the specific sound name, not the way to do it
appreciate it though
ow sorry
no worries 😄
VehicleHotwireStart is correct
VehicleHotwireFail
try this
GameSound_EngineStarted = "Engine Started",
GameSound_VehicleTireExplode = "Vehicle Tire Explode",
GameSound_VehicleTurnedOff = "Vehicle Turned Off",
GameSound_VehicleHotwireFail = "Vehicle Hotwire Fail",
GameSound_VehicleCrash = "Vehicle Crash",
GameSound_VehicleCrash1 = "Vehicle Crash 2",
GameSound_VehicleCrash2 = "Vehicle Crash 3",
GameSound_VehicleHitCharacter = "Vehicle Hit Character",
Anyone know where I can find where the range values for Shout/Whisper are set?
Also, does anyone know if a broken crafted spear has its own definition in Base? I saw in the Sandbox Options that there's a setting to remove items from the world after 24 hours and I want to add broken spears to that list so I don't have to waste time putting them in zombies.
No, it doesn't, and I don't think any of the vanilla items change their type/definition when broken.
Thanks Blair. Such a shame. 😦
Howdy partners, I wanted to make a mod that add cigars into the game, I did good so far, but I cant get models into the game I have icons instead of 3d object (I tried .fbx and .x files) but it doesn't work, I tried to import some vanilla meshes like Needle but it didn't worked out. Every thing seems to work properly except for the meshes, how do I import them? Is it a code issue or I missed some step? Here's mode structure
hey all
i need some advise
i am making my own zombie game and since i am 16 and i dont have the money to pay people to test my game i am going to ask here :))
what do you think of the stats of the first 2 weapons?
if you're looking for realism i think you probably should bump the crowbar weight up to 8, other than that, i don't really have comments on anything else
I've looked into the IsUninstallVehiclePart timed action, but I am not sure which part shows the flashing green/red bar when the user succeeds/fails in uninstalling the part, anyone got an idea?
zeds in the game will have health from 50-150 and the "armor" they wear will make a impect
I would trace which statements call ISVehicleMechanics:render() in media/lua/client/Vehicles/ISUI/ISVehicleMechanics.lua
I'll give that a go, thanks!
where can i find the maintenance perk name?
couldn't find it in Zomboid\media\lua\client\RadioCom\ISRadioInteractions.lua
is there a mod that will turn lights off during the day and back on at night? or a mod that adds a timer that can be placed on lights so they turn on and off at certain times?
i'm modifying hydrocraft a bit if anyone wants to know
Would be fun swinging it around and smashing zombies everywhere
It's not a bug, its a feature!
anyways, I am still facing issues with adding the flashing green/red bars that appear when player succeed/fail in uninstalling/installing a vehicle part. I tried to read the source code but couldn't make anything out of it. Would appreciate it if someone's got a better grip on this runs it down by me!
I am trying to do sth like
function BatteryJumpstarter_JumpstarterTimedAction:perform() -- Trigger when the action is complete
local chance = ZombRand(1,100) --Generate a random number between 1 and 100
self.item:Use()
if chance <= 75 then --Player succeeded in jumpstarting the battery
--Show a flashing green bar with "success"
self.part:getInventoryItem():setUsedDelta(0.05)
else: --player fails
--show a flashing red bar with "failure"
end
ISBaseTimedAction.perform(self);
end```
hey does anyone know how to open the vehicle models into blender or something?
Aren't vehicle models FBX files?
They appear as txt when I try using them
what was the path you went through to find them?
you can find vehicle.FBX files at steamapps\common\ProjectZomboid\media\models_X\vehicles
So, no one knows what's the issue there?
You need register the WorldStaticModel
In your case, should be something like this
module Base
{
model CigarBox_Ground
{
mesh = WorldItems/CigarBox_Ground,
scale = 1
}
}
WorldStaticModel = CigarBox_Ground
I did somethig like this actually
I copied the scale from another mod but should it replace meshes with icons if size is so small?
ahh i was looking in just models thnx!
Also your WorldStaticModel is named BoxofCigars, so you should have this on your item WorldStaticModel = BoxofCigars
Sheeeeeesh
you probably want to adjust the model size when exporting from blender
in export settings, make sure the size is adjusted accordingly
I took a cigaret pack as a reference, it seems it wasn't scaled)) I'll just adjust the scale parameter in code then. Is it ok or it has some downsides?
it worked ok*
oh that''s nice to hear
Does anyone know how can I fix this?
WARN : General , 1664220434410> ItemPickerJava.ExtractContainersFromLua> ignoring invalid ItemPicker item type "MxsQoLPack.AnarchistCookbook3"
Also what the hell this damn loot tables, why are my items always rolling low
They have the same roll chance as the other magazines
Oh, nifty. What displays the loot tables like that?
LootZed cheat for debug mode, and then right click on the container
I thought LootZed was for zombies only.
I am stupid I had a typo 😕
Oh! I just realised there's mod_support channel, i'll take it there
nvm, the mod_support is for reporting stuff about mods jeez
I'm getting confused here
Okay so, I'll post it here again. I keep getting this msg even though I have mod.info in the right place, and not sure what could be causing it
If anyone could help me out with this issue, then I'd really appreciate it, thank you in advance
Probably your file is a mod.info.txt
put your media and mod.info and poster inside another folder
the "mods" folder inside a workshop contents can have multiple mod folders inside it
Should be Workshop/VikingHoodie/Contents/mods/VikingHoodie/mod.info
Hello, I'm new here, I'm working on creating my first mod, I'm looking to modify the base first aid recipes so they also give a little bit of first aid experience. Would this be the recommended way of doing so:
module Base {
recipe Make Plantain Poultice
{
keep [Recipe.GetItemTypes.MortarPestle],
Plantain=5,
Result:PlantainCataplasm,
Time:60.0,
Category:Health,
OnGiveXP:Give1FirstAidXP
}
}
I also want to add a new attribute to the Player called immunity that will go up/down on a daily event, how would one go about adding new data to the Player?
hi guys
is it possible for a on create recipe to trigger another function?
function Recipe.OnCreate.repairGen(items, result, player)
repairPower()
end```
Hugely appreciate your help) Cheers
That's a mighty fine looking smoke there sir.
Does anyone know when IsoPlayer's getOnlineID() and getPing() methods are expected to return data other than "0"? This seemed fairly normal when I was testing in singleplayer but having moved to testing my code on a dedicated server it seems odd these aren't set. I've checked obtaining the data both at the client side and at the server side, and both return this.
I'll check it out shortly
It's possible I'm not truly seeing the server's information as my call is within a zone from Events.OnClientCommand so player is the player object dispatched from that event - just knowing when I'd expect it to be nonzero would be a useful starter for ten so I can debug.
yes that is fine
Ah that's great thank you... maybe it is entirely expected that I'm ID zero then, looking at that example... for some reason I thought this field would be the Steam ID or other external immutable property. So can I 100% disambiguate which player is which with :getOnlineID() then? (e.g. no two players will ever share the same number, even if offline?) (If no, is there any property that behaves this way, whether it be getPlayerNum() / getPlayerIndex() or even username?)
(Sorry for all the questions, there's a bit of guesswork involved in knowing exactly what each property/method actually describes!)
Id never will be a constat, I mean, every time a player enters, a new id is assigned IIRC there are a function that can find a specific steam user, but I can't confirm it
I don't have a source decompilated yet 😅
LOG : General , 1664223807142> EXITDEBUG: Core.quitToDesktop
LOG : General , 1664223807147> EXITDEBUG: GameWindow.exit 1
LOG : General , 1664223807152> EXITDEBUG: GameWindow.exit 2
LOG : General , 1664223807156> EXITDEBUG: GameWindow.exit 3
LOG : General , 1664223807161> EXITDEBUG: GameWindow.exit 4
LOG : General , 1664223807166> 1664223807166> znet: Java_zombie_core_znet_SteamUtils_n_1Shutdown
ERROR: General , 1664223807254> java.nio.file.NoSuchFileException: /lua/morefastkeys/saves
ERROR: General , 1664223807260> at jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.deleteFile(Unknown Source)
ERROR: General , 1664223807265> at jdk.zipfs/jdk.nio.zipfs.ZipPath.delete(Unknown Source)
ERROR: General , 1664223807270> at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.delete(Unknown Source)
ERROR: General , 1664223807275> at java.base/java.nio.file.Files.delete(Unknown Source)
ERROR: General , 1664223807280> at zombie.core.logger.ZipLogs.deleteDirectory(ZipLogs.java:305)
ERROR: General , 1664223807285> at zombie.core.logger.ZipLogs.addDirToZipLua(ZipLogs.java:264)
ERROR: General , 1664223807290> at zombie.core.logger.ZipLogs.addZipFile(ZipLogs.java:80)
ERROR: General , 1664223807294> at zombie.GameWindow.exit(GameWindow.java:941)
ERROR: General , 1664223807299> at zombie.GameWindow.run_ez(GameWindow.java:700)
ERROR: General , 1664223807303> at zombie.GameWindow.mainThread(GameWindow.java:494)
ERROR: General , 1664223807307> at java.base/java.lang.Thread.run(Unknown Source)
LOG : General , 1664223807350> GameThread exited.
LOG : General , 1664223807355> EXITDEBUG: GameWindow.exit 5
Why might this error be showing up when the pz application closes?
On the OnSave event, my mod used getFileWriter() to write to morefastkeys/saves/filename.json (which pz stores under ~/Zomboid/Lua), and that all works well and good. However, it seems that the pz routine in java that zips up old log files is also trying to access /lua/morefastkeys/saves, which is a different path. This error even shows if pz never loads any mods, just open pz with no mods and click Quit.
Ok. I'll try and get a few folks to log in to do some practical testing - so long as the IDs (or whichever field) are not re-used in the same game, that's the critical factor for me (i.e. one day I log in and have ID 2, and then the next day on the same server without reset I log in and have ID 3, causing my logic to attribute an action or event to the wrong player).
I didn't know that sendClientCommand just triggered an event 🤦♂️ no wonder nothing I was trying last night would work. Thanks for posting this
This looks like a bug that appears when there is a 2nd level directory inside ~/Zomboid/Lua. Doesn't even seem to matter what it is named nor whether the directory contains any files
Okay, so it works Tyrir, thanks! but now I have an issue of not seeing the hoodie I added (changed textures)
can't spawn it or anything so I must've done something wrong with the set up
jeez
it's my first time doing something like this
not really sure where's the problem though
function Recipe.GetItemTypes.WeldingMask(scriptItems)
scriptItems:addAll(getScriptManager():getItemsTag("WeldingMask"))
addExistingItemType(scriptItems, "WeldingMask")
end```
I wondering what this does exactly, is it adding weldingmask twice?
or is it assigning the tag of weldingmask to the item weldingmask
wait if I got this and I got hoodie, do I need to like ummm copy it and do it the same for hoodieup?
all of that is confusing to me
but I want to accomplish something with this
Are scripts such as recipes reloaded at all?
I know lua can be reloaded when you encounter an error to allow you to fix it, but I'm having issues related to my recipe that cause a crash
look, idk where it came from
but uh ur question
yes
diff <files></files> for each one
since that might not be obvious by the naming being plural
why does the nvg mod not work
yup done
though, not sure what I've done
each of the XML files it points to
oh
same GUID?
well two different GUIDs
as the one in the file list
most likely cuz of java.nio.file.NoSuchFileException: /lua/morefastkeys/saves
something's crashing
but i'm not sure what
like something's crashing my zomboid i'm trying to look inside the scripts and all that
Yea, seems to be a bug. Some code in java-land is prepending / to the path when trying to zip up the ~/Zomboid/Lua directory when the application is closing
one of those sussy bakas
is doing it, zomboid crashes when it loads scripts
oh wait I see one issue
Down changed to DOWN
looks like it gets all items existing in the PZ scriptmanager with the tag "WeldingMask" and adds them to the inputted param "scriptItems" then readds the item type welding mask to that list for some reason
That is what i was thinking but wanted to double check, thank you very much - and can we generate our own custom item tags, or is that outside the scope of mods?
:D
I get this when I try to wear it
I'm getting closer and closer to solving this!!!
and finally adding my h o o d i e
https://cdn.discordapp.com/attachments/1022574121156104222/1024099193041715210/unknown.png eh atleast it's placeable but still gotta fix that
Glad it works! It was my pleasure
Anyone with a good mod recommendation?
Nothing specific in mind...
I have some armors, vehicles and weapons
is it possible to modify one or more local variables of a function of a mod using another mod?
nop, unless the function is global, you can rewrite it
Not easily, no
In some cases, you might be able to insert metatables into environment tables to intercept assignments
rewrite the function that use that var
if it is a global function, can of course rewrite it, yes
it's not
if the function is also local, remove from event sub
or just plainly have a file with the same name but different implementation... probably that will works..
that's what I was wondering
That should work
its best practice to use a prefix to your mod, so none unintentionally overwriting yours
to everyfilename aswell
Does come with the cost of being brittle if the mod changes a lot, modifies the file regularly
yep, but hardly for filename i think, i prefer make a patch file somewhere, then use the same name to assign the function i define in that prefixed name patch file
I was wondering if you might be able to load your file before theirs and use setfenv to call require to load their file with a different environment that you control. Haven't actually tried that though
never try tho
under load order perhaps?
but...
you need 2 mod to do that :S 1 mod to load before and after lol
i dunno
Yea, you can load before other files easily enough. The files are loaded alphabetically, so can name your file !patchfile.lua, for example
ah.. i just know that.. alphabetical order
!beforepatchfile.lua
zzafterpatchfile.lua
:p
mess.. but i like the idea, like trapping stuff between it
!!!_PATCH_start.lua
Z_PATCH_end.lua
kinda weird use ! as filename
like css !important
lowercase ascii sorts after uppercase, so would go with lower case z
yep
ah I see, i fail to notice that
thank you for your answers @hearty dew & @lime hedge
Is there a way to see a performance graph?
Where is the lootzed tool at? Don't see it as a mod, nor in the dev tools you dl via steam
I see it mentioned in pz release notes
Oh, is it built into debug mode?
What's the easiest way to test a mod that requires a second player?
Man I'm just working backwards now, trying to intercept ISVehicleMenu.onMechanic isn't working at all, feel like I'm taking crazy pills this should be simple
Is there something different about games launched through the "Host" option? Should I be putting my client sided code in shared or something? I just don't get why overriding this function isn't working
Its literally just this
local original_openMechanics = ISVehicleMenu.onMechanic
function ISVehicleMenu.onMechanic(character, vehicle)
character:Say("New Open Mechanics UI Action", 0.0, 1.0, 1.0, UIFont.Small, 60.0, "radio")
--original_openMechanics(character, vehicle)
end```
that's exactly what that did to me cuz the name sounds like a separate program or mod lol
thank you verymuch @hearty dew for helping me with this!!!
https://steamcommunity.com/sharedfiles/filedetails/?id=2868229063
nice, how are you getting the power to come back on? Messing with the configured day?
getSandboxOptions():getOptionByName("ElecShutModifier"):setValue(2147483647)
print(getSandboxOptions():getOptionByName("ElecShutModifier"):getValue())
getSandboxOptions():getOptionByName("ElecShutModifier"):setValue(-1)
print(getSandboxOptions():getOptionByName("ElecShutModifier"):getValue())```
heres what i used
set it to max and then negative? Thats weird. But if its dumb and it works it's not dumb
your description doesn't quite explain the game mechanics of it
admin placed tile
but
more than one? what do they do to repair it? does it turn back off randomly?
does it break at random admin placed tiles out of the group of them?
would be fun to make it work on random electrical poles and then start them back at like.. random N (1-14) in game days before it runs out
so they have to hunt around for it
I had a mind to add a larger generator somewhere on the map. Natural gas maybe. Have it produce a tonne of noise while operating but as long as you keep the zombies out the power keeps running. Could be fun
Still facing issues here gentlemen. Can't figure it out from source code
I would have assumed it would be in ISInstallVehiclePart.lua but it doesn't appear to be. Maybe track down where sendClientCommand(self.character, 'vehicle', 'installPart', args) ends up. I suppose it could send a server command back to trigger the loading/flashing bar, who knows
I'll try to track that down, thanks
by the way, any idea what language each codename in /lua/shared/translate refers to?
They are probably bcp 47 language tags
I've checked, doesn't look like it though
It says CH is Italian, somehow, even though it has chinese characters in the vanilla files
BCP 47 Language Tags is the Internet Best Current Practices (BCP) for language tags. The purpose of these language tags is to establish codes to help identify languages both spoken and written. Since it is impossible to list all of the BCP 47 language tags and their combinations, we have provided a list of what we have found to be the most commo...
None of them start with CH though
anyhow, apparently the full language text appears in language.txt in each respective folder, thanks to the help in #translations. I appreciate your time!
Oh, then I don't know what standard they are following
Would you have an idea about this?
I'm not even sure what the flashing thing is in the vehicle menu. I play on settings that make it almost impossible to get a working car 😅
is there a way to create an explosion at a tile
Really looks awesome man, keep it up!
which one do i use ?
OnCreateSurvivor or OnCreatePlayer
i need a function as soon as a player createas a new character and spawns for the first time
im guessing its OnCreateSurvivor
hmm I can't find the intsallPart client command anywhere, any idea where I can find it?
I'm trying to figure out steam workshop formatting, is there a way to have a multi-level list?
yes you can create your own tags, and then you need to create the function that gathers all the items based on tags if you want to use them for recipes
is there a guide as to how to set up the spawn location/chance of a custom item?
Is it possible to change the volume of a sound added with addSound(soundFile)? Or should it be done directly on the sound file?
Pretty sure this is where to ask. Does anyone know how to remove items from Choose item directory when uploading workshop content?
The Workshop folder is cleared besides the mod template and the mods still show yet not existing as an uploaded mod on my Steam account.
Thanks
Anyone know what the following does in the vehicle distributions
table.insert(VehicleDistributions, 1, distributionTable)
I think you have to look in the folder C:\Users\USERNAME\Zomboid\Workshop
it just inserts the distributionTable into the vehicledistributions table.
but won't it be
VehicleDistributions.1
To access that distributionTable now?
Why is it saved into [1]?
-- VD:table 0x686968119 2:table 0x366126203 3:table 0x871284004
A_Mod.Debug("VD:" .. tostring(t_Distribution) .. " 2:" .. tostring(t_Distribution[1]) .. " 3:" .. tostring(t_Distribution[1].SUVSmashedRear));
So odd
so its the wierd way lists are implemented into lua since everything is a table
Yeah, but saving the distributiontable reference into [1] is so odd
And there's nothing that uses it
I think
everything that uses vehicle distributions uses it
all lua tables are dictionaries
but somethings make sense to use lists logically. but lua doesn't have lists
Yea, I guess somewhere in java they use this table and the [1] variable value?
so they are implemented as dictionaries that just index with 1 up to the N elements
Yeah, but for this case
-- table for glovebox
VehicleDistributions.GloveBox
-- table for distribution of smashed vehicles
VehicleDistributions[1]
I thought it's odd that they are using both
yeah so since they are ultimately tables, you can use both methods
Like, why not just call it
VehicleDistributions.SmashedDistributions
That's what's confusing me XD
yeah, you can do it, but why do it
so odd
I thought there was like a explenation somehow that it's for a specific reason so I tried to figure out why, too hard :S
its a really wierd behavior, because you can have a table with elements indexed with the normal list form and one random str index, and when you do ipairs, it will only return the indexed stuff with not the numbers
Yeah
my understanding is that lua design philosophy is to be easily portable and simple. and to try to acheive that philosophy, they heavily reduced the number of data types. so there is only 1 "data storage" which is the table
because it simplifies things
I see, that makes sense, yeah. Thanks
but there are still alot of useful things with lists and arrays and stuff which are very useful, so tables try to do it all
but the side effect is that weird thing that you can treat the same thing as lists or dictionaries or iterators because ultimately, they are all just a table
I got a question about these
self.character:setMaxWeight(NewWeight)
self.character:setMaxWeightBase(NewWeight)
How does it determine the new carry weight? Using specific numbers makes the outcome different then what is put in
Little question, im trying to understand more Lua scripting myself, and I trying to do a small run using Fireamrsb41 which has suppresor and Resident Evil Weapons (REWMOD) which also has silencer for its weapon
I have seen, the B41 weapons lose the suppresion sound and that when I have equip the RE weapon I get this error (if they the silencer attach)
and it points to this line in the Silencer lua
line 75
you would probably have to take a look at the decompiled code to figure that out. if I would have to guess, the maxweight and maxweightbase isn't directly used for carry limit, but are just constants used for some formula since the max weight you can carry depends on things like your perks and strength level.
alot of mods which add silencers are incompatible with each other. maybe try one at a time to see which you prefer
Yea, there is a formula. Just was asking if anyone knew it beforehand
player.setMaxWeight(player.getMaxWeight() + 2); If Green food Moodle is present
player.setMaxWeight((int)(player.getMaxWeight() * player.getMaxWeightDelta()));```
@heady cloak It was posted across several messages earlier
Simply put, setMaxWeightBase adjusts your minimum, and SetMaxWeightDelta is the strength multiplier
My ctrl+f skills didn't work, sorry about that
any idea why I am getting an error here?
Events.OnFillWorldObjectContextMenu.Add(function(player, context, worldobjects)
local generator
for _,worldObject in ipairs(worldobjects) do
if instanceof(worldObject, 'IsoGenerator') then
generator = worldObject
end
end
if generator then
local playerObj = getSpecificPlayer(player)
local invent = playerObj:getInventory()
local item = invent:getItemFromType("Jumpstarter")
local usedDelta
local remainingUses
local fuel
local discription = nil
description = "<RGB:0,255,0> Recharges the Battery Jumpstarter <LINE> <LINE>"
if item then
description = description .. " <RGB:1,1,1>" .. item:getDisplayName() .. " 1/1 <LINE>";
usedDelta = item:getUsedDelta()
remainingUses = 0
if usedDelta > 0 then
remainingUses = usedDelta*5
end
else
option.notAvailable = true;
description = description .. " <RED>" .. item:getDisplayName() .. " 0/1 <LINE>";
end
fuel = generator:getFuel()
local option = context:addOption("Recharge Jumpstarter", worldobjects, BatteryJumpstarter.onJumpstarterRecharge, generator, player, item, remainingUses, fuel);
if fuel > 1 then
description = description .. " <RGB:1,1,1> 1 unit of fuel <LINE>";
else
option.notAvailable = true;
description = description .. " <RED> 1 unit of fuel <LINE>";
end
end
if remainingUses == 5 then
option.notAvailable = true;
description = "<RED> Battery Jumpstarter is already fully charged <LINE>";
end
local tooltip = ISToolTip:new();
tooltip:initialise();
tooltip:setVisible(false);
tooltip.description = description
option.toolTip = tooltip
end)```
the error is on the last line of the code, end)
What is the error message?
Callframe at: se.krka.kahlua.integration.expose.MultiLuaJavaInvoker@d9c7e266
function: createMenu -- file: ISWorldObjectContextMenu.lua line # 1532 | Vanilla
function: createMenu -- file: ISMenuContextWorld.lua line # 50 | Vanilla
function: createWorldMenu -- file: ISContextManager.lua line # 28 | Vanilla
function: doRClick -- file: ISObjectClickHandler.lua line # 60 | Vanilla
function: onObjectRightMouseButtonUp -- file: ISObjectClickHandler.lua line # 369 | Vanilla
LOG : General , 1664295377295> attempted index of non-table
LOG : General , 1664295377349> creating new sourcewindow: C:/Users/Zeyad/Zomboid/mods/Battery Jumpstarter/media/lua/client/BatteryJumpstarter.lua
ERROR: General , 1664295380844> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: attempted index of non-table at KahluaUtil.fail line:82.
ERROR: General , 1664295380844> DebugLogStream.printException> Stack trace:
java.lang.RuntimeException: attempted index of non-table
--a lot of jibberish```
what is that closed bracket for?
Events.OnFillWorldObjectContextMenu.Add(
I had the exact same code, just reorganised line in a more logical manner and add few bits and pieces
can't find what is it that is causing the error though
here's the code before it was re-organised and starting throwing errors
Events.OnFillWorldObjectContextMenu.Add(function(player, context, worldobjects)
local playerObj = getSpecificPlayer(player)
local invent = playerObj:getInventory()
local item = invent:getItemFromType("Jumpstarter")
if item then
local generator = nil;
local usedDelta = item:getUsedDelta()
local remainingUses
if usedDelta > 0 then
remainingUses = usedDelta*5
else
remainingUses = 0
end
remainingUses = math.floor(remainingUses)
for _,worldObject in ipairs(worldobjects) do
if instanceof(worldObject, 'IsoGenerator') then
generator = worldObject
end
end
if generator then
if generator:isActivated() then
local fuel = generator:getFuel()
if remainingUses < 5 and fuel >= remainingUses then
local option = context:addOption("Recharge Jumpstarter", worldobjects, BatteryJumpstarter.onJumpstarterRecharge, generator, player, item, remainingUses, fuel);
end
end
end
end
end)```
"Attempted index of non-table" is usually caused by calling a function that doesn't exist
tooltip.description = description
Is tooltip nil?
description is initialized inside if generator, so if there is no generator found this would get thrown I believe
If you are in the debug UI, it has a window with the value of local variables. You might can check if something is unexpectedly nil using that
right, i think it was that. It makes the most sense. Idk how i never noticed it
oo i never actually knew that, thanks
Does using local inside an if then block set its scope to the function or the if then block? I'm not sure but I think its the latter. If that's the case even if a generator is found description won't exist
I think it was because I was trying to access the description outside the if condition, whereas the error was thrown when I right click off the generator. so it makes sense there was no description in the first place
Thanks for the time guys!
My bisect hosting server crashes when I add Noir's Attachments to the mod list
Did anyone ever experienced this?
Not sure from that what pz is doing to reach the inotify limit. Might check kernel messages to verify that's what's happening
and if so, you could try increasing the limit
or figuring out what could be causing that in pz, I suppose, but isn't much to go on from that
It's a bit tricky cause I don't have control of the server but I could ask their Devops team to increase them
Oh, yea, you'd need to fiddle with files in /proc to change it
Or some system-wide configuration. I don't remember off the top of my head
ERROR: General , 1664297835565> 4,503,823,357> at java.base/sun.nio.fs.UnixPath.register(Unknown Source)
ERROR: General , 1664297835565> 4,503,823,357> at java.base/java.nio.file.Path.register(Unknown Source)
ERROR: General , 1664297835565> 4,503,823,358> at zombie.DebugFileWatcher.registerDir(DebugFileWatcher.java:73)
ERROR: General , 1664297835565> 4,503,823,358> at zombie.DebugFileWatcher$1.preVisitDirectory(DebugFileWatcher.java:57)
ERROR: General , 1664297835565> 4,503,823,358> at zombie.DebugFileWatcher$1.preVisitDirectory(DebugFileWatcher.java:53)
ERROR: General , 1664297835565> 4,503,823,358> at java.base/java.nio.file.Files.walkFileTree(Unknown Source)
ERROR: General , 1664297835565> 4,503,823,358> at java.base/java.nio.file.Files.walkFileTree(Unknown Source)
ERROR: General , 1664297835565> 4,503,823,358> at zombie.DebugFileWatcher.registerDirRecursive(DebugFileWatcher.java:52)
ERROR: General , 1664297835565> 4,503,823,358> at zombie.DebugFileWatcher.addDirectoryRecurse(DebugFileWatcher.java:113)
ERROR: General , 1664297835565> 4,503,823,358> at zombie.ZomboidFileSystem.getAllModFoldersAux(ZomboidFileSystem.java:517)
ERROR: General , 1664297835566> 4,503,823,358> at zombie.ZomboidFileSystem.getAllModFolders(ZomboidFileSystem.java:555)```
Looks like pz registers all mod directories to watch
So might be due to a combination of your server having a low inotify limit and having many mod directories that pz registers for notifications
cat /proc/sys/fs/inotify/max_user_watches should show you the per-user limit
Damn, I wish I could just edit that myself, but I need to wait for the tech support
I should have hosted this server myself 😐
It does set the scope to the if then block
ya, that's what I thought
I did an Intervals Thread function in case someone finds it useful
local Interval = {}
local Intervals = {}
function Interval:CreateThread(seconds, cb)
local i = 1;
local waitThread = 0;
while Intervals[i] ~= nil do i = i + 1 end
Intervals[i] = true;
Events.OnTick.Add(function()
if waitThread == seconds then waitThread = 0; else waitThread = waitThread + 1 end
if waitThread == 0 then
if Intervals[i] ~= nil then
cb();
else
Events.OnTick.Remove(self);
end
end
end);
return i;
end
function Interval:ClearThread(id)
if Intervals[id] ~= nil then
Intervals[id] = nil
end
end
return Interval
How use?
local Interval = require "YOURMODNAME/Interval"
local TestInterval;
local onKeyStartPressed = function(key)
if key == Keyboard.KEY_NUMPAD1 then
TestInterval = Interval:CreateThread(500, function()
print("TESTING THREAD");
end)
end
if key == Keyboard.KEY_NUMPAD2 then
Interval:ClearThread(TestInterval);
end
end
Events.OnKeyStartPressed.Add(onKeyStartPressed);
How dificult would be to write a patch
In personal opinions
Don't you have to pass a reference to the cb wrapper to remove it? self is only defined by the : syntax, or does self do some magic inside anonymous functions?
self refers to itself inside a function
~~it's the same that
local OnTick = function(blabla)
end
Events.OnTick.Add(OnTick)
Events.OnTick.Remove(OnTick)
```~~
right, using the : syntactic sugar in lua, self is added as a parameter
Foo:bar()
-- self is in scope
end```
is equivalent to```lua
Foo.bar(self)
-- self is in scope
end```
Don't think it does that in lua otherwise?
IIRC it depends on which block you are using self
function f()
print("self is "..tostring(self))
end
f()```
outputs:
self is nil```
or if you define it
wait me a second, I need check that, It's only been 3 days since I've been modding again
Other languages give functions a self reference, but lua doesn't afaik (except when defining a function using the : syntax, function Foo:bar())
input
print(function()
print(self)
end)
output
function: 0x710330
yeah, works only anonymous functions
thats not printing "self". though...the function there is never run
soo i've made a model for a custom object but it's not appearing in-game. Like, physically its there, but its like the model is invisible. Keep in mind I didn't add textures yet. Would that cause the issue of it not appearing?
lol
mb
Mm, you'd expect two lines printed, one for the function object returned by function() .. end and a second for the print(self) inside when the function is called (if it were called)
yep
local cb_wrapper
cb_wrapper = function()
if waitThread == seconds then waitThread = 0; else waitThread = waitThread + 1 end
if waitThread == 0 then
if Intervals[i] ~= nil then
cb();
else
Events.OnTick.Remove(cb_wrapper);
end
end
end
Events.OnTick.Add(cb_wrapper)```
Might need something like this
this is pretty much correct, self will always refer to the table holding the function
umm i need help effectively binding a .fbx model to a custom item since apparently I am not doing it correctly, if anyone's got an idea
Did anyone ever had a situation where you can't unequip a piece of clothing? 🤔
Apparently, group:setMultiItem("NameHere", true) breaks the unequip button 😦
Hey yall im doing to do custom loot zones for the first time, how do i get the name of custom tiles?, for example i want to do a music store with dylans music tiles? Cant find the name for his shelves n what not
does someone has a list, where Events are separated by Server and Client? I am wonder which event is available where.
specifically the events "OnPlayerDeath" and "OnScoreboardUpdate"
Looks like a lot of them are the java code. I don't see them all in the lua source
$ grep -rh triggerEvent ProjectZomboid/media/lua/server | awk '{$1=$1;print}' | sort
triggerEvent("OnChangeWeather", season.weather);
triggerEvent("OnDawn"); -- we notify that we're on dawn for modding purpose
triggerEvent("OnDusk"); -- we notify that we're on dusk for modding purpose
triggerEvent("OnObjectAdded", self.javaObject)
triggerEvent("OnObjectAdded", self.javaObject)
triggerEvent("OnObjectAdded", self.javaObject)
$ grep -rh triggerEvent ProjectZomboid/media/lua/shared | awk '{$1=$1;print}' | sort
triggerEvent("OnContainerUpdate");
triggerEvent("OnSpawnRegionsLoaded", regions)
triggerEvent("onAddForageDefs", forageSystem);
triggerEvent("onUpdateIcon", zoneData, iconID, nil);
triggerEvent("preAddCatDefs", forageSystem);
triggerEvent("preAddForageDefs", forageSystem);
triggerEvent("preAddItemDefs", forageSystem);
triggerEvent("preAddSkillDefs", forageSystem);
triggerEvent("preAddZoneDefs", forageSystem);
$ grep -rh triggerEvent ProjectZomboid/media/lua/client/ | awk '{$1=$1;print}' | sort
triggerEvent("OnChallengeQuery");
triggerEvent("OnClothingUpdated", self.character);
triggerEvent("OnConnectFailed", error, detail)
triggerEvent("OnContainerUpdate")
triggerEvent("OnContainerUpdate")
triggerEvent("OnContainerUpdate")
triggerEvent("OnContainerUpdate")
triggerEvent("OnEnterVehicle", self.character)
triggerEvent("OnExitVehicle", self.character)
triggerEvent("OnFillInventoryContextMenuNoItems", playerNum, context, isLoot)
triggerEvent("OnFillInventoryObjectContextMenu", player, context, items);
triggerEvent("OnFillWorldObjectContextMenu", player, context, worldobjects, test);
triggerEvent("OnObjectAboutToBeRemoved", _object)
triggerEvent("OnObjectAboutToBeRemoved", _object) -- Hack for RainCollectorBarrel, Trap, etc
triggerEvent("OnObjectAboutToBeRemoved", _object) -- Hack for RainCollectorBarrel, Trap, etc
triggerEvent("OnObjectAdded", _obj)
triggerEvent("OnObjectAdded", _obj)
triggerEvent("OnObjectAdded", obj) -- for RainCollectorBarrel in singleplayer
triggerEvent("OnPreFillInventoryContextMenuNoItems", playerNum, context, isLoot)
triggerEvent("OnPreFillInventoryObjectContextMenu", player, context, items);
triggerEvent("OnPreFillWorldObjectContextMenu", player, context, worldobjects, test);
triggerEvent("OnRefreshInventoryWindowContainers", self, "beforeFloor")
triggerEvent("OnRefreshInventoryWindowContainers", self, "begin")
triggerEvent("OnRefreshInventoryWindowContainers", self, "buttonsAdded")
triggerEvent("OnRefreshInventoryWindowContainers", self, "end")
triggerEvent("OnSteamWorkshopItemCreated", "1234", true)
triggerEvent("OnSteamWorkshopItemUpdated", true)
triggerEvent("OnSwitchVehicleSeat", self.character)
triggerEvent("onDisableSearchMode", self.character, self.isSearchMode);
triggerEvent("onEnableSearchMode", self.character, self.isSearchMode);
triggerEvent("onFillSearchIconContextMenu", contextMenu, self);
triggerEvent("onToggleSearchMode", self.character, self.isSearchMode);
triggerEvent("onUpdateIcon", _icon.zoneData, _icon.iconID, _icon);
triggerEvent("onUpdateIcon", _zoneData, _iconID, _icon);
triggerEvent("onUpdateIcon", self.forageIcon.zoneData, self.forageIcon.iconID, nil);
triggerEvent("onUpdateIcon", self.zoneData, self.iconID, self);```
Those are just the ones in client / shared / server in lua source
The shared ones might have IsClient() or IsServer() conditionals missing from that info however
thanks for your work. I did not even came up with the idea to search the lua folder for triggers using wildcards. genius. thanks. 🔥
Might not be that useful as a lot are missing. The missing ones are likely in the java code, which I don't have decompiled to search through atm
It is alright. But you taught me something nonetheless.
Does anyone know where the whole definitions for guns, are especially how they are set up as objects in lua?
Diff between current stable and unstable lua api and java api - updated for todays unstable release
https://github.com/asledgehammer/PipeWrench/pull/19/files
Intervals Thread (now works fine lmao)
what sort of things would someone do with this?
subMenu:addOption("Follow me", clickedPlayer, function(dog)
followInterval = Interval:CreateThread(200, function()
ISTimedActionQueue.clear(clickedPlayer)
ISTimedActionQueue.add(ISWalkToTimedAction:new(clickedPlayer, playerObj:getCurrentSquare()))
end)
end);
this for example, ISWalkToTimedAction behaves weird if it is repeated a million times
so the action would fire every 200ms or something automatically until you kill it? Thats pretty neat
Is there any easy way to test multiplayer mods that require a second player? I understand there's some kind of splitscreen mode? Is this usable?
Probably this help you
https://steamcommunity.com/sharedfiles/filedetails/?id=2735092774
does anyone know if its possible to fire the command below on server level? i'm trying to allow someone without an access level to add new vehicles to the map, but firing the command seems to require a certain access level
Effectively I want to create multiple clients and iterate quickly on one machine
Oh awesome, your guide covers that. Thanks a lot Dislaik
@ruby urchin does this only work on the new unstable build or does it apply on the current stable
try searching for xyberviris carwanna mod
thanks!
it creates items called as pink slips which can be used to spawn vehickes as it sends commands to the server.
seems to be using addVehicleDebug() instead of the /addvehicle command, thanks for tip!
but u need to do the sendtoserver function otherwise it wont work
to check try it on lua console
then have another player come to you to see if he can see the vehicle
Does anybody know if the muzzle flash on firearms is vanilla? I'm working on some firearms in a mod, and some have the muzzle flash, some do not.. I'm tryin to figure out if that is a setting in the scripting of the firearm, or if thats part of the model I am exporting from blender.
Actually idk, I haven't seen any complaints so far
Good day, can anyone help me I've run out of places to search.
I've tried giving myself admin rights but it always says acess level 32 without access to the panel.
Turned on and off the debug menu, with and without mods.
I don't know at this point what prevents me from getting admin rights.
I typed Both.
/setaccesslevel "John Shepard N7117" admin
/setaccesslevel "JohnShepardN7117" admin
Both recognized and still it says access level 32.
screenshot your name
Is there a mod that allows you to ride the back of pickup trucks?
I swear that I remember seeing it on steamcommunity at some point
@midnight mica
forgot the H
3 damn hours
lol
Thank you kindly.
Anyone familiar with Lua's load() know if it is actually exposed? Seems like it is but the game throws up errors as if it's not
IIRC pz use a old version of lua, use loadstring() instead
doesnt seem like loadstring is exposed
ah load() was in my IDE from a lua library
I don't think either are exposed
this works?
Yeah, I used that when I was noob and I didn't know that require exists
last i checked loadstring worked
thank you very much
wish I asked sooner
spent like 2 days off and on trying to write a table to string to table
Trying to make it easier to manage a large amount of stores
Yeah
Saves to serverside global mod data
Can set up a store anywhere - it's in the modData so you can attach the same store to multiple mapobjects, or copy an existing store as a template
The issue was it can take a while to set everything up - and it's all lost on a server wipe
Ohh I see, look nice
ty
and thanks again for clarifying that
trying to parse nested tables was a nightmare
so glad loadstring works
Are you serializing and deserializing lua tables?
Yes
I've been using the regex.info guy's JSON library to do that
function _internal.tableToString(object,nesting)
nesting = nesting or 0
local text = ""..string.rep(" ", nesting)
if type(object) == 'table' then
local s = "{\n"
for k,v in pairs(object) do
s = s..string.rep(" ", nesting+1).."\[\""..k.."\"\] = ".._internal.tableToString(v,nesting+1)..",\n"
end
text = s..string.rep(" ", nesting).."}"
else
if type(object) == "string" then text = "\""..tostring(object).."\""
else text = tostring(object)
end
end
return text
end
function _internal.stringToTable(inputstr)
local tblTbl = loadstring("return "..inputstr)()
return tblTbl
end
{"0":{"AAApoc.AAAGelatinBoxAppleEmpty":"AAAGelatinBoxAppleEmpty","Base.Bag_Schoolbag":"Bag_Schoolbag","Base.BellyButton_DangleGoldRuby":"BellyButton_DangleGoldRuby"}}```
SHould handle nested tables
MyNamespace.JSON = require("lib/JSON")
-- decoding
local reader = getFileReader(configName, false)
local text
if reader then
text = reader:readLine()
else
text = '{}'
end
local myObject = MyNamespace.JSON:decode(text)
if reader then reader:close() end
-- encoding
local text = MyNamespace.JSON:encode(myObject)
local writer = getFileWriter(configName, true, false)
if not writer then
return
end
writer:write(text)
writer:close()
Basically how it is used. Hope I didn't make any typos
Anyone have some good challenge or objective based game modes or maps?
If that code does the trick, then it does the trick :)
I'll have to look through the library, seems like there's a lot of useful stuff
im thinking this isnt possible but im asking here cuz u guys may know a workaround
so i have this mod that on multiplayer admins can spawn this item that turns on the power grid..
a player commented asking if i could make the item craftable without admin(i assume he plays singleplayer)
but doing so will ruin the rp control of the admins on mp
so i was thinking
would it possible for a sandboxvar to toggle on and off
an item recipe code???
since it's on the scripts which is txt i was thinking its impossible..
i would have to make another mod as add on that just contains the item recipe if thats the case.. but hopefuly theres way to do the sandbox thing..
how would one print to the server chat or console? I've been using player:Say for my debug messages but I'd like to do it without needing a player object
Anyone knows if there is a mod that negates the vehicle "fullness" affecting the vehicle speed?
wht abt servermsg or add the variable as a ui that constantly updates
whats the servermsg method?
ibelieve it can be found on the zomoid lua if ubsearch for it
but if i can recall correctly its something like
sendcommandtoserver("/servermsg
something like that but im not sure
i think the original one is /removezombies
refer to that line of script
just change it to servermsg instead
i used loadstring a lot to arrange for mods to insert code into my mods but only run it at certain times for plugin purposes
very much works
when i have to go beyond load order into execution order territory
That doesn't use a milliseconds wait thread, but I did one (maybe it is not the conventional way of doing it, but the result is satisfactory)
Well looks like my current issue is that my onClientCommand event listener isn't firing 🤔
Someone uses true music modding?
oh it was 200 ticks? that makes sense too
My mod doesn’t gets detected by the game
if you print on server side, this should be show on your server console
local myMsg = "hello world";
SendCommandToServer(string.format("/servermsg \"" .. myMsg .. "\"")) ```
just use print(string)?
yep
this does work, but it doesn't print in order. not a huge deal, but makes the function call tracking I'm trying to do a little harder
What am I doing wrong?
Code:
addProfession('brickmason', {
name = "UI_prof_bricklayer",
description = "UI_profdesc_bricklayer",
icon = "prof_bricklayer",
cost = -3,
xp = {
[Perks.ShortBlunt] = 4,
[Perks.Woodwork] = 4,
[Perks.Strength] = 1,
[Perks.Fitness] = 1,
},
inventory = {
["Base.Toolbox"] = 1,
["Base.Screwdriver"] = 1,
["Base.Saw"] = 1,
["Base.Hammer"] = 1,
},
traits = {"ThickSkinned2"}
})
In game:
https://i.imgur.com/DtRHk1E.png
ow i missed read what you said,, i thought u said it didnt work so i had to try.. im still sleepy lol
lol ya no worries. It definitely works, it just seems to use a network packet to handle the command, so multiple messages sent that way sometimes show up out of order.
If an item is <1 in the distribution table, does it mean it never spawns?
So im at a bit of a loss here always seems to tell me "Bob Smith" is the offender, regardless of who the attacker was
print(_attacker:getForname() .. " " .. _attacker:getSurname() .. " hit a zombie.");
end```
Do you know what's calling it? If so, can investigate where the _attacker parameter is coming from
I don't see that event triggered in lua, so I presume it is trigger in the java code
Line 919 of IsoZombie.java is the best ive decerned
But once i reach that im at a loss
ProjectZomboid/zombie/characters/IsoZombie.class
ProjectZomboid/zombie/Lua/LuaEventManager.class```
Both of those match the string `OnHitZombie`
Thats all ive really found though lol
Let me decompile those real quick using http://www.javadecompilers.com/
mmk
Hmm.. odd. I'd wonder if any other values on the _attacker object are unexpected like that (because I'm wondering if getForname() and getSurname() are simply returning stubbed values)
Don't see anything to explain it in IsoZombie:Hit()
Does anyone know why Mod options/Map mods wouldn't show on my server
well getForname should be getForename. I don't see the first usage in the lua code anywhere, so that seems like a typo? But it ought to have given you an error in that case 😅
What happens if you try:lua print(_attacker:getDescriptor():getForename() .. " " .. _attacker:getDescriptor():getSurname() .. " hit a zombie.");?
ill have to test here in a bit, not on zomboid atm
https://zomboid-javadoc.com/41.65/zombie/characters/IsoGameCharacter.html
I don't see it on that javadoc. Do you have a more current version?
Javadoc Project Zomboid Modding API declaration: package: zombie.characters, class: IsoGameCharacter
Hey guys, so I tried to fix it by myself but couldn't figure anything out, can someone help me with that?
What's the error message when that occurs?
Hm, let me check
since I didn't see any error pop-up
maybe didn't notice it
I'll let you know in a sec
In debug mode, I believe it breaks on the code (so you can investigate) and so it stops before doing the error popup visual
around 200 errors popped out
What's the first one?
first one's at the top?
Yea, it'll appear first in console.txt
hmm
there are two items HoodieUP and HoodieDOWN
UP seems to work fine
but DOWN seems to be doing it
yeah when I try to put down the hood it happens
which makes me think something could be wrong here
That fixed it, i was using deprecated code it seems
Thank you
At the bottom there, it looks like it is trying to create the tooltip to display, but become some body part location is null (local14)? it is throwing an exception. I haven't messed with adding clothes, so idk if that's something you even affect that. Maybe that's just a consequence of some other issue
Can you get the rest of the error message?
it will be in console.txt if you can't view it in the debug ui
Zomboid/console.txt in your home directory
oh
got it
one sec
there's a lot of stuff going on in that console.txt
is there anything I need to look for?
actually I can it this way
this poops on the chat when I try to put the hood down
is it possibly about extra actions on the hoodie?
nope
What error shows up when you simply try to wear the down version?
Is it the same one that starts like:
function: render -- file: ISToolTipInv.lua line # 78 | Vanilla```?
Hrm, I think that's just something with the debug UI
hmm
In item MerchHoodieDOWN, if you setClothingItem = MerchHoodieUP, are you able to wear the down version?
yea
bet
let me check
yeah
I can
hmm, and I can put it down and up
maybe it's the model?
Okay, so something is up with the down version of the clothing properties, like the xml configuration or perhaps the model, not entirely sure
Can you paste the fileGuidTable.xml and the xml files for the two versions?
hmm I think the model might be fine since the ground one is basically hood down but flat
Okay
sec
that's how FileGuidTable looks like
and those are the xmls
why is there a | after the closing guid elements?
not sure
I was copying the script from the guide
and changing it a bit
it shouldn't be there?
No.. Couldn't tell if that was something up with your editor or what 😅
Can you format it like this```xml
<files>
<path>media/clothing/clothingItems/Jacket_PaddedDOWN.xml</path>
<guid>c1d742f9-d5a5-4c5f-99b1-8ee43c131f0f</guid>
</files>
<files>
<path>media/clothing/clothingItems/Jacket_Police.xml</path>
<guid>c280861d-1dae-4914-ac94-99de18700c68</guid>
</files>
definitely
and make sure your MerchHoodieDown.xml is where the path says it is
Okay
okay i put it in your format, imma go test it now
Okay
