ACR_CreatureBehavior.CreatureObject.SelectCombatRoundAction C# (CSharp) Method

SelectCombatRoundAction() public method

This function is the primary means by which actions are selected for a given combat round.
public SelectCombatRoundAction ( bool fromAllyCall ) : void
fromAllyCall bool
return void
        public void SelectCombatRoundAction(bool fromAllyCall)
        {
            HasCombatRoundProcess = true;
            if (Script.GetIsObjectValid(ObjectId) == CLRScriptBase.FALSE) return;

            #region Clean Up Before Attempting Action
            List<CreatureObject> deadEnemies = new List<CreatureObject>();
            foreach(CreatureObject enemy in Party.Enemies)
            {
                if(Script.GetCurrentHitPoints(enemy.ObjectId) < 1)
                {
                    if (Script.GetIsPC(enemy.ObjectId) != CLRScriptBase.FALSE)
                    {
                        if (!Party.CleanUpEnemies.Contains(enemy))
                            Party.CleanUpEnemies.Add(enemy);
                    }
                    deadEnemies.Add(enemy);
                }
            }
            foreach(CreatureObject enemy in deadEnemies)
            {
                Party.RemovePartyEnemy(enemy);
            }
            List<CreatureObject> revivedEnemies = new List<CreatureObject>();
            foreach(CreatureObject enemy in Party.CleanUpEnemies)
            {
                if(Script.GetCurrentHitPoints(enemy.ObjectId) > 0)
                {
                    Party.AddPartyEnemy(enemy);
                    revivedEnemies.Add(enemy);
                }
            }
            foreach(CreatureObject enemy in revivedEnemies)
            {
                Party.CleanUpEnemies.Remove(enemy);
            }
            #endregion

            #region Rally Any Party Mates
            if (!fromAllyCall)
            {
                foreach (CreatureObject ally in Party.PartyMembers)
                {
                    if (Script.GetCurrentAction(ally.ObjectId) == CLRScriptBase.ACTION_INVALID)
                    {
                        if (!ally.HasCombatRoundProcess)
                        {
                            ally.HasCombatRoundProcess = true;
                            ally.SelectCombatRoundAction(true);
                        }
                    }
                }
            }
            #endregion

            #region Gather Data on Status
            RefreshNegativeStatuses();
            #endregion

            #region Early return for not being able to act.
            // Can't do anything. Might as well give up early and pray there's help on the way.
            if (!CanAct())
            {
                return;
            }
            #endregion

            #region Specify panic behavior due to injury
            int nWellBeing = HealthPercentage;
            int nMissingHitPoints = MaxHitPoints - CurrentHitPoints;

            // Do we even have anyone to fight?
            if (Party.Enemies.Count == 0 &&
                Party.EnemiesLost.Count == 0)
            {
                HasCombatRoundProcess = false;
                UsingEndCombatRound = false;
                CreatureObject Healer = Party.GetNearest(this, Party.PartyMedics);
                // Everyone gather around the healer; he or she might be using mass heals.
                if (Healer != null && Healer != this)
                {
                    Script.ActionMoveToObject(Healer.ObjectId, CLRScriptBase.TRUE, 1.0f);
                    return;
                }
                if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_MEDIC &&
                    CurrentAction == CLRScriptBase.ACTION_INVALID)
                {
                    if (TryToHealAll())
                        CleanUpNeeded = true;
                    else
                        CleanUpNeeded = false;
                    return;
                }
                else
                    TryToHeal(this, nMissingHitPoints);

                _AmbientBehavior();
                return;
            }

            // Are we in critical condition?
            if (nWellBeing < 10)
            {
                CreatureObject Healer = Party.GetNearest(this, Party.PartyMedics);
                if (Healer == null)
                    Healer = Party.GetNearest(this, Party.PartyBuffs);
                if (Healer != null && Healer != this)
                {
                    if (Script.GetDistanceBetween(Healer.ObjectId, this.ObjectId) > 5.0f)
                    {
                        Script.ActionMoveToObject(Healer.ObjectId, CLRScriptBase.TRUE, 1.0f);
                        TryToHeal(this, nMissingHitPoints);
                        return;
                    }
                }
                else if (Party.PartyLeader != null && Party.PartyLeader != this)
                {
                    Healer = Party.PartyLeader;
                    if (Script.GetDistanceBetween(Healer.ObjectId, this.ObjectId) > 5.0f)
                    {
                        Script.ActionMoveToObject(Healer.ObjectId, CLRScriptBase.TRUE, 1.0f);
                        TryToHeal(this, nMissingHitPoints);
                        return;
                    }
                }
                if (TryToHeal(this, nMissingHitPoints))
                    return;
            }

            #region Early Returns: Mindless
            // We're mindless, and thus too stupid to do anything special. Hit the nearest bad guy.
            if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_MINDLESS)
            {
                CreatureObject AttackTarget = Party.GetNearest(this, Party.Enemies);
                if (AttackTarget == null)
                {
                    uint newEnemy = Script.GetNearestCreature(CLRScriptBase.CREATURE_TYPE_REPUTATION, CLRScriptBase.REPUTATION_TYPE_ENEMY, this.ObjectId, 1, -1, -1, -1, -1);
                    if(Script.GetIsObjectValid(newEnemy) != CLRScriptBase.FALSE &&
                       Script.GetObjectSeen(newEnemy, this.ObjectId) != CLRScriptBase.FALSE &&
                       Script.GetObjectHeard(newEnemy, this.ObjectId) != CLRScriptBase.FALSE)
                    {
                        AttackTarget = Server.ObjectManager.GetCreatureObject(newEnemy, true);
                        Party.AddPartyEnemy(AttackTarget);
                    }
                }
                if (AttackTarget == null) return;
                _AttackWrapper(AttackTarget);
                return;
            }
            #endregion

            // Bad enough to self heal?
            else if (nWellBeing < 50)
            {
                if (TryToHeal(this, nMissingHitPoints))
                    return;
            }
            #endregion

            #region AIType-Specific Behaviors
            #region Animals
            // Time to break off into the particular types
            // Animals are simple creatures; they want to protect themselves and their masters.
            if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_ANIMAL)
            {
                // Animals are too dumb to do anything other than use their direct attacks on foes.
                CreatureObject AttackTarget = Party.GetNearest(this, Party.Enemies);
                if (AttackTarget == null)
                {
                    uint newEnemy = Script.GetNearestCreature(CLRScriptBase.CREATURE_TYPE_REPUTATION, CLRScriptBase.REPUTATION_TYPE_ENEMY, this.ObjectId, 1, -1, -1, -1, -1);
                    if (Script.GetIsObjectValid(newEnemy) != CLRScriptBase.FALSE &&
                       Script.GetObjectSeen(newEnemy, this.ObjectId) != CLRScriptBase.FALSE &&
                       Script.GetObjectHeard(newEnemy, this.ObjectId) != CLRScriptBase.FALSE)
                    {
                        AttackTarget = Server.ObjectManager.GetCreatureObject(newEnemy, true);
                        Party.AddPartyEnemy(AttackTarget);
                    }
                }
                if (AttackTarget == null) return;
                _AttackWrapper(AttackTarget);
                return;
            }
            #endregion

            #region Archers
            // Archers have the advantage of reach and accuracy with acceptable damage. They strike weak and soft targets.
            if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_ARCHER)
            {
                if (TryToAttackRanged())
                    return;
                if (TryToDebuffAll())
                    return;
                if (TryToCallForHelp())
                    return;
                if (TryToDebuffCareful())
                    return;
                if (TryToBuffAll())
                    return;
                if (TryToAttackMelee(true, false))
                    return;
                if (TryToHealAll())
                    return;
                if (TryToCleanUp())
                    return;

                // We don't have anything productive to do. Figure out who we'd like to snuggle up against.
                if (Party.PartyMedics.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMedics).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyBuffs.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyBuffs).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyArchers.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyArchers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyMembers.Count > 1)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMembers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                return;
            }
            #endregion

            #region Buffs
            // Buffs try to boost the capabilities of their allies
            if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_BUFFS)
            {
                if (TryToBuffAll())
                    return;
                if (TryToHealAll())
                    return;
                if (TryToCallForHelp())
                    return;
                if (TryToDebuffAll())
                    return;
                if (TryToDebuffCareful())
                    return;
                if (TryToAttackRanged())
                    return;
                if (TryToAttackMelee())
                    return;
                if (TryToCleanUp())
                    return;

                // We don't have anything productive to do. Figure out who we'd like to snuggle up against.
                if (Party.PartyMedics.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMedics).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }                
                if (Party.PartyControls.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyControls).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyNukes.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyNukes).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyMembers.Count > 1)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMembers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                return;
            }
            #endregion

            #region Controls
            // Controls try to debuff enemies and impede movement on the field.
            if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_CONTROL)
            {
                if (TryToDebuffAll())
                    return;
                if (TryToCallForHelp())
                    return;
                if (TryToDebuffCareful())
                    return;
                if (TryToBuffAll())
                    return;
                if (TryToHealAll())
                    return;
                if (TryToAttackRanged())
                    return;
                if (TryToAttackMelee())
                    return;
                if (TryToCleanUp())
                    return;

                // We don't have anything productive to do. Figure out who we'd like to snuggle up against.
                if (Party.PartyMedics.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMedics).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyBuffs.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyBuffs).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyNukes.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyNukes).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyMembers.Count > 1)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMembers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                return;
            }
            #endregion

            #region Cowards
            // Cowards avoid fights and look for help.
            if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_COWARD)
            {
                CreatureObject medic = Party.GetNearest(this, Party.PartyMedics);
                if(medic == null)
                {
                    medic = Party.GetNearest(this, Party.PartyMembers);
                }
                if(medic != null)
                {
                    Script.AssignCommand(ObjectId, delegate { Script.ActionMoveToObject(medic.ObjectId, CLRScriptBase.TRUE, 1.0f); });
                }
                else if(Party.Enemies.Count > 0)
                {
                    Script.AssignCommand(ObjectId, delegate { Script.ActionMoveAwayFromObject(Party.Enemies[0].ObjectId, CLRScriptBase.TRUE, 50.0f); });
                }
                return;
            }
            #endregion

            #region Flanks
            // Flanks try to backstab people, and counter attack people who come after squishies.
            if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_FLANK)
            {
                if (TryToAttackMelee(true, false))
                    return; 
                if (TryToAttackRanged())
                    return;
                if (TryToDebuffAll())
                    return;
                if (TryToDebuffCareful())
                    return;
                if (TryToBuffAll())
                    return;
                if (TryToCallForHelp())
                    return;
                if (TryToHealAll())
                    return;
                if (TryToCleanUp())
                    return;

                // We don't have anything productive to do. Figure out who we'd like to snuggle up against.
                if (Party.PartyMedics.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMedics).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyBuffs.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyBuffs).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyArchers.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyArchers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyMembers.Count > 1)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMembers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                return;
            }
            #endregion

            #region Medics
            // Medics try to heal their friends.
            if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_MEDIC)
            {
                if (TryToHealAll())
                    return;
                if (TryToBuffAll())
                    return;
                if (TryToDebuffAll())
                    return;
                if (TryToDebuffCareful())
                    return;
                if (TryToCallForHelp())
                    return;
                if (TryToAttackRanged())
                    return;
                if (TryToAttackMelee())
                    return;
                if (TryToCleanUp())
                    return;

                // We don't have anything productive to do. Figure out who we'd like to snuggle up against.
                if(Party.PartyArchers.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyArchers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if(Party.PartyBuffs.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyBuffs).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if(Party.PartyControls.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyControls).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyNukes.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyNukes).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyMedics.Count > 1)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMedics).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if(Party.PartyMembers.Count > 1)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMembers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                return;
            }
            #endregion

            #region Nukes
            // Nukes try to explode hardened targets.
            if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_NUKE)
            {
                if (TryToDebuffAll())
                    return;
                if (TryToDebuffCareful())
                    return;
                if (TryToBuffAll())
                    return;
                if (TryToCallForHelp())
                    return;                
                if (TryToHealAll())
                    return;
                if (TryToAttackRanged())
                    return;
                if (TryToAttackMelee())
                    return;
                if (TryToCleanUp())
                    return;

                // We don't have anything productive to do. Figure out who we'd like to snuggle up against.
                if (Party.PartyMedics.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMedics).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyArchers.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyArchers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyBuffs.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyBuffs).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyControls.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyControls).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyMembers.Count > 1)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMembers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                return;
            }
            #endregion

            #region Shocks
            // Shocks try to break through the lines and take down squishies.
            if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_SHOCK)
            {
                if (TryToAttackMelee(true, false))
                    return;
                if (TryToAttackRanged())
                    return;
                if (TryToDebuffAll())
                    return;
                if (TryToDebuffCareful())
                    return;
                if (TryToBuffAll())
                    return;
                if (TryToCallForHelp())
                    return;
                if (TryToHealAll())
                    return;
                if (TryToCleanUp())
                    return;

                // We don't have anything productive to do. Figure out who we'd like to snuggle up against.
                if (Party.PartyMedics.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMedics).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyBuffs.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyBuffs).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyArchers.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyArchers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyMembers.Count > 1)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMembers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                return;
            }
            #endregion

            #region Skirmishers
            // Skirmishers try to resist shocks, flanks, and other skirmishers.
            if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_SKIRMISH)
            {
                if (TryToAttackRanged())
                    return;                
                if (TryToAttackMelee(true, false))
                    return;
                if (TryToDebuffAll())
                    return;
                if (TryToDebuffCareful())
                    return;
                if (TryToBuffAll())
                    return;
                if (TryToCallForHelp())
                    return;
                if (TryToHealAll())
                    return;
                if (TryToCleanUp())
                    return;

                // We don't have anything productive to do. Figure out who we'd like to snuggle up against.
                if (Party.PartyMedics.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMedics).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyBuffs.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyBuffs).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return; 
                }
                if (Party.PartyArchers.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyArchers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return; 
                }
                if (Party.PartyMembers.Count > 1)
                { 
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMembers).ObjectId, CLRScriptBase.TRUE, 3.0f); 
                    return; 
                }
                return;
            }
            #endregion

            #region Tanks
            // Tanks try to hold ground and contain dangerous foes.
            if (TacticsType == AIParty.AIType.BEHAVIOR_TYPE_TANK)
            {
                if (TryToAttackMelee(false, true))
                    return;
                if (TryToAttackRanged())
                    return;
                if (TryToDebuffAll())
                    return;
                if (TryToDebuffCareful())
                    return;
                if (TryToBuffAll())
                    return;
                if (TryToCallForHelp())
                    return;
                if (TryToHealAll())
                    return;
                if (TryToCleanUp())
                    return;

                // We don't have anything productive to do. Figure out who we'd like to snuggle up against.
                if (Party.PartyMedics.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMedics).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return; 
                }
                if (Party.PartyBuffs.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyBuffs).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return; 
                }
                if (Party.PartyArchers.Count > 0)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyArchers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                if (Party.PartyMembers.Count > 1)
                {
                    Script.ActionMoveToObject(Party.GetNearest(this, Party.PartyMembers).ObjectId, CLRScriptBase.TRUE, 3.0f);
                    return;
                }
                return;
            }
            #endregion
            #endregion
            // Making it this far is some kind of error case. Try to salvage something.

            return;
        }