#mod_development
1 messages ยท Page 218 of 1
It gets printed every tick.
He literally sent you the github repo to view the whole mod lol
Yep, that's the one.
true
But like again, what is the issue ?
Stress not setting ?
There's not a lot of points for the program to fail
Stress and stressFromWork are just 0.
timeSinceLastWork is updating but not the stressFromWork
So in-game the stress of the player is 0 ?
Yes.
---@param stress number
function WorkaholicModData.setStressFromWork(stress)
local player = getPlayer()
player:getModData().stressFromWork = PZMath.clamp(stress, 0, WorkaholicModData.getMaxStressFromWork())
player:getStats():setStress(player:getModData().stressFromWork)
end
Do a print to check local stress and do WorkaholicModData.setStressFromWork(1)
Check if those work properly
Also do a print("is updating") or some shit like that here
Test points of your code is actually triggering
Really don't hesitate to do that whenever something breaks
Like my code during testing phases has print almost everywhere to check what part runs when and how
setStressFromWork is being called and local stress is returning something.
But ModData.stressFromWork is still = 0
Same video than before
setStressFromWork works alright but is it actually setting your stress ?
Also make sure you're not in godmode, it keeps stress = 0
idk if that could be the reason, I doubt it
Here, I was recording Discord for some reason.
Your stress value is extremely low, that's normal ?
Also goes from e-6 to e-4 then back to e-6
I don't care about that value since it's not updating my character's stress level nor is it updating ModData.stressFromWork
Don't you think the amount of decimals is just too high to have it be kept in moddata ?
Same value but then again: variable is not updating.
No I didn't mean the decimals like 1.024994123 to 1.0250
I lack the english vocabulary, it's the e-4 maybe it's too low
Because that's value e-4 = 0.0000value and maybe it rounds it to 0 ?
Try doing x1000 maybe idk
Exploring ideas, idk what the limitations are of moddata
---@param stress number
function WorkaholicModData.setStressFromWork(stress)
local player = getPlayer()
stress = stress * 1000
player:getModData().stressFromWork = PZMath.clamp(stress, 0, WorkaholicModData.getMaxStressFromWork())
player:getStats():setStress(player:getModData().stressFromWork)
print("Set stressFromWork to: "..stress)
end
```That'll get clamped to 0.51 but I'll test it.
yeah it's fine
Nope.
About setStressFromWork, you tried setting player character stress to 1 ?
Forcing the value used in setStressFromWork to another value
Yes, it does nothing.
It does nothing ? So the issue is setting the stress of the character possibly
player:getModData().stressFromWork = PZMath.clamp(stress, 0, WorkaholicModData.getMaxStressFromWork())
player:getStats():setStress(player:getModData().stressFromWork)
```Plus, they're right next to each other.
Do that
player:getModData().stressFromWork = PZMath.clamp(stress, 0, WorkaholicModData.getMaxStressFromWork())
--player:getStats():setStress(player:getModData().stressFromWork)
player:getStats():setStress(1)
Could possibly be the clamp function too, idk how that works
It's like using min() and max() together.
No, it returns the min
I'm kind of confused what that function does tbf
If it returns the min then that returns 0 ?
Probably.
How about you remove that part for now and do that
player:getModData().stressFromWork = stress
player:getStats():setStress(player:getModData().stressFromWork)
Lemme try setting the min to 1
If you want to make sure your stress value is not above 0.51 you can do it yourself with a simple check
stress = min(0.51,stress)
It works.
Did you do my thing ?
Nice
So it was that stupid clamp all this time?
function math.clamp(value, min, max)
return math.min(math.max(value, min), max)
end
Literally just like that.
public static float clamp(float float1, float float2, float float3) {
float float4 = float1;
if (float1 < float2) {
float4 = float2;
}
if (float4 > float3) {
float4 = float3;
}
return float4;
}
public static long clamp(long long1, long long2, long long3) {
long long4 = long1;
if (long1 < long2) {
long4 = long2;
}
if (long4 > long3) {
long4 = long3;
}
return long4;
}
public static int clamp(int int1, int int2, int int3) {
int int4 = int1;
if (int1 < int2) {
int4 = int2;
}
if (int4 > int3) {
int4 = int3;
}
return int4;
}
public static int clamp(int value, int min, int max) {
int result = value;
if (value < min) {
result = min;
}
if (result > max) {
result = max;
}
return result;
}
Yeah you can basically do
stress = max(0,min(0.51,stress))
And you need the max part only if your stress value can go under 0 tbf
Well, thanks anyway.
np
It still works.
with my min max thing ?
No, just min()
๐
Yeah, do the max thing too
function cacheItems()
print("Startup, getting cache of items available for searching");
local displayNameSet = ITEMSEARCH_PERSISTENT_DATA.displayNameSet;
local allItems = getAllItems();
ITEMSEARCH_PERSISTENT_DATA.itemCache = allItems;
local javaItemsSize = allItems:size();
for x = 0, javaItemsSize -1 do
local item = allItems:get(x);
local displayName = item:getDisplayName();
if not displayNameSet:contains(displayName) then
displayNameSet:add(displayName);
ITEMSEARCH_PERSISTENT_DATA.itemsByDisplayName[displayName] = { item };
else
local matches = ITEMSEARCH_PERSISTENT_DATA.itemsByDisplayName[displayName];
table.insert(matches, item);
end
end
print("Done with cacheItems startup function, should have cached item info for " .. javaItemsSize .. " items provided by getAllItems()");
end```
@chrome egret
in there, the "getAllItems()" function
is that vanilla function or one you coded?
if custom made, could you tell me in which file it is located at??
getAllItems() is a vanilla global function
If you've decompiled the Java, you can see global functions in the LuaManager class
gotcha thank you
---@param value number
---@param min number
---@param max number
---@return number min <= value <= max
local function clamp(value, min, max)
return math.max(min, math.min(max, value))
end
```Made my own function, thank you again for helping my find the issue. You can't believe how many hours I've put into this.
yeah understandable, that's why you just need to go methodically checking everything you use
Reason: Bad word usage
hey all, working on adding adding silicone to the game for use in repairs. how do i define where the item will spawn?
idealy i would like it to be a uncommon spawn in industrial buildings and rarely in sheds and those types of places
apart from that im also wondering if anyone knows where i can find a list of all the display categories?
check the wiki maybe
yeah im trying
That's how susceptible does it
its all good, found the materials display catagory so all i need to do now is define where it spawns
oh ok thank you!
im sure ill need more help soon but for now i think im ok
Yeah I think there's a resource somewhere to know every loot distribution lists
also that guy used this, pretty handy to chance spawn chances, zones etc easily
ok cool! thanks a ton
WorkaholicBaseGameCharacterDetails = {}
function WorkaholicBaseGameCharacterDetails.DoTraits()
local workaholic = TraitFactory.addTrait("Workaholic", getText("UI_trait_workaholic"), 8, getText("UI_trait_workaholicdesc"), false)
workaholic:addXPBoost(Perks.Agility, 1)
workaholic:addXPBoost(Perks.Crafting, 1)
workaholic:addXPBoost(Perks.Fitness, 1)
workaholic:addXPBoost(Perks.Nimble, 1)
workaholic:addXPBoost(Perks.Sprinting, 2)
workaholic:addXPBoost(Perks.Strength, 1)
workaholic:addXPBoost(Perks.Lightfoot, -2)
workaholic:addXPBoost(Perks.Sneak, -1)
TraitFactory.setMutualExclusive("Workaholic", "Graceful")
TraitFactory.setMutualExclusive("Workaholic", "KeenHearing")
TraitFactory.setMutualExclusive("Workaholic", "EagleEyed")
TraitFactory.setMutualExclusive("Workaholic", "Dextrous")
TraitFactory.setMutualExclusive("Workaholic", "LightEater")
TraitFactory.setMutualExclusive("Workaholic", "Inconspicuous")
TraitFactory.setMutualExclusive("Workaholic", "AdrenalineJunkie")
TraitFactory.setMutualExclusive("Workaholic", "AllThumbs")
TraitFactory.setMutualExclusive("Workaholic", "Overweight")
TraitFactory.setMutualExclusive("Workaholic", "Underweight")
TraitFactory.setMutualExclusive("Workaholic", "Very Underweight")
TraitFactory.setMutualExclusive("Workaholic", "Out of Shape")
TraitFactory.setMutualExclusive("Workaholic", "Unfit")
TraitFactory.setMutualExclusive("Workaholic", "Smoker") -- You don't wanna handle both of these do you?
-- Compatibility with "More Description for Traits"
BaseGameCharacterDetails.SetTraitDescription(workaholic)
end
Events.OnGameBoot.Add(WorkaholicBaseGameCharacterDetails.DoTraits)
```This might be a bit too complicated lol
I'll just make it so that you have to manage it like Smoker trait.
And make it a negative trait instead of positive.
Yes, indeed there is
What is Perks.Agility?
how do i make it so that the oven turns on for all players in MP? as it stands everything works well in MP but it doesnt seem to sync, if one player triggers the function the oven still appears off in the other players game, and even the food doesnt refresh after its cooked, shows cooked on one client and uncooked on the other. should i move the custom timed action, which turns the oven on to the shared folder? or is there more to it?
good question
In ZombRand does it include 0, 100 or do I have to offset the 100 into 101?
I believe it goes from 0 to 99
So yes offset
You can test that in the game console too
This trait is gonna be fun to manage ๐
getPlayer():getModData().stressFromWork = 10; getPlayer():getModData().timeSinceLastWork = 10
what does the "survivalgear = TRUE" mean?
im seeing it in tons of items that i would like my item to spawn in (i want the silicone to spawn in industrial places)
Should I turn this into a full mod? Instead of just a single trait?
I already have a few professions and traits listed.
I'll call it: Isaglish's Traits and Professions
You know what? I'll release this into a single mod first and then work on the next one.
Anyway, I'm gonna go catch some dreams. I've got work tomorrow. Thanks again @bright fog I can progress more tomorrow.
my mistake, i got mixed up between the glue and sledgehammer as i was looking at both for the mod im working on
item Glue
{
DisplayCategory = Material,
Weight = 0.1,
Type = Drainable,
UseDelta = 0.2,
UseWhileEquipped = FALSE,
DisplayName = Glue,
Icon = Glue,
Tooltip = Tooltip_FixItems,
SurvivalGear = TRUE,
WorldStaticModel = Glue,
Tags = Glue,
}
this is the code the the glue. look to the 3rd to bottom line where it talks about survival gear
might have to do with this sandbox setting, i'm sure someone will have a better answer for you tho
oh ok
so its in relation to the item rarity?
gonna be asking a million stupid questions, to say im a amature modder is a understatment
my plan for this mod is to add one new item and then change a modded items repair recipe to include the new item
the new item being silicone that i want to be found in industrial areas primarily
ive never added a new item with its own spawn distribution before
Hm, custom modData that I'm setting on generators appears to be disappearing
if generator and not isModded(generator) then
log('We have an unmodded generator!')
local fuel = getRandomFuelLevel()
local condition = getRandomCondition()
local generatorType = getRandomGeneratorType()
local dualFuelSetting = (DUAL_FUEL == generatorType and getRandomDualFuelSetting()) or nil
log('Settings-- fuel:', fuel, ', condition:', condition, ', generatorType:', generatorType, ', dualFuelSetting: ', dualFuelSetting)
generator:setCondition(condition)
generator:setFuel(fuel)
generator:update()
log('Grabbing modData freshly off of generator to set further data points')
modData = generator:getModData()
modData.dualFuelSetting = dualFuelSetting
modData.fuel = fuel
modData.generatorType = generatorType
generator:transmitModData()
generator:transmitCompleteItemToServer()
log('Grabbing modData freshly off of generator after transmit to query data points')
modData = generator:getModData()
for k,v in pairs(modData) do
log('Key:', k, ', value:', v)
end
end
generatorUtils.isModded = function(generator)
local modData = generator:getModData();
if #modData > 0 then
log('All pairs in generator modData:')
for k,v in pairs(modData) do
log('Key:', k, ', value:', v)
end
else
log('No modData set on generator')
end
return modData.generatorType ~= nil;
end
LOG : General , 1708535339369> [Propane Generators (PGGeneratorUtils.lua)]: No modData set on generator
LOG : General , 1708535339369> [Propane Generators (PGCheckForGenerators.lua)]: We have an unmodded generator!
LOG : General , 1708535339369> [Propane Generators (PGCheckForGenerators.lua)]: Settings-- fuel: 87 , condition: 88 , generatorType: Propane , dualFuelSetting: nil
LOG : General , 1708535339370> [Propane Generators (PGCheckForGenerators.lua)]: Grabbing modData freshly off of generator to set further data points
LOG : General , 1708535339370> [Propane Generators (PGCheckForGenerators.lua)]: Grabbing modData freshly off of generator after transmit to query data points
LOG : General , 1708535339371> [Propane Generators (PGCheckForGenerators.lua)]: Key: fuel , value: 87
LOG : General , 1708535339371> [Propane Generators (PGCheckForGenerators.lua)]: Key: generatorType , value:Propane
LOG : General , 1708535339386> [Propane Generators (PGGeneratorUtils.lua)]: No modData set on generator
LOG : General , 1708535339402> [Propane Generators (PGGeneratorUtils.lua)]: No modData set on generator
LOG : General , 1708535339419> [Propane Generators (PGGeneratorUtils.lua)]: No modData set on generator
LOG : General , 1708535339436> [Propane Generators (PGGeneratorUtils.lua)]: No modData set on generator
LOG : General , 1708535339452> [Propane Generators (PGGeneratorUtils.lua)]: No modData set on generator
LOG : General , 1708535339470> [Propane Generators (PGGeneratorUtils.lua)]: No modData set on generator
LOG : General , 1708535339486> [Propane Generators (PGGeneratorUtils.lua)]: No modData set on generator
LOG : General , 1708535339502> [Propane Generators (PGGeneratorUtils.lua)]: No modData set on generator
Hi everyone, good evening, I needed a little help, I wanted to extract the image of this specific saw tile.
but I didn't find out how, I don't know if it's a different method.
but I even tried to search in the tile program, but supposedly where this saw was supposed to be located is invisible
(As in the second example image)
They may be in one of the .pack folders if I'm not mistaken
Go to tilezed
Go to Tools
Go to .pack
Go to .pack viewer
Then look around though the texturepacks folder in zomboid
To find out if it's there
i gonna check it
If you do find it
Hover over what you want
You unpack a file by typing into "Prefix" the first
Word of the tile you want
(Make sure that it's set to single image)
And put in output where you what the file to be put
i gonna save your text if you don't mind
Not at all
Go right ahead
Thanks :0 you helped me a lot
No problem
There aren't many sources on how to unpack things so I'm glad I can give some instruction
Good luck on your endeavor
you too, your mod is awesome
Is there any way I can make
The human and zombie blood colors different?
I want to give the zombies blacker blood
At least for my state of decay retexture
Because I like that about how the zombies looked in state of decay 1
uhhhhh
I feel like there's gotta be a way to assign them both 2 different blood texture files
Depends how hard coded it is
You could maybe modify the java for that
Perhaps
I'm definitely not good at coding but there's gotta be some way to figure it out
Like I said, depends
You could probably go ask in the modding Discord for such specific features
It's going deeper than just the lua itself
Not sure how much help you can get from here
I'll do that
I have alot of ideas but I need to do this to fully realize some of them
There's a whole other server for modding?
dang, link?
Sent you in dm already
danke
ZombRandFloat(min, max)
Aha, thank you!
Some other math functions are used in luautils, it seems plain odd to remove access to math.random
But w/e
it's frustrating because ZombRand uses pretty high quality rng so it causes a lot of slowdown for no real benefit
it's the agility category - to say the perks structure is scuffed would be an understatement ๐ the categories are perks that you just don't gain xp in, and the real perks are children of that perk
bruh
Hello. I'm trying to add some recipes to a certain Trait (if the player has the trait, he knows the recipes, if not, then not).
I have already tried a few things, but it doesn't work.
Can someone help me with that?
i think you need setFreeRecipes not get, but didnt work with traits yet so not sure what that function actually does ๐
Any idea how to tie a sound to a tile specifically? The fireplace for example.
Reason: Bad word usage
Why does the sound not play? what am i missing? character matches my character variable but sound wasnt declared before, is that an issue? No errors either, just the sound never plays
function ISUpgradeWorldObject:start()
self:setActionAnim("RemoveBarricade"); self:setAnimVariable("CrowbarMid");
self.sound = self.character:playSound("GeneratorRepair");
end
Get the player emitter and play the sound through it
yes the action finishes normally
so its not the character reference? (the one that u use for getInventory() for example)
You just do getEmitter on your player and then play the sound
Assuming you declared it
declared the emitter you mean right? ok let me look into it thank u!
No i mean the sound itself
You have to do the same thing as with a model essentially
oh ok so i cant use the in game declarations from scripts with your method?
lol bud i was in debug mode ๐ wasnt aware i dont emit noise when invisible
thanks for the help anyway thought id share this ๐
I'm trying to call a generic function, right after a recipe is completed / item is crafted.
Then, presumably, in that function I could narrow down what recipe was completed by using an if.
there is an items/oncreate and recipes/oncreate in albion's PZModdingGuides, but I don't think these are lua events.
Alternatively, maybe I can hook into ISCraftAction:perform() ??
i think it works like oncooked, event fires when the thing is done. you can hook up your own code to it
you assign the name of the function to the variable basically
I just don't want to overwrite anything, only add onto it.
an arbitrary example: When catching a fish, my player says "I got one!"
Looking at media\lua\client\Fishing\TimedActions
require "TimedActions/ISBaseTimedAction"
ISFishingAction = ISBaseTimedAction:derive("ISFishingAction");
function ISFishingAction:createFish(fishType, fish)
getPlayer():Say("I got one!")
end
But this honestly looks like I'm going to overwrite the function, and fishing will be broken completely
local old_createFish = ISFishingAction.createFish
function ISFishingAction:createFish(fishType, fish)
old_createFish(self, fishType, fish)
getPlayer():Say("I got one!")
end
make sure to pass all arguments to the copy of the original function, and if it has a return value make sure you end up returning it (or a new value depending on your usecase)
hmmm, interesting. What about the prior question, about detecting a just-finished recipe or craft?
you use onCreate to call a function after the recipe has been completed
if there's a timed action for it patching the perform function would be best, the oncreate functions are more for implementing specific recipe functionality, not for catching all of crafting
you could add logging to the onCreate function to print to console or something, or you can wrap the perform action and do something similar
pretty much what albion said tho
i ended up doing some really hacky stuff the other day to get an OnTest function to filter items for all recipes, i would avoid that approach if possible
I'm trying to run a custom line of code, after my player reads Chuck's Skill Recovery Journal.
I could try to hook into the function where it is performed, ISCraftAction:perform()
but I figured it would be easiest to just check if the last recipe i created was recipe Transcribe Journal
if it's just the Transcribe Journal recipe you could set an oncreate on it
i imagine it's probably implemented with one already even? you might be able to hook that
I cannot find it, strangely. I checked all files in /scripts and /lua.
Additionally, I've never hooked into an OnCreate, so I was trying to find examples in discord chat history, workshop, google, etc
hmm yeah he hooks ISCraftAction.perform instead for some reason
though, I've deduced the ISCraftAction.perform is where I need to be, as the translated string "There's nothing left to write" indicates the player has just written in the book / performed the transcribe recipe.
yeah hooking that function seems like the right approach
Like the fishing example, would I need to replace the entire function, where I call the old_function first, then return all vars, etc.? That feels heavy handed imo, hmm
actually...... i think i did it
Hi, how can I delete the "repair" option from clothes?
I have my gloves all set up
But to balance some of them, i want to remove the repairing option, sewing
you mean patching holes?
you might check a vanilla item that cannot be sewed, such as a police bullet proof vest, though i cannot find it in ProjectZomboid\media\scripts\clothing
@bronze yoke just a heads up, I figured it out!
require "TimedActions/ISCraftAction"
--some kind of action was just performed
function ISCraftAction:perform()
if self.item:getType() == "SkillRecoveryBoundJournal" then
--just transcribed a journal, YES
end
end
Ah thanks. I think it would've made sense to do Perks.Agility.Nimble but whatever ๐
Hi there. I'm learning. Can some of you good people explain to me the difference between prerender() and render() Thanks ๐
prerendering is probably where calculations occur before finally getting rendered.
Anyone know how I would be able to go about spawning a specific vehicle through the code? I have a really goofy mod idea that Iโll need to see how it might work ๐
okay. but if they can be used in the exact same way so what's the point of prerender then?
It can cache some calculations thus saving a bit of performance while rendering.
Oh okay thanks. So it calculates something beforehand to be used when necessary, right?
You can think of it that way.
A lot of people throw background stuff in prerender and foreground stuff (like the actual letters you write on a UI) in render. But there's no strict rules to my knowledge in a custom UI regarding what has to go where.
Guys, should I release my mod that adds a single trait or should I add it to a full professions and traits mod?
A single trait will probably not interest people that much
Hey everyone! Can someone provide a method to play sound for the player on the client side? I just need the sound to be audible to the player.
Awesome, I'll modify the file structure and rename the mod then.
Just a heads up... Your override would delete all of this as posted in the message above with no context:
function ISCraftAction:perform()
if self.craftSound and self.character:getEmitter():isPlaying(self.craftSound) then
self.character:stopOrTriggerSound(self.craftSound);
end
if self.container:getType() == "floor" then
self.fromFloor = true;
else
self.fromFloor = false;
end
self.container:setDrawDirty(true);
self.item:setJobDelta(0.0);
local resultItemCreated = RecipeManager.PerformMakeItem(self.recipe, self.item, self.character, self.containers);
if resultItemCreated and instanceof(resultItemCreated, "DrainableComboItem") and self.recipe:getResult():getDrainableCount() > 0 then
resultItemCreated:setUsedDelta(resultItemCreated:getUseDelta() * self.recipe:getResult():getDrainableCount());
end
if resultItemCreated and instanceof(resultItemCreated, "Food") and instanceof(self.item, "Food") then
-- TODO: this could be improved by checking/averaging all the items involved
resultItemCreated:setHeat(self.item:getHeat());
resultItemCreated:setFreezingTime(self.item:getFreezingTime());
resultItemCreated:setFrozen(self.item:isFrozen());
end
if resultItemCreated and self.recipe:getResult():getCount() > 1 then
-- FIXME: this does not call the recipe's OnCreate lua function
local itemsAdded = self.container:AddItems(resultItemCreated:getFullType(), self.recipe:getResult():getCount());
-- now we modify the variables of the item created, for example if you create a nailed baseball bat, it'll have the condition of the used baseball bat
if itemsAdded and instanceof(resultItemCreated, "Food") then
for i=0, itemsAdded:size()-1 do
local newItem = itemsAdded:get(i);
if resultItemCreated:isCustomName() then
```
newItem:setName(resultItemCreated:getDisplayName());
newItem:setCustomName(true);
end
newItem:setCooked(resultItemCreated:isCooked());
newItem:setRotten(resultItemCreated:isRotten());
newItem:setBurnt(resultItemCreated:isBurnt());
newItem:setAge(resultItemCreated:getAge());
newItem:setHungChange(resultItemCreated:getHungChange());
newItem:setBaseHunger(resultItemCreated:getBaseHunger());
newItem:setThirstChange(resultItemCreated:getThirstChangeUnmodified());
newItem:setPoisonDetectionLevel(resultItemCreated:getPoisonDetectionLevel());
newItem:setPoisonPower(resultItemCreated:getPoisonPower());
newItem:setCarbohydrates(resultItemCreated:getCarbohydrates());
newItem:setLipids(resultItemCreated:getLipids());
newItem:setProteins(resultItemCreated:getProteins());
newItem:setCalories(resultItemCreated:getCalories());
newItem:setTaintedWater(resultItemCreated:isTaintedWater());
newItem:setActualWeight(resultItemCreated:getActualWeight());
newItem:setWeight(resultItemCreated:getWeight());
newItem:setCustomWeight(resultItemCreated:isCustomWeight());
--set the new items heat/freezing/frozen
newItem:setHeat(resultItemCreated:getHeat());
newItem:setFreezingTime(resultItemCreated:getFreezingTime());
newItem:setFrozen(resultItemCreated:isFrozen());
newItem:setBoredomChange(resultItemCreated:getBoredomChangeUnmodified());
newItem:setUnhappyChange(resultItemCreated:getUnhappyChangeUnmodified());
end
end
if itemsAdded and instanceof(resultItemCreated, "HandWeapon") then
for i=0, itemsAdded:size()-1```
do
local newItem = itemsAdded:get(i);
newItem:setCondition(resultItemCreated:getCondition());
end
end
if itemsAdded and self.fromFloor then
for i=1,itemsAdded:size() do
self.character:getCurrentSquare():AddWorldInventoryItem(itemsAdded:get(i-1),
(self.character:getX() - math.floor(self.character:getX())) + ZombRandFloat(0.1,0.5),
(self.character:getY() - math.floor(self.character:getY())) + ZombRandFloat(0.1,0.5),
self.character:getZ() - math.floor(self.character:getZ()))
-- NOTE: AddWorldInventoryItem() sets the item's container to null
itemsAdded:get(i-1):setContainer(self.container)
end
end
if itemsAdded and not self.fromFloor then
for i=1,itemsAdded:size() do
self:addOrDropItem(itemsAdded:get(i-1))
end
end
elseif resultItemCreated then
if self.fromFloor then
self.character:getCurrentSquare():AddWorldInventoryItem(resultItemCreated,
self.character:getX() - math.floor(self.character:getX()) + ZombRandFloat(0.1,0.5),
self.character:getY() - math.floor(self.character:getY()) + ZombRandFloat(0.1,0.5),
self.character:getZ() - math.floor(self.character:getZ()))
self.container:AddItem(resultItemCreated)
else
self:addOrDropItem(resultItemCreated)
end
end
ISInventoryPage.dirtyUI()
if self.onCompleteFunc then
local args = self.onCompleteArgs
self.onCompleteFunc(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8])
end
-- needed to remove from queue / start next.
ISBaseTimedAction.perform(self);
end
Which is quite a lot of deleted vanilla behavior...
๐
Are you planning to call the original perform or did you not realize?
You need something like this if you want it to happen AFTER the vanilla behavior is over:
require "TimedActions/ISCraftAction"
local MartianModule = {}
MartianModule.CraftAction = {}
MartianModule.CraftAction.perform = ISCraftAction.perform
--some kind of action was just performed
function ISCraftAction:perform()
MartianModule.CraftAction.perform(self)
-- Possibly unnecessary. Depends on the valid assumptions that you can make about ISCraftActions.
if not (self.item and self.item.getType) then return end
if self.item:getType() == "SkillRecoveryBoundJournal" then
--just transcribed a journal, YES
end
end
-- ...
-- At end of file:
return MartianModule
That executes the original behavior and would be considered a safe decoration
I assume ISCraftActions always have items with getType(), but if they don't necessarily, you would also want if not (self.item and self.item.getType) then return end to be on the safe side.
Hopefully that makes sense.
(FYI, I delete "IS" from your "CraftAction" subtable because your subtable is not made by Indie Stone.)
I also wrap your backup function in a module so that other modders can in theory mod it the way you are modding Indie Stone's stuff (or would be based on above advice).
(Via decoration rather than pure override.)
A lot of people just say local ISCraftAction_perform = ISCraftAction.perform and just call ISCraftAction_perform(self) but I personally prefer keeping everything in a returned module for future compatibility opportunities as a matter of habit.
thanks for taking the time to write all of that out.
I had no idea I was replacing ISCraftAction:perform(), I thought I was just piggybacking onto a public/global function, and adding 1 line.
(I'm new to lua, modules, tables, etc).
I guess I could Copy+Paste your code block, above, into my script, to ensure I don't break the game,
But it, seems a bit heavy handed. --and everything in my current mod is written by me, and fully understood by me, which is ideal, lol
Can you share a bit more about the local ISCraftAction_perform(self) that people use?
It might potentially be the way forward I would prefer.
and lastly, in terms of compatability, wouldn't rewriting the vanilla ISCraftAction:perform() cause compatability issues, depending on where my mod is loaded, in a big mod list load order, anyways?
It's not any different from the above except you have no module. It is in my opinion less heavy-handed to use the module in my example code, because the module in my example could be imported and further decorated, if e.g. someone wants something to happen AFTER Skill Recovery Journal perform but BEFORE your added decoration.
Whereas otherwise no one will be able to access the state of the function as it was before you decorated it... because accessing that local function would be much more complex as a result (maybe not even possible in Zomboid Kahlua; I'm unsure of any way to do it.)
An even less heavy-handed approach (in my view) would be this:
require "TimedActions/ISCraftAction"
local MartianModule = {}
MartianModule.CraftAction = {}
MartianModule.CraftAction.perform = ISCraftAction.perform
--some kind of action was just performed
function ISCraftAction:perform()
MartianModule.CraftAction.perform(self)
-- Possibly unnecessary. Depends on the valid assumptions that you can make about ISCraftActions.
if not (self.item and self.item.getType) then return end
self:doMartianStuff()
end
function ISCraftAction:doMartianStuff()
if self.item:getType() == "SkillRecoveryBoundJournal" then
--just transcribed a journal, YES
end
end
-- ...
-- At end of file:
return MartianModule
Because then they could actually decorate your function's behavior more directly.
My sense of "heavy-handed" here is "changing things drastically in a way that is not as compatible with other mods or updates to vanilla behavior".
Though the code above may feel like "extra", it also increases opportunities for compatibility patching by other modders in the future, and is in that sense much less heavy-handed than, e.g., this alternative that uses fewer lines of code:
require "TimedActions/ISCraftAction"
ISCraftAction_perform = ISCraftAction.perform
--some kind of action was just performed
function ISCraftAction:perform()
ISCraftAction_perform(self)
-- Possibly unnecessary. Depends on the valid assumptions that you can make about ISCraftActions.
if not (self.item and self.item.getType) then return end
if self.item:getType() == "SkillRecoveryBoundJournal" then
--just transcribed a journal, YES
end
end
If by "heavy-handed" you mean "more lines of code", this is obviously less "heavy-handed" -- but if by "heavy-handed" you mean "less easily made compatible with other mods", the shorter code above is actually more heavy-handed.
And, no, decorating perform() this way would not necessarily cause compatibility issues if other mods are also decorating it this way. It is possible for 10 different mods to piggyback on perform() 10 different ways using this technique.
okay, given this latest code block, I'm starting to understand.
I meant heavy handed, in terms of complexity and line count.
As someone with an arts degree, it looked overengineered, or maybe even needlessly complex.
Though, that was before I fully understood what exactly I was doing in my code && before I read all of your explanations
Order would not matter unless the specific mods we're discussing had some very specific impact on the other mods that were doing things before or after them; but most mods would probably be using their own functions / modules / variables, and thus wouldn't mess each other up.
Absolutely fair, hence my clarification of our working definition. There is no "right answer", just facts and consequences to decisions.
Although this one would subjectively be the "wrong" answer for me personally, despite its brevity. Much likelier to cause mod incompatibility and would presumably break vanilla unless you duplicated all the vanilla code, which would look much more heavy-handed in terms of line count.
for sure
Decoration > Override to most of us, I think.
(decoration does involve overriding but it's also more than that.)
Anyhoo... hopefully all that pretty much makes sense to ya.
Good luck with whatever it is that you were doin
Idk honestly lol I just saw that override and thought, "I wonder if he knows..."
nah I had no idea, and was about to upload to workshop in a few minutes LOL
Lmao glad I posted.
Definitely good idea to test various consequences of a decoration of any vanilla function btw, just to make sure it still works as expected, e.g. by crafting vanilla stuff that relies on that action.
I've never actually used a vanilla function. Just lua events, which call my own custom functions, hence not knowing I was overwriting stuff
Also best to test in -debug mode if you're unaware; some errors won't even tell you they're happening if you're not in debug mode, and any error that does happen will make itself obvious at the point of the error.
Fair, fair. Do you know about searching game folders and indexing them?
hmm, no
You do that, and you can use Windows FIle Explorer to search the game files for stuff.
E.g. you could search ProjectZomboid/media for function ISCraftAction:perform() to see what the original does.
(That's what I just did upon seeing your post.)
Indexing folders causes search to hit on both file names and text contents.
I see, I see. I think without indexing, I can search a folder of C# for words in explorer, but i did notice it didnt work for lua
some items have a MetalValue variable but there doesnt seem to be a getMetalValue function, do i write my own getter?
or is that not even possible, i went into the files, found the item.java, indeed no getMetalValue, i wanted to try doing it the same way as with vanilla functions but dont think its gonna work with a compiled file, should i just copy paste the decompile? ๐
When you right-click an inventory item, there are choices. ...but what are they? I would like to find out.
local function CheckRightClickTable(items)
local mysteryTable = items
-- what is in this table...?
for key, value in pairs(mysteryTable) do
print("Key: ", key, "Value: ", value)
end
end
--parameters: int playerIndex, ISContextMenu context, table items,
Events.OnFillInventoryObjectContextMenu.Add(CheckRightClickTable)
ERROR: java.lang.RuntimeException: Expected a table
So did I, java. So did I.
hahah it worked
the getMetalValue getter? ๐ฎ
sheeeesh
well overwritten
gonna be fun keeping this updated
can i make a file not load at all with a condition?
is there any way i can edit bullet's velocity in advanced trajectory mod? i edited it from sandbox options but 2.4 was the limit and i want to make it almost instantaneous
Function(player, context, items). Context is a table.
for i, j in ipairs(context) do
print(i)
print(j)
.....
oh, items is not the table, ISContextMenu is the table? ๐ฎ I'll try that
Nice, I'll start doing this later. I already like doing module stuff but I haven't thought about doing it when injecting code to vanilla functions. The thought of other modders is a nice insight.
Did you change your function signature yet?
Like lect's?
I might have missed someone explicitly telling you, but local function CheckRightClickTable(items) is the wrong signature above.
lect implied it by giving an example
you mean, I need to pass all three parameters? (or arguments, or overloads, whichever is the correct terminology)
You need to receive parameters you plan to use in the order they are provided, and they're always provided to you in the order playerIndex, contextMenu, itemTable
If you are doing something that doesn't need the itemTable, you can leave that off
MartianModule.example = function(playerIndex, contextMenu) would be a valid signature.
But if you are doing something that only needs the items, you can't just drop playerIndex, contextMenu, because they come first whether you want them or not.
I have 13 traits planned and 2 professions for a mod, is that good enough to be released? I'll update the mod when I come up with other traits and professions.
lol I released Darkvision as a standalone trait and everyone who downloads it is happy with it; if your mod is useful to people, it's good enough.
I wouldn't stress over number of traits / professions per mod, personally.
I would stress over coolness and utility of mods.
And compatibility and lack of bugs.
I was planning on releasing my Workaholic mod as a standalone trait but someone told me that it might not get much attraction as much as those more traits mods.
I mean it might not. But my goal is a mod that I value that causes no problems for anyone, rather than mass appeal... some of the big trait mods are poorly debugged and I don't run them because they throw exceptions, so all the hard work that went into the parts that work is lost on me.
I would prefer to add 1 great trait that works than 15 traits where 2 are partly bugged.
local function CheckRightClickTable(playerIndex, context, items)
print("you just right clicked on an item in your inventory") -- this works
for i, j in ipairs(context) do
print(i) --will never print
print(j) --will never print
end
end
Events.OnFillInventoryObjectContextMenu.Add(CheckRightClickTable)
Thanks for the heads up, I added in all three parameters. Though, the function doesn't work as I thought it would, hmm
Awesome then. I love debugging so it should be fine.
context is not an indexed table
I think lect has a typo in the example
items is an indexed table.
context is an ISContextMenu
I mean, it IS technically a table
But not indexed
And it's more precisely conceived as a module
It's a classlike table used for instantiating objects in Lua
items is a purely indexed table
I have a negative trait idea called Bed Wetter 
[1] = value, [2] = next value
lol love it.
Not going to use it but why not
Haha
ah. i checked items, again, and now it prints (table 0x1202151246). very nice -- working, with the correct signature
I don't know what to do with this, or how to read it, but it's a start.
(i was hoping for favorite, equip primary, equip secondary, drop, place, etc.)
I support people roleplaying their way haha
Context:
JukeboxInventory.loadTracksFromInventory = function(playerIndex, menu, stack)
local item = nil
local items = nil
if stack and stack[1] and stack[1].items then
items = stack[1].items
item = items[1]
elseif stack and stack[1] then
item = stack[1]
end
if not (item and item.getType and item.getContainer and item.isInPlayerInventory) then return end
-- -- Looking at items within jukebox; bail.
-- if item:getContainer() and item:getContainer():getType() == "jukebox" then return end
if not Jukebox.isOrHasCassetteOrVinyl(item) then return end
if item:isInPlayerInventory() and Jukebox.playableCassetteOrVinyl(item) then
menu:insertOptionBefore(getText("IGUI_invpage_Transfer_all"), getText("IGUI_invpage_Transfer_all") .. " True Music",
getPlayerInventory(playerIndex), ISInventoryPage.transferAllTrueMusic)
elseif not item:isInPlayerInventory() then
menu:insertOptionBefore(getText("IGUI_invpage_Loot_all"), getText("IGUI_invpage_Loot_all") .. " True Music",
getPlayerLoot(playerIndex), ISInventoryPage.lootAllTrueMusic)
menu:insertOptionBefore(getText("IGUI_invpage_Loot_all"), getText("IGUI_invpage_Loot_all") .. Jukebox.translation.extraTrueMusic,
getPlayerLoot(playerIndex), ISInventoryPage.lootAllExtraTrueMusic)
end
end
Events.OnFillInventoryObjectContextMenu.Add(JukeboxInventory.loadTracksFromInventory)
Most of my traits are pretty serious.
@nimble yarrow That is an example from True Music Jukebox.
I call "items" stack to distinguish it from something I know to be an indexed list of InventoryItems.
stack = your "items"
The thing of note here is that the elements in the stack could be their own list of items
If you have e.g. many of the same item
It is alternatively possible that stack[1] is literally an InventoryItem
Since I don't know until later, I don't call it "items"
It might not REALLY be a list of items.
This is simply a teaser for now but if I really want it to be accurate to the zombies in the movie it's based on
I'll need to do some animation work
I only need 1 item in my code because I'm interested in the container so I just messily grab that
I have another negative trait idea called Chronic Flatulence where you have a chance to fart every hour.
There is a function called something like "getActualItems" that converts it to a list of actual Inventory Items if you need that iirc.
Idr the actual name of that function though
what happened to "time to take a break, before i get burned out. maybe i will try mapping"
Shhhhh
I got inspired again
I can't help it๐ญ
I think it may be ISInventoryPane.getActualItems(items) (or ISInventoryPane.getActualItems(stack) in the convention I posted).
I would have to test to be sure
You know how to use the debug console to enter code?
yeah
I wouldn't publish code with a bunch of global functions like this, but you can copy and paste a chunk like this into debug to reload test code for the OnFillInventoryObjectContextMenu event:
Events.OnFillInventoryObjectContextMenu.Remove(testingContextMenu)
testingContextMenu = function(playerIndex, menu, stack)
end
Events.OnFillInventoryObjectContextMenu.Add(testingContextMenu)
It basically removes the old version, edits it, and adds the new version
You can do anything you want in testingContextMenu
While I was going to end up using your solution for ISCraftAction:perform()...
I really only need to run a line of code, when player reads a journal.
(or, honestly, they wouldn't even need to read it, I just need to know if they have it).
So the new idea, was to just check if they right clicked on it. If they did, I run my 1 line of code,
and my mod is finally ready to be uploaded to workshop
Im not in front of my PC so I don't remember precisely but there is a way to print all the context options when you right click
If you get an error, just copy-paste a new chunk into debug.
You mean all the function names of an ISContextMenu?
When would you check if they right clicked on it?
Ohhhhhh
I see.
I see I see.
I didn't know you could print chunks into the console. that would be helpful, I've always done them in a single line with semicolons?
local myVariable = 1;print(myVariable)
That makes total sense.
Oh I don't think you can print the function names
but if you figure out the context string you can search for it and eventually find the function the context option calls
Oh I think I see what you mean; you meant print all the option names that currently exist in the menu?
You can literally copy-paste 50 lines of code straight into the console
More than (50 is not a limit, just an example)
Yes but if you can just right click and find the option string itself you can pretty much search for the EN context string and then just search the vanilla files for that string
You will find the context function fairly quickly that way
You can but you won't be able to see them.
I guess that doesn't matter.
Correct; you write them in an editor first
No need to see them
Man I swear to god when my framework to make custom zombies comes out you need to check it out lol
Not necessary
Who was the one making the Joy Virus textures?
If you paste them all at once you need no semicolons
The newlines will transfer into the console input
Is there a way to know how dark it is outside or how dark a room is?
I'll check how Claustrophobic works later when I get home.
I absolutely will
The monstrosities I shall create
I don't think I'll be able to make direct support for custom skins for the various zombies bcs I don't think you can have different skins ? But you'll be able to give various stats and behaviours to the zombies
I'm already working in parallel on my revamp of The Last of Us Infected but I plan on creating many addons that base themselves on my framework to demonstrate what is possible (Darkseekers, LeaperZed, random zombies etc)
And I hope it will give a good base for modders to create any type of special zombies
Yes.
Sort of, at least. I relied on getClimateManager():getDayLightStrength(), :getNightStrength() for outdoor lighting. I think other functions might help you with other forms of lighting more though.
If worried about square-level lighting, these elements of IsoGridSquare might be good bets:
I'll be able to use that to give The Knox Plague a bit more unique behavior
Such as staying out of the sun due to that "extreme photosensitivity"
Mentioned in the lore
Thanks, I'll check this out.
require= is this how you set dependency in workshop.txt too?
so it actually shows on the steam page
you can only set workshop dependencies after uploading, on the workshop page
ahh ok im blind cheers and good morning ๐
https://steamcommunity.com/sharedfiles/filedetails/?id=3165835650 spawn on x y coordinates mod anyone? ๐
@thick karma What do you think of this injection?
function ISUninstallVehiclePart:start()
ISTP.Workaholic.startWork()
return ISTPISUninstallVehiclePart.original_ISUninstallVehiclePart_start(self)
end
function ISUninstallVehiclePart:perform()
ISTP.Workaholic.finishWork()
return ISTPISUninstallVehiclePart.original_ISUninstallVehiclePart_perform(self)
end
The ISTP.Workaholic methods has an if statement so that it won't run even when it is called.
aren't you overwriting the originals like this?
No, this is called code injection.
I do my stuff and then the original code runs.
fair enough didnt know u can do it like this too thanks ๐
You're naming convention there is a bit odd (the repetition of "ISUninstallVehiclePart" twice in single function call seems a bit much), but those would work safely assuming you backed up the original functions correctly (you didn't show that part).
I do however suspect that you are unnecessarily returning the result of those function calls. Usually in my experience "perform" and "start" do not return any values to the function that calls them. If that's true here, you could just call them without return in that case. You generally only need to return the result of original function if the original function returned things. Otherwise you can just call it.
I see.
local ISTP = require("ISTPCore")
local ISTPISUninstallVehiclePart = {}
ISTPISUninstallVehiclePart.original_ISUninstallVehiclePart_start = ISUninstallVehiclePart.start
ISTPISUninstallVehiclePart.original_ISUninstallVehiclePart_stop = ISUninstallVehiclePart.stop
ISTPISUninstallVehiclePart.original_ISUninstallVehiclePart_perform = ISUninstallVehiclePart.perform
function ISUninstallVehiclePart:start()
ISTP.Workaholic.startWork()
ISTPISUninstallVehiclePart.original_ISUninstallVehiclePart_start(self)
end
function ISUninstallVehiclePart:stop()
ISTP.Workaholic.stopWork()
ISTPISUninstallVehiclePart.original_ISUninstallVehiclePart_stop(self)
end
function ISUninstallVehiclePart:perform()
ISTP.Workaholic.finishWork()
ISTPISUninstallVehiclePart.original_ISUninstallVehiclePart_perform(self)
end
return ISTPISUninstallVehiclePart
local ISTP = require("ISTPCore")
local ISTPISUninstallVehiclePart = {}
ISTPISUninstallVehiclePart.original_start = ISUninstallVehiclePart.start
ISTPISUninstallVehiclePart.original_stop = ISUninstallVehiclePart.stop
ISTPISUninstallVehiclePart.original_perform = ISUninstallVehiclePart.perform
function ISUninstallVehiclePart:start()
ISTP.Workaholic.startWork()
ISTPISUninstallVehiclePart.original_start(self)
end
function ISUninstallVehiclePart:stop()
ISTP.Workaholic.stopWork()
ISTPISUninstallVehiclePart.original_stop(self)
end
function ISUninstallVehiclePart:perform()
ISTP.Workaholic.finishWork()
ISTPISUninstallVehiclePart.original_perform(self)
end
return ISTPISUninstallVehiclePart
```This is better I guess?
Yes
it doesn't matter
I don't like abbreviation but I don't like long names either.
functions implicitly return nil if they have no return value, there's no difference between not returning and returning a function that doesn't return anything
(returning an unused value is harmless)
It does waste some memory.
No because it's nil
local player = getPlayer()
return player
-- V.S. just returning
return getPlayer()
afaik these perform identically
The one where player is defined will use more memory.
If any it would be virtually undetectable... Removing unnecessary statements is not always strictly required, but I tend to prefer the style of writing only what is necessary. Just an aesthetic choice
There's a really really really tiny difference
but aren't locals compiled?
I come from Python so I always go by their conventions when I can.
Lua is also faster than Python so.
unfortunate we don't really have the tools to profile memory usage
you could test it on normal lua but that wouldn't be any guarantee kahlua does it the same way
I would definitely not drop the return hoping to meaningfully optimize my code in a way that a player would be able to detect @cosmic ermine
I only drop the return for style
As I said I don't like unnecessary commands leftover in my files
That's all
It's fine, everyone has their own style.
i lean the way of minimalism too but forgetting a return on an injection is a common headache so i don't discourage it even when unnecessary
Anyway, my Workaholic trait is pretty much done. I only have it working when uninstalling vehicle parts but that'll change soon.
So what it does is it reduces your stress more the longer you work on something. This way, you can't exploit it by doing the quickest action possible because the value is not fixed.
This is way better before because I was just doing a calculation: 10 * ZombRand(5, 26) / 5...
I forgot the rest of the formula.
I sympathize with what albion is saying. And to be clear, forgetting a necessary return in an injection is FAR worse than unnecessarily using one.
That said, for the same reason I don't write "return nil" at the end of void functions, I don't return known-to-be-nil values.
Just looks off to me
Can't escape with that one buddy.
known to be nil today...
True!
i don't really agree with the absurd future proofing crowd on that one but it is at least an argument
Things could change in an update; never know
if they're making changes like that my mod is probably going to be much more broken than that
In Python when I do something that makes the function return I just do:
return None
```instead of
```python
return
It's just more clear and easier to read in my opinion.
That is unnecessary, yes.
my style recently has been return in functions that don't return values anyway, and return nil in functions that might
But albion's right as usual - there is a theoretical possibility of a function being slightly updated to return a value required by some new mechanic, and a formerly unnecessary return would be prepared for such a patch
Anyway, what do you guys think? I think it's pretty balanced.
well i know i said it but i think it's a little pedantic and not something i care to plan around myself
pretty cool!
I do love the trait idea
Thanks.
I planned to do these stuff.
Not every TimedAction will reduce your stress. Simple ones like unlocking a door or switching seat won't count as working.
I love this cause I can just copy-paste and change the ISUninstallVehiclePart lol
Looks great
What other stuff gives you stress apart from Television and Smoker trait?
Hmm, Stress is getting capped by my update function.
How do I overwrite a Java function in Lua?
I want to overwrite this so that it returns:
this.stress + this.getStressFromCigarettes() + getStressFromWork();
```Otherwise it'll get capped.
-- substitute the correct class
local index = __classmetatables[IsoPlayer.class].__index
local old_getStress = index.getStress
index.getStress = function(self)
return old_getStress(self) + getStressFromWork()
end
The function is a method of Stats though.
then Stats.class
What if it has the $ sign?
_G["String$Name"].class
Awesome, thanks! I'll let you know when it works.
Bug reports.
Especially when they're inaccurate
Hello have a question for the group
Oh wait I think I misunderstood the question
I am working with a new model and in game have texture issues
The texture (diffuse) has a transparency to it
you don't get a visceral thrill from the idea of the chase?
the cat and mouse of it
I do not have a mask or any overlays assigned to it
What can cause the diffuse to be transparent? The PNG isn't transparent
the ~~most ~~least dangerous game
someone here can probably help you but you should also ask in #modeling too
Good idea, I'll ask there as well
Lol not after the mod is live
If I discover a bug it's fine
If someone else does or thinks they do, I literally die
love the answer always turning out to be 'another mod they are using is written badly'
Umm.
-- Overwrites the Java function
local ISTPUtils = require("ISTPUtils")
local ISTPStats = {}
ISTPStats.index = __classmetatables[Stats.class].__index
ISTPStats.original_getStress = ISTPStats.index.getStress
function ISTPStats.index:getStress()
return self.original_getStress(self) + ISTPUtils.Workaholic.getStressFromWork()
end
return ISTPStats
self.original_getStress is not where you put the function
no, it's actually a stats object
the original function is declared that way so all calls are going to pass that
Exactly. The index IS Stats.
it's stats' index table, not an object reference, but yeah
Yeah, stress is no longer capped. Thanks!
Stress will only start decreasing after you work. AWESOME!
This is only my second mod and I'm learning a lot, all thanks to you guys!
that's a real creative concept too, fine work
Thanks.
I got mad on my first day trying to learn how to mod this game because of the lack of help and documentation lol
extremely relatable
i was at it for a couple weeks before going 'i wonder if there's a modding community on the discord'
ya true i found this one after
we get by with a little help from our friends
and a little educational plagiarism
it's a little scuffed when the code comments of a mod with 400 subscribers are the best documentation you'll find for some stuff lmao
Hi! I am kinda new to the modding community, and have some trouble making the simpliest mod. I want to try duplicate a base game clothing, and rename it and retexture it. I followed tutorials, and I think I've done everything needed, but the item doesn't show on the item list ingame. To start off, here's the folder hierarchy, is it correct or does it need more files ? (I use the default models for Vest_Bullets already in the gamefile, so I haven't put it in my mod folder) :
MYMODNAME
Contents
mods
MYMODNAME
media
clothing
clothingItems
Vest_BulletUN.xml
scripts
clothing
MavUN_clothing_shirts.txt
textures
Clothes
BulletVest
Vest_BulletUN.png
fileGuidTable.xml
mod.info
poster.png
Preview.png
Workshop.txt
Sorry in advance if I missed a lot of things or pieces of information. And I'm sorry for my english, I'm french.
I forgot to tell that I can succesfully load the mod in the game
query, what exactly does it take to make a new item repairable? tried making something repairable but it has not worked. is it just the fixer entry, or is there something more needed?
Anyone have any idea what would cause my weapon to not be considered a twohanded weapon
What is your script?
module D&D
{
imports
{
base
}
item Greatsword
{
DisplayCategory = Weapon,
MaxRange = 1.8,
WeaponSprite = Katana,
MinAngle = 0.8,
Type = Weapon,
MinimumSwingTime = 3,
EnduranceMod = 1.5,
HitFloorSound = KatanaHit,
ImpactSound = KatanaHit,
DoorHitSound = KatanaHit,
HitSound = KatanaHit,
SwingSound = KatanaSwing,
KnockBackOnNoDeath = TRUE,
SwingAmountBeforeImpact = 0.03,
Categories = LongBlade,
Weight = 4.5,
ConditionLowerChanceOneIn = 50,
PushBackMod = 1,
SubCategory = Swinging,
ConditionMax = 50,
MaxHitCount = 4,
DoorDamage = 14,
SwingAnim = Bat,
CriticalChance = 30,
CritDmgMultiplier = 4,
DisplayName = Greatsword,
MinRange = 0.8,
SwingTime = 7,
HitAngleMod = -30,
KnockdownMod = 2,
Icon = Katana,
RunAnim = Run_Weapon2,
BreakSound = KatanaBreak,
TreeDamage = 5,
MinDamage = 8,
MaxDamage = 10,
BaseSpeed = 0.8,
WeaponLength = 0.4
DamageCategory = Slash,
DamageMakeHole = TRUE,
TwoHandWeapon = TRUE,
AttachmentType = BigBlade,
}
}
How do you get rid of Depressed?
I'm planning on making a trait that plays with your unhappiness.
yes
add this line
TwoHandWeapon = TRUE,
And let me know if it works
its there on the bottom im pretty sure
Oh?
ahhhh
that might just do it
Ahh typo's bane of all things code
Yup working now thanks
Nice!
So I was making my mod and I believe I did something. and My character disappeared and the zombies looked like this
What can it be?
This looks quite ok so far. Are your naming conventions in the script.txt and the xml files correct? Do you also link to a 3D model somewhere because your mod seems not to contain one? (However, 3D is not always necessary in case you want just make a texture).
For the naming conventions, the name of the xml file should be the same as the name you put behind "item" in the script.txt and and the same value as "ClothingItem". (This is how it works for me at least.)
So far I've checked and changed all the needed names, I'm using the already existing Vest 3D model in the game files used by other bulletproof vests nammed: Kate_BulletVest.X (for female) and bob_bulletvest (for male)
I've been trying all this afternoon for possible fix, maybe I messed up the hierarchy
Because I can activate the mod, but the items are not even present in the item lists
the folder structure looks ok to me. guess you have an error in the xml or the script files. are the pathes in the xml and the fileGuidTable correct? do the guid numbers in the fileGuidTable and the xmls agree?
Until now, I've been testing the mod in C:\Users\MyPC\Zomboid\Workshop if that helps
I've only 3 files, can I send them ? Or just quote them on discord ?
if the game allows you to enable the mod, then this isn't the source of error
maybe posting the relevant files here in chat...
ok
but setting up clothing mods is always prone to errors since you have to arrange so many things to make them work. quite likely you just forget a tiny little thing somewhere
File: Vest_BulletUN.xml
<?xml version="1.0" encoding="utf-8"?>
<clothingItem>
<m_MaleModel>skinned\clothes\bob_bulletvest</m_MaleModel>
<m_FemaleModel>media\models_X\Skinned\Clothes\Kate_BulletVest.X</m_FemaleModel>
<m_GUID>ea897eb4-d341-40b0-a16b-d79bb9f0acfb</m_GUID>
<m_Static>false</m_Static>
<m_AllowRandomHue>false</m_AllowRandomHue>
<m_AllowRandomTint>false</m_AllowRandomTint>
<m_AttachBone></m_AttachBone>
<m_Masks>12</m_Masks>
<m_MasksFolder>media/textures/Clothes/BulletVest/Masks_BulletVest</m_MasksFolder>
<m_UnderlayMasksFolder>media/textures/Clothes/BulletVest/Masks_BulletVest</m_UnderlayMasksFolder>
<textureChoices>clothes\bulletvest\vest_bulletUN</textureChoices>
</clothingItem>
File: MavUN_clothing_shirts.txt
module Base
{
item Vest_BulletUN
{
DisplayCategory = Clothing,
Type = Clothing,
DisplayName = United Nation's Bulletproof Vest,
ClothingItem = Vest_BulletUN,
BodyLocation = TorsoExtraVest,
Icon = BulletVestUN,
BloodLocation = ShirtNoSleeves,
Insulation = 0.6,
WindResistance = 0.25,
BiteDefense = 30,
ScratchDefense = 55,
BulletDefense = 100,
WorldStaticModel = BulletVest_Ground,
}
}
File: fileGuidTable.xml
<?xml version="1.0" encoding="utf-8"?>
<fileGuidTable>
<files>
<path>media/clothing/clothingItems/Vest_BulletUN.xml</path>
<guid>ea897eb4-d341-40b0-a16b-d79bb9f0acfb</guid>
</files>
</fileGuidTable>
I know that from experience (I always forget things like semicolons, etc while coding)...
And I'm ashamed of that rn
I've created a unique GUID
That I used for the vest only
first thing I see: Kate_BulletVest.X should go without an ".X" at the end
I saw that too, but I didn't ask more questions since it was CTRL C CTRL V'd from the Vest_BulletCivilian item
hmmm ok...
Have you tried to put the 3D model into your mod's folder. So just copying the .X files from vanilla to your mod's folder "models_X/Skinned/Clothes" ??
not sure if this is necessary but worth a try
I'm gonna try that
ah... and renaming them after you copied!
But is it the reason why it doesn't even show in the item list ?
in case you copy them, I would still fix the entry in FemaleModel in the xml file
already done
not sure but maybe...
I'm launching the game, but I've also tried testing a similar mod I've found on the steam workshop, both locally (in C:\Users\MyPC\Zomboid\Workshop), and also the "normal" way, where it downloaded it from steam directly.
It only worked when I downloaded it from steam
(sorry if my english is bad btw...)
Weird, it still doesn't show up in the item list
you could also try to temporarily delete the 3 entries for the "Masks" in your xml file since they are not necessary to bring the item into game. also wondering why the pathes in there are defined with a "/" instead of a backslash...
otherwise I couldn't help you anymore...
I think I've found the issue
Don't worry ! You tried, and I thank you for that!
what was it??
The mod ID being the same as the "ModTemplate"
I THINK
Please don't tell me this is tha
I quit
Nope
I quit
It was that
I'm out
ok XD!! then it won't work cause the game will then simply load the empty ModTemplate instead of your mod!!! XD
2 weeks of work down the drain... because of a mod id
Ohhhh yes, it reminds me why I've chosen a programming school
as I said, in most cases, it is just a stupid little mistake which makes those clothing mods not work properly
And it works perfectly...
Thank you
Really
For taking your time to try resolving my problem
I really thought I was gonna be just a random message that no-one will ever read
Thank you
as a tip: in the ModTemplate folder, rename the mod.info file to mod_info. it then won't be load to your mod list anymore
Solid copy
Hey all -- I'm trying to find a way other than UnderwearDefinitions to spawn an item on every zombie. I've looked through the LUA events and don't see one that is triggered on zombie spawns, or even a way at all to grab all zombies, just specific ones in some cases. Am I missing something?
Does anyone have any good guides for adding models to melee weapons? would really appreciate it
Thats a great method to overwrite functions does it work for all functions or only those that are public?
Depends, what are you trying to add to every zombies ? Clothing or items in their inventory when they die ?
For adding clothing it can be a bit tricky but I was able to find a way to add clothing to zombies. The issue with zombies is that they don't actually have an inventory nor actual clothing items on them until they die, their inventory is created on death. The solution is either to make them reanimated zombies which means they will have an inventory but that can lag the fuck out of the game if you do it for every single zombies. The second solution is to change the visual of one of its clothing, I can share with you my method of doing it but overall you need to sacrifice a clothing to replace. I did a priority list of which clothings I want to replace in my case so you don't replace a hat clothing with new shirts for example
It's a clothing item. I figure if I have a way to get each zombie I can figure out ways to do whatever on them. If they don't have an inventory, I suppose that won't work, though. At least, not the way I was going to do it.
How does stuff like UnderwearDefinition work, then? You can specify which items are spawned, and the zombies always have them equipped even before death. Or is that the only way?
I think they always have them equipped yeah. That's the solution used in this mod
https://steamcommunity.com/sharedfiles/filedetails/?id=2789150859
However my way of changing that to not have to replace the underwears everytime (if you want zombies to spawn with em) was to basically replace the visual of clothing like I described in my message
Yeah, I've looked at that mod and it uses the exact same method I'm currently using for mine, heh. I wanted to have a way to do more than just one item, since UnderwearDefinition only has the option of one randomly selected "top" and one defined "bottom".
But yeah, I'm curious as to what your method was and if it'll work for what I'm doing.
If you want to see how I did it, download:
https://steamcommunity.com/sharedfiles/filedetails/?id=3128757602
then open the mod's folder, open TLOUZombies.lua then line 806 is the function handling this
revolves around zombie:getItemVisuals()
Awesome. I'll take a look, thanks!
Basically I've got a priority list that's defined above in local clothingPriority
And I check every visual items of the zombie and make the list of which clothing I want to replace the visual in priority
Since I want to add the fungi hat, it should replace in priority facial stuff then I priorities invisible clothing (so underwears and accessories) etc
What you would want to do basically is just change the priority list for yourself and your case usage
Do that maybe for all of your clothings you want to replace
So if you want to add a shirt to every zombies, replace in priority the shirt, vest tshirt etc
If you want to add a pant, replace pants in priority etc
One issue with that method is if the zombie is naked, you have nothing to replace but I believe you can add clothing visuals so I'll explore that in the next days to improve on it
I need help does anyone know why models would not be showing on a my modded melee weapon
Did you export it right ?
im using a model from another mod as a placeholder so I can figure it out without that variable
Alright that's the right way to go with it
Could simply be your script file the issue ?
I haven't worked on those sadly so I can't have a correct pov on it
as far as I know the position should be correct but that's all I can really say for sure
This is fantastic, thanks. I see what you're doing. I am just confused on where you actually get the zombie you're passing into these functions? Like, what is the actual variable you're sending as the zombie and how did you get it? Can't find that part.
Literally the variables haha
You can parse through bodyparts first - and have individual lists of replacements per parts.
May have less iterations that way (maybe?) + Cover naked
Well that depends but since I need to add the clothing either way I need to find a clothing to replace
Unless I didn't understand your idea exactly
You said you have cases where you want to add clothing but they're naked?
Yeah they just have 0 item visuals so nothing to replace
Rare cases of naked zombies around the map
Even saw that on a server yesterday that was using my tlou infected mod
Maybe I'm asking the wrong question. If I just send "zombie" as an argument, obviously the game will not know which zombie. There must be a way you're picking the specific zed to modify.
Also I'm personally fine having that many iterations because it is done only once
Oh you can look where my function is used and you should see it used on zombie update
Also you're looking at the old mod which is shitty and was extremely bad written by the original author and I'm rewriting it
The Last of Us Infected reworked version. Contribute to SirDoggyJvla/The-Last-of-Us-Infected development by creating an account on GitHub.
If you want to check it out, basically working on a framework to make special zombies and I have a file that details my TLOU zombies and then the ZomboidForge.lua which handles the zombies defined by the addon that add the TLOU zombies
(currently everything is kept in the same mod for easier use)
And I run the clothing thing every zombie update basically
(tho I need to improve it a little bit)
Ahhh, okay. Yes, OnZombieUpdate is what I was looking for. That alone might actually do what I wanted. When is that fired? Like, what is considered an "update"?
It's fired every ticks for every zombies
So be safe when doing stuff with it and not have too heavy features running on it
That can easily shit on performances of the game
Oh wow, every tick on every zombie? That is super simple. This is exactly what I was looking for, I think. Thanks!
๐
There's every events here and if you open them it even tells you when they are triggered and what parameters you can get from those
Yes, I checked that. The description for OnZombieUpdate is just "Triggered when a zombie is being updated." which isn't exactly well explained. :p
Did you check out the negative bits issue I found ?
yea but tbf that's already a lot compared to all the inexistent documentation for modding lmao
Oh, sure. I just didn't know what, exactly, "updated" meant.
๐
Not yet, didn't have an issue on my end - but I didn't test female vs male
The reason could be that you still end up with a trueID at the end, but just that it's 0
That probably means you're sharing the trueID between multiple zombies
basically every female zombies
But yeah if you test it out with any negative pID you'll always end up with trueID = 0
hey does anyone know where i can find those modding license images TIS made
the ones about distribution etc
If you find a steam workshop page with it you can easily access it
true but i want the one that's in the affirmative, and almost all examples of it are the negative ones
but i'll have a look ty
ya basically
i had them bookmarked at one point and i'm struggling to find em again
damn browsers
check out that maybe ?
https://projectzomboid.com/blog/modding-policy/
i feel like it's on one of those pages but it's not that one unfortunately
maybe i'll go scan the forums and see
they're on the spiffo page :) https://pzwiki.net/wiki/Spiffo
Modder people friends, hello 
Would like to inquire towards any of you who have experience with clothing mods, I have plenty of ideas of what I want and enough artistic skill to make textures and such, Iโm just unsure what I need to make, and make it work how I want and such. Would be fine working together on it instead of being taught how to make it work or vice-versa
i can't help ya directly but i've seen this guide recommended to people before
only public - technically speaking it doesn't overwrite the java function, but lua's reference to that function: so the new code won't be triggered if the function is called from java, and there wouldn't be any point overwriting things that lua doesn't have access to anyway
Well for all practical purposes it might aswell overwrite those but thanks for the answer nonetheless
to find an items container I can use item:getContainer() to get the object that that container is attached to item:getContainer():getParent() does this work the same way on things like backpacks?
Actually not all practical purposes. I wanted to use that technique to give power to everything but power is checked on many objects by Java-to-Java calls. Consequently I was able to trick Lua into thinking things had power with that technique, but Java disagreed and would not respond to commands to turn stuff on even though Lua UI options showed that I could.
๐ญ
ugh... the mess that is power...
I would politely suggest to not talk overly critical about the mods of other authors here as you did in your message (i.e. "shitty", "extremely bad written"). Just to avoid beef and stuff. ๐ (Disclaimer: I am not the author of the mod you talked about.)
I'm trying to detect when an item is inside a bag that is inside a player inventory vs when the item is inside a bag that is not in a player inventory... how about... device:getContainer():getParent():getContainer():getType() == "none"
I highly doubt that person is here and tbf, it is extremely badly written. I'm fairly new to modding but you can clearly see the issues with it. But I understand your point anyway.
If you are curious about my claims, it is a known mod that has lots of issues and all the annotations are in chinese so you can't even read it properly. It's a mess, things are getting called upon every ticks literally eating performances of the game.
The mod I'm remaking was a fork of this mod that modified stuff to adapt to his concept and it didn't fix the issues either
Anyway my plan is not make war to anyone nor was it the point of my original message. My point was that he would be looking at a mod that's a mess to read and just pure pain to navigate
Yeah, it's fine. A new implementation of the ideas contained in some other mod cause one doesn't like the original implementation is totally legitimate imo (maybe due to bugs, balance or whatever). Was just the wording of said message which I thought could have been a bit more moderate...
There's no way to use this parameter yet, right?
of only being able to craft an item if it is close to a specific tile?
It will only come in build 42, right? Or is it currently possible to do this?
I believe it is possible to do something like that
Really?
I'm making a mod that involves this, and for now I haven't made any physical "tiles", because I don't know how to make it work with crafting.
So the "tiles" are currently items.
(I don't know lua)
No
So if there's a way for me to make them solid, it will be much better. And I would appreciate it if you found
What he does?
And I have never worked on recipes for now so can't point you in the right direction
idk but I know there's a mod that adds buildable tiles that you need to be next to to craft items
It's NOT a fake furniture like The Workshop
It's an actual tile
it's parcially working
It adds like multiple workshop tiles:
forge, laboratory etc
that's the ingredients, not the tile you wanted it to check for
I mean, that's an item you added there as a requirement
Not a tile
I found this in the original zomboid "recipes" file
It still isn't recognizing it, so I'm unsure if this is still going to happen or has already been added.
https://steamcommunity.com/sharedfiles/filedetails/?id=2914364562
This mod has recipes for which you must be next to tile workstations
That's probably not implemented yet, especially since there's no crafting to make forks
only if you enable "know all recipes"
Right, but the mod uses lua (I don't understand anything about lua)
And when you look at the recipe you see it requires a tile ?
If yes then you can already do it
You can have an OnTest function that checks around the playerโs position and return true if its near the player
It's not hard
The anvil "doesnt" exist in the game yet
Yes but what does it tell you in the crafting menu ?
i gonna give you a example
Hmm
Can you craft the fork when next to this tile ?
I mean here it's an hunting knife you showed but doesn't matter
Try crafting an item that requires it when next to it
no, i can't craft anything
Rip
Then do like this
'm making a mod that adds,
For now)
Machines to facilitate metallurgy and other industrializations of the game. But I wish they were real solid tiles
For now it's just items, because that's the way I found to do crafting
I'll try, thank you very much in advance :)
And if anyone discovers something and wants to share it I would appreciate it
@shy hearth Bruh you are letting them modpack you and not even asking them to change mod ids? What are you crazy? ๐คฃ
i mean they can't upload to the same workshop item as my own right?
๐ You clearly don't do #mod_support
โค๏ธ
I love your generous intention but what you may not realize is that one of the most common bugs users run into is caused by people having two versions of the same mod installed due to a modpack containing an outdated version with the same mod id.
Workshop ID is not relevant to causing the bug
ahhh i see what you mean
The game loads the wrong mod routinely due to the way it finds mods.
It just finds first mod with matching mod ID and says, "This is probably it."
i know i forked a dev copy of my own and ran into the same issue, frustrated me a bit
Then later does Lua Checksum and goes, "Nope, not this one."
And boots the user to #mod_support
good point, i'll make a new notice, not that i trust the majority of users to actually honour it lmao
ty for pointing it out :)
Feel free to borrow suggestions
I wish I could remove embedding on phone
We link to a GitHub with code that has an alt mod id so they only cause issues for other modpackers and with other modpacks if they don't listen.
ooh that's clever
And we explicitly forbid using our mod id and I will straight up report anyone who ignores that lol
ya i'll do that for sure
mostly i make mods for use on my own dedicated so i'm a little indifferent to user error on their end but i'll definitely be putting that in place to protect my own
I do enough mod support that it feels justified lmao, they are the problem here. Usually I am cool about my uploads and my code but not at expense of people thinking my mod is bugged because of what other people do wrong... Annoys me too much haha
Use my code but not badly.
ya totally fair
That's my personal policy
i also get the urge to want one mod where you'd normally have a list of twenty so i do sympathise a little
I saw your prison map recently while troubleshooting for someone and it looked awesome. Good work on that.
I was on video with the guy going, "Oh wow, this is nice."
that means a lot thank you โค๏ธ it's fairly hacked together i must revisit it soon
i only came back to my weather mod today 'cause i saw someone had reuploaded it publicly lmao
I do sympathize but not if they don't sympathize with the effort of modding cooperatively. If I can spend 50 hours making a mod highly compatible, you can spend an hour changing mod id's and dependency refs.
very true, even the hours aside it's the frustration of figuring out how exactly something is done in this haggard codebase
i do also sympathise with wanting the recognition that's due
'cause man it is not easy
Honestly idc as much about the positive recognition as the absence of bad reputation. Being invisible doesn't bother me. Being improperly identified as someone's problem is irritating to me. ๐
ah you're hardly invisible all the same
but i very much understand
thanks for the advice โค๏ธ and doubly for the kind words :)
In the clothing.xml, can I make a probability that a zombie spawn with AT LEAST 1 out of 2 specific items ?
Litteraly an "OR" logic gate. A zombie can spawn with either 1 of the 2 items, can also spawn with 2, but never spawn with neither of them
Idk about doing it there but you might be able to make that kind of guarantee using the OnZombieDead event to give them items.
Sorry, my english is bad, I meant that a zombie spawn with specific clothing*...
Again, my bad...
Oh sorry
I just misunderstood your goal
Nothing about how you said it was wrong I just assumed you wanted them to have something for the player because I didn't read carefully enough
i don't think you can do it in .xml but it's very easy to do in lua
Because earlier today, I've made two pieces of clothing, a helmet and a vest, I want that the zombie with a specific profession get at least one of the items but I can't find anything besides Probabilities, but even if it's set to 0.5 and 0.5, there's still 0.25 chance that it spawns with none of the 2
... I haven't started converting my python knowledge to lua, yet...
no time like the present my friend
you'll love lua, it's awful
I've already codes to finish by the end of the week using homemade library in both Py and JS (please help me, why do I wanna go to programming school ?...)
ah you've more experience than you need then!
also you'll be addicted to this after you finish your first decently complex mod
(Yes, I need to finish code for school and I'm starting another PZ mod project.)
i have a trello board full of c# development tasks to do and i'm here maintaining a mod with 500 subscribers
I'm still a begineer, I don't even know how to center a div without using flex.
so don't worry you're in good company here
btw does anyone have a mask for reference for the ArmyHelmet please? I'm struggling to texture it

best of luck brother, feel free to ask if you need any help with lua stuff later
I think I'll do the .lua part tomorrow, rn in Europe it's midnight so it's gonna be hell if I try to think too much with my last braincell on this mod. Can I ask you about all that lua stuff needed tomorrow ?
absolutely, we're in the same timezone so any time works :)
Alright! Thank you again!
The modeling cult ? It's scary
ahah they're lovely
But I'll try
Hi! Asking for advice!
A colleague and I are working on a mod or enhancement proposal for the entire game UI.
We would like to progress gradually until covering the entirety of the game. Simultaneously, we would like to gradually publish these advancements and gather feedback from the community. We prefer not to scatter individual updates across different platforms and instead maintain a sort of hub where users from any platform (Reddit, Discord, Indie Stone forum, or all at once) could stay updated on these progressions, participate, provide feedback, and thus maintain a repository of sorts to gather everything, rather than dispersing it across different posts that may get lost over time.
What would be the best and easiest place to publish these advancements, where and how?
Thank you!
Github
Definitely Github
Makes it easy to publish changes, follow changes, publish bug reports etc
they want users feedback, not devs feedbacks
"Maintain a repository to gather everything" what do you think they should use ?
Maybe they won't have devs feedback but doesn't mean Github can't be used by others to share feedbacks ?
Tho definitely not the most user friendly to learn how to use, I've started using it for 2 weeks now and I think it's great to follow changes on something
Like Jvla said Github for devs, but Steam workshop comments/item discussion for users.
I mean, they could also simply use the Steam Workshop anyway and use the patch note features, discussions etc
yeah
well exactly I guess
GitHub is my vote - and in my opinion still by far easier to gather feedback/errors (even from users).
But more to the point - pick 1 place and redirect other places to that 1 - for your own sanity.
I also vote GitHub. But when you want players to try your project in-game, you'll want to publish a Steam Workshop Item. If you're trying to redo the entire UI, I'm guessing you're a ways away from Steam Workshop.
Running in debug mode, anyone know what on earth these white boxes at the upper left of my screen are?
You can see a bowl and a box of milk or juice idk
yeah it's weird
Did you modify your files ?
nope
I'm gonna drop Climb Wall support on Sunday
Might want to link people when it's up fwiw
Is it possible to detect whenever a zombie is attacking a door ?
Look for thumpable methods.
Probably that.
getThumpableFor ?
hmm that applies to an object not a zombie so wouldn't be very useful
I have no idea but maybe check for the state of the zombie's AI or something.
I know their current actions are saved into a variable.
My goal is to make a zombie on-shot a door it's hitting
Maybe they have a target variable?
nop
I don't know, bro. Use debug to check the zombies' AI in-game and look for those action variables.
I checked isAttacking, checked target
I'm still a beginner modder so I'm not reliable ๐
Went deeper in the java and found out how they get the object the zombie is attacking but eh
Maybe use that then.
Doesn't work
ow
tho I'm not exactly sure if I can even use it
If you can overwrite Java functions using Lua then you can definitely find a way to use it.
Anyway, I'm gonna take a nap, I'm still at work.
I just did. Read the messages above the message below.
.
does the server also use ModData or does it use a different equivalent?
you can't overwrite a java method, only lua's reference to it - sometimes this is inconsequential but sometimes this means patching is entirely worthless
it also uses moddata
You can't really overwrite a function from another language, can you? What I meant was that it works like I overwrote it since it was working as intended.
i just got around to trying to make blackouts work in MP, but so far i only copied the files and renamed them as client and server and prefixed the server file with if isClient() then return end
i havent changed anything else yet besides the name of the files and the thingy at the start and end to match the new file names
so when you said prefix the file, you mean to put it at the very beginning, meaning before everything, right?
the difference is that you're overwriting what lua calls when it calls that method, if that method were called from java instead your code wouldn't be run
as in the first line of code that does anything should be if isClient() then return end?
yes, the code will stop executing for clients wherever you put it
so typically it's the very first line of actual code
ok
so the second question
the original command to trigger the blackout was just
if blablablablabl
triggerEvent("BlackoutsPowerShutoff")
end```
roughly
should i add something that says like for player blablabla to make it cycle through all the players?
you probably want to use a servercommand here
ok i gtg actually but i will look into that. i think burryaga already dmed me an explanation about that awhile back so i can ask him
Yeah... That's why I asked if I could rewrite Java functions, if not then do it in Lua.
I heard you can manipulate the Java code though? Although the devs recommend against it?
well yeah but not really in the sense that there is any support for doing so
you just... replace the game files
So I just make the same structure and then change a few lines of code?
no, you replace the game files in your actual game install
Oh...
Well, very few Java codes use the Stress functions anyway so I guess it doesn't matter that much.
Can you put tables in ModData?
That includes functions as well.
Like ModData.table.variable to avoid possible conflict in the future.
tables yes, functions no
#mod_development message
is this example the same as what i need to do except on the inverse? instead of sendClientCommand it would be sendServerCommand?
Should I count hotwiring as work for my Workaholic trait?
depends, what have you counted so far?
seems like it wouldn't come into play very often tbh
yes, but there is no player argument
also trello chad
imo a bit annoying of them to put the one that changes in the middle X_X
i think you should start by defining "work" and then finding what fits that definition, rather than looking at each thing individually and asking yourself if you consider it work
I mean successfully hotwiring a vehicle should give you satisfaction and happiness right?
i guess, but that is subjective
I don't think it'd qualify as work in the 'workaholic' sense
but yes it would be satisfying to complete a task, ofc
i would try to define work as "a set of repetitive, mundane tasks that require excess (more than regular) physical or mental labor, with the purpose of achieving a long term objective"
then hotwiring would not qualify as work under the pretense that it isnt repetitive and it isnt necessarily for the purpose of a long term objective
but also my definition is flawed. i pulled it outta my ass
i think the definition works well enough, and personally i wouldnt bother programming for cases that are rather quick and not done very often
and the definition covers that with 'repetitive' and 'require excess labour'
consider this: the rest of the tasks in that list are all done for regular maintenance of the vehicle. hotwiring is not
How do you charge a car battery?
Do I have to take the car battery and then put it right next to a charger?
by using a screw and removing it, then plugging it into a charger. or by leaving the car running and not using the electricity features such as heater or radio iirc
u put it on the charger by interacting with it
Oh, I see.
i remember there being a thing with generators too but im not sure how accurate that is
yea
i think it already triggers anyway since ur removing the part and putting it back in
anything else will be overtuning
thanks. am i supposed to put anything in the curly brackets or is that just how the thing is written?
it's a table, it's not optional so i use that to just create an empty table, but if you need to transmit any information to the clients you put it in there
would that include information like ModData? or can i just use a client command to the server to keep everything in the server side?
can i optimize the mod so i dont need certain moddata that i had in order to prevent errors from happening in the previous version of my mod
like i have one called modData.eventplaying that is literally just a safeguard so that if you speed up the game immensely you cant make blackouts and power startups keep overlapping
ModData saves with your world/server. Unless you don't wanna save values then you can stop using it.
yes, so my question is, since the moddata is on the server, will i need to make a change to the client side commands so that instead of having any moddata change on the client side, it all stays on the server file?
If it's saved on the server then you still need to communicate it back to the clients.
depends really what your moddata is doing
will there be any issues tho if i make changes to the mod data -- which is mainly recorded on the server side -- on the client sided file
in many cases yeah the client never needs to see it
ok i figured as much
so can i use a client command just to tell the server to set everything back to normal after the event is triggered?
such as the blackout cooldown
i'd handle all of the logic to do with the timing of the blackouts on the server and just send commands to the client when it should actually start/stop one
lmao, found an exploit.
modData.eventplaying = false --?? labels that event is not occurring
modData.cooldown = SandboxVars.Blackouts.Cooldown
so i can remove this and instead just tell the server to reset them?
im trying to optimize the mod for multiplayer. i think i have a lot of things that dont make sense for someone who knows what they're doing, which is why im asking about what im doing that may not be necessary for what im trying to achieve
actually i think i need to completely rethink how im doing this
Heh, I patched it.
ok just from looking at this, i know if someone joins while the world is in middle of a temporary blackout, that player will be out of sync and still have the power on
Get the eventPlaying from the server and then pass it to the player who joins, that should fix it.
i think as long as you set the blackout on the server too joining players will just get that state from the server
the blackout is client sided, which is the issue reported to me from the comments on my mod
i think i asked about it before and the conclusion was to make a command to all the clients to black out at the same time
Anyone know how to add models to a custom weapon I have been struggling for a day to figure it out would really appreciate some help (this is my first time modding)
this data was used for something else, but that is something i was actually thinking about. now im trying to figure out how to change its purpose to this without making it break anything for other players who already have the mod installed
but rn i am testing the mod just to see if currently works in single player, because i could have broken something with all the changes i just made
i don't really know, but i would guess the current state is grabbed from the server upon joining, even if changes aren't synchronised automatically
i will just have to test with someone by triggering a blackout and then having them join
im surprised the lua files even loaded with all the changes i made without testing
usually when i make changes i get an error and the file disappears from the debug search thing
ok blackouts dont work on single player. should i have different functions for when the game is single player vs when it is multiplayer?
or does it just mean i wrote it wrong and if it was done correctly it should work either way in single or multiplayer
oh yeah so an annoying feature of commands is that server commands don't fire in singleplayer, even though client commands do
usually i just do something like
if isServer() then
sendServerCommand("MyMod", "MyCommand", {})
else
triggerEvent("OnServerCommand", "MyMod", "MyCommand", {})
end
oh okay i had something before, but i didnt realize i can do the samething with a module and command
before i made 2 whole events
as seen here
I figured it out now I think thanks anyways (never mind)(Update I was on the right path and it's fixed now)
that way will be a lot more convenient
can i name the module and command the same thing? or should i make them explicitly distinct? such as adding MP and SP to the command name?
ohh wait i see. does that thing you sent make it call the exact same event?
meaning i dont have to add a different version of the event that is identical
yeah it just fires the event like the command normally would
so that you don't need different code for sp and mp (usually)
ok i got it working in single player
i need to create a safeguard so that worlds already made will correct themselves
by default modData.eventplaying is already false, and it only (used to) turn true when the literal effect was being played, so i was thinking of just making a check so that if someone logged in it would check if modData.eventplaying is true or false and just trigger the event immediately to resync them with the server
by default that would mean most ppl would end up with their power coming back on
even if they got desynced and half the players have the power off and the other half on
(also im realizing that the way i had it before meant u could really screw something up if u logged off right in middle of the sound playing)
Joy has special code to mitigate this. @rancid panther this is the purpose of the directClients function I sent you.
(several days ago in DMs)
oh yeah i got that, i was looking at it while i was suddenly working on it tonight
i havent gotten a chance to try fixing it till now
can you explain it a bit more to me?
i also changed a lot of things so it looks very different from how it might have when u first looked at it
It's very similar to what albion sent you. If you're in singleplayer, it manually triggers an event that mimics the server response on MP.
That's what triggerEvent line is for.
oh yeah, so the way i had it before was basically just what albion sent me but they used to be separate events
i saw albion's suggestion and realized it was basically just a more compact way of doing things
as seen here
Your version is made to also autobranch for commands that go direct to player vs commands thaf forward to everyone
You may want both
If a player connects to server, you request data be sent just to that player
But if a blackout occurs while players are in game together, you forward data to everyone
