123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956 |
- //! Light / Heavy punches
- enum EFightLogicCooldownCategory
- {
- EVADE = 0
- }
- class DayZPlayerMeleeFightLogic_LightHeavy
- {
- //! cooldown timers settings
- const float EVADE_COOLDOWN = 0.5;
-
- //
- const float CLOSE_TARGET_DISTANCE = 1.5;
-
- //! dummy ammo types
- const string DUMMY_LIGHT_AMMO = "Dummy_Light";
- const string DUMMY_HEAVY_AMMO = "Dummy_Heavy";
- protected PlayerBase m_Player;
- protected ref DayZPlayerImplementMeleeCombat m_MeleeCombat;
- protected EMeleeHitType m_HitType;
- protected ref map <int, ref Timer> m_CooldownTimers;
- protected Mission m_Mission;
- protected bool m_IsInBlock;
- protected bool m_IsEvading;
- protected bool m_IsInComboRange;
- protected bool m_WasPreviousHitProcessed;
-
- void DayZPlayerMeleeFightLogic_LightHeavy(DayZPlayerImplement player)
- {
- Init(player);
- }
-
- void Init(DayZPlayerImplement player)
- {
- m_DZPlayer = player;
- m_Player = PlayerBase.Cast(player);
- m_MeleeCombat = m_Player.GetMeleeCombat();
- m_Mission = GetGame().GetMission();
- m_IsInBlock = false;
- m_IsEvading = false;
- m_WasPreviousHitProcessed = false;
- m_HitType = EMeleeHitType.NONE;
-
- RegisterCooldowns();
- }
- void ~DayZPlayerMeleeFightLogic_LightHeavy() {}
- bool IsInBlock()
- {
- return m_IsInBlock;
- }
-
- void SetBlock(bool block)
- {
- m_IsInBlock = block;
- }
-
- bool IsEvading()
- {
- return m_IsEvading;
- }
-
- bool GetCurrentHitType()
- {
- return m_HitType;
- }
-
- bool CanFight()
- {
- if (m_Player.IsEmotePlaying())
- return false;
-
- if (m_Player.GetActionManager() && m_Player.GetActionManager().GetRunningAction())
- return false;
- return true;
- }
- protected void RegisterCooldowns()
- {
- m_CooldownTimers = new map<int, ref Timer>();
- m_CooldownTimers.Insert(EFightLogicCooldownCategory.EVADE, new Timer(CALL_CATEGORY_SYSTEM)); // evades
- }
- protected EMeleeHitType GetAttackTypeFromInputs(HumanInputController pInputs)
- {
- if (pInputs.IsMeleeFastAttackModifier() && m_Player.CanConsumeStamina(EStaminaConsumers.MELEE_HEAVY))
- {
- return EMeleeHitType.HEAVY;
- }
- return EMeleeHitType.LIGHT;
- }
-
- protected EMeleeHitType GetAttackTypeByWeaponAttachments(EntityAI pEntity)
- {
- if (!m_Player.CanConsumeStamina(EStaminaConsumers.MELEE_HEAVY))
- {
- return EMeleeHitType.NONE;
- }
- //! use stabbing if the bayonet/knife is attached to firearm
- if (pEntity.HasBayonetAttached())
- {
- return EMeleeHitType.WPN_STAB;
- }
- else if (pEntity.HasButtstockAttached())
- {
- return EMeleeHitType.WPN_HIT_BUTTSTOCK;
- }
- return EMeleeHitType.WPN_HIT;
- }
-
- protected float GetAttackTypeByDistanceToTarget(EntityAI pTarget, EMeleeTargetType pTargetType = EMeleeTargetType.ALIGNABLE)
- {
- if (pTargetType == EMeleeTargetType.NONALIGNABLE)
- {
- return 1.0;
- }
- //! target in short distance - in place attack
- if (IsShortDistance(pTarget, Math.SqrFloat(CLOSE_TARGET_DISTANCE)))
- {
- return 1.0;
- }
-
- //! target is far from the player - forward movement attack
- return 0.0;
- }
-
- bool HandleFightLogic(int pCurrentCommandID, HumanInputController pInputs, EntityAI pEntityInHands, HumanMovementState pMovementState, out bool pContinueAttack)
- {
- HumanInventoryWithFSM invFSM = HumanInventoryWithFSM.Cast(m_Player.GetHumanInventory());
- if (invFSM && !invFSM.IsIdle())
- return false;
- HumanCommandMove hcm = m_Player.GetCommand_Move();
- InventoryItem itemInHands = InventoryItem.Cast(pEntityInHands);
- bool isFireWeapon = itemInHands && itemInHands.IsWeapon();
-
- //! Check if we need to damage
- if (HandleHitEvent(pCurrentCommandID, pInputs, itemInHands, pMovementState, pContinueAttack))
- return false;
- //! Actually pressing a button to start a melee attack
- if ((pInputs.IsAttackButtonDown() && !isFireWeapon) || (pInputs.IsMeleeWeaponAttack() && isFireWeapon) || (pContinueAttack && isFireWeapon))
- {
- //Debug.MeleeLog(m_Player, string.Format("HandleFightLogic[1] attackButtonDown=%1, meleeWeaponAttack=%2, pContinueAttack=%3, isFireWeapon=%4", pInputs.IsAttackButtonDown(), pInputs.IsMeleeWeaponAttack(), pContinueAttack, isFireWeapon));
-
- //! do not perform attacks when blocking
- if (m_IsInBlock || m_IsEvading)
- return false;
-
- //! if the item in hands cannot be used as melee weapon
- if (itemInHands && !itemInHands.IsMeleeWeapon() && !isFireWeapon)
- return false;
-
- //! Currently not performing any attacks, so here we start the initial
- if (pCurrentCommandID == DayZPlayerConstants.COMMANDID_MOVE)
- {
- //Debug.MeleeLog(m_Player, "HandleFightLogic[1a]");
- //! melee with firearm
- if (isFireWeapon)
- {
- return HandleInitialFirearmMelee(pCurrentCommandID, pInputs, itemInHands, pMovementState, pContinueAttack);
- }
- else
- {
- //! first attack in raised erc (light or heavy if modifier is used). Also added support for finishers
- if (pMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_RAISEDERECT)
- {
- return HandleInitialMeleeErc(pCurrentCommandID, pInputs, itemInHands, pMovementState, pContinueAttack);
- }
- //! kick from raised pne
- else if (pMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_RAISEDPRONE)
- {
- return HandleProneKick(pCurrentCommandID, pInputs, itemInHands, pMovementState, pContinueAttack);
- }
- //! sprint attack in erc stance
- else if (pMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_ERECT && m_Player.IsSprintFull())
- {
- return HandleSprintAttack(pCurrentCommandID, pInputs, itemInHands, pMovementState, pContinueAttack);
- }
- }
- }
- //! combo hits - when we are already in Melee command and clicking UseButton
- else if (pCurrentCommandID == DayZPlayerConstants.COMMANDID_MELEE2)
- {
- m_IsInComboRange = m_Player.GetCommand_Melee2().IsInComboRange();
- if (m_IsInComboRange)
- {
- return HandleComboHit(pCurrentCommandID, pInputs, itemInHands, pMovementState, pContinueAttack);
- }
- }
- }
- //! evade and blocking logic
- else if (!isFireWeapon && pCurrentCommandID == DayZPlayerConstants.COMMANDID_MOVE)
- {
- //! evades in raised erc stance while moving
- if (pMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_RAISEDERECT)
- {
- int roll = pInputs.IsMeleeLREvade();
- if (roll != 0)
- {
- //! not enough stamina to do evades
- if (!m_Player.CanConsumeStamina(EStaminaConsumers.MELEE_EVADE))
- {
- return false;
- }
-
- float angle;
- if (roll == 1)
- {
- angle = -90; // left
- }
- else
- {
- angle = 90; // right
- }
-
- // start melee evade
- m_IsEvading = true;
- SetCooldown(EVADE_COOLDOWN, EFightLogicCooldownCategory.EVADE);
- hcm.StartMeleeEvadeA(angle);
- m_Player.DepleteStamina(EStaminaModifiers.MELEE_EVADE);
-
- //Inflict shock when sidestepping with broken legs
- if (m_Player.GetBrokenLegs() == eBrokenLegs.BROKEN_LEGS)
- {
- m_Player.m_ShockHandler.SetShock(PlayerConstants.BROKEN_LEGS_LIGHT_MELEE_SHOCK);
- m_Player.m_ShockHandler.CheckValue(true);
- }
- }
- }
- //! stand up when crouching and raised pressed
- if (pInputs.IsWeaponRaised() && pMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_CROUCH)
- {
- //Debug.MeleeLog(m_Player, "HandleFightLogic[2b]");
- if (DayZPlayerUtils.PlayerCanChangeStance(m_Player, DayZPlayerConstants.STANCEIDX_RAISEDERECT))
- {
- //Debug.MeleeLog(m_Player, "HandleFightLogic[2c]");
- hcm.ForceStance(DayZPlayerConstants.STANCEIDX_RAISEDERECT);
-
- return false;
- }
- }
- //! blocks in raised erc/pro stance
- //! (bare hand or with melee weapon only)
- if (!isFireWeapon && (pMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_RAISEDERECT || pMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_RAISEDPRONE))
- {
- float angle2;
- if (hcm.GetCurrentInputAngle(angle2) && (angle2 < -130.0 || angle2 > 130))
- {
- hcm.SetMeleeBlock(true);
- SetBlock(true);
- }
- else
- {
- hcm.SetMeleeBlock(false);
- SetBlock(false);
- }
- }
- else
- {
- hcm.SetMeleeBlock(false);
- SetBlock(false);
- }
- }
- return false;
- }
- //! Handle the event that our melee hit something
- protected bool HandleHitEvent(int pCurrentCommandID, HumanInputController pInputs, InventoryItem itemInHands, HumanMovementState pMovementState, out bool pContinueAttack)
- {
- //! Check if we need to damage
- if (pCurrentCommandID == DayZPlayerConstants.COMMANDID_MELEE2)
- {
- HumanCommandMelee2 hmc2a = m_Player.GetCommand_Melee2();
- if (hmc2a)
- {
- //! on anim event Hit received
- if (hmc2a.WasHit())
- {
- //Debug.MeleeLog(m_Player, "HandleHitEvent[START]");
- //Debug.MeleeLog(m_Player, string.Format("HandleHitEvent[1] target=%1, hitPos=%2, hitZoneIdx=%3, finisherType=%4", m_MeleeCombat.GetTargetEntity(), m_MeleeCombat.GetHitPos().ToString(), m_MeleeCombat.GetHitZoneIdx(), m_MeleeCombat.GetFinisherType()));
- if (m_MeleeCombat.GetFinisherType() == -1)
- {
- //Debug.MeleeLog(m_Player, string.Format("HandleHitEvent[2] target=%1, hitPos=%2, hitZoneIdx=%3, finisherType=%4", m_MeleeCombat.GetTargetEntity(), m_MeleeCombat.GetHitPos().ToString(), m_MeleeCombat.GetHitZoneIdx(), m_MeleeCombat.GetFinisherType()));
- //! re-target (enemy can have moved out of range or disappeared)
- m_MeleeCombat.Update(itemInHands, m_HitType, true);
- }
- //! evaluate hit - selection of cfg 'ammo' type
- EvaluateHit(itemInHands);
-
- //Get gloves
- ClothingBase gloves;
- if (m_HitType == EMeleeHitType.KICK)
- {
- //We kick so "gloves" will be the shoes
- gloves = ClothingBase.Cast(m_Player.GetItemOnSlot("FEET"));
- }
- else
- {
- gloves = ClothingBase.Cast(m_Player.GetItemOnSlot("GLOVES"));
- }
-
- //If we hit something, inflict damage
- DamageHands(m_Player, gloves, itemInHands);
-
- m_MeleeCombat.ResetTarget();
-
- EnableControls();
-
- m_WasPreviousHitProcessed = true;
-
- //Debug.MeleeLog(m_Player, "HandleHitEvent[END]");
-
- return true;
- }
- }
- }
-
- return false;
- }
-
- //! NOTE: Only singular (or first) hits, combo attacks are handled in combo
- protected bool HandleInitialFirearmMelee(int pCurrentCommandID, HumanInputController pInputs, InventoryItem itemInHands, HumanMovementState pMovementState, out bool pContinueAttack)
- {
- //! don't allow bash to interfere with actions like chambering or ejecting bullets
- Weapon_Base weapon = Weapon_Base.Cast(itemInHands);
- if (weapon.IsWaitingForActionFinish())
- return false;
-
- HumanCommandMove hcm = m_Player.GetCommand_Move();
-
- //! perform firearm melee from raised erect or continue with attack after character stand up from crouch
- if (hcm.GetCurrentMovementSpeed() <= 2.05 && (pMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_RAISEDERECT || pContinueAttack) && !m_Player.IsFighting())
- {
- m_HitType = GetAttackTypeByWeaponAttachments(itemInHands);
- if ( m_HitType == EMeleeHitType.NONE )
- {
- pContinueAttack = false;
- return false; //! exit if there is no suitable attack
- }
-
- m_MeleeCombat.Update(itemInHands, m_HitType);
- EntityAI target;
- EMeleeTargetType targetType;
- GetTargetData(target, targetType);
- float attackByDistance = GetAttackTypeByDistanceToTarget(target, targetType);
- m_Player.StartCommand_Melee2(target, m_HitType == EMeleeHitType.WPN_STAB, attackByDistance, m_MeleeCombat.GetHitPos());
- m_Player.DepleteStamina(EStaminaModifiers.MELEE_HEAVY);
- DisableControls();
- pContinueAttack = false; // reset continueAttack flag
- return true;
- }
- //! char stand up when performing firearm melee from crouch
- else if ( pMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_RAISEDCROUCH )
- {
- if (hcm)
- {
- hcm.ForceStance(DayZPlayerConstants.STANCEIDX_RAISEDERECT);
- pContinueAttack = true;
- return false;
- }
- }
-
- return false;
- }
-
- //! First attack in raised erc (light or heavy if modifier is used). Also added support for finishers
- protected bool HandleInitialMeleeErc(int pCurrentCommandID, HumanInputController pInputs, InventoryItem itemInHands, HumanMovementState pMovementState, out bool pContinueAttack)
- {
- //Debug.MeleeLog(m_Player, "HandleInitialMeleeErc[1]");
-
- m_HitType = GetAttackTypeFromInputs(pInputs);
- m_MeleeCombat.Update(itemInHands, m_HitType);
-
- //Debug.MeleeLog(m_Player, string.Format("HandleInitialMeleeErc[2] %1", EnumTools.EnumToString(EMeleeHitType, m_HitType)));
-
- EntityAI target;
- EMeleeTargetType targetType;
- GetTargetData(target, targetType);
- float attackByDistance = GetAttackTypeByDistanceToTarget(target, targetType);
-
- // finisher attack hittype override
- int finisherType = m_MeleeCombat.GetFinisherType();
- if (finisherType != -1)
- {
- int animationType = DetermineFinisherAnimation(finisherType);
- if (animationType > -1)
- {
- //Debug.MeleeLog(m_Player, string.Format("HandleInitialMeleeErc[3a] target=%1, finisherType=%2, animationType=%3, hitPositionWS=%4", target, finisherType, animationType, m_MeleeCombat.GetHitPos().ToString()));
- m_Player.StartCommand_Melee2(target, animationType, attackByDistance, m_MeleeCombat.GetHitPos());
- }
- else
- {
- //Debug.MeleeLog(m_Player, string.Format("HandleInitialMeleeErc[3b] target=%1, finisherType=%2, animationType=%3, hitPositionWS=%4", target, finisherType, (m_HitType == EMeleeHitType.HEAVY).ToString(), m_MeleeCombat.GetHitPos().ToString()));
- m_Player.StartCommand_Melee2(target, m_HitType == EMeleeHitType.HEAVY, attackByDistance, m_MeleeCombat.GetHitPos());
- }
-
- m_HitType = finisherType;
- target.SetBeingBackstabbed(finisherType);
- }
- else
- {
- //Debug.MeleeLog(m_Player, string.Format("HandleInitialMeleeErc[3d] target=%1, animationType=%2, hitPositionWS=%3", target, (m_HitType == EMeleeHitType.HEAVY).ToString(), m_MeleeCombat.GetHitPos().ToString()));
- m_Player.StartCommand_Melee2(target, m_HitType == EMeleeHitType.HEAVY, attackByDistance, m_MeleeCombat.GetHitPos());
- }
-
- if (m_HitType == EMeleeHitType.HEAVY)
- {
- m_Player.DepleteStamina(EStaminaModifiers.MELEE_HEAVY);
- if (m_Player.GetBrokenLegs() == eBrokenLegs.BROKEN_LEGS)
- {
- m_Player.m_ShockHandler.SetShock(PlayerConstants.BROKEN_LEGS_HEAVY_MELEE_SHOCK);
- m_Player.m_ShockHandler.CheckValue(true);
- }
- }
- else
- {
- m_Player.DepleteStamina(EStaminaModifiers.MELEE_LIGHT);
- if (m_Player.GetBrokenLegs() == eBrokenLegs.BROKEN_LEGS)
- {
- m_Player.m_ShockHandler.SetShock(PlayerConstants.BROKEN_LEGS_LIGHT_MELEE_SHOCK);
- m_Player.m_ShockHandler.CheckValue(true);
- }
- }
- m_WasPreviousHitProcessed = false;
-
- DisableControls();
-
- return true;
- }
-
- //! kick from raised pne
- protected bool HandleProneKick(int pCurrentCommandID, HumanInputController pInputs, InventoryItem itemInHands, HumanMovementState pMovementState, out bool pContinueAttack)
- {
- HumanCommandWeapons hcw = m_Player.GetCommandModifier_Weapons();
- float hcw_angle = hcw.GetBaseAimingAngleLR();
- //! check if player is on back
- //! (situation where the player is raised in prone and on back is not in anim graph)
- if ( ( hcw_angle < -90 || hcw_angle > 90 ) && m_Player.GetBrokenLegs() != eBrokenLegs.BROKEN_LEGS )
- {
- // targetting
- m_HitType = EMeleeHitType.KICK;
- m_MeleeCombat.Update(itemInHands, m_HitType);
- EntityAI target;
- EMeleeTargetType targetType;
- GetTargetData(target, targetType);
- float attackByDistance = GetAttackTypeByDistanceToTarget(target, targetType);
- // command
- m_Player.StartCommand_Melee2(target, false, attackByDistance, m_MeleeCombat.GetHitPos());
- m_Player.DepleteStamina(EStaminaModifiers.MELEE_HEAVY);
- DisableControls();
-
- return true;
- }
-
- return false;
- }
-
- //! sprint attack in erc stance
- protected bool HandleSprintAttack(int pCurrentCommandID, HumanInputController pInputs, InventoryItem itemInHands, HumanMovementState pMovementState, out bool pContinueAttack)
- {
- //! targetting
- m_HitType = EMeleeHitType.SPRINT;
- m_MeleeCombat.Update(itemInHands, m_HitType);
- EntityAI target;
- EMeleeTargetType targetType;
- GetTargetData(target, targetType);
- float attackByDistance = GetAttackTypeByDistanceToTarget(target, targetType);
- //! command
- //Debug.MeleeLog(m_Player, string.Format("HandleSprintAttack[1] target=%1, animationType=%2, hitPositionWS=%3", target, false, m_MeleeCombat.GetHitPos().ToString()));
- m_Player.StartCommand_Melee2(target, false, attackByDistance, m_MeleeCombat.GetHitPos());
- m_Player.DepleteStamina(EStaminaModifiers.MELEE_HEAVY);
- DisableControls();
- return true;
- }
-
- //! combo hits - when we are already in Melee command and clicking UseButton
- protected bool HandleComboHit(int pCurrentCommandID, HumanInputController pInputs, InventoryItem itemInHands, HumanMovementState pMovementState, out bool pContinueAttack)
- {
- //Debug.MeleeLog(m_Player, "HandleComboHit::");
- m_IsInComboRange = false;
-
- //! wait for the previous hit commit before hitting again
- if (!m_WasPreviousHitProcessed)
- return false;
-
- //! select if the next attack will be light or heavy (based on input/attachment modifier)
- if (itemInHands && itemInHands.IsWeapon())
- m_HitType = GetAttackTypeByWeaponAttachments(itemInHands);
- else
- m_HitType = GetAttackTypeFromInputs(pInputs);
- //! no suitable attack - skip that
- if (m_HitType == EMeleeHitType.NONE)
- return false;
-
- //! No combos for the finisher command
- if (m_MeleeCombat.GetFinisherType() > -1)
- return false;
-
- EntityAI target;
- EMeleeTargetType targetType;
- GetTargetData(target, targetType);
- float attackByDistance = GetAttackTypeByDistanceToTarget(target, targetType);
- //! targetting
- //Debug.MeleeLog(m_Player, string.Format("HandleComboHit:: %1", EnumTools.EnumToString(EMeleeHitType, m_HitType)));
- m_MeleeCombat.Update(itemInHands, m_HitType);
- //! continue 'combo' - left hand attacks
- bool isHeavy = (m_HitType == EMeleeHitType.HEAVY || m_HitType == EMeleeHitType.WPN_STAB);
- m_Player.GetCommand_Melee2().ContinueCombo(isHeavy, attackByDistance, target, m_MeleeCombat.GetHitPos());
- DisableControls();
-
- //! broken legs shock
- if (m_Player.GetBrokenLegs() == eBrokenLegs.BROKEN_LEGS)
- {
- float shock = PlayerConstants.BROKEN_LEGS_HEAVY_MELEE_SHOCK;
-
- if (!isHeavy)
- shock = PlayerConstants.BROKEN_LEGS_LIGHT_MELEE_SHOCK;
-
- m_Player.m_ShockHandler.SetShock(PlayerConstants.BROKEN_LEGS_HEAVY_MELEE_SHOCK);
- m_Player.m_ShockHandler.CheckValue(true);
- }
- //! stamina depletion per attack
- switch (m_HitType)
- {
- case EMeleeHitType.HEAVY:
- case EMeleeHitType.SPRINT:
- case EMeleeHitType.WPN_STAB:
- case EMeleeHitType.WPN_HIT_BUTTSTOCK:
- case EMeleeHitType.WPN_HIT:
- m_Player.DepleteStamina(EStaminaModifiers.MELEE_HEAVY);
- break;
- default:
- m_Player.DepleteStamina(EStaminaModifiers.MELEE_LIGHT);
- break;
- }
- return true;
- }
- protected void EvaluateHit(InventoryItem weapon)
- {
- EntityAI target = m_MeleeCombat.GetTargetEntity();
-
- if (target)
- {
- if (target.IsInherited(DayZPlayer))
- {
- EvaluateHit_Player(weapon, target);
- }
- else if (target.IsInherited(DayZInfected))
- {
- EvaluateHit_Infected(weapon, target);
- }
- else if (target.GetMeleeTargetType() == EMeleeTargetType.NONALIGNABLE)
- {
- EvaluateHit_NonAlignableObjects(weapon, target);
- }
- else
- {
- EvaluateHit_Common(weapon, target);
- }
-
- m_MeleeCombat.CheckMeleeItem();
- }
- }
- protected void EvaluateHit_Player(InventoryItem weapon, Object target)
- {
- int hitZoneIdx = m_MeleeCombat.GetHitZoneIdx();
- int weaponMode = m_MeleeCombat.GetWeaponMode();
- int forcedWeaponMode = -1;
- vector hitPosWS;
- bool forcedDummy = false;
- PlayerBase targetPlayer = PlayerBase.Cast(target);
- //! Melee Hit/Impact modifiers
- if (targetPlayer)
- {
- vector targetPos = targetPlayer.GetPosition();
- vector agressorPos = m_Player.GetPosition();
-
- // We get the angle from which an infected hit the blocking player
- float hitAngle = Math.RAD2DEG * Math.AbsFloat(Math3D.AngleFromPosition(targetPos, MiscGameplayFunctions.GetHeadingVector(targetPlayer), agressorPos));
-
- //! if the oponnent is in Melee Block shift the damage down
- if (targetPlayer.GetMeleeFightLogic() && targetPlayer.GetMeleeFightLogic().IsInBlock() && hitAngle <= GameConstants.PVP_MAX_BLOCKABLE_ANGLE)
- {
- if (weaponMode > 0)
- {
- forcedWeaponMode = --weaponMode; // Heavy -> Light shift
- }
- else
- forcedDummy = true; // dummy hits, cannot shift lower than 0
- }
- }
- EvaluateHit_Common(weapon, target, forcedDummy, forcedWeaponMode);
- }
-
- protected void EvaluateHit_Infected(InventoryItem weapon, Object target)
- {
- //If the finisher attack haven't been performed, then use normal hit
- if (!EvaluateFinisherAttack(weapon, target))
- EvaluateHit_Common(weapon, target);
- }
-
- //! Check and evaluate stealth kill, if applicable
- protected bool EvaluateFinisherAttack(InventoryItem weapon, Object target)
- {
- //Debug.MeleeLog(m_Player, string.Format("EvaluateFinisherAttack[1] target=%1, hitPos=%2, hitZoneIdx=%3, finisherType=%4", m_MeleeCombat.GetTargetEntity(), m_MeleeCombat.GetHitPos().ToString(), m_MeleeCombat.GetHitZoneIdx(), m_MeleeCombat.GetFinisherType()));
-
- if (m_MeleeCombat.GetFinisherType() > -1)
- {
- if (GetGame().IsServer())
- DamageSystem.CloseCombatDamage(m_Player, target, m_MeleeCombat.GetHitZoneIdx(), DetermineFinisherAmmo(m_MeleeCombat.GetFinisherType()), m_MeleeCombat.GetHitPos(), ProcessDirectDamageFlags.NO_ATTACHMENT_TRANSFER);
-
- return true;
- }
- return false;
- }
-
- protected void EvaluateHit_Common(InventoryItem weapon, Object target, bool forcedDummy=false, int forcedWeaponMode = -1)
- {
- int hitZoneIdx = m_MeleeCombat.GetHitZoneIdx();
- int weaponMode = m_MeleeCombat.GetWeaponMode();
- vector hitPosWS;
- string ammo;
-
- if (forcedWeaponMode > -1)
- weaponMode = forcedWeaponMode;
- EntityAI targetEntity = EntityAI.Cast(target);
- //! check if we need to use dummy hit
- if (!DummyHitSelector(m_HitType, ammo) && !forcedDummy)
- {
- //! normal hit with applied damage to targeted component
- if (hitZoneIdx >= 0)
- {
- hitPosWS = targetEntity.ModelToWorld(targetEntity.GetDefaultHitPosition());
-
- if (WeaponDestroyedCheck(weapon, ammo))
- {
- DamageSystem.CloseCombatDamage(m_Player, target, hitZoneIdx, ammo, hitPosWS);
- //Debug.MeleeLog(m_Player, string.Format("EvaluateHit_Common[a]::CloseCombatDamage:: target: %1, hitzone: %2, ammo: %3", target, hitZoneIdx, ammo));
- }
- else
- {
- m_Player.ProcessMeleeHit(weapon, weaponMode, target, hitZoneIdx, hitPosWS);
- //Debug.MeleeLog(m_Player, string.Format("EvaluateHit_Common[b]::ProcessMeleeHit:: target: %1, hitzone: %2, meleeMode: %3, forcedWeaponMode:%4", target, hitZoneIdx, weaponMode));
- }
- }
- }
- else
- {
- //! play hit animation for dummy hits
- if (GetGame().IsServer() && targetEntity)
- {
- DummyHitSelector(m_HitType, ammo);
- hitPosWS = targetEntity.ModelToWorld(targetEntity.GetDefaultHitPosition()); //! override hit pos by pos defined in type
- DamageSystem.CloseCombatDamage(m_Player, target, hitZoneIdx, ammo, hitPosWS);
- //Debug.MeleeLog(m_Player, string.Format("EvaluateHit_Common[c]::CloseCombatDamage:: target: %1, hitzone: %2, meleeMode: %3, ammo: %4", target, hitZoneIdx, weaponMode, ammo));
- }
- }
- }
- protected void EvaluateHit_NonAlignableObjects(InventoryItem weapon, Object target)
- {
- int hitZoneIdx = m_MeleeCombat.GetHitZoneIdx();
- vector hitPosWS;
- string ammo;
-
- if (hitZoneIdx >= 0)
- {
- if (WeaponDestroyedCheck(weapon,ammo))
- DamageSystem.CloseCombatDamage(m_Player, target, hitZoneIdx, ammo, m_MeleeCombat.GetHitPos());
- else
- m_Player.ProcessMeleeHit(weapon, m_MeleeCombat.GetWeaponMode(), target, hitZoneIdx, m_MeleeCombat.GetHitPos());
- }
- return;
- }
-
- bool WeaponDestroyedCheck(InventoryItem weapon, out string ammo)
- {
- if (!weapon)
- return false;
-
- Weapon_Base firearm = Weapon_Base.Cast(weapon);
- ItemBase bayonet = ItemBase.Cast(weapon.GetInventory().FindAttachment(weapon.GetBayonetAttachmentIdx()));
-
- if ( firearm && bayonet && bayonet.IsRuined() )
- {
- ammo = bayonet.GetRuinedMeleeAmmoType();
- return true;
- }
- else if (weapon.IsRuined())
- {
- ammo = weapon.GetRuinedMeleeAmmoType();
- return true;
- }
- else
- {
- return false;
- }
- }
- protected void GetTargetData(out EntityAI target, out EMeleeTargetType targetType)
- {
- target = m_MeleeCombat.GetTargetEntity();
- targetType = EMeleeTargetType.ALIGNABLE; //! default
-
- // If there is no hitzone defined, then we won't be able to hit the target anyways..
- if (m_MeleeCombat.GetHitZoneIdx() < 0)
- {
- target = null;
- }
-
- if ( target )
- {
- targetType = target.GetMeleeTargetType();
- }
- //! nullify target for nonalignable objects (big objects)
- if ( targetType == EMeleeTargetType.NONALIGNABLE )
- {
- target = null;
- }
- }
- //! evaluation of hit player vs. player
- protected bool DummyHitSelector(EMeleeHitType hitType, out string ammoType)
- {
- switch (hitType)
- {
- //! in case of kick (on back or push from erc) change the ammo type to dummy
- case EMeleeHitType.KICK:
- ammoType = DUMMY_HEAVY_AMMO;
- return true;
- break;
- }
-
- ammoType = DUMMY_LIGHT_AMMO;
-
- return false;
- }
-
- //! DEPRECATED - moved into DayZPlayerImplementMeleeCombat
- protected bool IsBehindEntity(int angle, DayZPlayer source, Object target)
- {
- return false;
- }
- protected void SetCooldown(float time, EFightLogicCooldownCategory cooldownCategory)
- {
- //! stops currently running cooldown timer (for specific category)
- if ( m_CooldownTimers.Get(cooldownCategory).IsRunning() )
- {
- m_CooldownTimers.Get(cooldownCategory).Stop();
- }
-
- //! param for ResetCooldown
- Param1<int> param = new Param1<int>(cooldownCategory);
- m_CooldownTimers.Get(cooldownCategory).Run(time, this, "ResetCooldown", param);
- }
-
- protected void ResetCooldown(EFightLogicCooldownCategory cooldownCategory)
- {
- switch (cooldownCategory)
- {
- case EFightLogicCooldownCategory.EVADE:
- m_IsEvading = false;
- break;
- }
- }
- protected void EnableControls();
- protected void DisableControls();
-
- protected void DamageHands(DayZPlayer DZPlayer, ClothingBase gloves, InventoryItem itemInHands)
- {
- EntityAI target = m_MeleeCombat.GetTargetEntity();
-
- //We did not hit anything
- if (itemInHands || !target || !DZPlayer)
- return;
-
- //Check if server side
- if (GetGame().IsServer())
- {
- int randNum;
-
- //If gloves, damage gloves
- if (gloves && gloves.GetHealthLevel() < GameConstants.STATE_RUINED)
- {
- gloves.DecreaseHealth("", "", 1);
- }
- else
- {
- //Do not add bleeding if hitting player, zombie or animal
- if (PlayerBase.Cast(target) || DayZCreatureAI.Cast(target))
- return;
-
- BleedingSourcesManagerServer bleedingManager;
-
- //We don't inflict bleeding to hands when kicking
- if (m_HitType != EMeleeHitType.KICK)
- {
- //Random bleeding source
- randNum = Math.RandomIntInclusive(1, 15);
- switch (randNum)
- {
- case 1:
- if (m_Player)
- {
- bleedingManager = m_Player.GetBleedingManagerServer();
- if (bleedingManager)
- bleedingManager.AttemptAddBleedingSourceBySelection("RightForeArmRoll");
- }
- break;
-
- case 2:
- if (m_Player)
- {
- bleedingManager = m_Player.GetBleedingManagerServer();
- if (bleedingManager)
- bleedingManager.AttemptAddBleedingSourceBySelection("LeftForeArmRoll");
- }
- break;
- }
- }
- else
- {
- //Random bleeding source
- randNum = Math.RandomIntInclusive(1, 15);
- //We only add bleeding to left foot as character kicks with left foot
- switch (randNum)
- {
- case 1:
- if (m_Player)
- {
- bleedingManager = m_Player.GetBleedingManagerServer();
- if (bleedingManager)
- bleedingManager.AttemptAddBleedingSourceBySelection("LeftToeBase");
- }
- break;
-
- case 2:
- if (m_Player)
- {
- bleedingManager = m_Player.GetBleedingManagerServer();
- if (bleedingManager)
- bleedingManager.AttemptAddBleedingSourceBySelection("LeftFoot");
- }
- break;
- }
- }
- }
- }
- }
-
- //! Picks a specific finisher animation. Not used for mounted bayonet stabs
- int DetermineFinisherAnimation(int finisher_type)
- {
- int animation = -1;
-
- switch (finisher_type)
- {
- case EMeleeHitType.FINISHER_LIVERSTAB:
- animation = HumanCommandMelee2.HIT_TYPE_FINISHER;
- break;
-
- case EMeleeHitType.FINISHER_NECKSTAB:
- animation = HumanCommandMelee2.HIT_TYPE_FINISHER_NECK;
- break;
- }
-
- return animation;
- }
-
- //! Picks a specific finisher ammo fot the hit type. This gets synchronized and guides further behaviour of the target.
- string DetermineFinisherAmmo(int finisher_type)
- {
- string ret = "";
-
- switch (finisher_type)
- {
- case EMeleeHitType.FINISHER_NECKSTAB:
- ret = "FinisherHitNeck";
- break;
-
- default:
- ret = "FinisherHit";
- break;
- }
- return ret;
- }
- protected bool IsShortDistance(EntityAI pTarget, float pDistanceSq)
- {
- return pTarget && vector.DistanceSq(m_Player.GetPosition(), m_MeleeCombat.GetHitPos()) <= pDistanceSq || vector.DistanceSq(m_Player.GetBonePositionWS(m_Player.GetBoneIndexByName("Head")), m_MeleeCombat.GetHitPos()) <= pDistanceSq)
- }
- //!
- //! DEPRECATED
- protected DayZPlayerImplement m_DZPlayer;
- protected bool m_IsFinisher;
-
- int GetFinisherType(InventoryItem weapon, EntityAI target)
- {
- return -1;
- }
-
- bool IsHitTypeFinisher(int type)
- {
- return false;
- }
-
- int DetermineSpecificFinisherType(ItemBase weapon, int component)
- {
- return -1;
- }
- }
|