#mod_development
1 messages ยท Page 2 of 1
have fun
no problem son
xD stop right there criminal scum
was that from his adult swim show?
look like the black version of the skyrim guards
no, his mugshot
didn't zoom in, the lighting for the armor is overhead and lines up well lol
i love it so much lol
Nevermind, I figured it out.
Howdy folks, anybody know much about the evolved recipes? Trying to get an ingredient to offer three uses
If you want an ingredient to offer three uses, then for the "evolvedrecipes" property, you need to set whatever the hunger removal of the spice is divided by three to how many parts are consumed by each food type (soup, stew, etc.) it can be used in. At least, that's how I understand it.
You can use my crayon edit for reference:
item Crayons
{
DisplayCategory = Food,
Weight = 0.1,
Type = Food,
DisplayName = Crayons,
Icon = Crayons,
CantBeFrozen = TRUE,
EvolvedRecipe = Soup:1;Stew:1;Pie:1;Stir fry Griddle Pan:1;Stir fry:1;Burger:1;Salad:1;Roasted Vegetables:1;RicePot:1;RicePan:1;PastaPot:1;PastaPan:1;Sandwich:1;Sandwich Baguette:1;Taco:1;Burrito:1,
Spice = true,
HungerChange = -10,
ThirstChange = 20,
UnhappyChange = 20,
WorldStaticModel = Crayons,
}
With this edit, I made crayons give 10 hunger, and each time it's used as a spice, it consumes 1 hunger's worth of crayon. So, it has 10 uses in evolved recipes.
But if I changed it to 5 instead of 1, it would use 5 hunger's worth of crayon, giving me two uses.
Also, does anyone know if there's any existing code floating around that templates removing knowledge of certain recipes? I've been trying to figure out how to do such a thing but (at least for someone like me) it's not coming together the way I was hoping.
Ah, sweet! I was thinking that the EvolvedRecipe = number was the uses. But that's good to know! I had the hunger set to 3 and the evolved recipe to 3. I very much appreciate it!
Been trying to figure that out for a bit, I again very much am thankful
No prob, if I end up being wrong let me know, but I'm 99% sure that's how it works unless I got very lucky with my evolved recipe edits lol
I shall let ya' know!
Heck yeah, it works! Got the little Lunchable pizza sauce to work fully now! Thank you very much!
No problemo, I'm glad I could have helped bring lunchables to Project Zomboid. ๐
Aside from translations, is there a way to change or revert the display name of a base vanilla item that's been altered by another mod? I'm working on an add-on mod.
@thin hornet I once again come with a question.
I'm listening to the LevelPerk event, and if I find the level is higher than the skill cap (which is properly calculated elsewhere), I limit it like this:
character:getXp():setXPToLevel(perk, max_skill)
character:setPerkLevelDebug(perk, max_skill)
Issue is, it seems this infinitely loops.
Works fine if I debug set the perk level using the admin menu
Not so much when it's properly levelled with XP though
Any clue what might be the issue?
Update: So, setXPToLevel works, but trying to reduce a skill level using setPerkLevelDebug in conjunction with setXPToLevel seems to not work
Results in this, and unless I add a killswitch after the first run, it infinitely triggers
I want to level 1 level down, and set XP to that level so it doesn't immediately / repeatedly level back up.
@jagged ingot Sorry for the ping, but I figured I'd ask since you were helpful last time.
I would take a look at your code first to make sure it isn't a bug. Next I would do research into what those calls do. This might be why people can't take away XP with the server command.
As far as I can tell, it's not a bug
In general for every development project, when something goes wrong, it's best to assume it's your issue first. ๐
Ok then the next step would be digging.
My main lead is the LevelPerk event triggering potentially too often
Though, I haven't the faintest what's causing that.
Oh. You could set a flag and then check for in on that update.
It's too bad that event functions can't return true/false to tell the event manager to cancel.
Triggering a levelup using the admin menu works fine and gets the skill levelled back.
Levelling up using exp on the other hand, causes an infinite LevelPerk trigger.
Even when I explicitly set the experience below the cap (as can be seen in the above screenshot)
It's as if the XP set doesn't go through properly / the Levelling takes precedence - infinitely?
I have a debug question. How do I edit the weather? I am trying to look at a model I have been working on ingame, but its just been a thick fog for like 5 ingame days straight
Though, if I make it so my function can only be called once (through a global var), it stops fine. Albeit without actually de-levelling the skill. Only the XP is set "properly" (negative)
Sometimes altering values are handled as proxy variables in the engine.
A thought for if you go digging further.
The relevant bits of code are this, for reference:
if level > max_skill then
-- Cap the skill level.
character:getXp():setXPToLevel(perk, max_skill)
character:setPerkLevelDebug(perk, max_skill)
end
With level the level that is passed by the event, as the level the skill is raised to.
With max_skill the skill level cap I calculate. I have verified this calculates fine.
With perk the perk that is being levelled up.
With character the character that is levelling up a perk.
This works properly if the skill isn't levelled with XP, but rather set explicitly using the admin panel skill "add level" button.
Debug mode. You can open the climate manager then. https://pzwiki.net/wiki/Debug_mode
If you need a batch file to run the game in debug mode, I can provide one. I don't know the policies about uploading it here.
Oh wait nvm
To enable the debug mode, hold LShift while the game is booting, or for a more permanent option, add -debug to the game launch parameters prior to booting the game.
I'm too oldschool haha. (Still types mspaint in the start menu or start + r)
Take a look at how that admin panel is executing when running that.
It sets the xp explicitly to the level's minimum xp
Which is why I'm confused as to why my implementation isn't working
Did you walk the code?
The XP is being set, and the setPerkLevelDebug function works fine at setting the level. Issue is something (presumably something to do with the xp) keeps triggering the LevelPerk event
Maybe there's other code that stops that cycle from occurring.
I would suspect that it's somewhere either in the debug Lua code or somewhere else. Walk that code backwards and if you don't find it, take a search tool and look for the LevelPerk event in the entire Lua codebase.
That debug Lua code section gave me a hell of a headache when writing code to analyze the PZ Lua stuff.
It's not meant for the general playerbase to mess with so it's not written like the other areas of the Lua codebase.
Can't seem to find anything tbh
For all I know code stopping the LevelPerk event from firing is likely in another folder.

Discord is preventing me from posting a code snippet?
Anyway
This is what I could find in XpUpdate.lua
Doesn't seem particularly interesting for my case though
Well it gave me a thought. Would another perk or status cancel out your change?
It shouldn't
I can't alter the pain moodle in debug mode. It's due to BodyDamage.
It shouldn't but we can't verify that.
No, like, I can verify it works if there's no XP gain involved
It seems to be specifically something about levelling skills through XP
Ok. I'll trust you on that. This is me guiding you about how to approach the problem step-by-step.
This is something I don't know myself however this is how I'd begin to investigate it.
Like, I've gone through the javadoc, but that thing has very little documentation.
People seem to have done the same thing I have, but for actually levelling up skills.
I'm assuming something weird is happening because I'm trying to level it down
Have you gone through the Java itself?
The docs are only as good as telling you the names and methods of classes.
This is the closest I could find, for example.
But that doesn't deal explicitly with the LevelPerk event
Couldn't find the exact method related to LevelPerk
So you did check out the decompiled stuff?
I tried a search through it with my IDE. It couldn't find it though
Might have been a me issue, however.
It picked up fine on similarly named but unrelated entries in the Lua Zdoc though
Do you have any clue where Events are defined?
public void LoseLevel(PerkFactory.Perk var1) {
PerkInfo var2 = this.getPerkInfo(var1);
if (var2 != null) {
--var2.level;
if (var2.level < 0) {
var2.level = 0;
}
LuaEventManager.triggerEvent("LevelPerk", this, var1, var2.level, false);
if (var1 == PerkFactory.Perks.Sneak && GameClient.bClient && this instanceof IsoPlayer) {
GameClient.sendPerks((IsoPlayer)this);
}
} else {
LuaEventManager.triggerEvent("LevelPerk", this, var1, 0, false);
}
}
PerkInfo var2 = this.getPerkInfo(var1);
if (var2 != null) {
--var2.level;
if (var2.level < 0) {
var2.level = 0;
}
public void LevelPerk(PerkFactory.Perk var1, boolean var2) {
Objects.requireNonNull(var1, "perk is null");
if (var1 == PerkFactory.Perks.MAX) {
throw new IllegalArgumentException("perk == Perks.MAX");
} else {
IsoPlayer var3 = (IsoPlayer)Type.tryCastTo(this, IsoPlayer.class);
IsoGameCharacter.PerkInfo var4 = this.getPerkInfo(var1);
if (var4 != null) {
++var4.level;
if (var3 != null && !"Tutorial".equals(Core.GameMode) && this.getHoursSurvived() > 0.016666666666666666D) {
HaloTextHelper.addTextWithArrow(var3, "+1 " + var1.getName(), true, HaloTextHelper.getColorGreen());
}
if (var4.level > 10) {
var4.level = 10;
}
if (GameClient.bClient && var3 != null) {
GameClient.instance.sendSyncXp(var3);
}
LuaEventManager.triggerEventGarbage("LevelPerk", this, var1, var4.level, true);
if (GameClient.bClient && var3 != null) {
GameClient.sendPerks(var3);
}
} else {
var4 = new IsoGameCharacter.PerkInfo();
var4.perk = var1;
var4.level = 1;
this.PerkList.add(var4);
if (var3 != null && !"Tutorial".equals(Core.GameMode) && this.getHoursSurvived() > 0.016666666666666666D) {
HaloTextHelper.addTextWithArrow(var3, "+1 " + var1.getName(), true, HaloTextHelper.getColorGreen());
}
if (GameClient.bClient && this instanceof IsoPlayer) {
GameClient.instance.sendSyncXp(var3);
}
LuaEventManager.triggerEvent("LevelPerk", this, var1, var4.level, true);
}
}
}
This is what I believe is the relevant Java method
Not sure if it translates exactly to the Event though
Check my reference above yours.
I think this might be relevant.
What I do know is that the engine takes xp and level stuff differently in certain API calls.
So that's now a known.
local function limitSkill(character, perk, level, levelUp)
-- If not levelUp, then we do not need to check whether or not we should cap the skill.
-- This also prevents some infinite loops, since this function can cause a LevelPerk event to be fired.
if not levelUp then
return
end
(...)
Top of my function :/
How would I call this?
Hm, I see
It doesn't seem to be doing anything about experience though
I know. I didn't say it's the solution.
Just an observation
The whole point was to show you that there are negative clamps applied here.
This could be for xp as well as levels.
When you add a level to a player, the engine converts this into XP value.
It actually doesn't, from what I can tell
Ah well I guess I might be out of date with what I probably read, if even correctly.
XP & Skill level are separate
I recall a level-to-xp conversion table in the Java side.
Might be for networking though.
iirc it checks XP on XP gain
Perks have functions specifically to get the required XP for each level
^
I apologize. Most of my experience is with multiplayer and rendering.
No worries
thanks
I appreciate any help at this point
also I do the same
I hope that my approach to problem solving may help you when you do find something out.
The program was originally called 'mspaint'
๐
ya I know
Back in the kid-pix era of MacOS.
I used to have a Dell Workstation from 2000 next to me. Got it from a friend who got it from some work place.
Spiders love those barren, cheap and hollow tower builds.
I made the pc just so I can play one of my favorite old MMO's on it lol
public void setXPToLevel(PerkFactory.Perk var1, int var2) {
PerkFactory.Perk var3 = null;
for(int var4 = 0; var4 < PerkFactory.PerkList.size(); ++var4) {
PerkFactory.Perk var5 = (PerkFactory.Perk)PerkFactory.PerkList.get(var4);
if (var5.getType() == var1) {
var3 = var5;
break;
}
}
if (var3 != null) {
this.XPMap.put(var1, var3.getTotalXpForLevel(var2));
}
}
Seems like the setXPToLevel function is also not calling anything related to the LevelPerk event 
So, that's not the issue
And setPerkLevelDebug is simply not found in the java sources, beyond a declaration.
Hm
Can you disable events temporarily somehow, I wonder 
All events are fired from both the engine and the Lua codebase, however events are exclusively handled on Lua. You can override them.
This is not elegant, however it is an option should you want to explore that approach.
If it works, then you have successfully narrowed down where the issue is.
At this point I'm not sure if it's just some weird edge case / buggy behaviour, or an issue with my code tbh
I can't think of any reason why it's firing off level ups repeatedly even after I set the XP to 0 / below the level up threshold
I think that's fine. You're making good steps on identifying it. Don't rush. I often sleep on issues I deal with. ๐
All bugs are just like sore muscles.
any guides for creating. UI mods?
For Lua programming is there a library or API for auto filling / calling commands? Also how do events work mainly involving Lua? I'm looking more so for how Lua code is operated within the game files as a mod (Java files are more straightforward as they are just recompiled directly to the class location it affects
I think there's a website that breaks down things like this. You can take a look at some of the code in client/ISUI/.. and that may get you started.
Yeah that's why I like Java modding in PZ. What you could do is take what client/chat/ISChat.lua is doing when detecting key presses, take a string table (string array) of all commands, and do a string.startsWith(..) or string.indexOf(..) == 0 and then populate when this happens to what's currently in the chatbox when hitting something like TAB.
Er
By auto fill I mean in the IDE
Oh my apologies. Do you mean like say actual code?
Yeah
I know some people here use something along with Emmi Lua, however I write my code using TypeScript.
I want to do both Java and Lua, Java is direct in the code which means I'm not guessing what goes where and how to access it, with Lua it's through an API? How do you find calls to functions and which imports are used?
You use typescript and convert it to Lua?
@thin hornet has a guide on his github
Yes. There are now unofficial generated typings of the Java API and Lua typings in the works.
This guide should help if you want to stay canonical with your mods with Lua.
Sometimes Java isn't needed to mod.
You'd have to distribute modified code to use a java mod afaik which is potentially a no-no?
It's fine. It's with workshop mods that compilable code is againt their (Steam)'s ToS.
Compatible?
ah
Lua counts then
Compiled code, not compatible.
If I put .class files or .dll or .exe on the Workshop, I'd violate those terms.
I actually know Java better than Lua personally, so I'm looking to see if I should just mod without sharing in mind (Java) versus making mods for others. If I'm just looking to mod my own server I feel Java is best to focus on since I'm looking to do some wacky stuff
You can share your Java mods, just not on the workshop
I also have over 13 years' experience with Java. I know your feels haha.
Yeah fair enough, for people wanting to play my server how does the auto installer function with Java based mods?
With workshop items they auto install, would they have to manually install the modifications
That's definitely a gray-zone. (auto installers)
As two people that know java - how difficult would it be to create a general getter/setter for any public variables?
Like a blanket getter/setter
Project Lombok.
Or Kotlin.
Just wondering cause the java code is full of setters/getters for modders but a few objects have setvariable/getvariable using strings as IDs
I guess why would anyone play a super modded server with lots of Java mods if they had to manually install every single Java mod on there and renew it every time they were updated? Sounds like a nightmare for anyone wanting to host
The problem with PZ specifically is that only static fields are exposed.
๐ Some people still do it.
PZ has hardcore and committed players on communities.
For sure... But I guess my balance here is ease of access
Want to shoot for great mods and gameplay, but not alienate those who are not technically savvy as they outnumber those who are willing to go through the hastle
I agree. I think you'll be creative enough to find a worthwhile solution for your playerbase.. after all they matter most. ๐
Do you know Bukkit for Minecraft by chance?
Possibly in the future then if I run into more Java needs I'll make an auto installer
I do
Well I will tell you that there is a Kotlin flavor of a like-bukkit approach for PZ that is being worked on. A revival project a friend is working on for his older version.
Java modding servers is the most pragmatic approach. Do all you can with Lua on the client side.
You can use reloadlua <filename>.lua
That also reloads it clientside?
There is but depending on what the lua does it wouldn't be wise
It's just an event listener to do some skill level limiting
If the lexer freaks out, the file will not reload until restarting the server.
As in use Lua for clientside or try to do everything in Lua until it's not possible
๐งโ๐
That's useful to know
The pain of using that command more than a thousand times.
If you guys are primarily Java, how are you distributing access to your mods easily for a smooth experience? Other than the kotlin-bukkit-like interface that is WIP
I mainly worked on the server side of PZ. I did release a few client mods but these were for specific needs.
I will say that if your client mod is powerful and convenient enough for people to install trustingly, you can make a client mod work.
There are examples of this in the past.
Take a search to 'ModelLoader'. It's ancient. It enabled custom weapon models for mods to use without breaking a thing if it wasn't installed.
Long gone and 41 now gives more options than that mod ever did.
I feel a Java based client mod is a bad idea unless the class is just not accessible via Lua
Server side what sort of projects did you work on, like ingame logging ? I have some plans to make a logging bot for discord to track trades, items, chats, etc for administrative monitoring
Memory leaks, frameworks, IRC bots, etc.
IRC? And uh oh, I hope mem leaks arent the norm in PZ especially considering Java is supposed to be a memory-trash-handling language
There were also some serioues security vulnerabilities I patched.
A nuclear facility is only as strong as the people running it.
am alive
Hrm
So these server facing mods didn't require clients to match them ?
As in install them so the server is happy, if not that makes sense
Not at all.
There's a server mod out right now for adding custom server commands in both Java and Lua, built for Twitch streamers to use. Clients don't need anything.
so...
A. The car's direction isn't being changed for some reason.
B. The blasted keyID isn't changing either.
(continued from yesterday)
In order to use the mod would you have to match it, or does it pack itself into the server as if like the vanilla game
Also.... What kind of access do I need to the server? I host through a website that grants access to server-data and server-files but other than that it's not under my control to root and whatnot
Decompile it. Mod it. Recompile it. Run it. Test it & improve it.
That's it.
Some things are sensitive for the server when modding it is all.
All the client cares about is getting back the information it needs to perform its job.
Indeed
I think I'll keep Lua side code to the client so it's not a nightmare
And Java to server junk I can improve
What do you use again to convert Typescript to Lua?
I'll link you one sec.
And is that a language preference? I wouldn't expect TS to give some magical expansion of access as it's just going to be Lua anyway
With generated typings it's a lot better than you think.
Here is one of the generated typing files for example: https://github.com/asledgehammer/PipeWrenchTemplate/blob/master/typings/ProjectZomboid/41.71/Zomboid_41.71__zombie.d.ts
What's the generated typing for
One benefit I've heard is that TS makes it explicit where vars are going and no ambiguity of globals
Less time spent digging up what is what. ๐
Very much so indeed, and where do you plop those TS files / Lua files for people to use? Is TS allowable for workshop distros?
No TS code is ran in PZ. It all compiles to Lua files.
The GitHub link I provided is actually a Node environment.
It's basic but does the job.
Fair enough lol
Lots to learn then, ATM I am Java / C# / Python based in web apps and server management
Personally I haven't delved too much into hard modding and mostly keep to work for programming so it's a new process
All good. It's good to have more options.
My main goal is ease of access to the server for new players, then also cool mods to improve the game
But in a way that is better than most modders who are pushing out.... Not so great content (the mods break and are often standalone versus being future proof and easy to work with)
I'll say this: The mods that break aren't at fault with updates, neither is the developer. It's the model implemented. Version control is the part missing from this equation.
I mean updating a mod to the newer versions should be fairly simple
Not to mention some modders update multiple times a day, which I frown upon. They shouldn't be releasing a mod like that
Not so much. It was either you or someone in here that said the JavaDoc for the game isn't descriptive enough.
I also agree with rapid updates. It's up to that modder.
The game doesn't have version control. All these issues you have with mods can be fixed with it in place.
Not sure how I'd get every modder to get their mods on git lol
No. I mean in the game's engine.
Yeah. I mean nothing negative by saying it. It's more to do with fixing some issues with mods is all.
Indeed, just have to fix them every update to the game though lol
Just giving you a more accurate place to focus your issue on.
Indeed, but if I can't fix it I won't worry about it
Modders in here are full of kids too that are getting their feet wet.
I think that seeing people work on something they don't know is awesome.
That's good indeed
Wish I had the chance when I was younger
If you find new and better ways to mod something, share it with us. ๐
But it's a lot to work on. I used to mod for GTA, which was actually harder than this is here as you don't need a whole portfolio of setup going to work on the mods. I will say mods didn't require a complete restart each time a mod updated
Can't find better ways til I make some mods with the current tools first! That's why I've been paying through every single doc / link for the past week
I wonder if GTA modders use Ghidra.
First two major mods are Java and Lua respectively
One is a planned clientside Lua based UI overhaul for inventory and other interactions to beautiful some stuff
Other is server side Java based logging for all interactions on the server to post to my discord admin channels for monitoring
Can't speak for the other modders, but I did not
Spent my time as a kid trying to break a CRC32 checksum with the oldschool 90's self-unzipping machine code security pass for a game I played using Olly.
Learning that process fried my brain, but in a good way.
I respect the GTA modders.
When I was younger I was banned from having my own rig, finally got fed up and built my own when I turned 18 and i've had for seven years now. Been programming for not as long as most.of my peers but I'm still in the game.
Ive got the edge on 3d modeling however, just need to get myself going on modding here so I can justify quitting GTA
To think a game that had millions of players used a modified checksum that packaged malware from Europe.. That's a story.
Indeed, nowadays people are used to a lot of it
And they deserve it.
Indeed
Ahh I just saw build 42 is approaching at some point... Cant wait for my server to be down for a week as modders catch up lmao
Now people can code like it's poetry.
Welp thanks for lending me your ear, I'll be poking my head around a lot as I get into the thick of it lol
I believe you can modify the displayname using doParam like you would for any of the other properties.
are there any events connected to multiplayer voice chat? like an event for "voip start" and "voip end"?
good morning everyone! does anybody know a way to make object say lines like the radio/tv does? i wanna have some items in the ground that say different lines when the players get near ๐ thanks in advance!
Does anyone know which class(es) have the logic for spear sprinting/charging or the spear stab calculations? Going crazy looking for them
zombie\iso\objects\IsoWaveSignal.java
Radio like object can have a "text" speech
Only radio and IsoPlayer can
as far as i know
awesome man! many thanks, ill look right into it! ๐ฅณ ๐
Could make your custom tile object an IsoWaveSignal type
not sure what it would do on right click tho
this would only work on tile objects, right? or could i use the same for an world item i just dropped from inventory?
I doubt it
The only things that could "speak" is like players and radio objects.
roger, many thanks again! ๐
Tried to make the following recipe, but that breaks the game.
How can i make a recipe that gives multiple items per creation?
{
keep Jack,
keep LugWrench,
keep TirePump,
keep Spanner,
keep Screwdriver,
Result:MechanicMag1;MechanicMag2;MechanicMag3,
Sound:Hammering,
Time:10.0,
Category:AGCM 1,
}```
@open abyss set only one result item and add a OnCreate function that add the rest of it
have a look at lua/server/recipecodes.lua
will do, thanks ^_^
found this function Recipe.OnCreate.OpenCandyPackage(items, result, player) player:getInventory():AddItem("Base.MintCandy"); player:getInventory():AddItem("Base.MintCandy"); player:getInventory():AddItem("Base.MintCandy"); player:getInventory():AddItem("Base.MintCandy"); player:getInventory():AddItem("Base.MintCandy"); player:getInventory():AddItem("Base.MintCandy"); end
I guess what i can do is something like this:
{
keep Jack,
keep LugWrench,
keep TirePump,
keep Spanner,
keep Screwdriver,
Result:MechanicMag1,
Sound:Hammering,
Time:10.0,
Category:AGCM 1,
OnCreate:ThreeCarDoodles
}```Followed by, in a .lua file:
```function Recipe.OnCreate.OpenCandyPackage(items, result, player)
player:getInventory():AddItem("Base.MechanicMag2");
player:getInventory():AddItem("Base.MechanicMag3");
end```Right?
@thin hornet
Exactly yeah
function Recipe.OnCreate.ThreeCarDoodles(items, result, player)
local inv = player:getInventory();
inv:AddItem("Base.MechanicMag2");
inv:AddItem("Base.MechanicMag3");
end
OnCreate:Recipe.OnCreate.ThreeCarDoodles,
I suggest you make your own object for storing your recipe codes
create a file in your mod directory /media/lua/server/MyModName_RecipeCode.lua
then add this:
MyModName_Recipes = MyModName_Recipes or {};
MyModName_Recipes.OnCreate = MyModName_Recipes.OnCreate or {};
-- then add your funcs here
function MyModName_Recipes.OnCreate.ThreeCarDoodles(items, result, player)
local inv = player:getInventory();
inv:AddItem("Base.MechanicMag2");
inv:AddItem("Base.MechanicMag3");
end
then use this in the recipe
OnCreate:MyModName_Recipes.OnCreate.ThreeCarDoodles,
I already have such a file, apparently, about a year ago, i made a recipe using this oncreate system... but forgot all about how it works, lol
its just adding a global object with functions that can be called with recipes.
because it has to be global that why we try to keep it clean into a single global object
by using your mod name at least that make sure to never overwrite any other mod
here, let me post the entire code of that file:
function onCreate_AGCMFullSetOfClothing(items, resultItem, player)
resultItem:getInventory():AddItem("AGCMCheatItems.AGCMOddThingy");
resultItem:getInventory():AddItem("Hat_CrashHelmetFULL");
resultItem:getInventory():AddItem("Gloves_WhiteTINT");
resultItem:getInventory():AddItem("Scarf_White");
resultItem:getInventory():AddItem("Jacket_Fireman");
resultItem:getInventory():AddItem("Trousers_Fireman");
resultItem:getInventory():AddItem("Shirt_Denim");
resultItem:getInventory():AddItem("Tshirt_Profession_FiremanRed");
resultItem:getInventory():AddItem("Vest_BulletArmy");
resultItem:getInventory():AddItem("Vest_DefaultTEXTURE");
resultItem:getInventory():AddItem("Socks_Long");
resultItem:getInventory():AddItem("Shoes_ArmyBoots");
end
function OnCreate_AGCMThreeCarPowers(items, result, player)
player:getInventory():AddItem("Base.MechanicMag2");
player:getInventory():AddItem("Base.MechanicMag3");
end```
i don' even know if the first one works, i DID back in the day, but maybe the code has been changed since last year?
hum
I should test to see if the old recipe works ๐
yeah, i noticed, why i'm sceptical it'll work
yes
part of a carepackage
I learned back then, that you can't just wear all of it at once without dying of heat...
it's easy to forget how many important yet small mechanics this game has in place
probably would be
resultItem:getContainer()
not like a classic action RPG where you just play dressup doll... PZ is far more realistic...
give me... 10 minutes? i'll go test the recipe, alright?
it'll answer the question of whether it works or not
you might be able to fake it, by making the tile object invisible, and you would spawn it ontop of where the worldinventoryitem is, and using that to display the text
OFFTOPIC: "This is how you died" - that sentence always sends a chill down my spine...
great idea! ill try it! thanks alot mate! ๐ ๐
aaaaaaaaaaaaaAAAAAAAAAAAAAAAAAAA
function onCreate_AGCMFullSetOfClothing(items, resultItem, player)
local inventory = resultItem:getInventory()
inventory:AddItem("AGCMCheatItems.AGCMOddThingy")
inventory:AddItem("Hat_CrashHelmetFULL")
inventory:AddItem("Gloves_WhiteTINT")
inventory:AddItem("Scarf_White")
inventory:AddItem("Jacket_Fireman")
inventory:AddItem("Trousers_Fireman")
inventory:AddItem("Shirt_Denim")
inventory:AddItem("Tshirt_Profession_FiremanRed")
inventory:AddItem("Vest_BulletArmy")
inventory:AddItem("Vest_DefaultTEXTURE")
inventory:AddItem("Socks_Long")
inventory:AddItem("Shoes_ArmyBoots")
end
function OnCreate_AGCMThreeCarPowers(items, result, player)
local inventory = player:getInventory()
inventory:AddItem("Base.MechanicMag2")
inventory:AddItem("Base.MechanicMag3")
end
Would be nice if this:
AddItems(items: string[])
Heh.
AGCM_Recipes = AGCM_Recipes or {};
function AGCM_Recipes.onCreate_FullSetOfClothing(items, resultItem, player)
local list = {"AGCMCheatItems.AGCMOddThingy", "Hat_CrashHelmetFULL", "Gloves_WhiteTINT", "Scarf_White", "Jacket_Fireman", "Trousers_Fireman", "Shirt_Denim"};
local inv = resultItem:getContainer();
for i = 1, #list do
inv:AddItem(list[i]);
end
end
๐
If you know it's a proper table array then yeah.
I fit's an ArrayList instance or something else, then that goes differently.
huh?
java.util.ArrayList or something else.
Then you'd need to use for i=0, list.size(), 1 do .. end
Just pickin on ya.
Gonna be dope
ts?
typescript yeah
what if i want 5 scarf_white ?
to add more annoyance: what if i want 4 scarft_white, 1 scarf_white at 50% condition?
I think you'd create an item from some factory and then modify it.
๐
i supose you could change the array to
local list = {
{"AGCMCheatItems.AGCMOddThingy", 5}, "Hat_CrashHelmetFULL", "Gloves_WhiteTINT", "Scarf_White", "Jacket_Fireman", "Trousers_Fireman", "Shirt_Denim"
};
for i = 1, #list do
if type(list[i]) == "table" then
inv:AddItems(list[i][1], list[i][2]);
else
inv:AddItem(list[i]);
end
end
InventoryItemFactory.CreateItem("some_id")
Hey Max
I once again come to ask for help with my issue
oh yeah
Stuff ain't working :')
So you are doing something like
playerObj:LevelPerk(perk, false);
playerObj:getXp():setXPToLevel(perk, playerObj:getPerkLevel(perk));
SyncXp(playerObj)
local function limitSkill(character, perk, level, levelUp)
-- If not levelUp, then we do not need to check whether or not we should cap the skill.
-- This also prevents some infinite loops, since this function can cause a LevelPerk event to be fired.
if not levelUp then
return
end
(...)
-- max_skill_ is calculated here
(...)
if level > max_skill then
-- Cap the skill level.
character:getXp():setXPToLevel(perk, max_skill)
character:setPerkLevelDebug(perk, max_skill)
end
end
Events.LevelPerk.Add(limitSkill)
@thin hornet
I can confirm max_skill is properly calculated.
If setPerkLevelDebug is not commented out, however, it causes the entire thing to get called endlessly, causing a crash.
Seems like it triggers LevelPerk, and the xp for whatever reason isn't handled(?). Logs show me the limitSkill function keeps getting called repeatedly with the same arguments.
This only happens when you level up with XP. Not if I "add level" using the admin panel.
So it leads me to believe something about levelling up with XP is funky and needs to be handled differently here. Though, setting the XP to the previous level before debug levelling doesn't seem to do it.
Is the SyncXp required?
I wonder if that's the issue
Also, what does LevelPerk(perk, false) do?
Specifically, the "false"
I wonder if the server kept asking the player to level up, since xp wasn't synced 
Lemme try
is Events.AddXp never triggered?
Not sure, haven't used that Event
Cause you could use it to remove the added xp if the level is at its maximum
this way it would never really reach the next level
Issue is that'd be potentially a ton of calls?
Whereas only checking on LevelPerk is so much less taxing
@thin hornet SyncXp doesn't seem to do it.
it should trigger only when AddXP param3 is true
SyncXp only send the xp changes (from client to server)
That's what I want though, no?
I'm confused as to why the LevelPerk event keeps firing tbh
setPerkLevelDebug should only set the level of the perk, it doesnt change the xp
Does setPerkLevelDebug somehow cause LevelPerk to fire?
shouldnt really
I'm really confused then
but
Debug code is something I don't touch. It's whacky code.
public void setPerkLevelDebug(PerkFactory.Perk var1, int var2) {
IsoGameCharacter.PerkInfo var3 = this.getPerkInfo(var1);
if (var3 != null) {
var3.level = var2;
}
if (GameClient.bClient && this instanceof IsoPlayer) {
GameClient.sendPerks((IsoPlayer)this);
}
}
it does only set a variable and send the changes if its a client
Hahaha.
I didn't think that was a Java method last night.
what i think is going on
Was too busy watching something and eating dinner when I was working out the problem in my head. Thought it was a Lua call.
is that character xp is running into an update loop
So, test results:
If I comment out setPerkLevelDebug and level up using XP, the LevelPerk event fires once, and the xp becomes negative. It does not, however, reduce skill level.
If I do not comment out setPerkLevelDebug, and level up using XP, the LevelPerk event fires repeatedly (pretty much every tick or so, the log very quickly adds up), and the game crashes.
character:getXp():setXPToLevel(perk, max_skill)
character:setPerkLevelDebug(perk, max_skill)
SyncXp(character)
zombie\characters\IsoGameCharacter.java
line 11217 is the update loop function
I'm not familiar enough with Zomboid to fully understand what's happening in your snippet Konijima. What's this about an update loop?
ah thats just the server
I refer to this loop as "The Monolith".
Or will that not do anything (useful)?
Update: Syncing Xp before setPerkLevelDebug didn't change the behaviour / crash.
Isn't Syncing for multiplayer though?
if button.internal == "ADDXP" then
local modal = ISPlayerStatsAddXPUI:new(self.x + 200, self.y + 200, 300, 250, nil, ISPlayerStatsUI.onAddXP)
modal:initialise();
modal:addToUIManager();
table.insert(ISPlayerStatsUI.instance.windows, modal);
end
if button.internal == "LEVELPERK" then
self.char:LevelPerk(self.selectedPerk.perk, false);
self.char:getXp():setXPToLevel(self.selectedPerk.perk, self.char:getPerkLevel(self.selectedPerk.perk));
SyncXp(self.char)
self:loadPerks();
if self.selectedPerk.perk == Perks.Strength or self.selectedPerk.perk == Perks.Fitness then
self:loadTraits();
end
end
These are interesting
So, first of all, I can ditch the XP setting code from my end
Nevermind, I'm a doofus
setXPToLevel set the new required xp to level up that perk
char:LevelPerk does a LevelUP
Yep
LosePerk does a level down
false means it doesn't call the event?
you guys gonna freak out a bit more...
that bool does absolutly nothing
It doesn't?
lol
๐ฉ
its there but is not even used in the source
function onCreate_AGCMDupeDeluxe(items, resultItem, player)
resultItem:getInventory():AddItem("AGCMCheatItems.AGCMOddThingy");
resultItem:getInventory():AddItem("Sheet");
resultItem:getInventory():AddItem("RippedSheets");
resultItem:getInventory():AddItem("Log");
resultItem:getInventory():AddItem("Plank");
resultItem:getInventory():AddItem("TreeBranch");
------------ SNIPPED 63 more items from list to save space in the chat room ------------
resultItem:getInventory():AddItem("BathTowel");
resultItem:getInventory():AddItem("9mmClip");
resultItem:getInventory():AddItem("45Clip");
resultItem:getInventory():AddItem("44Clip");
end```
function ISPlayerStatsUI:onAddXP(button, perk, amount, addGlobalXP)
if amount and amount ~= "" then
amount = tonumber(amount);
ISPlayerStatsUI.instance.char:getXp():AddXP(perk:getType(), amount, false, false, true);
sendAddXp(ISPlayerStatsUI.instance.char, perk:getType(), amount);
ISPlayerStatsUI.instance:loadPerks();
end
end
@thin hornet This is the behaviour that's triggering when I add XP using the menu
It still works tho
So there's this method in uhhh GameServer.. that makes this look nice..
Is loadPerks() somehow an issue?
ISPlayerStatsUI.loadPerks = function(self)
local previousSelection = self.xpListBox.selected;
self.xpListBox:clear();
local maxNameWidth = 0
for i=0, Perks.getMaxIndex() - 1 do
local perk = PerkFactory.getPerk(Perks.fromIndex(i));
if perk and perk:getParent() ~= Perks.None then
local newPerk = {};
newPerk.perk = Perks.fromIndex(i);
newPerk.name = perk:getName() .. " (" .. PerkFactory.getPerkName(perk:getParent()) .. ")";
newPerk.level = self.char:getPerkLevel(Perks.fromIndex(i));
newPerk.xpToLevel = perk:getXpForLevel(newPerk.level + 1);
newPerk.xp = self.char:getXp():getXP(newPerk.perk) - ISSkillProgressBar.getPreviousXpLvl(perk, newPerk.level);
newPerk.xp = round(newPerk.xp,2)
local xpBoost = self.char:getXp():getPerkBoost(newPerk.perk);
if xpBoost == 1 then
newPerk.boost = "75%";
elseif xpBoost == 2 then
newPerk.boost = "100%";
elseif xpBoost == 3 then
newPerk.boost = "125%";
else
newPerk.boost = "50%";
end
newPerk.multiplier = self.char:getXp():getMultiplier(newPerk.perk);
self.xpListBox:addItem(newPerk.name, newPerk);
maxNameWidth = math.max(maxNameWidth, getTextManager():MeasureStringX(self.xpListBox.font, newPerk.name))
end
end
self.xpListBox:sort()
self.xpListBox.selected = previousSelection;
self.xpListBox.columnWidth[1] = maxNameWidth + 15
self:updateColumns()
end
nah thats just part of the player stats ui
@open abyss Take a peek at public static void loadModData(IsoGridSquare var0) in zombie.network.GameServer.
Any way to make sure the item i create ALWAYS gets dropped on the ground?
Cause this satchel is like 183 units heavy... well beyond 20 a strong chracter can carry ๐
@pulsar rock im going to test in a sec
which file? i can't find the file...
It's a Java file.
ah, okay, then that's why i find nothing... ๐
Okay, finding the right file is gonna be a bich, so gonna just do *.* ๐
gonna take a while to have npp search all files, but ooh well
You'd need to decompile the class file to view it.
Nope. You're reading dead code.
That's ancient. Like when I started playing ancient.
Go look at zombie.core.raknet.UdpEngine
Ah
@pulsar rock i dont have trouble limiting the level btw
The limit internally is around the signed byte max value.
i don't see that file
for example
local function limitSkill(character, perk, level, levelUp)
print("leveling up " .. perk:getName())
if level > 1 then
-- Cap the skill level.
character:getXp():setXPToLevel(perk, 1);
character:setPerkLevelDebug(perk, 1);
print("limited skill " .. perk:getName() .. " to 1")
end
end
Events.LevelPerk.Add(limitSkill)
it cap it to 1 and doesnt loop for ever
oh well... not that awefully important i guess
@smoky tendon Any chance we can be allowed to make threads?
Using XP, right?
Not just the add level button
But adding sufficient XP to level up
ooof ok
game blow up
alright ill just add a print for now and see what happen with that xp
I wouldn't mind if they at some point said "goodbye old mods" and cleaned some of this up, ngl
Hahah. I'd agree however this requires a lot of work and money.
Aye
I'd be selfish and biased in saying that the Lua should be rewritten in TS. xD
When is pz2 coming out ๐
Playztation 2
okay so added bunch of xp and it ran LevelPerk event for each level that it equated
The issue isn't the xp setting in our code btw
It seems to be something to do with the debug level setting
I also tried looping LoseLevel
That caused the same behaviour
For whatever reason, it seems like setting the level makes it so that the XP isn't overwritten and re-triggers the levelup?
somehow Events.AddXP.Add(addXP); doesnt seem to trigger at all
LevelPerk is its own event
triggered when using LevelPerk method
AddXP should trigger (based on the source) but ill test again
could be that i reloaded the script and it didnt catch it
On a side note; I did some tests and even when setting the XP - if it loops like that, the XP is the same each time. So the change isn't properly persisting.
Well i might have an idea to go around this issue but will have to test soon ๐
Up all night coding. Sleep sounds good.
'Night!
Night Delta
If you remove setPerkLevelDebug, the XP is set properly, however. And it's only called once.
Is it possible to set the condition of items using the recipe system?
There might be an event for crafted items that you can hook into?
looks like i need to use the oncreate feature again ๐
i'm trying to create some recipes that uses a custom item, that then in another recipe is combined with tire breaks or wheels or what not, repairs the condition of said item to max (or replaces the item with same type item, but with max condition)
(hope that made sense)
item:setCondition( item:getConditionMax() )
put that in the lua, sort of like i did with the recipes that created multiple items, right?
yeah but technically the new items should already come with full condition
oh, so... wait...
{
OldTire1, /* this would delete/consume the old wheel that has damage */
Result:OldTire1, /*this would give me one at max condition?*/
Sound:Hammering,
Time:10.0,
Category:AGCM 1,
}```
like this?
that should work yeah
would still work if that OldTire1 ingredient is not damaged tho
alright, will give them proper names and the like, but this is very helpful, Konijima!
so might want to add a CanPerform check
and only return true is the condition is lower then the maxcondition
eh?
yeah, sorry, i'm not great with all this x.x
if you check the recipecode.lua
no worries, i don't mind if one can replace a maxed condition tire...
you can see other type of functions
like
function Recipe.OnCanPerform.CleanMuffin(recipe, playerObj, item)
return item and not item:isCooked();
end
you can add in your recipe script a OnCanPerform:myOnCanPerformFunc
Wdym? It properly capped the skill if you use addXP?
I'll wait until the other issue is resolved ๐
this will prevent the recipe from being performed if the return is false
Nah but i mean that its triggered with adding xp for example while watching a cooking show
but adding xp from debug doesnt trigger it
anyway that not the point we gonna find a way to cap those perk
Aye
true, but then again, i think it's redundant.
With the way my recipes are, and how "cheap" it's going to be to "repair". It's not really a function needed.
Preferably using LevelPerk, rather than hooking into the far less efficient AddXp
However, i do have one last question. and then i think i got my mod at the point where i won't need to worry about it beyond updating it if it got out of date.
I see a few recipes of the base game use "destroy".
What is the difference of using that or not at all?
Don't they both do the same? Or is there more to it?
This``` recipe Fixing a wheel
{
OldTire1,
Result:OldTire1,
Sound:Hammering,
Time:10.0,
Category:AGCM 1,
}```VS This: ``` recipe Fixing a wheel
{
Destroy OldTire1,
Result:OldTire1,
Sound:Hammering,
Time:10.0,
Category:AGCM 1,
}```What is the difference?
(I added destroy, but what function does destroy serve??)
Once i know this info, i don't think there is possibly anything else i need (at least not in regards to my mod)
Destroy will remove the item
otherwise it would try to use it, so if for example its a WaterBottle with water in it, it would use only 1 unit inside of it, but with destroy it would just destroy it completly
I have made a work around
Oh?
it kind of hackish but it prevent the infinit loop
local perkTicks = 0;
local perkLeveledUp = {};
local function limitSkill(character, perk, level, levelUp)
if not levelUp then return; end
if level > 1 then
table.insert(perkLeveledUp, { -- add a table witht he reference of the level up to cap
player = character,
perk = perk,
level = 1 -- set limit level here
});
perkTicks = 4; -- set the delay for the onTick check
end
end
Events.LevelPerk.Add(limitSkill);
local function onTick()
if #perkLeveledUp > 0 then
if perkTicks > 0 then
perkTicks = perkTicks - 1;
return;
end
for i = 1, #perkLeveledUp do
local entry = perkLeveledUp[i];
entry.player:getXp():setXPToLevel(entry.perk, entry.level);
entry.player:setPerkLevelDebug(entry.perk, entry.level);
end
perkLeveledUp = {};
end
end
Events.OnTick.Add(onTick);
it kind of work you will see the level go up but go down 4 ticks later
wich is pretty fast but kind of give time to the game to complete its LevelPerk job before limiting it again
wait a sec... how do i start a new game?
Ya know, with all this modding, i kind of forgot...
? Solo button in main menu
Either you are the perv, or I am. I'm not into solo sessions right now... i just want to kill zombos... Me time can wait ๐
Sorry Copper i truly have no idea what you are talking about ๐คฃ
was trying to make a joke here, but i guess it failed hard... ooh well..
On the otherhand it would be good to remove the xp in AddXP so that it never level up at all when at the cap you set
That's just so many unnecessary checks though
Any chance you figured out what is causing the infinite levelling back up thing?
Well if your character is limited to level 3 of cooking and is currenctly at level 3 of cooking
all xp gained should be canceled so that it never reach level 4
Why not just revert back to 3 when it hits 4?
this way it wouldnt trigger the audio and halo over the head
Workshop Mech, super cool
I'm more worried about doing checks on every single xp gain
its a bit confusing if the player hear a level up but doesnt get it
well there is no trouble to check on every xp check
not really a performance issue
I'm not really comfortable with the potential impact tbh
im going to test it ๐
Like, I'm querying all the character's traits and looping over them to check the skill cap
And checking sandbox settings
And I can't just cache those since dynamic traits could be installed
could try and check how long your function take to run, but chance are its nothing
I'm assuming that has a non negligible impact if combined with other mods
local function addXp(character, perk, xp)
if character:getPerkLevel(perk) >= 1 then
character:getXp():setXPToLevel(perk, 1);
end
end
Events.AddXP.Add(addXp);
this mixed with the other code would be pretty solid
its not like you gain xp so often that the function would lag the game
oh i mean you can use both,
one prevent the actual level up and the xp one prevent the small xp from growing up
can't you just set the multiplier to 0 if you want to prevent gaining xp?
mhm not bad either it should work too
nothing seem to prevent LevelUpMultiplier to be set to zero
actually
you cant set the multiplier for a perk to you can only add
addXpMultiplier
and with AddXPNoMultiplier it would still add the xp no matter the multiplier
working on making more vanilla items into weapons and thought I could edit the attachment offset/rotate on those models for ground but there is only an attachment for world and none seemingly for weapons being held...
anyone know a good program to modify models? ๐
other than blender
does the game have an ingame animations editor like for vehicles?
would be great to be able to add world attachment right then and there
also, can't help but think it would have been wiser to do this before hand?
then again adding in 100+ models I'd try to mitigate the process too
could have sworn there was an animation viewer in game
there is an animation viewer
what's the key?
irc access via debug menu
there seem to have an attachment editor too
tho i have no idea where that animation viewer is anymore lol
the viewer is right above what you highlighted
lots of new animation updated recently
local git only
I think someone wrote a difference checker utility to print changes into a txt
use : for instanced objects
also if I recall, getDay get's the day of the month 1 to 29/31
if you want what day the game is on you should use getNightsSurvived()
almost every call will use : as they're all instances
lua side you will more likely use .
For the total days the server world exist, no mater the player survived time
local worldAge = getGameTime():getWorldAgeHours();
local totalDays = worldAge / 24;
that works too
so getDaysSurvived actually counts how long the player has been alive
while getnightssurvived is used for challengemaps I believe so it counts the days
Any way to change the zombie infection settings such as symptoms and certain meds that have to be taken to stave off the infection?
You could leverage off PlayerUpdate
There is a popular mod called "antibodies" that does this, except they made it so you lose infection status over time if meeting criteria.
Would not be all that hard to add more symptoms if your criteria is infection value > x, do etc
funny enough getWorldAgeHours uses night survived
public double getWorldAgeHours() {
float var1 = (float)(this.getNightsSurvived() * 24);
if (this.getTimeOfDay() >= 7.0F) {
var1 += this.getTimeOfDay() - 7.0F;
} else {
var1 += this.getTimeOfDay() + 17.0F;
}
return (double)var1;
}
heh
so its not player related
I know, dayssurvived is
player nightsurvived in inside the IsoPlayer
I'll be honest I've gotta figure out how that antibodies mod works, cause I satisfied all the good conditions and still died lmao
wait they have an additonal var in players for nights survived?
I'm looking more so to remove symptoms and add new ones, like sleeplessness, depression, larger FOV, etc
yeah in GameTime it say
public double getHoursSurvived() {
DebugLog.log("GameTime.getHoursSurvived() has no meaning, use IsoPlayer.getHourSurvived() instead");
return this.HoursSurvived;
}
Straight from the source - Idk if the wiki is updated.
I'd recommend setting up an environment so you can properly research/investigate: https://github.com/Konijima/PZ-Libraries
Oh that's hourssurvived, thank god they didn't name it nightssurvived too
Messing around in bodyparts code is a bit of a nest
player's have bodyparts with parts which have bodygamage and bodyparts or some such
the file is LuaEventManager
Did you properly set up the libraries section?
Oh yeah I noticed that too
because PZ events are not defined like objects and methods, they are pretty volatile
now that you mention it
I wonder why it isn't a function in luamanager
like addLuaTriggerEvent(eventID, function)
thats something that Typescript system is going to fix effortlesly
There's also Hooks which I don't think anyone has ever used
there's only like 3 hooks though - but they would allow for total overhauls
private static void AddEvents() {
AddEvent("AutoDrink");
AddEvent("UseItem");
AddEvent("Attack");
AddEvent("CalculateStats");
AddEvent("WeaponHitCharacter");
AddEvent("WeaponSwing");
AddEvent("WeaponSwingHitPoint");
}
I think they added more
Yeah not all events are defined in LuaEventManager.java
@wraith root Ironically, both topics merged - you can use the hook CalculateStats to completely modify how illness is handled but you would have to also recreate every other facet that the hook bypasses.
Idk if this convention is used elsewhere but Hooks circumvent the rest of the function entirely for a lua function.
I want to make a custom infection so I had a feeling I'd have to rework a bit to get it working...
protected void calculateStats() {
if (GameServer.bServer) {
this.stats.fatigue = 0.0F;
} else if (GameClient.bClient && (!ServerOptions.instance.SleepAllowed.getValue() || !ServerOptions.instance.SleepNeeded.getValue())) {
this.stats.fatigue = 0.0F;
}
if (!LuaHookManager.TriggerHook("CalculateStats", this)) {
this.updateEndurance();
this.updateTripping();
this.updateThirst();
this.updateStress();
this.updateStats_WakeState();
this.stats.endurance = PZMath.clamp(this.stats.endurance, 0.0F, 1.0F);
this.stats.hunger = PZMath.clamp(this.stats.hunger, 0.0F, 1.0F);
this.stats.stress = PZMath.clamp(this.stats.stress, 0.0F, 1.0F);
this.stats.fatigue = PZMath.clamp(this.stats.fatigue, 0.0F, 1.0F);
this.updateMorale();
this.updateFitness();
}
}
hmm
illness isn't handled here after all
LuaEventManager.triggerEvent("OnPlayerUpdate", this) will still work though
function thing(playerObj)
end
Events.OnPlayerUpdate.Add(thing)
Anyone knows if there is a method or example that returns the x/y/z of an item in the world?
Unfortunately it will be a situation where the game is adding x and you may have to subtract x lol
Indeed
For example, to find the Home VHS tapes
InventoryItem should have getSquare() and getX(), getY(), getZ() inherited from IsoMovingObject
@thin hornet Can typescript make it so I don't have to remember the class inherits?
I wish the lookup knew to grab the inherited functions
The Typescript thing is 200% better than that intelij intelisense yeah
Im just waiting a bit so that everything is perfect and ill make a mega tutorial how to get started with typescript modding
that will probably be a big game changer for the modding community
What would be some differences? Like would I have to write differently than I do now?
Well first, you wouldnt need to search as much in the source
and second, youll have access to a real complete intelisense of everything
events included with param types etc
oh damn
yeah I have to go in to see what types the params are sometimes
And lets not forget that typescript will let you know about any syntax error or wrong type usage
Yeah, but I don't think I can change model placements
I'd have to go in to every model to make it a weapon then add an attachment world to their script for when they're on the ground
Hello. I don't know how to introduce myself so I'm gonna go straight to the point lol. I'm new to modding. I don't know if this is correct
`-- Scripted Talk
if(SS:getModData().NoParty ~= true) then
if worldAgeDays < 1 then
if(SS.player:getModData().isChatValue ~= 1) then
getSpecificPlayer(0):Say("Testing 1")
SS:Speak("Testing 1")
mySS:setChatValue(2)
elseif(SS.player:getModData().isChatValue ~= 2) then
getSpecificPlayer(0):Say("Testing 2")
SS:Speak("Testing 2")
mySS:setChatValue(3)
end -- end of if ChatValue
end -- end of worldAgeDays < 1
end -- end of if NPC has no group`
what is SS in your script
It's in function TalkToSurvivorWP(test,SS)
and where does TalkToSurvivorWP come from
The function happen when you target an NPC from Superior Survivor *then go to context menu then click "Talk"
Okay, so what exactly you want to know about the snippet you sent?
Did you test it and did it work or throw an error?
I want to know if it's correct and if it doesn't have any errors
Not yet. Sorry ; (
Ok thanks ๐
if you get an error and dont know what it mean then post the error stack here we will try and help you understand it
Oh, ok. thank you
mommas dont let your babies grow up to be cowbooooooooys
when you add a trait the last param of the function is a boolean, if its set to true it wont show up in the selectable traits
for example
TraitFactory.addTrait("Mechanics2", getText("UI_trait_Mechanics"), 0, getText("UI_trait_Mechanics2Desc"), true);
you can also give perks a parent
so it shows up inside of a category
I don't know if category perks have a level/xp assigned to them but technically they could
@iron salmon they have unreleased tools right? right?
unless I'm doing something wrong lmao
gotta mail your 3D guys some liquor
there's probably a typo in your code - check your local files
C:\Users\<YOU>\Zomboid\console.txt
The path might be different for you- but that file will have whats printed on that screen
but you know - not garbled lol
that'll do it
in-game error report isn't all that reliable from what i've seen
would suggest bringing up the console.txt
also are you on unstable branch?
they added more features to the error screen
including a button to open the file / force the game to play on through errors iirc
yes as it's a new branch
I think it's up to .72 ?
so there's alot of changes
unstable is at .73 atm
and yeah you can just redo the setupWorkspace task in intelij to generate source and lib again (update the game first)
Okay, so make a dupe recipes and then duping a wheel, it dupes the condition of the original wheel duped (which might make sense, but not for my intentions and mod)
So i made a recipe like this:``` recipe Dupe x1 Performance Tire Heavy-Duty
{
keep ModernTire2,
Result:ModernTire2,
Sound:Hammering,
Time:10.0,
Category:AGCM C,
OnCreate:OnCreate_AGCM_ModernTire2,
}```And i made a script that does this:
item:setCondition( item:getConditionMax() );
end```I just wish to know if this is correct (since i have ZERO knowledge with Lua... )
you are using item:setCondition but look item is nowhere defined
you might actually want to us the variable resultItem instead
I did as you suggested ๐
resultItem:setCondition( resultItem:getConditionMax() );
end```??
on both?
so it dupe the item which mean the ingredient item should keep low condition (if low)?
It honestly does not matter for the design of the mod, whether the original item is at 100% or 44% or what ever... as long as the recipe can use the original item, then make a new item which is in pristine condition.
Is there many items than you intend to do this with?
Car parts only... (like doors, wheels, etc)
Okay then there is a way of doing this without having 30 new recipes
there is roughly 76 car parts, minus the engine and truck which you sadly cannot replace in vehicles
so once the engine is dead, repairing it is a hit and miss situation...
there's a context timed action for repairing engines
if I recall
recently made a mod that made wrenches recursively looked for like all other mechanic actions
yeah, but still, even with max skills, your not going to be able to turn the condition & damage of an engine to 100% again :/
at least not from what i have experienced :/
Yes you can?
Unless I'm mistaking modded gameplay, can't you just use spare engine parts?
shrugs
you said you've experienced it, does your experience differ?
removing engine parts nets 1 part per 10% of condition (I think higher mechanics gets more parts)
adding engine parts back gets 1% (higher mechanics nets more)
I do use a mechanics overhaul mod but I assumed they just added extra functions as to use scrap to repair parts directly rather than replace them
hmm, i'll experiement with it again later
.
getMoodleLevel
get Moodle Level
Moodle???
i'll take a look at the mod, see if i like what it brings to the table...
media/lua/server/MyModNameRecipe.lua
MyModNameRecipe = {}
MyModNameRecipe.GetItemTypes = {}
MyModNameRecipe.OnCreate = {}
MyModNameRecipe.OnCanPerform = {}
MyModNameRecipe.OnGiveXP = {}
MyModNameRecipe.OnTest = {}
local function addExistingItemType(scriptItems, type)
local all = getScriptManager():getItemsByType(type)
for i=1,all:size() do
local scriptItem = all:get(i-1)
if not scriptItems:contains(scriptItem) then
scriptItems:add(scriptItem)
end
end
end
-- Set all the items the recipe will accept as ingrediant
function MyModNameRecipe.GetItemTypes.DupeableMecanic(scriptItems)
addExistingItemType(scriptItems, "ModernTire1"));
addExistingItemType(scriptItems, "ModernTire2"));
-- add all mecanic item you want to be dupeable
end
-- Give a dupe of the result item type
function MyModNameRecipe.OnCreate.DupeItem(items, resultItem, player)
player:getInventory():AddItem(items:get(0):getFullType());
end
MyModRecipes.txt
recipe Dupe Mecanic Part
{
keep [MyModNameRecipe.GetItemTypes.DupeableMecanic] // this use a function to allow multiple input item
Result:ModernTire2, // this doesnt matter anymore
Sound:Hammering,
Time:10.0,
Category:AGCM C,
RemoveResultItem:true, // destroy the result item
AllowDestroyedItem:true, // allow duping the part even if its broken
OnCreate:MyModNameRecipe.OnCreate.DupeItem,
}
So basically with this code here you wont need 97 recipes to do the same on all the items defined inside MyModNameRecipe.GetItemTypes.DupeableMecanic
according to the decompiled code there are no overloads for int even
check out zombie/characters/Moodles/MoodleType.java
public enum MoodleType {
Endurance,
Tired,
Hungry,
Panic,
Sick,
Bored,
Unhappy,
Bleeding,
Wet,
HasACold,
Angry,
Stress,
Thirst,
Injured,
Pain,
HeavyLoad,
Drunk,
Dead,
Zombie,
Hyperthermia,
Hypothermia,
Windchill,
CantSprint,
FoodEaten,
MAX;
you can use from index with a number to get the type
but that might change if someone adds a moodle or they change them in the vanilla game
but you should be able to use the actual type path
local panicLevel = player:getMoodles():getMoodleLevel(MoodleType.Panic)
I use this is in one of my mods for conditional speech, and it works
Anyone have the code handy for checking if a particular mod is installed? Is there any documentation around for these API calls?
Ooh I do
I just need to check if a mod is installed for now, but reading the 92 step Github document on decompiling the Java source makes my brain hurt
local activeMods = {}
local activeModIDs = getActivatedMods()
for i=1,activeModIDs:size() do
local modID = activeModIDs:get(i-1)
activeMods[modID] = true
end
I also made a version that includes requires
local crossRefMods = {
["CatsWalkWhileReadMod"]="ReadFasterWhenSitting",
["CatsReadMod"]="ReadFasterWhenSitting",
["CatsReadMod(slower)"]="ReadFasterWhenSitting",
}
local loadedModIDs = {};
local activeModIDs = getActivatedMods()
for i=1, activeModIDs:size() do
local modID = activeModIDs:get(i-1)
if crossRefMods[modID] and not loadedModIDs[modID] then
require (crossRefMods[modID])
loadedModIDs[modID] = true
end
end
requires the modID and filename
could expand the filenames to a list if need be
Just decompiling the source?
an the shortest check for active mod would be like
if not getActivatedMods():contains("ThisModID") then return; end
-- dont execute if this mod not active
Oh god yeah that's the one haha. Guess I'll have to give it another go
Ah, nice. Thank you!
I already have the rest of the code ready to go, just needed that
I know there is an access to the infection symptoms, it's all in a class
I forget where
I'll have to go digging again
I know it's contained somewhere since last time I found it by tracing how the time of infection setting got passed along
Another quick question - when using ScriptManager.instance:getItem, if I'm trying to modify a value of a modded item's parameters, I would simply include the module like this ScriptManager.instance:getItem(ModdedModule.ModdedItem), or is that incorrect?
I usually drop in changes midway different parts of my mods for other mods - so I got lazy and prefer if activeMods["modID"] then lol
that is pretty dope tho, if you actually need other mod script to run first
that one uses a string
Oh yeah I know that but i'm trying to have my mod change the parameters of a modded item (if it is installed)
Their code overwrites because they included a copy of the vanilla function and then overwrote it properly themselves (I don't think they understood how to require) - so my code is basically holding the door open for them and saying "you first".
ScriptManager.instance:getItem("ModdedModule.ModdedItem") works?
Let me double check cause I mess with script manager alot
getScriptManager():getItem("") -- would be like that
getItemsByType
getItemsTag
getAllItems
FindItem - probably this
I don't know if isoplayer has a function like that directly - if they do then great
That I understand, but I'm trying to "get" a modded item. getScriptManager():getItem("Woodglue") works because Woodglue is a vanilla item... but what if the item isn't a "Base" module?
public int getMoodleLevel(MoodleType var1) {
return this.getMoodles().getMoodleLevel(var1);
}
Just include the Module.Item, right?
ah
just add the module name with the dot
it will get that modded item if it exist
Roger that, thanks!
public Item getItem(String var1) {
if (var1.contains(".") && this.FullTypeToItemMap.containsKey(var1)) {
return (Item)this.FullTypeToItemMap.get(var1);
} else {
ScriptModule var2 = this.getModule(var1);
return var2 == null ? null : var2.getItem(getItemName(var1));
}
}
actually getItem doesn't need the full path but you don't want to leave that opening for issues
I have to be explicit in this case because the item shares a name with a vanilla item ๐
yeah that's what I meant lol
getItem handle the module if not specified it would find a vanilla one
also:
seems like the direct method was a recent addition - and a good one - but it's not widely used
just from a cursory glance not used once
so yeah - this should be fine
Looks great!
if you set up the libraries you can ctrlshiftF to search through your own project and all files in scope
which include libraries
hope this code works O_O
This is awesome work you just did!
What software did you use to create this gif?
ShareX
thanks!
open sourced afaik - combined printscreen with the snipping tool - lets you record gifs as either - and has automatic options for upload to imgur or clipboard etc
also has a crap ton of other uses
@thin hornet if you have a few workshop PZ mods, could you be kind and link me to one of them?
I wish to add you to the credits, since you did a helleva lot of help for me, the least i can do is add you to the credits section
sure here my sw profile https://steamcommunity.com/id/konijima/myworkshopfiles/?appid=108600
awesome!
recipecode is getting more evolved with time so much more efficient
alot is now possible with so much less line of code or recipe duplicate
aye, also, i get errors when i try open crafting menu... so i derped or something...
if you have removeResult as true that breaks the tooltip system
I probably should have reported this bug but I forgot
๐
I think this is better, to show exactly file name and the code of them...
it remove alot of clutter in the recipe txt file
but also make the tooltip more efficient in game
i recall that rip clothing tooltip with over 400 rippable clothing item would lag alot when hovering
`-----------------------------------------
function: @stdlib.lua -- file: null line # 10
function: setVisible -- file: ISCraftingUI.lua line # 30
function: toggleCraftingUI -- file: ISCraftingUI.lua line # 1366
function: onPressKey -- file: ISCraftingUI.lua line # 1380.
[25-07-22 18:40:37.439] ERROR: General , 1658767237439> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: at KahluaUtil.fail line:82..
[25-07-22 18:40:37.439] ERROR: General , 1658767237439> DebugLogStream.printException> Stack trace:.
[25-07-22 18:40:37.440] LOG : General , 1658767237440> -----------------------------------------
STACK TRACE
function: @stdlib.lua -- file: null line # 10
function: setVisible -- file: ISCraftingUI.lua line # 30
function: toggleCraftingUI -- file: ISCraftingUI.lua line # 1366
function: onPressKey -- file: ISCraftingUI.lua line # 1380.
[25-07-22 18:40:38.552] LOG : General , 1658767238552> -------------------------------------------------------------
attempted index: view of non-table: null.
[25-07-22 18:40:38.553] LOG : General , 1658767238553> -----------------------------------------
STACK TRACE
function: getRecipeListBox -- file: ISCraftingUI.lua line # 21
function: refresh -- file: ISCraftingUI.lua line # 60
function: setVisible -- file: ISCraftingUI.lua line # 38
function: toggleCraftingUI -- file: ISCraftingUI.lua line # 1369
function: onPressKey -- file: ISCraftingUI.lua line # 1380.
[25-07-22 18:40:38.553] ERROR: General , 1658767238553> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: attempted index: view of non-table: null at KahluaThread.tableget line:1689..
[25-07-22 18:40:38.554] ERROR: General , 1658767238554> DebugLogStream.printException> Stack trace:.
[25-07-22 18:40:38.556] LOG : General , 1658767238556> -----------------------------------------
STACK TRACE
function: getRecipeListBox -- file: ISCraftingUI.lua line # 21
function: refresh -- file: ISCraftingUI.lua line # 60
function: setVisible -- file: ISCraftingUI.lua line # 38
function: toggleCraftingUI -- file: ISCraftingUI.lua line # 1369
function: onPressKey -- file: ISCraftingUI.lua line # 1380.`
Looking for people with modding, mapping and staff experience, contact me if you want to be part of a new server beginning.
So I'm looking for a simple mod, that makes the skeletons/burned skeletons a clothing mod that a player can wear, only can be gained by debug/console cheats. I tried doing it myself but I have no experience in code whatsoever, looking for pointers or someone to help
you want a new clothing mod?
correct
are you familiar with Blender?
not at all, figured i could have used the textures from the base game of the skeletons and use them for the player avatar
check out this and see if you can try making one https://steamcommunity.com/sharedfiles/filedetails/?id=2648115890
thank you
you could make a clothing item that just uses the skeleton model
yeah i tried following all the steps, so confused lol
Is there a place where all tags used in-game are displayed?
wait... I can just write it
Best mods for a server with only small group like 3 - 5 people?
Just browse the most downloaded mods and other section of the workshop and pick what you want. Maybe get an idea of what type of server/gameplay you want before.
There is also bunch of collections out there that could give you ideas
Do you know if there a mod where you can see each other on the minimap or map?
That should be a new server setting when the current unstable build goes stable.
Latest (unstable) has this already
going to be obsolete soon
https://steamcommunity.com/sharedfiles/filedetails/?id=2732804047
When I started up my dedicated server it just made a new file called "ServerTest" but I wanted it to use "ServerBuildPT" is it possible ? I can't find it anywhere in the bat .
add -servername "MyConfig"
Some interesting things in the tags
function Recipe.GetItemTypes.BrokenGlass(scriptItems)
scriptItems:addAll(getScriptManager():getItemsTag("BrokenGlass"))
addExistingItemType(scriptItems, "SmashedBottle")
end
I wonder what this is for
"FitsToaster" is a tag
heh
item Waffles { DisplayName = Waffles, DisplayCategory = Food, Type = Food, Weight = 0.3, Icon = Waffles, DaysFresh = 3, DaysTotallyRotten = 5, HungerChange = -15, UnhappyChange = -10, Calories = 80, Carbohydrates = 13, Lipids = 4, Proteins = 3, WorldStaticModel = Waffles_Ground, Tags = FitsToaster, } item Waffles**Recipe** { DisplayName = Waffles, DisplayCategory = Food, Type = Food, Weight = 0.3, Icon = **Saffles**Fruit, DaysFresh = 3, DaysTotallyRotten = 5, HungerChange = -15, UnhappyChange = -10, Calories = 80, Carbohydrates = 13, Lipids = 4, Proteins = 3, WorldStaticModel = WafflesFruit_Ground, }
uh
Probably that new feature where you can only fit some specific stuff into some specific containers
also idk if fruit waffles are like infused or ontop but should probably have fits toaster too if infused
I know just thought the tag was funny with out context
Put a metal knife in the toaster
but the fruit waffles script has typos
let see what happen
lol
DONT DO THAT
just saying
I wonder if it was a fire hazard to add metal object into a microwave (i mean in game)
yeah the fruit waffle has infused fruit
where do I report this critical bug
hm pancakes fruit is also called 'PancakesRecipe'
xD
I wonder if the type was inuse before and just reused for fruit?
potentially
item PancakesCraft { DisplayName = Pancakes, DisplayCategory = Food, Type = Food, Weight = 0.3, Icon = Pancakes, BadInMicrowave = true, IsCookable = true, ReplaceOnCooked = Base.Pancakes, MinutesToCook = 10, MinutesToBurn = 30, DaysFresh = 3, DaysTotallyRotten = 5, HungerChange = -20, UnhappyChange = 10, Calories = 210, Carbohydrates = 42, Lipids = 2, Proteins = 6, WorldStaticModel = Pancakes, } item PancakesRecipe { DisplayName = Pancakes, DisplayCategory = Food, Type = Food, Weight = 0.3, Icon = PancakesFruit, DaysFresh = 3, DaysTotallyRotten = 5, HungerChange = -20, UnhappyChange = -10, Calories = 210, Carbohydrates = 42, Lipids = 2, Proteins = 6, WorldStaticModel = PancakesFruit_Ground, }
BadInMicrowave = true,
IsCookable = true,
ReplaceOnCooked = Base.Pancakes,
MinutesToCook = 10,
MinutesToBurn = 30,
oh thats cause you have the pancake package box
does this mean we can't cook fruit pancakes?
and can make your own mix
Unrecognized option: -servername ?
Oh you know what - it may be that way because you make them with a mix package
I added it to StartServer64_nosteam.bat
the suffix of Recipe might have something to do with evolved recipes maybe
not sure if the cooked stuff matters though
evolvedrecipe Waffles { BaseItem:Waffles, MaxItems:3, ResultItem:WafflesRecipe, AddIngredientIfCooked:true, Name:Waffles, CanAddSpicesEmpty:true, }
hmm
try adding it after -statistic 0 -servername EasyMode
Does this mean anything you use in waffles makes it a fruit waffle?
That worked ๐ @thin hornet
yay
What else will you add to your waffle man? Potatoes?
based on the evolved recipe yes
D:
it's still called waffle though
fruit is only mentioned in the art
I've played SS13 - the more modular the recipes the better
Well there is baby food with weird mix theses days, like Strawberry+Carrots
really excited for the liquids aupdate
give me cooking to that same extent
let me have a bottle of cheese
Liquid cheeze 
jarring should be handled as containers that get sealed
probably could write that as a mod right now
adding more item types for each outcome feels wrong to me
what do you mean
like cheesewaterbottle, cheesecan, cheesejar
I would think making a liquid compatible container object would make more sense
ah so just a bottle containing something instead
hell even a behavior object you can then perscribe to any other object
let people use shoes as a liquid container with a 80% retention

it's the apocalypse god can not judge me
Well my shoes would clearly have 0% retention with those holes
this is already a technique used in game for item containers
the player/bags/mapobjects don't have lists to themselves they have itemcontainer objects
you can extend this to other behaviors
as nice as the tag system is for items
doing the above could make things like adding generators or other types of power sources much more accessible
Have all vegetables get a tag vegetable and fruits a tag fruits and tomatoes exceptionally have both
and you can mix and match behaviors
that's fine for identifying stuff, but I meant for system behaviors
an example would be clothing / weapons / items
then have evolved recipe accept tags



๐
