/// <summary> /// Does attack behavior, if no attackTarget, Seek for one. If there is one, attack! /// </summary> public void DoAttackBehavior(List <Player> a_players, PathFinder a_pathfinder, ViewClasses.iParticles a_particleHandler, float a_elapsedTime) { Cooldown(a_elapsedTime); if (m_attacker.m_thingState == ThingState.Hold || m_attacker.m_thingState == ThingState.Hunting) { m_baseState = m_attacker.m_thingState; } //All the stuff you can't be when attacking. if (m_attacker.m_thingState != ThingState.Moving && m_attacker.m_thingState != ThingState.Building) { foreach (Player player in a_players) { Seek(player); } //if you have no target if (m_target == null) { if (m_attacker.m_currentposition != m_huntingPosition && m_baseState == ThingState.Hunting) { StartHunting(m_huntingPosition, a_pathfinder); } else if (m_attacker.m_currentposition == m_huntingPosition && m_baseState == ThingState.Hunting) { m_baseState = ThingState.Idle; } m_absoluteTarget = false; }//if you doo! else { Attack(a_pathfinder, a_particleHandler); } } }
public void Attack(PathFinder a_pathFinder, ViewClasses.iParticles a_particleHandler) { /* Flow: * 1. Is target alive or dead? * 2. Is target inside my chase range? * 3. Is target inside my attack range? * 4. Is my state Attacking? * 5. Is my attack ready? * 6. Do Damage and set cooldown to the attackrate * 7. If target is dead after dealing damage, set my state to my baseState (Hold or Hunting) * * 1a. If Target is dead set my attack target to null * 2a. If target is outside my chase range, I stop attacking the target and go back to my previous state (Hunting, or Hold tho Hold should never happen) * 3a. If target is outside my attack range and my baseState = Hold, I drop my target. * 3b. If target is outside my attack range I will start to chase target! * 4a. If my state is not Attacking but Chasing I will set my state to Idle * 4b. If my state is not Attacking but Hold or Idle I will set my state to Attacking * 5b. If my attack is not ready, do nothing */ //If target is alive try to attack if (m_target.m_alive && m_target.m_exists) { float f_length = CalculateLengthToATarget(m_target); //If target is within chase range if (f_length <= m_chaseRangeSquared) { //If target is within attackrange if (f_length <= m_attackRangeSquared) { if (m_attacker.m_thingState == ThingState.Attacking) { //if cooldown is ready, do the attack check if (m_cooldownTimer <= 0) { m_target.TakeDamage(m_damage); m_cooldownTimer = m_attackRate; a_particleHandler.CreateOddys(m_attacker.m_currentposition, ref m_target.m_currentposition); if (!m_target.m_alive) { m_attacker.m_thingState = m_baseState; } } }//Sets attacker state from Chasing -> Idle -> Attacking else if (m_attacker.m_thingState == ThingState.Chasing || m_attacker.m_thingState == ThingState.Hunting) { m_attacker.m_thingState = ThingState.Idle; }//If the state is idle or hold the unit can attack! else if (m_attacker.m_thingState == ThingState.Idle || m_attacker.m_thingState == ThingState.Hold) { m_attacker.m_thingState = ThingState.Attacking; } }//If outside the attackerRange and the state is hold do: else if (m_baseState == ThingState.Hold) { //Set the attackerTarget to null, since someone else might be inside the attack range m_target = null; }//If the unit is idling it will chase target else { if (a_pathFinder.FindPath(m_attacker.m_currentposition, m_target.m_currentposition) == 1) { ChaseTarget(a_pathFinder.m_pathList); }//if unit can't find path to target, drop it! else { m_target = null; } } }//If the target was selected by player, chase it till the end of time! else if (m_absoluteTarget) { if (a_pathFinder.FindPath(m_attacker.m_currentposition, m_target.m_currentposition) == 1) { ChaseTarget(a_pathFinder.m_pathList); }//if unit can't find path to target, drop it! else { m_target = null; } }//If outside chase range else { //If the base state was hold or hunting, go back to doing that! if (m_baseState == ThingState.Hold || m_baseState == ThingState.Hunting) { m_attacker.m_thingState = m_baseState; } m_target = null; } }//If target is dead else { //set attack target to null so Seek is called again m_target = null; m_attacker.m_thingState = m_baseState; } }