/*////////////////////////////////////////////////////////////////////////////// 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."); }