Battledale_PRC8/_removed/nw_i0_generic.nss
Jaysyn904 7b9e44ebbb Initial upload
Initial upload.  PRC8 has been added.  Module compiles, PRC's default AI & treasure scripts have been integrated.  Started work on top hak for SLA / Ability / Scripting modifications.
2024-03-11 23:44:08 -04:00

1398 lines
52 KiB
Plaintext

////::////////////////////////////////////////////////
//:: Generic Scripting Include v1.0
//:: NW_I0_GENERIC
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
********************************************
WARNING THIS SCRIPT IS CHANGED AT YOUR PERIL
********************************************
This is the master generic script and currently
handles all combat and some plot behavior
within NWN. If this script is tampered
with there is a chance of introducing game
breaking bugs. But other than that enjoy.
*/
//::///////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Sept 20, 2001
//::///////////////////////////////////////////////
#include "jw_talents_inc"
#include "jw_walkways_inc"
//GENERIC STRUCTURES
struct sSpellSelect
{
int RANGED;
int MELEE;
object GROUP_TARGET;
object MOB_TARGET;
object MELEE_TOUGHEST;
object TOUGHEST_TARGET;
int ENEMY_HD;
int ALLIED_HD;
};
//Flee and move constants
int NW_GENERIC_FLEE_EXIT_FLEE = 0;
int NW_GENERIC_FLEE_EXIT_RETURN = 1;
int NW_GENERIC_FLEE_TELEPORT_FLEE = 2;
int NW_GENERIC_FLEE_TELEPORT_RETURN = 3;
//Shout constants
int NW_GENERIC_SHOUT_I_WAS_ATTACKED = 1; // NOT USED
int NW_GENERIC_SHOUT_I_AM_DEAD = 12; //IN OnDeath Script
int NW_GENERIC_SHOUT_BACK_UP_NEEDED = 13; //IN TalentMeleeAttacked
int NW_GENERIC_SHOUT_BLOCKER = 2;
//Master Constants
int NW_FLAG_SPECIAL_CONVERSATION = 0x00000001;
int NW_FLAG_SHOUT_ATTACK_MY_TARGET = 0x00000002;
int NW_FLAG_STEALTH = 0x00000004;
int NW_FLAG_SEARCH = 0x00000008;
int NW_FLAG_SET_WARNINGS = 0x00000010;
int NW_FLAG_ESCAPE_RETURN = 0x00000020; //Failed
int NW_FLAG_ESCAPE_LEAVE = 0x00000040;
int NW_FLAG_TELEPORT_RETURN = 0x00000080; //Failed
int NW_FLAG_TELEPORT_LEAVE = 0x00000100;
int NW_FLAG_PERCIEVE_EVENT = 0x00000200;
int NW_FLAG_ATTACK_EVENT = 0x00000400;
int NW_FLAG_DAMAGED_EVENT = 0x00000800;
int NW_FLAG_SPELL_CAST_AT_EVENT = 0x00001000;
int NW_FLAG_DISTURBED_EVENT = 0x00002000;
int NW_FLAG_END_COMBAT_ROUND_EVENT = 0x00004000;
int NW_FLAG_ON_DIALOGUE_EVENT = 0x00008000;
int NW_FLAG_RESTED_EVENT = 0x00010000;
int NW_FLAG_DEATH_EVENT = 0x00020000;
int NW_FLAG_SPECIAL_COMBAT_CONVERSATION = 0x00040000;
int NW_FLAG_AMBIENT_ANIMATIONS = 0x00080000;
int NW_FLAG_HEARTBEAT_EVENT = 0x00100000;
int NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS = 0x00200000;
int NW_FLAG_DAY_NIGHT_POSTING = 0x00400000;
int NW_FLAG_AMBIENT_ANIMATIONS_AVIAN = 0x00800000;
int NW_FLAG_APPEAR_SPAWN_IN_ANIMATION = 0x01000000;
int NW_FLAG_SLEEPING_AT_NIGHT = 0x02000000;
int NW_FLAG_FAST_BUFF_ENEMY = 0x04000000;
//Behavior Constants
int NW_FLAG_BEHAVIOR_SPECIAL = 0x00000001;
int NW_FLAG_BEHAVIOR_CARNIVORE = 0x00000002; //Will always attack regardless of faction
int NW_FLAG_BEHAVIOR_OMNIVORE = 0x00000004; //Will only attack if approached
int NW_FLAG_BEHAVIOR_HERBIVORE = 0x00000008; //Will never attack. Will alway flee.
//CORE AI FUNCTIONS
void DetermineCombatRound(object oIntruder = OBJECT_INVALID, int nAI_Difficulty = 10);
void SetListeningPatterns();
void RespondToShout(object oShouter, int nShoutIndex, object oIntruder = OBJECT_INVALID);
//PLOT FUNCTIONS
void SetNPCWarningStatus(int nStatus = TRUE);
int GetNPCWarningStatus();
void SetSummonHelpIfAttacked();
void CreateSignPostNPC(string sTag, location lLocal);
void ActivateFleeToExit();
int GetFleeToExit();
//AMBIENT ANIMATION COMMANDS
void PlayMobileAmbientAnimations();
void PlayImmobileAmbientAnimations();
//BEHAVIOR LOCAL FUNCTIONS
void SetBehaviorState(int nCondition, int bValid = TRUE);
int GetBehaviorState(int nCondition);
void DetermineSpecialBehavior(object oIntruder = OBJECT_INVALID);
//::///////////////////////////////////////////////
//:: Master Local Get and Set
//:: FileName
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
All On Spawn in conditions in the game are now
being stored within one local. The get and set
changed or checks the condition of this one
Hex local. The NW_FLAG_XXX variables above
allow for the user of these functions throughout
the generic scripts.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 14, 2001
//:://////////////////////////////////////////////
//::///////////////////////////////////////////////
//:: DetermineCombatRound
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
This function is the master function for the
generic include and is called from the main
script. This function is used in lieu of
any actual scripting.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 16, 2001
//:://////////////////////////////////////////////
void DetermineCombatRound(object oIntruder = OBJECT_INVALID, int nAI_Difficulty = 10)
{
MyPrintString("********************** DETERMINE COMBAT ROUND START ****************************************");
MyPrintString("********************** " + GetTag(OBJECT_SELF) + " ****************************************");
if(GetAssociateState(NW_ASC_IS_BUSY))
{
return;
}
// very first thing we do is run away if we are a commoner or coward
object oAttacker=GetTarget();
int nCoward=FALSE;
if ((GetLevelByClass(CLASS_TYPE_COMMONER)>=1)||(GetLocalInt(OBJECT_SELF,"coward")==TRUE))
{
nCoward=TRUE;
}
if ((GetObjectSeen(oAttacker))&&(nCoward==TRUE))
{
TalentFlee(oAttacker);
return;
}
/*
// Added this to try to fix bug of mobs not attacking
object oHostile=GetLastHostileActor();
if (!GetIsEnemy(oHostile))
{
SetIsTemporaryEnemy(oHostile);
SetIsTemporaryEnemy(OBJECT_SELF,oHostile);
}
*/
if (GetHasEffect(EFFECT_TYPE_FRIGHTENED)||GetHasEffect(EFFECT_TYPE_TURNED))
{
ClearAllActions();
TalentFlee(oAttacker);
return;
}
if (GetHasEffect(EFFECT_TYPE_PARALYZE)||GetHasEffect(EFFECT_TYPE_STUNNED)||GetHasEffect(EFFECT_TYPE_CUTSCENE_PARALYZE))
{
return;
}
if (!GetIsObjectValid(oIntruder))
{
oIntruder=ChooseTarget();
}
if (!GetObjectSeen(oIntruder)||!GetIsObjectValid(oIntruder)||GetIsDeadOrBleeding(oIntruder))
{
oIntruder=GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,OBJECT_SELF,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN_AND_HEARD);
}
if (!GetIsObjectValid(oIntruder))
{
oIntruder=GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,OBJECT_SELF,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN_AND_NOT_HEARD);
}
if (!GetIsObjectValid(oIntruder))
{
oIntruder=GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,OBJECT_SELF,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_HEARD_AND_NOT_SEEN);
}
int nClass = DetermineClassToUse();
///This check is to see if the master is being attacked and in need of help
if(GetAssociateState(NW_ASC_HAVE_MASTER))
{
if(GetAssociateState(NW_ASC_MODE_DEFEND_MASTER))
{
oIntruder = GetLastHostileActor(GetMaster());
if(!GetIsObjectValid(oIntruder))
{
oIntruder = GetGoingToBeAttackedBy(GetMaster());
if(!GetIsObjectValid(oIntruder))
{
oIntruder = GetLastHostileActor();
if(!GetIsObjectValid(oIntruder))
{
return;
}
else if(!GetIsEnemy(oIntruder))
{
oIntruder = OBJECT_INVALID;
}
}
}
}
}
if(GetIsObjectValid(GetMaster()))
{
if(GetDistanceToObject(GetMaster()) > 15.0)
{
if(GetCurrentAction(GetMaster()) != ACTION_FOLLOW)
{
ClearAllActions();
//ActionAttack(OBJECT_INVALID);
ActionForceFollowObject(GetMaster(), GetFollowDistance());
//ActionForceMoveToObject(GetMaster(), TRUE, GetFollowDistance(), 5.0);
return;
}
}
}
int nOffense = d100();
MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Offense Roll " + IntToString(nOffense));
if(GetIsObjectValid(oIntruder) ||
GetIsObjectValid(GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN)) ||
(GetIsObjectValid(oIntruder) && GetIsObjectValid(GetMaster())))
{
///// Palmer's list of things the mob will do.
//Use healing potions to not die
if(TalentHealingSelf()) { return;}
//Check if allies or self are injured
if(TalentHeal()) { return;}
// Heal undead
// Heal undead is not currently working
//if(TalentHealUndead()) { return;}
if(TalentPersistentAbilities()) { return;}
// use aura
if(TalentDismissal(oIntruder)) { return;}
// dismiss summoned mob if possible
if(TalentSummonAllies()) {return;}
//Summon allies if posible
// if(TalentBlackguardAura(oIntruder)) { return;}
// do blackgaurd aura if possible
if(TalentBardSong()) { return;}
// do bard song if possible
if(TalentCurseSong(oIntruder)) { return;}
// do curse song if possible
if(TalentBuffSelf()) { return;}
// use potions on self
if(TalentUseEnhancementOnSelf()) { return;}
//Use Enhancements on self
if(TalentEnhanceOthers()) { return;}
//use enhancement on others
if(TalentUseProtectionOnSelf()) { return;}
// use basic protection on self
if(TalentUseProtectionOthers()) {return;}
//Check if the character can enhance themselves
if(TalentCureCondition()) { return;}
//cure allies
if(TalentMimicCombat(oIntruder)) { return;}
// MimicCombat
if(TalentThrowTree(oIntruder)) { return;}
// Throw a tree
if(TalentBlindSpit(oIntruder)) { return;}
// spitting spider attack
if(TalentGarotte (oIntruder)) { return;}
// Use a garotte
if(TalentDispelEffects(oIntruder)) { return;}
// Dispel effects if possible
if(TalentDragonCombat(oIntruder)) { return;}
// use dragon breath
if(TalentSneakAttack()) { return;}
// sneak if rogue
if(TalentAdvancedProtectSelf()) {return;} //******************************************//
//Use advanced protections on Self
if(TalentFlyToEnemy(oIntruder)) { return;}
// fly to enemy
if (TalentWingBlast(oIntruder)) {return;}
if (TalentUseTurning()) { return;}
// turn undead
if(TalentRangedAttackers(oIntruder)) { return;}
//cast ranged spells
if(TalentRangedEnemies(oIntruder)) { return;}
// cast ranged spells
if(TalentMeleeAttacked(oIntruder)) { return;}
// cast melee spells
if(TalentSpellAttack(oIntruder)) {return;}
//Spell Attack
if(TalentMeleeAttack(oIntruder)) { return;}
// just hit them
if(TalentFlee(oIntruder)) { return;}
// run away
SendMessageToAllDMs("My AI is failing, I am "+GetName(OBJECT_SELF)+" in "+GetName(GetArea(OBJECT_SELF)));
return;
}
//This check is to make sure that people do not drop out of combat before they are supposed to.
object oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
if(GetIsObjectValid(oTarget))
{
SpeakString("Danger Will Robinson Danger");
DetermineCombatRound(oTarget);
return;
}
//This is a call to the function which determines which way point to go back to.
ClearAllActions();
SetLocalObject(OBJECT_SELF, "NW_GENERIC_LAST_ATTACK_TARGET", OBJECT_INVALID);
WalkWayPoints();
}
//::///////////////////////////////////////////////
//:: SetListeningPatterns
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Sets the correct listen checks on the NPC by
determining what talents they possess or what
class they use.
This is also a good place to set up all of
the sleep and appear disappear animations for
various models.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 24, 2001
//:://////////////////////////////////////////////
void SetListeningPatterns()
{
//There is a 70% chance to make someone sleep if it is night.
//If they have no way points to walk.
if(GetIsNight() && !CheckWayPoints())
{
if(GetSpawnInCondition(NW_FLAG_SLEEPING_AT_NIGHT))
{
if(d10() <= 7)
{
int nRand = Random(361);
SetFacing(IntToFloat(nRand));
//effect eSleep = EffectSleep();
//ApplyEffectToObject(DURATION_TYPE_PERMANENT, eSleep, OBJECT_SELF);
}
}
}
if(GetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION))
{
MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "USING SPAWN IN CONDITION NOW BASTARDO");
effect eAppear = EffectAppear();
ApplyEffectToObject(DURATION_TYPE_INSTANT, eAppear, OBJECT_SELF);
}
SetListening(OBJECT_SELF, TRUE);
SetListenPattern(OBJECT_SELF, "NW_I_WAS_ATTACKED", 1);
//This sets the commoners listen pattern to mob under
//certain conditions
if(GetLevelByClass(CLASS_TYPE_COMMONER) > 0)
{
SetListenPattern(OBJECT_SELF, "NW_MOB_ATTACK", 2);
}
SetListenPattern(OBJECT_SELF, "NW_I_AM_DEAD", 3);
//Set a custom listening pattern for the creature so that placables with
//"NW_BLOCKER" + Blocker NPC Tag will correctly call to their blockers.
string sBlocker = "NW_BLOCKER_BLK_" + GetTag(OBJECT_SELF);
SetListenPattern(OBJECT_SELF, sBlocker, 4);
SetListenPattern(OBJECT_SELF, "NW_CALL_TO_ARMS", 6);
}
//::///////////////////////////////////////////////
//:: Respond To Shouts
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Allows the listener to react in a manner
consistant with the given shout but only to one
combat shout per round
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 25, 2001
//:://////////////////////////////////////////////
//NOTE ABOUT COMMONERS
/*
Commoners are universal cowards. If you attack anyone they will flee for 4 seconds away from the attacker.
However to make the commoners into a mob, make a single commoner at least 10th level of the same faction.
If that higher level commoner is attacked or killed then the commoners will attack the attacker. They will disperse again
after some of them are killed. Should NOT make multi-class creatures using commoners.
*/
//NOTE ABOUT BLOCKERS
/*
It should be noted that the Generic Script for On Dialogue attempts to get a local set on the shouter by itself.
This object represents the LastOpenedBy object. It is this object that becomes the oIntruder within this function.
*/
//NOTE ABOUT INTRUDERS
/*
The intruder object is for cases where a placable needs to pass a LastOpenedBy Object or a AttackMyAttacker
needs to make his attacker the enemy of everyone.
*/
void RespondToShout(object oShouter, int nShoutIndex, object oIntruder = OBJECT_INVALID)
{
switch (nShoutIndex)
{
case 1://NW_GENERIC_SHOUT_I_WAS_ATTACKED:
{
object oTarget = oIntruder;
if(!GetIsObjectValid(oTarget))
{
oTarget = GetLastHostileActor(oShouter);
}
if(!GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL))
{
if(!GetLevelByClass(CLASS_TYPE_COMMONER))
{
if(!GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()))
{
if(GetIsObjectValid(oTarget))
{
if(!GetIsFriend(oTarget) && GetIsFriend(oShouter))
{
RemoveAmbientSleep();
//DetermineCombatRound(oTarget);
DetermineCombatRound(GetLastHostileActor(oShouter));
}
}
}
}
else if (GetLevelByClass(CLASS_TYPE_COMMONER, oShouter) >= 10)
{
ActionAttack(GetLastHostileActor(oShouter));
}
else
{
DetermineCombatRound(oIntruder);
}
}
else
{
DetermineSpecialBehavior();
}
}
break;
case 2://NW_GENERIC_SHOUT_MOB_ATTACK:
{
if(!GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL))
{
//Is friendly check to make sure that only like minded commoners attack.
if(GetIsFriend(oShouter))
{
ActionAttack(GetLastHostileActor(oShouter));
}
//if(TalentMeleeAttack()) {return;}
}
else
{
DetermineSpecialBehavior();
}
}
break;
case 3://NW_GENERIC_SHOUT_I_AM_DEAD:
{
if(!GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL))
{
//Use I was attacked script above
if(!GetLevelByClass(CLASS_TYPE_COMMONER))
{
if(!GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()))
{
if(GetIsObjectValid(GetLastHostileActor(oShouter)))
{
if(!GetIsFriend(GetLastHostileActor(oShouter)) && GetIsFriend(oShouter))
{
DetermineCombatRound(GetLastHostileActor(oShouter));
}
}
}
}
else if (GetLevelByClass(CLASS_TYPE_COMMONER, oShouter) >= 10)
{
ActionAttack(GetLastHostileActor(oShouter));
}
else
{
DetermineCombatRound();
}
}
else
{
DetermineSpecialBehavior();
}
}
break;
//For this shout to work the object must shout the following
//string sHelp = "NW_BLOCKER_BLK_" + GetTag(OBJECT_SELF);
case 4: //BLOCKER OBJECT HAS BEEN DISTURBED
{
if(!GetLevelByClass(CLASS_TYPE_COMMONER))
{
if(!GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()))
{
if(GetIsObjectValid(oIntruder))
{
SetIsTemporaryEnemy(oIntruder);
DetermineCombatRound(oIntruder);
}
}
}
else if (GetLevelByClass(CLASS_TYPE_COMMONER, oShouter) >= 10)
{
ActionAttack(oIntruder);
}
else
{
DetermineCombatRound();
}
}
break;
case 5: //ATTACK MY TARGET
{
if(GetIsFriend(oShouter))
{
SetIsTemporaryEnemy(oIntruder,OBJECT_SELF,TRUE,180.0);
ClearAllActions();
DetermineCombatRound(oIntruder);
}
}
break;
case 6: //CALL_TO_ARMS
{
//This was once commented out.
DetermineCombatRound();
}
break;
//ASSOCIATE SHOUT RESPONSES ******************************************************************************
case ASSOCIATE_COMMAND_ATTACKNEAREST: //Used to de-activate AGGRESSIVE DEFEND MODE
{
ResetHenchmenState();
SetAssociateState(NW_ASC_MODE_DEFEND_MASTER, FALSE);
SetAssociateState(NW_ASC_MODE_STAND_GROUND, FALSE);
DetermineCombatRound();
}
break;
case ASSOCIATE_COMMAND_FOLLOWMASTER: //Only used to retreat, or break free from Stand Ground Mode
{
ResetHenchmenState();
SetAssociateState(NW_ASC_MODE_STAND_GROUND, FALSE);
DelayCommand(2.5, PlayVoiceChat(VOICE_CHAT_CANDO));
if(GetAssociateState(NW_ASC_AGGRESSIVE_STEALTH))
{
//ActionUseSkill(SKILL_HIDE, OBJECT_SELF);
}
if(GetAssociateState(NW_ASC_AGGRESSIVE_SEARCH))
{
ActionUseSkill(SKILL_SEARCH, OBJECT_SELF);
}
ActionForceFollowObject(GetMaster(), GetFollowDistance());
SetAssociateState(NW_ASC_IS_BUSY);
DelayCommand(5.0, SetAssociateState(NW_ASC_IS_BUSY, FALSE));
}
break;
case ASSOCIATE_COMMAND_GUARDMASTER: //Used to activate AGGRESSIVE DEFEND MODE
{
ResetHenchmenState();
DelayCommand(2.5, PlayVoiceChat(VOICE_CHAT_CANDO));
//Companions will only attack the Masters Last Attacker
SetAssociateState(NW_ASC_MODE_DEFEND_MASTER);
SetAssociateState(NW_ASC_MODE_STAND_GROUND, FALSE);
if(GetIsObjectValid(GetLastHostileActor(GetMaster())))
{
DetermineCombatRound(GetLastHostileActor(GetMaster()));
}
}
break;
case ASSOCIATE_COMMAND_HEALMASTER: //Ignore current healing settings and heal me now
{
ResetHenchmenState();
//SetCommandable(TRUE);
if(TalentCureCondition()) {DelayCommand(2.0, PlayVoiceChat(VOICE_CHAT_CANDO)); return;}
if(TalentHeal(TRUE)) {DelayCommand(2.0, PlayVoiceChat(VOICE_CHAT_CANDO)); return;}
DelayCommand(2.5, PlayVoiceChat(VOICE_CHAT_CANTDO));
}
break;
case ASSOCIATE_COMMAND_MASTERFAILEDLOCKPICK: //Check local for Re-try locked doors and
{
if(!GetAssociateState(NW_ASC_MODE_STAND_GROUND))
{
if(GetAssociateState(NW_ASC_RETRY_OPEN_LOCKS))
{
int bValid = TRUE;
object oLastObject = GetLockedObject(GetMaster());
int nSkill = GetSkillRank(SKILL_OPEN_LOCK) - GetAbilityModifier(ABILITY_DEXTERITY);
if(GetIsObjectValid(oLastObject) && GetPlotFlag(oLastObject) == FALSE)
{
if(GetIsDoorActionPossible(oLastObject, DOOR_ACTION_KNOCK) || GetIsPlaceableObjectActionPossible(oLastObject, PLACEABLE_ACTION_KNOCK))
{
ClearAllActions();
PlayVoiceChat(VOICE_CHAT_CANDO);
ActionCastSpellAtObject(SPELL_KNOCK, oLastObject);
ActionWait(1.0);
bValid = FALSE;
}
else if (GetIsDoorActionPossible(oLastObject, DOOR_ACTION_UNLOCK)|| GetIsPlaceableObjectActionPossible(oLastObject, PLACEABLE_ACTION_UNLOCK))
{
ClearAllActions();
PlayVoiceChat(VOICE_CHAT_PICKLOCK);
ActionWait(1.0);
ActionUseSkill(SKILL_OPEN_LOCK,oLastObject);
bValid = FALSE;
}
else if(nSkill < 5 && GetAbilityScore(OBJECT_SELF, ABILITY_STRENGTH) >= 16 && GetSkillRank(SKILL_OPEN_LOCK) <= 0)
{
if(GetIsDoorActionPossible(oLastObject, DOOR_ACTION_BASH) || GetIsPlaceableObjectActionPossible(oLastObject, PLACEABLE_ACTION_BASH))
{
ClearAllActions();
PlayVoiceChat(VOICE_CHAT_CANDO);
ActionEquipMostDamagingMelee(oLastObject);
ActionAttack(oLastObject);
SetLocalObject(OBJECT_SELF, "NW_GENERIC_DOOR_TO_BASH", oLastObject);
bValid = FALSE;
}
}
if(bValid == TRUE)
{
//ClearAllActions();
PlayVoiceChat(VOICE_CHAT_CANTDO);
}
else
{
ActionDoCommand(PlayVoiceChat(VOICE_CHAT_TASKCOMPLETE));
}
}
}
}
}
break;
case ASSOCIATE_COMMAND_MASTERUNDERATTACK: //Check whether the master has you in AGGRESSIVE DEFEND MODE
{
if(!GetAssociateState(NW_ASC_MODE_STAND_GROUND))
{
//Check the henchmens current target
object oTarget = GetAttemptedAttackTarget();
if(!GetIsObjectValid(oTarget))
{
oTarget = GetAttemptedSpellTarget();
if(!GetIsObjectValid(oTarget))
{
if(GetAssociateState(NW_ASC_MODE_DEFEND_MASTER))
{
//PlayVoiceChat(VOICE_CHAT_ENEMIES);
DetermineCombatRound(GetLastHostileActor(GetMaster()));
}
else
{
//PlayVoiceChat(VOICE_CHAT_ENEMIES);
DetermineCombatRound();
}
}
}
//Switch targets only if the target is not attacking the master and is greater than 6.0 from
//the master.
if(GetAttackTarget(oTarget) != GetMaster() && GetDistanceBetween(oTarget, GetMaster()) > 6.0)
{
if(GetAssociateState(NW_ASC_MODE_DEFEND_MASTER) && GetIsObjectValid(GetLastHostileActor(GetMaster())))
{
//PlayVoiceChat(VOICE_CHAT_ENEMIES);
DetermineCombatRound(GetLastHostileActor(GetMaster()));
}
}
}
}
break;
case ASSOCIATE_COMMAND_STANDGROUND: //No longer follow the master or guard him
{
SetAssociateState(NW_ASC_MODE_STAND_GROUND);
SetAssociateState(NW_ASC_MODE_DEFEND_MASTER, FALSE);
DelayCommand(2.0, PlayVoiceChat(VOICE_CHAT_CANDO));
ActionAttack(OBJECT_INVALID);
ClearAllActions();
}
break;
case ASSOCIATE_COMMAND_MASTERSAWTRAP:
{
int nCheck = 0;
if(!GetIsInCombat())
{
if(!GetAssociateState(NW_ASC_MODE_STAND_GROUND))
{
object oTrap = GetLastTrapDetected();
if(GetIsObjectValid(oTrap))
{
int nTrapDC = GetTrapDisarmDC(oTrap);
int nSkill = GetSkillRank(SKILL_DISABLE_TRAP);
int nMod = GetAbilityModifier(ABILITY_DEXTERITY);
if((nSkill - nMod) > 0)
{
nSkill = nSkill + 20 - nTrapDC;
}
else
{
nSkill = 0;
nCheck = 1;
}
if(GetCurrentAction(OBJECT_SELF) != ACTION_DISABLETRAP && nSkill > 0)
{
PlayVoiceChat(VOICE_CHAT_STOP);
if(GetHasSkill(SKILL_DISABLE_TRAP, OBJECT_SELF))
{
ClearAllActions();
ActionUseSkill(SKILL_DISABLE_TRAP, oTrap);
ActionDoCommand(SetCommandable(TRUE));
ActionDoCommand(PlayVoiceChat(VOICE_CHAT_TASKCOMPLETE));
SetCommandable(FALSE);
nCheck = 2;
}
}
else if(nCheck = 0 &&
GetSkillRank(SKILL_DISABLE_TRAP) > 0 &&
GetCurrentAction(OBJECT_SELF) != ACTION_DISABLETRAP)
{
PlayVoiceChat(VOICE_CHAT_CANTDO);
}
}
}
}
}
break;
case ASSOCIATE_COMMAND_MASTERATTACKEDOTHER:
{
if(!GetAssociateState(NW_ASC_MODE_STAND_GROUND))
{
if(!GetAssociateState(NW_ASC_MODE_DEFEND_MASTER))
{
if(!GetIsFighting(OBJECT_SELF))
{
//PlayVoiceChat(VOICE_CHAT_ENEMIES);
object oAttack = GetAttackTarget(GetMaster());
if(GetIsObjectValid(oAttack) && GetObjectSeen(oAttack))
{
ClearAllActions();
DetermineCombatRound(oAttack);
}
}
}
}
}
break;
case ASSOCIATE_COMMAND_MASTERGOINGTOBEATTACKED:
{
if(!GetAssociateState(NW_ASC_MODE_STAND_GROUND))
{
if(!GetIsFighting(OBJECT_SELF))
{
object oAttacker = GetGoingToBeAttackedBy(GetMaster());
if(GetIsObjectValid(oAttacker) && GetObjectSeen(oAttacker))
{
ClearAllActions();
//PlayVoiceChat(VOICE_CHAT_ENEMIES);
DetermineCombatRound(oAttacker);
}
}
}
}
break;
case ASSOCIATE_COMMAND_LEAVEPARTY:
{
object oMaster = GetMaster();
if(GetIsObjectValid(oMaster))
{
ClearAllActions();
if(GetAssociate(ASSOCIATE_TYPE_HENCHMAN, GetMaster()) == OBJECT_SELF)
{
AddJournalQuestEntry("Henchman",50,GetMaster(),FALSE,FALSE,TRUE);
}
SetLocalObject(OBJECT_SELF,"NW_L_FORMERMASTER", oMaster);
RemoveHenchman(oMaster, OBJECT_SELF);
}
}
break;
}
}
//::///////////////////////////////////////////////
//:: Set and Get NPC Warning Status
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
This function sets a local int on OBJECT_SELF
which will be checked in the On Attack, On
Damaged and On Disturbed scripts to check if
the offending poarty was a PC and was friendly.
The Get will return the status of the local.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 29, 2001
//:://////////////////////////////////////////////
void SetNPCWarningStatus(int nStatus = TRUE)
{
SetLocalInt(OBJECT_SELF, "NW_GENERIC_WARNING_STATUS", nStatus);
}
int GetNPCWarningStatus()
{
return GetLocalInt(OBJECT_SELF, "NW_GENERIC_WARNING_STATUS");
}
//::///////////////////////////////////////////////
//:: Set SummonHelpIfAttacked
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
This function works in tandem with an encounter
to spawn in guards to fight for the attacked
NPC. MAKE SURE THE ENCOUNTER TAG IS SET TO:
"ENC_" + NPC TAG
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 29, 2001
//:://////////////////////////////////////////////
//Presently Does not work with the current implementation of encounter trigger
void SetSummonHelpIfAttacked()
{
string sEncounter = "ENC_" + GetTag(OBJECT_SELF);
object oTrigger = GetObjectByTag(sEncounter);
if(GetIsObjectValid(oTrigger))
{
SetEncounterActive(TRUE, oTrigger);
}
}
//************************************************************************************************************************************
//************************************************************************************************************************************
//
// ESCAPE FUNCTIONS
//
//************************************************************************************************************************************
//************************************************************************************************************************************
//::///////////////////////////////////////////////
//:: Set, Get Activate,Flee to Exit
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
The target object flees to the specified
way point and then destroys itself, to be
respawned at a later point. For unkillable
sign post characters who are not meant to fight
back.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 29, 2001
//:://////////////////////////////////////////////
//This function is used only because ActionDoCommand can only accept void functions
void CreateSignPostNPC(string sTag, location lLocal)
{
CreateObject(OBJECT_TYPE_CREATURE, sTag, lLocal);
}
void ActivateFleeToExit()
{
object oExitWay = GetWaypointByTag("EXIT_" + GetTag(OBJECT_SELF));
int nPlot = GetLocalInt(OBJECT_SELF, "NW_GENERIC_MASTER");
location lLocal = GetLocalLocation(OBJECT_SELF, "NW_GENERIC_START_POINT");
float fDelay = 6.0;
string sTag = GetTag(OBJECT_SELF);
if(nPlot & NW_FLAG_TELEPORT_RETURN || nPlot & NW_FLAG_TELEPORT_LEAVE)
{
effect eVis = EffectVisualEffect(VFX_IMP_UNSUMMON);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, OBJECT_SELF);
if(nPlot & NW_FLAG_TELEPORT_RETURN)
{
DelayCommand(fDelay, ActionDoCommand(CreateSignPostNPC(sTag, lLocal)));
}
ActionDoCommand(DestroyObject(OBJECT_SELF, 0.75));
}
else
{
if(nPlot & NW_FLAG_ESCAPE_LEAVE)
{
ActionMoveToObject(oExitWay, TRUE);
ActionDoCommand(DestroyObject(OBJECT_SELF, 1.0));
}
else if(nPlot & NW_FLAG_ESCAPE_RETURN)
{
ActionMoveToObject(oExitWay, TRUE);
DelayCommand(fDelay, ActionDoCommand(CreateSignPostNPC(sTag, lLocal)));
ActionDoCommand(DestroyObject(OBJECT_SELF, 1.0));
}
}
}
int GetFleeToExit()
{
int nPlot = GetLocalInt(OBJECT_SELF, "NW_GENERIC_MASTER");
if(nPlot & NW_FLAG_ESCAPE_RETURN)
{
return TRUE;
}
else if(nPlot & NW_FLAG_ESCAPE_LEAVE)
{
return TRUE;
}
else if(nPlot & NW_FLAG_TELEPORT_RETURN)
{
return TRUE;
}
else if(nPlot & NW_FLAG_TELEPORT_LEAVE)
{
return TRUE;
}
return FALSE;
}
//************************************************************************************************************************************
//************************************************************************************************************************************
//************************************************************************************************************************************
// PRIVATE FUNCTIONS
//************************************************************************************************************************************
//************************************************************************************************************************************
//************************************************************************************************************************************
//This is experimental and has not been looked at closely.
void ExitAOESpellArea(object oAOEObject)
{
ClearAllActions();
ActionMoveAwayFromObject(oAOEObject, TRUE, 5.0);
AssignCommand(OBJECT_SELF, DetermineCombatRound());
}
//::///////////////////////////////////////////////
//:: Play Mobile Ambient Animations
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Used for spawned creatures to not look like
zombies
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 23, 2001
//:://////////////////////////////////////////////
void PlayMobileAmbientAnimations()
{
location lLocal;
vector vFrnd;
int nRoll = Random(5)+1;
object oFriend = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nRoll, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
int nHDMe = GetHitDice(OBJECT_SELF);
int nHDOther = GetHitDice(oFriend);
//If a bird
if(!GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS_AVIAN))
{
/*
Use this animation for all player races and humanoids
who are civilized. Monstrous races will wonder about
and try to look busy in as non-social manner.
*/
if(GetRacialType(OBJECT_SELF) == RACIAL_TYPE_ELF ||
GetRacialType(OBJECT_SELF) == RACIAL_TYPE_GNOME ||
GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HALFELF ||
GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HALFLING ||
GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HALFORC ||
GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HUMAN ||
GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HUMANOID_GOBLINOID ||
GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HUMANOID_REPTILIAN ||
GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HUMANOID_ORC)
{
if(nRoll == 4 || nRoll == 5)
{
ClearAllActions();
ActionRandomWalk();
}
else
{
if(!GetIsObjectValid(oFriend) || GetIsPC(oFriend) || IsInConversation(oFriend))
{
ClearAllActions();
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
}
else
{
if(GetDistanceToObject(oFriend) >= 3.0 && GetDistanceToObject(oFriend) <= 5.0 )
{
ClearAllActions();
ActionMoveToObject(oFriend, FALSE, 2.0);
}
else if(GetDistanceToObject(oFriend) >= 5.0)
{
ClearAllActions();
ActionPlayAnimation(ANIMATION_FIREFORGET_GREETING, 0.75);
ActionMoveToObject(oFriend, FALSE, 2.0);
}
vFrnd = GetPosition(oFriend);
SetFacingPoint(vFrnd);
nRoll = d4();
}
if(GetIsObjectValid(oFriend))
{
ClearAllActions();
if(nHDMe == nHDOther)
{
if(nRoll == 1)
{
ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 6.0);
}
else if(nRoll == 2)
{
ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 1.0, 6.0);
}
else if(nRoll == 3)
{
ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 6.0);
}
else
{
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
}
}
else if(nHDMe > nHDOther)
{
if(nRoll == 1)
{
ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 6.0);
}
else if(nRoll == 2)
{
ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 6.0);
}
else if(nRoll == 3)
{
ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 1.0, 6.0);
}
else
{
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
}
}
else if (nHDMe < nHDOther)
{
if(nRoll == 1)
{
ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 6.0);
}
else if(nRoll == 2)
{
ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 1.0, 6.0);
}
else if(nRoll == 3)
{
ActionPlayAnimation(ANIMATION_FIREFORGET_SALUTE, 0.75);
}
else
{
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
}
}
}
}
}
else
{
ClearAllActions();
int nRand = d6();
if(nRand == 1)
{
if(GetDistanceToObject(oFriend) >= 3.0 && GetDistanceToObject(oFriend) <= 10.0 )
{
ActionMoveToObject(oFriend, FALSE, 2.0);
vFrnd = GetPosition(oFriend);
SetFacingPoint(vFrnd);
}
}
else if(nRand == 2 || nRand == 3 || nRand == 4)
{
ActionRandomWalk();
}
else if(nRand == 5)
{
ActionPlayAnimation(ANIMATION_LOOPING_GET_MID);
}
else if(nRand == 6)
{
}
}
}
else //Birds Ambient Behavior
{
int nBird = d4();
location lFriend;
effect eBird;
if(GetIsObjectValid(oFriend))
{
lFriend = GetLocation(oFriend);
}
else
{
lFriend = GetLocation(OBJECT_SELF);
}
if(nBird == 0)
{
ClearAllActions();
ActionMoveToObject(oFriend, TRUE, 4.0);
// BK: Commenting this out because the effect wasn't meant to be played here
// ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBird, OBJECT_SELF, 5.0);
}
else if (nBird == 1 || nBird == 2 || nBird == 3)
{
ClearAllActions();
ActionMoveAwayFromObject(oFriend, TRUE, 100.0);
}
else
{
ClearAllActions();
eBird = EffectDisappearAppear(lFriend);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBird, OBJECT_SELF, 4.0);
ActionMoveAwayFromObject(oFriend, TRUE, 100.0);
}
}
}
//::///////////////////////////////////////////////
//:: Play Immobile Ambient Animations
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Used for spawned creatures to not look like
zombies
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 23, 2001
//:://////////////////////////////////////////////
void PlayImmobileAmbientAnimations()
{
location lLocal;
vector vFrnd;
int nRoll = d2();
object oFriend = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nRoll, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
int nHDMe = GetHitDice(OBJECT_SELF);
int nHDOther = GetHitDice(oFriend);
if(!GetIsObjectValid(oFriend) || GetIsPC(oFriend) || IsInConversation(oFriend))
{
if (d4()==1)
{
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
}
}
else
{
if(GetIsObjectValid(oFriend) && GetDistanceToObject(oFriend) <= 3.0)
{
vFrnd = GetPosition(oFriend);
SetFacingPoint(vFrnd);
nRoll = d10();
ClearAllActions();
if(nRoll == 1)
{
ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_BORED, 1.0, 6.0);
}
else if(nRoll == 2)
{
ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 1.0, 6.0);
}
else if(nRoll == 3)
{
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
}
else if(nRoll == 4)
{
ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 0.75,2.0);
}
else
{
return;
}
}
else
if (d4()==1)
{
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
}
}
}
//:://////////////////////////////////////////////////////////////////////////////////////////////
//:: Special Behavior Functions
//:: Copyright (c) 2001 Bioware Corp.
//:://///////////////////////////////////////////////////////////////////////////////////////////
/*
These commands handle the setting and getting of the Behavioral Master
If these special behaviors are used they will override the normal behavior expected
the animals normal Neutral Faction.
*/
//:://///////////////////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 10, 2001
//:://///////////////////////////////////////////////////////////////////////////////////////////
void SetBehaviorState(int nCondition, int bValid = TRUE)
{
int nPlot = GetLocalInt(OBJECT_SELF, "NW_BEHAVIOR_MASTER");
if(bValid == TRUE)
{
nPlot = nPlot | nCondition;
SetLocalInt(OBJECT_SELF, "NW_BEHAVIOR_MASTER", nPlot);
}
else if (bValid == FALSE)
{
nPlot = nPlot & ~nCondition;
SetLocalInt(OBJECT_SELF, "NW_BEHAVIOR_MASTER", nPlot);
}
}
int GetBehaviorState(int nCondition)
{
int nPlot = GetLocalInt(OBJECT_SELF, "NW_BEHAVIOR_MASTER");
if(nPlot & nCondition)
{
return TRUE;
}
return FALSE;
}
//::///////////////////////////////////////////////
//:: Determine Special Behavior
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Determines the special behavior used by the NPC.
Generally all NPCs who you want to behave differently
than the defualt behavior.
For these behaviors, passing in a valid object will
cause the creature to become hostile the the attacker.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 14, 2001
//:://////////////////////////////////////////////
void DetermineSpecialBehavior(object oIntruder = OBJECT_INVALID)
{
object oTarget = GetNearestCreature(CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, OBJECT_SELF ,1, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
if(GetBehaviorState(NW_FLAG_BEHAVIOR_OMNIVORE))
{
if(!GetIsObjectValid(oIntruder))
{
if(!GetIsObjectValid(GetAttemptedAttackTarget()) &&
!GetIsObjectValid(GetAttemptedSpellTarget()) &&
!GetIsObjectValid(GetAttackTarget()))
{
if(GetIsObjectValid(oTarget) && GetDistanceToObject(oTarget) <= 5.0)
{
if(!GetIsFriend(oTarget))
{
if(GetLevelByClass(CLASS_TYPE_DRUID, oTarget) == 0 && GetLevelByClass(CLASS_TYPE_RANGER, oTarget) == 0)
{
SetIsTemporaryEnemy(oTarget, OBJECT_SELF, FALSE, 20.0);
DetermineCombatRound(oTarget);
}
}
}
}
}
else if(!IsInConversation(OBJECT_SELF))
{
DetermineCombatRound(oIntruder);
}
else
{
ClearAllActions();
ActionRandomWalk();
return;
}
}
else if(GetBehaviorState(NW_FLAG_BEHAVIOR_HERBIVORE))
{
if(!GetIsObjectValid(GetAttemptedAttackTarget()) &&
!GetIsObjectValid(GetAttemptedSpellTarget()) &&
!GetIsObjectValid(GetAttackTarget()))
{
if(GetIsObjectValid(oTarget) && GetDistanceToObject(oTarget) <= 6.0)
{
if(!GetIsFriend(oTarget))
{
if(GetLevelByClass(CLASS_TYPE_DRUID, oTarget) == 0 && GetLevelByClass(CLASS_TYPE_RANGER, oTarget) == 0)
{
TalentFlee(oTarget);
}
}
}
}
else if(!IsInConversation(OBJECT_SELF))
{
ClearAllActions();
ActionRandomWalk();
return;
}
}
}