private IEnumerator _Attack(AttackAction attackAction)
    {
        float chargeDistance = (_chargeAmount - chargeMinLength + 0.1f) * 2.5f;

        if (_isparticleTrailNotNull)
        {
            var emissionModule = _repelCirclePart.particleTrail.emission;
            emissionModule.rateOverDistance = TrailRateOverDistance;
        }
        weapon.Blocking            = true;
        _rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
        while (chargeDistance > 0 && _repelCirclePart.energy > 0 && !_repelCirclePart.touchingHittable)
        {
            _rb.gravityScale         = 0;
            _rb.velocity             = attackSpeed * _dir;
            chargeDistance          -= Time.fixedDeltaTime * attackLengthReducer;
            _repelCirclePart.energy -= Time.fixedDeltaTime * attackLengthReducer;

            yield return(Yields.WaitForFixedUpdate);
        }
        attackAction.state = AttackState.Recovering;
        attackAction.BeginRecovering();
    }
Beispiel #2
0
 /// <summary> Receives events from weapon animations. </summary>
 /// <param name="e"> The object sent from the animation </param>
 /// <param name="duration"> An optional duration that some events need </param>
 public void ReceiveAnimationEvent(AnimationEventObject e, float duration)
 {
     if (primaryAttack.state == AttackState.Ended)
     {
         return;
     }
     if (e == _animEventObjs.attackFadeIn && primaryAttack.state == AttackState.WindingUp)
     {
         FadeAttackIn(duration);
     }
     else if (e == _animEventObjs.attackAttackingStart && primaryAttack.state == AttackState.WindingUp)
     {
         primaryAttack.BeginAttacking();
     }
     else if (e == _animEventObjs.attackAttackingEnd && primaryAttack.state == AttackState.Attacking)
     {
         primaryAttack.BeginRecovering();
     }
     else if (e == _animEventObjs.attackFadeOut && primaryAttack.state == AttackState.Recovering)
     {
         primaryAttack.EndAttack(duration);
     }
 }
Beispiel #3
0
    internal IEnumerator _CheckMeleeHit(AttackAction attackAction)
    {
        DirectionalAttackDefinition attackDefinition = attackAction.attackDefinition;

        _prevBase = weaponBase.position;
        _prevTip  = weaponTip.position;
        while (attackAction.state == AttackState.Attacking)
        {
            bool GetBaddyHit(out RaycastHit2D swingCheck)
            {
                bool HitBaddy(RaycastHit2D rHit)
                {
#if UNITY_EDITOR
                    if (visualizeDebug && rHit && !(rHit.collider.GetComponentInParent <IDamageable>() is null) &&
                        Linecast(_prevBase, rHit.point, whatIsNotHittable & ~(1 << rHit.collider.gameObject.layer)))
                    {
                        Debug.DrawLine(_prevBase, rHit.point, Color.red);
                    }
#endif
                    return(rHit && !(rHit.collider.GetComponentInParent <IDamageable>() is null) &&
                           // Make sure nothing of a different layer is between where the sword was and where it hit
                           !Linecast(_prevBase, rHit.point,
                                     whatIsNotHittable & ~(1 << rHit.collider.gameObject.layer)));
                }

//               print("CHECK1");
                //CHECK1: along blade
                Vector2 basePos = weaponBase.position;
                Vector2 tipPos  = weaponTip.position;
                swingCheck = Linecast(basePos, tipPos, whatIsHittable);
#if UNITY_EDITOR
                if (visualizeDebug)
                {
                    Debug.DrawLine(basePos, tipPos);
                }
#endif
                if (HitBaddy(swingCheck))
                {
                    return(true);
                }


//               print("CHECK2");
                //CHECK2: along tip movement
                swingCheck = Linecast(_prevTip, tipPos, whatIsHittable);
#if UNITY_EDITOR
                if (visualizeDebug)
                {
                    Debug.DrawLine(_prevTip, tipPos);
                }
#endif
                if (HitBaddy(swingCheck))
                {
                    return(true);
                }

//                print("CHECK3");
                //CHECK3: along base movement
                swingCheck = Linecast(_prevBase, basePos, whatIsHittable);
#if UNITY_EDITOR
                if (visualizeDebug)
                {
                    Debug.DrawLine(_prevBase, basePos);
                }
#endif
                if (HitBaddy(swingCheck))
                {
                    return(true);
                }

//               print("CHECK4");
                //CHECK4: along lower third movement
                swingCheck = Linecast(Vector2.Lerp(_prevBase, _prevTip, 0.33f), Vector2.Lerp(basePos, tipPos, 0.33f),
                                      whatIsHittable);
#if UNITY_EDITOR
                if (visualizeDebug)
                {
                    Debug.DrawLine(Vector2.Lerp(_prevBase, _prevTip, 0.33f), Vector2.Lerp(basePos, tipPos, 0.33f));
                }
#endif
                if (HitBaddy(swingCheck))
                {
                    return(true);
                }

//               print("CHECK5");
                //CHECK5: along upper third movement
                swingCheck = Linecast(Vector2.Lerp(_prevBase, _prevTip, 0.66f), Vector2.Lerp(basePos, tipPos, 0.66f),
                                      whatIsHittable);
#if UNITY_EDITOR
                if (visualizeDebug)
                {
                    Debug.DrawLine(Vector2.Lerp(_prevBase, _prevTip, 0.66f), Vector2.Lerp(basePos, tipPos, 0.66f));
                }
#endif
                if (HitBaddy(swingCheck))
                {
                    return(true);
                }

//               print("CHECK6");
                //CHECK6: along first third blade
                float   swordLength = Vector2.Distance(basePos, tipPos);
                Vector2 baseMid     = Vector2.Lerp(_prevBase, basePos, 0.33f);
                Vector2 tipMid      = Vector2.Lerp(_prevTip, tipPos, 0.33f);
                swingCheck = Raycast(baseMid, tipMid - baseMid, swordLength, whatIsHittable);
#if UNITY_EDITOR
                if (visualizeDebug)
                {
                    Debug.DrawRay(baseMid, (tipMid - baseMid).normalized * swordLength);
                }
#endif
                if (HitBaddy(swingCheck))
                {
                    return(true);
                }

//               print("CHECK7");
                //CHECK7: along second third blade
                baseMid    = Vector2.Lerp(_prevBase, basePos, 0.66f);
                tipMid     = Vector2.Lerp(_prevTip, tipPos, 0.66f);
                swingCheck = Raycast(baseMid, tipMid - baseMid, swordLength, whatIsHittable);
#if UNITY_EDITOR
                if (visualizeDebug)
                {
                    Debug.DrawRay(baseMid, (tipMid - baseMid).normalized * swordLength);
                }
#endif
                return(HitBaddy(swingCheck));
            }

            // Check for any hits, then update the prev things
            bool baddyHit = GetBaddyHit(out RaycastHit2D swingHit);
            _prevBase = weaponBase.position;
            _prevTip  = weaponTip.position;
            // Wait till next frame if we didn't hit anything hittable
            if (!baddyHit)
            {
                yield return(Yields.WaitForFixedUpdate);

                continue;
            }

            IDamageable damageable = swingHit.collider.GetComponentInParent <IDamageable>();
            Vector2     point      = swingHit.point;
            Vector2     force      = mvmt.rb.velocity; //Relative Velocity
            if (swingHit.collider.attachedRigidbody)
            {
                force -= swingHit.collider.attachedRigidbody.velocity;
            }
            force  = mass * force;                                        //Kinetic Energy = mv^2, but that was too much so just doing mv lol
            force += attackAction.attackDir * attackDefinition.knockback; // Add knockback in the direction of the swing


            switch (damageable.CheckProtected(point, swingHit.collider))
            {
            case ProtectedType.Dodging: yield break;

            case ProtectedType.Blocking: {
                //TODO recoil and sparks or something shit idk
                var     hTf    = holder.transform;
                Vector2 recoil = (hTf.position - swingHit.transform.position + hTf.up / 6) *
                                 attackDefinition.knockback;
                holder.characterPhysics?.AddForceAt(point, recoil, GetComponentInParent <Collider2D>());
                FadeAttackOut(0.30121f);
                attackAction.BeginRecovering();
                yield break;
            }
            }
            // Damage scaled based on relative velocity
            int damageGiven = (int)Math.Max(attackAction.attackDefinition.damage,
                                            attackAction.attackDefinition.knockback * mvmt.rb.velocity.magnitude);
            damageable.DamageMe(point, force, damageGiven, swingHit.collider);
            yield break;
        }
    }