public void ActiveWeaponController(bool meleeTrigger, bool grenadeTrigger)
 {
     if (!player.FireAnimationPlaying() && !player.ReloadAnimationPlaying())
     {
         if (grenadeTrigger)
         {
             if (currentAttack != CurrentAttack.Grenade)
             {
                 SetActiveWeapon(grenadeLauncher);
                 currentAttack = CurrentAttack.Grenade;
             }
         }
         else if (meleeTrigger)
         {
             if (currentAttack != CurrentAttack.Melee)
             {
                 SetActiveWeapon(meleeWeapon);
                 currentAttack = CurrentAttack.Melee;
             }
         }
         else
         {
             if (currentAttack != CurrentAttack.Normal)
             {
                 SetActiveWeapon(inventoryWeapons[currentWeaponIndex]);
                 currentAttack = CurrentAttack.Normal;
             }
         }
     }
 }
 // Used in player UpdateAmmoPool and player Load
 public void ForceSwitchCurrentWeapon(int weaponIndex)
 {
     if (!inventoryWeapons[weaponIndex].locked)
     {
         currentWeaponIndex = weaponIndex;
         currentAttack      = CurrentAttack.Switch;
     }
 }
 public bool SwitchCurrentWeapon(int weaponIndex)
 {
     if (player.OutOfAmmo())
     {
         return(false);
     }
     // As long as the weapon is not locked, switch and return true
     if (!inventoryWeapons[weaponIndex].locked && currentAttack == CurrentAttack.Normal && (player.HasAmmo(weaponIndex) || player.HasAmmoPool(weaponIndex)))
     {
         currentWeaponIndex = weaponIndex;
         currentAttack      = CurrentAttack.Switch; // Will switch back to normal next frame (ensures that weapon prefab and mesh get updated)
         return(true);
         // Else return false
     }
     else
     {
         return(false);
     }
 }
    public void ChooseNextAttack()
    {
        if (m_HasRangedAttack && m_TargerDistance >= GetComponent<RangeAttack>().GetAttackRange() - 2)
        {
            m_current = CurrentAttack.ranged;
        }

        else if (m_HasMeleeAttack)
        {
            m_current = CurrentAttack.melee;
        }

        else if (m_HasRangedAttack)
        {
            m_current = CurrentAttack.ranged;
        }

        else
        {
            m_current = CurrentAttack.none;
        }
    }
示例#5
0
    /// <summary>
    /// Inflict damages to a specified target.
    /// </summary>
    /// <param name="_target">Target to hit.</param>
    private void InflictDamages(TDS_Damageable _target)
    {
        // Attack the target
        if (CurrentAttack.Attack(this, _target) < -1)
        {
            return;
        }

        // Call local method on the character who hit
        if (Owner)
        {
            if (PhotonNetwork.offlineMode && (Owner is TDS_Player _player))
            {
                _player.HitCallback(_target.Collider.bounds.center.x, _target.Collider.bounds.max.y, _target.transform.position.z);
            }
            else
            {
                TDS_RPCManager.Instance?.RPCPhotonView.RPC("CallMethodOnline", Owner.photonView.owner, TDS_RPCManager.GetInfo(Owner.photonView, Owner.GetType(), "HitCallback"), new object[] { _target.Collider.bounds.center.x, _target.Collider.bounds.max.y, _target.transform.position.z });
            }
        }

        // Triggers event
        OnTouch?.Invoke();
    }
示例#6
0
        public override IEnumerable <Status> Run()
        {
            if (CurrentAttack == null)
            {
                yield return(Status.Fail);

                yield break;
            }

            Timeout.Reset();

            if (Target == null && TargetName != null)
            {
                Target = Agent.Blackboard.GetData <Body>(TargetName);

                if (Target == null)
                {
                    yield return(Status.Fail);

                    yield break;
                }
            }

            while (true)
            {
                Timeout.Update(DwarfTime.LastTime);

                if (Timeout.HasTriggered)
                {
                    if (Training)
                    {
                        Agent.AddXP(10);
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = Creature.CharacterMode.Walking;
                        yield return(Status.Success);

                        yield break;
                    }
                    else
                    {
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = Creature.CharacterMode.Walking;
                        yield return(Status.Fail);

                        yield break;
                    }
                }

                if (Target == null || Target.IsDead)
                {
                    Creature.CurrentCharacterMode = Creature.CharacterMode.Walking;
                    Creature.Physics.Orientation  = Physics.OrientMode.RotateY;
                    yield return(Status.Success);
                }

                // Find the location of the melee target
                Vector3 targetPos = new Vector3(Target.GlobalTransform.Translation.X,
                                                Target.GetBoundingBox().Min.Y,
                                                Target.GlobalTransform.Translation.Z);

                bool    collides = Creature.Physics.Collide(Target.BoundingBox);
                Vector3 diff     = targetPos - Creature.AI.Position;

                Creature.Physics.Face(targetPos);

                // If we are far away from the target, run toward it
                if (diff.Length() > CurrentAttack.Range * 8 && !collides)
                {
                    Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                    Creature.OverrideCharacterMode = false;
                    Creature.CurrentCharacterMode  = Creature.CharacterMode.Walking;
                    yield return(Status.Fail);
                }
                if (diff.Length() > CurrentAttack.Range && !collides)
                {
                    Creature.CurrentCharacterMode = Creature.CharacterMode.Walking;
                    Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, targetPos, Creature.Physics.GlobalTransform.Translation) * 0.9f;
                    output.Y = 0.0f;
                    Creature.Physics.ApplyForce(output, DwarfTime.Dt);

                    if ((targetPos - Creature.AI.Position).Y > 0.3 && Creature.IsOnGround)
                    {
                        Agent.Jump(DwarfTime.LastTime);
                    }
                    Creature.Physics.Orientation = Physics.OrientMode.RotateY;
                }
                else if (CurrentAttack.Mode != Attack.AttackMode.Melee &&
                         diff.Length() < CurrentAttack.Range * 0.75f && !collides)
                {
                    /*
                     *
                     * Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, targetPos, Creature.Physics.GlobalTransform.Translation) * 0.9f;
                     * output.Y = 0.0f;
                     * Creature.Physics.ApplyForce(-output, DwarfTime.Dt);
                     *
                     * Creature.CurrentCharacterMode = Creature.CharacterMode.Walking;
                     * Creature.Physics.Orientation = Physics.OrientMode.RotateY;
                     */
                    foreach (Act.Status stat in AvoidTarget(CurrentAttack.Range))
                    {
                        yield return(Status.Running);
                    }
                }
                // Else, stop and attack
                else
                {
                    Creature.Physics.Orientation = Physics.OrientMode.Fixed;
                    Creature.Physics.Velocity    = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f);
                    CurrentAttack.RechargeTimer.Reset(CurrentAttack.RechargeRate);

                    Creature.Sprite.ResetAnimations(Creature.CharacterMode.Attacking);
                    Creature.Sprite.PlayAnimations(Creature.CharacterMode.Attacking);
                    Creature.CurrentCharacterMode = Creature.CharacterMode.Attacking;

                    while (!CurrentAttack.Perform(Creature, Target, DwarfTime.LastTime, Creature.Stats.BuffedStr + Creature.Stats.BuffedSiz,
                                                  Creature.AI.Position, Creature.Faction.Name))
                    {
                        Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f);
                        yield return(Status.Running);
                    }

                    while (!Agent.Creature.Sprite.CurrentAnimation.IsDone())
                    {
                        yield return(Status.Running);
                    }

                    Creature.CurrentCharacterMode = Creature.CharacterMode.Attacking;
                    Creature.Sprite.PauseAnimations(Creature.CharacterMode.Attacking);

                    CurrentAttack.RechargeTimer.Reset(CurrentAttack.RechargeRate);

                    while (!CurrentAttack.RechargeTimer.HasTriggered)
                    {
                        Creature.Sprite.PauseAnimations(Creature.CharacterMode.Attacking);
                        CurrentAttack.RechargeTimer.Update(DwarfTime.LastTime);
                        Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f);
                        yield return(Status.Running);
                    }

                    Creature.CurrentCharacterMode = Creature.CharacterMode.Idle;
                    Creature.Physics.Orientation  = Physics.OrientMode.RotateY;
                    if (Target.IsDead)
                    {
                        if (Creature.Faction.ChopDesignations.Contains(Target))
                        {
                            Creature.Faction.ChopDesignations.Remove(Target);
                        }

                        if (Creature.Faction.AttackDesignations.Contains(Target))
                        {
                            Creature.Faction.AttackDesignations.Remove(Target);
                        }

                        Target = null;
                        Agent.AddXP(10);
                        Creature.Physics.Face(Creature.Physics.Velocity + Creature.Physics.GlobalTransform.Translation);
                        Creature.Stats.NumThingsKilled++;
                        Creature.AI.AddThought(Thought.ThoughtType.KilledThing);
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = Creature.CharacterMode.Walking;
                        yield return(Status.Success);

                        break;
                    }
                }

                yield return(Status.Running);
            }
        }
示例#7
0
        public override IEnumerable <Status> Run()
        {
            if (CurrentAttack == null)
            {
                yield return(Status.Fail);

                yield break;
            }

            Timeout.Reset();
            FailTimer.Reset();
            if (Target == null && TargetName != null)
            {
                Target = Agent.Blackboard.GetData <Body>(TargetName);

                if (Target == null)
                {
                    yield return(Status.Fail);

                    yield break;
                }
            }

            Inventory targetInventory = Target.GetRoot().GetComponent <Inventory>();

            if (targetInventory != null)
            {
                targetInventory.OnDeath += targetInventory_OnDeath;
            }

            CharacterMode defaultCharachterMode = Creature.AI.Movement.CanFly
                ? CharacterMode.Flying
                : CharacterMode.Walking;

            bool avoided = false;

            while (true)
            {
                Timeout.Update(DwarfTime.LastTime);
                FailTimer.Update(DwarfTime.LastTime);
                if (FailTimer.HasTriggered)
                {
                    Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                    Creature.OverrideCharacterMode = false;
                    Creature.CurrentCharacterMode  = defaultCharachterMode;
                    yield return(Status.Fail);

                    yield break;
                }

                if (Timeout.HasTriggered)
                {
                    if (Training)
                    {
                        Agent.AddXP(1);
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = defaultCharachterMode;
                        yield return(Status.Success);

                        yield break;
                    }
                    else
                    {
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = defaultCharachterMode;
                        yield return(Status.Fail);

                        yield break;
                    }
                }

                if (Target == null || Target.IsDead)
                {
                    Creature.CurrentCharacterMode = defaultCharachterMode;
                    Creature.Physics.Orientation  = Physics.OrientMode.RotateY;
                    yield return(Status.Success);
                }

                // Find the location of the melee target
                Vector3 targetPos = new Vector3(Target.GlobalTransform.Translation.X,
                                                Target.GetBoundingBox().Min.Y,
                                                Target.GlobalTransform.Translation.Z);

                Vector2 diff = new Vector2(targetPos.X, targetPos.Z) - new Vector2(Creature.AI.Position.X, Creature.AI.Position.Z);

                Creature.Physics.Face(targetPos);

                bool intersectsbounds = Creature.Physics.BoundingBox.Intersects(Target.BoundingBox);

                // If we are really far from the target, something must have gone wrong.
                if (!intersectsbounds && diff.Length() > CurrentAttack.Range * 8)
                {
                    Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                    Creature.OverrideCharacterMode = false;
                    Creature.CurrentCharacterMode  = defaultCharachterMode;
                    yield return(Status.Fail);
                }
                // If we're out of attack range, run toward the target.
                if (!Creature.AI.Movement.IsSessile && !intersectsbounds && diff.Length() > CurrentAttack.Range)
                {
                    Creature.CurrentCharacterMode = defaultCharachterMode;

                    /*
                     * Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, targetPos, Creature.Physics.GlobalTransform.Translation) * 0.9f;
                     * output.Y = 0.0f;
                     * if (Creature.AI.Movement.CanFly)
                     * {
                     *  Creature.Physics.ApplyForce(-Creature.Physics.Gravity, DwarfTime.Dt);
                     * }
                     * if (Creature.AI.Movement.IsSessile)
                     * {
                     *  output *= 0.0f;
                     * }
                     * Creature.Physics.ApplyForce(output, DwarfTime.Dt);
                     * Creature.Physics.Orientation = Physics.OrientMode.RotateY;
                     */
                    GreedyPathAct greedyPath = new GreedyPathAct(Creature.AI, Target, CurrentAttack.Range * 0.75f)
                    {
                        PathLength = 5
                    };
                    greedyPath.Initialize();

                    foreach (Act.Status stat in greedyPath.Run())
                    {
                        if (stat == Act.Status.Running)
                        {
                            yield return(Status.Running);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                // If we have a ranged weapon, try avoiding the target for a few seconds to get within range.
                else if (!Creature.AI.Movement.IsSessile && !intersectsbounds && !avoided && (CurrentAttack.Mode == Attack.AttackMode.Ranged &&
                                                                                              diff.Length() < CurrentAttack.Range * 0.15f))
                {
                    FailTimer.Reset();
                    foreach (Act.Status stat in AvoidTarget(CurrentAttack.Range, 3.0f))
                    {
                        yield return(Status.Running);
                    }
                    avoided = true;
                }
                // Else, stop and attack
                else
                {
                    if (CurrentAttack.Mode == Attack.AttackMode.Ranged &&
                        VoxelHelpers.DoesRayHitSolidVoxel(Creature.World.ChunkManager.ChunkData,
                                                          Creature.AI.Position, Target.Position))
                    {
                        yield return(Status.Fail);

                        yield break;
                    }

                    FailTimer.Reset();
                    avoided = false;
                    Creature.Physics.Orientation = Physics.OrientMode.Fixed;
                    Creature.Physics.Velocity    = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f);
                    CurrentAttack.RechargeTimer.Reset(CurrentAttack.RechargeRate);

                    Creature.Sprite.ResetAnimations(CharacterMode.Attacking);
                    Creature.Sprite.PlayAnimations(CharacterMode.Attacking);
                    Creature.CurrentCharacterMode  = CharacterMode.Attacking;
                    Creature.OverrideCharacterMode = true;
                    while (!CurrentAttack.Perform(Creature, Target, DwarfTime.LastTime, Creature.Stats.BuffedStr + Creature.Stats.BuffedSiz,
                                                  Creature.AI.Position, Creature.Faction.Name))
                    {
                        Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f);
                        if (Creature.AI.Movement.CanFly)
                        {
                            Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt);
                        }
                        yield return(Status.Running);
                    }

                    while (!Agent.Creature.Sprite.AnimPlayer.IsDone())
                    {
                        if (Creature.AI.Movement.CanFly)
                        {
                            Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt);
                        }
                        yield return(Status.Running);
                    }

                    var targetCreature = Target.GetRoot().GetComponent <CreatureAI>();
                    if (targetCreature != null && !Creature.AI.FightOrFlight(targetCreature))
                    {
                        yield return(Act.Status.Fail);

                        yield break;
                    }
                    Creature.CurrentCharacterMode = CharacterMode.Attacking;
                    Creature.Sprite.ReloopAnimations(CharacterMode.Attacking);

                    CurrentAttack.RechargeTimer.Reset(CurrentAttack.RechargeRate);

                    Vector3 dogfightTarget = Vector3.Zero;
                    while (!CurrentAttack.RechargeTimer.HasTriggered && !Target.IsDead)
                    {
                        CurrentAttack.RechargeTimer.Update(DwarfTime.LastTime);
                        if (CurrentAttack.Mode == Attack.AttackMode.Dogfight)
                        {
                            Creature.CurrentCharacterMode = CharacterMode.Attacking;
                            dogfightTarget += MathFunctions.RandVector3Cube() * 0.1f;
                            Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, dogfightTarget + Target.Position, Creature.Physics.GlobalTransform.Translation) * 0.9f;
                            Creature.Physics.ApplyForce(output - Creature.Physics.Gravity, DwarfTime.Dt);
                        }
                        else
                        {
                            Creature.Sprite.PauseAnimations(CharacterMode.Attacking);
                            Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f);
                            if (Creature.AI.Movement.CanFly)
                            {
                                Creature.Physics.ApplyForce(-Creature.Physics.Gravity, DwarfTime.Dt);
                            }
                        }
                        yield return(Status.Running);
                    }

                    Creature.CurrentCharacterMode = defaultCharachterMode;
                    Creature.Physics.Orientation  = Physics.OrientMode.RotateY;
                    if (Target.IsDead)
                    {
                        Creature.Faction.Designations.RemoveEntityDesignation(Target, DesignationType.Attack);

                        Target = null;
                        Agent.AddXP(10);
                        Creature.Physics.Face(Creature.Physics.Velocity + Creature.Physics.GlobalTransform.Translation);
                        Creature.Stats.NumThingsKilled++;
                        Creature.AI.AddThought(Thought.ThoughtType.KilledThing);
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = defaultCharachterMode;
                        yield return(Status.Success);

                        break;
                    }
                }

                yield return(Status.Running);
            }
        }
示例#8
0
        public override IEnumerable <Status> Run()
        {
            Creature.IsCloaked = false;

            if (CurrentAttack == null)
            {
                yield return(Status.Fail);

                yield break;
            }

            Timeout.Reset();
            FailTimer.Reset();
            if (Target == null && TargetName != null)
            {
                Target = Agent.Blackboard.GetData <GameComponent>(TargetName);

                if (Target == null)
                {
                    yield return(Status.Fail);

                    yield break;
                }
            }

            if (Agent.Faction.Race.IsIntelligent)
            {
                var targetInventory = Target.GetRoot().GetComponent <Inventory>();
                if (targetInventory != null)
                {
                    targetInventory.SetLastAttacker(Agent);
                }
            }

            CharacterMode defaultCharachterMode = Creature.AI.Movement.CanFly
                ? CharacterMode.Flying
                : CharacterMode.Walking;

            bool avoided = false;

            while (true)
            {
                Timeout.Update(DwarfTime.LastTime);
                FailTimer.Update(DwarfTime.LastTime);
                if (FailTimer.HasTriggered)
                {
                    Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                    Creature.OverrideCharacterMode = false;
                    Creature.CurrentCharacterMode  = defaultCharachterMode;
                    yield return(Status.Fail);

                    yield break;
                }

                if (Timeout.HasTriggered)
                {
                    if (Training)
                    {
                        Agent.AddXP(1);
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = defaultCharachterMode;
                        yield return(Status.Success);

                        yield break;
                    }
                    else
                    {
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = defaultCharachterMode;
                        yield return(Status.Fail);

                        yield break;
                    }
                }

                if (Target == null || Target.IsDead)
                {
                    Creature.CurrentCharacterMode = defaultCharachterMode;
                    Creature.Physics.Orientation  = Physics.OrientMode.RotateY;
                    yield return(Status.Success);
                }

                // Find the location of the melee target
                Vector3 targetPos = new Vector3(Target.GlobalTransform.Translation.X,
                                                Target.GetBoundingBox().Min.Y,
                                                Target.GlobalTransform.Translation.Z);

                Vector2 diff = new Vector2(targetPos.X, targetPos.Z) - new Vector2(Creature.AI.Position.X, Creature.AI.Position.Z);

                Creature.Physics.Face(targetPos);

                bool  intersectsbounds = Creature.Physics.BoundingBox.Intersects(Target.BoundingBox);
                float dist             = diff.Length();
                // If we are really far from the target, something must have gone wrong.
                if (DefensiveStructure == null && !intersectsbounds && dist > CurrentAttack.Weapon.Range * 4)
                {
                    Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                    Creature.OverrideCharacterMode = false;
                    Creature.CurrentCharacterMode  = defaultCharachterMode;
                    yield return(Status.Fail);

                    yield break;
                }

                if (DefensiveStructure != null)
                {
                    if (Creature.Hp < LastHp)
                    {
                        float damage = LastHp - Creature.Hp;
                        Creature.Heal(Math.Min(5.0f, damage));
                        var health = DefensiveStructure.GetRoot().GetComponent <Health>();
                        if (health != null)
                        {
                            health.Damage(damage);
                            Drawer2D.DrawLoadBar(health.World.Renderer.Camera, DefensiveStructure.Position, Color.White, Color.Black, 32, 1, health.Hp / health.MaxHealth, 0.1f);
                        }
                        LastHp = Creature.Hp;
                    }

                    if (dist > CurrentAttack.Weapon.Range)
                    {
                        float sqrDist = dist * dist;
                        foreach (var threat in Creature.AI.Faction.Threats)
                        {
                            float threatDist = (threat.AI.Position - Creature.AI.Position).LengthSquared();
                            if (threatDist < sqrDist)
                            {
                                sqrDist = threatDist;
                                Target  = threat.Physics;
                                break;
                            }
                        }
                        dist = (float)Math.Sqrt(sqrDist);
                    }

                    if (dist > CurrentAttack.Weapon.Range * 4)
                    {
                        yield return(Status.Fail);

                        yield break;
                    }

                    if (DefensiveStructure.IsDead)
                    {
                        DefensiveStructure = null;
                    }
                }

                LastHp = Creature.Hp;


                // If we're out of attack range, run toward the target.
                if (DefensiveStructure == null && !Creature.AI.Movement.IsSessile && !intersectsbounds && diff.Length() > CurrentAttack.Weapon.Range)
                {
                    Creature.CurrentCharacterMode = defaultCharachterMode;
                    var greedyPath = new GreedyPathAct(Creature.AI, Target, CurrentAttack.Weapon.Range * 0.75f)
                    {
                        PathLength = 5
                    };
                    greedyPath.Initialize();

                    foreach (Act.Status stat in greedyPath.Run())
                    {
                        if (stat == Act.Status.Running)
                        {
                            yield return(Status.Running);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                // If we have a ranged weapon, try avoiding the target for a few seconds to get within range.
                else if (DefensiveStructure == null && !Creature.AI.Movement.IsSessile && !intersectsbounds && !avoided && (CurrentAttack.Weapon.Mode == Weapon.AttackMode.Ranged &&
                                                                                                                            dist < CurrentAttack.Weapon.Range * 0.15f))
                {
                    FailTimer.Reset();
                    foreach (Act.Status stat in AvoidTarget(CurrentAttack.Weapon.Range, 3.0f))
                    {
                        yield return(Status.Running);
                    }
                    avoided = true;
                }
                // Else, stop and attack
                else if ((DefensiveStructure == null && dist < CurrentAttack.Weapon.Range) ||
                         (DefensiveStructure != null && dist < CurrentAttack.Weapon.Range * 2.0))
                {
                    if (CurrentAttack.Weapon.Mode == Weapon.AttackMode.Ranged &&
                        VoxelHelpers.DoesRayHitSolidVoxel(Creature.World.ChunkManager, Creature.AI.Position, Target.Position))
                    {
                        yield return(Status.Fail);

                        yield break;
                    }

                    FailTimer.Reset();
                    avoided = false;
                    Creature.Physics.Orientation = Physics.OrientMode.Fixed;
                    Creature.Physics.Velocity    = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f);
                    CurrentAttack.RechargeTimer.Reset(CurrentAttack.Weapon.RechargeRate);

                    Creature.Sprite.ResetAnimations(Creature.Stats.CurrentClass.AttackMode);
                    Creature.Sprite.PlayAnimations(Creature.Stats.CurrentClass.AttackMode);
                    Creature.CurrentCharacterMode  = Creature.Stats.CurrentClass.AttackMode;
                    Creature.OverrideCharacterMode = true;
                    Timer timeout = new Timer(10.0f, true);
                    while (!CurrentAttack.Perform(Creature, Target, DwarfTime.LastTime, Creature.Stats.Strength + Creature.Stats.Size,
                                                  Creature.AI.Position, Creature.Faction.ParentFaction.Name))
                    {
                        timeout.Update(DwarfTime.LastTime);
                        if (timeout.HasTriggered)
                        {
                            break;
                        }

                        Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f);
                        if (Creature.AI.Movement.CanFly)
                        {
                            Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt);
                        }
                        yield return(Status.Running);
                    }

                    timeout.Reset();
                    while (!Agent.Creature.Sprite.AnimPlayer.IsDone())
                    {
                        timeout.Update(DwarfTime.LastTime);
                        if (timeout.HasTriggered)
                        {
                            break;
                        }
                        if (Creature.AI.Movement.CanFly)
                        {
                            Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt);
                        }
                        yield return(Status.Running);
                    }

                    var targetCreature = Target.GetRoot().GetComponent <CreatureAI>();
                    if (targetCreature != null && Creature.AI.FightOrFlight(targetCreature) == CreatureAI.FightOrFlightResponse.Flee)
                    {
                        yield return(Act.Status.Fail);

                        yield break;
                    }
                    Creature.CurrentCharacterMode = CharacterMode.Attacking;

                    Vector3 dogfightTarget = Vector3.Zero;
                    while (!CurrentAttack.RechargeTimer.HasTriggered && !Target.IsDead)
                    {
                        CurrentAttack.RechargeTimer.Update(DwarfTime.LastTime);
                        if (CurrentAttack.Weapon.Mode == Weapon.AttackMode.Dogfight)
                        {
                            dogfightTarget += MathFunctions.RandVector3Cube() * 0.1f;
                            Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, dogfightTarget + Target.Position, Creature.Physics.GlobalTransform.Translation) * 0.9f;
                            Creature.Physics.ApplyForce(output - Creature.Physics.Gravity, DwarfTime.Dt);
                        }
                        else
                        {
                            Creature.Physics.Velocity = Vector3.Zero;
                            if (Creature.AI.Movement.CanFly)
                            {
                                Creature.Physics.ApplyForce(-Creature.Physics.Gravity, DwarfTime.Dt);
                            }
                        }
                        yield return(Status.Running);
                    }

                    Creature.CurrentCharacterMode = defaultCharachterMode;
                    Creature.Physics.Orientation  = Physics.OrientMode.RotateY;

                    if (Target.IsDead)
                    {
                        Target = null;
                        Agent.AddXP(10);
                        Creature.Physics.Face(Creature.Physics.Velocity + Creature.Physics.GlobalTransform.Translation);
                        Creature.Stats.NumThingsKilled++;
                        Creature.AddThought("I killed somehing!", new TimeSpan(0, 8, 0, 0), 1.0f);
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = defaultCharachterMode;
                        yield return(Status.Success);

                        break;
                    }
                }

                yield return(Status.Running);
            }
        }
示例#9
0
    // Update is called once per frame
    void Update()
    {
        // Bools for all possible attacks
        playerAnim.SetBool("attackQ", currentAttack == CurrentAttack.QGroundAttack);
        playerAnim.SetBool("attackW", currentAttack == CurrentAttack.WGroundAttack);
        playerAnim.SetBool("attackE", currentAttack == CurrentAttack.EGroundAttack);
        playerAnim.SetBool("attackR", currentAttack == CurrentAttack.RGroundAttack);
        playerAnim.SetBool("attackQC", currentAttack == CurrentAttack.QCGroundAttack);
        playerAnim.SetBool("attackEC", currentAttack == CurrentAttack.ECGroundAttack);

        playerAnim.SetBool("attackQA", currentAttack == CurrentAttack.QAirAttack);
        playerAnim.SetBool("attackWA", currentAttack == CurrentAttack.WAirAttack);
        playerAnim.SetBool("attackEA", currentAttack == CurrentAttack.EAirAttack);
        playerAnim.SetBool("attackRA", currentAttack == CurrentAttack.RAirAttack);

        if (attackFlag)
        {
            if (collisionCheck != 0)
            {
                Debug.Log("Enter colCh");
                CheckLineCollision();
            }
            else
            {
                CheckEnemyCollision();
            }

            attackTime -= Time.deltaTime;
        }
        else if (!attackFlagAir)
        {
            collisionCheck = 0;
        }

        if (attackFlagAir)
        {
            if (collisionCheck != 0)
            {
                CheckLineCollision();
            }
            else
            {
                CheckEnemyCollision();
            }

            if (currentAttack != CurrentAttack.RAirAttack)
            {
                attackTimeAir -= Time.deltaTime;
            }
        }
        else if (!attackFlag)
        {
            collisionCheck = 0;
        }

        if (attackCooldown)
        {
            attackCooldownTimer -= Time.deltaTime;
        }

        if (attackCooldownTimer <= 0)
        {
            attackCooldown      = false;
            attackCooldownTimer = 1.0f;
        }

        if (attackTime <= 0)
        {
            attackTime    = 0.40f;
            attackFlag    = false;
            currentAttack = 0;

            Destroy(playerAttack);
        }

        if (attackTimeAir <= 0)
        {
            attackTimeAir = 0.40f;
            attackFlagAir = false;
            currentAttack = 0;

            Destroy(playerAttack);
        }

        if ((currentAttack == CurrentAttack.RAirAttack) && (playerMove.IsGrounded()))
        {
            Destroy(playerAttack);
            currentAttack = 0;
        }

        // Verifies if there is a 'Hitbox' tagged GameObject as a child, and if the animation has stopped
        // playing, destroying said object afterwards.

        // Verifies if the button is pressed and if there is no animation playing
        // IMP - Need to implement the rest of the attacks
        if (playerMove.IsGrounded() && !playerAnim.GetBool("shikiDeath") && comboStringCounter > 0)
        {
            for (int i = 0; i < attackButtons.Length; i++)
            {
                if (currentAttack != attackButtons[i].attack)
                {
                    BufferAttackGround(attackButtons[i].text, ref attackButtons[i].buttonPressed, ref attackButtons[i].attackHoldTime, attackButtons[i].identif);
                }
            }
        }
        else if (!playerMove.IsGrounded() && !playerAnim.GetBool("shikiDeath") && !attackFlagAir)
        {
            // Bug where ground attack gets air buffered and "gets out" when player returns to the ground
            for (int i = 0; i < attackButtons.Length; i++)
            {
                if (currentAttack != attackButtons[i].attack)
                {
                    BufferAttackAir(attackButtons[i].text, attackButtons[i].identif);
                }
            }
        }

        if (comboStringCounter <= 0)
        {
            comboDowntime -= Time.deltaTime;

            if (attackTime <= 0.05f)
            {
                comboEndFlag = true;
            }

            if (comboDowntime <= 0)
            {
                comboEndFlag       = false;
                comboStringCounter = 3;
                comboDowntime      = 0.4f;
            }
        }

        if (!attackFlag && (comboStringCounter > 0))
        {
            comboStringCounter = 3;
            comboEndFlag       = false;
        }
    }
示例#10
0
    private void CheckLineCollision()
    {
        bool test = false;

        Debug.Log("number: " + currentLines.Count);

        foreach (GameObject i in currentLines)
        {
            BoxCollider2D[] results = new BoxCollider2D[5];
            int             nCollisions;

            if (attackCheck == null)
            {
                return;
            }
            else if ((collisionCheck == CurrentAttack.RGroundAttack) || (collisionCheck == CurrentAttack.RAirAttack))
            {
                nCollisions = Physics2D.OverlapCollider(attackCheck, attackFilter, results);
            }
            else
            {
                if (attackHitbox == null)
                {
                    return;
                }

                nCollisions = Physics2D.OverlapCollider(attackHitbox, attackFilter, results);
            }

            Debug.Log("nCollisions: " + nCollisions);
            if (nCollisions >= 1)
            {
                test = false;
                if (currentAttack == CurrentAttack.QGroundAttack || currentAttack == CurrentAttack.QAirAttack)
                {
                    foreach (BoxCollider2D col in results)
                    {
                        if (col != null)
                        {
                            if ((col == sepColliders[0]) && (col.tag == i.tag))
                            {
                                test = true;
                            }
                        }
                    }

                    if (!test)
                    {
                        continue;
                    }
                }
                else if (currentAttack == CurrentAttack.EGroundAttack || currentAttack == CurrentAttack.EAirAttack)
                {
                    foreach (BoxCollider2D col in results)
                    {
                        if (col != null)
                        {
                            if ((col == sepColliders[1]) && (col.tag == i.tag))
                            {
                                test = true;
                            }
                        }
                    }

                    if (!test)
                    {
                        continue;
                    }
                }

                i.transform.parent.GetComponent <EnemyHealth>().DestroyLine(i, transform.gameObject.GetComponent <HealthPoints>());
                collisionCheck = 0;
            }
        }

        currentLines.Clear();

        if (!test)
        {
            collisionCheck = 0;
        }
    }
示例#11
0
    private void CheckEnemyCollision()
    {
        currentLines.Clear();

        BoxCollider2D[] results     = new BoxCollider2D[5];
        int             nCollisions = 0;

        if (attackCheck != null)
        {
            nCollisions = Physics2D.OverlapCollider(attackCheck, contactFilter, results);
        }

        if (nCollisions > 0)
        {
            for (int i = 0; i < nCollisions; i++)
            {
                BoxCollider2D enemyCollider = results[i];

                if (enemyCollider.transform.gameObject.tag == "Araya")
                {
                    if (!enemyCollider.transform.gameObject.GetComponent <DamageZone>().enabled)
                    {
                        enemyCollider.transform.gameObject.GetComponent <EnemyHealth>().CommonDamage(GetComponent <HealthPoints>());
                    }

                    Destroy(attackCheck);
                    return;
                }

                foreach (Transform t in enemyCollider.transform)
                {
                    GameObject line = t.gameObject;

                    // fix
                    if (((line.tag == "line_dh") || (line.tag == "line_uh")) &&
                        (currentAttack == CurrentAttack.QGroundAttack || currentAttack == CurrentAttack.QAirAttack ||
                         currentAttack == CurrentAttack.EGroundAttack || currentAttack == CurrentAttack.EAirAttack))
                    {
                        collisionCheck = currentAttack;
                        currentLines.Add(line);
                        sepColliders = line.GetComponents <BoxCollider2D>();
                        Debug.Log("Q, E:" + collisionCheck);
                    }
                    else if ((line.tag == "line_h") &&
                             (currentAttack == CurrentAttack.WGroundAttack || currentAttack == CurrentAttack.WAirAttack))
                    {
                        collisionCheck = currentAttack;
                        currentLines.Add(line);
                        Debug.Log("W: " + collisionCheck);
                    }
                    else if ((line.tag == "line_v") &&
                             (currentAttack == CurrentAttack.QCGroundAttack || currentAttack == CurrentAttack.ECGroundAttack ||
                              currentAttack == CurrentAttack.RAirAttack))
                    {
                        collisionCheck = currentAttack;
                        currentLines.Add(line);
                        Debug.Log("Rair: " + collisionCheck);
                    }
                    else if (((line.tag == "point") || (line.tag == "lpoint")) &&
                             (currentAttack == CurrentAttack.RGroundAttack))
                    {
                        collisionCheck = currentAttack;
                        currentLines.Add(line);
                        Debug.Log("R: " + collisionCheck);
                    }
                }
            }
        }
    }
示例#12
0
    private void AttackAir(string input, Vector2 size, Vector2 offset, Vector3 lPos)
    {
        Debug.Log("(Air) Pressed " + input);

        playerAttack = new GameObject(input + "_Attack");
        playerAttack.transform.SetParent(transform);

        // Creates an attack hitbox on playerAttack and plays correct attack animation
        attackCheck = playerAttack.AddComponent <BoxCollider2D>();

        if (input != "R")
        {
            playerHitbox = new GameObject(input + "_Hitbox");
            playerHitbox.transform.SetParent(playerAttack.transform);
            attackHitbox = playerHitbox.AddComponent <BoxCollider2D>();
        }

        attackCheck.size   = size;
        attackCheck.offset = offset;

        playerAttack.layer = 9;
        playerAttack.transform.localPosition = lPos;

        Debug.Log("Attack Vect: " + playerAttack.transform.position);

        // Initiates the corresponding animation
        attackFlagAir = true;

        switch (input)
        {
        case "Q":
            currentAttack = CurrentAttack.QAirAttack;

            attackHitbox.size   = new Vector2(14, 14);
            attackHitbox.offset = new Vector2(-23f, 25.7f);
            playerHitbox.layer  = 15;
            break;

        case "W":
            currentAttack = CurrentAttack.WAirAttack;

            attackHitbox.size   = size;
            attackHitbox.offset = offset;
            playerHitbox.layer  = 15;
            break;

        case "E":
            currentAttack = CurrentAttack.EAirAttack;

            attackHitbox.size   = new Vector2(30, 38.4f);
            attackHitbox.offset = new Vector2(-24.45f, -7.95f);
            playerHitbox.layer  = 15;
            break;

        case "R":
            currentAttack      = CurrentAttack.RAirAttack;
            playerAttack.layer = 15;
            break;
        }

        // Flips the attack if needed
        if (transform.rotation != Quaternion.identity)
        {
            playerAttack.transform.rotation = Quaternion.Euler(0, 180, 0);
        }
    }
示例#13
0
    /// <summary>
    /// Creates a GameObject in the 'Hitbox' layer that will create the attack and play the animation.
    /// </summary>
    /// <param name="input">The button the player has pressed</param>
    /// <param name="size">Size of the attack hitbox</param>
    /// <param name="offset">Offset of the attack hitbox</param>
    /// <param name="lPos">Position of object's Vector3 in relation to the player</param>
    private void AttackGround(string input, Vector2 size, Vector2 offset, Vector3 lPos)
    {
        Debug.Log("Pressed " + input);

        playerAttack = new GameObject(input + "_Attack");

        playerAttack.transform.SetParent(transform);

        // Creates an attack hitbox on playerAttack and plays correct attack animation
        // IMP - Needs to check if player is flipped or not
        attackCheck = playerAttack.AddComponent <BoxCollider2D>();

        if (input != "R")
        {
            playerHitbox = new GameObject(input + "_Hitbox");
            playerHitbox.transform.SetParent(playerAttack.transform);
            attackHitbox = playerHitbox.AddComponent <BoxCollider2D>();
        }

        attackCheck.size   = size;
        attackCheck.offset = offset;

        playerAttack.layer = 9;
        playerAttack.transform.localPosition = lPos;

        Debug.Log("Attack Vect: " + playerAttack.transform.position);

        // Initiates the corresponding animation
        attackFlag     = true;
        attackCooldown = true;


        switch (input)
        {
        case "Q":
            currentAttack = CurrentAttack.QGroundAttack;

            attackHitbox.size   = new Vector2(21.4f, 21.4f);
            attackHitbox.offset = new Vector2(-19.3f, 32.6f);
            playerHitbox.layer  = 15;
            break;

        case "W":
            currentAttack = CurrentAttack.WGroundAttack;

            attackHitbox.size   = size;
            attackHitbox.offset = offset;
            playerHitbox.layer  = 15;
            break;

        case "E":
            currentAttack = CurrentAttack.EGroundAttack;

            attackHitbox.size   = new Vector2(11, 16);
            attackHitbox.offset = new Vector2(-24.45f, -39.85f);
            playerHitbox.layer  = 15;
            break;

        case "R":
            currentAttack      = CurrentAttack.RGroundAttack;
            playerAttack.layer = 15;
            break;

        case "QC":
            currentAttack = CurrentAttack.QCGroundAttack;
            break;

        case "EC":
            currentAttack = CurrentAttack.ECGroundAttack;
            break;
        }

        // Flips the attack if needed
        if (transform.rotation != Quaternion.identity)
        {
            playerAttack.transform.rotation = Quaternion.Euler(0, 180, 0);
        }
    }
        public override void AI()
        {
            npc.TargetClosest();

            if (cooldownFrames <= 0)
            {
                Main.NewText(currentAttack);
                switch (currentAttack)
                {
                case CurrentAttack.IdleFloat:
                    IdleFloat();
                    break;

                case CurrentAttack.Dash:
                    Dash();
                    break;

                case CurrentAttack.LightningStorm:
                    LightningStorm();
                    break;

                case CurrentAttack.SummonMoths:
                    cooldownFrames = 2;
                    break;

                case CurrentAttack.BlastVolleys:
                    cooldownFrames = 2;
                    break;

                case CurrentAttack.Divebomb:
                    DiveBomb();
                    break;

                case CurrentAttack.CrystalStomp:
                    cooldownFrames = 2;
                    break;

                case CurrentAttack.CrystalSpin:
                    cooldownFrames = 2;
                    break;

                case CurrentAttack.JumpAtPlayer:
                    cooldownFrames = 2;
                    break;

                case CurrentAttack.SummonJolts:
                    cooldownFrames = 2;
                    break;

                default:
                    Main.NewText("Error");
                    cooldownFrames = 2;
                    break;
                }
            }
            else
            {
                if (cooldownFrames == 1)
                {
                    int attack = grounded ? Main.rand.Next(3) + 6 : Main.rand.Next(6);
                    if (!grounded && phaseTwo && Main.rand.Next(8) == 0)
                    {
                        attack = 9;
                    }
                    currentAttack = (CurrentAttack)attack;
                }
                npc.velocity *= 0.97f;
                attackCounter = 0;
                cooldownFrames--;
                if (!grounded)
                {
                    UpdateFrame(0.3f, 0, 6);
                    npc.noGravity     = true;
                    npc.noTileCollide = true;
                }
                else
                {
                    UpdateFrame(0.3f, 8, 17);
                    npc.noGravity     = false;
                    npc.noTileCollide = false;
                }
            }
        }