Пример #1
0
    private bool CanBlockAttack(PlayerBaseAttackLogic attackLogic)
    {
        if (attackLogic is PlayerProjectileAttackLogic projectileAttack)
        {
            if (projectileAttack.IsGuardCrush())
            {
                return(false);
            }
        }

        if (IsBlockingAllAttacks())
        {
            SetupStanceToBlockAttack(attackLogic);
            return(true);
        }
        else
        {
            bool canBlockAttack = IsInBlockingStance_Internal();
            if (canBlockAttack && m_MovementComponent)
            {
                //Check if the player is in the right stance for this attack
                bool isCrouching = m_MovementComponent.IsCrouching();
                canBlockAttack &= attackLogic.CanAttackBeBlocked(isCrouching);

                if (!canBlockAttack && m_StunInfoSC.IsInAutoBlockingState())
                {
                    SetupStanceToBlockAttack(attackLogic);
                    canBlockAttack = true;
                }
            }

            return(canBlockAttack);
        }
    }
Пример #2
0
    void OnGrabTry(BaseEventParameters baseParams)
    {
        if (IsDead())
        {
            return;
        }

        GrabTryEventParameters grabTryParams   = (GrabTryEventParameters)baseParams;
        PlayerBaseAttackLogic  grabAttackLogic = grabTryParams.m_AttackLogic;

        ChronicleManager.AddChronicle(gameObject, EChronicleCategory.Health, "On grab try");

        if (CanBlockGrabAttack(grabAttackLogic))
        {
            // Here, both players are currently playing grab attack
            // But one is the attacker, and the second the defender
            // Only the defender can trigger GrabBlocked event and start a block animation
            // If the player who's trying to grab is the first one to have triggered the grab attack, he's the attacker, so we can block it
            if (IsGrabAttacker(grabAttackLogic))
            {
                ChronicleManager.AddChronicle(gameObject, EChronicleCategory.Health, "On grab blocked");

                Utils.GetEnemyEventManager(gameObject).TriggerEvent(EPlayerEvent.GrabBlocked, new GrabBlockedEventParameters(grabAttackLogic));
                m_StunInfoSC.StartStun(grabAttackLogic, EAttackResult.Blocked);
                PlayBlockAnimation(grabAttackLogic);
            }
        }
        else if (!m_StunInfoSC.IsHitStunned() && !m_StunInfoSC.IsBlockStunned() && !m_MovementComponent.IsJumping()) // A grab can't touch if player is stunned or is jumping
        {
            ChronicleManager.AddChronicle(gameObject, EChronicleCategory.Health, "On grab touched");

            Utils.GetEnemyEventManager(gameObject).TriggerEvent(EPlayerEvent.GrabTouched, new GrabTouchedEventParameters(grabAttackLogic));
        }
    }
Пример #3
0
    private void TriggerHitFX(PlayerBaseAttackLogic attackLogic, Vector3 hitPoint, EAttackResult attackResult, EHitNotificationType hitNotificationType)
    {
        Profiler.BeginSample("PlayerHealthComponent.TriggerHitFX");

        m_HitFXTypeList.Clear();
        attackLogic.GetHitFX(attackResult, hitNotificationType, ref m_HitFXTypeList);
        if (m_HitFXTypeList.Count > 0)
        {
            bool       flipHitFX;
            Collider2D lastHitCollider = attackLogic.GetLastHitCollider();
            if (lastHitCollider != null)
            {
                Transform hitOwner = lastHitCollider.transform.root;
                flipHitFX = hitOwner.position.x < transform.position.x;
            }
            else
            {
                flipHitFX = attackLogic.GetOwner().transform.position.x < transform.position.x;
            }

            int playerIndex = m_InfoComponent.GetPlayerIndex();
            for (int i = 0; i < m_HitFXTypeList.Count; i++)
            {
                m_FXManager.SpawnHitFX(playerIndex, m_HitFXTypeList[i], hitPoint, Quaternion.identity, flipHitFX);
            }
        }

        Profiler.EndSample();
    }
Пример #4
0
    public virtual bool EvaluateConditions(PlayerBaseAttackLogic currentAttackLogic)
    {
        bool conditionIsValid = true;

        PlayerAttack attack = GetAttack();

        if (m_MovementComponent != null)
        {
            conditionIsValid &= (attack.m_NeededStanceList.Contains(m_MovementComponent.GetCurrentStance()));
        }

        if (attack.m_HasCondition)
        {
            if (attack.m_SuperGaugeAmountNeeded > 0f)
            {
                PlayerSuperGaugeSubComponent superGaugeSC = m_AttackComponent.GetSuperGaugeSubComponent();
                if (superGaugeSC != null)
                {
                    conditionIsValid &= superGaugeSC.GetCurrentGaugeValue() >= attack.m_SuperGaugeAmountNeeded;
                }
            }

            if (attack.m_HasAttackRequirement)
            {
                conditionIsValid &= (currentAttackLogic != null && currentAttackLogic.GetAttack().m_AnimationAttackName == attack.m_AttackRequired);
            }

            if (attack.m_HasMovementRequirement)
            {
                conditionIsValid &= attack.m_MovementRequiredList.Contains(m_MovementComponent.GetMovingDirection());
            }
        }

        return(conditionIsValid);
    }
Пример #5
0
    private void PlayBlockAnimation(PlayerBaseAttackLogic attackLogic)
    {
        //Play block anim
        string blockAnimName = attackLogic.GetBlockAnimName(m_MovementComponent.GetCurrentStance(), EStunAnimState.In);

        m_Anim.Play(blockAnimName, 0, 0);
    }
Пример #6
0
    private void OnDamageTaken(PlayerBaseAttackLogic attackLogic, uint damage, EAttackResult attackResult, EHitNotificationType hitNotificationType)
    {
        Profiler.BeginSample("PlayerHealthComponent.OnDamageTaken");

#if DEBUG_DISPLAY || UNITY_EDITOR
        KakutoDebug.Log("Player : " + gameObject.name + " HP : " + m_HP + " damage taken : " + damage + " attack " + attackResult.ToString());
#endif
        ChronicleManager.AddChronicle(gameObject, EChronicleCategory.Health, "On damage taken : " + damage + ", current HP : " + m_HP);

        DamageTakenEventParameters damageTakenInfo = new DamageTakenEventParameters(gameObject, attackLogic, attackResult, m_StunInfoSC.IsHitStunned(), damage, (float)m_HP / (float)m_HealthConfig.m_MaxHP, hitNotificationType);
        Utils.GetPlayerEventManager(gameObject).TriggerEvent(EPlayerEvent.DamageTaken, damageTakenInfo);

        if (!IsDead() && attackLogic.CanPlayDamageTakenAnim())
        {
            PlayDamageTakenAnim(attackLogic, attackResult);
        }

        TriggerEffects(attackLogic, damage, attackResult, hitNotificationType);

        if (damage > 0 && m_InfoComponent.GetPlayerSettings().m_DisplayDamageTaken)
        {
            DisplayDamageTakenUI(damage);
        }

        if (IsDead())
        {
            OnDeath(attackLogic);
        }
        Profiler.EndSample();
    }
Пример #7
0
    protected override void Awake()
    {
        base.Awake();
#if UNITY_EDITOR
        if (m_HealthComponent == null)
        {
            KakutoDebug.LogError("Missing HealthComponent in " + this);
        }
        if (m_Controller == null)
        {
            KakutoDebug.LogError("Missing CharacterController2D in " + this);
        }
        if (m_AttackComponent == null)
        {
            KakutoDebug.LogError("Missing AttackComponent in " + this);
        }
        if (m_Rigidbody == null)
        {
            KakutoDebug.LogError("Missing Rigidbody in " + this);
        }
#endif

        m_CurrentAttack = null;
        RegisterListeners();
    }
Пример #8
0
 void OnEndOfAttack(BaseEventParameters baseParams)
 {
     EndOfAttackEventParameters endOfAttackEvent = (EndOfAttackEventParameters)baseParams;
     if (m_AttackComponent.GetCurrentAttackLogic() == null || m_AttackComponent.CheckIsCurrentAttack(endOfAttackEvent.m_Attack))
     {
         m_CurrentAttack = null;
     }
 }
Пример #9
0
 public DamageTakenEventParameters(GameObject victim, PlayerBaseAttackLogic attackLogic, EAttackResult attackResult, bool isAlreadyHitStunned, uint damage, float healthRatio, EHitNotificationType hitNotif)
 {
     m_Victim              = victim;
     m_AttackLogic         = attackLogic;
     m_AttackResult        = attackResult;
     m_DamageTaken         = damage;
     m_HealthRatio         = healthRatio;
     m_IsAlreadyHitStunned = isAlreadyHitStunned;
     m_HitNotificationType = hitNotif;
 }
Пример #10
0
    void OnAttackLaunched(BaseEventParameters baseParams)
    {
        AttackLaunchedEventParameters attackLaunchedParams = (AttackLaunchedEventParameters)baseParams;

        m_CurrentAttack = null;
        if(attackLaunchedParams.m_AttackLogic.NeedPushBoxCollisionCallback())
        {
            m_CurrentAttack = attackLaunchedParams.m_AttackLogic;
        }   
    }
Пример #11
0
    public override bool EvaluateConditions(PlayerBaseAttackLogic currentAttackLogic)
    {
        bool conditionIsValid = base.EvaluateConditions(currentAttackLogic);

        if (conditionIsValid)
        {
            conditionIsValid &= GetTriggerPointStatus(m_InfoComponent.GetPlayerIndex()) == ETriggerPointStatus.Active && CheckConditionsInternal();
        }

        return(conditionIsValid);
    }
Пример #12
0
    public override bool EvaluateConditions(PlayerBaseAttackLogic currentAttackLogic)
    {
        bool conditionIsValid = base.EvaluateConditions(currentAttackLogic);

        if (conditionIsValid)
        {
            conditionIsValid &= ConditionIsValid();
        }

        return(conditionIsValid);
    }
Пример #13
0
    void OnAttackLaunched(BaseEventParameters baseParams)
    {
        AttackLaunchedEventParameters attackLaunchedParams = (AttackLaunchedEventParameters)baseParams;

        // PlayerProjectileAttackLogic will be handled by ProjectileProximityBoxHandler
        if (attackLaunchedParams.m_AttackLogic is PlayerProjectileAttackLogic)
        {
            return;
        }
        m_CurrentAttack = attackLaunchedParams.m_AttackLogic;
    }
Пример #14
0
 void OnEnemyTakesDamages(BaseEventParameters baseParams)
 {
     if (m_HurtBoxesDetected.Count > 0)
     {
         DamageTakenEventParameters damageTakenEventParameters = (DamageTakenEventParameters)baseParams;
         if (damageTakenEventParameters.m_AttackLogic == m_CurrentAttack)
         {
             Utils.GetEnemyEventManager(gameObject).TriggerEvent(EPlayerEvent.ProximityBox, new ProximityBoxParameters(false, m_Collider));
             m_CurrentAttack = null;
         }
     }
 }
Пример #15
0
    private bool CanParryAttack(PlayerBaseAttackLogic attackLogic)
    {
        if (m_AttackComponent)
        {
            // Check if we are playing parry attack
            if (m_AttackComponent.GetCurrentAttackLogic() is PlayerParryAttackLogic parryAttackLogic && parryAttackLogic.CanParryAttack(attackLogic))
            {
                return(attackLogic.CanAttackBeParried());
            }
        }

        return(false);
    }
Пример #16
0
    private void ApplyDamage(PlayerBaseAttackLogic attackLogic, uint damage, EAttackResult attackResult, EHitNotificationType hitNotificationType)
    {
        if (damage >= m_HP)
        {
            m_HP = (uint)(m_InfoComponent.GetPlayerSettings().m_IsInvincible ? 1 : 0);
        }
        else
        {
            m_HP -= damage;
        }

        OnDamageTaken(attackLogic, damage, attackResult, hitNotificationType);
    }
Пример #17
0
    protected override void Awake()
    {
        base.Awake();
#if UNITY_EDITOR
        if (m_AttackComponent == null)
        {
            KakutoDebug.LogError("Missing AttackComponent in " + this);
        }
#endif

        m_CurrentAttack = null;
        RegisterListeners();
    }
Пример #18
0
    private void OnDeath(PlayerBaseAttackLogic attackLogic)
    {
        m_Anim.SetBool("IsDead", true);

        // Only play death animation if we're not killed by grab animation
        // For grab attacks, let the anim end correctly
        if (!(attackLogic is PlayerGrabAttackLogic))
        {
            m_Anim.Play("Death", 0, 0);
        }

        Utils.GetPlayerEventManager(gameObject).TriggerEvent(EPlayerEvent.OnDeath, new DeathEventParameters(gameObject.tag));
    }
Пример #19
0
    private bool CanBlockGrabAttack(PlayerBaseAttackLogic attackLogic)
    {
        // Can't blocked grab attack when stunned
        if (!m_StunInfoSC.IsStunned())
        {
            if (m_AttackComponent)
            {
                // Check if we are playing grab attack as well
                if (m_AttackComponent.GetCurrentAttackLogic() is PlayerGrabAttackLogic grabAttack)
                {
                    return(grabAttack.GetGrabPhase() == EGrabPhase.Startup);
                }
            }
        }

        return(false);
    }
Пример #20
0
    public override bool EvaluateConditions(PlayerBaseAttackLogic currentAttackLogic)
    {
        bool conditionIsValid = base.EvaluateConditions(currentAttackLogic);

        // If projectile is a super, don't need to check others projectiles
        if (conditionIsValid && !m_Attack.m_IsASuper)
        {
            foreach (ProjectileComponent projectile in m_CurrentProjectiles)
            {
                if (!projectile.HasDestructionBeenRequested())
                {
                    conditionIsValid &= projectile.GetLogic().IsASuper(); // Condition is valid only if there is no other alive projectile than super in the scene
                }
            }
        }
        return(conditionIsValid);
    }
Пример #21
0
 private void SetupStanceToBlockAttack(PlayerBaseAttackLogic attackLogic)
 {
     // In order to simulate the correct blocking anim
     // If this is a low attack type, need to force crouch to the dummy
     if (attackLogic is PlayerNormalAttackLogic normalAttackLogic)
     {
         EAttackType attackType = normalAttackLogic.GetNormalAttackConfig().m_AttackType;
         if (attackType == EAttackType.Low)
         {
             m_MovementComponent.ForceCrouchInput(true);
         }
         else if (attackType == EAttackType.Overhead)
         {
             m_MovementComponent.ForceCrouchInput(false);
         }
     }
 }
Пример #22
0
    private void PlayDamageTakenAnim(PlayerBaseAttackLogic attackLogic, EAttackResult attackResult)
    {
        switch (attackResult)
        {
        case EAttackResult.Hit:
            PlayHitAnimation(attackLogic);
            break;

        case EAttackResult.Blocked:
            PlayBlockAnimation(attackLogic);
            break;

        case EAttackResult.Parried:
            PlayParriedAnimation(attackLogic);
            break;

        default:
            break;
        }
    }
Пример #23
0
    private bool CanReceiveHit(PlayerBaseAttackLogic playerBaseAttackLogic)
    {
        if (IsDead())
        {
            return(false);
        }

        if (m_StunInfoSC.IsStunned() && m_MovementComponent.IsJumping())
        {
            if (playerBaseAttackLogic.GetAttack().m_CanJuggleLaunch ||
                (m_StunInfoSC.IsInJuggleState() && playerBaseAttackLogic.GetAttack().m_CanJuggleHit))
            {
                return(true);
            }

            return(false);
        }

        return(true);
    }
Пример #24
0
    private bool IsGrabAttacker(PlayerBaseAttackLogic grabLogic)
    {
        bool       isGrabAttacker             = false;
        GameObject grabInstigator             = grabLogic.GetOwner();
        Animator   grabInstigatorAnim         = grabLogic.GetAnimator();
        float      currentGrabInstigatorFrame = Utils.GetCurrentAnimFrame(grabInstigatorAnim);
        float      currentGrabOwnerFrame      = Utils.GetCurrentAnimFrame(m_Anim);

        // If grab instigator has been triggered at exact same frame than owner
        if (currentGrabInstigatorFrame == currentGrabOwnerFrame)
        {
            isGrabAttacker = grabInstigator.CompareTag(Player.Player1);
            ChronicleManager.AddChronicle(gameObject, EChronicleCategory.Health, "Is " + grabInstigator.tag + " GrabAttacker | Grab attack has been triggered at same frame on both players. Player1 defined as attacker by default");
        }
        else
        {
            isGrabAttacker = currentGrabInstigatorFrame > currentGrabOwnerFrame;
            ChronicleManager.AddChronicle(gameObject, EChronicleCategory.Health, "Is " + grabInstigator.tag + " GrabAttacker | " + ((isGrabAttacker) ? grabInstigator.tag : gameObject.tag) + " is grab attacker");
        }
        return(isGrabAttacker);
    }
Пример #25
0
    void OnGrabbed(BaseEventParameters baseParams)
    {
        if (IsDead())
        {
            return;
        }

#if UNITY_EDITOR || DEBUG_DISPLAY
        if (m_DEBUG_BreakOnGrabbed)
        {
            Debug.Break();
        }
#endif
        GrabbedEventParameters grabbedParams   = (GrabbedEventParameters)baseParams;
        PlayerBaseAttackLogic  grabAttackLogic = grabbedParams.m_AttackLogic;

        ChronicleManager.AddChronicle(gameObject, EChronicleCategory.Health, "On grabbed by : " + grabAttackLogic.GetAttack().m_Name);
        m_StunInfoSC.StartStun(grabAttackLogic, EAttackResult.Hit);
        PlayHitAnimation(grabAttackLogic);
        m_AudioManager.PlayHitSFX(m_InfoComponent.GetPlayerIndex(), EAttackSFXType.Hit_Throw, false);
    }
Пример #26
0
    public List <PlayerBaseAttackLogic> CreateLogics(PlayerAttackComponent playerAttackComponent)
    {
        List <PlayerBaseAttackLogic> attackLogics = new List <PlayerBaseAttackLogic>();

        for (int i = 0; i < m_AttackList.Count; i++)
        {
            PlayerAttack attack = m_AttackList[i];
            if (attack.m_AttackConfig)
            {
                PlayerBaseAttackLogic attackLogic = attack.m_AttackConfig.CreateLogic();
                attackLogic.OnInit(playerAttackComponent, attack);
                attackLogics.Add(attackLogic);
            }
            else
            {
                KakutoDebug.LogError("No attack config found for " + attack.m_Name);
            }
        }

        return(attackLogics);
    }
Пример #27
0
    private void PlayHitSFX(PlayerBaseAttackLogic attackLogic, EAttackResult attackResult, EHitNotificationType hitNotificationType)
    {
        EAttackSFXType attackSFXType = EAttackSFXType.Hit_Light;

        bool validHitSFXFound = IsDead() || attackLogic.GetHitSFX(attackResult, hitNotificationType, ref attackSFXType);

        if (IsDead())
        {
            attackSFXType = EAttackSFXType.Final_Hit;
        }

        if (validHitSFXFound)
        {
            // Play attack SFX on the instigator of the hit in order to cancel whiff sfx
            m_AudioManager.PlayHitSFX(m_InfoComponent.GetPlayerIndex(), attackSFXType, attackLogic is PlayerProjectileAttackLogic);
        }
        else
        {
            KakutoDebug.LogError("No SFX found for attack " + attackLogic.GetAnimationAttackName() + " taken in " + attackResult);
            ChronicleManager.AddChronicle(gameObject, EChronicleCategory.Health, "No SFX found for attack " + attackLogic.GetAnimationAttackName() + " taken in " + attackResult);
        }
    }
Пример #28
0
    private void GetHitInfo(PlayerBaseAttackLogic attackLogic, out uint hitDamage, out EAttackResult attackResult, out EHitNotificationType hitNotificationType)
    {
        Profiler.BeginSample("PlayerHealthComponent.GetHitInfo");
        hitNotificationType = EHitNotificationType.None;

        if (CanParryAttack(attackLogic))
        {
            attackResult = EAttackResult.Parried;
            hitDamage    = 0;
        }
        else if (CanBlockAttack(attackLogic))
        {
            attackResult = EAttackResult.Blocked;
            hitDamage    = attackLogic.GetHitDamage(attackResult);
        }
        else
        {
            attackResult        = EAttackResult.Hit;
            hitDamage           = attackLogic.GetHitDamage(attackResult);
            hitNotificationType = attackLogic.GetHitNotificationType(attackResult, IsInBlockingStance(), m_MovementComponent.IsCrouching(), m_MovementComponent.IsFacingRight(), m_AttackComponent);
        }
        Profiler.EndSample();
    }
Пример #29
0
    void OnHit(BaseEventParameters baseParams)
    {
        Profiler.BeginSample("PlayerHealthComponent.OnHit");

        HitEventParameters    hitParams      = (HitEventParameters)baseParams;
        PlayerBaseAttackLogic hitAttackLogic = hitParams.m_AttackLogic;

        if (CanReceiveHit(hitAttackLogic))
        {
#if UNITY_EDITOR || DEBUG_DISPLAY
            if (m_DEBUG_BreakOnHit)
            {
                Debug.Break();
            }
#endif

            GetHitInfo(hitAttackLogic, out uint hitDamage, out EAttackResult attackResult, out EHitNotificationType hitNotificationType);
            ChronicleManager.AddChronicle(gameObject, EChronicleCategory.Health, "On hit by : " + hitAttackLogic.GetAttack().m_Name + ", damage : " + hitDamage + ", result : " + attackResult + ", hitNotif : " + hitNotificationType);

            ApplyDamage(hitAttackLogic, hitDamage, attackResult, hitNotificationType);
        }

        Profiler.EndSample();
    }
Пример #30
0
 public bool CanParryAttack(PlayerBaseAttackLogic attackLogic)
 {
     return(m_ParryState == EParryState.Startup);
 }