Update FancyHandwork, add BrutalHandwork
This commit is contained in:
@@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<animNode>
|
||||||
|
<m_Name>AttackDefaultL</m_Name>
|
||||||
|
<m_AnimName>Bob_Attack1Hand01_Hit_L</m_AnimName>
|
||||||
|
<m_Priority>4</m_Priority>
|
||||||
|
<m_deferredBoneAxis>Y</m_deferredBoneAxis>
|
||||||
|
<m_Looped>false</m_Looped>
|
||||||
|
<m_EarlyTransitionOut>true</m_EarlyTransitionOut>
|
||||||
|
<m_SpeedScale>LCombatSpeed</m_SpeedScale>
|
||||||
|
<m_BlendTime>0.15</m_BlendTime>
|
||||||
|
<m_BlendOutTime>0.25</m_BlendOutTime>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>PerformingAction</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>LAttack</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>LAttackType</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>bash</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Transitions>
|
||||||
|
<m_Target>Idle</m_Target>
|
||||||
|
<m_AnimName>Bob_AimToIdle_1Hand</m_AnimName>
|
||||||
|
<m_blendInTime>0.5</m_blendInTime>
|
||||||
|
<m_blendOutTime>0.5</m_blendOutTime>
|
||||||
|
<m_speedScale>1.3</m_speedScale>
|
||||||
|
</m_Transitions>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>AttackCollisionCheck</m_EventName>
|
||||||
|
<m_TimePc>0.25</m_TimePc>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>BlockMovement</m_EventName>
|
||||||
|
<m_TimePc>0.75</m_TimePc>
|
||||||
|
<m_ParameterValue>TRUE</m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>StartAttack</m_EventName>
|
||||||
|
<m_Time>Start</m_Time>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>EndAttack</m_EventName>
|
||||||
|
<m_Time>End</m_Time>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>SetVariable</m_EventName>
|
||||||
|
<m_TimePc>0.1</m_TimePc>
|
||||||
|
<m_ParameterValue>ZombieHitReaction=HeadRight</m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Spine1</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Neck</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_BackPack</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Prop2</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Spine</boneName>
|
||||||
|
<includeDescendants>false</includeDescendants>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
</animNode>
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<animNode>
|
||||||
|
<m_Name>BH_LeftPunch1</m_Name>
|
||||||
|
<m_AnimName>Bob_BH_AttackPunch01_L_Hit</m_AnimName>
|
||||||
|
<m_Priority>4</m_Priority>
|
||||||
|
<m_deferredBoneAxis>Y</m_deferredBoneAxis>
|
||||||
|
<m_Looped>false</m_Looped>
|
||||||
|
<m_EarlyTransitionOut>true</m_EarlyTransitionOut>
|
||||||
|
<m_SpeedScale>LCombatSpeed</m_SpeedScale>
|
||||||
|
<m_BlendTime>0.15</m_BlendTime>
|
||||||
|
<m_BlendOutTime>0.25</m_BlendOutTime>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>PerformingAction</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>LAttack</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>LAttackType</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>lpunch1</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Transitions>
|
||||||
|
<m_Target>Idle</m_Target>
|
||||||
|
<m_AnimName>Bob_AimToIdle_1Hand</m_AnimName>
|
||||||
|
<m_blendInTime>0.5</m_blendInTime>
|
||||||
|
<m_blendOutTime>0.5</m_blendOutTime>
|
||||||
|
<m_speedScale>1.3</m_speedScale>
|
||||||
|
</m_Transitions>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>AttackCollisionCheck</m_EventName>
|
||||||
|
<m_TimePc>0.25</m_TimePc>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>BlockMovement</m_EventName>
|
||||||
|
<m_TimePc>0.75</m_TimePc>
|
||||||
|
<m_ParameterValue>TRUE</m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>StartAttack</m_EventName>
|
||||||
|
<m_Time>Start</m_Time>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>EndAttack</m_EventName>
|
||||||
|
<m_Time>End</m_Time>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>SetVariable</m_EventName>
|
||||||
|
<m_TimePc>0.1</m_TimePc>
|
||||||
|
<m_ParameterValue>ZombieHitReaction=HeadRight</m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Spine1</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Neck</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_BackPack</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Spine</boneName>
|
||||||
|
<includeDescendants>false</includeDescendants>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
</animNode>
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<animNode>
|
||||||
|
<m_Name>BH_LeftPunch1</m_Name>
|
||||||
|
<m_AnimName>Bob_BH_AttackPunch02_L_Hit</m_AnimName>
|
||||||
|
<m_Priority>4</m_Priority>
|
||||||
|
<m_deferredBoneAxis>Y</m_deferredBoneAxis>
|
||||||
|
<m_Looped>false</m_Looped>
|
||||||
|
<m_EarlyTransitionOut>true</m_EarlyTransitionOut>
|
||||||
|
<m_SpeedScale>LCombatSpeed</m_SpeedScale>
|
||||||
|
<m_BlendTime>0.15</m_BlendTime>
|
||||||
|
<m_BlendOutTime>0.25</m_BlendOutTime>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>PerformingAction</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>LAttack</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>LAttackType</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>lpunch2</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Transitions>
|
||||||
|
<m_Target>Idle</m_Target>
|
||||||
|
<m_AnimName>Bob_AimToIdle_1Hand</m_AnimName>
|
||||||
|
<m_blendInTime>0.5</m_blendInTime>
|
||||||
|
<m_blendOutTime>0.5</m_blendOutTime>
|
||||||
|
<m_speedScale>1.3</m_speedScale>
|
||||||
|
</m_Transitions>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>AttackCollisionCheck</m_EventName>
|
||||||
|
<m_TimePc>0.25</m_TimePc>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>BlockMovement</m_EventName>
|
||||||
|
<m_TimePc>0.75</m_TimePc>
|
||||||
|
<m_ParameterValue>TRUE</m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>StartAttack</m_EventName>
|
||||||
|
<m_Time>Start</m_Time>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>EndAttack</m_EventName>
|
||||||
|
<m_Time>End</m_Time>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>SetVariable</m_EventName>
|
||||||
|
<m_TimePc>0.1</m_TimePc>
|
||||||
|
<m_ParameterValue>ZombieHitReaction=Uppercut</m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Spine1</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Neck</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_BackPack</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Spine</boneName>
|
||||||
|
<includeDescendants>false</includeDescendants>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
</animNode>
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<animNode>
|
||||||
|
<m_Name>BH_RightPunch1</m_Name>
|
||||||
|
<m_AnimName>Bob_BH_AttackPunch01_R_Hit</m_AnimName>
|
||||||
|
<m_Priority>4</m_Priority>
|
||||||
|
<m_deferredBoneAxis>Y</m_deferredBoneAxis>
|
||||||
|
<m_Looped>false</m_Looped>
|
||||||
|
<m_EarlyTransitionOut>true</m_EarlyTransitionOut>
|
||||||
|
<m_SpeedScale>LCombatSpeed</m_SpeedScale>
|
||||||
|
<m_BlendTime>0.15</m_BlendTime>
|
||||||
|
<m_BlendOutTime>0.25</m_BlendOutTime>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>PerformingAction</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>LAttack</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>LAttackType</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>rpunch1</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Transitions>
|
||||||
|
<m_Target>Idle</m_Target>
|
||||||
|
<m_AnimName>Bob_AimToIdle_1Hand</m_AnimName>
|
||||||
|
<m_blendInTime>0.5</m_blendInTime>
|
||||||
|
<m_blendOutTime>0.5</m_blendOutTime>
|
||||||
|
<m_speedScale>1.3</m_speedScale>
|
||||||
|
</m_Transitions>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>AttackCollisionCheck</m_EventName>
|
||||||
|
<m_TimePc>0.25</m_TimePc>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>BlockMovement</m_EventName>
|
||||||
|
<m_TimePc>0.75</m_TimePc>
|
||||||
|
<m_ParameterValue>TRUE</m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>StartAttack</m_EventName>
|
||||||
|
<m_Time>Start</m_Time>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>EndAttack</m_EventName>
|
||||||
|
<m_Time>End</m_Time>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>SetVariable</m_EventName>
|
||||||
|
<m_TimePc>0.1</m_TimePc>
|
||||||
|
<m_ParameterValue>ZombieHitReaction=HeadLeft</m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Spine1</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Neck</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_BackPack</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Spine</boneName>
|
||||||
|
<includeDescendants>false</includeDescendants>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
</animNode>
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<animNode>
|
||||||
|
<m_Name>BH_RightPunch1</m_Name>
|
||||||
|
<m_AnimName>Bob_BH_AttackPunch02_R_Hit</m_AnimName>
|
||||||
|
<m_Priority>4</m_Priority>
|
||||||
|
<m_deferredBoneAxis>Y</m_deferredBoneAxis>
|
||||||
|
<m_Looped>false</m_Looped>
|
||||||
|
<m_EarlyTransitionOut>true</m_EarlyTransitionOut>
|
||||||
|
<m_SpeedScale>LCombatSpeed</m_SpeedScale>
|
||||||
|
<m_BlendTime>0.15</m_BlendTime>
|
||||||
|
<m_BlendOutTime>0.25</m_BlendOutTime>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>PerformingAction</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>LAttack</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>LAttackType</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>rpunch2</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Transitions>
|
||||||
|
<m_Target>Idle</m_Target>
|
||||||
|
<m_AnimName>Bob_AimToIdle_1Hand</m_AnimName>
|
||||||
|
<m_blendInTime>0.5</m_blendInTime>
|
||||||
|
<m_blendOutTime>0.5</m_blendOutTime>
|
||||||
|
<m_speedScale>1.3</m_speedScale>
|
||||||
|
</m_Transitions>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>AttackCollisionCheck</m_EventName>
|
||||||
|
<m_TimePc>0.25</m_TimePc>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>BlockMovement</m_EventName>
|
||||||
|
<m_TimePc>0.75</m_TimePc>
|
||||||
|
<m_ParameterValue>TRUE</m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>StartAttack</m_EventName>
|
||||||
|
<m_Time>Start</m_Time>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>EndAttack</m_EventName>
|
||||||
|
<m_Time>End</m_Time>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>SetVariable</m_EventName>
|
||||||
|
<m_TimePc>0.1</m_TimePc>
|
||||||
|
<m_ParameterValue>ZombieHitReaction=Uppercut</m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Spine1</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Neck</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_BackPack</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Spine</boneName>
|
||||||
|
<includeDescendants>false</includeDescendants>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
</animNode>
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<animNode>
|
||||||
|
<m_Name>KnifeDefaultL</m_Name>
|
||||||
|
<m_AnimName>Bob_AttackKnife01_Hit_L</m_AnimName>
|
||||||
|
<m_Priority>1</m_Priority>
|
||||||
|
<m_DeferredBoneName>Bip01</m_DeferredBoneName>
|
||||||
|
<m_deferredBoneAxis>Y</m_deferredBoneAxis>
|
||||||
|
<m_maxTorsoTwist>70.0</m_maxTorsoTwist>
|
||||||
|
<m_Looped>false</m_Looped>
|
||||||
|
<m_EarlyTransitionOut>true</m_EarlyTransitionOut>
|
||||||
|
<m_SpeedScale>LCombatSpeed</m_SpeedScale>
|
||||||
|
<m_BlendTime>0.15</m_BlendTime>
|
||||||
|
<m_BlendOutTime>0.25</m_BlendOutTime>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>PerformingAction</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>LAttack</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>LAttackType</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>knife</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Transitions>
|
||||||
|
<m_Target>Idle</m_Target>
|
||||||
|
<m_AnimName>Bob_AimToIdle_1Hand</m_AnimName>
|
||||||
|
<m_blendInTime>0.5</m_blendInTime>
|
||||||
|
<m_blendOutTime>0.5</m_blendOutTime>
|
||||||
|
<m_speedScale>1.3</m_speedScale>
|
||||||
|
</m_Transitions>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>AttackCollisionCheck</m_EventName>
|
||||||
|
<m_TimePc>0.25</m_TimePc>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>BlockMovement</m_EventName>
|
||||||
|
<m_TimePc>0.6</m_TimePc>
|
||||||
|
<m_ParameterValue>TRUE</m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>StartAttack</m_EventName>
|
||||||
|
<m_Time>Start</m_Time>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>EndAttack</m_EventName>
|
||||||
|
<m_Time>End</m_Time>
|
||||||
|
<m_ParameterValue></m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_Events>
|
||||||
|
<m_EventName>SetVariable</m_EventName>
|
||||||
|
<m_TimePc>0.1</m_TimePc>
|
||||||
|
<m_ParameterValue>ZombieHitReaction=Uppercut</m_ParameterValue>
|
||||||
|
</m_Events>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01</boneName>
|
||||||
|
<weight>0.0</weight>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Spine1</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Neck</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_BackPack</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Prop2</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Spine</boneName>
|
||||||
|
<includeDescendants>false</includeDescendants>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
</animNode>
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<animNode>
|
||||||
|
<m_Name>BHUnarmedAimMask</m_Name>
|
||||||
|
<m_AnimName>Bob_BH_UnarmedAim</m_AnimName>
|
||||||
|
<m_Priority>10</m_Priority>
|
||||||
|
<m_deferredBoneAxis>Y</m_deferredBoneAxis>
|
||||||
|
<m_SyncTrackingEnabled>false</m_SyncTrackingEnabled>
|
||||||
|
<m_SpeedScale>0.80</m_SpeedScale>
|
||||||
|
<m_BlendTime>0.20</m_BlendTime>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>RightHandMask</m_Name>
|
||||||
|
<m_Type>STRING</m_Type>
|
||||||
|
<m_StringValue>bhunarmedaim</m_StringValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>FHDoingAction</m_Name>
|
||||||
|
<m_Type>BOOL</m_Type>
|
||||||
|
<m_BoolValue>false</m_BoolValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>Aim</m_Name>
|
||||||
|
<m_Type>BOOL</m_Type>
|
||||||
|
<m_BoolValue>true</m_BoolValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_Conditions>
|
||||||
|
<m_Name>bShoveAiming</m_Name>
|
||||||
|
<m_Type>BOOL</m_Type>
|
||||||
|
<m_BoolValue>false</m_BoolValue>
|
||||||
|
</m_Conditions>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_Neck</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_R_Clavicle</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
<m_SubStateBoneWeights>
|
||||||
|
<boneName>Bip01_L_Clavicle</boneName>
|
||||||
|
</m_SubStateBoneWeights>
|
||||||
|
</animNode>
|
||||||
12731
BrutalHandwork/Contents/mods/BrutalHandwork/media/anims_X/Bob/Bob_Attack1Hand01_Hit_L.x
Executable file
12731
BrutalHandwork/Contents/mods/BrutalHandwork/media/anims_X/Bob/Bob_Attack1Hand01_Hit_L.x
Executable file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
15942
BrutalHandwork/Contents/mods/BrutalHandwork/media/anims_X/Bob/Bob_BH_UnarmedAim.x
Executable file
15942
BrutalHandwork/Contents/mods/BrutalHandwork/media/anims_X/Bob/Bob_BH_UnarmedAim.x
Executable file
File diff suppressed because it is too large
Load Diff
797
BrutalHandwork/Contents/mods/BrutalHandwork/media/lua/client/BrutalAttack.lua
Executable file
797
BrutalHandwork/Contents/mods/BrutalHandwork/media/lua/client/BrutalAttack.lua
Executable file
@@ -0,0 +1,797 @@
|
|||||||
|
-- BrutalAttack is intended to be a module that can be used by anyone
|
||||||
|
--- This is a more-or-less port of the Java functions to find and perform attacks
|
||||||
|
--- Not everything is exposed to us that is used, so some liberties were taken
|
||||||
|
local BrutalAttack = {}
|
||||||
|
|
||||||
|
-- for caching, let's reuse these
|
||||||
|
local checkValid = function(player, weapon)
|
||||||
|
return (player and instanceof(weapon, "HandWeapon"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clamp(low, n, high) return math.min(math.max(n, low), high) end
|
||||||
|
|
||||||
|
BrutalAttack.SplitValueString = function(str)
|
||||||
|
local t = {}
|
||||||
|
for k, v in string.gmatch(str, "(%w+)=(%w+)") do
|
||||||
|
t[k] = v
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
-- WARNING
|
||||||
|
---- This ONLY returns the available count, as the objects this returns are not exported for use in Lua
|
||||||
|
BrutalAttack.GetAvailableTargetCount = function(player, weapon)
|
||||||
|
local prone = ArrayList.new()
|
||||||
|
local stand = ArrayList.new()
|
||||||
|
-- we want a player, and a hand weapon
|
||||||
|
if not checkValid(player, weapon) then return end
|
||||||
|
|
||||||
|
SwipeStatePlayer.instance():calcValidTargets(player, weapon, true, prone, stand)
|
||||||
|
local pC = prone:size()
|
||||||
|
local sC = stand:size()
|
||||||
|
|
||||||
|
--prone:clear()
|
||||||
|
--stand:clear()
|
||||||
|
|
||||||
|
return pC, sC
|
||||||
|
end
|
||||||
|
|
||||||
|
local moodleOffset = {
|
||||||
|
0.5, 0.2, 0.1, 0.05
|
||||||
|
}
|
||||||
|
|
||||||
|
local weaponLevelOffset = {
|
||||||
|
0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3
|
||||||
|
}
|
||||||
|
|
||||||
|
BrutalAttack.GetWeaponLevel = function(player, weapon)
|
||||||
|
local lvl = -1
|
||||||
|
if weapon and player then
|
||||||
|
local cats = weapon:getCategories()
|
||||||
|
if cats:contains("Axe") then
|
||||||
|
lvl = lvl + player:getPerkLevel(Perks.Axe)
|
||||||
|
end
|
||||||
|
if cats:contains("Spear") then
|
||||||
|
lvl = lvl + player:getPerkLevel(Perks.Spear)
|
||||||
|
end
|
||||||
|
|
||||||
|
if cats:contains("SmallBlade") then
|
||||||
|
lvl = lvl + player:getPerkLevel(Perks.SmallBlade)
|
||||||
|
end
|
||||||
|
if cats:contains("LongBlade") then
|
||||||
|
lvl = lvl + player:getPerkLevel(Perks.LongBlade)
|
||||||
|
end
|
||||||
|
if cats:contains("Blunt") then
|
||||||
|
lvl = lvl + player:getPerkLevel(Perks.Blunt)
|
||||||
|
end
|
||||||
|
if cats:contains("SmallBlunt") then
|
||||||
|
lvl = lvl + player:getPerkLevel(Perks.SmallBlunt)
|
||||||
|
end
|
||||||
|
-- if cats:contains("Unarmed") then
|
||||||
|
-- lvl = lvl + player:getPerkLevel(Perks.Unarmed)
|
||||||
|
-- end
|
||||||
|
end
|
||||||
|
|
||||||
|
return (lvl == -1 and 0) or lvl
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Yea, you see all this here? This is the FULL damage code ported from Java to Lua, made weapon agnostic.
|
||||||
|
---- This doesn't fucking work in MP though, as there is NO method to get a zombie remotely.
|
||||||
|
---- So, I cannot accurately sync hit reactions. This causes zombies to fall for you, and walk in place for others
|
||||||
|
---- I could fix this if I could just get a zombie by its online id or something. But noooooooooooo. I can't have nice things......
|
||||||
|
-- BrutalAttack.processHitDamage = function(weapon, player, target, damage, ignoreDamage, delta)
|
||||||
|
-- local dmg = damage * delta
|
||||||
|
-- local dmg2 = (ignoreDamage and dmg/2.7) or dmg
|
||||||
|
|
||||||
|
-- local force = dmg2 * player:getShovingMod()
|
||||||
|
-- if force > 1.0 then force = 1.0 end
|
||||||
|
|
||||||
|
-- if not weapon:isRanged() then
|
||||||
|
-- force = (player:HasTrait("Strong") and force*1.4) or (player:HasTrait("Weak") and force*0.6) or force
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- local dist = 1.0 - ((target:DistTo(player) - weapon:getMinRange())/weapon:getMaxRange(player))
|
||||||
|
-- if dist > 1.0 then dist = 1.0 end
|
||||||
|
|
||||||
|
-- -- Apparently, this is supposed to be modified by knockbackAttackMod, but this always seems to be 1
|
||||||
|
-- local endurance = player:getStats():getEndurance()
|
||||||
|
-- if endurance < 0.5 then
|
||||||
|
-- endurance = endurance * 1.3
|
||||||
|
-- if endurance < 0.4 then
|
||||||
|
-- endurance = 0.4
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- force = force * endurance
|
||||||
|
|
||||||
|
|
||||||
|
-- if not weapon:isRangeFalloff() then
|
||||||
|
-- dist = 1.0
|
||||||
|
-- end
|
||||||
|
-- if not weapon:isShareDamage() then
|
||||||
|
-- damage = 1.0
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if not ignoreDamage then
|
||||||
|
-- force = force * 2.0
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if player:isDoShove() then
|
||||||
|
-- local vec = Vector2.new()
|
||||||
|
-- vec:set(target:getX() - player:getX(), target:getY() - player:getY())
|
||||||
|
-- vec:normalize()
|
||||||
|
-- local vec2 = Vector2.new()
|
||||||
|
-- vec2:set(player:getX(), player:getY())
|
||||||
|
-- vec2 = target:getVectorFromDirection(vec2)
|
||||||
|
-- local dir = vec:dot(vec2)
|
||||||
|
-- if dir > -0.3 then
|
||||||
|
-- dmg = dmg * 1.5
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- dmg = (instanceof(target, "IsoPlayer") and dmg * 0.4) or dmg * 1.5
|
||||||
|
|
||||||
|
-- dmg = dmg * (weaponLevelOffset[BrutalAttack.GetWeaponLevel(player, weapon)] or 0.3)
|
||||||
|
|
||||||
|
-- if player:isAimAtFloor() and not player:isDoShove() and not ignoreDamage then
|
||||||
|
-- dmg = dmg * (math.max(5.0, weapon:getCritDmgMultiplier()))
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if player:isCriticalHit() and not ignoreDamage then
|
||||||
|
-- dmg = dmg * math.max(2.0, weapon:getCritDmgMultiplier())
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if weapon:isTwoHandWeapon() and not player:isItemInBothHands(weapon) then
|
||||||
|
-- dmg = dmg * 0.5
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- return dmg
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- local basehitConsequences = function(weapon, player, target, ignoreDamage, damage)
|
||||||
|
-- if not ignoreDamage then
|
||||||
|
-- if weapon:isAimedFirearm() then
|
||||||
|
-- target:setHealth(target:getHealth() - damage * 0.7)
|
||||||
|
-- else
|
||||||
|
-- target:setHealth(target:getHealth() - damage * 0.15)
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if target:isDead() then
|
||||||
|
-- if target:isOnKillDone() and target:shouldDoInventory() then
|
||||||
|
-- target:Kill(player)
|
||||||
|
-- end
|
||||||
|
-- if target:isZombie() then
|
||||||
|
-- player:setZombieKills(player:getZombieKills() + 1)
|
||||||
|
-- end
|
||||||
|
-- else
|
||||||
|
-- if weapon:isSplatBloodOnNoDeath() then
|
||||||
|
-- target:splatBlood(2, 0.2)
|
||||||
|
-- end
|
||||||
|
-- if (weapon:isKnockBackOnNoDeath()) then
|
||||||
|
-- player:getXp():AddXP(Perks.Strength, 2.0)
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- local zedhitConsequences = function(weapon, player, target, ignoreDamage, damage)
|
||||||
|
-- if not target:isOnlyJawStab() or target:isCloseKilled() then
|
||||||
|
-- basehitConsequences(weapon, player, target, ignoreDamage, damage)
|
||||||
|
-- end
|
||||||
|
-- if getDebug() then
|
||||||
|
-- print("BRUTAL: Zombie #" .. tostring(target:getOnlineID()) .. " got hit for " .. tostring(damage))
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- target:reportEvent("wasHit")
|
||||||
|
-- if not ignoreDamage then
|
||||||
|
-- local react = player:getVariableString("ZombieHitReaction") or ""
|
||||||
|
-- local cats = weapon:getCategories()
|
||||||
|
-- if react == "Shot" then
|
||||||
|
-- -- Shot
|
||||||
|
-- elseif cats:contains("Blunt") or cats:contains("BHUnarmed") then
|
||||||
|
-- target:addBlood(BloodBodyPartType.FromIndex(ZombRand(BloodBodyPartType.MAX:index())), false, false, true)
|
||||||
|
-- elseif not cats:contains("Unarmed") then
|
||||||
|
-- target:addBlood(BloodBodyPartType.FromIndex(ZombRand(BloodBodyPartType.MAX:index())), false, true, true)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if react == "ShotHeadFwd" and ZombRand(2) == 0 then
|
||||||
|
-- react = "ShotHeadFwd02"
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if target:getEatBodyTarget() ~= nil then
|
||||||
|
-- if target:getVariableBoolean("onknees") then
|
||||||
|
-- react = "OnKnees"
|
||||||
|
-- else
|
||||||
|
-- react = "Eating"
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if string.lower(react) == "floor" and target:isCurrentState(ZombieGetUpState.instance()) and target:isFallOnFront() then
|
||||||
|
-- react = "GettingUpFront"
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if react ~= "" then
|
||||||
|
-- target:setHitReaction(react)
|
||||||
|
-- else
|
||||||
|
-- target:setStaggerBack(true)
|
||||||
|
-- target:setHitReaction("")
|
||||||
|
-- if target:getPlayerAttackPosition() == "LEFT" or target:getPlayerAttackPosition() == "RIGHT" then
|
||||||
|
-- player:setCriticalHit(false)
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- local tgt = target:getTarget()
|
||||||
|
-- if not tgt or tgt == player or target:DistToSquared(player) < 10.0 then
|
||||||
|
-- target:setTarget(player)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if player:isLocalPlayer() and not target:isRemoteZombie() then
|
||||||
|
-- target:setKnockedDown(player:isCriticalHit() or target:isOnFloor() or target:isAlwaysKnockedDown())
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if not target:isOnFloor() then
|
||||||
|
-- local windowFence = function(x,y)
|
||||||
|
-- local dir = target:getDir()
|
||||||
|
-- if dir == IsoDirections.W then
|
||||||
|
-- target:setX(x + 0.9)
|
||||||
|
-- target:setLx(target:getX())
|
||||||
|
-- elseif dir == IsoDirections.E then
|
||||||
|
-- target:setX(x + 0.1)
|
||||||
|
-- target:setLx(target:getX())
|
||||||
|
-- elseif dir == IsoDirections.N then
|
||||||
|
-- target:setY(y + 0.9)
|
||||||
|
-- target:setLy(target:getY())
|
||||||
|
-- elseif dir == IsoDirections.S then
|
||||||
|
-- target:setY(y + 0.1)
|
||||||
|
-- target:setLy(target:getY())
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- target:setStaggerBack(false);
|
||||||
|
-- target:setKnockedDown(true);
|
||||||
|
-- target:setOnFloor(true);
|
||||||
|
-- target:setFallOnFront(true);
|
||||||
|
-- target:setHitReaction("FenceWindow");
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if target:isCurrentState(ClimbOverFenceState.instance()) and target:getVariableBoolean("ClimbFenceStarted") and not target:isVariable("ClimbFenceOutcome", "fall") and not target:getVariableBoolean("ClimbFenceFlopped") then
|
||||||
|
-- local map = target:getStateMachineParams(ClimbOverFenceState.instance())
|
||||||
|
-- windowFence(map:get(3), map:get(4))
|
||||||
|
-- elseif target:isCurrentState(ClimbThroughWindowState.instance()) and target:getVariableBoolean("ClimbWindowStarted") and not target:isVariable("ClimbWindowOutcome", "fall") and not target:getVariableBoolean("ClimbWindowFlopped") then
|
||||||
|
-- local map = target:getStateMachineParams(ClimbThroughWindowState.instance())
|
||||||
|
-- windowFence(map:get(12), map:get(13))
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- local crawler = false
|
||||||
|
-- if target:isBecomeCrawler() then
|
||||||
|
-- crawler = true
|
||||||
|
-- elseif target:isCrawling() or BrutalAttack.isLastStand or target:isDead() or target:isCloseKilled() then
|
||||||
|
-- crawler = false
|
||||||
|
-- else
|
||||||
|
-- if not player:isAimAtFloor() and player:isDoShove() then
|
||||||
|
-- crawler = false
|
||||||
|
-- elseif player:isAimAtFloor() and player:isDoShove() then
|
||||||
|
-- crawler = (ZombRand((target:isHitLegsWhileOnFloor() and 7) or 15) % 2) == 0
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- if crawler then
|
||||||
|
-- target:setBecomeCrawler(true)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- local playerhitConsequences = function(weapon, player, target, ignoreDamage, damage)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- BrutalAttack.hitConsequences = function(weapon, player, target, ignoreDamage, damage)
|
||||||
|
-- if instanceof(target, "IsoPlayer") then
|
||||||
|
-- playerhitConsequences(weapon, player, target, ignoreDamage, damage)
|
||||||
|
-- else
|
||||||
|
-- zedhitConsequences(weapon, player, target, ignoreDamage, damage)
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- BrutalAttack.OnWeaponHitCharacter = function(player, target, weapon, damage)
|
||||||
|
-- if not instanceof(weapon, "HandWeapon") or not instanceof(player, "IsoPlayer") or not instanceof(target, "IsoGameCharacter") then return false end
|
||||||
|
-- if weapon:isRanged() then return false end -- not implemented
|
||||||
|
-- local vec2 = Vector2.new()
|
||||||
|
-- vec2:set(target:getX()-player:getX(), target:getY()-player:getY())
|
||||||
|
-- local delta = BrutalAttack.calcDelta(player, weapon, vec2)
|
||||||
|
-- BrutalAttack.weaponHitCharacter(player, target, weapon, damage, false, delta)
|
||||||
|
-- return true
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- BrutalAttack.weaponHitCharacter = function(player, target, weapon, damage, ignoreDamage ,delta)
|
||||||
|
-- if target:avoidDamage() then
|
||||||
|
-- target:setAvoidDamage(false)
|
||||||
|
-- return 0
|
||||||
|
-- end
|
||||||
|
-- local ignoreDamage = target:getNoDamage()
|
||||||
|
-- if ignoreDamage then
|
||||||
|
-- target:setNoDamage(false)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- if instanceof(target, "IsoSurvivor") then
|
||||||
|
-- local enemyList = target:getEnemyList()
|
||||||
|
-- if enemyList and not enemyList:contains(player) then
|
||||||
|
-- enemyList:add(player)
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- target:setStaggerTimeMod(weapon:getPushBackMod() * weapon:getKnockbackMod(player) * player:getShovingMod())
|
||||||
|
|
||||||
|
-- player:addWorldSoundUnlessInvisible(5, 1, false)
|
||||||
|
|
||||||
|
-- local vec2 = Vector2.new()
|
||||||
|
-- vec2:set(target:getX() - player:getX(), target:getY() - player:getY())
|
||||||
|
-- vec2:normalize()
|
||||||
|
-- vec2:set(vec2:getX() * weapon:getPushBackMod(), vec2:getY() * weapon:getPushBackMod())
|
||||||
|
-- -- Literally everything that I can find uses -30 for the HitAngleMod, including modded items. This parameter does not have a 'get', so lets just use -30
|
||||||
|
-- vec2:rotate(-30)
|
||||||
|
-- target:setHitDir(vec2)
|
||||||
|
|
||||||
|
-- target:setAttackedBy(player)
|
||||||
|
|
||||||
|
-- local finalDamage = BrutalAttack.processHitDamage(weapon, player, target, damage, ignoreDamage, delta)
|
||||||
|
-- local weight = 0
|
||||||
|
-- if weapon:isTwoHandWeapon() and player:isItemInBothHands(weapon) then
|
||||||
|
-- weight = weapon:getWeight()/0.15
|
||||||
|
-- end
|
||||||
|
-- weight = (weapon:getWeight() * 0.28 * weapon:getFatigueMod(player) * target:getFatigueMod() * weapon:getEnduranceMod() * 0.30 + weight) * 0.04
|
||||||
|
|
||||||
|
-- if instanceof(player, "IsoPlayer") and player:isAimAtFloor() and player:isDoShove() then
|
||||||
|
-- weight = weight * 2.0
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- local enduranceDmg = finalDamage * ((weapon:isAimedFirearm() and 0.7) or 0.15)
|
||||||
|
-- enduranceDmg = ((target:getHealth() < enduranceDmg and target:getHealth()) or enduranceDmg)/weapon:getMaxDamage()
|
||||||
|
-- if enduranceDmg > 1.0 then enduranceDmg = 1.0 end
|
||||||
|
-- enduranceDmg = (target:isCloseKilled() and 0.2) or enduranceDmg
|
||||||
|
|
||||||
|
-- if weapon:isUseEndurance() then
|
||||||
|
-- enduranceDmg = ((finalDamage <= 0) and 1.0) or enduranceDmg
|
||||||
|
-- player:getStats():setEndurance(player:getStats():getEndurance() - (weight * enduranceDmg))
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- --BrutalAttack.hitConsequences(weapon, player, target, ignoreDamage, finalDamage)
|
||||||
|
-- target:hitConsequences(weapon, player, ignoreDamage, finalDamage, false)
|
||||||
|
|
||||||
|
-- if target:isZombie() then
|
||||||
|
-- if not target:isRemoteZombie() then
|
||||||
|
-- target:addAggro(player, finalDamage)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- target:setTargetSeenTime(0)
|
||||||
|
-- if not target:isDead() and not target:isOnFloor() and not ignoreDamage and weapon:getScriptItem():getCategories():contains("Blade") then
|
||||||
|
-- target:setHitForce(0.5)
|
||||||
|
-- target:changeState(StaggerBackState.instance())
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- return finalDamage
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- BrutalAttack.Hit = function(weapon, player, target, damage, ignoreDamage, delta)
|
||||||
|
-- if not instanceof(weapon, "HandWeapon") or not instanceof(player, "IsoPlayer") or not instanceof(target, "IsoGameCharacter") then return end
|
||||||
|
-- if not ignoreDamage and target:isZombie() then
|
||||||
|
-- target:setHitTime(target:getHitTime()+1)
|
||||||
|
-- if target:getHitTime() >= 4 then
|
||||||
|
-- damage = damage * ((target:getHitTime()-2) * 1.50)
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- -- Set the shove damage. probably un-needed, but lets do it anyways
|
||||||
|
-- if player:isDoShove() and not player:isAimAtFloor() then
|
||||||
|
-- ignoreDamage = true
|
||||||
|
-- delta = delta * 1.5
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- triggerEvent("OnWeaponHitCharacter", player, target, weapon, damage)
|
||||||
|
-- triggerEvent("OnPlayerGetDamage", target, "WEAPONHIT", damage)
|
||||||
|
|
||||||
|
-- BrutalAttack.weaponHitCharacter(player, target, weapon, damage, ignoreDamage, delta)
|
||||||
|
|
||||||
|
-- triggerEvent("OnWeaponHitXp", player, weapon, target, damage)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
BrutalAttack.calcDelta = function(player, weapon, vec2)
|
||||||
|
local delta = 1.0
|
||||||
|
if weapon:isRangeFalloff() then
|
||||||
|
delta = 1.0
|
||||||
|
elseif weapon:isRanged() then
|
||||||
|
delta = 0.5
|
||||||
|
else
|
||||||
|
delta = vec2:getLength() / weapon:getMaxRange(player)
|
||||||
|
end
|
||||||
|
delta = delta * 2.0
|
||||||
|
if delta < 0.3 then delta = 1 end
|
||||||
|
|
||||||
|
-- I'm tired. I've written 3 methods for calculating damage, only to run into an issue.
|
||||||
|
--- So we're just going to correct it using math and the `delta` parameter
|
||||||
|
---- We must correct for the offhand weapon skill here
|
||||||
|
---- first, we divide by the primary hand's skill offset; later, this is counter-acted by the offset being multiplied
|
||||||
|
delta = delta / (weaponLevelOffset[BrutalAttack.GetWeaponLevel(player, player:getPrimaryHandItem())] or 0.3)
|
||||||
|
-- then we multiply the real skill offset
|
||||||
|
delta = delta * (weaponLevelOffset[BrutalAttack.GetWeaponLevel(player, weapon)] or 0.3)
|
||||||
|
|
||||||
|
return delta
|
||||||
|
end
|
||||||
|
|
||||||
|
BrutalAttack.calcDamage = function(player, weapon, target, count)
|
||||||
|
local vec2 = Vector2.new()
|
||||||
|
vec2:set(target:getX()-player:getX(), target:getY()-player:getY())
|
||||||
|
local delta = BrutalAttack.calcDelta(player, weapon, vec2)
|
||||||
|
|
||||||
|
local minDamage = weapon:getMinDamage() -- var50
|
||||||
|
local maxDamage = weapon:getMaxDamage() -- var28
|
||||||
|
local deltaDamage = maxDamage - minDamage -- var52
|
||||||
|
local twoHand = not weapon:isTwoHandWeapon() or player:isItemInBothHands(weapon) -- var54
|
||||||
|
|
||||||
|
local initDamage = 0 -- var51
|
||||||
|
if deltaDamage == 0.0 then
|
||||||
|
initDamage = minDamage
|
||||||
|
else
|
||||||
|
initDamage = minDamage + (ZombRand(maxDamage*1000.0)/1000.0)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not weapon:isRanged() then
|
||||||
|
initDamage = initDamage * weapon:getDamageMod(player) * player:getHittingMod()
|
||||||
|
if not twoHand and maxDamage > minDamage then
|
||||||
|
initDamage = initDamage - minDamage
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- local damage = 0 --var34
|
||||||
|
-- local forward = target:getForwardDirection()
|
||||||
|
-- vec2:normalize()
|
||||||
|
-- forward:normalize()
|
||||||
|
-- damage = vec2.dot(forward)
|
||||||
|
-- local fromBehind = damage > 0.50
|
||||||
|
|
||||||
|
local damage = 0
|
||||||
|
for i=0,BodyPartType.ToIndex(BodyPartType.MAX) - 1 do
|
||||||
|
damage = damage + player:getBodyDamage():getBodyParts():get(i):getPain()
|
||||||
|
end
|
||||||
|
if damage > 10.0 then
|
||||||
|
initDamage = initDamage/clamp(damage/10.0, 1.0, 30.0)
|
||||||
|
end
|
||||||
|
|
||||||
|
if player:HasTrait("Underweight") then
|
||||||
|
initDamage = initDamage * 0.8
|
||||||
|
end
|
||||||
|
|
||||||
|
if player:HasTrait("VeryUnderweight") then
|
||||||
|
initDamage = initDamage * 0.6
|
||||||
|
end
|
||||||
|
|
||||||
|
if player:HasTrait("Emaciated") then
|
||||||
|
initDamage = initDamage * 0.4
|
||||||
|
end
|
||||||
|
|
||||||
|
-- this way, the other items hit get less damage, i get it
|
||||||
|
damage = initDamage/(count/2.0)
|
||||||
|
|
||||||
|
if player:isAttackWasSuperAttack() then
|
||||||
|
damage = damage * 5.0
|
||||||
|
end
|
||||||
|
|
||||||
|
if weapon:isRanged() and player:getPerkLevel(Perks.Aiming) < 6 and player:getMoodles():getMoodleLevel(MoodleType.Panic) > 2 then
|
||||||
|
damage = damage - (player:getMoodles():getMoodleLevel(MoodleType.Panic) * 0.2)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not weapon:isRanged() and player:getMoodles():getMoodleLevel(MoodleType.Panic) > 1 then
|
||||||
|
damage = damage - (player:getMoodles():getMoodleLevel(MoodleType.Panic) * 0.1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if player:getMoodles():getMoodleLevel(MoodleType.Stress) > 1 then
|
||||||
|
damage = damage - (player:getMoodles():getMoodleLevel(MoodleType.Stress) * 0.1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if damage < 0 then damage = 0.1 end
|
||||||
|
|
||||||
|
if not weapon:isRanged() then
|
||||||
|
damage = damage * (moodleOffset[player:getMoodles():getMoodleLevel(MoodleType.Endurance)] or 1.0)
|
||||||
|
damage = damage * (moodleOffset[player:getMoodles():getMoodleLevel(MoodleType.Tired)] or 1.0)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- local part = ZombRand(BodyPartType.ToIndex(BodyPartType.Hand_L), BodyPartType.ToIndex(BodyPartType.Neck) + 1)
|
||||||
|
-- local def = target:getBodyPartClothingDefense(part, false, weapon:isRanged())/2.0
|
||||||
|
-- def = def + target:getBodyPartClothingDefense(part, true, weapon:isRanged())
|
||||||
|
-- if def > 70.0 then def = 70.0 end
|
||||||
|
-- damage = damage * math.abs(1.0-def/100.0)
|
||||||
|
|
||||||
|
-- triggerEvent("OnHitZombie", target, player, part, weapon)
|
||||||
|
|
||||||
|
return damage, delta
|
||||||
|
end
|
||||||
|
|
||||||
|
local addToHitList = function(list, obj, player, weapon, extraRange, vec)
|
||||||
|
if obj and obj:isZombie() and obj:isAlive() then
|
||||||
|
obj:getPosition(vec)
|
||||||
|
if player:IsAttackRange(weapon, obj, vec, extraRange) then
|
||||||
|
-- Add our zed, cache the distance to the player
|
||||||
|
list[#list+1] = { obj = obj, dist = obj:DistTo(player) }
|
||||||
|
if isDebugEnabled() then
|
||||||
|
print("Found: " .. tostring(#list) .. " | Distance: " .. tostring(list[#list].dist))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local directions = {
|
||||||
|
[0] = IsoDirections.N,
|
||||||
|
[1] = IsoDirections.NW,
|
||||||
|
[2] = IsoDirections.W,
|
||||||
|
[3] = IsoDirections.SW,
|
||||||
|
[4] = IsoDirections.S,
|
||||||
|
[5] = IsoDirections.SE,
|
||||||
|
[6] = IsoDirections.E,
|
||||||
|
[7] = IsoDirections.NE,
|
||||||
|
}
|
||||||
|
|
||||||
|
local getAttackSquares = function(player)
|
||||||
|
local psquare = player:getSquare()
|
||||||
|
if not psquare then return nil end
|
||||||
|
local squares = {psquare}
|
||||||
|
local currentDir = player:getDir():index()
|
||||||
|
local leftIndex = currentDir+1
|
||||||
|
if leftIndex > 7 then leftIndex=0 end
|
||||||
|
--local middleIndex = currentDir
|
||||||
|
local rightIndex = currentDir-1
|
||||||
|
if rightIndex < 0 then rightIndex=7 end
|
||||||
|
-- this should collect any additional squares, only if we nothing is in the way
|
||||||
|
local sq = psquare:getAdjacentSquare(directions[leftIndex])
|
||||||
|
if sq and not sq:isBlockedTo(psquare) then
|
||||||
|
squares[#squares+1] = sq
|
||||||
|
end
|
||||||
|
sq = psquare:getAdjacentSquare(directions[currentDir])
|
||||||
|
if sq and not sq:isBlockedTo(psquare) then
|
||||||
|
squares[#squares+1] = sq
|
||||||
|
end
|
||||||
|
sq = psquare:getAdjacentSquare(directions[rightIndex])
|
||||||
|
if sq and not sq:isBlockedTo(psquare) then
|
||||||
|
squares[#squares+1] = sq
|
||||||
|
end
|
||||||
|
return squares
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Finds and performs the attack on players in weapon range
|
||||||
|
BrutalAttack.FindAndAttackTargets = function(player, weapon, extraRange)
|
||||||
|
-- we want a player, and a hand weapon
|
||||||
|
if not checkValid(player, weapon) then return end
|
||||||
|
|
||||||
|
-- honor the max hit
|
||||||
|
local maxHit = (SandboxVars.MultiHitZombies and weapon:getMaxHitCount()) or 1
|
||||||
|
|
||||||
|
-- this seems to be the default sooooooooo
|
||||||
|
if extraRange == nil then extraRange = true end
|
||||||
|
|
||||||
|
-- We do everything so we can attack non-zeds too
|
||||||
|
--local objs = getCell():getObjectList()
|
||||||
|
local found = {}
|
||||||
|
local psquare = player:getSquare()
|
||||||
|
if not psquare then return end -- can't attack
|
||||||
|
local attackSquares = getAttackSquares(player)
|
||||||
|
if not attackSquares then return end -- no squares?
|
||||||
|
local vec = Vector3.new() -- reuse this
|
||||||
|
for i=1, #attackSquares do
|
||||||
|
local objs = attackSquares[i]:getMovingObjects()
|
||||||
|
if objs then
|
||||||
|
for j=0, objs:size()-1 do
|
||||||
|
addToHitList(found, objs:get(j), player, weapon, extraRange, vec)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if #found > 0 then
|
||||||
|
-- sort our found list by the closest zed
|
||||||
|
table.sort(found, function(a,b)
|
||||||
|
if a.obj:isZombie() then return true end
|
||||||
|
if b.obj:isZombie() then return false end
|
||||||
|
return a.dist < b.dist
|
||||||
|
end)
|
||||||
|
local count = 1
|
||||||
|
local sound = false
|
||||||
|
for _,v in ipairs(found) do
|
||||||
|
-- hit em!
|
||||||
|
local damage, dmgDelta = BrutalAttack.calcDamage(player, weapon, v.obj, count)
|
||||||
|
if isDebugEnabled() then
|
||||||
|
print("Damage: " .. tostring(damage) .. " | Delta: " .. tostring(dmgDelta))
|
||||||
|
end
|
||||||
|
v.obj:Hit(weapon, player, damage, false, dmgDelta)
|
||||||
|
|
||||||
|
--v.zed:splatBloodFloor()
|
||||||
|
if not sound then
|
||||||
|
-- if we haven't played the sound yet, do so
|
||||||
|
sound = true
|
||||||
|
local zSound = weapon:getZombieHitSound()
|
||||||
|
if zSound then v.obj:playSound(zSound) end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- stop at maxhit
|
||||||
|
if count >= maxHit then break end
|
||||||
|
count = count + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
luautils.weaponLowerCondition(weapon, player)
|
||||||
|
else
|
||||||
|
-- Swing and collide with anything not a zed
|
||||||
|
SwipeStatePlayer.instance():ConnectSwing(player, weapon)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
BrutalAttack.CalcCombatSpeed = function(player, weapon, right)
|
||||||
|
|
||||||
|
-- we want a player, and a hand weapon
|
||||||
|
if not checkValid(player, weapon) then return nil end
|
||||||
|
local speed = weapon:getBaseSpeed()
|
||||||
|
|
||||||
|
local other
|
||||||
|
if right then
|
||||||
|
other = player:getSecondaryHandItem()
|
||||||
|
else
|
||||||
|
other = player:getPrimaryHandItem()
|
||||||
|
end
|
||||||
|
|
||||||
|
if weapon:isTwoHandWeapon() and weapon ~= other then
|
||||||
|
speed = speed * 0.77
|
||||||
|
end
|
||||||
|
|
||||||
|
if player:HasTrait("Axeman") and weapon:getCategories():contains("Axe") then
|
||||||
|
speed = speed * player:getChopTreeSpeed()
|
||||||
|
end
|
||||||
|
|
||||||
|
speed = speed - (player:getMoodles():getMoodleLevel(MoodleType.Endurance) * 0.07)
|
||||||
|
speed = speed - (player:getMoodles():getMoodleLevel(MoodleType.HeavyLoad) * 0.07)
|
||||||
|
speed = speed + (player:getWeaponLevel() * 0.03)
|
||||||
|
speed = speed + (player:getPerkLevel(Perks.Fitness) * 0.02)
|
||||||
|
|
||||||
|
if instanceof(other, "InventoryContainer") then
|
||||||
|
speed = speed * 0.95
|
||||||
|
end
|
||||||
|
|
||||||
|
local md = player:getModData()
|
||||||
|
-- our calculation is still just a bit too fast. So lets actually reduce it a bit instead of increasing:
|
||||||
|
speed = speed * ZombRandFloat(1.1, 1.2)
|
||||||
|
speed = speed * ((md.BrutalHandwork and md.BrutalHandwork.CombatSpeed) or 1)
|
||||||
|
speed = speed * BrutalAttack.getArmsInjurySpeedModifier(player, right)
|
||||||
|
|
||||||
|
if player:getBodyDamage() and player:getBodyDamage():getThermoregulator() then
|
||||||
|
speed = speed * player:getBodyDamage():getThermoregulator():getCombatModifier()
|
||||||
|
end
|
||||||
|
|
||||||
|
speed = math.min(1.6, speed)
|
||||||
|
speed = math.max(0.8, speed)
|
||||||
|
|
||||||
|
speed = speed * GameTime.getAnimSpeedFix()
|
||||||
|
|
||||||
|
return speed
|
||||||
|
end
|
||||||
|
|
||||||
|
BrutalAttack.calcInjurySpeed = function(part, pain)
|
||||||
|
if part:haveBullet() then return 1.0 end
|
||||||
|
|
||||||
|
local scratch = part:getScratchSpeedModifier()
|
||||||
|
local cut = part:getCutSpeedModifier()
|
||||||
|
local burn = part:getBurnSpeedModifier()
|
||||||
|
local wound = part:getDeepWoundSpeedModifier()
|
||||||
|
local temp = 0.0
|
||||||
|
|
||||||
|
if part:getScratchTime() > 2.0 or part:getCutTime() > 5.0 or part:getBurnTime() > 0
|
||||||
|
or part:getDeepWoundTime() > 0 or part:isSplint() or part:getFractureTime() > 0
|
||||||
|
or part:getBiteTime() > 0 then
|
||||||
|
temp = (part:getScratchTime()/scratch) + (part:getCutTime()/cut) + (part:getBurnTime()/burn) + (part:getDeepWoundTime()/wound)
|
||||||
|
temp = temp + (part:getBiteTime()/20.0)
|
||||||
|
if part:bandaged() then
|
||||||
|
temp = temp/2.0
|
||||||
|
end
|
||||||
|
if part:getFractureTime() > 0 then
|
||||||
|
local frac = 0.4
|
||||||
|
if part:getFractureTime() > 20 then
|
||||||
|
frac = 1.0
|
||||||
|
elseif part:getFractureTime() > 10 then
|
||||||
|
frac = 0.7
|
||||||
|
end
|
||||||
|
if part:getSplintFactor() > 0 then
|
||||||
|
frac = frac - 0.2
|
||||||
|
frac = frac - math.min(part:getSplintFactor()/10.0, 0.8)
|
||||||
|
end
|
||||||
|
temp = math.max(0, frac)
|
||||||
|
end
|
||||||
|
|
||||||
|
if pain and part:getPain() > 20 then
|
||||||
|
temp = temp + (part:getPain()/10.0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return temp
|
||||||
|
end
|
||||||
|
|
||||||
|
BrutalAttack.getArmsInjurySpeedModifier = function(player, right)
|
||||||
|
local out = 1.0
|
||||||
|
local temp = 0.0
|
||||||
|
local part
|
||||||
|
if right then
|
||||||
|
part = player:getBodyDamage():getBodyPart(BodyPartType.Hand_R)
|
||||||
|
temp = BrutalAttack.calcInjurySpeed(part, true)
|
||||||
|
if temp > 0 then
|
||||||
|
out = out - temp
|
||||||
|
end
|
||||||
|
|
||||||
|
part = player:getBodyDamage():getBodyPart(BodyPartType.ForeArm_R)
|
||||||
|
temp = BrutalAttack.calcInjurySpeed(part, true)
|
||||||
|
if temp > 0 then
|
||||||
|
out = out - temp
|
||||||
|
end
|
||||||
|
|
||||||
|
part = player:getBodyDamage():getBodyPart(BodyPartType.UpperArm_R)
|
||||||
|
temp = BrutalAttack.calcInjurySpeed(part, true)
|
||||||
|
if temp > 0 then
|
||||||
|
out = out - temp
|
||||||
|
end
|
||||||
|
else
|
||||||
|
part = player:getBodyDamage():getBodyPart(BodyPartType.Hand_L)
|
||||||
|
temp = BrutalAttack.calcInjurySpeed(part, true)
|
||||||
|
if temp > 0 then
|
||||||
|
out = out - temp
|
||||||
|
end
|
||||||
|
|
||||||
|
part = player:getBodyDamage():getBodyPart(BodyPartType.ForeArm_L)
|
||||||
|
temp = BrutalAttack.calcInjurySpeed(part, true)
|
||||||
|
if temp > 0 then
|
||||||
|
out = out - temp
|
||||||
|
end
|
||||||
|
|
||||||
|
part = player:getBodyDamage():getBodyPart(BodyPartType.UpperArm_L)
|
||||||
|
temp = BrutalAttack.calcInjurySpeed(part, true)
|
||||||
|
if temp > 0 then
|
||||||
|
out = out - temp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
local onPlayerUpdateClothes = function(player)
|
||||||
|
-- recalc attack speeds
|
||||||
|
local speed = 1.0
|
||||||
|
local items = player:getWornItems()
|
||||||
|
for i=0, items:size()-1 do
|
||||||
|
local item = items:get(i):getItem()
|
||||||
|
if instanceof(item, "Clothing") then
|
||||||
|
speed = speed + item:getCombatSpeedModifier() - 1.0
|
||||||
|
end
|
||||||
|
-- if instanceof(item, "InventoryContainer") then
|
||||||
|
-- speed = speed + ((item:getActualWeight()/100.0) + 0.1) - 1.0
|
||||||
|
-- end
|
||||||
|
end
|
||||||
|
player:getModData().BrutalHandwork = player:getModData().BrutalHandwork or {}
|
||||||
|
player:getModData().BrutalHandwork.CombatSpeed = speed
|
||||||
|
end
|
||||||
|
|
||||||
|
local onPlayerCreate = function(player)
|
||||||
|
local character = getSpecificPlayer(player)
|
||||||
|
-- i know this is preserved, but i want to reset it
|
||||||
|
character:getModData().BrutalHandwork = {
|
||||||
|
wasShove = false,
|
||||||
|
leftAttack = false,
|
||||||
|
|
||||||
|
combo = 1,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local setup = function()
|
||||||
|
Events.OnCreatePlayer.Add(onPlayerCreate)
|
||||||
|
Events.OnClothingUpdated.Add(onPlayerUpdateClothes)
|
||||||
|
|
||||||
|
BrutalAttack.BareHands = InventoryItemFactory.CreateItem("Base.Fisticuffs")
|
||||||
|
--BrutalAttack.BareHands = InventoryItemFactory.CreateItem("Base.BareHands")
|
||||||
|
--BrutalAttack.isLastStand = getCore():getGameMode()=="LastStand"
|
||||||
|
end
|
||||||
|
|
||||||
|
BrutalAttack.setupGameEvents = function()
|
||||||
|
Events.OnGameBoot.Remove(setup)
|
||||||
|
Events.OnGameBoot.Add(setup)
|
||||||
|
end
|
||||||
|
|
||||||
|
return BrutalAttack
|
||||||
41
BrutalHandwork/Contents/mods/BrutalHandwork/media/lua/client/TOC_Compat.lua
Executable file
41
BrutalHandwork/Contents/mods/BrutalHandwork/media/lua/client/TOC_Compat.lua
Executable file
@@ -0,0 +1,41 @@
|
|||||||
|
-- Compatibility for The Only Cure
|
||||||
|
local TOC_Compat = {}
|
||||||
|
|
||||||
|
-- Raw access, must pass valid part
|
||||||
|
--- @param player
|
||||||
|
--- @param part string
|
||||||
|
--- @return boolean
|
||||||
|
TOC_Compat.hasArmPart = function(player, part)
|
||||||
|
if not player or not part then return false end
|
||||||
|
local data = (player:getModData().TOC and player:getModData().TOC.Limbs) or nil
|
||||||
|
if not data then return false end
|
||||||
|
return not data[part] or (data[part].is_cut and data[part].is_prosthesis_equipped) or not data[part].is_cut
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if hand is available
|
||||||
|
--- @param player
|
||||||
|
--- @param left boolean -- optional
|
||||||
|
--- @return boolean
|
||||||
|
TOC_Compat.hasHand = function(player, left)
|
||||||
|
return TOC_Compat.hasArmPart(player, ((left and "Left_Hand") or "Right_Hand"))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if both hands are available
|
||||||
|
--- @param player
|
||||||
|
--- @return boolean
|
||||||
|
TOC_Compat.hasBothHands = function(player)
|
||||||
|
return TOC_Compat.hasHand(player) and TOC_Compat.hasHand(player, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This returns a number for the hands that you have
|
||||||
|
----- 11 == both hands
|
||||||
|
----- 10 == left hand
|
||||||
|
----- 01 (1) == right hand
|
||||||
|
----- 00 (0) == no hands
|
||||||
|
--- @param player
|
||||||
|
--- @return integer
|
||||||
|
TOC_Compat.getHands = function(player)
|
||||||
|
return ((TOC_Compat.hasHand(player) and 1) or 0) + ((TOC_Compat.hasHand(player, true) and 10) or 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
return TOC_Compat
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
require "TimedActions/ISBaseTimedAction"
|
||||||
|
|
||||||
|
BHMeleeAttack = ISBaseTimedAction:derive("BHMeleeAttack");
|
||||||
|
|
||||||
|
local BrutalAttack = require("BrutalAttack")
|
||||||
|
BrutalHands = BrutalHands or {}
|
||||||
|
|
||||||
|
function BHMeleeAttack:isValid()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function BHMeleeAttack:waitToStart()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function BHMeleeAttack:update()
|
||||||
|
-- we need to force the current facing direction until the animation starts
|
||||||
|
if self.lockDir then
|
||||||
|
self.character:setDirectionAngle(self.vec)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- safeguard to make sure that the action is ended
|
||||||
|
function BHMeleeAttack:beDone()
|
||||||
|
self.character:setVariable("AttackAnim", false)
|
||||||
|
self.character:setBlockMovement(false)
|
||||||
|
self.character:setMeleeDelay(8)
|
||||||
|
end
|
||||||
|
|
||||||
|
function BHMeleeAttack:start()
|
||||||
|
local prone, stand = BrutalAttack.GetAvailableTargetCount(self.character, self.weapon)
|
||||||
|
if stand == 0 and prone > 0 then
|
||||||
|
self:forceStop()
|
||||||
|
-- Fall through to doing the character stomp or main attack
|
||||||
|
self.character:DoAttack(self.chargeDelta)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local atype = "bash"
|
||||||
|
if self.unarmed then
|
||||||
|
local hands = (BrutalHands.TOC and BrutalHands.TOC.getHands(self.character)) or 11
|
||||||
|
local rand = 4
|
||||||
|
local randoff = 1
|
||||||
|
if hands == 00 then
|
||||||
|
self:forceStop()
|
||||||
|
-- Fall through to doing the character stomp or push
|
||||||
|
return self.character:DoAttack(self.chargeDelta)
|
||||||
|
elseif hands == 01 then -- right only
|
||||||
|
rand = 2
|
||||||
|
elseif hands == 10 then -- left only
|
||||||
|
randoff = 3
|
||||||
|
end
|
||||||
|
local num = ZombRand(rand)+randoff
|
||||||
|
if num==1 then
|
||||||
|
atype = "rpunch1"
|
||||||
|
elseif num==2 then
|
||||||
|
atype = "rpunch2"
|
||||||
|
elseif num==3 then
|
||||||
|
atype = "lpunch2"
|
||||||
|
else
|
||||||
|
atype = "lpunch1"
|
||||||
|
end
|
||||||
|
--atype = (ZombRand(3) == 1 and "lpunch1") or "rpunch1"
|
||||||
|
elseif self.weapon:getSubCategory() == "Stab" then
|
||||||
|
self.maxHit = 1
|
||||||
|
atype = "knife"
|
||||||
|
end
|
||||||
|
|
||||||
|
self.character:setVariable("LCombatSpeed", self.speed)
|
||||||
|
self.character:setVariable("AttackAnim", true)
|
||||||
|
self:setActionAnim("LAttack")
|
||||||
|
self:setAnimVariable("LAttackType", atype)
|
||||||
|
end
|
||||||
|
|
||||||
|
function BHMeleeAttack:animEvent(event, parameter)
|
||||||
|
if event == 'StartAttack' then
|
||||||
|
if self.swingSound then
|
||||||
|
self.character:getEmitter():playSound(self.swingSound)
|
||||||
|
end
|
||||||
|
self.lockDir = false
|
||||||
|
elseif event == 'SetVariable' then
|
||||||
|
local str = BrutalAttack.SplitValueString(parameter)
|
||||||
|
for k,v in pairs(str) do
|
||||||
|
self.character:setVariable(k,v)
|
||||||
|
end
|
||||||
|
elseif event == 'AttackCollisionCheck' then
|
||||||
|
BrutalAttack.FindAndAttackTargets(self.character, self.weapon, true)
|
||||||
|
if isClient() then
|
||||||
|
sendClientCommand(self.character, "BrutalAttack", "Attack", {PID=self.character:getPlayerNum(), Offhand=true, extraRange=true})
|
||||||
|
end
|
||||||
|
elseif event == 'BlockMovement' and SandboxVars.AttackBlockMovements then
|
||||||
|
self.character:setBlockMovement((parameter == "TRUE" and true) or false)
|
||||||
|
elseif event == 'EndAttack' then
|
||||||
|
self:forceComplete()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function BHMeleeAttack:stop()
|
||||||
|
self:beDone()
|
||||||
|
ISBaseTimedAction.stop(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
function BHMeleeAttack:perform()
|
||||||
|
self:beDone()
|
||||||
|
-- needed to remove from queue / start next.
|
||||||
|
ISBaseTimedAction.perform(self)
|
||||||
|
triggerEvent("OnPlayerAttackFinished", self.character, self.weapon)
|
||||||
|
end
|
||||||
|
|
||||||
|
function BHMeleeAttack:new(character, weapon, chargeDelta)
|
||||||
|
local o = ISBaseTimedAction.new(self, character)
|
||||||
|
|
||||||
|
o.weapon = weapon
|
||||||
|
o.speed = BrutalAttack.CalcCombatSpeed(character, weapon, false)
|
||||||
|
o.maxTime = -1
|
||||||
|
o.stopOnAim = false
|
||||||
|
o.stopOnWalk = false
|
||||||
|
o.stopOnRun = false
|
||||||
|
|
||||||
|
o.useProgressBar = false
|
||||||
|
|
||||||
|
o.swingSound = weapon:getSwingSound()
|
||||||
|
o.hitSound = weapon:getZombieHitSound()
|
||||||
|
|
||||||
|
o.vec = character:getDirectionAngle()
|
||||||
|
-- Needed if we fall through
|
||||||
|
o.chargeDelta = chargeDelta
|
||||||
|
o.lockDir = true
|
||||||
|
o.lHandAttack = true
|
||||||
|
|
||||||
|
o.unarmed = weapon and weapon:getCategories():contains("Unarmed")
|
||||||
|
|
||||||
|
return o
|
||||||
|
end
|
||||||
220
BrutalHandwork/Contents/mods/BrutalHandwork/media/lua/client/zBrutalHandwork.lua
Executable file
220
BrutalHandwork/Contents/mods/BrutalHandwork/media/lua/client/zBrutalHandwork.lua
Executable file
@@ -0,0 +1,220 @@
|
|||||||
|
------------------------------------------
|
||||||
|
-- Brutal Handwork Init
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
BrutalHands = BrutalHands or {}
|
||||||
|
|
||||||
|
------------------------------------------
|
||||||
|
-- Brutal Handwork Configuration
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
BrutalHands.config = {}
|
||||||
|
|
||||||
|
local BrutalAttack = require("BrutalAttack")
|
||||||
|
BrutalAttack.setupGameEvents()
|
||||||
|
|
||||||
|
BrutalHands.TOC = nil
|
||||||
|
if getActivatedMods():contains("Amputation2") then
|
||||||
|
BrutalHands.TOC = require('TOC_Compat')
|
||||||
|
end
|
||||||
|
|
||||||
|
------------------------------------------
|
||||||
|
-- Brutal Handwork Utilities
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
local function BrutalHandwork()
|
||||||
|
print(getText("UI_Init_BrutalHandwork"))
|
||||||
|
end
|
||||||
|
|
||||||
|
BrutalHandwork()
|
||||||
|
|
||||||
|
local mouseDown = false
|
||||||
|
|
||||||
|
local attackHook = function(character, chargeDelta, primary)
|
||||||
|
if not instanceof(character, "IsoPlayer") or character:isAttackStarted() or not character:isAuthorizeMeleeAction() then return end
|
||||||
|
|
||||||
|
-- Here we check if the primary weapon is actually a weapon
|
||||||
|
primary = (instanceof(primary, "HandWeapon") and primary) or nil
|
||||||
|
|
||||||
|
-- Get the secondary weapon, do the same check
|
||||||
|
local secondary = character:getSecondaryHandItem()
|
||||||
|
secondary = (instanceof(secondary, "HandWeapon") and secondary) or nil
|
||||||
|
|
||||||
|
-- check if we can actually use that arm, if applicable
|
||||||
|
---- set our weapons to nil if we don't have that arm
|
||||||
|
--local hasRArm = true
|
||||||
|
if BrutalHands.TOC then
|
||||||
|
primary = (BrutalHands.TOC.hasHand(character, false) and primary) or nil
|
||||||
|
secondary = (BrutalHands.TOC.hasHand(character, true) and secondary) or nil
|
||||||
|
--hasRArm = BrutalHands.TOC.hasHand(character, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- get our mod data
|
||||||
|
local brutal = character:getModData().BrutalHandwork
|
||||||
|
|
||||||
|
-- get our ModKey
|
||||||
|
local mk = isFHModBindDown(character)
|
||||||
|
|
||||||
|
-- if we are always ready to punch, or the modkey is down.
|
||||||
|
if (SandboxVars.BrutalHandwork.AlwaysUnarmed or mk) then
|
||||||
|
-- we have nothing
|
||||||
|
if not primary and not secondary then
|
||||||
|
-- make our secondary hand the item so it doesn't trip the main attack
|
||||||
|
secondary = BrutalAttack.BareHands
|
||||||
|
elseif primary and twoH and primary:getCategories():contains("Unarmed") then
|
||||||
|
-- if we have an unarmed weapon equipped, then we use our custom attack; secondary will still be our weapon
|
||||||
|
primary = nil
|
||||||
|
-- This isn't really implemented yet
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if its 2 handed
|
||||||
|
local twoH = primary and (primary == secondary)
|
||||||
|
|
||||||
|
-- If we made it here and there's still nothing equipped, then just push
|
||||||
|
---- This seems to set our push to start next update loop, otherwise we get a weird epic attack that is a push but it does like 100+ damage
|
||||||
|
if not primary and not secondary then
|
||||||
|
character:setInitiateAttack(false)
|
||||||
|
character:setDoShove(true)
|
||||||
|
brutal.wasShove = true
|
||||||
|
brutal.leftAttack = false
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- we could break our weapon, or just unequip it while the thing is going. bail if so
|
||||||
|
if not secondary then
|
||||||
|
brutal.leftAttack = false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- override our modkey with left attack setting
|
||||||
|
mk = secondary and not twoH and (brutal.leftAttack or mk)
|
||||||
|
|
||||||
|
local did = false
|
||||||
|
|
||||||
|
-- if no modkey or shoving, and we have a primary
|
||||||
|
if not mk and primary then
|
||||||
|
-- fall through
|
||||||
|
ISReloadWeaponAction.attackHook(character, chargeDelta, primary or 1)
|
||||||
|
did = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if not did and secondary then
|
||||||
|
ISTimedActionQueue.clear(character)
|
||||||
|
|
||||||
|
if secondary:isRanged() then
|
||||||
|
character:setDoShove(true)
|
||||||
|
return
|
||||||
|
-- Coming soon!
|
||||||
|
-- if ISReloadWeaponAction.canShoot(secondary) then
|
||||||
|
-- character:playSound(secondary:getSwingSound());
|
||||||
|
-- local radius = secondary:getSoundRadius();
|
||||||
|
-- if isClient() then -- limit sound radius in MP
|
||||||
|
-- radius = radius / 1.8;
|
||||||
|
-- end
|
||||||
|
-- character:addWorldSoundUnlessInvisible(radius, secondary:getSoundVolume(), false);
|
||||||
|
-- character:startMuzzleFlash()
|
||||||
|
-- character:DoAttack(0);
|
||||||
|
-- else
|
||||||
|
-- character:DoAttack(0);
|
||||||
|
-- character:setRangedWeaponEmpty(true);
|
||||||
|
-- end
|
||||||
|
-- nerf so players in vehicles cannot use melee attacks
|
||||||
|
elseif not character:getVehicle() then
|
||||||
|
ISTimedActionQueue.add(BHMeleeAttack:new(character, secondary, chargeDelta or 0))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- if we have a left and right weapon, and its not 2handed, and we have the option to automelee enabled
|
||||||
|
if primary and secondary and not twoH and SandboxVars.BrutalHandwork.DualWieldMelee then
|
||||||
|
brutal.leftAttack = not (brutal.wasShove or brutal.leftAttack)
|
||||||
|
else
|
||||||
|
brutal.leftAttack = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Removed the default attack hook
|
||||||
|
Hook.Attack.Remove(ISReloadWeaponAction.attackHook)
|
||||||
|
Hook.Attack.Add(attackHook)
|
||||||
|
|
||||||
|
-- We are going to override this function so that doing a left hand attack cannot be canceled :)
|
||||||
|
local _isPlayerDoingActionThatCanBeCancelled = isPlayerDoingActionThatCanBeCancelled
|
||||||
|
function isPlayerDoingActionThatCanBeCancelled(playerObj)
|
||||||
|
if not playerObj then return false end
|
||||||
|
local queue = ISTimedActionQueue.queues[playerObj]
|
||||||
|
if queue and #queue.queue > 0 and queue.queue[1].lHandAttack then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return _isPlayerDoingActionThatCanBeCancelled(playerObj)
|
||||||
|
end
|
||||||
|
|
||||||
|
local forceAttack = function(character)
|
||||||
|
character:setDoShove(false)
|
||||||
|
attackHook(character, character:getPrimaryHandItem(), 1.0)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local checkDoAttack = function(character)
|
||||||
|
if not character or not character:isAiming() or character:getMeleeDelay() > 0.0 then return false end
|
||||||
|
local queue = ISTimedActionQueue.queues[character]
|
||||||
|
if queue and #queue.queue > 0 and queue.queue[1].lHandAttack then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local hands = (BrutalHands.TOC and BrutalHands.TOC.getHands(character)) or 11
|
||||||
|
local primary = character:getPrimaryHandItem()
|
||||||
|
primary = (instanceof(primary, "HandWeapon") and primary) or nil
|
||||||
|
local secondary = character:getSecondaryHandItem()
|
||||||
|
secondary = (instanceof(secondary, "HandWeapon") and secondary) or nil
|
||||||
|
-- just do nothing here
|
||||||
|
if not primary and not secondary and not (SandboxVars.BrutalHandwork.EnableUnarmed and (SandboxVars.BrutalHandwork.AlwaysUnarmed or isFHModBindDown(character))) then return false end
|
||||||
|
if hands == 1 then
|
||||||
|
-- if we only have the right hand, then the attackHook will handle everything
|
||||||
|
--if not instanceof(primary, "HandWeapon") then return forceAttack(character) end
|
||||||
|
return false -- we'll still do the base attack, so just ignore
|
||||||
|
elseif hands == 11 then
|
||||||
|
-- if we have a primary weapon, then the attackHook will do the thing
|
||||||
|
if primary then return false end
|
||||||
|
-- otherwise, manually attack
|
||||||
|
return forceAttack(character)
|
||||||
|
elseif hands == 10 then
|
||||||
|
-- just our left, do the attack
|
||||||
|
return forceAttack(character)
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- soooooooooo, i guess TOC makes it so you no longer do the attack hook
|
||||||
|
---- That's fine, we'll just do it ourselves
|
||||||
|
local onMouseClick = function(x,y)
|
||||||
|
checkDoAttack(getSpecificPlayer(0))
|
||||||
|
mouseDown = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This is a little hack so we can still hold the offhand attack
|
||||||
|
local onMouseUp = function(x,y)
|
||||||
|
mouseDown = false
|
||||||
|
end
|
||||||
|
|
||||||
|
local playerUpdate = function(player)
|
||||||
|
local num = player:getPlayerNum()
|
||||||
|
if (num == 0 and mouseDown) or (JoypadState.players[num+1] and (getControllerAxisValue(player:getJoypadBind(), 5) > 0.90)) then
|
||||||
|
checkDoAttack(player)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local OnWeaponHitCharacter = function(player, target, weapon, damage)
|
||||||
|
print("OnWeaponHitCharacter: " .. tostring(damage))
|
||||||
|
print("IsCritical: " .. tostring(player:isCriticalHit()))
|
||||||
|
end
|
||||||
|
|
||||||
|
Events.OnGameStart.Add(function()
|
||||||
|
Events.OnMouseDown.Add(onMouseClick)
|
||||||
|
Events.OnMouseUp.Add(onMouseUp)
|
||||||
|
Events.OnPlayerUpdate.Add(playerUpdate)
|
||||||
|
if isDebugEnabled() then
|
||||||
|
Events.OnWeaponHitCharacter.Add(OnWeaponHitCharacter)
|
||||||
|
end
|
||||||
|
-- if SandboxVars.BrutalHandwork.BaseAttackOverride then
|
||||||
|
-- --Hook.WeaponHitCharacter.Add(WeaponHitCharacter)
|
||||||
|
-- Hook.WeaponHitCharacter.Add(BrutalAttack.OnWeaponHitCharacter)
|
||||||
|
-- end
|
||||||
|
end)
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
Sandbox_EN = {
|
||||||
|
Sandbox_BrutalHandwork = "Brutal Handwork",
|
||||||
|
|
||||||
|
Sandbox_BrutalHandwork_DualWieldMelee = "Automatically alternate left and right attacks when dual-wielding melee weapons",
|
||||||
|
Sandbox_BrutalHandwork_DualWieldMelee_tooltip = "When a player is dual-wielding melee weapons, automatically alternate between left and right attacks. Disable to require the Modifier to be pressed for an offhand attack.",
|
||||||
|
|
||||||
|
Sandbox_BrutalHandwork_EnableUnarmed = "Enable Unarmed Attacks",
|
||||||
|
Sandbox_BrutalHandwork_EnableUnarmed_tooltip = "Even when a player is unarmed, they will be able to attack. By default, must be aiming and holding the Modifier key to punch.",
|
||||||
|
|
||||||
|
Sandbox_BrutalHandwork_AlwaysUnarmed = "Always raise fists when unarmed",
|
||||||
|
Sandbox_BrutalHandwork_AlwaysUnarmed_tooltip = "When a player is unarmed, always raise their fists when aiming for unarmed attacks. Disable to require the Modifier to be held when aiming.",
|
||||||
|
|
||||||
|
Sandbox_BrutalHandwork_BaseAttackOverride = "EXPERIMENTAL: Main Attack Damage Override",
|
||||||
|
Sandbox_BrutalHandwork_BaseAttackOverride_tooltip = "Main Attacks use the damage calculation functions from BrutalHandwork instead of Vanilla. This forces consistency between the expected damage for both hand attacks. <LINE> WARNING: This option is currently experimental, but is likely to become the default and will be required for many additional options in the future. It is stable, but may cause inconsistencies compared to vanilla as it is still being developed. PLEASE READ the mod's description for current limitations!",
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
UI_EN = {
|
||||||
|
UI_Init_BrtualHandwork = "Hello: Brutal Handwork!",
|
||||||
|
UI_optionscreen_binding_BrtualHandwork = Brutal Handwork",
|
||||||
|
}
|
||||||
21
BrutalHandwork/Contents/mods/BrutalHandwork/media/sandbox-options.txt
Executable file
21
BrutalHandwork/Contents/mods/BrutalHandwork/media/sandbox-options.txt
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
VERSION = 1,
|
||||||
|
option BrutalHandwork.DualWieldMelee
|
||||||
|
{
|
||||||
|
type = boolean, default = false,
|
||||||
|
page = BrutalHandwork,
|
||||||
|
translation = BrutalHandwork_DualWieldMelee,
|
||||||
|
}
|
||||||
|
|
||||||
|
option BrutalHandwork.EnableUnarmed
|
||||||
|
{
|
||||||
|
type = boolean, default = true,
|
||||||
|
page = BrutalHandwork,
|
||||||
|
translation = BrutalHandwork_EnableUnarmed,
|
||||||
|
}
|
||||||
|
|
||||||
|
option BrutalHandwork.AlwaysUnarmed
|
||||||
|
{
|
||||||
|
type = boolean, default = false,
|
||||||
|
page = BrutalHandwork,
|
||||||
|
translation = BrutalHandwork_AlwaysUnarmed,
|
||||||
|
}
|
||||||
33
BrutalHandwork/Contents/mods/BrutalHandwork/media/scripts/brutalweapons.txt
Executable file
33
BrutalHandwork/Contents/mods/BrutalHandwork/media/scripts/brutalweapons.txt
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
module Base {
|
||||||
|
item Fisticuffs {
|
||||||
|
DisplayCategory = Weapon,
|
||||||
|
MaxRange = 0.8,
|
||||||
|
WeaponSprite = null,
|
||||||
|
MinAngle = 0.65,
|
||||||
|
MinimumSwingTime = 2,
|
||||||
|
Type = Weapon,
|
||||||
|
SwingAnim = Shove,
|
||||||
|
KnockBackOnNoDeath = TRUE,
|
||||||
|
WeaponWeight = 0,
|
||||||
|
DisplayName = Bare Hands,
|
||||||
|
Categories = Unarmed,
|
||||||
|
SwingAmountBeforeImpact = 0.1,
|
||||||
|
SwingTime = 2,
|
||||||
|
MinDamage = 0.1,
|
||||||
|
SplatNumber = 1,
|
||||||
|
EnduranceMod = 1.7,
|
||||||
|
Weight = 1,
|
||||||
|
PushBackMod = 0.5,
|
||||||
|
MaxDamage = 0.25,
|
||||||
|
SplatBloodOnNoDeath = FALSE,
|
||||||
|
MaxHitCount = 1,
|
||||||
|
Icon = Axe,
|
||||||
|
DoorDamage = 2,
|
||||||
|
TreeDamage = 1,
|
||||||
|
RunAnim = Run_Weapon2,
|
||||||
|
IdleAnim = Idle,
|
||||||
|
DoorHitSound = BareHandsHit,
|
||||||
|
HitSound = BareHandsHit,
|
||||||
|
HitFloorSound = BareHandsHit,
|
||||||
|
}
|
||||||
|
}
|
||||||
11
BrutalHandwork/Contents/mods/BrutalHandwork/mod.info
Executable file
11
BrutalHandwork/Contents/mods/BrutalHandwork/mod.info
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
name=Brutal Handwork
|
||||||
|
id=BrutalHandwork
|
||||||
|
require=FancyHandwork
|
||||||
|
authors=dhert
|
||||||
|
|
||||||
|
description=An overhaul to combat to make your player more Brutal!
|
||||||
|
|
||||||
|
pzversion=41
|
||||||
|
tags=Realistic;Framework
|
||||||
|
|
||||||
|
poster=poster.png
|
||||||
BIN
BrutalHandwork/Contents/mods/BrutalHandwork/poster.png
Executable file
BIN
BrutalHandwork/Contents/mods/BrutalHandwork/poster.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 612 KiB |
BIN
BrutalHandwork/preview.png
Executable file
BIN
BrutalHandwork/preview.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 94 KiB |
9
BrutalHandwork/workshop.txt
Executable file
9
BrutalHandwork/workshop.txt
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
version=1
|
||||||
|
id=2934621024
|
||||||
|
title=Brutal Handwork
|
||||||
|
description=[h1]Supports B41+. Works in Multiplayer[/h1]
|
||||||
|
description=[h3]A new save is not required[/h3]
|
||||||
|
description=
|
||||||
|
description=[img]https://i.imgur.com/p7Fv1Z6.gif[/img]
|
||||||
|
tags=Build 41;Balance;Framework;Realistic
|
||||||
|
visibility=private
|
||||||
@@ -11,35 +11,14 @@
|
|||||||
<m_Type>STRING</m_Type>
|
<m_Type>STRING</m_Type>
|
||||||
<m_StringValue>FH_Boop</m_StringValue>
|
<m_StringValue>FH_Boop</m_StringValue>
|
||||||
</m_Conditions>
|
</m_Conditions>
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01</boneName>
|
|
||||||
<weight>0.00</weight>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
<m_SubStateBoneWeights>
|
||||||
<boneName>Bip01_R_Clavicle</boneName>
|
<boneName>Bip01_R_Clavicle</boneName>
|
||||||
<weight>0.80</weight>
|
<weight>0.80</weight>
|
||||||
|
<includeDescendants>false</includeDescendants>
|
||||||
</m_SubStateBoneWeights>
|
</m_SubStateBoneWeights>
|
||||||
<m_SubStateBoneWeights>
|
<m_SubStateBoneWeights>
|
||||||
<boneName>Bip01_R_UpperArm</boneName>
|
<boneName>Bip01_R_UpperArm</boneName>
|
||||||
</m_SubStateBoneWeights>
|
</m_SubStateBoneWeights>
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01_R_Forearm</boneName>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01_R_Hand</boneName>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01_R_Finger0</boneName>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01_R_Finger0Nub</boneName>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01_R_Finger1</boneName>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01_R_Finger1Nub</boneName>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
<m_SubStateBoneWeights>
|
||||||
<boneName>Bip01_Prop1</boneName>
|
<boneName>Bip01_Prop1</boneName>
|
||||||
</m_SubStateBoneWeights>
|
</m_SubStateBoneWeights>
|
||||||
|
|||||||
@@ -73,7 +73,7 @@
|
|||||||
</m_SubStateBoneWeights>
|
</m_SubStateBoneWeights>
|
||||||
<m_SubStateBoneWeights>
|
<m_SubStateBoneWeights>
|
||||||
<boneName>Translation_Data</boneName>
|
<boneName>Translation_Data</boneName>
|
||||||
<weight>0.4</weight>
|
<weight>0.25</weight>
|
||||||
</m_SubStateBoneWeights>
|
</m_SubStateBoneWeights>
|
||||||
<m_Events>
|
<m_Events>
|
||||||
<m_EventName>SetVariable</m_EventName>
|
<m_EventName>SetVariable</m_EventName>
|
||||||
|
|||||||
@@ -11,35 +11,14 @@
|
|||||||
<m_Type>STRING</m_Type>
|
<m_Type>STRING</m_Type>
|
||||||
<m_StringValue>FH_BoopL</m_StringValue>
|
<m_StringValue>FH_BoopL</m_StringValue>
|
||||||
</m_Conditions>
|
</m_Conditions>
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01</boneName>
|
|
||||||
<weight>0.00</weight>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
<m_SubStateBoneWeights>
|
||||||
<boneName>Bip01_L_Clavicle</boneName>
|
<boneName>Bip01_L_Clavicle</boneName>
|
||||||
<weight>0.80</weight>
|
<weight>0.80</weight>
|
||||||
|
<includeDescendants>false</includeDescendants>
|
||||||
</m_SubStateBoneWeights>
|
</m_SubStateBoneWeights>
|
||||||
<m_SubStateBoneWeights>
|
<m_SubStateBoneWeights>
|
||||||
<boneName>Bip01_L_UpperArm</boneName>
|
<boneName>Bip01_L_UpperArm</boneName>
|
||||||
</m_SubStateBoneWeights>
|
</m_SubStateBoneWeights>
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01_L_Forearm</boneName>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01_L_Hand</boneName>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01_L_Finger0</boneName>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01_L_Finger0Nub</boneName>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01_L_Finger1</boneName>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
|
||||||
<boneName>Bip01_L_Finger1Nub</boneName>
|
|
||||||
</m_SubStateBoneWeights>
|
|
||||||
<m_SubStateBoneWeights>
|
<m_SubStateBoneWeights>
|
||||||
<boneName>Bip01_Prop2</boneName>
|
<boneName>Bip01_Prop2</boneName>
|
||||||
</m_SubStateBoneWeights>
|
</m_SubStateBoneWeights>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ local function doOverride()
|
|||||||
|
|
||||||
function ISHotbar:equipItem(item)
|
function ISHotbar:equipItem(item)
|
||||||
-- Get Modifier
|
-- Get Modifier
|
||||||
local mod = isFHModKeyDown()
|
local mod = isFHModBindDown(self.chr)
|
||||||
local primary = self.chr:getPrimaryHandItem()
|
local primary = self.chr:getPrimaryHandItem()
|
||||||
local secondary = self.chr:getSecondaryHandItem()
|
local secondary = self.chr:getSecondaryHandItem()
|
||||||
local equip = true
|
local equip = true
|
||||||
|
|||||||
@@ -94,18 +94,19 @@ end
|
|||||||
local _ISAddItemInRecipe_start = ISAddItemInRecipe.start
|
local _ISAddItemInRecipe_start = ISAddItemInRecipe.start
|
||||||
function ISAddItemInRecipe:start()
|
function ISAddItemInRecipe:start()
|
||||||
local base = nil
|
local base = nil
|
||||||
|
local baseType = self.baseItem:getType()
|
||||||
if luautils.stringStarts(self.baseItem:getType(), "GridlePan") or luautils.stringStarts(self.baseItem:getType(), "GriddlePan") then
|
if string.find(baseType, "GridlePan") or string.find(baseType, "GriddlePan") then
|
||||||
base = "GridlePan"
|
base = "GridlePan"
|
||||||
elseif luautils.stringStarts(self.baseItem:getType(), "WaterSaucepan") or luautils.stringStarts(self.baseItem:getType(), "Saucepan") then
|
elseif string.find(baseType, "Saucepan") then
|
||||||
base = "SaucePan"
|
base = "SaucePan"
|
||||||
elseif luautils.stringStarts(self.baseItem:getType(), "WaterPot") or luautils.stringStarts(self.baseItem:getType(), "Pot") then
|
elseif string.find(baseType, "Pot") then
|
||||||
base = "CookingPot"
|
base = "CookingPot"
|
||||||
elseif luautils.stringStarts(self.baseItem:getType(), "RoastingPan") or luautils.stringStarts(self.baseItem:getType(), "RoastingPan") then
|
elseif string.find(baseType, "RoastingPan") then
|
||||||
base = "RoastingPan"
|
base = "RoastingPan"
|
||||||
else
|
else
|
||||||
base = self.baseItem:getStaticModel() or "FryingPan"
|
base = self.baseItem:getStaticModel() or "FryingPan"
|
||||||
end
|
end
|
||||||
|
|
||||||
self:setAnimVariable("BaseType", base)
|
self:setAnimVariable("BaseType", base)
|
||||||
self:setActionAnim("AddToPan")
|
self:setActionAnim("AddToPan")
|
||||||
self:setOverrideHandModelsString(self.usedItem:getStaticModel(), base)
|
self:setOverrideHandModelsString(self.usedItem:getStaticModel(), base)
|
||||||
@@ -201,3 +202,36 @@ function ISWearClothing:new(...)
|
|||||||
|
|
||||||
return o
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- DON'T LOOK AT ME! :O
|
||||||
|
---- I'm trying to add some new animations for Transfer Actions, but wasn't able to get this completed before the next update.
|
||||||
|
-- -- Fix for the Transfer action.
|
||||||
|
-- --- Player will now only pick items off the ground when they are on the ground :)
|
||||||
|
-- local _ISInventoryTransferAction_doActionAnim = ISInventoryTransferAction.doActionAnim
|
||||||
|
-- function ISInventoryTransferAction:doActionAnim(cont)
|
||||||
|
-- _ISInventoryTransferAction_doActionAnim(self, cont)
|
||||||
|
-- if self.srcContainer:getType() == "floor" then
|
||||||
|
-- local worldItem = self.item:getWorldItem()
|
||||||
|
-- if worldItem then
|
||||||
|
-- --worldItem:removeFromSquare()
|
||||||
|
-- local anim = (self.item:getActualWeight() <= 1.0 and "FancyLoot") or nil
|
||||||
|
-- local posAnim = (anim and "FH_Hand") or "LootPosition"
|
||||||
|
-- local z = worldItem:getWorldPosZ() - self.character:getZ()
|
||||||
|
-- local position
|
||||||
|
-- if z > 0.1 then
|
||||||
|
-- position = (anim and ((ZombRand(3) == 1 and "left") or "right")) or "Mid"
|
||||||
|
-- elseif z > 0.5 then
|
||||||
|
-- position = "High"
|
||||||
|
-- end
|
||||||
|
-- if position == "left" then
|
||||||
|
-- self.action:setOverrideHandModels(nil, self.item)
|
||||||
|
-- else
|
||||||
|
-- self.action:setOverrideHandModels(self.item, nil)
|
||||||
|
-- end
|
||||||
|
-- if anim then
|
||||||
|
-- self:setActionAnim(anim)
|
||||||
|
-- end
|
||||||
|
-- self:setAnimVariable(posAnim, position)
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
@@ -48,7 +48,7 @@ end
|
|||||||
|
|
||||||
local _ISOvenUITimedAction_perform = ISOvenUITimedAction.perform
|
local _ISOvenUITimedAction_perform = ISOvenUITimedAction.perform
|
||||||
function ISOvenUITimedAction:perform()
|
function ISOvenUITimedAction:perform()
|
||||||
ISTimedActionQueue.add(FHBoopAction:new(self.character, { item = self.object, extra = 0 }))
|
ISTimedActionQueue.add(FHBoopAction:new(self.character, { item = self.mcwave or self.stove, extra = 0 }))
|
||||||
_ISOvenUITimedAction_perform(self)
|
_ISOvenUITimedAction_perform(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -110,8 +110,10 @@ function ISInventoryPage:toggleStove()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local _ISRadioAction_perform = ISRadioAction.perform
|
local _ISRadioAction_perform = ISRadioAction.perform
|
||||||
|
|
||||||
function ISRadioAction:perform()
|
function ISRadioAction:perform()
|
||||||
|
-- Fix for the infinite error when the device is in your inventory
|
||||||
|
if not (instanceof(self.device, "InventoryItem") and self.device:isInPlayerInventory()) and not self.character:isSeatedInVehicle() then
|
||||||
ISTimedActionQueue.add(FHBoopAction:new(self.character, { item = self.device, extra = 0 }))
|
ISTimedActionQueue.add(FHBoopAction:new(self.character, { item = self.device, extra = 0 }))
|
||||||
|
end
|
||||||
_ISRadioAction_perform(self)
|
_ISRadioAction_perform(self)
|
||||||
end
|
end
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
-- Animation Framework for Project Zomboid
|
-- Animation Framework for Project Zomboid
|
||||||
---- Code inspired and modifed from "Tsarlib"
|
---- Code inspired and modifed from "Tsarlib"
|
||||||
|
|
||||||
|
-- next release, this will be removed!
|
||||||
|
|
||||||
if not isClient() and not isServer() or AnimationFramework then return end
|
if not isClient() and not isServer() or AnimationFramework then return end
|
||||||
AnimationFramework = true
|
AnimationFramework = true
|
||||||
|
|
||||||
|
|||||||
@@ -14,13 +14,14 @@ local rearObjects = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
local function skipInstances(obj)
|
local function skipInstances(obj)
|
||||||
return not obj or rearObjects[obj:getObjectName()]
|
return not obj or rearObjects[obj:getObjectName()] or (obj:getObjectName() == "Thumpable" and obj:isDoor())
|
||||||
end
|
end
|
||||||
|
|
||||||
--character:getModData().FancyHands and not character:getModData().FancyHands.recentMove and (character:getModData().FancyHands.recentMove and not skipInstances(data.item) or true)
|
--character:getModData().FancyHands and not character:getModData().FancyHands.recentMove and (character:getModData().FancyHands.recentMove and not skipInstances(data.item) or true)
|
||||||
local function shouldDoTurn(obj, player)
|
local function shouldDoTurn(obj, player)
|
||||||
if not obj or not player or player:isAiming() or not SandboxVars.FancyHandwork or SandboxVars.FancyHandwork.DisableTurn == 1 then return false end
|
if not obj or not player or player:isAiming() or not SandboxVars.FancyHandwork or SandboxVars.FancyHandwork.DisableTurn == 1 then return false end
|
||||||
if SandboxVars.FancyHandwork.DisableTurn == 3 then return true end
|
if SandboxVars.FancyHandwork.DisableTurn == 3 then return true end
|
||||||
|
if instanceof(obj, "InventoryItem") and obj:isInPlayerInventory() then return false end -- safeguard
|
||||||
if SandboxVars.FancyHandwork.TurnBehavior <= 2 then
|
if SandboxVars.FancyHandwork.TurnBehavior <= 2 then
|
||||||
return (player:getModData().FancyHands and not player:getModData().FancyHands.recentMove)
|
return (player:getModData().FancyHands and not player:getModData().FancyHands.recentMove)
|
||||||
elseif SandboxVars.FancyHandwork.TurnBehavior == 3 then
|
elseif SandboxVars.FancyHandwork.TurnBehavior == 3 then
|
||||||
@@ -34,7 +35,6 @@ function FHBoopAction:isValid()
|
|||||||
return true;
|
return true;
|
||||||
end
|
end
|
||||||
|
|
||||||
-- blech, I really want this, but turning overrides my animation
|
|
||||||
function FHBoopAction:waitToStart()
|
function FHBoopAction:waitToStart()
|
||||||
if self.character:isSeatedInVehicle() then
|
if self.character:isSeatedInVehicle() then
|
||||||
-- If we are in a car, we should just stop here actually
|
-- If we are in a car, we should just stop here actually
|
||||||
@@ -48,6 +48,51 @@ function FHBoopAction:waitToStart()
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Brought to you by ChuckGPT
|
||||||
|
---@param char IsoPlayer|IsoGameCharacter|IsoMovingObject|IsoObject
|
||||||
|
local function getDotSide(char,mouseX,mouseY)
|
||||||
|
|
||||||
|
---@type Vector2
|
||||||
|
local lookVector = char:getLookVector(Vector2.new())
|
||||||
|
local lookVX, lookVY = lookVector:getX(), lookVector:getY()
|
||||||
|
|
||||||
|
local charX, charY, charZ, charNum = char:getX(), char:getY(), char:getZ(), char:getPlayerNum()
|
||||||
|
|
||||||
|
---@type Vector2
|
||||||
|
local charVector = Vector2.new(charX,charY)
|
||||||
|
local charVX, charVY = charVector:getX(), charVector:getY()
|
||||||
|
|
||||||
|
local objX = screenToIsoX(charNum, mouseX, mouseY, charZ)
|
||||||
|
local objY = screenToIsoY(charNum, mouseX, mouseY, charZ)
|
||||||
|
|
||||||
|
---@type Vector2
|
||||||
|
local objVector = Vector2.new(objX-charVX,objY-charVY)
|
||||||
|
objVector:normalize()
|
||||||
|
|
||||||
|
local dot = Vector2.dot(objVector:getX(), objVector:getY(), lookVX, lookVY)
|
||||||
|
|
||||||
|
local front = dot > 0.0
|
||||||
|
|
||||||
|
-- if dot < 0.0 then
|
||||||
|
-- results = false
|
||||||
|
-- else--if (dot < 0.0 and dot < -0.5) then
|
||||||
|
-- results = results.. "BEHIND"
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- results = results.."|"
|
||||||
|
|
||||||
|
local lcVX, lcVY = charVX + lookVX, charVY + lookVY
|
||||||
|
local dotSide = (objX - charVX) * (lcVY - charVY) - (objY - charVY) * (lcVX - charVX)
|
||||||
|
local left = dotSide > 0.0
|
||||||
|
-- if dotSide > 0.0 then
|
||||||
|
-- results = results.. "LEFT"
|
||||||
|
-- else
|
||||||
|
-- results = results.. "RIGHT"
|
||||||
|
-- end
|
||||||
|
|
||||||
|
return front, left
|
||||||
|
end
|
||||||
|
|
||||||
function FHBoopAction:isInRearRange()
|
function FHBoopAction:isInRearRange()
|
||||||
-- This game is weird man
|
-- This game is weird man
|
||||||
---- I tried to get the angle between the player and the object but its fucking inconsistent because large numbers, AND fucking light switches
|
---- I tried to get the angle between the player and the object but its fucking inconsistent because large numbers, AND fucking light switches
|
||||||
|
|||||||
0
FancyHandwork/Contents/mods/FancyHandwork/media/lua/shared/Translate/TH/UI_TH.txt
Normal file → Executable file
0
FancyHandwork/Contents/mods/FancyHandwork/media/lua/shared/Translate/TH/UI_TH.txt
Normal file → Executable file
@@ -26,6 +26,19 @@ FancyHands.special = {
|
|||||||
["Base.CorpseFemale"] = "holdingbody"
|
["Base.CorpseFemale"] = "holdingbody"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Use the animations from this mod instead!
|
||||||
|
if getActivatedMods():contains('Skizots Visible Boxes and Garbage2') then
|
||||||
|
FancyHands.special = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- We will begin to store compatibility objects here
|
||||||
|
FancyHands.compat = {}
|
||||||
|
-- if getActivatedMods():contains('Amputation2') then -- now included in TOC!
|
||||||
|
-- FancyHands.compat.TOC = require('compat/FH_TOC')
|
||||||
|
-- end
|
||||||
|
if getActivatedMods():contains('BrutalHandwork') then
|
||||||
|
FancyHands.compat.brutal = true
|
||||||
|
end
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
-- Fancy Handwork Utilities
|
-- Fancy Handwork Utilities
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
@@ -34,6 +47,10 @@ function isFHModKeyDown()
|
|||||||
return isKeyDown(getCore():getKey('FHModifier'))
|
return isKeyDown(getCore():getKey('FHModifier'))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function isFHModBindDown(player)
|
||||||
|
return isFHModKeyDown() or (player and player:isLBPressed())
|
||||||
|
end
|
||||||
|
|
||||||
local FHswapItems = function(character)
|
local FHswapItems = function(character)
|
||||||
local primary = character:getPrimaryHandItem()
|
local primary = character:getPrimaryHandItem()
|
||||||
local secondary = character:getSecondaryHandItem()
|
local secondary = character:getSecondaryHandItem()
|
||||||
@@ -160,6 +177,16 @@ local function fancy(player)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if FancyHands.compat.brutal then
|
||||||
|
local equipped = instanceof(primary, "HandWeapon") and primary:getCategories():contains("Unarmed")
|
||||||
|
-- we already established that primary and secondary are the same, so if primary is nil then so is secondary
|
||||||
|
-- or, this is a 2h fist weapon and therefore we should still get ready to punch
|
||||||
|
if (not primary and player:isAiming() and (SandboxVars.BrutalHandwork.EnableUnarmed and (SandboxVars.BrutalHandwork.AlwaysUnarmed or isFHModBindDown(player)))) or equipped then
|
||||||
|
player:clearVariable("LeftHandMask")
|
||||||
|
player:setVariable("RightHandMask", "bhunarmedaim")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
player:clearVariable("LeftHandMask")
|
player:clearVariable("LeftHandMask")
|
||||||
player:clearVariable("RightHandMask")
|
player:clearVariable("RightHandMask")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ description=[*] [b]NEW:[/b] Wrench Repair Animation!
|
|||||||
description=[/list]
|
description=[/list]
|
||||||
description=
|
description=
|
||||||
description=[h2]Updates[/h2]
|
description=[h2]Updates[/h2]
|
||||||
description=Important information is updated on this page, but full information and release notes are available in the Discussions. Please see the latest:
|
description=Important information is updated on this page, but full information and release notes are available in the Discussions. Please see the latest: [url=https://steamcommunity.com/workshop/filedetails/discussion/2904920097/3762228679801751286/]Fancy Handwork - "It's Over 9,000!" Update[/url]
|
||||||
description=
|
description=
|
||||||
description=[h2]IMPORTANT[/h2]
|
description=[h2]IMPORTANT[/h2]
|
||||||
description=If you receive an error about missing actions, or world interactions are simply not playing, you may need to restart Project Zomboid. I have noticed that enabling this mod on an already-existing save and starting the game will result in the animations not being loaded until the game is restarted. This is a [b]BASE GAME[/b] issue!
|
description=If you receive an error about missing actions, or world interactions are simply not playing, you may need to restart Project Zomboid. I have noticed that enabling this mod for the first time on an already-existing save and starting the game will result in the new animations not being loaded until the game is restarted. This is a [b]BASE GAME[/b] issue, but should only happen the first time.
|
||||||
description=
|
description=
|
||||||
description=If you receive an error following any update, please see: [url=https://theindiestone.com/forums/index.php?/topic/42925-how-to-fix-updated-mods-in-build-41-multiplayer/]How to fix updated mods in Build 41 Multiplayer[/url]
|
description=If you receive an error following any update, please see: [url=https://theindiestone.com/forums/index.php?/topic/42925-how-to-fix-updated-mods-in-build-41-multiplayer/]How to fix updated mods in Build 41 Multiplayer[/url]
|
||||||
description=This mod adds many additional animation and action files, which may change between releases. I try to minimize this, but sometimes it is necessary. Unfortunately, Steam sometimes doesn't like to update these correctly.
|
description=This mod adds many additional animation and action files, which may change between releases. I try to minimize this, but sometimes it is necessary. Unfortunately, Steam sometimes doesn't like to update these correctly resulting in errors.
|
||||||
description=
|
description=
|
||||||
description=[h2]Usage[/h2]
|
description=[h2]Usage[/h2]
|
||||||
description=When Attaching or Detaching an item on your Hotbar, you have a chance for the action to automatically be done with your left hand.
|
description=When Attaching or Detaching an item on your Hotbar, you have a chance for the action to automatically be done with your left hand.
|
||||||
@@ -42,18 +42,17 @@ description=When you press the Modifier Key and a Hotbar slot, the item slotted
|
|||||||
description=
|
description=
|
||||||
description=Pressing the Modifier and "E" will swap the items in your hands. (Configurable)
|
description=Pressing the Modifier and "E" will swap the items in your hands. (Configurable)
|
||||||
description=
|
description=
|
||||||
description=Interacting with the world normally, such as opening and closing doors and curtains,flicking light switches, and more, all now have an Animation!
|
description=Interacting with the world normally, such as opening and closing doors and curtains, flicking light switches, and more, all now have an Animation!
|
||||||
description=
|
description=
|
||||||
description=Almost ALL TimedActions now have an Animation! No longer will your character just stand there, waiting for a progress bar to fill up!
|
description=Almost ALL TimedActions now have an Animation! No longer will your character just stand there, waiting for a progress bar to fill up!
|
||||||
description=
|
description=
|
||||||
description=[h3]Notes about World Interactions[/h3]
|
description=[h3]Notes about World Interactions[/h3]
|
||||||
description=If you are standing still you will turn and face the object you are interacting with if you are not already doing so. There is a Sandbox setting to control how long of a delay before you character is standing still.
|
description=If you are standing still you will turn and face the object you are interacting with if you are not already doing so. There is a Sandbox setting to control how long of a delay before you character is standing still, or the forced turn can be disabled or required.
|
||||||
description=[b]NOTE:[/b] This is based on your selected Render Framerate. As such, you may need to change this according to your current framerate. A value of 60 is about 1 second at 60 FPS. I will update this at some point.
|
|
||||||
description=
|
description=
|
||||||
description=When performing a World Interaction and moving your character will slow down slightly, and stop altogether in the case of opening a Garage Door, for a very brief moment. I have no plans on this being a configurable option, and this is done intentionally. It is a fantastic inclusion for immersion in my opinion, and in tight situations makes planning your movement all the more important. After time, you will hardly notice it.
|
description=When performing a World Interaction and moving your character will slow down slightly, and stop altogether in the case of opening a Garage Door, for a very brief moment. I have no plans on this being a configurable option, and this is done intentionally. It is a fantastic inclusion for immersion in my opinion, and in tight situations makes planning your movement all the more important. After time, you will hardly notice it.
|
||||||
|
description=[b]NEW 01/19/2023[/b] - The speed reduction has been reduced from 50% to 25%. This should help prevent the player from being trapped, while still being a nice addition to immersion.
|
||||||
description=
|
description=
|
||||||
description=[h2]Multiplayer[/h2]
|
description=[h2]Multiplayer[/h2]
|
||||||
description=[b]NEW 01/07/2023 [/b] - New Animation Sync method is now being used!
|
|
||||||
description=Animations should sync across multiplayer with little to no issues!
|
description=Animations should sync across multiplayer with little to no issues!
|
||||||
description=
|
description=
|
||||||
description=[h2]Controllers[/h2]
|
description=[h2]Controllers[/h2]
|
||||||
@@ -70,6 +69,5 @@ description=[url=https://steamcommunity.com/sharedfiles/filedetails/?id=28097195
|
|||||||
description=[url=https://steamcommunity.com/sharedfiles/filedetails/?id=2651128766]Body Remodel - FINGERS.[/url] by Akyet
|
description=[url=https://steamcommunity.com/sharedfiles/filedetails/?id=2651128766]Body Remodel - FINGERS.[/url] by Akyet
|
||||||
description=
|
description=
|
||||||
description=Source: [url=https://github.com/hlfstr/pz-mods]GitHub[/url]
|
description=Source: [url=https://github.com/hlfstr/pz-mods]GitHub[/url]
|
||||||
description=
|
|
||||||
tags=Build 41;Realistic;Silly/Fun
|
tags=Build 41;Realistic;Silly/Fun
|
||||||
visibility=public
|
visibility=public
|
||||||
|
|||||||
Reference in New Issue
Block a user