Project Zomboid

Project Zomboid

Brutal Handwork
dhert  [developer] Feb 17, 2023 @ 2:38am
Report Bugs here
A list of current bugs and limitations of this mod are below. I am calling the limitations "bugs" because they will be fixed.
  • RANGED WEAPONS DO NOT CURRENTLY WORK IN YOUR OFFHAND! THIS WILL COME IN A LATER UPDATE! ONLY MELEE WEAPONS FOR NOW!
  • PVP IS COMPLETELY UNTESTED, BUT TECHNICALLY SHOULD WORK. YOU WILL ONLY HIT ANOTHER PLAYER IF NO ZOMBIES ARE IN RANGE. PVP WILL BE DEFINITIVELY/TESTED ADDED LATER!
  • The offhand/unarmed attack is a TimedAction, but really this is only used to sync the state of the animation; timing and other stuff is all done based on the calculated attack speed, etc. This has left one issue: the Turning Animation. Turning in Project Zomboid kinda sucks, as it overrides the animation state and will delay TimedActions. I have worked around this by briefly locking your character's facing direction (talking 2-3 frames, so not even noticeable) so that the attack animation has time to start before allowing the turn again. This is not perfect and the turn can still kinda happen, so do note that attempting to turn and do the offhand attack may cause the offhand attack to start a bit later than expected.
  • Offhand damage is sometimes incorrect. The vanilla functions are used to perform the Hit action, and the primary weapon is hardcoded to be used in some functions. I work around this now by changing a multiplier by the inverse it would receive for the primary weapon and apply corrections to the secondary, but this does not yield 100% accurate results. The only solution that worked after weeks of testing was to completely rewrite the damage calculations myself. I have done this, but found I could not get target hit reactions to sync in multiplayer; so for now the code is unsued. I have some major plans to incorporate this, but need more time to work out a solution for the target syncing.
    In the next update, I will first release a SINGLEPLAYER only version of this damage function.
  • Offhand attacks use the vanilla Hit function, and for whatever reason the hit reaction doesn't seem to work as expected for offhand attacks. Zombies don't seem to fall down as consistently, but it still does happen; they do stagger from the hit and all no problem still. My functions correct this, but they do not sync in multiplayer at this time.
  • Offhand/Unarmed attacks currently do not trigger Critical Hits, and sometimes Rear Damage for some reason (blame the built-in Hit function). My functions correct this, so will be fixed later.
  • Offhand attacks sometimes hit a different enemy than expected. The target is determined based on the weapon's attack range and arc, and found objects are sorted by distance; the closest object is then hit. This does mean that you may hit a target that is closer to you but to your left or right instead of what is highlighted. I am working to fix this.
  • Offhand attacks do not trigger a "Down" attack, and will instead do the primary weapons "Down" attack or stomp on the enemy.
  • Sometimes when you spam press the offhand attack, your character will flap their arms as a "shove" instead of attacking. This attack could do a lot of damage for some reason. I have tried to mitigate this as much as possible, but it still can happen.
  • When using on a Dedicated Server, there is sometimes an error when unarmed attacking. I have found no rhyme or reason for this: it sometimes happens when you hit a Zombie, but the next/other hits on the same zombie work fine. It seems to be due to the server not instancing the weapon properly on hit sometimes. The error is harmless and everything seems to still work, but does generate noise in the log. Sorry about that.
  • Raising your fists does not sync in multiplayer, but attacks do. This will require a change in Fancy Handwork, coming soon.
Any bugs should also be reported here with logs; please do not simply say "X doesn't work" without giving more information or your comment will just be deleted. These comments do nothing to help, and unless it is very easy to reproduce, will not lead to me being able to replicate or fix it. Help me, help you.
Last edited by dhert; Feb 17, 2023 @ 2:45am
< >
Showing 1-15 of 131 comments
NalMac Feb 17, 2023 @ 5:51am 
So it appears the mod isn't working at all and is throwing up errors whenever I try to attack. it has also made attacking in general do nothing. I am only using this, fance handwork and one true cure but better but I did also run into this issue without OTC.
NalMac Feb 17, 2023 @ 5:52am 
The errors I get are the folling.
`function: attackHook -- file: zBrutalHandwork.lua line # 56 | MOD: Brutal Handwork java.lang.RuntimeException: Object tried to call nil in attackHook at se.krka.kahlua.vm.KahluaUtil.fail(KahluaUtil.java:82) at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:973) at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163) at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980) at se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1812) at se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:66) at se.krka.kahlua.integration.LuaCaller.protectedCallVoid(LuaCaller.java:139) at zombie.Lua.Event.trigger(Event.java:64) at zombie.Lua.LuaHookManager.TriggerHook(LuaHookManager.java:75) at zombie.characters.IsoLivingCharacter.AttemptAttack(IsoLivingCharacter.java:66) at zombie.characters.IsoPlayer.updateInternal2(IsoPlayer.java:2485) at zombie.characters.IsoPlayer.updateInternal1(IsoPlayer.java:1935) at zombie.util.lambda.Invokers$Params1$CallbackStackItem.run(Invokers.java:37) at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71) at zombie.core.profiling.AbstractPerformanceProfileProbe.lambda$invokeAndMeasure$0(AbstractPerformanceProfileProbe.java:83) at zombie.util.lambda.Stacks$Params3$CallbackStackItem.invoke(Stacks.java:230) at zombie.util.lambda.Stacks$GenericStack.invokeAndRelease(Stacks.java:26) at zombie.util.Lambda.capture(Lambda.java:130) at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:81) at zombie.characters.IsoPlayer.update(IsoPlayer.java:1924) at zombie.MovingObjectUpdateSchedulerUpdateBucket.update(MovingObjectUpdateSchedulerUpdateBucket.java:79) at zombie.MovingObjectUpdateScheduler.update(MovingObjectUpdateScheduler.java:145) at zombie.iso.IsoCell.ProcessObjects(IsoCell.java:2955) at zombie.iso.IsoCell.updateInternal(IsoCell.java:5750) at zombie.util.lambda.Invokers$Params1$CallbackStackItem.run(Invokers.java:37) at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71) at zombie.core.profiling.AbstractPerformanceProfileProbe.lambda$invokeAndMeasure$0(AbstractPerformanceProfileProbe.java:83) at zombie.util.lambda.Stacks$Params3$CallbackStackItem.invoke(Stacks.java:230) at zombie.util.lambda.Stacks$GenericStack.invokeAndRelease(Stacks.java:26) at zombie.util.Lambda.capture(Lambda.java:130) at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:81) at zombie.iso.IsoCell.update(IsoCell.java:5696) at zombie.iso.IsoWorld.updateInternal(IsoWorld.java:3499) at zombie.util.lambda.Invokers$Params1$CallbackStackItem.run(Invokers.java:37) at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71) at zombie.core.profiling.AbstractPerformanceProfileProbe.lambda$invokeAndMeasure$0(AbstractPerformanceProfileProbe.java:83) at zombie.util.lambda.Stacks$Params3$CallbackStackItem.invoke(Stacks.java:230) at zombie.util.lambda.Stacks$GenericStack.invokeAndRelease(Stacks.java:26) at zombie.util.Lambda.capture(Lambda.java:130) at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:81) at zombie.iso.IsoWorld.update(IsoWorld.java:3427) at zombie.gameStates.IngameState.updateInternal(IngameState.java:1617) at zombie.gameStates.IngameState.update(IngameState.java:1333) at zombie.gameStates.GameStateMachine.update(GameStateMachine.java:101) at zombie.GameWindow.logic(GameWindow.java:298) at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71) at zombie.GameWindow.frameStep(GameWindow.java:765) at zombie.GameWindow.run_ez(GameWindow.java:681) at zombie.GameWindow.mainThread(GameWindow.java:495) at java.base/java.lang.Thread.run(Unknown Source) `

`function: checkDoAttack -- file: zBrutalHandwork.lua line # 168 | MOD: Brutal Handwork function: onMouseClick -- file: zBrutalHandwork.lua line # 188 | MOD: Brutal Handwork java.lang.RuntimeException: Object tried to call nil in checkDoAttack at se.krka.kahlua.vm.KahluaUtil.fail(KahluaUtil.java:82) at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:973) at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163) at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980) at se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1812) at se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:66) at se.krka.kahlua.integration.LuaCaller.protectedCallVoid(LuaCaller.java:139) at zombie.Lua.Event.trigger(Event.java:64) at zombie.Lua.LuaEventManager.triggerEvent(LuaEventManager.java:134) at zombie.ui.UIManager.update(UIManager.java:775) at zombie.GameWindow.logic(GameWindow.java:262) at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71) at zombie.GameWindow.frameStep(GameWindow.java:765) at zombie.GameWindow.run_ez(GameWindow.java:681) at zombie.GameWindow.mainThread(GameWindow.java:495) at java.base/java.lang.Thread.run(Unknown Source) `
Pao Feb 17, 2023 @ 6:16am 
About that error:
line 58 in zBrutalHandwork.lua, you're setting
local mkl = isFHModBindDown(character)

Also in line 168 same thing

that specific function doesn't exist right now, but I guess that should be isFHModKeyDown(). I tried to replace it with that and it seems to work.
dhert  [developer] Feb 17, 2023 @ 9:23am 
Hey @NalMac and @Pao. This would indicate that Fancy Handwork was not updated on your server/host. An update was pushed at around the same time this was released which added the `isFHModBindDown(character)` function. I use this to also add support for the "Left Bumper" on the controller, and moving forward this will replace `isFHModKeyDown()` everywhere.
DmitriySenpai Feb 17, 2023 @ 10:05am 
Not compatible with Firearms B41 mod
https://steamcommunity.com/sharedfiles/filedetails/?id=2256623447
For some reason if you using this mod you can't dual wielding melee weapons
In dual wield doesn't use offhand weapon
And if you take firearm in secondary hand and melee in main hand you cant melee attack only shove
Last edited by DmitriySenpai; Feb 17, 2023 @ 10:07am
dhert  [developer] Feb 17, 2023 @ 10:24am 
@DmitriySenpai - The Firearms B41 overrides the Attack Hook as well it seems, and does so in a way that is not compatible. I tested this with Brita's gun mod.
This shouldn't be too difficult to fix though, and would possibly give me better compatibility with other mods. Thanks for letting me know.
Sco Feb 17, 2023 @ 12:29pm 
ERROR: Multiplayer , 1676665478071> 227,005,344> GameServer.receiveHitCharacter> Exception thrown java.nio.BufferUnderflowExce
ption at Buffer.nextGetIndex. Message: ReceiveHitCharacter: failed
ERROR: Multiplayer , 1676665478071> 227,005,345> DebugLogStream.printException> Stack trace:
java.nio.BufferUnderflowException
at java.base/java.nio.Buffer.nextGetIndex(Unknown Source)
at java.base/java.nio.HeapByteBuffer.getFloat(Unknown Source)
at zombie.network.packets.hit.WeaponHit.parse(WeaponHit.java:35)
at zombie.network.packets.hit.PlayerHitZombiePacket.parse(PlayerHitZombiePacket.java:38)
at zombie.network.GameServer.receiveHitCharacter(GameServer.java:6630)
at zombie.network.PacketTypes$PacketType.onServerPacket(PacketTypes.java:1022)
at zombie.network.GameServer.mainLoopDealWithNetData(GameServer.java:1532)
at zombie.network.GameServer.main(GameServer.java:800)

it happens when I attack
dhert  [developer] Feb 17, 2023 @ 12:48pm 
@matte - Does this only occur when you are unarmed, or when you are using an offhand attack too? Is this when you are using the "Host" option, or a Dedicated Server?

This error is from me using the vanilla Hit functions, as it uses this to sync the hit state. The error is inconsistent in my testing, but seems to happen moreso with modded weapons. Not sure where the error is or if I can fix it as its called from the Java side of things. I have encountered similar errors, but it mostly seems to just be "noise" in the logs and it all still works.
RottenEye Feb 17, 2023 @ 3:32pm 
With Brita's Weapon Pack (Not tested will vanilla firearms) If you have a pistol in the primary and knife in the secondary using the knife will have the range of the pistol.
Last edited by RottenEye; Feb 17, 2023 @ 3:50pm
RottenEye Feb 17, 2023 @ 3:49pm 
It also seems that sometimes offhand weapons will do no damage at all.
dhert  [developer] Feb 17, 2023 @ 4:01pm 
@Broski - Yes, I am aware of the offhand attacks just sometimes not applying damage. This is an issue with how the base game does the damage when I use the Hit function; it just sometimes doesn't apply the damage even though I see numbers going. Unfortunately, that cannot be fixed until I switch over to my own damage functions as the issue where this occurs is is not exposed to changes via modding.

As for the offhand melee weapon range, seems you are right about this as offhand melee weapons do use primary hand properties when there are no zombies around. This means even more work for me, as I was hoping to just use a vanilla function for hitting world objects; but it seems to hit zombies if the primary weapon is in range too. For now, I will simply prevent the offhand attacks from doing any damage if you have a gun in your primary hand and there are no zombies to hit.
Katt19 Feb 17, 2023 @ 7:39pm 
So the mod seems to work, but whenever I try to punch the air with my fist or with a weapon on my second hand (without having any weapons on my first hand) it makes errors pop up, doesn't affect on gameplay so far but it does stack errors on the logs, tested on singleplayer with following mods: Mod Options; Swapt it(and Easy Config Chucked); Brutal Handwork, Fancy Handwork; Donazo's Fine Fisticuffs.
I did restart my game after activating the mods, and tested it both in an existing save and a new save.
Katt19 Feb 17, 2023 @ 7:41pm 
LOG : General , 1676690835783> -----------------------------------------
STACK TRACE
-----------------------------------------
function: FindAndAttackTargets -- file: BrutalAttack.lua line # 621 | MOD: Brutal Handwork
function: animEvent -- file: BH_MeleeAttackTimedAction.lua line # 87 | MOD: Brutal Handwork

ERROR: General , 1676690835784> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: attempted index: isRanged of non-table: null at KahluaThread.tableget line:1689.
ERROR: General , 1676690835784> DebugLogStream.printException> Stack trace:
java.lang.RuntimeException: attempted index: isRanged of non-table: null
at se.krka.kahlua.vm.KahluaThread.tableget(KahluaThread.java:1689)
at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:641)
at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163)
at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980)
at se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1861)
at se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:48)
at zombie.characters.CharacterTimedActions.LuaTimedActionNew.OnAnimEvent(LuaTimedActionNew.java:152)
at zombie.characters.IsoPlayer.OnAnimEvent(IsoPlayer.java:9409)
at zombie.core.skinnedmodel.advancedanimation.AdvancedAnimator.OnAnimEvent(AdvancedAnimator.java:264)
at zombie.core.skinnedmodel.advancedanimation.AnimLayer.invokeAnimEvent(AnimLayer.java:211)
at zombie.core.skinnedmodel.advancedanimation.AnimLayer.updateInternal(AnimLayer.java:419)
at zombie.GameProfiler.invokeAndMeasure(GameProfiler.java:166)
at zombie.core.skinnedmodel.advancedanimation.AnimLayer.Update(AnimLayer.java:323)
at zombie.core.skinnedmodel.advancedanimation.AdvancedAnimator$SubLayerSlot.update(AdvancedAnimator.java:665)
at zombie.core.skinnedmodel.advancedanimation.AdvancedAnimator.updateInternal(AdvancedAnimator.java:403)
at zombie.GameProfiler.invokeAndMeasure(GameProfiler.java:166)
at zombie.core.skinnedmodel.advancedanimation.AdvancedAnimator.update(AdvancedAnimator.java:368)
at zombie.characters.IsoGameCharacter.postUpdateInternal(IsoGameCharacter.java:12087)
at zombie.util.lambda.Invokers$Params1$CallbackStackItem.run(Invokers.java:37)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.core.profiling.AbstractPerformanceProfileProbe.lambda$invokeAndMeasure$0(AbstractPerformanceProfileProbe.java:83)
at zombie.util.lambda.Stacks$Params3$CallbackStackItem.invoke(Stacks.java:230)
at zombie.util.lambda.Stacks$GenericStack.invokeAndRelease(Stacks.java:26)
at zombie.util.Lambda.capture(Lambda.java:130)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:81)
at zombie.characters.IsoGameCharacter.postupdate(IsoGameCharacter.java:12063)
at zombie.characters.IsoPlayer.postupdateInternal(IsoPlayer.java:3740)
at zombie.util.lambda.Invokers$Params1$CallbackStackItem.run(Invokers.java:37)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.core.profiling.AbstractPerformanceProfileProbe.lambda$invokeAndMeasure$0(AbstractPerformanceProfileProbe.java:83)
at zombie.util.lambda.Stacks$Params3$CallbackStackItem.invoke(Stacks.java:230)
at zombie.util.lambda.Stacks$GenericStack.invokeAndRelease(Stacks.java:26)
at zombie.util.Lambda.capture(Lambda.java:130)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:81)
at zombie.characters.IsoPlayer.postupdate(IsoPlayer.java:3733)
at zombie.MovingObjectUpdateSchedulerUpdateBucket.postupdate(MovingObjectUpdateSchedulerUpdateBucket.java:97)
at zombie.MovingObjectUpdateScheduler.postupdate(MovingObjectUpdateScheduler.java:168)
at zombie.CollisionManager.resolveContactsInternal(CollisionManager.java:411)
at zombie.util.lambda.Invokers$Params1$CallbackStackItem.run(Invokers.java:37)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.core.profiling.AbstractPerformanceProfileProbe.lambda$invokeAndMeasure$0(AbstractPerformanceProfileProbe.java:83)
at zombie.util.lambda.Stacks$Params3$CallbackStackItem.invoke(Stacks.java:230)
at zombie.util.lambda.Stacks$GenericStack.invokeAndRelease(Stacks.java:26)
at zombie.util.Lambda.capture(Lambda.java:130)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:81)
at zombie.CollisionManager.ResolveContacts(CollisionManager.java:236)
at zombie.iso.IsoWorld.updateInternal(IsoWorld.java:3502)
at zombie.util.lambda.Invokers$Params1$CallbackStackItem.run(Invokers.java:37)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.core.profiling.AbstractPerformanceProfileProbe.lambda$invokeAndMeasure$0(AbstractPerformanceProfileProbe.java:83)
at zombie.util.lambda.Stacks$Params3$CallbackStackItem.invoke(Stacks.java:230)
at zombie.util.lambda.Stacks$GenericStack.invokeAndRelease(Stacks.java:26)
at zombie.util.Lambda.capture(Lambda.java:130)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:81)
at zombie.iso.IsoWorld.update(IsoWorld.java:3427)
at zombie.gameStates.IngameState.updateInternal(IngameState.java:1617)
at zombie.gameStates.IngameState.update(IngameState.java:1333)
at zombie.gameStates.GameStateMachine.update(GameStateMachine.java:101)
at zombie.GameWindow.logic(GameWindow.java:298)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.GameWindow.frameStep(GameWindow.java:765)
at zombie.GameWindow.run_ez(GameWindow.java:681)
at zombie.GameWindow.mainThread(GameWindow.java:495)
at java.base/java.lang.Thread.run(Unknown Source)
LOG : General , 1676690835787> -----------------------------------------
STACK TRACE
-----------------------------------------
function: FindAndAttackTargets -- file: BrutalAttack.lua line # 621 | MOD: Brutal Handwork
function: animEvent -- file: BH_MeleeAttackTimedAction.lua line # 87 | MOD: Brutal Handwork
dhert  [developer] Feb 17, 2023 @ 8:24pm 
@Katt19 - Thanks for your report. I accidentally used an `and` instead of an `or` in my logic, so it caused an error. I have just pushed an update to fix this.
Farshot Feb 18, 2023 @ 2:17am 
Holding the modifier with a gun while switching weapons gives melee sniping capabilities
Last edited by Farshot; Feb 18, 2023 @ 2:36am
< >
Showing 1-15 of 131 comments
Per page: 1530 50