#mod_development
1 messages ยท Page 503 of 1
Not subclasses
So it's an instance of Class<InventoryItem>, and getClass() on that is just Class.
writing some java code to prove you wrong ๐
@teal slate so if you compile this:
import java.lang.reflect.Method;
public class Test {
public int someMethod() {
return 0;
}
public static void main(String[] args) throws Exception {
Test test = new Test();
Method[] methods = test.getClass().getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
}
}
``` and run it, it prints this:
```$ java Test
public static void Test.main(java.lang.String[]) throws java.lang.Exception
public int Test.someMethod()
that's not what I'm doing, though
oh wait
public class Test
yeah, but
that's because you made a subtype of class
try it with Test as an object
Test test = new Test();
Method[] methods = test.getClass().getDeclaredMethods();```
public class Test
so what?
in LuaManager it's the same:
@LuaMethod(name = "getClassFunction", global = true)
public static Method getClassFunction(Object object, int int1) {
Method method = object.getClass().getDeclaredMethods()[int1];
return method;
}
InventoryItem is declared as a class too?
I mean it is a class, the same way my Test class is
wait
aghhh i'm
i haven't slept
:)
yeah, i'm silly
it won't work, darn
though, wait
Method[] methods = test.getClass().getDeclaredMethods();
what i'm doing is effectively equivalent to Method[] methods = test.getClass().getClass().getDeclaredMethods();
try that @weary matrix
sure
hold on
ok this one indeed returns the method from Class
because you're getting the superclass of Class<Test> which is Class<Class> or just Class
but from Lua I presume you'd need the class Class to be exposed right?
how do you get a reference to the super class of Class<Clothing>?
Rather, we don't manipulate the userdata in Lua at all. We just pass the userdata between various Java functions.
Not being exposed doesn't mean we can't access the class; it just means it doesn't have a metatable set.
yes, so how would you get access to the methods of Class?
Via getClassFunction, which is a global function in Lua.
If we can't call a Method directly, well... it was worth a shot!
but the getClassFunction() is doing the same as the Test example I showed you, so it wouldn't allow us to get reference to the methods of Class
it would only give access to the method of InventoryItem
InventoryItem.class is equivalent to getClass() on an InventoryItem.
And getClassFunction calls getClass() on the object passed, so it's basically inventoryItem.getClass().getClass().getDeclaredMethods()
it is, but it will return a Class<InventoryItem> not a class, the same way my test.getClass() returns Class<Test> not class
no, that's what InventoryItem.class is
that's Class<InventoryItem>
calling getClass() on Class<InventoryItem> will just give Class
@teal slate what's the difference between getClassFunction and this:
public static void main(String[] args) throws Exception {
Test test = new Test();
Method[] methods = test.getClass().getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
}
}
Nothing, that should work
no
oh you edited it
as I showed you it only prints the methods from the class Test
like I said, test is an object
yeah I copy pasted the last version by mistake
but you can't call getClass().getClass() with the method getClassFunction:
@LuaMethod(name = "getClassFunction", global = true)
public static Method getClassFunction(Object object, int int1) {
Method method = object.getClass().getDeclaredMethods()[int1];
return method;
}
public static void main(String[] args) throws Exception {
Test test = new Test();
listClassFunctions(test);
listClassFunctions(test.getClass());
}
public static void listClassFunctions(Object obj)
{
Method[] methods = obj.getClass().getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
}
you don't have to
we're not passing an InventoryItem instance
we're passing Class<InventoryItem>
(which is what the Lua variable InventoryItem.class is)
no ๐
let me show you
@teal slate ```java
import java.lang.reflect.Method;
public class Test {
public int someMethod() {
return 0;
}
public static void listClassFunctions(Object obj) {
Method[] methods = obj.getClass().getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
}
public static void main(String[] args) throws Exception {
Test test = new Test();
listClassFunctions(test);
}
}
$ javac Test.java
$ java Test
public static void Test.main(java.lang.String[]) throws java.lang.Exception
public static void Test.listClassFunctions(java.lang.Object)
public int Test.someMethod()
you're creating a new Test
InventoryItem.class is equivalent to (new InventoryItem).getClass()
which is Class<InventoryItem>
then we do getNumClassFunctions(InventoryItem.class)
which calls getClass() on Class<InventoryItem>
which returns Class.
It's fine, I was having a little trouble understanding myself until I sat down and put it all together
This is why you don't not sleep and code
so let's assume we can get all the method of Class with this:
local Class = {}
for i=0, getNumClassFunctions(InventoryItem.class) - 1 do -- any class would work
local func = getClassFunction(InventoryItem.class, i)
Class[func:getName()] = func
end```
How would you pass the instance on which to call Class.cast()?
true I have to stop doing that ๐
Class.cast(superclass, instance)
I'm not 100% sure if you can call Methods from Lua like this, but it's worth a shot
but Class.cast() only takes on argument not two
I mean Class.cast() is not a static method from Class
Exactly.
Instance methods in lua take the first argument as the instance to run it on.
So instead of instance.instanceMethod(), you'd use instance:instanceMethod(), which is syntactic sugar for instance.instanceMethod(instance)
so this is what you mean right?
local Class = {}
for i=0, getNumClassFunctions(InventoryItem.class) - 1 do -- any class would work
local func = getClassFunction(InventoryItem.class, i)
Class[func:getName()] = func
end
for k = 0, items:size() - 1 do
local item = items:get(k)
local superclass = Class.getSuperclass(InventoryItem.class, item)
local test = Class.cast(superclass, item)
print('DEBUG')
print(test)
hmmm
Exception thrown java.lang.RuntimeException: Object public native java.lang.Class java.lang.Class.getSuperclass() did not have __call metatable set at KahluaUtil.fail line:82.
guess I have to call metatable() and declare a __call method but not sure how
I really suck at Lua
You should, yeah
I'll look into the methods thing in a bit
Aha, it's invoke
Class.getSuperclass.invoke(InventoryItem.class)
Class.cast.invoke(superclass, item)
interesting, I think the call for getSuperclass is working, if I do this: Class.getSuperclass:invoke(InventoryItem.class), but then getting an error on the cast
got an error but no exception
trying again with a fresh start
damn
local superclass = Class.getSuperclass:invoke(InventoryItem.class)
local test = Class.cast:invoke(superclass, item)
``` is giving me just this error, but no real stack trace ๐ฆ
```LOG : General , 1640787205601> creating new sourcewindow: /home/co/Zomboid/mods/ModHack/media/lua/client/ModHack/StatsWindow.lua
LOG : General , 1640787219094> -----------------------------------------
STACK TRACE
-----------------------------------------
Callframe at: invoke
function: onKeyPressed -- file: StatsWindow.lua line # 188
function: OnKeyPressed -- file: StatsWindow.lua line # 103
LOG : General , 1640787219095>
if I don't use the : syntax, then I'm getting this:
at se.krka.kahlua.integration.expose.MethodArguments.assertValid(MethodArguments.java:123)
at se.krka.kahlua.integration.expose.LuaJavaInvoker.call(LuaJavaInvoker.java:186)
at se.krka.kahlua.vm.KahluaThread.callJava(KahluaThread.java:182)
at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:1007)
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:88)
at zombie.input.GameKeyboard.update(GameKeyboard.java:65)
at zombie.GameWindow.logic(GameWindow.java:240)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.GameWindow.frameStep(GameWindow.java:745)
at zombie.GameWindow.run_ez(GameWindow.java:661)
at zombie.GameWindow.mainThread(GameWindow.java:475)
at java.base/java.lang.Thread.run(Unknown Source)
LOG : General , 1640787058708> -----------------------------------------
STACK TRACE
-----------------------------------------
Callframe at: invoke
function: onKeyPressed -- file: StatsWindow.lua line # 188
function: OnKeyPressed -- file: StatsWindow.lua line # 103
oh wait wait
Class.cast.invoke(superclass, superclass, item)
try that?
that or
Class.cast.invoke(InventoryItem.class, superclass, item)
local Class = {}
for i=0, getNumClassFunctions(InventoryItem.class) - 1 do -- any class would work
local func = getClassFunction(InventoryItem.class, i)
Class[func:getName()] = func
end
also this bit can be put anywhere in your code, ideally it would only be run once
(*ideally-*ideally none of this would be necessary)
hmm but cast() only takes one argument, two if you count the object receiving the call
how could it work with 3 arguments?
mmm maybe I don't need to call getSuperclass() at all actually
if (self == null || !clazz.isInstance(self)) {
methodArguments.fail(syntaxErrorMessage("Expected a method call but got a function call."));
return methodArguments;
}
maybe
... oh wait
yeah, we're
casting to InventoryItem, aren't we
:P
yes
Class.cast.invoke(InventoryItem.class, item)
Class.getSuperclass:invoke(InventoryItem.class) oh this is why i think
no, you can't use :
doesn't work if I dont
damn, same thing ๐ข
LOG : General , 1640787622876> -----------------------------------------
STACK TRACE
-----------------------------------------
Callframe at: invoke
function: onKeyPressed -- file: StatsWindow.lua line # 188
function: OnKeyPressed -- file: StatsWindow.lua line # 103
LOG : General , 1640787622876>
it's weird cause it seem I can cal getSuperclass() but not cast()
not sure what's the difference
what does getSuperclass() return?
try printing it
Class.cast:invoke(InventoryItem.class, item) ought to work fine
LOG : General , 1640787898375> class java.lang.Object
mmm wait I had something funky, hold on
mmm no same thing ๐ข
LOG : General , 1640788044745> class java.lang.Object
LOG : General , 1640788044817> creating new sourcewindow: ~/Zomboid/mods/ModHack/media/lua/client/ModHack/StatsWindow.lua
LOG : General , 1640788050095> -----------------------------------------
STACK TRACE
-----------------------------------------
Callframe at: invoke
function: onKeyPressed -- file: StatsWindow.lua line # 176
function: OnKeyPressed -- file: StatsWindow.lua line # 103
LOG : General , 1640788050095>
with this code:
local Class = {}
for i=0, getNumClassFunctions(InventoryItem.class) - 1 do -- any class would work
local func = getClassFunction(InventoryItem.class, i)
Class[func:getName()] = func
end
for k = 0, items:size() - 1 do
local item = items:get(k)
local superclass = Class.getSuperclass:invoke(InventoryItem.class)
print('SUPERCLASS')
print(superclass)
local test = Class.cast:invoke(InventoryItem.class, item)
print('DEBUG')
print(test)
same thing as when I pass the superclass variable to cast()
mmm
but so that means InventoryItem.class.getSuperclass()is Object not Class? ๐ฎ
OnZombieSpawn event?
OnZombieUpdate
OnZombieUpdate is a loop no?
it is
but you can do something like this:
zombies = {}
function OnZombieUpdate(zombie)
if not zombies[zombie] then
zombies[zombie] = true
-- you got a spawned zombie here
end
end```
not sure that would work depending what you're trying to achieve though
Anyone know if it's possible to "add" a mesh to another with a mod? I want to create a mod that allows players to reinforce cars with metal plates mad max style.
I should probably start by adding a new car of some sort I guess and work my way up from there.
mm I don't know but if you know which Java object is involved with the mesh I can try to check it out
and I definitely want mad max style cars !!!! ๐ ๐ ๐
also protection for the tires please! ๐
yeah
is there a way to download workshop mods and just get the files?
rather than having to go digging into my folders
like this you mean? https://steamworkshopdownloader.io/
heck yes thanks
time to find out kahlua does something terrifying, like pass null to lua as a singleton object or something
I don't think it will be possible without creating new models for each "phase" of improvement/reinforcement.
not sure I understand what you mean
oh i'm just making a joke about kahlua making some
how would you do it otherwise than creadting models for each reinforcement?
questionable choices :P
but actually I'm wondering if this weirdness doesn't come from java itself
cause the generics are "erased" at compile time, they're just here to let the compiler check for type safety
and the super class of Class<T> is Object anyway
hmmmmmmmmm
hopefully you could create a model/mesh for each addition and merge it's geometry with the car. I want to start with something like this:
Hey @weary matrix you seems pretty much skilled with modData manipulation, I was wondering, how can I add modData to some IsoObject?
This crashed for me โคต๏ธ
for i=0,sq:getObjects():size()-1 do
...
local tileIsoObject = sq:getObjects():get(i);
...
local modData = tileIsoObject:getModData():getOrCreate('BarricadedWorld')
aah think I got what you meant, like for each addon you'd have to make a whole car with the addon integrated correct?
yeah
try this maybe?
local modData = tileIsoObject:getModData().getOrCreate('BarricadedWorld')```
getOrCreate is static IIRC
hey, is there any guide or some info on how ZombiesZoneDefinition works?
except reading the vanilla code I'm not sure
sigh i see, ty any way
at least it's all in one file hehe
well it is sort of understandable how it is working, im digging rn through one of the mods to find out how where is object that he adds
i mean like ZombiesZoneDefinition.Police = { Leon = { name="Leon", chance=20, gender="male", beardStyles="null:80", }, Jillstars = { name="Jillstars", chance=20, gender="female", },
so basically this author set obj leon and it should have its own items correct?
i guess
but where did he defined this items i cant find
well at least this is what i am trying to figure out
mmm but which items are you talking about? You mean the loot when they die?
yes
Found a bumper model that looks pretty good:
that's the 92 prelude model from a pz mod
Good point, I always get confused by these things! However the crash persists, from my experiments, tileIsoObject:getModData() returns a table but running .getOrCreate('BarricadedWorld') on it triggers a crash ๐ค
local modData = tileIsoObject:getModData()
if modData then
local myModData = modData.getOrCreate('BarricadedWorld') <--- Crash here
end
Crash message is Object tried to call nil
mmm weird
what if you try to use the table directly?
sweet ๐
@glass rampart so IsoZombie.DoZombieInventory has this code:
this.getInventory().removeAllItems();
this.getInventory().setSourceGrid(this.getCurrentSquare());
this.wornItems.setFromItemVisuals(this.itemVisuals);
this.wornItems.addItemsToItemContainer(this.getInventory());
InventoryItem inventoryItem;
for (int int1 = 0; int1 < this.attachedItems.size(); ++int1) {
AttachedItem attachedItem = this.attachedItems.get(int1);
inventoryItem = attachedItem.getItem();
if (!this.getInventory().contains(inventoryItem)) {
inventoryItem.setContainer(this.getInventory());
this.getInventory().getItems().add(inventoryItem);
}
}
``` but not reallly sure that's helpful
guess te magic lies within those lines:
this.wornItems.setFromItemVisuals(this.itemVisuals);
this.wornItems.addItemsToItemContainer(this.getInventory());```
hmm...
Yeah I did that and it worked! By the way, is doing this modData["BarricadedWorld:isParsed"] = true a good namespacing of my modData or am I doing it wrong?
should be OK but why not something simpler like:
modData["BarricadedWorld"] = modData["BarricadedWorld"] or {}
modData["BarricadedWorld"].isParsed = true```
but still it's weird that you can't call getOrCreate :/
Becauuuuuse I have not thought about it and copied the naming pattern from fence code ๐
hehe
Looks like the devs were actually planning on adding car modifications at some point: https://projectzomboid.com/blog/news/2018/09/beeverdoid/
Hey all, Thursday greetings. IWBUMS BETA 40.14 RELEASED Weโve just released IWBUMS beta 40.14, which is another release thatโs primarily fix and polish โ our current aim for the devs working on this build being to make lots of quality of life corrections and adjustments while Turbo finishes his weather/climate work and the version can [โฆ]
well what I showed is easier for my eyes to parse, but only because I'm used to it I guess
hehe
Yeah I find it too, maybe it is because I am inside an OnLOadGRidSquare function? Anyway thanks again for everything, really nice to have someone to ask for those kind of stuff ๐
Did not thought this little erosion extension mod would interest so much people so I am trying to polish it a little more!
you mean OnLoadedTileDefinitions?
Actually I do Events.LoadGridsquare.Add(PlaceWindowsBaricades.loadGridsquare);
ah my bad
So performance wise this force me to be really straight to the point in the code and don't get me started with prints inside this kind of functions, it takes forever so much harder to debug, need to be cautious with performance... Challenging dev it is!
@weary matrix man i think you should get paid for your work, i mean every time i open this ch you always answering some questions or helping ppl, and from my personal experience i know how hard it can be some times!
any way ty for help! and great job on making this ch better and more friendlier ๐
aawww thank you man, feels good to hear โค๏ธ
also you should tell that to TIS ๐
never seen a community with everyone so nice actually
i think car mods are gonna be part of the vehicle rework , which will come eventualyl
@winged lotus mmm I'm thinking maybe at the time LoadGridsquare is square, ModData might not have been initialized yet? Not sure. What are you doing in this handler?
some ppl just forget to say simple "thank you" after they receive help and it is kind of demoralizing in some way, and simple "thank you" can make you feel much better and feel that you have not spend your time in vain, ppl tends to forget that to help some one you need to spend your own time and brain power!
and btw i found what i was looking for, it was in xml file ... i dunno why did i miss it srsly
it is true
ah nice, so at least I know why I couldn't find it, been looking only at the java and lua
well i think i have not explain properly what i was looking for in the first place
There's already mods for them as well:
i wanted properties of object (items that can be spawned on it) not how the spawn works
what you wanted was clear, I was just looking at how the spawn works hoping it would give clues about what you needed
in this case it indeed helped, after reading method to spawn i got an idea to check .xml xD
thanks!
hi guys sorry to bother but I am trying to learn how to mod and have a question: I was reading some codes from mods and was wondering how many times does a function registered on the event Event.OnPlayerUpdate is called per second
hehe ๐
I am getting all IsoObject Windows on tile load and randomly breaking / barricading them. It is for my extended erosion barricaded world mod. But I need to flag them as Parsed or PlayerMade so that the ones that have been spared on first load don't get destroyed on second
guess it depends on the machine on which the game it's running
Oh so is like tick based? or something like that?
yeah
IIRC it is called for each OnTick() event
mmm you could try to save the coordinates to a table to do the work at a later time when ModData has been initialized?
then when you're done you can just trash the table to get the space back ๐
Smart! I'll see how I could to that
but is there like a standard tick rate? or that should not be used to count time passed for example? and TY very much @weary matrix for the swift reply
something like this maybe?:
local allWindows = {}
function LoadGridsquare(square)
if square:hasWindowOrWindowFrame() then
local key = square:getX() .. 'x' .. square:getY()
allWindows[key] = true
end
end```
well if I'm not mistaken it's called by the rendering part, meaning it would have different rate depending on your FPS or something like that. You could use getGameTime.getTimeOfDay() though, and do your own calculation
like store the return value once, and at a later time you call getGameTime.getTimeOfDay() again and compute the difference to see how much time has passed?
also you have all the EveryOneMinutes, EveryTenMinutes, EveryHours events
https://pzwiki.net/wiki/Modding:Lua_Events/EveryOneMinute
oh ok I see, so the OnPlayerUpdate is called several times per real second and if it is something the is related to game time it is a better if i use those functions since it saves time for cpu. Is that correct?
definitely
depends if you need in-game time or real-time
TY so much for all the help, You are AWESOME @weary matrix ๐
๐
Has anyone previously run into this error with sendServerCommand? It seems you can't save the player at all, but I would like to specifically filter out the player who sent the command. I can get around this by sending the player's online ID, and then getting the player by online ID, but I would rather skip that and pass the player if possible.
ERROR: sendServerCommand: can't save key,value=playerShooting,zombie.characters.IsoPlayer@120df990
local args = {handWeaponSoundRadius = args.handWeaponSoundRadius, playerShooting = player}
sendServerCommand('DeafFromGuns', 'toclient', args) --send command to client
I know there's also sendServerCommand() with player as the first argument, but that seems to only call the command on that client, rather than pass the player at all.
On the plus side, there's quite a few ways to work around this.
not possible. it converts the args into a binary representation of a kahlua table. the only accepted values are bool, numbers, strings and additional tables
@brittle jewel ```java
while (kahluaTableIterator.advance()) {
if (!TableNetworkUtils.canSave(kahluaTableIterator.getKey(), kahluaTableIterator.getValue())) {
Object object = kahluaTableIterator.getKey();
DebugLog.log("ERROR: sendServerCommand: can't save key,value=" + object + "," + kahluaTableIterator.getValue());
}
}
right
Ahh okay, thanks!
Hi, I have a timedactions which is taking too long because the player is injured and tired. Is there a way to speed it up, just this one?
I call the timedactions from lua
what about changing the time required for the action by hooking :new() as you mentioned earlier?
not working?
I can, I thought about it but I was hoping that we could choose the time when we called ISTimedActionQueue.add(myTimedAction:new(arg1, arg2, arg3))
I'm not sure I understand the difference. You want to speed it up without changing the work time?
Just want the timedaction to be done quickly
Is it me that don't know where to search or do we have very little access to erosion data / functions in lua? Also a more global question, when you need to know what you have access to, do you search in the online javadoc or in lua game files?
@drifting ore why is hooking :new not good then?
I try
I go first to the java source usually
javadoc is useful but doesn't really help understand how the stuff work
apparently i was wrong. instances of InventoryItem and IsoDirections are also valid values for kahlua table network transfers (though not in the binary save format)
actually maybe not the IsoDirections (edit: nope..they're fine)
no clue about erosion data though, haven't looked into it so far
Wait, not the first time I heard about that, the java source, it is available inside the steam game folder or do I have to decompile things?
you have to decompile
Wow there's a tool for that? Thanks for the link ๐
anyone know how i can get a custom amount of metalworking xp?
currently there is only for 10, 20, etc
but i want 1, 2, 4, 5, 15 etc
I made the tool! ๐
Hello! If I made a map, with x cells, then uploaded that map, and played on it for a while. Then later added new cells, not replacing any, would that corrupt the save, or would it continue working as normal? Thanks
more context plz
I add that but it's do nothing, same time:
function ISApplyBandage:new(doctor, otherPlayer, item, bodyPart, doIt)
if doctor:isTimedActionInstant() or modData.TOC.JustCut then
o.maxTime = 1;
o.doctorLevel = 10;
end
end
??
i just want a custom amount of metalworking XP xD
for recipes
Are there any mods for latest build that gives more plantable crops. Like bell peppers and onions
@heavy ginkgo you should ask in #mod_support here it's about developing mods
Sorry!
hmmm where is o declared?
function ISApplyBandage:new(doctor, otherPlayer, item, bodyPart, doIt)
local o = {}
setmetatable(o, self)
self.__index = self
o.character = doctor;
o.otherPlayer = otherPlayer;
o.doctorLevel = doctor:getPerkLevel(Perks.Doctor);
o.item = item;
o.doIt = doIt;
o.bodyPart = bodyPart;
o.stopOnWalk = bodyPart:getIndex() > BodyPartType.ToIndex(BodyPartType.Groin);
o.stopOnRun = true;
o.bandagedPlayerX = otherPlayer:getX();
o.bandagedPlayerY = otherPlayer:getY();
o.maxTime = 120 - (o.doctorLevel * 4);
local modData = otherPlayer:getModData()
if doctor:isTimedActionInstant() or modData.TOC.JustCut then
o.maxTime = 1;
o.doctorLevel = 10;
end
return o;
end
I took the on of the game and rewrite it
show some code or something? ๐
i dont know how to code lol
o.maxTime = 1 when get to return o
thats why im asking here
Are you sure your hook is called correctly?
I don't know anything about recipes, so unless you give more context I don't know how to help. You talked about 10 20 etc have no idea where you get that from for instance. Lua god maybe but can't read your mind yet ๐
hook ?
oh this is just a regular timed action not related to when you wanted to intercept all timed actions?
yes it is for when I apply a bandage only
ok, and your timed action derives directly from ISBaseTimedAction?
Yes, it's IsApplyBandage in client/timedActions
hey guys, does anybody knows how to draw a text/image fixed on the client ui?
hmm what about this
function ISBaseTimedAction:adjustMaxTime(maxTime)
if maxTime ~= -1 then
-- add a slight maxtime if the character is unhappy
maxTime = maxTime + ((self.character:getMoodles():getMoodleLevel(MoodleType.Unhappy)) * 10)
-- add more time if the character have his hands wounded
if not self.ignoreHandsWounds then
for i=BodyPartType.ToIndex(BodyPartType.Hand_L), BodyPartType.ToIndex(BodyPartType.ForeArm_R) do
local part = self.character:getBodyDamage():getBodyPart(BodyPartType.FromIndex(i));
maxTime = maxTime + part:getPain();
end
end
-- Apply a multiplier based on body temperature.
maxTime = maxTime * self.character:getTimedActionTimeModifier();
end
return maxTime;
end
it's used here:
function ISBaseTimedAction:create()
self.maxTime = self:adjustMaxTime(self.maxTime);
self.action = LuaTimedActionNew.new(self, self.character);
end
no conditions, no events, just static and fixed showing a text (just like the game version on bottom right)
Mmmmmm, I did't see that. I will try
good question
Can a good Samaritan message me and help me figure out why none of my mods work in mp? Iโm hosting the server on my pc, and itโs just me and a couple friends.
I have them subscribed in the workshop, added in the main menu, and added to the server settings.
have you checked client/OptionScreens/MainScreen.lua?
you should ask in #mod_support
I found this:
self.versionLabel = ISLabel:new(-12, 0, FONT_HGT_SMALL, version , 1, 1, 1, 0.7, UIFont.Small);
self.versionLabel:initialise();
self.versionDetail:addChild(self.versionLabel);
Damn thanks again for the link @weary matrix, decompiled code allowed me to get my hand on getGameTime():getDaysSurvived() and getSandboxOptions():getErosionSpeed() easily!
client/ISUI/ISEquippedItem.lua has the code to draw the game version and ping on client ui
kind of weird btw
Awesome! Was using BeautifulJava easy enough?
is it using an ISLabel too?
Work perfect thx
I tried to overwrite the ISEquippedItem:prerender method (https://github.com/FWolfe/Zomboid-Modding-Guide/blob/master/api/README.md#:~:text=use the original callback) but when the game loads it crashes at this line:
local original_render = ISEquippedItem.prerender
function ISEquippedItem:prerender()
if isClient() then
self:drawText("Hello World", 80, 10, 1, 1, 1, 1, UIFont.NewLarge);
end
original_render()
end
this is what i tried to do
mmm what about trying to display the stuff from scratch? Like the example in MainScreen
Followed the steps, already had IntelliJ & Git installed so it went quite fast and easily!
also you could try to move the call to original_render() before drawing your text maybe?
Oh also you might have to pass self
Anyone having issues with spawning zombies in MP and having them remain?
i tried and got the same error
perfect, that's what I'm targeting for, guess I could get rid from intelliJ
you probably have to pass self to original_render
oooh you got it
you mean they disappear after a few seconds?
They disappear instantly
Atleast when I use the same method used in the debug window
Haven't tested the debug hordeUI though maybe I should
Are there any mods or ability to get up close shots of, and different angles of character or zombie models in the game without a 3rd party tool?
can you try to call Wander() on your zombies?
Nice! ๐
tiba aprove that name
I've opened the -debug in the launch before, but I do not know how to access a debug animator. Is that native in the Solo options when launching a session?
yeah, pretty sure it will help:
public void Wander() {
GameServer.sendZombie(this);
this.changeState(ZombieIdleState.instance());
}
mmm for vehicle ther'es problably something to with with sendServerCommand or something
Can't seem to get server command to work tbh
mmm I can see this but it's only for parts:
zombie/vehicles/BaseVehicle.java: public void transmitPartCondition(VehiclePart vehiclePart) {
zombie/vehicles/BaseVehicle.java: public void transmitPartItem(VehiclePart vehiclePart) {
zombie/vehicles/BaseVehicle.java: public void transmitPartModData(VehiclePart vehiclePart) {
zombie/vehicles/BaseVehicle.java: public void transmitPartUsedDelta(VehiclePart vehiclePart) {
zombie/vehicles/BaseVehicle.java: public void transmitPartDoor(VehiclePart vehiclePart) {
zombie/vehicles/BaseVehicle.java: public void transmitPartWindow(VehiclePart vehiclePart) {
never used it either, but @thin hornet could probably have a look at your sendServerCommand code
He has, I'm probably doing something very minor but wrong
mmm in VehicleManager you have a private method like this: private void sendVehicles(UdpConnection udpConnection) {
Hmm
not sure how to reach it though
I'll do some research
@sour island let me know when you have some time, we could try to figure out how to use sendServerCommand properly
I'll dm you when I can
is it what you're talking about?
I am... not sure lol. I am seeing if there is a way to get up close shots of characters that aren't from the 3/4 top down angle
wanna make a photo album or something? ๐
Wait Lua tables indexes start a one ?! 
How did I never encountered that in 5 mods x)
been using ArrayList I presume? ๐
lol thanks anyways my dude
Again, anyone has an idea?
Is there any way I can get the player SteamID on Lua? player:getSteamID() kind of works, but since this value is a long in java, I get precision errors inside Lua..
Let me know if you get sendservercommand to work properly
I'd like to try use it to spawn vehicles in mp through lua
@weary matrix
It's not a big rush or anything, more just curious for if there is a possibility to make cooler shots
nvm i think i know it now xD
sure, in the meantime you could check /addvehicle, pretty sure it's going to be helpful
How do I use addSound() ? Because on a custom timedActions like that addSound(self.character, self.character:getX(), self.character:getY(), self.getZ(), 50, 50), that give a error (character is ofc a isoplayer)
The error: Object tried to call nil in start
I think I'm missing something before addSound() but I don't know what
Any reason as to why my map mod doesn't show up in the mod folder?
self.getZ is probably nil
why not self.character:getZ
do i need to add to my ZombiesZoneDefinition vanilla objects like nurse or doctorM if i am adding my own objects to that locations?
and will it conflict with ZZDef from other mods?
Damn I didn't see that, thx
in hydrocraft 41, is there any way to pick up an anchored mine hole?
how do I reload lua without restarting game ?
@lapis stump its best to reload the savegame. (go back to menu and go back in game)
Otherwise with the -Ddebug enabled you can access the debug window with F11.
Then you can find the script you want to reload
thx
@weary matrix tried it, addvehicle doesn't appear to work through lua though. I'm trying to make it work through completion of a recipe. Strangely addallvehicles works, but spawns every vehicle xD
Maybe I'm using addvehicle wrong
talking about this right?
* addvehicle : Spawn a vehicle. Use: /addvehicle \"script\" \"user or x,y,z\", ex /addvehicle \"Base.VanAmbulance\" \"rj\"
I didnt try it using \
Recipe.OnCreate.BuyVehicleVan(items, result, player)
addAllVehicles():("KrazAdmin");
That spawns all cars on me on completion of the buy van recipe
Atm it's just the user for testing, but I'll use x y z later
I believe I tried
addVehicle():("Base.Van", "KrazAdmin") but it threw an error
@weary matrix
how can you check if the target is a zombie ?
and will it work on MP ?
@blissful meteor ( @weary matrix ) - For vehicle spawning I use addVehicleDebug() as it seems there is more arguments to use
with debug mode enabled can i change the weather?
is that in F11 ?
no it is in debug menu
round icon on the left side of your screen below map icon
you can see it only if you enable debug (just in case)
thx didnt notice that icon ๐
np
ugh is there any one familiar with ZombiesZoneDefinition? specifically on how to make it compatible with other mods that also change zoneDefinition
maybe ask Authentic Peach?
I think he's a he ๐
well some times it is hard to say who is who from nickname ๐
indeed
Hey guys, does anyone use Autosar Trailers? Am I able to find them in an already existing save game?
@late hound hello, sorry to bother you, but if/when you have some spare time i would like to ask you some questions about ZombiesZoneDefinition!
you probably should ask this question in #mod_support
I don't think so, cars spawn at the world generation phase
hey I just made the first release of my Project Zomboid Server Tools in case anyone is interested. Should be quite handy for mod development too
https://github.com/quarantin/pz-server-tools/
Hey peeps, new to modding PZ, can't seem to find where bins are located in code to change some qualities. Can anyone tell me where they are located?
e.g. Green Bin, Wheelie Bin, not .bin files
Could someone recommend a modding for beginners skill book? I have a mod that I have permission from the author to edit and publish it to the work shop. https://steamcommunity.com/sharedfiles/filedetails/?id=1992785456
I used https://zomboid-javadoc.com/41.65/ for refrencing and https://www.tutorialspoint.com/lua/index.htm for basic overview of lua
Javadoc Project Zomboid Modding API package index
Lua Tutorial, Lua is an open source language built on top of C programming language. Lua has its value across multiple platforms ranging from large server systems to small mo
Thank you very much kind sir!
i already know how to program though might be harder for someone with no experience
If I have examples to work from I can do it
writing fresh mods? No way lol
learn as I go
Hmm, i wonder, is it possible to make a zombie that will explode when hit?
Should be possible
When a zombie dies, put a probability that he explodes or something like that
Mmmmm, that would be more complicated. Should store the variable that the zombie has already been touched. And I guess you want it to be just some zombie?
I have found a few examples for adding new items into the game with the Distributions.lua, what about removing things? If I wanted to change the loot table a bit for example, how does removing something from this work. Also, these methods for adding to the loot table seem rather... complex for something that used to be (iirc) a lot easier?
Well yeah, like random sprinters but random explosive zombies
No idea to help sry
Nah that was just a theoretical question, i doubt anyone would wanna play with this kind of zedz
Well done it could be fun, they just need to be rare and serve a bit as a boss
Finally I leave the prototyping phase and start the alpha! Many features are not shown here and more will be added.
I now take ideas to my mod, if you have some, don't hesitate
guys i need some help iam out of town and might be away for a while need someone to test out my mod and tell me if it needs patching or no your help is very much appreciatedโค๏ธ
any good pz modlists for mp?
alright, i tried a hacky mod to set PRINTDEBUG to true on RadioData and. now my console.log has hung
and when i alt-tab out of the frozen window it turns solid red
is it because i put it in shared?
i'll try moving it to client
I think I confused the Steam Workshop with a mod called "Just Muldraugh"
I thought it was straight forward :P
lmao
guys, the events OnConnected and OnDisconnect are triggered from the server?
is there a way to know which player has been connected/disconnected?
i have counter question, Do you think most of the people READ the descr? if at lest 25% had read it it would be already great!
@weary matrix PRINTDEBUG on RadioData doesn't appear in zomboid-javadoc, is that because it's a default visibility (package) field? if so, that's kind of disappointing ๐
public final class RadioData {
static boolean PRINTDEBUG = false;
I mean, I'd assume so
I read the descriptions of things
well that's you, that's probably 95% of what users of this ch also do
but there is also thousands of usual users
who don't give a f about descr and all they want to do is leave raging comment or "detailed" bug report as "this sh*t isn't working" and that's about it ๐
you can disable comments ๐
yes, but still there is some that indeed leave descriptive bug reports etc
Counter counter question, do you think they can read?
well i think they do? unless they blindly installed steam, bought PZ and went to workshop to search for mods? unless they was following images that they liked? xD
They was just following images
If the images are good that means the mod is good too!
Lol
right?
I guess SoulFilcher's mods are out
Cool
Nobody wants download spiffo surrounded by icons :P
Soul's mods are downloaded by people who already have Soul's mods
and if they do not understand some thing from img they just need to press img with finger pointing dow "rate down" coz why not?
that persons mod broke my game had to unsub
I mean, Hydrocraft was popular because girl and mod theft
You people don't like Spiffo? Do you want to get banned or something?
No, but spiffo is boring unless gun spiffo to the average user
That is interesting, never played with hydrocraft
From what I understand,
And since I'm am Admin at New Dawn/Gateway, where he was an admin once in like, 2015 or so.
He stole a lot of shit from other people
And just threw it in Hydrocraft
Yikes
Yikes
I'm honestly glsd 41 killed it
that doesnt really surprise me since there are like 15 different artstyles of varying quality lmao
Were finally switching over to Soul's stuff as a replacement
So that's why everything looked so inconsistent in that mod
the clipart farm animals are a real highlight for me
oh hey, it's Frackin' Universe all over again
lmao
oh was that stolen too lmao?
yeah
yikes
lot of it was taken from other mods without credit
yikes x2
hydrocraft is basically frackin' universe for project zomboid lmao
both are fun and were basically essential for playing
well do be honest, can you say for sure that any thing that any one from modders have done in pz was original and unique idea? and was not mentioned in some way or another in some other projects books movies etc?
ohhhh my, what a big responsibility!
there's a difference between "inspired by" and "literally taken verbatim"
im not trying to defend author of hydro and i have not used it even once
then what are you trying to do
but its just in our time it is hard to create some thing unique
if i had a penny for the amount of times that an indie game had a big mod with a ton of content of questionable quality that was really popular for some reason i'd only have 2 pennies but its weird that its happened twice
so you're trying to defend the author of hydrocraft?
ehm read things i wrote earlier? ๐
because if not, it's really unclear what it is you're trying to do
"can you say for sure that every idea is original?" is a non-sequitur when we're talking about intellectual property theft
dude we're talking not about ideas, but about literal mechanics and content
"Y was inspired by X" is not "Y stole wholesale from X"
so are you saying that he stole "ready code" from some other mods and integrated it in his own?
was this to the wrong message lol
What did the author of hydro do?
uuhh? yes, what the fuck discord
discord moment lmao
more important. Is there anything from Hydro that we still don't have covered by a more recent, better implemented mod?
@teal slate that's a good question. I have no idea why it's missing but it should be there
i guess animals but those are gonna be vanilla soon
honestly if i wanted any mod of questionable quality to make a comeback it would be uuuh
only the private stuff are "supposed" to be missing
OZMeds
i put some work into getting it to work in build 41, but also i'd need to contact the original author about licensing to upload a fixed version
man do you know the best rule in the world is not to believe/trust of what other ppl say unless you check it yourself?
Mods aren't intellectual property...
From my understanding, it was literal assets and code from other people
uh, code is
lmao
like
there's a reason SS13 is a lawyer's worst nightmare
And iirc, it killed a lot of mods
the copyright law there would take decades to unravel
yeah, we don't really need to spend time trying to add that
Reason why I'm happy Soul's stuff is modular
No it wouldn't. This is armchair lawyering. Mods are open source
no they arent
open source has nothing to do with it
I also should say, that like
you can extract the source from your mods folder
but open source does not mean it's public domain
open source repositories have licenses
since we still have another season of the current lore to finish out in B40, we still have to use hydrocraft
if they have no license it's under All Rights Reserved by default
Depends on what country you are in, at least art in your mod is intellectual property
all my mods are published under The Unlicense which means they're released into the public domain
From Valve:
Using content from other mods
It's a sad fact, but in some cases content is also being lifted from one mod to another. It's often a misconception that just because a mod is free to download, its contents are also free for you to take and choose from as you wish.
Even if a mod is free or not, the creators of any original work included within it (sounds, materials, models, source code) own the copyright for their work. This is true if you are a high-school kid, a corporation, or just some other modder who puts stuff together for fun. Every author gains these rights by default when they create their work.
The authors alone can decide how and who may use their work and have the law behind them should they decide to take issue of anything used without permission. If you see something in another mod that would be of use to you in your own mod or map, your first step should be to contact the mod team and then specifically ask the creator of the item your after. They and they alone can give you permission to use their work.
If you create contents for mods and don't mind other people using your content, then it could save a lot of trouble and benefit the community as a whole if you release your works under a Creative Commons license. See the Official Website to select a License for your works.
Mods are open source because they themselves build off of an already existing product
That's not what open source means.
You're thinking of contagious licensing clauses like those in AGPLv3, but PZ is not AGPLv3
Look
open source is free, but not as in free beers ๐
Mod Theft is Bad
I'm pretty sure PZ is actually All Rights Reserved by TIS
Lifting Mods and not providing credit is bad
Claiming that EVERYTHING WAS HIS OWN WORK LIKE HYDRO DID WAS BAD
can we at least agree on that?
There simply isn't enough case law on the subject to talk about this in a legal sense
i have been doing open source development for years what are you talking about
licenses exist
Who cares about legality?
Bad, maybe, criminal? No
Who said anything about Criminal?
I actually never tried hydro, it felt to much. Was interested in it but never pulled the trigger on it
Code without a license is assumed to have all rights reserved by the original author
Here
if i switch my mod to private will it unsubscribe ppl ?
Personally, my mods have no liscence and are open source. I could care less someone use it in his modpack.
If it breaks that his server problem.
Can we like....
never said they would be able to successfully litigate it
Stop this arguement?
here goes the drama....
Get the popcorn
this is why I use the Unlicense
and i thought it was ch for modding ....
This sounds like... pointless in the face of "What Hydro did was shitty."
it releases it into the public domain
either way its still shitty to just steal mods and say you made them
Basically,
technically "no license" -> "the original author can tell you to stop whenever and you have no rights"
we need #quarreling chennel
I didn't mean to
"the unlicense" -> "the work is in the public domain" -> "the original author has no control over what you do"
On the topic of mods, Why isn't there a breakdancing zombies mod, instead of eating you after you die they jsut breakdance on your corpse
I don't see why people always have to grandstand over this stuff
It's a discussion that still have a purpose.
We've been asked to move on.
official pz drama channel
Yeah, thanks
Can't get an answer for legitimate question but can watch quarrelling with popcorn, typical Discord chat is typical
Like, Jade stopped, so like, if she stopped, you should stop too tbh
Probably scripts?
That's pretty unusual tbh, it was pretty quiet for the last week
Class = {}
__classmetatables[Method.class]["__call"] = function (self, args) return self:invoke(args) end
for i=0, getNumClassFunctions(RadioData.class) - 1 do -- any class would work
local func = getClassFunction(RadioData.class, i)
Class[func:getName()] = func
print(func:getName())
end
local PRINTDEBUG = Class.getField(RadioData.class, "PRINTDEBUG")
printdebug is null ๐ญ
@teal slate mmm it's really weird, can't figure out why it's missing. I'm just using the javadoc command, so it should be there
guess because the field is package-level visibility we can't access it
is it private members that are supposed to be missing, or is it all non-public members?
That being said, I did ask last night about if a new version of WordZed will come out soon so we can create CDs/VHS tapes
i'm thinking it's probably the latter, unfortunately
Because from the code I found, I don't think I can reverse engineer it
@teal slate but for example this one is too: https://zomboid-javadoc.com/41.65/zombie/characters/IsoPlayer.html#accessLevel
maybe i should try getDeclaredField??
it's not, it's public
@teal slate only private members should be missing
@teal slate searched all files in scripts with multiple possible alt names couldn't find any reference, so I'm thinking I'm soo noob to PZ modding that they aren't even mean to be in there to begin with and I just don't know better
that said, protected ones are visible
oh my bad
oh wait, the names you're searching are probably in shared/Translate
YUP
./shared/Translate/EN/Moveables_EN.txt: Empty_Mall_Decoration = "Mall Garbage Bin",
./shared/Translate/EN/Moveables_EN.txt: Fossoil_Garbage_Bin = "Fossoil Garbage Bin",
./shared/Translate/EN/Moveables_EN.txt: Garbage_Bin = "Garbage Bin",
./shared/Translate/EN/Moveables_EN.txt: Green_Garbage_Bin = "Green Garbage Bin",
./shared/Translate/EN/Moveables_EN.txt: Grey_Garbage_Bin = "Gray Garbage Bin",
./shared/Translate/EN/Moveables_EN.txt: Recycle_Bin = "Recycle Bin",
./shared/Translate/EN/Moveables_EN.txt: Round_Bin = "Round Bin",
./shared/Translate/EN/Moveables_EN.txt: Spiffos_Garbage_Bin = "Spiffo's Garbage Bin",
./shared/Translate/EN/Moveables_EN.txt: Washing_Bin = "Washing Bin",
./shared/Translate/EN/Moveables_EN.txt: Wheelie_Bin = "Wheelie Bin",
which means those strings will have to be referenced somewhere
odd
All I was trying to do was update stats to make bins collect rain lol
trying to find it...
That would be nice, will you make it show the water inside?
On first pass probably not, if I get further into PZ modding then possibly
I've considered both using them as standard and requiring bleach/cleaning agent to make them usueable, either way it'd be nice to not be a carpenter to catch meaningful rain.
terrified at the prospect, but it might be that they're only defined on the maps in some weird bespoke way
still searching though
That's what I thought
What exactly you guys are trying to do?
Find where the Bin items are referenced like the other items to hopefully alter their qualities such as rain collection
Ok but why do you need to alter stats of the original ones
If you would anyway combine/craft them with bleach into different ones
they said that was only one idea
tile definitions
and the worst part.... overriding tile definitions
I had a feeling they'd be there but not being familiar I went for asking vs seeking for hours
It'd be nice to have them useable without crafting such as with the iron barrels that can be found
hold on though, let me check something
aaaaaaaaaaaaaaargh
you have to edit it in the tile definitions
i really wanna make an in depth trading card mod, where you can open packs of cards and get 3 cards from it, with diff rarities and holos / foils and stuff, i just am not sure where to start that project
i can make all the visual and 3d assets for it but i have 0 idea how to code lua or java, or script at all
do u guys have any pointers for how i might do this? :o
Sounds cool
is that some kind of modding tool with UI?
the packs wouldnt be too common unless you found like a dedicated comic book store or smth
@teal slate Thank you ๐
You will have to learn the basics of adding items and recipes
Whats the preferred tool for editting .tile files?
yeah, it's TileZed
i've never used it before now :P
oh was hoping it was a mod tool for like the whole game ๐ฆ
ha-ha.... no
is it possible to give certain items an animated icon? like in the inventory?
it would be cool to give the foil cards a slight animated glitter around the edges
Not sure but i think no
@teal slate this is the script I use to generate the javadoc if you want to have a look: https://github.com/quarantin/beautiful-java/blob/main/scripts/javadoc.sh
add -package to javadoc
default is protected and public only, i think
however i think excluding package members is a good idea because i don't think they're accessible?
Class = {}
__classmetatables[Method.class]["__call"] = function (self, args) return self:invoke(args) end
for i=0, getNumClassFunctions(RadioData.class) - 1 do -- any class would work
local func = getClassFunction(RadioData.class, i)
Class[func:getName()] = func
--print(func:getName())
end
local PRINTDEBUG = nil
for i=0, getNumClassFields(RadioData.class) - 1 do
local field = getClassField(RadioData.class, i)
print(field)
if field:getName() == "PRINTDEBUG" then
PRINTDEBUG = field
break
end
end
--local PRINTDEBUG = Class.getField(RadioData.class, "PRINTDEBUG")
print(PRINTDEBUG)
PRINTDEBUG:setBoolean(RadioData, true)
PRINTDEBUG:setBoolean(RadioData, true) still gives attempted index: setBoolean of non-table: null and PRINTDEBUG is nil
:|
gonna rerun now that i added print(field)
oh no it's
getting the fields on class
๐
RIGHT because. it does class
agh
time to reimplement getNumClassFields
does anyone know the image size of the little item icons
#RadioData.class:getDeclaredFields() let's try this
it can be whatever you want as long as it's .png
although if you want it to be exact as vanilla you can look in the texture files
Class = {}
__classmetatables[Method.class]["__call"] = function (self, args) return self:invoke(args) end
for i=0, getNumClassFunctions(RadioData.class) - 1 do -- any class would work
local func = getClassFunction(RadioData.class, i)
Class[func:getName()] = func
end
local PRINTDEBUG = Class.getField(RadioData.class, "PRINTDEBUG")
PRINTDEBUG:setBoolean(RadioData, true)
this might actually work
i think im gonna start actually making assets for this trading card idea
nope ๐ agh
oops, wrong number of args
Class.getField(RadioData.class, "PRINTDEBUG")
oh i have to use getDeclaredField
only that can get package/protected/private fields
__len not defined for operand
that's progress baybee
32x32
ty :)
this is becoming a mess
Array = {}
for i=0, getNumClassFunctions(declaredFields) - 1 do
local func = getClassFunction(declaredFields, i)
Array[func:getName()] = func
end
so many shims
all this just to enable PRINTDEBUG on RadioData
Ah yes, the alien language
i am using reflection on reflection on reflection
this file is basically a hall of mirrors now
oh god i know why it didn't work
because i used getName
and that doesn't take into account signatures
local ArrayClass = Class["public static java.lang.Class java.lang.Class.forName(java.lang.String) throws java.lang.ClassNotFoundException"]("java.lang.reflect.Array")
this is what i have to do now
obviously a texture for a model in game shouldnt be huge or too detailed but is there a max size
@teal slate so should I push the doc with -package?
@@ -161,6 +186,20 @@ extends java.lang.Object</pre>
</section>
<section class="details">
<ul class="details-list">
+<!-- ============ FIELD DETAIL =========== -->
+<li>
+<section class="field-details" id="field.detail">
+<h2>Field Details</h2>
+<ul class="member-list">
+<li>
+<section class="detail" id="PRINTDEBUG">
+<h3>PRINTDEBUG</h3>
+<div class="member-signature"><span class="modifiers">static</span> <span class="return-type">boolean</span> <span class="member-name">PRINTDEBUG</span></div>
+</section>
+</li>
+</ul>
+</section>
+</li>
<!-- ========= CONSTRUCTOR DETAIL ======== -->
<li>
<section class="constructor-details" id="constructor.detail">
or even -private?
Don't think there is, at least before it wouldn't just load the texture
-private would display private variables, though i'm not sure how useful seeing those would be
I used 1024*1024, you don't really need more
askin cuz im making the model for a card pack rn
I think it does
I guess would be nice to have private fields (some useful methods are private too) just knowing they exist can help
but that also makes a lot of extra noise
people might get confused like "oh but the method is here but I can't use it" etc
Hand eating gang
lol what, you could eat with spoons? oO
I suggest looking into commanders hobbies mod. its an old mod that introduced trading cards.
yeah i saw that but i didnt really execute it how i envisioned it
tbh the only reason im still using commanders mods is becouse of the trading cards, if you make that mod then ill defno use it
i dont know how to make it in terms of actually implementing it in the game, but im making models / stuff for it right now
omg finally
if someone wants to help me code it into the game then im all down
i was just about to ask about that
Unfortunately just altering the tile definitions didn't allow for bin rain collection so I'm guessing the moveable items are referenced elsewhere too unless a property they already have prevents the functionality.
I am committing sins against modding
Class = {}
__classmetatables[Method.class]["__call"] = function (self, args) return self:invoke(args) end
__classmetatables[Field.class]["__call"] = function (self, args) return self:get(args) end
function exposeClass(exposedClass, container)
for i=0, getNumClassFunctions(exposedClass) - 1 do -- any class would work
local func = getClassFunction(exposedClass, i)
func:setAccessible(true)
container[func:toString()] = func
--print("'"..func:toString().."'")
end
for i=0, getNumClassFields(exposedClass) - 1 do -- any class would work
local field = getClassField(exposedClass, i)
field:setAccessible(true)
container[field:toString()] = field
--print("'"..field:toString().."'")
end
end
exposeClass(RadioData.class, Class) -- any class would work
local Object = {}
Object.class = Class["public java.lang.reflect.Type java.lang.Class.getGenericSuperclass()"](RadioData.class)
local objectInstance = Class["public java.lang.Object java.lang.Class.newInstance() throws java.lang.InstantiationException,java.lang.IllegalAccessException"](Object.class);
exposeClass(objectInstance, Object)
local Constructor = {}
Constructor.class = Class["public java.lang.Class java.lang.Class.getComponentType()"](Object["public final native java.lang.Class java.lang.Object.getClass()"](Class["public java.lang.reflect.Constructor[] java.lang.Class.getConstructors() throws java.lang.SecurityException"](Object.class)))
exposeClass(Constructor.class, Constructor)
behold, the ability to expose an arbitrary class's methods and fields on a whim (in debug mode only) @weary matrix
i'm doing all of this just so i can set one (1) static var
i want the TIS devs to look upon this monstrosity and weep
or like, the Kahlua devs
๐คฃ
every time i do Array.class = Class["public static java.lang.Class java.lang.Class.forName(java.lang.String) throws java.lang.ClassNotFoundException"](Class.class, "java.lang.reflect.Array") it gives me Caused by: java.lang.IllegalArgumentException: wrong number of arguments
blurgh
... oh wait
is it static??
it's static
yeah has to be
still getting the error even with just Array.class = Class["public static java.lang.Class java.lang.Class.forName(java.lang.String) throws java.lang.ClassNotFoundException"]("java.lang.reflect.Array")
guess Kahlua is trying to load the .class but can't find it?
see, that's weird because it's a java builtin
and it's wrong number of arguments
oh
not anymore
oh?
that's the error i'm getting still
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
any clue which method is receiving invalid number of arguments? is it forName?
it's forName, yeah
and what do you pass it?
ERROR: General , 1640831545809> ExceptionLogger.logException> Exception thrown java.lang.reflect.InvocationTargetException at GeneratedMethodAccessor579.invoke.
ERROR: General , 1640831545809> DebugLogStream.printException> Stack trace:
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.GeneratedMethodAccessor579.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
...
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
with uhhh
Array.class = Class["public static java.lang.Class java.lang.Class.forName(java.lang.String) throws java.lang.ClassNotFoundException"]("java.lang.reflect.Array")
if kahlua doesn't convert lua strings to java strings i'll be so mad
can you show the call itself?
oh ๐
__classmetatables[Method.class]["__call"] = function (self, args) return self:invoke(args) end
this is how it's invoked
mmm but what argument are you passing to forName? I just see "java.lang.String"
no, no
Class["public static java.lang.Class java.lang.Class.forName(java.lang.String) throws java.lang.ClassNotFoundException"]
this is how you get the method
by passing the fully qualified name or w/e
including signature
then i pass ("java.lang.reflect.Array")
still unsure why it's giving that
wait
i can use reflection to get the proper number of arguments ๐
PZ is using java 15 now IIRC https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/lang/Class.html
but for example if a function expects a string but you pass null, then reflection will fail
to find the method/constructor etc
the signature indicated that it takes java.lang.String and is static
๐ค
printed the function and it agrees
public static java.lang.Class java.lang.Class.forName(java.lang.String) throws java.lang.ClassNotFoundException
have you tried to strace the process to see if it's looking for a .class? ๐
uuuuuuuuuuuuugh no ๐ญ
ERROR: General , 1640831932303> ExceptionLogger.logException> Exception thrown java.lang.reflect.InvocationTargetException at GeneratedMethodAccessor579.invoke.
ERROR: General , 1640831932303> DebugLogStream.printException> Stack trace:
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.GeneratedMethodAccessor579.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at se.krka.kahlua.integration.expose.caller.MethodCaller.call(MethodCaller.java:62)
at se.krka.kahlua.integration.expose.LuaJavaInvoker.call(LuaJavaInvoker.java:198)
at se.krka.kahlua.integration.expose.LuaJavaInvoker.call(LuaJavaInvoker.java:188)
i'll look at the kahlua source
I hope you have some dolipran ๐
@Override
public void call(Object self, ReturnValues rv, Object[] params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
if (!hasSelf) {
self = owner;
}
Object ret = method.invoke(self, params);
if (hasReturnValue) {
rv.push(ret);
}
}
I wish i could undrstand this code so i could laugh too ._.
the code isn't what's being laughed at, it's me :P
i am doing all of this to enable one (1) static var
... which i think i could probably do anyway
hold on
I can safely say a lot of us programmers have been there before and laughed at ourselves for it, our effort vs reward scales often don't work ๐
oh my god i don't need to expose java.lang.reflect.Array
because.
they exposed Iterator already...
or i could try java.util.Arrays
I think I'm giving up on making bins water collectors for now and moving on to making it a whole new craftable instead
I created an item with the variable DisplayCategory = Surgeon Kit but in games the category displayed is IGUI_Item_Cat_Surgeon Kit. Any idea how to get rid of IGUI_ItemCat_?
You need to define translations for it.
okay, incredibly interesting:
Arrays.class = Class["public static java.lang.Class java.lang.Class.forName(java.lang.String) throws java.lang.ClassNotFoundException"]("java.lang.Object")
this gives IllegalArgumentException
@drifting ore Steam Games\steamapps\common\ProjectZomboid\media\lua\shared\Translate\EN\IG_UI_EN change in this file
The problem is that I am using item:getDisplayCategory() to differentiate between several items. Isn't that going to be a problem? I must also change the place where I make the difference I imagine
Just outta curiosity, how hard would it be to create a new UI panel?
@iron salmon - Idk if this is the right place to ask but I'm stumped on something that I don't think anyone else could have experience with:
if (GameClient.bClient && this.authOwner == null && (!this.bRemote || this.lastRemoteUpdate > 5000)) {
DebugLog.log(DebugType.Zombie, "removing stale zombie 5000 id=" + this.OnlineID);
DebugLog.log("Zombie: removing stale zombie 5000 id=" + this.OnlineID);
removing stale zombie 5000.instance.removeZombieFromWorld(this);
} else {
When I use addZombiesInOutfit() the zombies instantly despawn - giving the printout message above. I looked in media/lua/client/DebugUIs/ISSpawnHordeUI.lua which is the debug spawners:
if isClient() then
SendCommandToServer(string.format("/createhorde2 -x %d -y %d -z %d -count %d -radius %d -crawler %s -isFallOnFront %s -isFakeDead %s -knockedDown %s -health %s -outfit %s ", self.selectX, self.selectY, self.selectZ, count, radius, tostring(crawler), tostring(isFallOnFront), tostring(isFakeDead), tostring(knockedDown), tostring(health), outfit or ""))
return
end
for i=1,count do
local x = ZombRand(self.selectX-radius, self.selectX+radius+1);
local y = ZombRand(self.selectY-radius, self.selectY+radius+1);
addZombiesInOutfit(x, y, self.selectZ, 1, outfit, femaleChance, crawler, isFallOnFront, isFakeDead, knockedDown, health);
end
Which features a isclient check that deviates from addzombies to a sendservercommand - which makes sense as the command originates off UI - and those zombies don't get hit with the "5000" message and don't get instantly deleted. If my lua is in the server folder, and I'm using addZombiesInOutfit() why are they getting instant deleted?
Similar issue with vehicles using addvehicledebug() - they appear for host but not players, and they don't get saved.
They also feature a sendservercommand for UI calls on the debug panel.
Arrays.class = Class["public static java.lang.Class java.lang.Class.forName(java.lang.String) throws java.lang.ClassNotFoundException"](Class.class, "java.lang.reflect.Array") throws java.lang.IllegalArgumentException ๐ฉ
okay so it turns out this is because the jvm got tired of giving me detailed debug info
tried a fresh restart :)
how would i go about creating an infinite stamina trait?
i would like to try to survive as long as possible with extreme sprinter population with pinpoint hearing, bloodhound smelling and eagle sight, by running as much as possible
Hello everyone. I am wondering if anyone would be so kind to point me in the right direction. I have a lot of experience in C+ and Python coding but never sat down to learn lua deeply (I do this as a hobby). Is there a good updated tutorial somewhere? I'm not sure which ones are good...I am specifically trying to figure out how to pull a players username
you can browse the java and documentation for exposed classes and methods
but once you have the IsoPlayer in question you can use :getUsername()
Yeah, I think once I figure out the syntax for lua, it will click much faster. I've been coding in python for so long that it feels like I'm back to zero lol
A lot of the same principles. I love how easy it is to add new items, weapons, and etc
Wait....does does IsoPlayer player pull up the local player?
local username = Isoplayer(player):getUsername();
Like such?
not quite
each game has a client attached to it - getplayer() is short hand for getting the main player
it gets a bit trickier when you have coop players or online players
Gotcha, so I assume in PZ that getplayer() on a dedicated server would not necessarily pull the local player
but the process is to gather up the isoplayers
Found my answer a bit ago, but thanks for the reply here <3
I got something written up, but I know it's wrong lol
in mp the code would be running on client side
then updating the server
so getplayer would pull what ever player is doing the code
Hmm okay, so close
So I am just trying to do check a players username and then add a trait(I think should be simple?) Could I paste the short snippet here? I think I see what you're saying but I am failing to use the getplayers() correctly
I do appreciate your time
are you trying to add a trait based on their username?
local function IdentifyPlayer()
local username = Isoplayer(player):getUsername();
local players = getOnlinePlayers();
print(tostring(Isoplayer(player):getUsername()));
local array_size = players:size();
for i=0, array_size-1, 1 do
local player = players:get(i);
if username == "Tester3" then
TraitFactory.addTrait("Testing", "TestingTestingTesting",-1,"Did this work", false, false);
end
end
end
Yes
and sure - just know discord uses markdown for code
```lua
codehere
```
Oh! good to know
That's really neat
I appreciate your patience, I am new to lua...I wish I spent more time with it back in the Gary's mod days
local function IdentifyPlayer()
local players = getOnlinePlayers()
for i=0, players:size()-1, 1 do
local player = players:get(i)
if player:getUsername() == "Tester3" then
TraitFactory.addTrait("Testing", "TestingTestingTesting",-1,"Did this work", false, false)
end
end
end
it's probably your former experience but you can't declare types in lua
also ; are unneeded
you got the array use right
which most people get hung up on
as there are lua tables/lists
so having a java array to deal within lua gets weird
Yeah, I can see that
Chuck, you are a very helpful person
You just saved me a headache
idk if this is doing what you think it is though'
Hmm...maybe not?
I use this later ```Events.OnCreateSurvivor.Add(IdentifyPlayer);
To call it upon character creation...I believe?
TraitFactory (and all the factories as TIS calls them) are for housing behaviors/enums/etc
so I think this is creating a trait
not actually assigning it
OnCreatePlayer also works
Okay, I believe that is what I want, so if you have a certain username the trait pops up and you can select if, if you want.
idk if survivor is used anymore as it was meant for NPCs
I mean traitFactory add makes a new trait in general
so anyone would be able to pick it
Could I ask if this is a reference resource you'd use? https://projectzomboid.com/modding/zombie/network/GameServer.html
if you want only specific people to be able to pick it or be assigned it you'd have to dig into the UI lua to hide certain traits
that documentation is good
I think @weary matrix made an updated one
Oh really, because it loops through and 1 person on the server has that username, then all could use it?
unless I'm mistaken TraitFactory add would be adding to the global list of traits
I've read through traits and professions for Skill Recovery Journal
the term factory is generally something used to house behaviors/types of objects/instances
I cannot stop dying, i love this game! Please help
This is #mod_development
Gotcha
I'm not really formerly trained or anything - so I only know how TIS uses it
FWIW, only traits with a non-zero cost show up in that list
Well, so far the trait DID show up - so that's a good sign...I will have to grab a buddy and test if it's global
oh, that's only the good trait list actually
if you want to hide it you can look for the isRemoveInMP() calls
that might remove it entirely rather than just visually
Okay. I will have to find a different way, @sour island was correct
What is the point of this trait tbh?
It now shows for any username lol
nah, that's only queried for the trait list in the UI
see CharacterCreationProfession:populateTraitList
@sour island Honestly? I am just learning. I was thinking of making a "unique trait" for a friend of mine that only he could use...makes em feel special.
you'd also have to practice safe overloading of lua functions
hmm
maybe you could just tap into the UI on character stats
and spoof a trait?
free traits are also hidden from that list, but that might also hide from from the stats window
idk if it's like this for other games but modding PZ to do things it's not already doing can be a labor of love
Haha okay, so what I'm hearing is that I picked something to try and do that's probably above my skill level at the moment
I'm looking at CharacterCreationProfession right now
Interesting stuff
yeah, looks like you can hide it from the trait selection UI and still have it appear in the stats panel
maybe not above your skill level - as this isn't a project to be distributed but definitely something that's roundabout
that'd work then
you can use Events.OnGameBoot instead
so it's only added once
then in oncreateplayer figure out the actual trait adding per player
it's probably a method with in isoplayer or isogamecharacter
it's how profession traits like Burglar are handled:
TraitFactory.addTrait("Burglar", getText("UI_prof_Burglar"), 0, getText("UI_trait_BurglarDesc"), true);
--^-- make it free
Okay, that makes sense
So add the trait upon launch
Hidden
Then check for the player name and add it that way
Okay
Using CharacterCreationProfession:addTrait ?
to add the trait to a player you want to do player:getTraits():add("My Trait Name")
where player is some variable with the player you want to add the trait to
that's the list of all traits, not a characters traits
oh nvm
it's not, I think, you're right
Man, I really appreciate both of your help
You saved me hours of scratching my head
It's starting to make a lot more sense. I will need to get better at seeing what functions are already around and how to use them
I am going to brb and see if I can write it up
holy trouble batman!
Anybody know if True Music can work with custom music on servers?
Like would the host have to place the music, or would everyone have to, or does anyone know how that'd work
I'm not 100% sure Teemo, but I'm sure it doesn't work unless everyone has the same music
@tacit ermine @sour island Ah man, I'm so close lol. I can get the trait to be made and be invisible (I can add it via admin console) but it won't add during character creation. Do you have one last round of help in you for the night? It's okay if not too
how and when are you trying to add the trait to the character?
is it possible to change electricity and water cutoff to something like 3-5 days instead of 0-30 ?
Yeah, servertest.ini settings, you can set it up to however you'd like. If you're hosting a server
I'm sure I'm messing that up, this is what I have
local function IdentifyPlayer()
local players = getOnlinePlayers()
for i=0, players:size()-1, 1 do
local player = players:get(i)
if player:getUsername() == "Tester3" then
player:getTraits():add("Testing1234")
print ("Testing")
end
end
end
and then
Events.OnCreatePlayer.Add(IdentifyPlayer)
TraitFactory.addTrait("Testing1234", "Testing1234",0,"Did this work?", true)
That gets ran in a prior function
does the "Testing" print?
I have -debug on, but I don't actually see where it would be printing
In the console.txt?
wherever your console output is going, yeah
getonline players also only works for MP
No, output. Hm the function is not executing
Good to know, I am testing it on a dedi