134 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| /*//////////////////////////////////////////////////////////////////////////////
 | |
|  Script Name: ai_coward
 | |
| ////////////////////////////////////////////////////////////////////////////////
 | |
|  ai script for cowardly creatures (Any) used when they fail a moral check or
 | |
|  when associates are to remain out of combat.
 | |
|  OBJECT_SELF is the creature running the ai.
 | |
| ////////////////////////////////////////////////////////////////////////////////
 | |
|  Programmer: Philos
 | |
| *///////////////////////////////////////////////////////////////////////////////
 | |
| #include "0i_actions"
 | |
| void main()
 | |
| {
 | |
|     object oCreature = OBJECT_SELF;
 | |
|     // Get the number of enemies that we are in melee combat with us.
 | |
|     int nInMelee = ai_GetNumOfEnemiesInRange(oCreature);
 | |
|     object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST);
 | |
|     // If we have been healed up then get back in there!
 | |
|     if(ai_GetPercHPLoss(oCreature) > AI_HEALTH_WOUNDED)
 | |
|     {
 | |
|         string sDefaultCombatScript = GetLocalString(oCreature, AI_DEFAULT_SCRIPT);
 | |
|         SetLocalString(oCreature, AI_COMBAT_SCRIPT, sDefaultCombatScript);
 | |
|         ExecuteScript(sDefaultCombatScript, oCreature);
 | |
|         return;
 | |
|     }
 | |
|     // In Melee combat!
 | |
|     if(nInMelee)
 | |
|     {
 | |
|         if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return;
 | |
|         if(ai_TryImprovedExpertiseFeat(oCreature)) return;
 | |
|         if(ai_TryExpertiseFeat(oCreature)) return;
 | |
|         // Lets get the strongest melee opponent in melee with us.
 | |
|         object oTarget = ai_GetHighestCRTargetForMeleeCombat(oCreature, nInMelee);
 | |
|         if(oTarget == OBJECT_INVALID) oTarget = oNearestEnemy;
 | |
|         // Use knockdown when appropriate and the target is not immune.
 | |
|         if(ai_TryKnockdownFeat(oCreature, oTarget)) return;
 | |
|         if (ai_TryParry(oCreature)) return;
 | |
|         // We have tried everything to protect ourselves so the only thing left
 | |
|         // to do is man up and attack!
 | |
|         // Physical attacks are under TALENT_CATEGORY_HARMFUL_MELEE(22).
 | |
|         ai_DoPhysicalAttackOnNearest(oCreature, nInMelee);
 | |
|         return;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         // If can turn invisible then we should probably do that!
 | |
|         if(ai_UseTalent(oCreature, SPELL_IMPROVED_INVISIBILITY, oCreature)) return;
 | |
|         if(ai_UseTalent(oCreature, SPELL_INVISIBILITY, oCreature)) return;
 | |
|         if(ai_UseTalent(oCreature, SPELL_INVISIBILITY_SPHERE, oCreature)) return;
 | |
|         if(ai_UseTalent(oCreature, SPELL_SANCTUARY, oCreature)) return;
 | |
|         if(ai_UseTalent(oCreature, SPELL_ETHEREALNESS, oCreature)) return; // Greater Sanctuary
 | |
|         if(ai_UseTalent(oCreature, SPELLABILITY_AS_IMPROVED_INVISIBLITY, oCreature)) return;
 | |
|         if(ai_UseTalent(oCreature, SPELLABILITY_AS_INVISIBILITY, oCreature)) return;
 | |
|         // If we are seen by the enemy we need to move back so we can hide.
 | |
|         int nEnemyIndex = ai_GetNearestIndexThatSeesUs(oCreature);
 | |
|         if(nEnemyIndex)
 | |
|         {
 | |
|             // Check for an attacker and can they see through invisibility?
 | |
|             object oAttacker = ai_GetEnemyAttackingMe(oCreature);
 | |
|             int bCanSeeInvisible;
 | |
|             if(oAttacker != OBJECT_INVALID)
 | |
|             {
 | |
|                 bCanSeeInvisible = ai_GetHasEffectType(oAttacker, EFFECT_TYPE_SEEINVISIBLE);
 | |
|                 if(!bCanSeeInvisible) bCanSeeInvisible = ai_GetHasEffectType(oAttacker, EFFECT_TYPE_TRUESEEING);
 | |
|                 if(!bCanSeeInvisible) bCanSeeInvisible = GetHasFeat(FEAT_BLINDSIGHT_5_FEET, oCreature);
 | |
|                 if(!bCanSeeInvisible) bCanSeeInvisible = GetHasFeat(FEAT_BLINDSIGHT_10_FEET, oCreature);
 | |
|                 if(!bCanSeeInvisible) bCanSeeInvisible = GetHasFeat(FEAT_BLINDSIGHT_60_FEET, oCreature);
 | |
|             }
 | |
|             if(!bCanSeeInvisible)
 | |
|             {
 | |
|                 if(GetHasFeat(FEAT_HIDE_IN_PLAIN_SIGHT, oCreature))
 | |
|                 {
 | |
|                     if(!GetActionMode(oCreature, ACTION_MODE_STEALTH))
 | |
|                     {
 | |
|                         if(AI_DEBUG) ai_Debug("ai_coward", "74", GetName(oCreature) + " is using hide in plain sight!");
 | |
|                         ClearAllActions(TRUE);
 | |
|                         SetActionMode(oCreature, ACTION_MODE_STEALTH, TRUE);
 | |
|                         return;
 | |
|                     }
 | |
|                 }
 | |
|                 // Does not have hide in plain sight.
 | |
|                 else
 | |
|                 {
 | |
|                     string sEnemyIndex = IntToString(nEnemyIndex);
 | |
|                     float fEnemyDistance = GetLocalFloat(oCreature, AI_ENEMY_RANGE + sEnemyIndex);
 | |
|                     if(AI_DEBUG) ai_Debug("ai_coward", "85", "fDistance: " + FloatToString(fEnemyDistance, 0, 2));
 | |
|                     if(fEnemyDistance >= AI_RANGE_CLOSE)
 | |
|                     {
 | |
|                         int bTried = GetLocalInt(oCreature, AI_TRIED_TO_HIDE);
 | |
|                         if(!bTried)
 | |
|                         {
 | |
|                             // Move away so we can hide.
 | |
|                             if(AI_DEBUG) ai_Debug("ai_coward", "93", GetName(oCreature) + " is trying to move away to hide!");
 | |
|                             SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE);
 | |
|                             object oEnemy = GetLocalObject(oCreature, AI_ENEMY + sEnemyIndex);
 | |
|                             ActionMoveAwayFromObject(oEnemy, TRUE, AI_RANGE_BATTLEFIELD);
 | |
|                             SetLocalInt(oCreature, AI_TRIED_TO_HIDE, 3);
 | |
|                             return;
 | |
|                         }
 | |
|                         else SetLocalInt(oCreature, AI_TRIED_TO_HIDE, GetLocalInt(oCreature, AI_TRIED_TO_HIDE) - 1);
 | |
|                     }
 | |
|                     // We have been seen by an enemy near us so drop stealth.
 | |
|                     else SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE);
 | |
|                 }
 | |
|             }
 | |
|             // The enemy can see through stealth so lets drop it.
 | |
|             else SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE);
 | |
|         }
 | |
|         // We are not in stealth mode so lets get there.
 | |
|         else if(!GetActionMode(oCreature, ACTION_MODE_STEALTH))
 | |
|         {
 | |
|             // Use any hiding talents we have
 | |
|             if(AI_DEBUG) ai_Debug("ai_coward", "113", GetName(oCreature) + " is trying to hide!");
 | |
|             SetActionMode(oCreature, ACTION_MODE_STEALTH, TRUE);
 | |
|             SetLocalInt(oCreature, AI_TRIED_TO_HIDE, 3);
 | |
|             return;
 | |
|         }
 | |
|     }
 | |
|     // Either we cannot go into stealth or we are in stealth so do something else.
 | |
|     //*************************  OUT OF MELEE COMBAT  **************************
 | |
|     //***************************  HEALING & CURES  ****************************
 | |
|     if(ai_TryHealingTalent(oCreature, 0, oCreature)) return;
 | |
|     if(ai_TryCureConditionTalent(oCreature, 0)) return;
 | |
|     int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature);
 | |
|     //**************************  DEFENSIVE TALENTS  ***************************
 | |
|     if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS))
 | |
|     {
 | |
|         if(ai_TrySummonFamiliarTalent(oCreature)) return;
 | |
|         if(ai_TrySummonAnimalCompanionTalent(oCreature)) return;
 | |
|     }
 | |
|     if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel)) return;
 | |
|     // Stand and watch the battle we don't want to provoke anyone!
 | |
|     if(AI_DEBUG) ai_Debug("ai_coward", "132", GetName(oCreature) + " is holding here.");
 | |
| }
 |