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; } }
/// <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(); }
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); } }
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); } }
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); } }
// 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; } }
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; } }
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); } } } } }
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); } }
/// <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; } } }