home *** CD-ROM | disk | FTP | other *** search
/ PC Zone 125 / DPPCZ0203B.7z / DPPCZ0203B.ISO / Demos / Neverwinter / data1.cab / override / nw_i0_generic.nss < prev    next >
Text File  |  2002-09-10  |  194KB  |  5,027 lines

  1. //::///////////////////////////////////////////////
  2. //:: Generic Scripting Include v1.0
  3. //:: NW_I0_GENERIC
  4. //:: Copyright (c) 2001 Bioware Corp.
  5. //:://////////////////////////////////////////////
  6. /*
  7.     ********************************************
  8.     WARNING THIS SCRIPT IS CHANGED AT YOUR PERIL
  9.     ********************************************
  10.     
  11.     This is the master generic script and currently
  12.     handles all combat and some plot behavior
  13.     within NWN. If this script is tampered
  14.     with there is a chance of introducing game
  15.     breaking bugs.  But other than that enjoy.
  16. */
  17. //:://////////////////////////////////////////////
  18. //:: Created By: Preston Watamaniuk
  19. //:: Created On: Sept 20, 2001
  20. //:://////////////////////////////////////////////
  21.  
  22. //GENERIC STRUCTURES
  23.  
  24. struct sEnemies
  25. {
  26.     int FIGHTERS;
  27.     int FIGHTER_LEVELS;
  28.     int CLERICS;
  29.     int CLERIC_LEVELS;
  30.     int MAGES;
  31.     int MAGE_LEVELS;
  32.     int MONSTERS;
  33.     int MONTERS_LEVELS;
  34.     int TOTAL;
  35.     int TOTAL_LEVELS;
  36. };
  37.  
  38. struct sSpellSelect
  39. {
  40.     int RANGED;
  41.     int MELEE;
  42.     object GROUP_TARGET;
  43.     object MOB_TARGET;
  44.     object MELEE_TOUGHEST;
  45.     object TOUGHEST_TARGET;
  46.     int ENEMY_HD;
  47.     int ALLIED_HD;
  48. };
  49.  
  50. //Flee and move constants
  51. int NW_GENERIC_FLEE_EXIT_FLEE = 0;
  52. int NW_GENERIC_FLEE_EXIT_RETURN = 1;
  53. int NW_GENERIC_FLEE_TELEPORT_FLEE = 2;
  54. int NW_GENERIC_FLEE_TELEPORT_RETURN = 3;
  55.  
  56. //Shout constants
  57. int NW_GENERIC_SHOUT_I_WAS_ATTACKED = 1;    // NOT USED
  58. int NW_GENERIC_SHOUT_I_AM_DEAD = 12;        //IN OnDeath Script
  59. int NW_GENERIC_SHOUT_BACK_UP_NEEDED = 13;   //IN TalentMeleeAttacked
  60. int NW_GENERIC_SHOUT_BLOCKER = 2;
  61.  
  62. //Master Constants
  63. int NW_FLAG_SPECIAL_CONVERSATION        = 0x00000001;
  64. int NW_FLAG_SHOUT_ATTACK_MY_TARGET      = 0x00000002;
  65. int NW_FLAG_STEALTH                     = 0x00000004;
  66. int NW_FLAG_SEARCH                      = 0x00000008;
  67. int NW_FLAG_SET_WARNINGS                = 0x00000010;
  68. int NW_FLAG_ESCAPE_RETURN               = 0x00000020; //Failed
  69. int NW_FLAG_ESCAPE_LEAVE                = 0x00000040;
  70. int NW_FLAG_TELEPORT_RETURN             = 0x00000080; //Failed
  71. int NW_FLAG_TELEPORT_LEAVE              = 0x00000100;
  72. int NW_FLAG_PERCIEVE_EVENT              = 0x00000200;
  73. int NW_FLAG_ATTACK_EVENT                = 0x00000400;
  74. int NW_FLAG_DAMAGED_EVENT               = 0x00000800;
  75. int NW_FLAG_SPELL_CAST_AT_EVENT         = 0x00001000;
  76. int NW_FLAG_DISTURBED_EVENT             = 0x00002000;
  77. int NW_FLAG_END_COMBAT_ROUND_EVENT      = 0x00004000;
  78. int NW_FLAG_ON_DIALOGUE_EVENT           = 0x00008000;
  79. int NW_FLAG_RESTED_EVENT                = 0x00010000;
  80. int NW_FLAG_DEATH_EVENT                 = 0x00020000;
  81. int NW_FLAG_SPECIAL_COMBAT_CONVERSATION = 0x00040000;
  82. int NW_FLAG_AMBIENT_ANIMATIONS          = 0x00080000;
  83. int NW_FLAG_HEARTBEAT_EVENT             = 0x00100000;
  84. int NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS = 0x00200000;
  85. int NW_FLAG_DAY_NIGHT_POSTING           = 0x00400000;
  86. int NW_FLAG_AMBIENT_ANIMATIONS_AVIAN    = 0x00800000;
  87. int NW_FLAG_APPEAR_SPAWN_IN_ANIMATION   = 0x01000000;
  88. int NW_FLAG_SLEEPING_AT_NIGHT           = 0x02000000;
  89. int NW_FLAG_FAST_BUFF_ENEMY             = 0x04000000;
  90.  
  91. //Behavior Constants
  92. int NW_FLAG_BEHAVIOR_SPECIAL       = 0x00000001;
  93. int NW_FLAG_BEHAVIOR_CARNIVORE     = 0x00000002; //Will always attack regardless of faction
  94. int NW_FLAG_BEHAVIOR_OMNIVORE      = 0x00000004; //Will only attack if approached
  95. int NW_FLAG_BEHAVIOR_HERBIVORE     = 0x00000008; //Will never attack.  Will alway flee.
  96.  
  97. //Talent Type Constants
  98. int NW_TALENT_PROTECT = 1;
  99. int NW_TALENT_ENHANCE = 2;
  100.  
  101. //PRIVATE FUNCTION DECLARATIONS
  102.  
  103. //Checks the target for a specific EFFECT_TYPE constant value
  104. int GetHasEffect(int nEffectType, object oTarget = OBJECT_SELF);
  105. //Adds all three of the class levels together.  Used before GetHitDice became available
  106. int GetCharacterLevel(object oTarget);
  107. //Returns the number of persons who are considered friendly to the the target.
  108. int CheckFriendlyFireOnTarget(object oTarget, float fDistance = 5.0);
  109. //Returns the number of enemies on a target.
  110. int CheckEnemyGroupingOnTarget(object oTarget, float fDistance = 5.0);
  111. //Find a single target who is an enemy with 30m of self
  112. object FindSingleRangedTarget();
  113. //Calculate the number of people currently attacking self.
  114. int GetNumberOfMeleeAttackers();
  115. //Calculate the number of people attacking self from beyond 5m
  116. int GetNumberOfRangedAttackers();
  117. //Determine the percentage of HP object-self has left
  118. int GetPercentageHPLoss(object oWounded);
  119. //Determine the number of targets within 20m that are of the specified racial-type
  120. int GetRacialTypeCount(int nRacial_Type);
  121. //Returns the nearest object that can be seen, then checks for the nearest heard target.
  122. object GetNearestSeenOrHeardEnemy();
  123. //Sets a local variable for the last spell used
  124. void SetLastGenericSpellCast(int nSpell);
  125. //Returns a SPELL_ constant for the last spell used
  126. int GetLastGenericSpellCast();
  127. //Compares the current spell with the last one cast
  128. int CompareLastSpellCast(int nSpell);
  129. //If using ambient sleep this will remove the effect
  130. void RemoveAmbientSleep();
  131. //Does a check to determine if the NPC has an attempted spell or attack target
  132. int GetIsFighting(object oFighting);
  133. //Searches for the nearest locked object to the master
  134. object GetLockedObject(object oMaster);
  135. //Equip the weapon appropriate to enemy and position
  136. void EquipAppropriateWeapons(object oTarget);
  137. //Returns the henchmen to a commandable state of grace
  138. void ResetHenchmenState();
  139. //Returns true if self is a henchmen
  140. int AssociateCheck(object oCheck);
  141. //Returns true if the object has any posts or waypoints to walk
  142. int GetIsPostOrWalking(object oWalker = OBJECT_SELF);
  143. //Prints a log string with the ID of the passed in talent.
  144. void DubugPrintTalentID(talent tTalent);
  145. //Inserts a debug print string into the log.
  146. void MyPrintString(string sString);
  147.  
  148.  
  149. //DETERMINE COMBAT ROUND SUB FUNCTIONS
  150.  
  151. int BashDoorCheck(object oIntruder = OBJECT_INVALID);
  152. int DetermineClassToUse();
  153. struct sEnemies DetermineEnemies();
  154. string GetMostDangerousClass(struct sEnemies sCount);
  155. int GetMatchCompatibility(talent tUse, string sClass, int nType);
  156. int MatchCombatProtections(talent tUse);
  157. int MatchSpellProtections(talent tUse);
  158. int MatchElementalProtections(talent tUse);
  159. talent StartProtectionLoop();
  160. int GetAttackCompatibility(talent tUse, int nClass);
  161. int MatchReflexAttacks(talent tUse);
  162. int MatchFortAttacks(talent tUse);
  163. object GetRangedAttackGroup(int bAllowFriendlyFire = FALSE);
  164. object GetToughestMeleeAttacker();
  165. object GetToughestAttacker();
  166. struct sSpellSelect AnalyzeCombatSituation();
  167. int GetAlliedHD();
  168. int GetEnemyHD();
  169. talent StartAttackLoop();
  170. int VerifyDisarm(talent tUse, object oTarget);
  171. int VerifyCombatMeleeTalent(talent tUse, object oTarget);
  172. int UniversalSpellMatch(talent tUse);
  173.  
  174. //CURRENT TALENT FUNCTIONS
  175. int TalentUseProtectionOnSelf();
  176. int TalentUseProtectionOthers();
  177. int TalentEnhanceOthers();
  178. int TalentUseEnhancementOnSelf();
  179. int TalentMeleeAttacked(object oIntruder = OBJECT_INVALID);
  180. int TalentRangedAttackers(object oIntruder = OBJECT_INVALID);
  181. int TalentRangedEnemies(object oIntruder = OBJECT_INVALID);
  182. int TalentSummonAllies();
  183. int TalentHealingSelf(); //Use spells and potions
  184. int TalentHeal(int nForce = FALSE); //User spells only on others and self
  185. int TalentMeleeAttack(object oIntruder = OBJECT_INVALID);
  186. int TalentSneakAttack();
  187. int TalentFlee(object oIntruder = OBJECT_INVALID);
  188. int TalentUseTurning();
  189. int TalentPersistentAbilities();
  190. int TalentAdvancedBuff(float fDistance);
  191. int TalentBuffSelf();  //Used for Potions of Enhancement and Protection
  192. int TalentSeeInvisible();
  193. int TalentCureCondition();
  194. int TalentDragonCombat(object oIntruder = OBJECT_INVALID);
  195. int TalentBardSong();
  196. int TalentAdvancedProtectSelf();
  197. int TalentSpellAttack(object oIntruder);
  198.  
  199.  
  200. //CORE AI FUNCTIONS
  201. void DetermineCombatRound(object oIntruder = OBJECT_INVALID, int nAI_Difficulty = 10);
  202. void SetListeningPatterns();
  203. void RespondToShout(object oShouter, int nShoutIndex, object oIntruder = OBJECT_INVALID);
  204. void RunCircuit(int nTens, int nNum, int nRun = FALSE, float fPause = 1.0);
  205. void WalkWayPoints(int nRun = FALSE, float fPause = 1.0);
  206. void RunNextCircuit(int nRun = FALSE, float fPause = 1.0);
  207. int CheckWayPoints(object oWalker = OBJECT_SELF);
  208.  
  209. //PLOT FUNCTIONS
  210. void SetNPCWarningStatus(int nStatus = TRUE);
  211. int GetNPCWarningStatus();
  212. void SetSummonHelpIfAttacked();
  213. void CreateSignPostNPC(string sTag, location lLocal);
  214. void ActivateFleeToExit();
  215. int GetFleeToExit();
  216.  
  217. //MASTER LOCAL FUNCTIONS
  218. void SetSpawnInCondition(int nCondition, int bValid = TRUE);
  219. int GetSpawnInCondition(int nCondition);
  220. void SetSpawnInLocals(int nCondition);
  221.  
  222. //ASSOCIATE MASTER VARIABLE FUNCTIONS
  223. void SetAssociateState(int nCondition, int bValid = TRUE);
  224. int GetAssociateState(int nCondition);
  225.  
  226. //ASSOCIATE FUNCTIONS
  227. int GetAssociateCRMax();
  228. int GetAssociateHealMaster();
  229. float GetFollowDistance();
  230. void CheckIsUnlocked(object oLastObject);
  231. void SetAssociateStartLocation();
  232. location GetAssociateStartLocation();
  233.  
  234. //AMBIENT ANIMATION COMMANDS
  235. void PlayMobileAmbientAnimations();
  236. void PlayImmobileAmbientAnimations();
  237.  
  238. //BEHAVIOR LOCAL FUNCTIONS
  239. void SetBehaviorState(int nCondition, int bValid = TRUE);
  240. int GetBehaviorState(int nCondition);
  241. void DetermineSpecialBehavior(object oIntruder = OBJECT_INVALID);
  242.  
  243. //::///////////////////////////////////////////////
  244. //:: Master Local Get and Set
  245. //:: FileName
  246. //:: Copyright (c) 2001 Bioware Corp.
  247. //:://////////////////////////////////////////////
  248. /*
  249.     All On Spawn in conditions in the game are now
  250.     being stored within one local.  The get and set
  251.     changed or checks the condition of this one
  252.     Hex local.  The NW_FLAG_XXX variables above
  253.     allow for the user of these functions throughout
  254.     the generic scripts.
  255. */
  256. //:://////////////////////////////////////////////
  257. //:: Created By: Preston Watamaniuk
  258. //:: Created On: Nov 14, 2001
  259. //:://////////////////////////////////////////////
  260.  
  261. void SetSpawnInCondition(int nCondition, int bValid = TRUE)
  262. {
  263.     int nPlot = GetLocalInt(OBJECT_SELF, "NW_GENERIC_MASTER");
  264.     if(bValid == TRUE)
  265.     {
  266.         nPlot = nPlot | nCondition;
  267.         SetSpawnInLocals(nCondition);
  268.         SetLocalInt(OBJECT_SELF, "NW_GENERIC_MASTER", nPlot);
  269.     }
  270.     else if (bValid == FALSE)
  271.     {
  272.         nPlot = nPlot & ~nCondition;
  273.         SetLocalInt(OBJECT_SELF, "NW_GENERIC_MASTER", nPlot);
  274.     }
  275. }
  276.  
  277. int GetSpawnInCondition(int nCondition)
  278. {
  279.     int nPlot = GetLocalInt(OBJECT_SELF, "NW_GENERIC_MASTER");
  280.     if(nPlot & nCondition)
  281.     {
  282.         return TRUE;
  283.     }
  284.     return FALSE;
  285. }
  286.  
  287. void SetSpawnInLocals(int nCondition)
  288. {
  289.     if(nCondition == NW_FLAG_SHOUT_ATTACK_MY_TARGET)
  290.     {
  291.         SetListenPattern(OBJECT_SELF, "NW_ATTACK_MY_TARGET", 5);
  292.     }
  293.     else if(nCondition == NW_FLAG_ESCAPE_RETURN)
  294.     {
  295.         SetLocalLocation(OBJECT_SELF, "NW_GENERIC_START_POINT", GetLocation(OBJECT_SELF));
  296.     }
  297.     else if(nCondition == NW_FLAG_TELEPORT_LEAVE)
  298.     {
  299.         SetLocalLocation(OBJECT_SELF, "NW_GENERIC_START_POINT", GetLocation(OBJECT_SELF));
  300.     }
  301. }
  302.  
  303. //::///////////////////////////////////////////////
  304. //:: DetermineCombatRound
  305. //:: Copyright (c) 2001 Bioware Corp.
  306. //:://////////////////////////////////////////////
  307. /*
  308.     This function is the master function for the
  309.     generic include and is called from the main
  310.     script.  This function is used in lieu of
  311.     any actual scripting.
  312. */
  313. //:://////////////////////////////////////////////
  314. //:: Created By: Preston Watamaniuk
  315. //:: Created On: Oct 16, 2001
  316. //:://////////////////////////////////////////////
  317.  
  318. void DetermineCombatRound(object oIntruder = OBJECT_INVALID, int nAI_Difficulty = 10)
  319. {
  320.     MyPrintString("********************** DETERMINE COMBAT ROUND START ****************************************");
  321.     MyPrintString("**********************  " + GetTag(OBJECT_SELF) + "  ****************************************");
  322.     if(GetAssociateState(NW_ASC_IS_BUSY))
  323.     {
  324.         return;
  325.     }
  326.     if(BashDoorCheck(oIntruder)) {return;}
  327.     int nClass = DetermineClassToUse();
  328.  
  329.     //This check is to see if the master is being attacked and in need of help
  330.  
  331.     if(GetAssociateState(NW_ASC_HAVE_MASTER))
  332.     {
  333.         if(GetAssociateState(NW_ASC_MODE_DEFEND_MASTER))
  334.         {
  335.             oIntruder = GetLastHostileActor(GetMaster());
  336.             if(!GetIsObjectValid(oIntruder))
  337.             {
  338.                 oIntruder = GetGoingToBeAttackedBy(GetMaster());
  339.                 if(!GetIsObjectValid(oIntruder))
  340.                 {
  341.                     oIntruder = GetLastHostileActor();
  342.                     if(!GetIsObjectValid(oIntruder))
  343.                     {
  344.                         return;
  345.                     }
  346.                     else if(!GetIsEnemy(oIntruder))
  347.                     {
  348.                         oIntruder = OBJECT_INVALID;
  349.                     }
  350.                 }
  351.             }
  352.         }
  353.     }
  354.     if(GetIsObjectValid(GetMaster()))
  355.     {
  356.         if(GetDistanceToObject(GetMaster()) > 15.0)
  357.         {
  358.             if(GetCurrentAction(GetMaster()) != ACTION_FOLLOW)
  359.             {
  360.                 ClearAllActions();
  361.                 //ActionAttack(OBJECT_INVALID);
  362.                 ActionForceFollowObject(GetMaster(), GetFollowDistance());
  363.                 //ActionForceMoveToObject(GetMaster(), TRUE, GetFollowDistance(), 5.0);
  364.                 return;
  365.             }
  366.         }
  367.     }
  368.  
  369.     int nOffense = d100();
  370.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Offense Roll " + IntToString(nOffense));
  371.  
  372.     if(GetIsObjectValid(oIntruder) ||
  373.        GetIsObjectValid(GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN)) ||
  374.        (GetIsObjectValid(oIntruder) && GetIsObjectValid(GetMaster())))
  375.     {
  376.         int nAlignment = GetAlignmentGoodEvil(OBJECT_SELF);
  377.         //AM I AN ARCANE SPELLCASTER?
  378.         if(nClass == CLASS_TYPE_WIZARD || nClass == CLASS_TYPE_SORCERER || nClass == CLASS_TYPE_BARD)
  379.         {
  380.             if(nClass == CLASS_TYPE_BARD)
  381.             {
  382.                 if(TalentHeal()) {return;}
  383.                 if(TalentBardSong()) {return;}
  384.             }
  385.             if(GetRacialType(OBJECT_SELF) != RACIAL_TYPE_ABERRATION ||
  386.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_BEAST ||
  387.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_ELEMENTAL ||
  388.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_VERMIN ||
  389.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_MAGICAL_BEAST ||
  390.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_UNDEAD ||
  391.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_DRAGON ||
  392.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_ANIMAL)
  393.             {
  394.                 //Use healing potions to not die
  395.                 if(TalentHealingSelf()) {return;}
  396.             }
  397.             //Use a defensive talent fire then offensive if that fails
  398.             if(nOffense > 75)
  399.             {
  400.                 if(TalentAdvancedProtectSelf()){return;} //******************************************//
  401.                 //Use protections on Self
  402.                 if(TalentUseProtectionOnSelf()) {return;}
  403.                 //Use protection on allies
  404.                 if(TalentUseProtectionOthers()) {return;}
  405.                 //Check if the character can enhance themselves
  406.                 if(TalentUseEnhancementOnSelf()) {return;}
  407.                 //Use Enhancements on the part
  408.                 if(TalentEnhanceOthers()) {return;}
  409.                 //Check for Personal Attackers
  410.                 if(TalentMeleeAttacked(oIntruder)) {return;}
  411.                  //Check for Ranged Attackers
  412.                 if(TalentRangedAttackers(oIntruder)) {return;}
  413.                  //Check for Ranged Enemies
  414.                 if(TalentRangedEnemies(oIntruder)) {return;}
  415.                 //Check for Allies
  416.                 if(TalentSummonAllies()) {return;}
  417.                 //Spell Attack
  418.                 if(TalentSpellAttack(oIntruder)) {return;}
  419.                    //Attack if out of spells
  420.                 if(TalentMeleeAttack(oIntruder)) {return;}
  421.             }
  422.             else //Use a offensive talent only
  423.             {
  424.                 if(GetIsObjectValid(GetMaster()))
  425.                 {
  426.                     if(TalentUseProtectionOthers()) {return;}
  427.                     if(TalentEnhanceOthers()) {return;}
  428.                 }
  429.                 //Check for Personal Attackers
  430.                 if(TalentMeleeAttacked(oIntruder)) {return;}
  431.                  //Check for Ranged Attackers
  432.                 if(TalentRangedAttackers(oIntruder)) {return;}
  433.                  //Check for Ranged Enemies
  434.                 if(TalentRangedEnemies(oIntruder)) {return;}
  435.                  //Summon Allies
  436.                 if(TalentSummonAllies()) {return;}
  437.                 //Spell Attack
  438.                 if(TalentSpellAttack(oIntruder)) {return;}
  439.                  //Attack if out of spells
  440.                 if(TalentMeleeAttack(oIntruder)) {return;}
  441.             }
  442.             return;
  443.         }
  444.         else if((nClass == CLASS_TYPE_CLERIC || nClass == CLASS_TYPE_DRUID) && GetRacialType(OBJECT_SELF) != RACIAL_TYPE_UNDEAD)
  445.         {
  446.             //Cast spells specific to the main enemy I am facing.
  447.             if(TalentAdvancedProtectSelf()) {return;} //******************************************//
  448.             //Remove negative effects from allies
  449.             if(TalentCureCondition()) {return;}
  450.             //Turning check
  451.             if(TalentUseTurning()) {return;}
  452.             //Check if allies or self are injured
  453.             if(TalentHeal()) {return;}
  454.             //Use healing potions to not die
  455.             if(TalentHealingSelf()) {return;}
  456.             
  457.             if(nOffense > 75)
  458.             {
  459.                 if(GetNumberOfMeleeAttackers() > 1)
  460.                 {
  461.                     if(TalentMeleeAttacked(oIntruder)) {return;}
  462.                     if(TalentMeleeAttack(oIntruder)) {return;}
  463.                 }
  464.                 else if(GetNumberOfMeleeAttackers() == 1)
  465.                 {
  466.  
  467.                     if(TalentMeleeAttack(oIntruder)) {return;}
  468.                 }
  469.                 else
  470.                 {
  471.                     //Check if the character can enhance themselves
  472.                     if(TalentUseEnhancementOnSelf()) {return;}
  473.                     // Check for enhancements on party
  474.                     if(TalentEnhanceOthers()) {return;}
  475.                     //Cast general protection on self
  476.                     if(TalentUseProtectionOnSelf()) {return;}
  477.                     //Check for Allies
  478.                     if(TalentUseProtectionOthers()) {return;}
  479.                     //Check for Allies
  480.                     if(TalentSummonAllies()) {return;}
  481.                      //Check for Personal Attackers
  482.                     if(Random(101) > 75)
  483.                     {
  484.                         if(TalentMeleeAttacked(oIntruder)) {return;}
  485.                     }
  486.                      //Check for Ranged Attackers
  487.                     if(TalentRangedAttackers(oIntruder)) {return;}
  488.                      //Check for Ranged Enemies
  489.                     if(TalentRangedEnemies(oIntruder)) {return;}
  490.                      //Attack if out of spells
  491.                     if(TalentMeleeAttack(oIntruder)) {return;}
  492.                 }
  493.             }
  494.             else
  495.             {
  496.                 //Cast Summon Spells
  497.                 if(TalentSummonAllies()) {return;}
  498.                  //Check for Personal Attackers
  499.                 if(TalentMeleeAttacked(oIntruder)) {return;}
  500.                  //Check for Ranged Attackers
  501.                 if(TalentRangedAttackers(oIntruder)) {return;}
  502.                  //Check for Ranged Enemies
  503.                 if(TalentRangedEnemies(oIntruder)) {return;}
  504.                 //Spell Attack
  505.                 if(TalentSpellAttack(oIntruder)) {return;}
  506.                  //Attack if out of spells
  507.                 if(TalentMeleeAttack(oIntruder)) {return;}
  508.             }
  509.             return;
  510.         }
  511.         else if((nClass == CLASS_TYPE_CLERIC || nClass == CLASS_TYPE_DRUID) && GetRacialType(OBJECT_SELF) == RACIAL_TYPE_UNDEAD)
  512.         {
  513.             //Turning check
  514.             if(TalentUseTurning()) {return;}
  515.             if(nOffense > 75)
  516.             {
  517.                 if(GetNumberOfMeleeAttackers() > 1)
  518.                 {
  519.                     if(TalentMeleeAttacked(oIntruder)) {return;}
  520.                     if(TalentMeleeAttack(oIntruder)) {return;}
  521.                 }
  522.                 else if(GetNumberOfMeleeAttackers() == 1)
  523.                 {
  524.                     if(TalentMeleeAttack(oIntruder)) {return;}
  525.                 }
  526.                 else
  527.                 {
  528.                     //Check if the character can enhance themselves
  529.                     if(TalentUseEnhancementOnSelf()) {return;}
  530.                     // Check for enhancements on party
  531.                     if(TalentEnhanceOthers()) {return;}
  532.                     //Cast general protection on self
  533.                     if(TalentUseProtectionOnSelf()) {return;}
  534.                     //Check for Allies
  535.                     if(TalentUseProtectionOthers()) {return;}
  536.                     //Check for Allies
  537.                     if(TalentSummonAllies()) {return;}
  538.                      //Check for Personal Attackers
  539.                     if(Random(101) > 75)
  540.                     {
  541.                         if(TalentMeleeAttacked(oIntruder)) {return;}
  542.                     }
  543.                      //Check for Ranged Attackers
  544.                     if(TalentRangedAttackers(oIntruder)) {return;}
  545.                      //Check for Ranged Enemies
  546.                     if(TalentRangedEnemies(oIntruder)) {return;}
  547.                      //Attack if out of spells
  548.                     if(TalentMeleeAttack(oIntruder)) {return;}
  549.                 }
  550.             }
  551.             else
  552.             {
  553.                 //Cast Summon Spells
  554.                 if(TalentSummonAllies()) {return;}
  555.                  //Check for Personal Attackers
  556.                 if(TalentMeleeAttacked(oIntruder)) {return;}
  557.                  //Check for Ranged Attackers
  558.                 if(TalentRangedAttackers(oIntruder)) {return;}
  559.                 //Spell Attack
  560.                 if(TalentSpellAttack(oIntruder)) {return;}
  561.                  //Check for Ranged Enemies
  562.                 if(TalentRangedEnemies(oIntruder)) {return;}
  563.                  //Attack if out of spells
  564.                 if(TalentMeleeAttack(oIntruder)) {return;}
  565.             }
  566.             return;
  567.         }
  568.         else if(nClass == CLASS_TYPE_FIGHTER ||
  569.             nClass == CLASS_TYPE_ROGUE ||
  570.             nClass == CLASS_TYPE_PALADIN ||
  571.             nClass == CLASS_TYPE_RANGER ||
  572.             nClass == CLASS_TYPE_MONK ||
  573.             nClass == CLASS_TYPE_BARBARIAN)
  574.         {
  575.             if(GetRacialType(OBJECT_SELF) != RACIAL_TYPE_ABERRATION ||
  576.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_BEAST ||
  577.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_ELEMENTAL ||
  578.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_VERMIN ||
  579.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_MAGICAL_BEAST ||
  580.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_UNDEAD ||
  581.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_DRAGON ||
  582.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_ANIMAL ||
  583.                GetRacialType(OBJECT_SELF) != RACIAL_TYPE_CONSTRUCT)
  584.             {
  585.                 //Use healing potions to not die
  586.                 if(TalentHealingSelf()) {return;}
  587.                 //Use potions of enhancement and protection
  588.                 if(TalentBuffSelf()) {return;}
  589.             }
  590.             //Check if the character can enhance themselves
  591.             if(TalentUseEnhancementOnSelf()) {return;}
  592.             //Check for Paladins who can turn undead
  593.             if(TalentUseTurning()) {return;}
  594.             //Sneak Attack Flanking attack
  595.             if(TalentSneakAttack()) {return;}
  596.             //Use melee skills and feats
  597.             if(TalentMeleeAttack(oIntruder)) {return;}
  598.             return;
  599.         }
  600.         else if(nClass == CLASS_TYPE_COMMONER)
  601.         {
  602.             if(TalentFlee(oIntruder)) {return;}
  603.             return;
  604.         }
  605.         else if(nClass == CLASS_TYPE_UNDEAD)
  606.         {
  607.             //SpeakString("Determining Combat Round Undead");
  608.             if(TalentPersistentAbilities()) {return;}
  609.             if(nOffense > 75)
  610.             {
  611.                 if(TalentAdvancedProtectSelf()){return;}
  612.                 //Check if the character can enhance themselves
  613.                 if(TalentUseEnhancementOnSelf()) {return;}
  614.                 // Check for enhancements on party
  615.                 if(TalentEnhanceOthers()) {return;}
  616.                 //Use protections on Self
  617.                 if(TalentUseProtectionOnSelf()) {;return;};
  618.                 //Check for Allies
  619.                 if(TalentUseProtectionOthers()) {return;}
  620.                 //Check for Allies
  621.                 if(TalentSummonAllies()) {return;}
  622.                  //Check for Personal Attackers
  623.                 if(TalentMeleeAttacked(oIntruder)) {return;}
  624.                  //Check for Ranged Attackers
  625.                 if(TalentRangedAttackers(oIntruder)) {return;}
  626.                  //Check for Ranged Enemies
  627.                 if(TalentRangedEnemies(oIntruder)) {return;}
  628.                  //Attack if out of spells
  629.                 if(TalentMeleeAttack(oIntruder)) {return;}
  630.             }
  631.             else
  632.             {
  633.                 if(TalentSummonAllies()) {return;}
  634.                  //Check for Personal Attackers
  635.                 if(TalentMeleeAttacked(oIntruder)) {return;}
  636.                  //Check for Ranged Attackers
  637.                 if(TalentRangedAttackers(oIntruder)) {return;}
  638.                  //Check for Ranged Enemies
  639.                 if(TalentRangedEnemies(oIntruder)) {return;}
  640.                 //Spell Attack
  641.                 if(TalentSpellAttack(oIntruder)) {return;}
  642.                  //Attack if out of spells
  643.                 if(TalentMeleeAttack(oIntruder)) {return;}
  644.             }
  645.             return;
  646.         }
  647.         else if(nClass == CLASS_TYPE_DRAGON)
  648.         {
  649.             //Use healing
  650.             if(TalentHeal()) {return;}
  651.             if(TalentCureCondition()) {return;}
  652.             if(d100() < 15)
  653.             {
  654.                 if(TalentRangedEnemies(oIntruder)) {return;}
  655.                 if(TalentMeleeAttacked(oIntruder)) {return;}
  656.             }
  657.             if(TalentPersistentAbilities()) {return;}
  658.             if(TalentAdvancedProtectSelf()){return;}
  659.             if(TalentUseProtectionOnSelf()) {return;}
  660.             if(TalentDragonCombat(oIntruder)) {return;}
  661.         }
  662.         else if (nClass == CLASS_TYPE_OUTSIDER)
  663.         {
  664.             if(TalentPersistentAbilities()) {return;}
  665.             if(TalentSummonAllies()) {return;}
  666.             if(d100() > 50)
  667.             {
  668.                 if(TalentMeleeAttack(oIntruder)) {return;}
  669.             }
  670.             if(GetAlignmentGoodEvil(OBJECT_SELF) == ALIGNMENT_GOOD)
  671.             {
  672.                 if(TalentHeal()) {return;}
  673.             }
  674.             if(TalentHealingSelf()) {return;}
  675.             if(TalentAdvancedProtectSelf()){return;}
  676.             if(TalentUseProtectionOnSelf()) {return;}
  677.             if(TalentUseEnhancementOnSelf()) {return;}
  678.             if(TalentMeleeAttacked(oIntruder)) {return;}
  679.             if(TalentRangedAttackers(oIntruder)) {return;}
  680.             if(TalentRangedEnemies(oIntruder)) {return;}
  681.             if(TalentSpellAttack(oIntruder)) {return;}
  682.             if(TalentMeleeAttack(oIntruder)) {return;}
  683.         }
  684.         else if (nClass == CLASS_TYPE_CONSTRUCT || nClass == CLASS_TYPE_ELEMENTAL)
  685.         {
  686.             if(TalentPersistentAbilities()) {return;}
  687.             if(TalentSummonAllies()) {return;}
  688.             if(d100() > 50)
  689.             {
  690.                 if(TalentMeleeAttack(oIntruder)) {return;}
  691.             }
  692.             if(TalentAdvancedProtectSelf()){return;}
  693.             if(TalentUseProtectionOnSelf()) {return;}
  694.             if(TalentUseEnhancementOnSelf()) {return;}
  695.             if(TalentMeleeAttacked(oIntruder)) {return;}
  696.             if(TalentRangedAttackers(oIntruder)) {return;}
  697.             if(TalentRangedEnemies(oIntruder)) {return;}
  698.             if(TalentSpellAttack(oIntruder)) {return;}
  699.             if(TalentMeleeAttack(oIntruder)) {return;}
  700.         }
  701.         else
  702.         {
  703.             if(TalentPersistentAbilities()) {return;}
  704.             //Check if I am injured
  705.             if(TalentHeal()) {return;}
  706.             if(nOffense > 75)
  707.             {
  708.                 if(TalentAdvancedProtectSelf()){return;}
  709.                 //Check if the character can enhance themselves
  710.                 if(TalentUseEnhancementOnSelf()) {return;}
  711.                 // Check for enhancements on party
  712.                 if(TalentEnhanceOthers()) {return;}
  713.                 //Use protections on Self
  714.                 if(TalentUseProtectionOnSelf()) {return;}
  715.                 //Check for Allies
  716.                 if(TalentUseProtectionOthers()) {return;}
  717.                 //Check for Allies
  718.                 if(TalentSummonAllies()) {return;}
  719.                  //Check for Personal Attackers
  720.                 if(TalentMeleeAttacked(oIntruder)) {return;}
  721.                  //Check for Ranged Attackers
  722.                 if(TalentRangedAttackers(oIntruder)) {return;}
  723.                  //Check for Ranged Enemies
  724.                 if(TalentRangedEnemies(oIntruder)) {return;}
  725.                  //Attack if out of spells
  726.                 if(TalentMeleeAttack(oIntruder)) {return;}
  727.             }
  728.             else
  729.             {
  730.                 if(TalentSummonAllies()) {return;}
  731.                  //Check for Personal Attackers
  732.                 if(TalentMeleeAttacked(oIntruder)) {return;}
  733.                  //Check for Ranged Attackers
  734.                 if(TalentRangedAttackers(oIntruder)) {return;}
  735.                  //Check for Ranged Enemies
  736.                 if(TalentRangedEnemies(oIntruder)) {return;}
  737.                  //Spell Attack
  738.                 if(TalentSpellAttack(oIntruder)) {return;}
  739.                   //Attack if out of spells
  740.                 if(TalentMeleeAttack(oIntruder)) {return;}
  741.             }
  742.             return;
  743.         }
  744.     }
  745.     //This check is to make sure that people do not drop out of combat before they are supposed to.
  746.     object oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  747.     if(GetIsObjectValid(oTarget))
  748.     {
  749.         SpeakString("Danger Will Robinson Danger");
  750.         DetermineCombatRound(oTarget);
  751.         return;
  752.     }
  753.     //This is a call to the function which determines which way point to go back to.
  754.     ClearAllActions();
  755.     SetLocalObject(OBJECT_SELF, "NW_GENERIC_LAST_ATTACK_TARGET", OBJECT_INVALID);
  756.     WalkWayPoints();
  757. }
  758.  
  759. //::///////////////////////////////////////////////
  760. //:: SetListeningPatterns
  761. //:: Copyright (c) 2001 Bioware Corp.
  762. //:://////////////////////////////////////////////
  763. /*
  764.     Sets the correct listen checks on the NPC by
  765.     determining what talents they possess or what
  766.     class they use.
  767.     
  768.     This is also a good place to set up all of
  769.     the sleep and appear disappear animations for
  770.     various models.
  771. */
  772. //:://////////////////////////////////////////////
  773. //:: Created By: Preston Watamaniuk
  774. //:: Created On: Oct 24, 2001
  775. //:://////////////////////////////////////////////
  776.  
  777. void SetListeningPatterns()
  778. {
  779.     //There is a 70% chance to make someone sleep if it is night.
  780.     //If they have no way points to walk.
  781.     if(GetIsNight() && !CheckWayPoints())
  782.     {
  783.         if(GetSpawnInCondition(NW_FLAG_SLEEPING_AT_NIGHT))
  784.         {
  785.             if(d10() <= 7)
  786.             {
  787.                 int nRand = Random(361);
  788.                 SetFacing(IntToFloat(nRand));
  789.                 //effect eSleep = EffectSleep();
  790.                 //ApplyEffectToObject(DURATION_TYPE_PERMANENT, eSleep, OBJECT_SELF);
  791.             }
  792.         }
  793.     }
  794.     if(GetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION))
  795.     {
  796.         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "USING SPAWN IN CONDITION NOW BASTARDO");
  797.  
  798.         effect eAppear = EffectAppear();
  799.         ApplyEffectToObject(DURATION_TYPE_INSTANT, eAppear, OBJECT_SELF);
  800.     }
  801.  
  802.     SetListening(OBJECT_SELF, TRUE);
  803.  
  804.     SetListenPattern(OBJECT_SELF, "NW_I_WAS_ATTACKED", 1);
  805.     
  806.     //This sets the commoners listen pattern to mob under
  807.     //certain conditions
  808.     if(GetLevelByClass(CLASS_TYPE_COMMONER) > 0)
  809.     {
  810.         SetListenPattern(OBJECT_SELF, "NW_MOB_ATTACK", 2);
  811.     }
  812.     SetListenPattern(OBJECT_SELF, "NW_I_AM_DEAD", 3);
  813.  
  814.     //Set a custom listening pattern for the creature so that placables with
  815.     //"NW_BLOCKER" + Blocker NPC Tag will correctly call to their blockers.
  816.     string sBlocker = "NW_BLOCKER_BLK_" + GetTag(OBJECT_SELF);
  817.     SetListenPattern(OBJECT_SELF, sBlocker, 4);
  818.     SetListenPattern(OBJECT_SELF, "NW_CALL_TO_ARMS", 6);
  819. }
  820.  
  821. //::///////////////////////////////////////////////
  822. //:: Respond To Shouts
  823. //:: Copyright (c) 2001 Bioware Corp.
  824. //:://////////////////////////////////////////////
  825. /*
  826.     Allows the listener to react in a manner
  827.     consistant with the given shout but only to one
  828.     combat shout per round
  829. */
  830. //:://////////////////////////////////////////////
  831. //:: Created By: Preston Watamaniuk
  832. //:: Created On: Oct 25, 2001
  833. //:://////////////////////////////////////////////
  834.  
  835. //NOTE ABOUT COMMONERS
  836. /*
  837.     Commoners are universal cowards.  If you attack anyone they will flee for 4 seconds away from the attacker.
  838.     However to make the commoners into a mob, make a single commoner at least 10th level of the same faction.
  839.     If that higher level commoner is attacked or killed then the commoners will attack the attacker.  They will disperse again
  840.     after some of them are killed.  Should NOT make multi-class creatures using commoners.
  841. */
  842. //NOTE ABOUT BLOCKERS
  843. /*
  844.     It should be noted that the Generic Script for On Dialogue attempts to get a local set on the shouter by itself.
  845.     This object represents the LastOpenedBy object.  It is this object that becomes the oIntruder within this function.
  846. */
  847.  
  848. //NOTE ABOUT INTRUDERS
  849. /*
  850.     The intruder object is for cases where a placable needs to pass a LastOpenedBy Object or a AttackMyAttacker
  851.     needs to make his attacker the enemy of everyone.
  852. */
  853.  
  854. void RespondToShout(object oShouter, int nShoutIndex, object oIntruder = OBJECT_INVALID)
  855. {
  856.     switch (nShoutIndex)
  857.     {
  858.         case 1://NW_GENERIC_SHOUT_I_WAS_ATTACKED:
  859.             {
  860.                 object oTarget = oIntruder;
  861.                 if(!GetIsObjectValid(oTarget))
  862.                 {
  863.                     oTarget = GetLastHostileActor(oShouter);
  864.                 }
  865.                 if(!GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL))
  866.                 {
  867.                     if(!GetLevelByClass(CLASS_TYPE_COMMONER))
  868.                     {
  869.                         if(!GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()))
  870.                         {
  871.                             if(GetIsObjectValid(oTarget))
  872.                             {
  873.                                 if(!GetIsFriend(oTarget) && GetIsFriend(oShouter))
  874.                                 {
  875.                                     RemoveAmbientSleep();
  876.                                     //DetermineCombatRound(oTarget);
  877.                                     DetermineCombatRound(GetLastHostileActor(oShouter));
  878.                                 }
  879.                             }
  880.                         }
  881.                     }
  882.                     else if (GetLevelByClass(CLASS_TYPE_COMMONER, oShouter) >= 10)
  883.                     {
  884.                         ActionAttack(GetLastHostileActor(oShouter));
  885.                     }
  886.                     else
  887.                     {
  888.                         DetermineCombatRound(oIntruder);
  889.                     }
  890.                 }
  891.                 else
  892.                 {
  893.                     DetermineSpecialBehavior();
  894.                 }
  895.             }
  896.         break;
  897.  
  898.         case 2://NW_GENERIC_SHOUT_MOB_ATTACK:
  899.             {
  900.                 if(!GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL))
  901.                 {
  902.  
  903.                     //Is friendly check to make sure that only like minded commoners attack.
  904.                     if(GetIsFriend(oShouter))
  905.                     {
  906.                         ActionAttack(GetLastHostileActor(oShouter));
  907.                     }
  908.                     //if(TalentMeleeAttack()) {return;}
  909.                 }
  910.                 else
  911.                 {
  912.                     DetermineSpecialBehavior();
  913.                 }
  914.             }
  915.         break;
  916.  
  917.         case 3://NW_GENERIC_SHOUT_I_AM_DEAD:
  918.             {
  919.                 if(!GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL))
  920.                 {
  921.                     //Use I was attacked script above
  922.                     if(!GetLevelByClass(CLASS_TYPE_COMMONER))
  923.                     {
  924.                         if(!GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()))
  925.                         {
  926.                             if(GetIsObjectValid(GetLastHostileActor(oShouter)))
  927.                             {
  928.                                 if(!GetIsFriend(GetLastHostileActor(oShouter)) && GetIsFriend(oShouter))
  929.                                 {
  930.                                     DetermineCombatRound(GetLastHostileActor(oShouter));
  931.                                 }
  932.                             }
  933.                         }
  934.                     }
  935.                     else if (GetLevelByClass(CLASS_TYPE_COMMONER, oShouter) >= 10)
  936.                     {
  937.                         ActionAttack(GetLastHostileActor(oShouter));
  938.                     }
  939.                     else
  940.                     {
  941.                         DetermineCombatRound();
  942.                     }
  943.                 
  944.                 }
  945.                 else
  946.                 {
  947.                     DetermineSpecialBehavior();
  948.                 }
  949.             }
  950.         break;
  951.         //For this shout to work the object must shout the following
  952.         //string sHelp = "NW_BLOCKER_BLK_" + GetTag(OBJECT_SELF);
  953.         case 4: //BLOCKER OBJECT HAS BEEN DISTURBED
  954.             {
  955.                 if(!GetLevelByClass(CLASS_TYPE_COMMONER))
  956.                 {
  957.                     if(!GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()))
  958.                     {
  959.                         if(GetIsObjectValid(oIntruder))
  960.                         {
  961.                             SetIsTemporaryEnemy(oIntruder);
  962.                             DetermineCombatRound(oIntruder);
  963.                         }
  964.                     }
  965.                 }
  966.                 else if (GetLevelByClass(CLASS_TYPE_COMMONER, oShouter) >= 10)
  967.                 {
  968.                     ActionAttack(oIntruder);
  969.                 }
  970.                 else
  971.                 {
  972.                     DetermineCombatRound();
  973.                 }
  974.             }
  975.         break;
  976.         
  977.         case 5: //ATTACK MY TARGET
  978.             {
  979.                 AdjustReputation(oIntruder, OBJECT_SELF, -100);
  980.                 if(GetIsFriend(oShouter))
  981.                 {
  982.                     SetIsTemporaryEnemy(oIntruder);
  983.                     ClearAllActions();
  984.                     DetermineCombatRound(oIntruder);
  985.                 }
  986.             }
  987.         break;
  988.         
  989.         case 6: //CALL_TO_ARMS
  990.             {
  991.                 //This was once commented out.
  992.                 DetermineCombatRound();
  993.             }
  994.         break;
  995.         
  996.         //ASSOCIATE SHOUT RESPONSES  ******************************************************************************
  997.         
  998.         case ASSOCIATE_COMMAND_ATTACKNEAREST: //Used to de-activate AGGRESSIVE DEFEND MODE
  999.             {
  1000.                 ResetHenchmenState();
  1001.                 SetAssociateState(NW_ASC_MODE_DEFEND_MASTER, FALSE);
  1002.                 SetAssociateState(NW_ASC_MODE_STAND_GROUND, FALSE);
  1003.                 DetermineCombatRound();
  1004.             }
  1005.         break;
  1006.         
  1007.         case ASSOCIATE_COMMAND_FOLLOWMASTER: //Only used to retreat, or break free from Stand Ground Mode
  1008.             {
  1009.                 ResetHenchmenState();
  1010.                 SetAssociateState(NW_ASC_MODE_STAND_GROUND, FALSE);
  1011.                 DelayCommand(2.5, PlayVoiceChat(VOICE_CHAT_CANDO));
  1012.  
  1013.                 if(GetAssociateState(NW_ASC_AGGRESSIVE_STEALTH))
  1014.                 {
  1015.                    //ActionUseSkill(SKILL_HIDE, OBJECT_SELF);
  1016.                 }
  1017.                 if(GetAssociateState(NW_ASC_AGGRESSIVE_SEARCH))
  1018.                 {
  1019.                    ActionUseSkill(SKILL_SEARCH, OBJECT_SELF);
  1020.                 }
  1021.                 ActionForceFollowObject(GetMaster(), GetFollowDistance());
  1022.                 SetAssociateState(NW_ASC_IS_BUSY);
  1023.                 DelayCommand(5.0, SetAssociateState(NW_ASC_IS_BUSY, FALSE));
  1024.             }
  1025.         break;
  1026.         
  1027.         case ASSOCIATE_COMMAND_GUARDMASTER: //Used to activate AGGRESSIVE DEFEND MODE
  1028.             {
  1029.                 ResetHenchmenState();
  1030.                 DelayCommand(2.5, PlayVoiceChat(VOICE_CHAT_CANDO));
  1031.                 //Companions will only attack the Masters Last Attacker
  1032.                 SetAssociateState(NW_ASC_MODE_DEFEND_MASTER);
  1033.                 SetAssociateState(NW_ASC_MODE_STAND_GROUND, FALSE);
  1034.                 if(GetIsObjectValid(GetLastHostileActor(GetMaster())))
  1035.                 {
  1036.                     DetermineCombatRound(GetLastHostileActor(GetMaster()));
  1037.                 }
  1038.             }
  1039.         break;
  1040.         
  1041.         case ASSOCIATE_COMMAND_HEALMASTER: //Ignore current healing settings and heal me now
  1042.             {
  1043.                 ResetHenchmenState();
  1044.                 //SetCommandable(TRUE);
  1045.                 if(TalentCureCondition()) {DelayCommand(2.0, PlayVoiceChat(VOICE_CHAT_CANDO)); return;}
  1046.                 if(TalentHeal(TRUE)) {DelayCommand(2.0, PlayVoiceChat(VOICE_CHAT_CANDO)); return;}
  1047.                 DelayCommand(2.5, PlayVoiceChat(VOICE_CHAT_CANTDO));
  1048.             }
  1049.         break;
  1050.         
  1051.         case ASSOCIATE_COMMAND_MASTERFAILEDLOCKPICK: //Check local for Re-try locked doors and
  1052.             {
  1053.                 if(!GetAssociateState(NW_ASC_MODE_STAND_GROUND))
  1054.                 {
  1055.                     if(GetAssociateState(NW_ASC_RETRY_OPEN_LOCKS))
  1056.                     {
  1057.                         int bValid = TRUE;
  1058.                         object oLastObject = GetLockedObject(GetMaster());
  1059.                         int nSkill = GetSkillRank(SKILL_OPEN_LOCK) - GetAbilityModifier(ABILITY_DEXTERITY);
  1060.  
  1061.                         if(GetIsObjectValid(oLastObject) && GetPlotFlag(oLastObject) == FALSE)
  1062.                         {
  1063.                             if(GetIsDoorActionPossible(oLastObject, DOOR_ACTION_KNOCK) || GetIsPlaceableObjectActionPossible(oLastObject, PLACEABLE_ACTION_KNOCK))
  1064.                             {
  1065.                                 ClearAllActions();
  1066.                                 PlayVoiceChat(VOICE_CHAT_CANDO);
  1067.                                 ActionCastSpellAtObject(SPELL_KNOCK, oLastObject);
  1068.                                 ActionWait(1.0);
  1069.                                 bValid = FALSE;
  1070.                             }
  1071.                             else if (GetIsDoorActionPossible(oLastObject, DOOR_ACTION_UNLOCK)|| GetIsPlaceableObjectActionPossible(oLastObject, PLACEABLE_ACTION_UNLOCK))
  1072.                             {
  1073.                                 ClearAllActions();
  1074.                                 PlayVoiceChat(VOICE_CHAT_PICKLOCK);
  1075.                                 ActionWait(1.0);
  1076.                                 ActionUseSkill(SKILL_OPEN_LOCK,oLastObject);
  1077.                                 bValid = FALSE;
  1078.                             }
  1079.                             else if(nSkill < 5 && GetAbilityScore(OBJECT_SELF, ABILITY_STRENGTH) >= 16 && GetSkillRank(SKILL_OPEN_LOCK) <= 0)
  1080.                             {
  1081.                                 if(GetIsDoorActionPossible(oLastObject, DOOR_ACTION_BASH) || GetIsPlaceableObjectActionPossible(oLastObject, PLACEABLE_ACTION_BASH))
  1082.                                 {
  1083.                                     ClearAllActions();
  1084.                                     PlayVoiceChat(VOICE_CHAT_CANDO);
  1085.                                     ActionEquipMostDamagingMelee(oLastObject);
  1086.                                     ActionAttack(oLastObject);
  1087.                                     SetLocalObject(OBJECT_SELF, "NW_GENERIC_DOOR_TO_BASH", oLastObject);
  1088.                                     bValid = FALSE;
  1089.                                 }
  1090.                             }
  1091.                             if(bValid == TRUE)
  1092.                             {
  1093.                                 //ClearAllActions();
  1094.                                 PlayVoiceChat(VOICE_CHAT_CANTDO);
  1095.                             }
  1096.                             else
  1097.                             {
  1098.                                 ActionDoCommand(PlayVoiceChat(VOICE_CHAT_TASKCOMPLETE));
  1099.                             }
  1100.                         }
  1101.                     }
  1102.                 }
  1103.             }
  1104.         break;
  1105.         
  1106.         case ASSOCIATE_COMMAND_MASTERUNDERATTACK:  //Check whether the master has you in AGGRESSIVE DEFEND MODE
  1107.             {
  1108.                 if(!GetAssociateState(NW_ASC_MODE_STAND_GROUND))
  1109.                 {
  1110.                     //Check the henchmens current target
  1111.                     object oTarget = GetAttemptedAttackTarget();
  1112.                     if(!GetIsObjectValid(oTarget))
  1113.                     {
  1114.                         oTarget = GetAttemptedSpellTarget();
  1115.                         if(!GetIsObjectValid(oTarget))
  1116.                         {
  1117.                             if(GetAssociateState(NW_ASC_MODE_DEFEND_MASTER))
  1118.                             {
  1119.                                 //PlayVoiceChat(VOICE_CHAT_ENEMIES);
  1120.                                 DetermineCombatRound(GetLastHostileActor(GetMaster()));
  1121.                             }
  1122.                             else
  1123.                             {
  1124.                                 //PlayVoiceChat(VOICE_CHAT_ENEMIES);
  1125.                                 DetermineCombatRound();
  1126.                             }
  1127.                         }
  1128.                     }
  1129.                     //Switch targets only if the target is not attacking the master and is greater than 6.0 from
  1130.                     //the master.
  1131.                     if(GetAttackTarget(oTarget) != GetMaster() && GetDistanceBetween(oTarget, GetMaster()) > 6.0)
  1132.                     {
  1133.                         if(GetAssociateState(NW_ASC_MODE_DEFEND_MASTER) && GetIsObjectValid(GetLastHostileActor(GetMaster())))
  1134.                         {
  1135.                             //PlayVoiceChat(VOICE_CHAT_ENEMIES);
  1136.                             DetermineCombatRound(GetLastHostileActor(GetMaster()));
  1137.                         }
  1138.                     }
  1139.                 }
  1140.             }
  1141.         break;
  1142.  
  1143.         case ASSOCIATE_COMMAND_STANDGROUND: //No longer follow the master or guard him
  1144.             {
  1145.                 SetAssociateState(NW_ASC_MODE_STAND_GROUND);
  1146.                 SetAssociateState(NW_ASC_MODE_DEFEND_MASTER, FALSE);
  1147.                 DelayCommand(2.0, PlayVoiceChat(VOICE_CHAT_CANDO));
  1148.                 ActionAttack(OBJECT_INVALID);
  1149.                 ClearAllActions();
  1150.             }
  1151.         break;
  1152.         
  1153.         case ASSOCIATE_COMMAND_MASTERSAWTRAP:
  1154.             {
  1155.                 int nCheck = 0;
  1156.                 if(!GetIsInCombat())
  1157.                 {
  1158.                     if(!GetAssociateState(NW_ASC_MODE_STAND_GROUND))
  1159.                     {
  1160.                         object oTrap = GetLastTrapDetected();
  1161.                         if(GetIsObjectValid(oTrap))
  1162.                         {
  1163.                             int nTrapDC = GetTrapDisarmDC(oTrap);
  1164.                             int nSkill = GetSkillRank(SKILL_DISABLE_TRAP);
  1165.                             int nMod = GetAbilityModifier(ABILITY_DEXTERITY);
  1166.                             if((nSkill - nMod) > 0)
  1167.                             {
  1168.                                 nSkill = nSkill + 20 - nTrapDC;
  1169.                             }
  1170.                             else
  1171.                             {
  1172.                                 nSkill = 0;
  1173.                                 nCheck = 1;
  1174.                             }
  1175.  
  1176.                             if(GetCurrentAction(OBJECT_SELF) != ACTION_DISABLETRAP && nSkill > 0)
  1177.                             {
  1178.                                 PlayVoiceChat(VOICE_CHAT_STOP);
  1179.                                 if(GetHasSkill(SKILL_DISABLE_TRAP, OBJECT_SELF))
  1180.                                 {
  1181.                                     ClearAllActions();
  1182.                                     ActionUseSkill(SKILL_DISABLE_TRAP, oTrap);
  1183.                                     ActionDoCommand(SetCommandable(TRUE));
  1184.                                     ActionDoCommand(PlayVoiceChat(VOICE_CHAT_TASKCOMPLETE));
  1185.                                     SetCommandable(FALSE);
  1186.                                     nCheck = 2;
  1187.                                 }
  1188.                             }
  1189.                             else if(nCheck = 0 &&
  1190.                                     GetSkillRank(SKILL_DISABLE_TRAP) > 0 &&
  1191.                                     GetCurrentAction(OBJECT_SELF) != ACTION_DISABLETRAP)
  1192.                             {
  1193.                                 PlayVoiceChat(VOICE_CHAT_CANTDO);
  1194.                             }
  1195.                         }
  1196.                     }
  1197.                 }
  1198.             }
  1199.         break;
  1200.         
  1201.         case ASSOCIATE_COMMAND_MASTERATTACKEDOTHER:
  1202.             {
  1203.                 if(!GetAssociateState(NW_ASC_MODE_STAND_GROUND))
  1204.                 {
  1205.                     if(!GetAssociateState(NW_ASC_MODE_DEFEND_MASTER))
  1206.                     {
  1207.                         if(!GetIsFighting(OBJECT_SELF))
  1208.                         {
  1209.                             //PlayVoiceChat(VOICE_CHAT_ENEMIES);
  1210.                             object oAttack = GetAttackTarget(GetMaster());
  1211.                             if(GetIsObjectValid(oAttack) && GetObjectSeen(oAttack))
  1212.                             {
  1213.                                 ClearAllActions();
  1214.                                 DetermineCombatRound(oAttack);
  1215.                             }
  1216.                         }
  1217.                     }
  1218.                 }
  1219.             }
  1220.         break;
  1221.         
  1222.         case ASSOCIATE_COMMAND_MASTERGOINGTOBEATTACKED:
  1223.             {
  1224.                 if(!GetAssociateState(NW_ASC_MODE_STAND_GROUND))
  1225.                 {
  1226.                     if(!GetIsFighting(OBJECT_SELF))
  1227.                     {
  1228.                         object oAttacker = GetGoingToBeAttackedBy(GetMaster());
  1229.                         if(GetIsObjectValid(oAttacker) && GetObjectSeen(oAttacker))
  1230.                         {
  1231.                             ClearAllActions();
  1232.                             //PlayVoiceChat(VOICE_CHAT_ENEMIES);
  1233.                             DetermineCombatRound(oAttacker);
  1234.                         }
  1235.                     }
  1236.                 }
  1237.             }
  1238.         break;
  1239.         
  1240.         case ASSOCIATE_COMMAND_LEAVEPARTY:
  1241.             {
  1242.                 object oMaster = GetMaster();
  1243.                 if(GetIsObjectValid(oMaster))
  1244.                 {
  1245.                     ClearAllActions();
  1246.                     if(GetAssociate(ASSOCIATE_TYPE_HENCHMAN, GetMaster()) == OBJECT_SELF)
  1247.                     {
  1248.                         AddJournalQuestEntry("Henchman",50,GetMaster(),FALSE,FALSE,TRUE);
  1249.                     }
  1250.                     SetLocalObject(OBJECT_SELF,"NW_L_FORMERMASTER", oMaster);
  1251.                     RemoveHenchman(oMaster, OBJECT_SELF);
  1252.                 }
  1253.             }
  1254.         break;
  1255.     }
  1256. }
  1257.  
  1258. //::///////////////////////////////////////////////
  1259. //:: Set and Get NPC Warning Status
  1260. //:: Copyright (c) 2001 Bioware Corp.
  1261. //:://////////////////////////////////////////////
  1262. /*
  1263.     This function sets a local int on OBJECT_SELF
  1264.     which will be checked in the On Attack, On
  1265.     Damaged and On Disturbed scripts to check if
  1266.     the offending poarty was a PC and was friendly.
  1267.     The Get will return the status of the local.
  1268. */
  1269. //:://////////////////////////////////////////////
  1270. //:: Created By: Preston Watamaniuk
  1271. //:: Created On: Oct 29, 2001
  1272. //:://////////////////////////////////////////////
  1273.  
  1274. void SetNPCWarningStatus(int nStatus = TRUE)
  1275. {
  1276.     SetLocalInt(OBJECT_SELF, "NW_GENERIC_WARNING_STATUS", nStatus);
  1277. }
  1278.  
  1279. int GetNPCWarningStatus()
  1280. {
  1281.     return GetLocalInt(OBJECT_SELF, "NW_GENERIC_WARNING_STATUS");
  1282. }
  1283.  
  1284. //::///////////////////////////////////////////////
  1285. //:: Set SummonHelpIfAttacked
  1286. //:: Copyright (c) 2001 Bioware Corp.
  1287. //:://////////////////////////////////////////////
  1288. /*
  1289.     This function works in tandem with an encounter
  1290.     to spawn in guards to fight for the attacked
  1291.     NPC.  MAKE SURE THE ENCOUNTER TAG IS SET TO:
  1292.     
  1293.              "ENC_" + NPC TAG
  1294. */
  1295. //:://////////////////////////////////////////////
  1296. //:: Created By: Preston Watamaniuk
  1297. //:: Created On: Oct 29, 2001
  1298. //:://////////////////////////////////////////////
  1299.  
  1300. //Presently Does not work with the current implementation of encounter trigger
  1301. void SetSummonHelpIfAttacked()
  1302. {
  1303.     string sEncounter = "ENC_" + GetTag(OBJECT_SELF);
  1304.     object oTrigger = GetObjectByTag(sEncounter);
  1305.  
  1306.     if(GetIsObjectValid(oTrigger))
  1307.     {
  1308.         SetEncounterActive(TRUE, oTrigger);
  1309.     }
  1310. }
  1311.  
  1312. //************************************************************************************************************************************
  1313. //************************************************************************************************************************************
  1314. //
  1315. // ESCAPE FUNCTIONS
  1316. //
  1317. //************************************************************************************************************************************
  1318. //************************************************************************************************************************************
  1319.  
  1320. //::///////////////////////////////////////////////
  1321. //:: Set, Get Activate,Flee to Exit
  1322. //:: Copyright (c) 2001 Bioware Corp.
  1323. //:://////////////////////////////////////////////
  1324. /*
  1325.     The target object flees to the specified
  1326.     way point and then destroys itself, to be
  1327.     respawned at a later point.  For unkillable
  1328.     sign post characters who are not meant to fight
  1329.     back.
  1330. */
  1331. //:://////////////////////////////////////////////
  1332. //:: Created By: Preston Watamaniuk
  1333. //:: Created On: Oct 29, 2001
  1334. //:://////////////////////////////////////////////
  1335.  
  1336. //This function is used only because ActionDoCommand can only accept void functions
  1337. void CreateSignPostNPC(string sTag, location lLocal)
  1338. {
  1339.     CreateObject(OBJECT_TYPE_CREATURE, sTag, lLocal);
  1340. }
  1341.  
  1342. void ActivateFleeToExit()
  1343. {
  1344.      object oExitWay = GetWaypointByTag("EXIT_" + GetTag(OBJECT_SELF));
  1345.      int nPlot = GetLocalInt(OBJECT_SELF, "NW_GENERIC_MASTER");
  1346.      location lLocal = GetLocalLocation(OBJECT_SELF, "NW_GENERIC_START_POINT");
  1347.      float fDelay =  6.0;
  1348.       string sTag = GetTag(OBJECT_SELF);
  1349.  
  1350.      if(nPlot & NW_FLAG_TELEPORT_RETURN || nPlot & NW_FLAG_TELEPORT_LEAVE)
  1351.      {
  1352.         effect eVis = EffectVisualEffect(VFX_IMP_UNSUMMON);
  1353.         ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, OBJECT_SELF);
  1354.         if(nPlot & NW_FLAG_TELEPORT_RETURN)
  1355.         {
  1356.             DelayCommand(fDelay, ActionDoCommand(CreateSignPostNPC(sTag, lLocal)));
  1357.         }
  1358.         ActionDoCommand(DestroyObject(OBJECT_SELF, 0.75));
  1359.      }
  1360.      else
  1361.      {
  1362.         if(nPlot & NW_FLAG_ESCAPE_LEAVE)
  1363.         {
  1364.             ActionMoveToObject(oExitWay, TRUE);
  1365.             ActionDoCommand(DestroyObject(OBJECT_SELF, 1.0));
  1366.         }
  1367.         else if(nPlot & NW_FLAG_ESCAPE_RETURN)
  1368.         {
  1369.             ActionMoveToObject(oExitWay, TRUE);
  1370.             DelayCommand(fDelay, ActionDoCommand(CreateSignPostNPC(sTag, lLocal)));
  1371.             ActionDoCommand(DestroyObject(OBJECT_SELF, 1.0));
  1372.         }
  1373.      }
  1374. }
  1375.  
  1376. int GetFleeToExit()
  1377. {
  1378.     int nPlot = GetLocalInt(OBJECT_SELF, "NW_GENERIC_MASTER");
  1379.     if(nPlot & NW_FLAG_ESCAPE_RETURN)
  1380.     {
  1381.         return TRUE;
  1382.     }
  1383.     else if(nPlot & NW_FLAG_ESCAPE_LEAVE)
  1384.     {
  1385.         return TRUE;
  1386.     }
  1387.     else if(nPlot & NW_FLAG_TELEPORT_RETURN)
  1388.     {
  1389.         return TRUE;
  1390.     }
  1391.     else if(nPlot & NW_FLAG_TELEPORT_LEAVE)
  1392.     {
  1393.        return TRUE;
  1394.     }
  1395.     return FALSE;
  1396. }
  1397.  
  1398. //************************************************************************************************************************************
  1399. //************************************************************************************************************************************
  1400. //
  1401. //WAY POINT WALK FUNCTIONS
  1402. //
  1403. //************************************************************************************************************************************
  1404. //************************************************************************************************************************************
  1405.  
  1406. //::///////////////////////////////////////////////
  1407. //:: Walk Way Point Path
  1408. //:: Copyright (c) 2001 Bioware Corp.
  1409. //:://////////////////////////////////////////////
  1410. /*
  1411.     Allows specified person walk a waypoint path
  1412. */
  1413. //:://////////////////////////////////////////////
  1414. //:: Created By: Aidan Scanlan
  1415. //:: Created On: July 10, 2001
  1416. //:://////////////////////////////////////////////
  1417.  
  1418. void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)  //Run first circuit
  1419. {
  1420.     ClearAllActions();
  1421.     string DayWayString;
  1422.     string NightWayString;
  1423.     string DayPostString;
  1424.     string NightPostString;
  1425.     string sWay;
  1426.     string sPost;
  1427.     
  1428.     //The block of code below deals with night and day cycle for postings and walkway points.
  1429.     if(GetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING))
  1430.     {
  1431.         DayWayString = "WP_";
  1432.         NightWayString = "WN_";
  1433.         DayPostString = "POST_";
  1434.         NightPostString = "NIGHT_";
  1435.     }
  1436.     else
  1437.     {
  1438.         DayWayString = "WP_";
  1439.         NightWayString = "WP_";
  1440.         DayPostString = "POST_";
  1441.         NightPostString = "POST_";
  1442.     }
  1443.  
  1444.     if(GetIsDay() || GetIsDawn())
  1445.     {
  1446.         SetLocalString(OBJECT_SELF, "NW_GENERIC_WALKWAYS_PREFIX", DayWayString);
  1447.         SetLocalString(OBJECT_SELF, "NW_GENERIC_POSTING_PREFIX", DayPostString);
  1448.     }
  1449.     else
  1450.     {
  1451.         SetLocalString(OBJECT_SELF, "NW_GENERIC_WALKWAYS_PREFIX", NightWayString);
  1452.         SetLocalString(OBJECT_SELF, "NW_GENERIC_POSTING_PREFIX", NightPostString);
  1453.     }
  1454.  
  1455.  
  1456.     sWay = GetLocalString(OBJECT_SELF, "NW_GENERIC_WALKWAYS_PREFIX");
  1457.     sPost = GetLocalString(OBJECT_SELF, "NW_GENERIC_POSTING_PREFIX");
  1458.  
  1459.     //I have now determined what the prefixs for the current walkways and postings are and will use them instead
  1460.     // of POST_ and WP_
  1461.     
  1462.     if(GetSpawnInCondition(NW_FLAG_STEALTH))
  1463.     {
  1464.         //MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Attempting to Activate Stealth");
  1465.         ActionUseSkill(SKILL_HIDE, OBJECT_SELF);
  1466.     }
  1467.     if(GetSpawnInCondition(NW_FLAG_SEARCH))
  1468.     {
  1469.         //MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Attempting to Activate Search");
  1470.         ActionUseSkill(SKILL_SEARCH, OBJECT_SELF);
  1471.     }
  1472.     
  1473.     //Test if OBJECT_SELF has waypoints to walk
  1474.     string sWayTag = GetTag( OBJECT_SELF );
  1475.     sWayTag = sWay + sWayTag + "_01";
  1476.     object oWay1 = GetNearestObjectByTag(sWayTag);
  1477.     if(!GetIsObjectValid(oWay1))
  1478.     {
  1479.         oWay1 = GetObjectByTag(sWayTag);
  1480.     }
  1481.     if(GetIsObjectValid(oWay1) && GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS))
  1482.     {
  1483.         //turn off the ambient animations if the creature should walk way points.
  1484.         SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS, FALSE);
  1485.         SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS, FALSE);
  1486.     }
  1487.  
  1488.     if(GetIsObjectValid(oWay1))
  1489.     {
  1490.         int nNth = 1;
  1491.         int nTens;
  1492.         int nNum;
  1493.         object oNearest = GetNearestObject(OBJECT_TYPE_WAYPOINT, OBJECT_SELF, nNth);
  1494.         while (GetIsObjectValid(oNearest))
  1495.         {
  1496.            string sNearestTag = GetTag(oNearest);
  1497.            //removes the first 3 and last three characters from the waypoint's tag
  1498.            //and checks it against his own tag.  Waypoint tag format is WP_MyTag_XX.
  1499.            if( GetSubString( sNearestTag, 3, GetStringLength( sNearestTag ) - 6 ) == GetTag( OBJECT_SELF ) )
  1500.            {
  1501.                 string sTens = GetStringRight(GetTag(oNearest),2);
  1502.                 nTens = StringToInt(sTens)/10;
  1503.                 nNum= StringToInt(GetStringRight(GetTag(oNearest),1));
  1504.                 oNearest = OBJECT_INVALID;
  1505.            }
  1506.            else
  1507.            {
  1508.                nNth++;
  1509.                oNearest = GetNearestObject(OBJECT_TYPE_WAYPOINT,OBJECT_SELF,nNth);
  1510.            }
  1511.         }
  1512.         RunCircuit(nTens, nNum, nRun, fPause); //***************************************
  1513.         ActionWait(fPause);
  1514.         ActionDoCommand(RunNextCircuit(nRun, fPause));
  1515.         //ActionDoCommand(SignalEvent(OBJECT_SELF,EventUserDefined(2)));
  1516.     }
  1517.     else
  1518.     {
  1519.         sWayTag = GetTag( OBJECT_SELF );
  1520.         sWayTag = sPost + sWayTag;
  1521.         oWay1 = GetNearestObjectByTag(sWayTag);
  1522.         if(!GetIsObjectValid(oWay1))
  1523.         {
  1524.             oWay1 = GetObjectByTag(sWayTag);
  1525.         }
  1526.  
  1527.         if(GetIsObjectValid(oWay1))
  1528.         {
  1529.             ActionForceMoveToObject(oWay1, nRun, 1.0, 60.0);
  1530.             float fFacing = GetFacing(oWay1);
  1531.             ActionDoCommand(SetFacing(fFacing));
  1532.         }
  1533.     }
  1534.     if(GetIsObjectValid(oWay1) && GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS))
  1535.     {
  1536.         SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS, FALSE);
  1537.         SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS, FALSE);
  1538.     }
  1539. }
  1540.  
  1541. void RunNextCircuit(int nRun = FALSE, float fPause = 1.0)
  1542. {
  1543.     RunCircuit(0,1, nRun, fPause);  //***************************************
  1544.     ActionWait(fPause);
  1545.     ActionDoCommand(RunNextCircuit(nRun, fPause));
  1546.     //ActionDoCommand(SignalEvent(OBJECT_SELF,EventUserDefined(2)));
  1547. }
  1548.  
  1549. //::///////////////////////////////////////////////
  1550. //:: Run Circuit
  1551. //:: Copyright (c) 2001 Bioware Corp.
  1552. //:://////////////////////////////////////////////
  1553. /*
  1554.     Calculates the proper path to follow along a
  1555.     predetermined set of way points
  1556. */
  1557. //:://////////////////////////////////////////////
  1558. //:: Created By: Aidan Scanlan
  1559. //:: Created On: July 10, 2001
  1560. //:://////////////////////////////////////////////
  1561.  
  1562. void RunCircuit(int nTens, int nNum, int nRun = FALSE, float fPause = 1.0)
  1563. {
  1564.     // starting at a given way point, move sequentialy through incrementally
  1565.     // increasing points until there are no more valid ones.
  1566.     string sWay = GetLocalString(OBJECT_SELF, "NW_GENERIC_WALKWAYS_PREFIX");
  1567.  
  1568.     object oTargetPoint = GetWaypointByTag(sWay + GetTag(OBJECT_SELF) + "_" + IntToString(nTens) +IntToString(nNum));
  1569.  
  1570.     while(GetIsObjectValid(oTargetPoint))
  1571.     {
  1572.         ActionWait(fPause);
  1573.         ActionMoveToObject(oTargetPoint, nRun);
  1574.         nNum++;
  1575.         if (nNum > 9)
  1576.         {
  1577.             nTens++;
  1578.             nNum = 0;
  1579.         }
  1580.         oTargetPoint = GetWaypointByTag(sWay + GetTag(OBJECT_SELF) + "_" + IntToString(nTens) +IntToString(nNum));
  1581.     }
  1582.     // once there are no more waypoints available, decriment back to the last
  1583.     // valid point.
  1584.     nNum--;
  1585.     if (nNum < 0)
  1586.     {
  1587.         nTens--;
  1588.         nNum = 9;
  1589.     }
  1590.  
  1591.     // start the cycle again going back to point 01
  1592.     oTargetPoint = GetWaypointByTag(sWay + GetTag(OBJECT_SELF) + "_" + IntToString(nTens) +IntToString(nNum));
  1593.     while(GetIsObjectValid(oTargetPoint))
  1594.     {
  1595.         ActionWait(fPause);
  1596.         ActionMoveToObject(oTargetPoint, nRun);
  1597.         nNum--;
  1598.         if (nNum < 0)
  1599.         {
  1600.             nTens--;
  1601.             nNum = 9;
  1602.         }
  1603.         oTargetPoint = GetWaypointByTag(sWay + GetTag(OBJECT_SELF) + "_" + IntToString(nTens) +IntToString(nNum));
  1604.     }
  1605. }
  1606.  
  1607. //::///////////////////////////////////////////////
  1608. //:: Check Walkways
  1609. //:: Copyright (c) 2001 Bioware Corp.
  1610. //:://////////////////////////////////////////////
  1611. /*
  1612.     This function checks the passed in object to
  1613.     see if they are supposed to be walking to
  1614.     day or night postings.
  1615. */
  1616. //:://////////////////////////////////////////////
  1617. //:: Created By: Preston Watamaniuk
  1618. //:: Created On: Feb 26, 2002
  1619. //:://////////////////////////////////////////////
  1620.  
  1621. int CheckWayPoints(object oWalker = OBJECT_SELF)
  1622. {
  1623.     object oWay1;
  1624.     object oWay2;
  1625.     object oWay3;
  1626.     object oWay4;
  1627.     string sTag = GetTag(oWalker);
  1628.     if(GetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING))
  1629.     {
  1630.         oWay2 = GetWaypointByTag("NIGHT_" + sTag);
  1631.         oWay4 = GetWaypointByTag("WN_" + sTag + "_01");
  1632.     }
  1633.  
  1634.     oWay1 = GetWaypointByTag("POST_" + sTag);
  1635.     oWay3 = GetWaypointByTag("WP_" + sTag + "_01");
  1636.     
  1637.     if(GetIsObjectValid(oWay2) || GetIsObjectValid(oWay4) || GetIsObjectValid(oWay1) || GetIsObjectValid(oWay3))
  1638.     {
  1639.  
  1640.         return TRUE;
  1641.     }
  1642.     return FALSE;
  1643. }
  1644.  
  1645.  
  1646. //:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1647. //:: Talent checks and use functions
  1648. //:: Copyright (c) 2001 Bioware Corp.
  1649. //:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1650. /*
  1651.     This is a series of functions that check
  1652.     if a particular type of talent is available and
  1653.     if so then use that talent.
  1654. */
  1655. //:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1656. //:: Created By: Preston Watamaniuk
  1657. //:: Created On: Oct 16, 2001
  1658. //:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1659.  
  1660. // PROTECT SELF
  1661. int TalentUseProtectionOnSelf()
  1662. {
  1663.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOnSelf Enter");
  1664.     talent tUse;
  1665.     int nType, nIndex;
  1666.     int bValid = FALSE;
  1667.     int nCR = GetAssociateCRMax();
  1668.  
  1669.     tUse = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_PROTECTION_SELF, 20);
  1670.     if(!GetIsTalentValid(tUse))
  1671.     {
  1672.         tUse = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_PROTECTION_SINGLE, 20);
  1673.         if(GetIsTalentValid(tUse))
  1674.         {
  1675.            //MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "I have found a way to protect my self");
  1676.            bValid = TRUE;
  1677.         }
  1678.     }
  1679.     else
  1680.     {
  1681.         //MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "I have found a way to protect my self");
  1682.         bValid = TRUE;
  1683.     }
  1684.  
  1685.     if(bValid == TRUE)
  1686.     {
  1687.         nType = GetTypeFromTalent(tUse);
  1688.         nIndex = GetIdFromTalent(tUse);
  1689.  
  1690.         if(nType == TALENT_TYPE_SPELL)
  1691.         {
  1692.             if(!GetHasSpellEffect(nIndex))
  1693.             {
  1694.                 ClearAllActions();
  1695.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOnSelf Successful Exit");
  1696.  
  1697.                 ActionUseTalentOnObject(tUse, OBJECT_SELF);
  1698.                 return TRUE;
  1699.             }
  1700.         }
  1701.         else if(nType == TALENT_TYPE_FEAT)
  1702.         {
  1703.             if(!GetHasFeatEffect(nIndex))
  1704.             {
  1705.                 ClearAllActions();
  1706.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOnSelf Successful Exit");
  1707.                 ActionUseTalentOnObject(tUse, OBJECT_SELF);
  1708.                 return TRUE;
  1709.             }
  1710.         }
  1711.         else
  1712.         {
  1713.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOnSelf Successful Exit");
  1714.             ActionUseTalentOnObject(tUse, OBJECT_SELF);
  1715.             return TRUE;
  1716.         }
  1717.     }
  1718.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOnSelf Failed Exit");
  1719.     return FALSE;
  1720. }
  1721.  
  1722. //PROTECT PARTY
  1723. int TalentUseProtectionOthers()
  1724. {
  1725.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOthers Enter");
  1726.     talent tUse, tMass;
  1727.     int nType, nFriends, nIndex;
  1728.     int nCnt = 1;
  1729.     int bValid = FALSE;
  1730.     int nCR = GetAssociateCRMax();
  1731.     object oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  1732.     tUse = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_PROTECTION_SINGLE, nCR);
  1733.     tMass = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_PROTECTION_AREAEFFECT, nCR);
  1734.  
  1735.     //Override the nearest target if the master wants aggressive buff spells
  1736.     if(GetAssociateState(NW_ASC_AGGRESSIVE_BUFF) && GetAssociateState(NW_ASC_HAVE_MASTER))
  1737.     {
  1738.         oTarget = GetMaster();
  1739.     }
  1740.     
  1741.     while(GetIsObjectValid(oTarget))
  1742.     {
  1743.         if(GetIsTalentValid(tMass))
  1744.         {
  1745.             if(CheckFriendlyFireOnTarget(oTarget) > 2)
  1746.             {
  1747.                 nType = GetTypeFromTalent(tMass);
  1748.                 nIndex = GetIdFromTalent(tMass);
  1749.                 if(nType == TALENT_TYPE_SPELL)
  1750.                 {
  1751.                     if(!GetHasSpellEffect(nIndex, oTarget))
  1752.                     {
  1753.                         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOthers Successful Exit");
  1754.                         ClearAllActions();
  1755.                         ActionUseTalentOnObject(tMass, oTarget);
  1756.                         return TRUE;
  1757.                     }
  1758.                 }
  1759.                 else if(nType == TALENT_TYPE_FEAT)
  1760.                 {
  1761.                     if(!GetHasFeatEffect(nIndex, oTarget))
  1762.                     {
  1763.                         ClearAllActions();
  1764.                         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOthers Successful Exit");
  1765.                         ActionUseTalentOnObject(tUse, OBJECT_SELF);
  1766.                         return TRUE;
  1767.                     }
  1768.                 }
  1769.                 else
  1770.                 {
  1771.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOthers Successful Exit");
  1772.                     ClearAllActions();
  1773.                     ActionUseTalentOnObject(tMass, oTarget);
  1774.                     return TRUE;
  1775.                 }
  1776.             }
  1777.         }
  1778.  
  1779.         if(GetIsTalentValid(tUse))
  1780.         {
  1781.             nType = GetTypeFromTalent(tUse);
  1782.             nIndex = GetIdFromTalent(tUse);
  1783.             if(nType == TALENT_TYPE_SPELL)
  1784.             {
  1785.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Has Effects from Spell ID " + IntToString(nIndex) + " is: " + IntToString(GetHasSpellEffect(nIndex)));
  1786.                 if(!GetHasSpellEffect(nIndex, oTarget))
  1787.                 {
  1788.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOthers Successful Exit");
  1789.                     ClearAllActions();
  1790.                     ActionUseTalentOnObject(tUse, oTarget);
  1791.                     return TRUE;
  1792.                 }
  1793.             }
  1794.             else if(nType == TALENT_TYPE_FEAT)
  1795.             {
  1796.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Has Effects from Feat ID " + IntToString(nIndex) + " is: " + IntToString(GetHasSpellEffect(nIndex)));
  1797.                 if(!GetHasFeatEffect(nIndex, oTarget))
  1798.                 {
  1799.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOthers Successful Exit");
  1800.                     ClearAllActions();
  1801.                     ActionUseTalentOnObject(tUse, OBJECT_SELF);
  1802.                     return TRUE;
  1803.                 }
  1804.             }
  1805.             else
  1806.             {
  1807.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOthers Successful Exit");
  1808.                 ClearAllActions();
  1809.                 ActionUseTalentOnObject(tUse, oTarget);
  1810.                 return TRUE;
  1811.             }
  1812.         }
  1813.         nCnt++;
  1814.         oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  1815.     }
  1816.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseProtectionOthers Failed Exit");
  1817.     return FALSE;
  1818. }
  1819.  
  1820. // ENHANCE OTHERS
  1821. int TalentEnhanceOthers()
  1822. {
  1823.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentEnhanceOthers Enter");
  1824.     talent tUse, tMass;
  1825.     int nType, nFriends, nIndex;
  1826.     int nCnt = 1;
  1827.     int bValid = FALSE;
  1828.     int nCR = GetAssociateCRMax();
  1829.     object oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  1830.     tUse = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_ENHANCEMENT_SINGLE, nCR);
  1831.     tMass = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_ENHANCEMENT_AREAEFFECT, nCR);
  1832.     
  1833.     //Override the nearest target if the master wants aggressive buff spells
  1834.     if(GetAssociateState(NW_ASC_AGGRESSIVE_BUFF) && GetAssociateState(NW_ASC_HAVE_MASTER))
  1835.     {
  1836.         oTarget = GetMaster();
  1837.     }
  1838.     while(GetIsObjectValid(oTarget))
  1839.     {
  1840.         if(GetIsTalentValid(tMass))
  1841.         {
  1842.             if(CheckFriendlyFireOnTarget(oTarget) > 2)
  1843.             {
  1844.                 nType = GetTypeFromTalent(tMass);
  1845.                 nIndex = GetIdFromTalent(tMass);
  1846.                 if(nType == TALENT_TYPE_SPELL)
  1847.                 {
  1848.                     if(!GetHasSpellEffect(nIndex, oTarget))
  1849.                     {
  1850.                         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentEnhanceOthers Successful Exit");
  1851.                         ClearAllActions();
  1852.                         ActionUseTalentOnObject(tMass, oTarget);
  1853.                         return TRUE;
  1854.                     }
  1855.                 }
  1856.                 else if(nType == TALENT_TYPE_FEAT)
  1857.                 {
  1858.                     if(!GetHasFeatEffect(nIndex, oTarget))
  1859.                     {
  1860.                         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentEnhanceOthers Successful Exit");
  1861.                         ClearAllActions();
  1862.                         ActionUseTalentOnObject(tUse, OBJECT_SELF);
  1863.                         return TRUE;
  1864.                     }
  1865.                 }
  1866.                 else
  1867.                 {
  1868.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentEnhanceOthers Successful Exit");
  1869.                     ClearAllActions();
  1870.                     ActionUseTalentOnObject(tMass, oTarget);
  1871.                     return TRUE;
  1872.                 }
  1873.             }
  1874.         }
  1875.  
  1876.         if(GetIsTalentValid(tUse))
  1877.         {
  1878.             nType = GetTypeFromTalent(tUse);
  1879.             nIndex = GetIdFromTalent(tUse);
  1880.             if(nType == TALENT_TYPE_SPELL)
  1881.             {
  1882.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Has Effects from Spell ID " + IntToString(nIndex) + " is: " + IntToString(GetHasSpellEffect(nIndex)));
  1883.  
  1884.                 if(!GetHasSpellEffect(nIndex, oTarget))
  1885.                 {
  1886.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentEnhanceOthers Successful Exit");
  1887.                     ClearAllActions();
  1888.                     ActionUseTalentOnObject(tUse, oTarget);
  1889.                     return TRUE;
  1890.                 }
  1891.             }
  1892.             else if(nType == TALENT_TYPE_FEAT)
  1893.             {
  1894.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Has Effects from Feat ID " + IntToString(nIndex) + " is: " + IntToString(GetHasFeatEffect(nIndex)));
  1895.                 if(!GetHasFeatEffect(nIndex, oTarget))
  1896.                 {
  1897.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentEnhanceOthers Successful Exit");
  1898.                     ClearAllActions();
  1899.                     ActionUseTalentOnObject(tUse, OBJECT_SELF);
  1900.                     return TRUE;
  1901.                 }
  1902.             }
  1903.             else
  1904.             {
  1905.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentEnhanceOthers Successful Exit");
  1906.                 ClearAllActions();
  1907.                 ActionUseTalentOnObject(tUse, oTarget);
  1908.                 return TRUE;
  1909.             }
  1910.         }
  1911.         nCnt++;
  1912.         oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  1913.     }
  1914.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentEnhanceOthers Failed Exit");
  1915.     return FALSE;
  1916. }
  1917.  
  1918. // ENHANCE SELF
  1919. int TalentUseEnhancementOnSelf()
  1920. {
  1921.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseEnhancementOnSelf Enter");
  1922.     talent tUse;
  1923.     int nType;
  1924.     int bValid = FALSE;
  1925.     int nIndex;
  1926.     int nCR = GetAssociateCRMax();
  1927.  
  1928.     tUse = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_ENHANCEMENT_SELF, 20);
  1929.     if(!GetIsTalentValid(tUse))
  1930.     {
  1931.         tUse = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_ENHANCEMENT_SINGLE, 20);
  1932.         if(GetIsTalentValid(tUse))
  1933.         {
  1934.            bValid = TRUE;
  1935.         }
  1936.     }
  1937.     else
  1938.     {
  1939.         bValid = TRUE;
  1940.     }
  1941.  
  1942.     if(bValid == TRUE)
  1943.     {
  1944.         nType = GetTypeFromTalent(tUse);
  1945.         nIndex = GetIdFromTalent(tUse);
  1946.         
  1947.         if(nType == TALENT_TYPE_SPELL)
  1948.         {
  1949.             if(!GetHasSpellEffect(nIndex))
  1950.             {
  1951.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseEnhancementOnSelf Successful Exit");
  1952.                 ClearAllActions();
  1953.                 ActionUseTalentOnObject(tUse, OBJECT_SELF);
  1954.                 return TRUE;
  1955.             }
  1956.         }
  1957.         else if(nType == TALENT_TYPE_FEAT)
  1958.         {
  1959.             if(!GetHasFeatEffect(nIndex))
  1960.             {
  1961.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseEnhancementOnSelf Successful Exit");
  1962.                 ClearAllActions();
  1963.                 ActionUseTalentOnObject(tUse, OBJECT_SELF);
  1964.                 return TRUE;
  1965.             }
  1966.         }
  1967.         else
  1968.         {
  1969.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseEnhancementOnSelf Successful Exit");
  1970.             ActionUseTalentOnObject(tUse, OBJECT_SELF);
  1971.             return TRUE;
  1972.         }
  1973.     }
  1974.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseEnhancementOnSelf Failed Exit");
  1975.     return FALSE;
  1976. }
  1977.  
  1978. // SPELL CASTER MELEE ATTACKED
  1979. int TalentMeleeAttacked(object oIntruder = OBJECT_INVALID)
  1980. {
  1981.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Enter");
  1982.     talent tUse;
  1983.     int nMelee = GetNumberOfMeleeAttackers();
  1984.     object oTarget = oIntruder;
  1985.     int nCR = GetAssociateCRMax();
  1986.  
  1987.     if(!GetIsObjectValid(oIntruder) && GetIsObjectValid(GetLastHostileActor()))
  1988.     {
  1989.         oTarget = GetLastHostileActor();
  1990.     }
  1991.     else
  1992.     {
  1993.         return FALSE;
  1994.     }
  1995.     /*
  1996.         ISSUE 1: The check in this function to use a random ability after failing to use best will fail in the following
  1997.         case.  The creature is unable to affect the target with the spell and has only 1 spell of that type.  This can
  1998.         be eliminated with a check in the else to the effect of :
  1999.         
  2000.             else if(!CompareLastSpellCast(GetIdFromTalent(tUse)))
  2001.             
  2002.         This check was not put in in version 1.0 due to time constraints.
  2003.  
  2004.         ISSUE 2: Given the Spell Attack is the drop out check the else statements in this talent should be cut.
  2005.     */
  2006.     
  2007.     if(nMelee == 1)
  2008.     {
  2009.         tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_TOUCH, nCR);
  2010.         if(GetIsTalentValid(tUse))
  2011.         {
  2012.             if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2013.                 !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2014.                 !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2015.                 GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2016.             {
  2017.                 if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2018.                 {
  2019.                     SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2020.                 }
  2021.                 DubugPrintTalentID(tUse);
  2022.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Successful Exit");
  2023.                 ClearAllActions();
  2024.                 ActionUseTalentOnObject(tUse, oTarget);
  2025.                 return TRUE;
  2026.             }
  2027.             else
  2028.             {
  2029.                 tUse = GetCreatureTalentRandom(TALENT_CATEGORY_HARMFUL_TOUCH);
  2030.                 if(GetIsTalentValid(tUse))
  2031.                 {
  2032.                     DubugPrintTalentID(tUse);
  2033.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Successful Exit");
  2034.                     ClearAllActions();
  2035.                     ActionUseTalentOnObject(tUse, oTarget);
  2036.                     return TRUE;
  2037.                 }
  2038.             }
  2039.         }
  2040.  
  2041.         tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_RANGED, nCR);
  2042.         if(GetIsTalentValid(tUse))
  2043.         {
  2044.             if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2045.                 !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2046.                 !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2047.                 GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2048.             {
  2049.                 if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2050.                 {
  2051.                     SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2052.                 }
  2053.                 DubugPrintTalentID(tUse);
  2054.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Successful Exit");
  2055.                 ClearAllActions();
  2056.                 ActionUseTalentOnObject(tUse, oTarget);
  2057.                 return TRUE;
  2058.             }
  2059.             else
  2060.             {
  2061.                 tUse = GetCreatureTalentRandom(TALENT_CATEGORY_HARMFUL_RANGED);
  2062.                 if(GetIsTalentValid(tUse))
  2063.                 {
  2064.                     DubugPrintTalentID(tUse);
  2065.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Successful Exit");
  2066.                     ClearAllActions();
  2067.                     ActionUseTalentOnObject(tUse, oTarget);
  2068.                     return TRUE;
  2069.                 }
  2070.             }
  2071.         }
  2072.  
  2073.         tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_AREAEFFECT_DISCRIMINANT, nCR);
  2074.         if(GetIsTalentValid(tUse))
  2075.         {
  2076.             if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2077.                 !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2078.                 !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2079.                 GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2080.             {
  2081.                 if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2082.                 {
  2083.                     SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2084.                 }
  2085.                 DubugPrintTalentID(tUse);
  2086.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Successful Exit");
  2087.                 ClearAllActions();
  2088.                 ActionUseTalentOnObject(tUse, oTarget);
  2089.                 return TRUE;
  2090.             }
  2091.             else
  2092.             {
  2093.                 tUse = GetCreatureTalentRandom(TALENT_CATEGORY_HARMFUL_AREAEFFECT_DISCRIMINANT);
  2094.                 if(GetIsTalentValid(tUse))
  2095.                 {
  2096.                     DubugPrintTalentID(tUse);
  2097.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Successful Exit");
  2098.                     ClearAllActions();
  2099.                     ActionUseTalentOnObject(tUse, oTarget);
  2100.                     return TRUE;
  2101.                 }
  2102.             }
  2103.         }
  2104.     }
  2105.     else if (nMelee > 1)
  2106.     {
  2107.         tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_AREAEFFECT_DISCRIMINANT, nCR);
  2108.         if(GetIsTalentValid(tUse))
  2109.         {
  2110.              if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2111.                 !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2112.                 !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2113.                 GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2114.              {
  2115.                 if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2116.                 {
  2117.                     SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2118.                 }
  2119.                 DubugPrintTalentID(tUse);
  2120.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Successful Exit");
  2121.                 ClearAllActions();
  2122.                 ActionUseTalentOnObject(tUse, oTarget);
  2123.                 return TRUE;
  2124.             }
  2125.             else
  2126.             {
  2127.                 tUse = GetCreatureTalentRandom(TALENT_CATEGORY_HARMFUL_AREAEFFECT_DISCRIMINANT);
  2128.                 if(GetIsTalentValid(tUse))
  2129.                 {
  2130.  
  2131.                     DubugPrintTalentID(tUse);
  2132.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Successful Exit");
  2133.                     ClearAllActions();
  2134.                     ActionUseTalentOnObject(tUse, oTarget);
  2135.                     return TRUE;
  2136.                 }
  2137.             }
  2138.         }
  2139.         tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_TOUCH, nCR);
  2140.         if(GetIsTalentValid(tUse))
  2141.         {
  2142.             if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2143.                 !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2144.                 !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2145.                 GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2146.             {
  2147.                 if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2148.                 {
  2149.                     SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2150.                 }
  2151.                 DubugPrintTalentID(tUse);
  2152.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Successful Exit");
  2153.                 ClearAllActions();
  2154.                 ActionUseTalentOnObject(tUse, oTarget);
  2155.                 return TRUE;
  2156.             }
  2157.             else
  2158.             {
  2159.                 tUse = GetCreatureTalentRandom(TALENT_CATEGORY_HARMFUL_TOUCH);
  2160.                 if(GetIsTalentValid(tUse))
  2161.                 {
  2162.                     DubugPrintTalentID(tUse);
  2163.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Successful Exit");
  2164.                     ClearAllActions();
  2165.                     ActionUseTalentOnObject(tUse, oTarget);
  2166.                     return TRUE;
  2167.                 }
  2168.             }
  2169.         }
  2170.  
  2171.         tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_RANGED, nCR);
  2172.         if(GetIsTalentValid(tUse))
  2173.         {
  2174.             if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL && !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2175.                 !CompareLastSpellCast(GetIdFromTalent(tUse)) ) || GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2176.             {
  2177.                 if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2178.                 {
  2179.                     SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2180.                 }
  2181.                 DubugPrintTalentID(tUse);
  2182.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Successful Exit");
  2183.                 ClearAllActions();
  2184.                 ActionUseTalentOnObject(tUse, oTarget);
  2185.                 return TRUE;
  2186.             }
  2187.             else
  2188.             {
  2189.                 tUse = GetCreatureTalentRandom(TALENT_CATEGORY_HARMFUL_RANGED);
  2190.                 if(GetIsTalentValid(tUse))
  2191.                 {
  2192.                     DubugPrintTalentID(tUse);
  2193.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Successful Exit");
  2194.                     ClearAllActions();
  2195.                     ActionUseTalentOnObject(tUse, oTarget);
  2196.                     return TRUE;
  2197.                 }
  2198.             }
  2199.         }
  2200.     }
  2201.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttacked Failed Exit");
  2202.     return FALSE;
  2203. }
  2204.  
  2205. // SPELL CASTER RANGED ATTACKED
  2206. int TalentRangedAttackers(object oIntruder = OBJECT_INVALID)
  2207. {
  2208.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentRangedAttackers Enter");
  2209.     //Check for Single Ranged Targets
  2210.     talent tUse;
  2211.     object oTarget = oIntruder;
  2212.     int nCR = GetAssociateCRMax();
  2213.     if(!GetIsObjectValid(oIntruder))
  2214.     {
  2215.         oTarget = GetLastHostileActor();
  2216.     }
  2217.     if(GetIsObjectValid(oTarget) && GetDistanceBetween(oTarget, OBJECT_SELF) > 5.0)
  2218.     {
  2219.         if(CheckFriendlyFireOnTarget(oTarget) > 0)
  2220.         {
  2221.             tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_AREAEFFECT_DISCRIMINANT, nCR);
  2222.             if(GetIsTalentValid(tUse))
  2223.             {
  2224.                 if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2225.                     !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2226.                     !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2227.                     GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2228.                 {
  2229.                     if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2230.                     {
  2231.                         SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2232.                     }
  2233.                     DubugPrintTalentID(tUse);
  2234.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentRangedAttackers Successful Exit");
  2235.                     ClearAllActions();
  2236.                     ActionUseTalentOnObject(tUse, oTarget);
  2237.                     return TRUE;
  2238.                 }
  2239.             }
  2240.         }
  2241.         else if(CheckEnemyGroupingOnTarget(oTarget) > 0)
  2242.         {
  2243.             tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_AREAEFFECT_INDISCRIMINANT, nCR);
  2244.             if(GetIsTalentValid(tUse))
  2245.             {
  2246.                 if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2247.                     !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2248.                     !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2249.                     GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2250.                 {
  2251.                     if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2252.                     {
  2253.                         SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2254.                     }
  2255.                     DubugPrintTalentID(tUse);
  2256.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentRangedAttackers Successful Exit");
  2257.                     ClearAllActions();
  2258.                     //ActionUseTalentOnObject(tUse, oTarget);
  2259.                     ActionUseTalentAtLocation(tUse, GetLocation(oTarget));
  2260.                     return TRUE;
  2261.                 }
  2262.             }
  2263.         }
  2264.         else
  2265.         {
  2266.             tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_RANGED, nCR);
  2267.             if(GetIsTalentValid(tUse))
  2268.             {
  2269.                 if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2270.                     !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2271.                     !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2272.                     GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2273.                 {
  2274.                     if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2275.                     {
  2276.                         SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2277.                     }
  2278.                     DubugPrintTalentID(tUse);
  2279.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentRangedAttackers Successful Exit");
  2280.                     ClearAllActions();
  2281.                     ActionUseTalentOnObject(tUse, oTarget);
  2282.                     return TRUE;
  2283.                 }
  2284.             }
  2285.         }
  2286.     }
  2287.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentRangedAttackers Failed Exit");
  2288.     return FALSE;
  2289. }
  2290.  
  2291. // SPELL CASTER WITH RANGED ENEMIES
  2292. int TalentRangedEnemies(object oIntruder = OBJECT_INVALID)
  2293. {
  2294.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentRangedEnemies Enter");
  2295.     talent tUse;
  2296.     object oTarget = oIntruder;
  2297.     int nCR = GetAssociateCRMax();
  2298.     if(!GetIsObjectValid(oIntruder))
  2299.     {
  2300.         oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  2301.     }
  2302.     if(GetIsObjectValid(oTarget))
  2303.     {
  2304.         int nEnemy = CheckEnemyGroupingOnTarget(oTarget);
  2305.         if(CheckFriendlyFireOnTarget(oTarget) > 0 &&  nEnemy > 0)
  2306.         {
  2307.             tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_AREAEFFECT_DISCRIMINANT, nCR);
  2308.             if(GetIsTalentValid(tUse))
  2309.             {
  2310.                 if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2311.                     !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2312.                     !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2313.                     GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2314.                 {
  2315.                     if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2316.                     {
  2317.                         SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2318.                     }
  2319.                     DubugPrintTalentID(tUse);
  2320.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentRangedEnemies Successful Exit");
  2321.                     ClearAllActions();
  2322.                     ActionUseTalentOnObject(tUse, oTarget);
  2323.                     return TRUE;
  2324.                 }
  2325.             }
  2326.         }
  2327.         else if(nEnemy > 0)
  2328.         {
  2329.             tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_AREAEFFECT_INDISCRIMINANT, nCR);
  2330.             if(GetIsTalentValid(tUse))
  2331.             {
  2332.                 if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2333.                     !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2334.                     !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2335.                     GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2336.                 {
  2337.                     if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2338.                     {
  2339.                         SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2340.                     }
  2341.                     DubugPrintTalentID(tUse);
  2342.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentRangedEnemies Successful Exit");
  2343.                     ClearAllActions();
  2344.                     ActionUseTalentAtLocation(tUse, GetLocation(oTarget));
  2345.                     //ActionUseTalentOnObject(tUse, oTarget);
  2346.                     return TRUE;
  2347.                 }
  2348.             }
  2349.             else
  2350.             {
  2351.                 tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_AREAEFFECT_DISCRIMINANT, nCR);
  2352.                 if(GetIsTalentValid(tUse))
  2353.                 {
  2354.                     if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2355.                         !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2356.                         !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2357.                         GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2358.                     {
  2359.                         if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2360.                         {
  2361.                             SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2362.                         }
  2363.                         DubugPrintTalentID(tUse);
  2364.                         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentRangedEnemies Successful Exit");
  2365.                         ClearAllActions();
  2366.                         ActionUseTalentOnObject(tUse, oTarget);
  2367.                         return TRUE;
  2368.                     }
  2369.                 }
  2370.             }
  2371.         }
  2372.         else if(GetDistanceToObject(oTarget) > 5.0)
  2373.         {
  2374.             tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_RANGED, nCR);
  2375.             if(GetIsTalentValid(tUse))
  2376.             {
  2377.                 if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2378.                     !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2379.                     !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2380.                     GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2381.                 {
  2382.                     if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2383.                     {
  2384.                         SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2385.                     }
  2386.                     DubugPrintTalentID(tUse);
  2387.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentRangedEnemies Successful Exit");
  2388.                     ClearAllActions();
  2389.                     ActionUseTalentOnObject(tUse, oTarget);
  2390.                     return TRUE;
  2391.                 }
  2392.             }
  2393.         }
  2394.         else
  2395.         {
  2396.             tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_TOUCH, nCR);
  2397.             if(GetIsTalentValid(tUse))
  2398.             {
  2399.                 if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL &&
  2400.                     !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget) &&
  2401.                     !CompareLastSpellCast(GetIdFromTalent(tUse)) ) ||
  2402.                     GetTypeFromTalent(tUse) != TALENT_TYPE_SPELL )
  2403.                 {
  2404.                     if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2405.                     {
  2406.                         SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2407.                     }
  2408.                     DubugPrintTalentID(tUse);
  2409.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentRangedEnemies Successful Exit");
  2410.                     ClearAllActions();
  2411.                     ActionUseTalentOnObject(tUse, oTarget);
  2412.                     return TRUE;
  2413.                 }
  2414.             }
  2415.         }
  2416.     }
  2417.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentRangedEnemies Failed Exit");
  2418.     return FALSE;
  2419. }
  2420.     /*
  2421.         ISSUE 1: The check in this function to use a random ability after failing to use best will fail in the following
  2422.         case.  The creature is unable to affect the target with the spell and has only 1 spell of that type.  This can
  2423.         be eliminated with a check in the else to the effect of :
  2424.  
  2425.             else if(!CompareLastSpellCast(GetIdFromTalent(tUse)))
  2426.  
  2427.         This check was not put in in version 1.0 due to time constraints.
  2428.         May cause an AI loop in some Mages with limited spell selection.
  2429.     */
  2430. int TalentSpellAttack(object oIntruder)
  2431. {
  2432.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Talent Spell Attack Enter");
  2433.     talent tUse;
  2434.     object oTarget = oIntruder;
  2435.     if(!GetIsObjectValid(oTarget) || GetArea(oTarget) != GetArea(OBJECT_SELF) || GetPlotFlag(OBJECT_SELF) == TRUE)
  2436.     {
  2437.         oTarget = GetLastHostileActor();
  2438.         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Last Hostile Attacker: " + ObjectToString(oTarget));
  2439.         if(!GetIsObjectValid(oTarget)
  2440.             || GetIsDead(oTarget)
  2441.             || GetArea(oTarget) != GetArea(OBJECT_SELF)
  2442.             || GetPlotFlag(OBJECT_SELF) == TRUE)
  2443.         {
  2444.             oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  2445.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Get Nearest Seen or Heard: " + ObjectToString(oTarget));
  2446.             if(!GetIsObjectValid(oTarget))
  2447.             {
  2448.                 return FALSE;
  2449.             }
  2450.         }
  2451.     }
  2452.     //Attack chosen target
  2453.     int bValid = FALSE;
  2454.     tUse = GetCreatureTalentRandom(TALENT_CATEGORY_HARMFUL_AREAEFFECT_DISCRIMINANT);
  2455.     if(GetIsTalentValid(tUse))
  2456.     {
  2457.         if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL && !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget)) )
  2458.         {
  2459.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Spell Attack Discriminate Chosen");
  2460.             bValid = TRUE;
  2461.         }
  2462.     }
  2463.     if(bValid == FALSE)
  2464.     {
  2465.         tUse = GetCreatureTalentRandom(TALENT_CATEGORY_HARMFUL_RANGED);
  2466.         if(GetIsTalentValid(tUse))
  2467.         {
  2468.             if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL && !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget)) )
  2469.             {
  2470.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Spell Attack Harmful Ranged Chosen");
  2471.                 bValid = TRUE;
  2472.             }
  2473.         }
  2474.     }
  2475.     if(bValid == FALSE)
  2476.     {
  2477.         tUse = GetCreatureTalentRandom(TALENT_CATEGORY_HARMFUL_TOUCH);
  2478.         if(GetIsTalentValid(tUse))
  2479.         {
  2480.             if( (GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL && !GetHasSpellEffect(GetIdFromTalent(tUse), oTarget)) )
  2481.             {
  2482.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Spell Attack Harmful Ranged Chosen");
  2483.                 bValid = TRUE;
  2484.             }
  2485.         }
  2486.     }
  2487.     if (bValid == TRUE)
  2488.     {
  2489.         if( GetTypeFromTalent(tUse) == TALENT_TYPE_SPELL)
  2490.         {
  2491.             SetLastGenericSpellCast(GetIdFromTalent(tUse));
  2492.         }
  2493.         DubugPrintTalentID(tUse);
  2494.         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Talent Spell Attack Successful Exit");
  2495.         ClearAllActions();
  2496.         ActionUseTalentOnObject(tUse, oTarget);
  2497.         return TRUE;
  2498.     }
  2499.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Talent Spell Attack Failed Exit");
  2500.     return FALSE;
  2501. }
  2502.  
  2503.  
  2504. // SUMMON ALLIES
  2505. int TalentSummonAllies()
  2506. {
  2507.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentSummonAllies Enter");
  2508.     talent tUse;
  2509.     int nCR = GetAssociateCRMax();
  2510.     object oTarget;
  2511.     location lSelf;
  2512.  
  2513.     if(!GetIsObjectValid(GetAssociate(ASSOCIATE_TYPE_SUMMONED)))
  2514.     {
  2515.         tUse = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_OBTAIN_ALLIES, 20);
  2516.         if(GetIsTalentValid(tUse))
  2517.         {
  2518.             oTarget =  FindSingleRangedTarget();
  2519.             if(GetIsObjectValid(oTarget))
  2520.             {
  2521.                 vector vTarget = GetPosition(oTarget);
  2522.                 vector vSource = GetPosition(OBJECT_SELF);
  2523.                 vector vDirection = vTarget - vSource;
  2524.                 float fDistance = VectorMagnitude(vDirection) / 2.0f;
  2525.                 vector vPoint = VectorNormalize(vDirection) * fDistance + vSource;
  2526.                 lSelf = Location(GetArea(OBJECT_SELF), vPoint, GetFacing(OBJECT_SELF));
  2527.                 //lSelf = GetLocation(oTarget);
  2528.             }
  2529.             else
  2530.             {
  2531.                 lSelf = GetLocation(OBJECT_SELF);
  2532.             }
  2533.             ClearAllActions();
  2534.             //This is for henchmen wizards, so they do no run off and get killed
  2535.             //summoning in allies.
  2536.             if(GetIsObjectValid(GetMaster()))
  2537.             {
  2538.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentSummonAllies Successful Exit");
  2539.                 ActionUseTalentAtLocation(tUse, GetLocation(GetMaster()));
  2540.             }
  2541.             else
  2542.             {
  2543.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentSummonAllies Successful Exit");
  2544.                 ActionUseTalentAtLocation(tUse, lSelf);
  2545.             }
  2546.             return TRUE;
  2547.         }
  2548.     }
  2549.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentSummonAllies Failed Exit");
  2550.     return FALSE;
  2551. }
  2552.  
  2553. // HEAL SELF WITH POTIONS AND SPELLS
  2554. int TalentHealingSelf()
  2555. {
  2556.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentHealingSelf Enter");
  2557.     talent tUse;
  2558.     int nCurrent = GetCurrentHitPoints(OBJECT_SELF) * 2;
  2559.     int nBase = GetMaxHitPoints(OBJECT_SELF);
  2560.     if(nCurrent < nBase)
  2561.     {
  2562.         tUse = GetCreatureTalentRandom(TALENT_CATEGORY_BENEFICIAL_HEALING_TOUCH);
  2563.         if(GetIsTalentValid(tUse))
  2564.         {
  2565.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentHealingSelf Successful Exit");
  2566.             ClearAllActions();
  2567.             ActionUseTalentOnObject(tUse, OBJECT_SELF);
  2568.             return TRUE;
  2569.         }
  2570.         else
  2571.         {
  2572.             tUse = GetCreatureTalentRandom(TALENT_CATEGORY_BENEFICIAL_HEALING_POTION);
  2573.             if(GetIsTalentValid(tUse))
  2574.             {
  2575.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentHealingSelf Successful Exit");
  2576.                 ClearAllActions();
  2577.                 ActionUseTalentOnObject(tUse, OBJECT_SELF);
  2578.                 return TRUE;
  2579.             }
  2580.         }
  2581.     }
  2582.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentHealingSelf Failed Exit");
  2583.     return FALSE;
  2584. }
  2585.  
  2586. // HEAL ALL ALLIES
  2587. int TalentHeal(int nForce = FALSE)
  2588. {
  2589.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentHeal Enter");
  2590.     talent tUse;
  2591.     int nCurrent = GetCurrentHitPoints(OBJECT_SELF) * 2;
  2592.     int nBase = GetMaxHitPoints(OBJECT_SELF);
  2593.     int nCR;
  2594.  
  2595.     if(GetAssociateHealMaster() || nForce == TRUE)
  2596.     {
  2597.         tUse = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_HEALING_TOUCH, 20);
  2598.         if(GetIsTalentValid(tUse) && !GetIsDead(GetMaster()))
  2599.         {
  2600.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentHeal Successful Exit");
  2601.             ClearAllActions();
  2602.             ActionUseTalentOnObject(tUse, GetMaster());
  2603.             return TRUE;
  2604.         }
  2605.     }
  2606.     if(nCurrent < nBase)
  2607.     {
  2608.         tUse = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_HEALING_TOUCH, 20);
  2609.         if(GetIsTalentValid(tUse))
  2610.         {
  2611.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentHeal Successful Exit");
  2612.             ClearAllActions();
  2613.             ActionUseTalentOnObject(tUse, OBJECT_SELF);
  2614.             return TRUE;
  2615.         }
  2616.     }
  2617.     
  2618.     object oTarget = GetFactionMostDamagedMember(OBJECT_SELF);
  2619.     if(GetIsObjectValid(oTarget))
  2620.     {
  2621.         if(GetRacialType(oTarget) == RACIAL_TYPE_UNDEAD)
  2622.         {
  2623.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentHeal Failed Exit");
  2624.             return FALSE;
  2625.         }
  2626.         nCurrent = GetCurrentHitPoints(oTarget)*2;
  2627.         nBase = GetMaxHitPoints(oTarget);
  2628.  
  2629.         if(nCurrent < nBase && !GetIsDead(oTarget))
  2630.         {
  2631.             tUse = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_HEALING_TOUCH, 20);
  2632.             if(GetIsTalentValid(tUse))
  2633.             {
  2634.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentHeal Successful Exit");
  2635.                 ClearAllActions();
  2636.                 ActionUseTalentOnObject(tUse, oTarget);
  2637.                 return TRUE;
  2638.             }
  2639.         }
  2640.     }
  2641.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentHeal Failed Exit");
  2642.     return FALSE;
  2643. }
  2644.  
  2645. // MELEE ATTACK OTHERS
  2646. /*
  2647.     ISSUE 1: Talent Melee Attack should set the Last Spell Used to 0 so that melee casters can use
  2648.     a single special ability.
  2649. */
  2650.  
  2651. int TalentMeleeAttack(object oIntruder = OBJECT_INVALID)
  2652. {
  2653.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttack Enter");
  2654.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Intruder: " + ObjectToString(oIntruder));
  2655.  
  2656.     object oTarget = oIntruder;
  2657.     if(!GetIsObjectValid(oTarget) || GetArea(oTarget) != GetArea(OBJECT_SELF) || GetPlotFlag(OBJECT_SELF) == TRUE)
  2658.     {
  2659.         oTarget = GetAttemptedAttackTarget();
  2660.         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Attempted Attack Target: " + ObjectToString(oTarget));
  2661.         if(!GetIsObjectValid(oTarget) || GetIsDead(oTarget) ||
  2662.           (!GetObjectSeen(oTarget) && !GetObjectHeard(oTarget))
  2663.            || GetArea(oTarget) != GetArea(OBJECT_SELF)
  2664.            || GetPlotFlag(OBJECT_SELF) == TRUE)
  2665.         {
  2666.             oTarget = GetLastHostileActor();
  2667.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Last Attacker: " + ObjectToString(oTarget));
  2668.             if(!GetIsObjectValid(oTarget)
  2669.                 || GetIsDead(oTarget)
  2670.                 || GetArea(oTarget) != GetArea(OBJECT_SELF)
  2671.                 || GetPlotFlag(OBJECT_SELF) == TRUE)
  2672.             {
  2673.                 oTarget = GetNearestSeenOrHeardEnemy();
  2674.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Get Nearest Seen or Heard: " + ObjectToString(oTarget));
  2675.                 if(!GetIsObjectValid(oTarget))
  2676.                 {
  2677.                     return FALSE;
  2678.                 }
  2679.             }
  2680.         }
  2681.     }
  2682.     else
  2683.     {
  2684.         //MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "My Target is valid off of oIntruder");
  2685.     }
  2686.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Selected Target: " + ObjectToString(oTarget));
  2687.  
  2688.     talent tUse;
  2689.     int nAC = GetAC(oTarget);
  2690.     float fAttack;
  2691.     int nAttack = GetCharacterLevel(OBJECT_SELF);
  2692.  
  2693.     fAttack = (IntToFloat(nAttack) * 0.75) + IntToFloat(GetAbilityModifier(ABILITY_STRENGTH));
  2694.     //fAttack = IntToFloat(nAttack) + GetAbilityModifier(ABILITY_STRENGTH);
  2695.     
  2696.     int nDiff = nAC - nAttack;
  2697.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "nDiff = " + IntToString(nDiff));
  2698.  
  2699.     if(nDiff < 10)
  2700.     {
  2701.         ClearAllActions();
  2702.         EquipAppropriateWeapons(oTarget);
  2703.         tUse = GetCreatureTalentRandom(TALENT_CATEGORY_HARMFUL_MELEE);
  2704.         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Melee Talent Valid = " + IntToString(GetIsTalentValid(tUse)));
  2705.         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Feat ID = " + IntToString(GetIdFromTalent(tUse)));
  2706.  
  2707.         if(GetIsTalentValid(tUse) && VerifyDisarm(tUse, oTarget) && VerifyCombatMeleeTalent(tUse, oTarget))
  2708.         {
  2709.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttack: Talent Use Successful");
  2710.             ActionUseTalentOnObject(tUse, oTarget);
  2711.             return TRUE;
  2712.         }
  2713.         else
  2714.         {
  2715.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttack Successful Exit");
  2716.             ActionAttack(oTarget);
  2717.             return TRUE;
  2718.         }
  2719.     }
  2720.     else
  2721.     {
  2722.         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentMeleeAttack Successful Exit");
  2723.         ClearAllActions();
  2724.         EquipAppropriateWeapons(oTarget);
  2725.         ActionAttack(oTarget);
  2726.         return TRUE;
  2727.     }
  2728.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TALENT MELEE ATTACK FAILURE EXIT - THIS IS VERY BAD");
  2729.     return FALSE;
  2730. }
  2731.  
  2732. // SNEAK ATTACK OTHERS
  2733. int TalentSneakAttack()
  2734. {
  2735.      MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentSneakAttack Enter");
  2736.      object oTarget;
  2737.      int nFriends;
  2738.      
  2739.      if(GetHasFeat(FEAT_SNEAK_ATTACK))
  2740.      {
  2741.          nFriends = CheckFriendlyFireOnTarget(OBJECT_SELF);
  2742.          if(nFriends > 0)
  2743.          {
  2744.             oTarget = GetLastHostileActor(GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN));
  2745.             if(GetIsObjectValid(oTarget) && !GetIsDead(oTarget))
  2746.             {
  2747.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentSneakAttack Successful Exit");
  2748.                 ActionAttack(oTarget);
  2749.                 return TRUE;
  2750.             }
  2751.          }
  2752.      }
  2753.      MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentSneakAttack Failed Exit");
  2754.      return FALSE;
  2755. }
  2756.  
  2757. // FLEE COMBAT AND HOSTILES
  2758. int TalentFlee(object oIntruder = OBJECT_INVALID)
  2759. {
  2760.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentFlee Enter");
  2761.     object oTarget = oIntruder;
  2762.     if(!GetIsObjectValid(oIntruder))
  2763.     {
  2764.         oTarget = GetLastHostileActor();
  2765.         if(!GetIsObjectValid(oTarget) || GetIsDead(oTarget))
  2766.         {
  2767.             oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  2768.             float fDist = GetDistanceBetween(OBJECT_SELF, oTarget);
  2769.             if(!GetIsObjectValid(oTarget))
  2770.             {
  2771.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentFlee Failed Exit");
  2772.                 return FALSE;
  2773.             }
  2774.         }
  2775.     }
  2776.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentFlee Successful Exit");
  2777.     ClearAllActions();
  2778.     //Look at this to remove the delay
  2779.     ActionMoveAwayFromObject(oTarget, TRUE, 10.0f);
  2780.     DelayCommand(4.0, ClearAllActions());
  2781.     return TRUE;
  2782. }
  2783.  
  2784. // TURN UNDEAD
  2785. int TalentUseTurning()
  2786. {
  2787.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseTurning Enter");
  2788.     int nCount;
  2789.     if(GetHasFeat(FEAT_TURN_UNDEAD))
  2790.     {
  2791.         object oUndead = GetNearestSeenOrHeardEnemy();
  2792.         int nHD = GetHitDice(oUndead);
  2793.         if(GetHasEffect(EFFECT_TYPE_TURNED, oUndead) || GetHitDice(OBJECT_SELF) <= nHD)
  2794.         {
  2795.             return FALSE;
  2796.         }
  2797.         int nElemental = GetHasFeat(FEAT_AIR_DOMAIN_POWER) + GetHasFeat(FEAT_EARTH_DOMAIN_POWER) + GetHasFeat(FEAT_FIRE_DOMAIN_POWER) + GetHasFeat(FEAT_FIRE_DOMAIN_POWER);
  2798.         int nVermin = GetHasFeat(FEAT_PLANT_DOMAIN_POWER) + GetHasFeat(FEAT_ANIMAL_COMPANION);
  2799.         int nConstructs = GetHasFeat(FEAT_DESTRUCTION_DOMAIN_POWER);
  2800.         int nOutsider = GetHasFeat(FEAT_GOOD_DOMAIN_POWER) + GetHasFeat(FEAT_EVIL_DOMAIN_POWER);
  2801.  
  2802.         if(nElemental == TRUE)
  2803.         {
  2804.             nCount += GetRacialTypeCount(RACIAL_TYPE_ELEMENTAL);
  2805.         }
  2806.         if(nVermin == TRUE)
  2807.         {
  2808.             nCount += GetRacialTypeCount(RACIAL_TYPE_VERMIN);
  2809.         }
  2810.         if(nOutsider == TRUE)
  2811.         {
  2812.             nCount += GetRacialTypeCount(RACIAL_TYPE_OUTSIDER);
  2813.         }
  2814.         if(nConstructs == TRUE)
  2815.         {
  2816.             nCount += GetRacialTypeCount(RACIAL_TYPE_CONSTRUCT);
  2817.         }
  2818.         nCount += GetRacialTypeCount(RACIAL_TYPE_UNDEAD);
  2819.  
  2820.         if(nCount > 0)
  2821.         {
  2822.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseTurning Successful Exit");
  2823.             ClearAllActions();
  2824.             //ActionCastSpellAtObject(SPELLABILITY_TURN_UNDEAD, OBJECT_SELF);
  2825.             ActionUseFeat(FEAT_TURN_UNDEAD, OBJECT_SELF);// GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY));
  2826.             return TRUE;
  2827.         }
  2828.     }
  2829.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentUseTurning Failed Exit");
  2830.     return FALSE;
  2831. }
  2832.  
  2833. // ACTIVATE AURAS
  2834. int TalentPersistentAbilities()
  2835. {
  2836.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentPersistentAbilities Enter");
  2837.     talent tUse = GetCreatureTalentBest(TALENT_CATEGORY_PERSISTENT_AREA_OF_EFFECT, 20);
  2838.     int nSpellID;
  2839.     if(GetIsTalentValid(tUse))
  2840.     {
  2841.         nSpellID = GetIdFromTalent(tUse);
  2842.         if(!GetHasSpellEffect(nSpellID))
  2843.         {
  2844.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentPersistentAbilities Successful Exit");
  2845.             ClearAllActions();
  2846.             ActionUseTalentOnObject(tUse, OBJECT_SELF);
  2847.             return TRUE;
  2848.         }
  2849.     }
  2850.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentPersistentAbilities Failed Exit");
  2851.     return FALSE;
  2852. }
  2853.  
  2854. // FAST BUFF SELF
  2855. int TalentAdvancedBuff(float fDistance)
  2856. {
  2857.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentAdvancedBuff Enter");
  2858.     object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, OBJECT_SELF, 1, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
  2859.     if(GetIsObjectValid(oPC))
  2860.     {
  2861.         if(GetDistanceToObject(oPC) <= fDistance)
  2862.         {
  2863.             if(!GetIsFighting(OBJECT_SELF))
  2864.             {
  2865.                 ClearAllActions();
  2866.                 //Combat Protections
  2867.                 if(GetHasSpell(SPELL_PREMONITION))
  2868.                 {
  2869.                     ActionCastSpellAtObject(SPELL_PREMONITION, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2870.                 }
  2871.                 else if(GetHasSpell(SPELL_GREATER_STONESKIN))
  2872.                 {
  2873.                     ActionCastSpellAtObject(SPELL_GREATER_STONESKIN, OBJECT_SELF, METAMAGIC_NONE, 0, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2874.                 }
  2875.                 else if(GetHasSpell(SPELL_STONESKIN))
  2876.                 {
  2877.                     ActionCastSpellAtObject(SPELL_STONESKIN, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2878.                 }
  2879.                 //Visage Protections
  2880.                 if(GetHasSpell(SPELL_SHADOW_SHIELD))
  2881.                 {
  2882.                     ActionCastSpellAtObject(SPELL_SHADOW_SHIELD, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2883.                 }
  2884.                 else if(GetHasSpell(SPELL_ETHEREAL_VISAGE))
  2885.                 {
  2886.                     ActionCastSpellAtObject(SPELL_ETHEREAL_VISAGE, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2887.                 }
  2888.                 else if(GetHasSpell(SPELL_GHOSTLY_VISAGE))
  2889.                 {
  2890.                     ActionCastSpellAtObject(SPELL_GHOSTLY_VISAGE, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2891.                 }
  2892.                 //Mantle Protections
  2893.                 if(GetHasSpell(SPELL_GREATER_SPELL_MANTLE))
  2894.                 {
  2895.                     ActionCastSpellAtObject(SPELL_GREATER_SPELL_MANTLE, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2896.                 }
  2897.                 else if(GetHasSpell(SPELL_SPELL_MANTLE))
  2898.                 {
  2899.                     ActionCastSpellAtObject(SPELL_SPELL_MANTLE, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2900.                 }
  2901.                 else if(GetHasSpell(SPELL_LESSER_SPELL_BREACH))
  2902.                 {
  2903.                     ActionCastSpellAtObject(SPELL_LESSER_SPELL_BREACH, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2904.                 }
  2905.                 // Globes
  2906.                 if(GetHasSpell(SPELL_GLOBE_OF_INVULNERABILITY))
  2907.                 {
  2908.                     ActionCastSpellAtObject(SPELL_GLOBE_OF_INVULNERABILITY, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2909.                 }
  2910.                 else if(GetHasSpell(SPELL_MINOR_GLOBE_OF_INVULNERABILITY))
  2911.                 {
  2912.                     ActionCastSpellAtObject(SPELL_MINOR_GLOBE_OF_INVULNERABILITY, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2913.                 }
  2914.  
  2915.                 //Misc Protections
  2916.                 if(GetHasSpell(SPELL_ELEMENTAL_SHIELD))
  2917.                 {
  2918.                     ActionCastSpellAtObject(SPELL_ELEMENTAL_SHIELD, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2919.                 }
  2920.  
  2921.                 //Elemental Protections
  2922.                 if(GetHasSpell(SPELL_PROTECTION_FROM_ELEMENTS))
  2923.                 {
  2924.                     ActionCastSpellAtObject(SPELL_PROTECTION_FROM_ELEMENTS, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2925.                 }
  2926.                 else if(GetHasSpell(SPELL_RESIST_ELEMENTS))
  2927.                 {
  2928.                     ActionCastSpellAtObject(SPELL_RESIST_ELEMENTS, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2929.                 }
  2930.                 else if(GetHasSpell(SPELL_ENDURE_ELEMENTS))
  2931.                 {
  2932.                     ActionCastSpellAtObject(SPELL_ENDURE_ELEMENTS, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2933.                 }
  2934.  
  2935.                 //Mental Protections
  2936.                 if(GetHasSpell(SPELL_MIND_BLANK))
  2937.                 {
  2938.                     ActionCastSpellAtObject(SPELL_MIND_BLANK, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2939.                 }
  2940.                 else if(GetHasSpell(SPELL_LESSER_MIND_BLANK))
  2941.                 {
  2942.                     ActionCastSpellAtObject(SPELL_LESSER_MIND_BLANK, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2943.                 }
  2944.                 else if(GetHasSpell(SPELL_CLARITY))
  2945.                 {
  2946.                     ActionCastSpellAtObject(SPELL_CLARITY, OBJECT_SELF, METAMAGIC_NONE, FALSE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2947.                 }
  2948.                 //Summon Ally
  2949.                 if(GetHasSpell(SPELL_SUMMON_CREATURE_IX))
  2950.                 {
  2951.                     ActionCastSpellAtLocation(SPELL_SUMMON_CREATURE_IX, GetLocation(OBJECT_SELF), METAMAGIC_NONE, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2952.                 }
  2953.                 else if(GetHasSpell(SPELL_SUMMON_CREATURE_VIII))
  2954.                 {
  2955.                     ActionCastSpellAtLocation(SPELL_SUMMON_CREATURE_VIII, GetLocation(OBJECT_SELF), METAMAGIC_NONE, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2956.                 }
  2957.                 else if(GetHasSpell(SPELL_SUMMON_CREATURE_VII))
  2958.                 {
  2959.                     ActionCastSpellAtLocation(SPELL_SUMMON_CREATURE_VII, GetLocation(OBJECT_SELF), METAMAGIC_NONE, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2960.                 }
  2961.                 else if(GetHasSpell(SPELL_SUMMON_CREATURE_VI))
  2962.                 {
  2963.                     ActionCastSpellAtLocation(SPELL_SUMMON_CREATURE_VI, GetLocation(OBJECT_SELF), METAMAGIC_NONE, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2964.                 }
  2965.                 else if(GetHasSpell(SPELL_SUMMON_CREATURE_V))
  2966.                 {
  2967.                     ActionCastSpellAtLocation(SPELL_SUMMON_CREATURE_V, GetLocation(OBJECT_SELF), METAMAGIC_NONE, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2968.                 }
  2969.                 else if(GetHasSpell(SPELL_SUMMON_CREATURE_IV))
  2970.                 {
  2971.                     ActionCastSpellAtLocation(SPELL_SUMMON_CREATURE_IV, GetLocation(OBJECT_SELF), METAMAGIC_NONE, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2972.                 }
  2973.                 else if(GetHasSpell(SPELL_SUMMON_CREATURE_III))
  2974.                 {
  2975.                     ActionCastSpellAtLocation(SPELL_SUMMON_CREATURE_III, GetLocation(OBJECT_SELF), METAMAGIC_NONE, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2976.                 }
  2977.                 else if(GetHasSpell(SPELL_SUMMON_CREATURE_II))
  2978.                 {
  2979.                     ActionCastSpellAtLocation(SPELL_SUMMON_CREATURE_II, GetLocation(OBJECT_SELF), METAMAGIC_NONE, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2980.                 }
  2981.                 else if(GetHasSpell(SPELL_SUMMON_CREATURE_I))
  2982.                 {
  2983.                     ActionCastSpellAtLocation(SPELL_SUMMON_CREATURE_I, GetLocation(OBJECT_SELF), METAMAGIC_NONE, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  2984.                 }
  2985.  
  2986.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentAdvancedBuff Successful Exit");
  2987.                 return TRUE;
  2988.             }
  2989.         }
  2990.     }
  2991.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentAdvancedBuff Failed Exit");
  2992.     return FALSE;
  2993. }
  2994.  
  2995. // USE POTIONS
  2996. int TalentBuffSelf()
  2997. {
  2998.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentBuffSelf Enter");
  2999.     talent tUse;
  3000.     int nType;
  3001.     int bValid = FALSE;
  3002.     int nIndex;
  3003.  
  3004.     tUse = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_PROTECTION_POTION, 20);
  3005.     if(!GetIsTalentValid(tUse))
  3006.     {
  3007.         tUse = GetCreatureTalentBest(TALENT_CATEGORY_BENEFICIAL_ENHANCEMENT_POTION, 20);
  3008.         if(!GetIsTalentValid(tUse))
  3009.         {
  3010.             return FALSE;
  3011.         }
  3012.     }
  3013.     nType = GetTypeFromTalent(tUse);
  3014.     nIndex = GetIdFromTalent(tUse);
  3015.  
  3016.     if(nType == TALENT_TYPE_SPELL)
  3017.     {
  3018.         if(!GetHasSpellEffect(nIndex))
  3019.         {
  3020.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentBuffSelf Successful Exit");
  3021.             ClearAllActions();
  3022.             ActionUseTalentOnObject(tUse, OBJECT_SELF);
  3023.             return TRUE;
  3024.         }
  3025.     }
  3026.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentBuffSelf Failed Exit");
  3027.     return FALSE;
  3028. }
  3029.  
  3030. // USE SPELLS TO DEFEAT INVISIBLE CREATURES
  3031. // THIS TALENT IS NOT USED
  3032. int TalentSeeInvisible()
  3033. {
  3034.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentSeeInvisible Enter");
  3035.     int nSpell;
  3036.     int bValid = FALSE;
  3037.     if(GetHasSpell(SPELL_TRUE_SEEING))
  3038.     {
  3039.         nSpell = SPELL_TRUE_SEEING;
  3040.         bValid = TRUE;
  3041.     }
  3042.     else if(GetHasSpell(SPELL_INVISIBILITY_PURGE))
  3043.     {
  3044.         nSpell = SPELL_INVISIBILITY_PURGE;
  3045.         bValid = TRUE;
  3046.     }
  3047.     else if(GetHasSpell(SPELL_SEE_INVISIBILITY))
  3048.     {
  3049.         nSpell = SPELL_SEE_INVISIBILITY;
  3050.         bValid = TRUE;
  3051.     }
  3052.     else if(GetHasSpell(SPELL_CLAIRAUDIENCE_AND_CLAIRVOYANCE))
  3053.     {
  3054.         nSpell = SPELL_CLAIRAUDIENCE_AND_CLAIRVOYANCE;
  3055.         bValid = TRUE;
  3056.     }
  3057.     if(bValid == TRUE)
  3058.     {
  3059.         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentSeeInvisible Successful Exit");
  3060.         ClearAllActions();
  3061.         ActionCastSpellAtObject(nSpell, OBJECT_SELF);
  3062.     }
  3063.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentSeeInvisible Failed Exit");
  3064.     return bValid;
  3065. }
  3066.  
  3067. // CURE DISEASE, POISON ETC
  3068. int TalentCureCondition()
  3069. {
  3070.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentCureCondition Enter");
  3071.     int nCurse = 0x00000001;
  3072.     int nPoison = 0x00000002;
  3073.     int nDisease = 0x00000004;
  3074.     int nAbility = 0x00000008;
  3075.     int nDrained = 0x00000010;
  3076.     int nBlindDeaf = 0x00000020;
  3077.     int nSum;
  3078.     int nType;
  3079.     int nSpell;
  3080.     effect eEffect;
  3081.  
  3082.     object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, GetLocation(OBJECT_SELF));
  3083.     while(GetIsObjectValid(oTarget))
  3084.     {
  3085.         if(GetIsFriend(oTarget))
  3086.         {
  3087.             eEffect = GetFirstEffect(oTarget);
  3088.             while(GetIsEffectValid(eEffect))
  3089.             {
  3090.                 nType = GetEffectType(eEffect);
  3091.                 
  3092.                 if(nType == EFFECT_TYPE_DISEASE)
  3093.                 {
  3094.                     nSum = nSum | nDisease;
  3095.                 }
  3096.                 else if(nType == EFFECT_TYPE_POISON)
  3097.                 {
  3098.                     nSum = nSum | nPoison;
  3099.                 }
  3100.                 else if(nType == EFFECT_TYPE_CURSE)
  3101.                 {
  3102.                     nSum = nSum | nCurse;
  3103.                 }
  3104.                 else if(nType == EFFECT_TYPE_NEGATIVELEVEL)
  3105.                 {
  3106.                     nSum = nSum | nDrained;
  3107.                 }
  3108.                 else if(nType == EFFECT_TYPE_ABILITY_DECREASE)
  3109.                 {
  3110.                     nSum = nSum | nAbility;
  3111.                 }
  3112.                 else if(nType == EFFECT_TYPE_BLINDNESS || nType == EFFECT_TYPE_DEAF)
  3113.                 {
  3114.                     nSum = nSum | nBlindDeaf;
  3115.                 }
  3116.                 eEffect = GetNextEffect(oTarget);
  3117.             }
  3118.         }
  3119.         if(nSum != 0)
  3120.         {
  3121.             if(((nSum & nDrained) ||
  3122.                 (nSum & nDisease & nPoison) ||
  3123.                 (nSum & nDisease) ||
  3124.                 (nSum & nBlindDeaf) ||
  3125.                 (nSum & nCurse & nPoison) ||
  3126.                 (nSum & nCurse & nDisease) ||
  3127.                 (nSum & nBlindDeaf & nPoison) ||
  3128.                 (nSum & nCurse & nBlindDeaf) ||
  3129.                 (nSum & nBlindDeaf & nDisease)) &&
  3130.                 (GetHasSpell(SPELL_GREATER_RESTORATION) || GetHasSpell(SPELL_RESTORATION))
  3131.                )
  3132.             {
  3133.                 nSpell = SPELL_GREATER_RESTORATION;
  3134.                 if(!GetHasSpell(SPELL_GREATER_RESTORATION))
  3135.                 {
  3136.                     nSpell = SPELL_RESTORATION;
  3137.                 }
  3138.             }
  3139.             else if((nSum & nAbility) &&
  3140.                     (GetHasSpell(SPELL_GREATER_RESTORATION) || GetHasSpell(SPELL_RESTORATION) || GetHasSpell(SPELL_LESSER_RESTORATION)))
  3141.             {
  3142.                 nSpell = SPELL_GREATER_RESTORATION;
  3143.                 if(!GetHasSpell(SPELL_GREATER_RESTORATION))
  3144.                 {
  3145.                     nSpell = SPELL_RESTORATION;
  3146.                     if(!GetHasSpell(SPELL_RESTORATION))
  3147.                     {
  3148.                         nSpell = SPELL_LESSER_RESTORATION;
  3149.                     }
  3150.                 }
  3151.             }
  3152.             else if(((nSum & nPoison) ||
  3153.                     (nSum & nDisease & nPoison) ||
  3154.                     (nSum & nDisease)) &&
  3155.                     GetHasSpell(SPELL_NEUTRALIZE_POISON))
  3156.             {
  3157.                 nSpell = SPELL_NEUTRALIZE_POISON;
  3158.             }
  3159.             else if((nSum & nDisease) && GetHasSpell(SPELL_REMOVE_DISEASE))
  3160.             {
  3161.                 nSpell = SPELL_REMOVE_DISEASE;
  3162.             }
  3163.             else if((nSum & nCurse) && GetHasSpell(SPELL_REMOVE_CURSE))
  3164.             {
  3165.                 nSpell = SPELL_REMOVE_CURSE;
  3166.             }
  3167.             else if((nSum & nBlindDeaf) && GetHasSpell(SPELL_REMOVE_BLINDNESS_AND_DEAFNESS))
  3168.             {
  3169.                 nSpell = SPELL_REMOVE_BLINDNESS_AND_DEAFNESS;
  3170.             }
  3171.             if(nSpell != 0)
  3172.             {
  3173.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentCureCondition Successful Exit");
  3174.                 ClearAllActions();
  3175.                 ActionCastSpellAtObject(nSpell, oTarget);
  3176.                 return TRUE;
  3177.             }
  3178.         }
  3179.         nSum = 0;
  3180.         oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, GetLocation(OBJECT_SELF));
  3181.     }
  3182.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentCureCondition Failed Exit");
  3183.     return FALSE;
  3184. }
  3185.  
  3186. // DRAGON COMBAT
  3187. int TalentDragonCombat(object oIntruder = OBJECT_INVALID)
  3188. {
  3189.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentDragonCombat Enter");
  3190.     object oTarget = oIntruder;
  3191.     if(!GetIsObjectValid(oTarget))
  3192.     {
  3193.         oTarget = GetAttemptedAttackTarget();
  3194.         if(!GetIsObjectValid(oTarget) || GetIsDead(oTarget))
  3195.         {
  3196.             oTarget = GetLastHostileActor();
  3197.             if(!GetIsObjectValid(oTarget) || GetIsDead(oTarget))
  3198.             {
  3199.                 oTarget = GetNearestSeenOrHeardEnemy();
  3200.                 if(!GetIsObjectValid(oTarget))
  3201.                 {
  3202.                     return FALSE;
  3203.                 }
  3204.             }
  3205.         }
  3206.     }
  3207.     talent tUse;
  3208.     int nCnt = GetLocalInt(OBJECT_SELF, "NW_GENERIC_DRAGONS_BREATH");
  3209.     tUse = GetCreatureTalentBest(TALENT_CATEGORY_DRAGONS_BREATH, 20);
  3210.     //SpeakString(IntToString(nCnt));
  3211.     if(GetIsTalentValid(tUse) && nCnt >= 2)
  3212.     {
  3213.         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentDragonCombat Successful Exit");
  3214.         ClearAllActions();
  3215.         ActionUseTalentOnObject(tUse, oTarget);
  3216.         nCnt = 0;
  3217.         SetLocalInt(OBJECT_SELF, "NW_GENERIC_DRAGONS_BREATH", nCnt);
  3218.         return TRUE;
  3219.     }
  3220.     nCnt++;
  3221.     tUse = GetCreatureTalentRandom(TALENT_CATEGORY_HARMFUL_MELEE);
  3222.     if(GetIsTalentValid(tUse) && VerifyDisarm(tUse, oTarget))
  3223.     {
  3224.         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentDragonCombat Successful Exit");
  3225.         ClearAllActions();
  3226.         ActionUseTalentOnObject(tUse, oTarget);
  3227.         SetLocalInt(OBJECT_SELF, "NW_GENERIC_DRAGONS_BREATH", nCnt);
  3228.         return TRUE;
  3229.     }
  3230.     else
  3231.     {
  3232.         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentDragonCombat Successful Exit");
  3233.         ClearAllActions();
  3234.         ActionAttack(oTarget);
  3235.         SetLocalInt(OBJECT_SELF, "NW_GENERIC_DRAGONS_BREATH", nCnt);
  3236.         return TRUE;
  3237.     }
  3238.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentDragonCombat Failed Exit");
  3239.     SetLocalInt(OBJECT_SELF, "NW_GENERIC_DRAGONS_BREATH", nCnt);
  3240.     return FALSE;
  3241. }
  3242.  
  3243. // BARD SONG
  3244. int TalentBardSong()
  3245. {
  3246.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentBardSong Enter");
  3247.     //BARD SONG CONSTANT PENDING
  3248.     if(!GetHasSpellEffect(411))
  3249.     {
  3250.         if(GetHasFeat(FEAT_BARD_SONGS))
  3251.         {
  3252.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentBardSong Successful Exit");
  3253.             ClearAllActions();
  3254.             ActionUseFeat(FEAT_BARD_SONGS, OBJECT_SELF);
  3255.             return TRUE;
  3256.         }
  3257.     }
  3258.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentBardSong Failed Exit");
  3259.     return FALSE;
  3260. }
  3261.  
  3262. //************************************************************************************************************************************
  3263. //************************************************************************************************************************************
  3264. //************************************************************************************************************************************
  3265. // VERSION 2.0 TALENTS
  3266. //************************************************************************************************************************************
  3267. //************************************************************************************************************************************
  3268. //************************************************************************************************************************************
  3269.  
  3270. // ADVANCED PROTECT SELF Talent 2.0
  3271. // This will use the class specific defensive spells first and leave the rest for the normal defensive AI
  3272.  
  3273. int TalentAdvancedProtectSelf()
  3274. {
  3275.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentAdvancedProtectSelf Enter");
  3276.  
  3277.     talent tUse;
  3278.     struct sEnemies sCount = DetermineEnemies();
  3279.     int bValid = FALSE;
  3280.     int nCnt;
  3281.     string sClass = GetMostDangerousClass(sCount);
  3282.     tUse = StartProtectionLoop();
  3283.     while(GetIsTalentValid(tUse) && nCnt < 10)
  3284.     {
  3285.         MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentAdvancedProtectSelf Search Self");
  3286.         tUse = GetCreatureTalentRandom(TALENT_CATEGORY_BENEFICIAL_PROTECTION_SELF);
  3287.         if(GetIsTalentValid(tUse) && GetMatchCompatibility(tUse, sClass, NW_TALENT_PROTECT))
  3288.         {
  3289.             bValid = TRUE;
  3290.             nCnt = 11;
  3291.         }
  3292.         else
  3293.         {
  3294.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + " TalentAdvancedProtectSelfSearch Single");
  3295.             tUse = GetCreatureTalentRandom(TALENT_CATEGORY_BENEFICIAL_PROTECTION_SINGLE);
  3296.             if(GetIsTalentValid(tUse) && GetMatchCompatibility(tUse, sClass, NW_TALENT_PROTECT))
  3297.             {
  3298.                 bValid = TRUE;
  3299.                 nCnt = 11;
  3300.             }
  3301.             else
  3302.             {
  3303.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentAdvancedProtectSelf Search Area");
  3304.                 tUse = GetCreatureTalentRandom(TALENT_CATEGORY_BENEFICIAL_PROTECTION_AREAEFFECT);
  3305.                 if(GetIsTalentValid(tUse) && GetMatchCompatibility(tUse, sClass, NW_TALENT_PROTECT))
  3306.                 {
  3307.                     bValid = TRUE;
  3308.                     nCnt = 11;
  3309.                 }
  3310.             }
  3311.         }
  3312.         nCnt++;
  3313.     }
  3314.     if(bValid == TRUE)
  3315.     {
  3316.         int nType = GetTypeFromTalent(tUse);
  3317.         int nIndex = GetIdFromTalent(tUse);
  3318.  
  3319.         if(nType == TALENT_TYPE_SPELL)
  3320.         {
  3321.             if(!GetHasSpellEffect(nIndex))
  3322.             {
  3323.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentAdvancedProtectSelf Successful Exit");
  3324.                 ClearAllActions();
  3325.                 ActionUseTalentOnObject(tUse, OBJECT_SELF);
  3326.                 return TRUE;
  3327.             }
  3328.         }
  3329.         else if(nType == TALENT_TYPE_FEAT)
  3330.         {
  3331.             if(!GetHasFeatEffect(nIndex))
  3332.             {
  3333.                 MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentAdvancedProtectSelf Successful Exit");
  3334.                 ClearAllActions();
  3335.                 ActionUseTalentOnObject(tUse, OBJECT_SELF);
  3336.                 return TRUE;
  3337.             }
  3338.         }
  3339.         else
  3340.         {
  3341.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentAdvancedProtectSelf Successful Exit");
  3342.             ClearAllActions();
  3343.             ActionUseTalentOnObject(tUse, OBJECT_SELF);
  3344.             return TRUE;
  3345.         }
  3346.     }
  3347.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "TalentAdvancedProtectSelf Failed Exit");
  3348.     return FALSE;
  3349. }
  3350.  
  3351. //************************************************************************************************************************************
  3352. //************************************************************************************************************************************
  3353. //************************************************************************************************************************************
  3354. // PRIVATE FUNCTIONS
  3355. //************************************************************************************************************************************
  3356. //************************************************************************************************************************************
  3357. //************************************************************************************************************************************
  3358.  
  3359. //This is experimental and has not been looked at closely.
  3360. void ExitAOESpellArea(object oAOEObject)
  3361. {
  3362.     ClearAllActions();
  3363.     ActionMoveAwayFromObject(oAOEObject, TRUE, 5.0);
  3364.     AssignCommand(OBJECT_SELF, DetermineCombatRound());
  3365. }
  3366.  
  3367.  
  3368. //::///////////////////////////////////////////////
  3369. //:: Get Character Levels
  3370. //:: Copyright (c) 2001 Bioware Corp.
  3371. //:://////////////////////////////////////////////
  3372. /*
  3373.     Returns the combined class levels of the
  3374.     target.
  3375. */
  3376. //:://////////////////////////////////////////////
  3377. //:: Created By: Preston Watamaniuk
  3378. //:: Created On: Oct 22, 2001
  3379. //:://////////////////////////////////////////////
  3380.  
  3381. int GetCharacterLevel(object oTarget)
  3382. {
  3383.     return GetLevelByPosition(1, oTarget) + GetLevelByPosition(2, oTarget) + GetLevelByPosition(3, oTarget);
  3384. }
  3385.  
  3386. //::///////////////////////////////////////////////
  3387. //:: Get Has Effect
  3388. //:: Copyright (c) 2001 Bioware Corp.
  3389. //:://////////////////////////////////////////////
  3390. /*
  3391.     Checks to see if the target has a given
  3392.     spell effect
  3393. */
  3394. //:://////////////////////////////////////////////
  3395. //:: Created By: Preston Watamaniuk
  3396. //:: Created On: Oct 26, 2001
  3397. //:://////////////////////////////////////////////
  3398. int GetHasEffect(int nEffectType, object oTarget = OBJECT_SELF)
  3399. {
  3400.     effect eCheck = GetFirstEffect(oTarget);
  3401.     while(GetIsEffectValid(eCheck))
  3402.     {
  3403.         if(GetEffectType(eCheck) == nEffectType)
  3404.         {
  3405.              return TRUE;
  3406.         }
  3407.         eCheck = GetNextEffect(oTarget);
  3408.     }
  3409.     return FALSE;
  3410. }
  3411.  
  3412. //::///////////////////////////////////////////////
  3413. //:: Check Friendly Fire on Target
  3414. //:: Copyright (c) 2001 Bioware Corp.
  3415. //:://////////////////////////////////////////////
  3416. /*
  3417.     Takes a target object and a radius and
  3418.     returns how many targets of the caster's faction
  3419.     are in that zone.
  3420. */
  3421. //:://////////////////////////////////////////////
  3422. //:: Created By: Preston Watamaniuk
  3423. //:: Created On:  , 2001
  3424. //:://////////////////////////////////////////////
  3425.  
  3426. int CheckFriendlyFireOnTarget(object oTarget, float fDistance = 5.0)
  3427. {
  3428.     int nCnt, nHD, nMyHD;
  3429.     nMyHD = GetHitDice(OBJECT_SELF);
  3430.     object oCheck = GetFirstObjectInShape(SHAPE_SPHERE, fDistance, GetLocation(oTarget));
  3431.     while(GetIsObjectValid(oCheck))
  3432.     {
  3433.         //Use this instead of GetIsFriend to make sure that friendly casualties do not occur.
  3434.         //Formerlly GetIsReactionTypeFriendly(oCheck)
  3435.         nHD = GetHitDice(oCheck);
  3436.         if((GetIsFriend(oCheck)) &&
  3437.             oTarget != oCheck &&
  3438.             nMyHD <= (nHD * 2))
  3439.         {
  3440.             if(!GetIsReactionTypeFriendly(oCheck) || !AssociateCheck(oCheck))
  3441.             {
  3442.                 nCnt++;
  3443.             }
  3444.         }
  3445.         oCheck = GetNextObjectInShape(SHAPE_SPHERE, fDistance, GetLocation(oTarget));
  3446.     }
  3447.     return nCnt;
  3448. }
  3449.  
  3450. //::///////////////////////////////////////////////
  3451. //:: Check For Enemies Around Target
  3452. //:: Copyright (c) 2001 Bioware Corp.
  3453. //:://////////////////////////////////////////////
  3454. /*
  3455.     Takes a target object and a radius and
  3456.     returns how many targets of the enemy faction
  3457.     are in that zone.
  3458. */
  3459. //:://////////////////////////////////////////////
  3460. //:: Created By: Preston Watamaniuk
  3461. //:: Created On: Oct 16, 2001
  3462. //:://////////////////////////////////////////////
  3463. int CheckEnemyGroupingOnTarget(object oTarget, float fDistance = 5.0)
  3464. {
  3465.     int nCnt;
  3466.     object oCheck = GetFirstObjectInShape(SHAPE_SPHERE, fDistance, GetLocation(oTarget));
  3467.     while(GetIsObjectValid(oCheck))
  3468.     {
  3469.         if(GetIsEnemy(oCheck) && oTarget != oCheck)
  3470.         {
  3471.             nCnt++;
  3472.         }
  3473.         oCheck = GetNextObjectInShape(SHAPE_SPHERE, fDistance, GetLocation(oTarget));
  3474.     }
  3475.     return nCnt;
  3476. }
  3477.  
  3478. //::///////////////////////////////////////////////
  3479. //:: Find Single Ranged Target
  3480. //:: Copyright (c) 2001 Bioware Corp.
  3481. //:://////////////////////////////////////////////
  3482. /*
  3483.     Seeks out an enemy more than 5m away and alone
  3484. */
  3485. //:://////////////////////////////////////////////
  3486. //:: Created By: Preston Watamaniuk
  3487. //:: Created On: October 5, 2001
  3488. //:://////////////////////////////////////////////
  3489.  
  3490. object FindSingleRangedTarget()
  3491. {
  3492.     int nCnt = FALSE;
  3493.     object oTarget;
  3494.     float fDistance = 50.0;
  3495.     object oCount = GetFirstObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF));
  3496.     while (GetIsObjectValid(oCount) && nCnt == FALSE)
  3497.     {
  3498.         if(oCount != OBJECT_SELF)
  3499.         {
  3500.             if(GetIsEnemy(oCount) && oTarget != OBJECT_SELF)
  3501.             {
  3502.                 fDistance = GetDistanceBetween(oTarget, OBJECT_SELF);
  3503.                 if(fDistance == 0.0)
  3504.                 {
  3505.                     fDistance = 60.0;
  3506.                 }
  3507.                 if(GetDistanceBetween(oCount, OBJECT_SELF) < fDistance && fDistance > 3.0)
  3508.                 {
  3509.                     oTarget = oCount;
  3510.                     //nCnt = TRUE;
  3511.                 }
  3512.             }
  3513.         }
  3514.         oCount = GetNextObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF));
  3515.     }
  3516.     return oTarget;
  3517. }
  3518.  
  3519. //::///////////////////////////////////////////////
  3520. //:: GetNumberOfMeleeAttackers
  3521. //:: Copyright (c) 2001 Bioware Corp.
  3522. //:://////////////////////////////////////////////
  3523. /*
  3524.     Check how many enemies are within 5m of the
  3525.     target object.
  3526. */
  3527. //:://////////////////////////////////////////////
  3528. //:: Created By: Preston Watamaniuk
  3529. //:: Created On: Oct 11, 2001
  3530. //:://////////////////////////////////////////////
  3531. int GetNumberOfMeleeAttackers()
  3532. {
  3533.     int nCnt = 0;
  3534.     object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 5.0, GetLocation(OBJECT_SELF), TRUE);
  3535.     while(GetIsObjectValid(oTarget))
  3536.     {
  3537.          if(GetIsEnemy(oTarget))
  3538.          {
  3539.             nCnt++;
  3540.          }
  3541.          oTarget = GetNextObjectInShape(SHAPE_SPHERE, 5.0, GetLocation(OBJECT_SELF), TRUE);
  3542.     }
  3543.     return nCnt;
  3544. }
  3545.  
  3546. //::///////////////////////////////////////////////
  3547. //:: GetNumberOfRangedAttackers
  3548. //:: Copyright (c) 2001 Bioware Corp.
  3549. //:://////////////////////////////////////////////
  3550. /*
  3551.     Check how many enemies are attacking the
  3552.     target from as distance
  3553. */
  3554. //:://////////////////////////////////////////////
  3555. //:: Created By: Preston Watamaniuk
  3556. //:: Created On: Oct 12, 2001
  3557. //:://////////////////////////////////////////////
  3558. int GetNumberOfRangedAttackers()
  3559. {
  3560.     int nCnt;
  3561.     object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 40.0, GetLocation(OBJECT_SELF), TRUE);
  3562.     while(GetIsObjectValid(oTarget))
  3563.     {
  3564.          if(GetAttackTarget(oTarget) == OBJECT_SELF && GetDistanceBetween(OBJECT_SELF, oTarget) > 5.0)
  3565.          {
  3566.             nCnt++;
  3567.          }
  3568.          oTarget = GetNextObjectInShape(SHAPE_SPHERE, 40.0, GetLocation(OBJECT_SELF), TRUE);
  3569.     }
  3570.     return nCnt;
  3571. }
  3572.  
  3573. //::///////////////////////////////////////////////
  3574. //:: Get Percentage of HP Loss
  3575. //:: Copyright (c) 2001 Bioware Corp.
  3576. //:://////////////////////////////////////////////
  3577. /*
  3578.     Returns a number between 0 and 1.0 that gives
  3579.     a representation of how wounded the target is.
  3580. */
  3581. //:://////////////////////////////////////////////
  3582. //:: Created By: Preston Watamaniuk
  3583. //:: Created On: Nov 18, 2001
  3584. //:://////////////////////////////////////////////
  3585.  
  3586. int GetPercentageHPLoss(object oWounded)
  3587. {
  3588.     float fMaxHP = IntToFloat(GetMaxHitPoints(oWounded));
  3589.     float fCurrentHP = IntToFloat(GetCurrentHitPoints(oWounded));
  3590.     float fHP_Perc = (fCurrentHP / fMaxHP) * 100;
  3591.  
  3592.     int nHP = FloatToInt(fHP_Perc);
  3593.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Percentage HP of Target: " + IntToString(nHP));
  3594.     return nHP;
  3595. }
  3596.  
  3597. //::///////////////////////////////////////////////
  3598. //:: Get Racial Type Count
  3599. //:: Copyright (c) 2001 Bioware Corp.
  3600. //:://////////////////////////////////////////////
  3601. /*
  3602.     Counts and returns the number of a certain
  3603.     racial type within a certain radius.
  3604. */
  3605. //:://////////////////////////////////////////////
  3606. //:: Created By: Preston Watamaniuk
  3607. //:: Created On: Nov 18, 2001
  3608. //:://////////////////////////////////////////////
  3609.  
  3610. int GetRacialTypeCount(int nRacial_Type)
  3611. {
  3612.     int nCnt = 1;
  3613.     int nCount = 0;
  3614.     object oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_RACIAL_TYPE, nRacial_Type);
  3615.     while(GetIsObjectValid(oTarget) && GetDistanceToObject(oTarget) <= 20.0)
  3616.     {
  3617.         if(!GetHasEffect(EFFECT_TYPE_TURNED, oTarget))
  3618.         {
  3619.             nCount++;
  3620.         }
  3621.         nCnt++;
  3622.         oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_RACIAL_TYPE, nRacial_Type);
  3623.     }
  3624.     return nCount;
  3625. }
  3626.  
  3627. //::///////////////////////////////////////////////
  3628. //:: Get Enemy Creature Seen or Heard
  3629. //:: Copyright (c) 2002 Bioware Corp.
  3630. //:://////////////////////////////////////////////
  3631. /*
  3632.     This function finds an enemy that can be seen
  3633.     first and if that fails an enemy that can be
  3634.     heard only.
  3635. */
  3636. //:://////////////////////////////////////////////
  3637. //:: Created By: Preston Watamaniuk
  3638. //:: Created On: Jan 28, 2002
  3639. //:://////////////////////////////////////////////
  3640.  
  3641. object GetNearestSeenOrHeardEnemy()
  3642. {
  3643.     object oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  3644.     if(!GetIsObjectValid(oTarget))
  3645.     {
  3646.         oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_HEARD_AND_NOT_SEEN);
  3647.         if(!GetIsObjectValid(oTarget))
  3648.         {
  3649.            return OBJECT_INVALID;
  3650.         }
  3651.     }
  3652.     return oTarget;
  3653. }
  3654.  
  3655. //::///////////////////////////////////////////////
  3656. //:: Get / Set Compare Last Spell Cast
  3657. //:: Copyright (c) 2001 Bioware Corp.
  3658. //:://////////////////////////////////////////////
  3659. /*
  3660.     Gets the local int off of the character
  3661.     determining what the Last Spell Cast was.
  3662.     
  3663.     Sets the local int on of the character
  3664.     storing what the Last Spell Cast was.
  3665.     
  3666.     Compares whether the local is the same as the
  3667.     currently selected spell.
  3668. */
  3669. //:://////////////////////////////////////////////
  3670. //:: Created By: Preston Watamaniuk
  3671. //:: Created On: Feb 27, 2002
  3672. //:://////////////////////////////////////////////
  3673.  
  3674. int GetLastGenericSpellCast()
  3675. {
  3676.     return GetLocalInt(OBJECT_SELF, "NW_GENERIC_LAST_SPELL");
  3677. }
  3678.  
  3679. void SetLastGenericSpellCast(int nSpell)
  3680. {
  3681.     SetLocalInt(OBJECT_SELF, "NW_GENERIC_LAST_SPELL", nSpell);
  3682. }
  3683.  
  3684. int CompareLastSpellCast(int nSpell)
  3685. {
  3686.     int nLastSpell = GetLastGenericSpellCast();
  3687.     if(nSpell == nLastSpell)
  3688.     {
  3689.         return TRUE;
  3690.         SetLastGenericSpellCast(-1);
  3691.     }
  3692.     return FALSE;
  3693. }
  3694.  
  3695. //::///////////////////////////////////////////////
  3696. //:: Remove Ambient Sleep
  3697. //:: Copyright (c) 2001 Bioware Corp.
  3698. //:://////////////////////////////////////////////
  3699. /*
  3700.     Checks if the NPC has sleep on them because
  3701.     of ambient animations. Sleeping creatures
  3702.     must make a DC 15 listen check.
  3703. */
  3704. //:://////////////////////////////////////////////
  3705. //:: Created By: Preston Watamaniuk
  3706. //:: Created On: Feb 27, 2002
  3707. //:://////////////////////////////////////////////
  3708.  
  3709. void RemoveAmbientSleep()
  3710. {
  3711.     if(GetHasEffect(EFFECT_TYPE_SLEEP))
  3712.     {
  3713.         effect eSleep = GetFirstEffect(OBJECT_SELF);
  3714.         while(GetIsEffectValid(eSleep))
  3715.         {
  3716.             if(GetEffectCreator(eSleep) == OBJECT_SELF)
  3717.             {
  3718.                 int nRoll = d20();
  3719.                 nRoll += GetSkillRank(SKILL_LISTEN);
  3720.                 nRoll += GetAbilityModifier(ABILITY_WISDOM);
  3721.                 if(nRoll > 15)
  3722.                 {
  3723.                     RemoveEffect(OBJECT_SELF, eSleep);
  3724.                 }
  3725.             }
  3726.             eSleep = GetNextEffect(OBJECT_SELF);
  3727.         }
  3728.     }
  3729. }
  3730.  
  3731. //::///////////////////////////////////////////////
  3732. //:: GetIsFighting
  3733. //:: Copyright (c) 2001 Bioware Corp.
  3734. //:://////////////////////////////////////////////
  3735. /*
  3736.     Checks if the passed object has an Attempted
  3737.     Attack or Spell Target
  3738. */
  3739. //:://////////////////////////////////////////////
  3740. //:: Created By: Preston Watamaniuk
  3741. //:: Created On: March 13, 2002
  3742. //:://////////////////////////////////////////////
  3743. int GetIsFighting(object oFighting)
  3744. {
  3745.     object oAttack = GetAttemptedAttackTarget();
  3746.     object oSpellTarget = GetAttemptedSpellTarget();
  3747.     
  3748.     if(GetIsObjectValid(oAttack) || GetIsObjectValid(oSpellTarget))
  3749.     {
  3750.         return TRUE;
  3751.     }
  3752.     return FALSE;
  3753. }
  3754.  
  3755. //::///////////////////////////////////////////////
  3756. //:: Get Locked Object
  3757. //:: Copyright (c) 2001 Bioware Corp.
  3758. //:://////////////////////////////////////////////
  3759. /*
  3760.     Finds the closest locked object to the object
  3761.     passed in up to a maximum of 10 objects.
  3762. */
  3763. //:://////////////////////////////////////////////
  3764. //:: Created By: Preston Watamaniuk
  3765. //:: Created On: March 15, 2002
  3766. //:://////////////////////////////////////////////
  3767.  
  3768. object GetLockedObject(object oMaster)
  3769. {
  3770.     int nCnt = 1;
  3771.     int bValid = TRUE;
  3772.     object oLastObject = GetNearestObjectToLocation(OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE, GetLocation(oMaster), nCnt);
  3773.     while (GetIsObjectValid(oLastObject) && bValid == TRUE)
  3774.     {
  3775.         //COMMENT THIS BACK IN WHEN DOOR ACTION WORKS ON PLACABLE.
  3776.  
  3777.         //object oItem = GetFirstItemInInventory(oLastObject);
  3778.         if(GetLocked(oLastObject))
  3779.         {
  3780.             return oLastObject;
  3781.         }
  3782.         nCnt++;
  3783.         if(nCnt == 10)
  3784.         {
  3785.             bValid = FALSE;
  3786.         }
  3787.         oLastObject = GetNearestObjectToLocation(OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE, GetLocation(oMaster), nCnt);
  3788.     }
  3789.     return OBJECT_INVALID;
  3790. }
  3791.  
  3792. //::///////////////////////////////////////////////
  3793. //:: Equip Appropriate Weapons
  3794. //:: Copyright (c) 2001 Bioware Corp.
  3795. //:://////////////////////////////////////////////
  3796. /*
  3797.     Makes the user get his best weapons.  If the
  3798.     user is a Henchmen then he checks the player
  3799.     preference.
  3800. */
  3801. //:://////////////////////////////////////////////
  3802. //:: Created By: Preston Watamaniuk
  3803. //:: Created On: April 2, 2002
  3804. //:://////////////////////////////////////////////
  3805.  
  3806. void EquipAppropriateWeapons(object oTarget)
  3807. {
  3808.     if(GetIsObjectValid(GetMaster()))
  3809.     {
  3810.         if(GetAssociateState(NW_ASC_USE_RANGED_WEAPON))
  3811.         {
  3812.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Associate Equiping Ranged Weapon");
  3813.             ActionEquipMostDamagingRanged(oTarget);
  3814.         }
  3815.         else
  3816.         {
  3817.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Associate Equiping Melee Weapon");
  3818.             ActionEquipMostDamagingMelee(oTarget);
  3819.         }
  3820.     }
  3821.     else
  3822.     {
  3823.         //if(!GetIsWeaponEffective(oTarget))
  3824.         //{
  3825.             if(GetDistanceToObject(oTarget) > 5.0)
  3826.             {
  3827.                 ActionEquipMostDamagingRanged(oTarget);
  3828.             }
  3829.             else
  3830.             {
  3831.                 ActionEquipMostDamagingMelee(oTarget);
  3832.             }
  3833.         //}
  3834.     }
  3835. }
  3836.  
  3837. int AssociateCheck(object oCheck)
  3838. {
  3839.     object oHench = GetAssociate(ASSOCIATE_TYPE_HENCHMAN);
  3840.     if(oCheck != oHench)
  3841.     {
  3842.         return TRUE;
  3843.     }
  3844.     return FALSE;
  3845. }
  3846.  
  3847. //::///////////////////////////////////////////////
  3848. //:: Verify Disarm
  3849. //:: Copyright (c) 2001 Bioware Corp.
  3850. //:://////////////////////////////////////////////
  3851. /*
  3852.     Checks that the melee talent being used
  3853.     is Disarm and if so then if the target has a
  3854.     weapon.
  3855. */
  3856. //:://////////////////////////////////////////////
  3857. //:: Created By:
  3858. //:: Created On:
  3859. //:://////////////////////////////////////////////
  3860.  
  3861. int VerifyDisarm(talent tUse, object oTarget)
  3862. {
  3863.     int bValid = FALSE;
  3864.     
  3865.     if(GetTypeFromTalent(tUse) == TALENT_TYPE_FEAT)
  3866.     {
  3867.         int nFeat = GetIdFromTalent(tUse);
  3868.         if(nFeat == FEAT_DISARM)
  3869.         {
  3870.             object oSlot1 = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget);
  3871.             object oSlot2 = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget);
  3872.             object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND);
  3873.             object oWeapon2 = GetItemInSlot(INVENTORY_SLOT_LEFTHAND);
  3874.             
  3875.             if(GetIsObjectValid(oSlot1) || GetIsObjectValid(oSlot2))
  3876.             {
  3877.                 if(GetIsObjectValid(oWeapon) && !GetWeaponRanged(oWeapon))
  3878.                 {
  3879.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Verify Disarm = TRUE");
  3880.  
  3881.                     return TRUE;
  3882.                 }
  3883.                 else if(GetIsObjectValid(oWeapon2) && !GetWeaponRanged(oWeapon2))
  3884.                 {
  3885.                     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Verify Disarm = TRUE");
  3886.                     return TRUE;
  3887.                 }
  3888.             }
  3889.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Verify Disarm = FALSE");
  3890.             return FALSE;
  3891.         }
  3892.         else
  3893.         {
  3894.             MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Verify Disarm = TRUE");
  3895.             return TRUE;
  3896.         }
  3897.     }
  3898.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Verify Disarm = TRUE");
  3899.     return TRUE;
  3900. }
  3901.  
  3902. //::///////////////////////////////////////////////
  3903. //:: Verify Melee Talent Use
  3904. //:: Copyright (c) 2001 Bioware Corp.
  3905. //:://////////////////////////////////////////////
  3906. /*
  3907.     Makes sure that certain talents are not used
  3908.     on Elementals, Undead or Constructs
  3909. */
  3910. //:://////////////////////////////////////////////
  3911. //:: Created By: Preston Watamaniuk
  3912. //:: Created On: May 23, 2002
  3913. //:://////////////////////////////////////////////
  3914. int VerifyCombatMeleeTalent(talent tUse, object oTarget)
  3915. {
  3916.     int nFeatID = GetIdFromTalent(tUse);
  3917.     if(nFeatID == FEAT_SAP ||
  3918.        nFeatID == FEAT_STUNNING_FIST)
  3919.     {
  3920.         int nRacial = GetRacialType(oTarget);
  3921.         if(nRacial == RACIAL_TYPE_CONSTRUCT ||
  3922.            nRacial == RACIAL_TYPE_UNDEAD ||
  3923.            nRacial == RACIAL_TYPE_ELEMENTAL ||
  3924.            nRacial == RACIAL_TYPE_VERMIN)
  3925.         {
  3926.             return FALSE;
  3927.         }
  3928.     }
  3929.     return TRUE;
  3930. }
  3931.  
  3932. //:://////////////////////////////////////////////////////////////////////////////////////////////
  3933. //:: Associate Include Functions
  3934. //:: NW_I0_ASSOCIATE
  3935. //:: Copyright (c) 2001 Bioware Corp.
  3936. //:://///////////////////////////////////////////////////////////////////////////////////////////
  3937. /*
  3938.     Determines and stores the behavior of the
  3939.     associates used by the PC
  3940. */
  3941. //:://///////////////////////////////////////////////////////////////////////////////////////////
  3942. //:: Created By: Preston Watamaniuk
  3943. //:: Created On: November 16, 2001
  3944. //:://///////////////////////////////////////////////////////////////////////////////////////////
  3945.  
  3946. //Distance
  3947. int NW_ASC_DISTANCE_2_METERS =   0x00000001;
  3948. int NW_ASC_DISTANCE_4_METERS =   0x00000002;
  3949. int NW_ASC_DISTANCE_6_METERS =   0x00000004;
  3950. //Heal when
  3951. int NW_ASC_HEAL_AT_75 =          0x00000008;
  3952. int NW_ASC_HEAL_AT_50 =          0x00000010;
  3953. int NW_ASC_HEAL_AT_25 =          0x00000020;
  3954. //Auto AI
  3955. int NW_ASC_AGGRESSIVE_BUFF =     0x00000040;
  3956. int NW_ASC_AGGRESSIVE_SEARCH =   0x00000080;
  3957. int NW_ASC_AGGRESSIVE_STEALTH =  0x00000100;
  3958. //Open Locks on master fail
  3959. int NW_ASC_RETRY_OPEN_LOCKS =    0x00000200;
  3960. //Casting power
  3961. int NW_ASC_OVERKIll_CASTING =    0x00000400; // GetMax Spell
  3962. int NW_ASC_POWER_CASTING =       0x00000800; // Get Double CR or max 4 casting
  3963. int NW_ASC_SCALED_CASTING =      0x00001000; // CR + 4;
  3964.  
  3965. int NW_ASC_USE_CUSTOM_DIALOGUE = 0x00002000;
  3966. int NW_ASC_DISARM_TRAPS =        0x00004000;
  3967. int NW_ASC_USE_RANGED_WEAPON   = 0x00008000;
  3968. int NW_ASC_MODE_DEFEND_MASTER =  0x04000000; //Guard Me Mode, Attack Nearest sets this to FALSE.
  3969. int NW_ASC_MODE_STAND_GROUND =   0x08000000; //The Henchman will ignore move to object in the heartbeat
  3970.                                              //If this is set to FALSE then they are in follow mode
  3971. int NW_ASC_MASTER_GONE =         0x10000000;
  3972. int NW_ASC_MASTER_REVOKED =      0x20000000;
  3973. int NW_ASC_IS_BUSY =             0x40000000; //Only busy if attempting to bash or pick a lock
  3974. int NW_ASC_HAVE_MASTER =         0x80000000; //Not actually used, here for system continuity
  3975.  
  3976. void SetAssociateState(int nCondition, int bValid = TRUE)
  3977. {
  3978.     int nPlot = GetLocalInt(OBJECT_SELF, "NW_ASSOCIATE_MASTER");
  3979.     if(bValid == TRUE)
  3980.     {
  3981.         nPlot = nPlot | nCondition;
  3982.         SetLocalInt(OBJECT_SELF, "NW_ASSOCIATE_MASTER", nPlot);
  3983.     }
  3984.     else if (bValid == FALSE)
  3985.     {
  3986.         nPlot = nPlot & ~nCondition;
  3987.         SetLocalInt(OBJECT_SELF, "NW_ASSOCIATE_MASTER", nPlot);
  3988.     }
  3989. }
  3990.  
  3991. int GetAssociateState(int nCondition)
  3992. {
  3993.     if(nCondition == NW_ASC_HAVE_MASTER)
  3994.     {
  3995.         if(GetIsObjectValid(GetMaster()))
  3996.         {
  3997.             return TRUE;
  3998.         }
  3999.     }
  4000.     else
  4001.     {
  4002.         int nPlot = GetLocalInt(OBJECT_SELF, "NW_ASSOCIATE_MASTER");
  4003.         if(nPlot & nCondition)
  4004.         {
  4005.             return TRUE;
  4006.         }
  4007.     }
  4008.     return FALSE;
  4009. }
  4010.  
  4011. //::///////////////////////////////////////////////
  4012. //:: Get CR Max for Talents
  4013. //:: Copyright (c) 2001 Bioware Corp.
  4014. //:://////////////////////////////////////////////
  4015. /*
  4016.     Determines the Spell CR to be used in the
  4017.     given situation
  4018. */
  4019. //:://////////////////////////////////////////////
  4020. //:: Created By: Preston Watamaniuk
  4021. //:: Created On: Nov 18, 2001
  4022. //:://////////////////////////////////////////////
  4023.  
  4024. int GetAssociateCRMax()
  4025. {
  4026.     int nCR;
  4027.     /*
  4028.     if(GetAssociateState(NW_ASC_HAVE_MASTER))
  4029.     {
  4030.         object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  4031.         oEnemy = GetFactionStrongestMember(oEnemy);
  4032.         int nHD = GetHitDice(oEnemy);
  4033.         if(GetAssociateState(NW_ASC_OVERKIll_CASTING))
  4034.         {
  4035.             nCR = 20;
  4036.         }
  4037.         else if(GetAssociateState(NW_ASC_POWER_CASTING))
  4038.         {
  4039.             nCR = nHD * 2;
  4040.             if (nCR > 20) {nCR = 20;}
  4041.             if (nCR < 5) {nCR = 5;}
  4042.         }
  4043.         else
  4044.         {
  4045.             nCR = nHD + 4;
  4046.             if (nCR > 20){nCR = 20;}
  4047.         }
  4048.         return nCR;
  4049.     }
  4050.     */
  4051.     return 20;
  4052. }
  4053.  
  4054. //::///////////////////////////////////////////////
  4055. //:: Should I Heal My Master
  4056. //:: Copyright (c) 2001 Bioware Corp.
  4057. //:://////////////////////////////////////////////
  4058. /*
  4059.     Determines the healing variable for the master
  4060.     and then asks if the master if below that level.
  4061. */
  4062. //:://////////////////////////////////////////////
  4063. //:: Created By: Preston Watamaniuk
  4064. //:: Created On: Nov 18, 2001
  4065. //:://////////////////////////////////////////////
  4066.  
  4067. int GetAssociateHealMaster()
  4068. {
  4069.     if(GetAssociateState(NW_ASC_HAVE_MASTER))
  4070.     {
  4071.         object oMaster = GetMaster();
  4072.         int nLoss = GetPercentageHPLoss(oMaster);
  4073.         if(!GetIsDead(oMaster))
  4074.         {
  4075.             if(GetAssociateState(NW_ASC_HEAL_AT_75) && nLoss <= 75)
  4076.             {
  4077.                 return TRUE;
  4078.             }
  4079.             else if(GetAssociateState(NW_ASC_HEAL_AT_50) && nLoss <= 50)
  4080.             {
  4081.                 return TRUE;
  4082.             }
  4083.             else if(GetAssociateState(NW_ASC_HEAL_AT_25) && nLoss <= 25)
  4084.             {
  4085.                 return TRUE;
  4086.             }
  4087.         }
  4088.     }
  4089.     return FALSE;
  4090. }
  4091.  
  4092. float GetFollowDistance()
  4093. {
  4094.     float fDistance;
  4095.     if(GetAssociateState(NW_ASC_DISTANCE_2_METERS))
  4096.     {
  4097.         fDistance = 2.0;
  4098.     }
  4099.     else if(GetAssociateState(NW_ASC_DISTANCE_4_METERS))
  4100.     {
  4101.         fDistance = 4.0;
  4102.     }
  4103.     else if(GetAssociateState(NW_ASC_DISTANCE_6_METERS))
  4104.     {
  4105.         fDistance = 6.0;
  4106.     }
  4107.     //SpeakString(FloatToString(fDistance, 5, 5));
  4108.     return fDistance;
  4109. }
  4110.  
  4111.  
  4112. //::///////////////////////////////////////////////
  4113. //:: Check if an item is locked
  4114. //:: Copyright (c) 2001 Bioware Corp.
  4115. //:://////////////////////////////////////////////
  4116. /*
  4117.     Checks that an item was unlocked.
  4118. */
  4119. //:://////////////////////////////////////////////
  4120. //:: Created By: Preston Watamaniuk
  4121. //:: Created On: Nov 19, 2001
  4122. //:://////////////////////////////////////////////
  4123.  
  4124. void CheckIsUnlocked(object oLastObject)
  4125. {
  4126.     if(GetLocked(oLastObject))
  4127.     {
  4128.         ActionDoCommand(PlayVoiceChat(VOICE_CHAT_CUSS));
  4129.     }
  4130.     else
  4131.     {
  4132.         ActionDoCommand(PlayVoiceChat(VOICE_CHAT_CANDO));
  4133.     }
  4134. }
  4135.  
  4136. //::///////////////////////////////////////////////
  4137. //:: Set and Get Associate Start Location
  4138. //:: Copyright (c) 2001 Bioware Corp.
  4139. //:://////////////////////////////////////////////
  4140. //:://////////////////////////////////////////////
  4141. //:: Created By: Preston Watmaniuk
  4142. //:: Created On: Nov 21, 2001
  4143. //:://////////////////////////////////////////////
  4144.  
  4145. void SetAssociateStartLocation()
  4146. {
  4147.     SetLocalLocation(OBJECT_SELF, "NW_ASSOCIATE_START", GetLocation(OBJECT_SELF));
  4148. }
  4149.  
  4150. location GetAssociateStartLocation()
  4151. {
  4152.     return GetLocalLocation(OBJECT_SELF, "NW_ASSOCIATE_START");
  4153. }
  4154.  
  4155. //::///////////////////////////////////////////////
  4156. //:: Play Mobile Ambient Animations
  4157. //:: Copyright (c) 2001 Bioware Corp.
  4158. //:://////////////////////////////////////////////
  4159. /*
  4160.     Used for spawned creatures to not look like
  4161.     zombies
  4162. */
  4163. //:://////////////////////////////////////////////
  4164. //:: Created By: Preston Watamaniuk
  4165. //:: Created On: Nov 23, 2001
  4166. //:://////////////////////////////////////////////
  4167.  
  4168. void PlayMobileAmbientAnimations()
  4169. {
  4170.     location lLocal;
  4171.     vector vFrnd;
  4172.     int nRoll = Random(5)+1;
  4173.     object oFriend = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nRoll, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  4174.     int nHDMe = GetHitDice(OBJECT_SELF);
  4175.     int nHDOther = GetHitDice(oFriend);
  4176.  
  4177.     //If a bird
  4178.     if(!GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS_AVIAN))
  4179.     {
  4180.         /*
  4181.             Use this animation for all player races and humanoids
  4182.             who are civilized. Monstrous races will wonder about
  4183.             and try to look busy in as non-social manner.
  4184.         */
  4185.         if(GetRacialType(OBJECT_SELF) == RACIAL_TYPE_ELF ||
  4186.            GetRacialType(OBJECT_SELF) == RACIAL_TYPE_GNOME ||
  4187.            GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HALFELF ||
  4188.            GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HALFLING ||
  4189.            GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HALFORC ||
  4190.            GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HUMAN ||
  4191.            GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HUMANOID_GOBLINOID ||
  4192.            GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HUMANOID_REPTILIAN ||
  4193.            GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HUMANOID_ORC)
  4194.         {
  4195.             if(nRoll == 4 || nRoll == 5)
  4196.             {
  4197.                 ClearAllActions();
  4198.                 ActionRandomWalk();
  4199.             }
  4200.             else
  4201.             {
  4202.                 if(!GetIsObjectValid(oFriend) || GetIsPC(oFriend) || IsInConversation(oFriend))
  4203.                 {
  4204.                     ClearAllActions();
  4205.                     ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
  4206.                     ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
  4207.                 }
  4208.                 else
  4209.                 {
  4210.                     if(GetDistanceToObject(oFriend) >= 3.0 && GetDistanceToObject(oFriend) <= 5.0 )
  4211.                     {
  4212.                         ClearAllActions();
  4213.                         ActionMoveToObject(oFriend, FALSE, 2.0);
  4214.                     }
  4215.                     else if(GetDistanceToObject(oFriend) >= 5.0)
  4216.                     {
  4217.                         ClearAllActions();
  4218.                         ActionPlayAnimation(ANIMATION_FIREFORGET_GREETING, 0.75);
  4219.                         ActionMoveToObject(oFriend, FALSE, 2.0);
  4220.                     }
  4221.                     vFrnd = GetPosition(oFriend);
  4222.                     SetFacingPoint(vFrnd);
  4223.                     nRoll = d4();
  4224.                 }
  4225.  
  4226.                 if(GetIsObjectValid(oFriend))
  4227.                 {
  4228.                     ClearAllActions();
  4229.                     if(nHDMe == nHDOther)
  4230.                     {
  4231.                         if(nRoll == 1)
  4232.                         {
  4233.                             ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 6.0);
  4234.                         }
  4235.                         else if(nRoll == 2)
  4236.                         {
  4237.                             ActionPlayAnimation(ANIMATION_LOOPING_TALK_PLEADING, 1.0, 6.0);
  4238.                         }
  4239.                         else if(nRoll == 3)
  4240.                         {
  4241.                             ActionPlayAnimation(ANIMATION_LOOPING_TALK_FORCEFUL, 1.0, 6.0);
  4242.                         }
  4243.                         else
  4244.                         {
  4245.                             ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
  4246.                             ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
  4247.                         }
  4248.                     }
  4249.                     else if(nHDMe > nHDOther)
  4250.                     {
  4251.                         if(nRoll == 1)
  4252.                         {
  4253.                             ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 6.0);
  4254.                         }
  4255.                         else if(nRoll == 2)
  4256.                         {
  4257.                             ActionPlayAnimation(ANIMATION_LOOPING_TALK_FORCEFUL, 1.0, 6.0);
  4258.                         }
  4259.                         else if(nRoll == 3)
  4260.                         {
  4261.                             ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING, 1.0, 6.0);
  4262.                         }
  4263.                         else
  4264.                         {
  4265.                             ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
  4266.                             ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
  4267.                         }
  4268.                     }
  4269.                     else if (nHDMe < nHDOther)
  4270.                     {
  4271.                         if(nRoll == 1)
  4272.                         {
  4273.                             ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 6.0);
  4274.                         }
  4275.                         else if(nRoll == 2)
  4276.                         {
  4277.                             ActionPlayAnimation(ANIMATION_LOOPING_TALK_PLEADING, 1.0, 6.0);
  4278.                         }
  4279.                         else if(nRoll == 3)
  4280.                         {
  4281.                             ActionPlayAnimation(ANIMATION_FIREFORGET_SALUTE, 0.75);
  4282.                         }
  4283.                         else
  4284.                         {
  4285.                             ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
  4286.                             ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
  4287.                         }
  4288.                     }
  4289.                 }
  4290.             }
  4291.         }
  4292.         else
  4293.         {
  4294.             ClearAllActions();
  4295.             int nRand = d6();
  4296.             if(nRand == 1)
  4297.             {
  4298.                 if(GetDistanceToObject(oFriend) >= 3.0 && GetDistanceToObject(oFriend) <= 10.0 )
  4299.                 {
  4300.                     ActionMoveToObject(oFriend, FALSE, 2.0);
  4301.                     vFrnd = GetPosition(oFriend);
  4302.                     SetFacingPoint(vFrnd);
  4303.                 }
  4304.             }
  4305.             else if(nRand == 2 || nRand == 3 || nRand == 4)
  4306.             {
  4307.                 ActionRandomWalk();
  4308.             }
  4309.             else if(nRand == 5)
  4310.             {
  4311.                 ActionPlayAnimation(ANIMATION_LOOPING_GET_MID);
  4312.             }
  4313.             else if(nRand == 6)
  4314.             {
  4315.             }
  4316.         }
  4317.     }
  4318.     else //Birds Ambient Behavior
  4319.     {
  4320.         int nBird = d4();
  4321.         location lFriend;
  4322.         effect eBird;
  4323.         if(GetIsObjectValid(oFriend))
  4324.         {
  4325.             lFriend = GetLocation(oFriend);
  4326.         }
  4327.         else
  4328.         {
  4329.             lFriend = GetLocation(OBJECT_SELF);
  4330.         }
  4331.         if(nBird == 0)
  4332.         {
  4333.             ClearAllActions();
  4334.             ActionMoveToObject(oFriend, TRUE, 4.0);
  4335.             ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBird, OBJECT_SELF, 5.0);
  4336.         }
  4337.         else if (nBird == 1 || nBird == 2 || nBird == 3)
  4338.         {
  4339.             ClearAllActions();
  4340.             ActionMoveAwayFromObject(oFriend, TRUE, 100.0);
  4341.         }
  4342.         else
  4343.         {
  4344.             ClearAllActions();
  4345.             eBird = EffectDisappearAppear(lFriend);
  4346.             ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBird, OBJECT_SELF, 4.0);
  4347.             ActionMoveAwayFromObject(oFriend, TRUE, 100.0);
  4348.         }
  4349.     }
  4350. }
  4351.  
  4352. //::///////////////////////////////////////////////
  4353. //:: Play Immobile Ambient Animations
  4354. //:: Copyright (c) 2001 Bioware Corp.
  4355. //:://////////////////////////////////////////////
  4356. /*
  4357.     Used for spawned creatures to not look like
  4358.     zombies
  4359. */
  4360. //:://////////////////////////////////////////////
  4361. //:: Created By: Preston Watamaniuk
  4362. //:: Created On: Nov 23, 2001
  4363. //:://////////////////////////////////////////////
  4364.  
  4365. void PlayImmobileAmbientAnimations()
  4366. {
  4367.     location lLocal;
  4368.     vector vFrnd;
  4369.     int nRoll = d2();
  4370.     object oFriend = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nRoll, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  4371.     int nHDMe = GetHitDice(OBJECT_SELF);
  4372.     int nHDOther = GetHitDice(oFriend);
  4373.     if(!GetIsObjectValid(oFriend) || GetIsPC(oFriend) || IsInConversation(oFriend))
  4374.     {
  4375.         ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
  4376.         ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
  4377.     }
  4378.     else
  4379.     {
  4380.         if(GetIsObjectValid(oFriend) && GetDistanceToObject(oFriend) <= 3.0)
  4381.         {
  4382.             vFrnd = GetPosition(oFriend);
  4383.             SetFacingPoint(vFrnd);
  4384.             nRoll = d4();
  4385.             ClearAllActions();
  4386.             if(nHDMe == nHDOther)
  4387.             {
  4388.  
  4389.                 if(nRoll == 1)
  4390.                 {
  4391.                     ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 6.0);
  4392.                 }
  4393.                 else if(nRoll == 2)
  4394.                 {
  4395.                     ActionPlayAnimation(ANIMATION_LOOPING_TALK_PLEADING, 1.0, 6.0);
  4396.                 }
  4397.                 else if(nRoll == 3)
  4398.                 {
  4399.                     ActionPlayAnimation(ANIMATION_LOOPING_TALK_FORCEFUL, 1.0, 6.0);
  4400.                 }
  4401.                 else
  4402.                 {
  4403.                     ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
  4404.                     ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
  4405.                 }
  4406.             }
  4407.             else if(nHDMe > nHDOther)
  4408.             {
  4409.                 if(nRoll == 1)
  4410.                 {
  4411.                     ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 6.0);
  4412.                 }
  4413.                 else if(nRoll == 2)
  4414.                 {
  4415.                     ActionPlayAnimation(ANIMATION_LOOPING_TALK_FORCEFUL, 1.0, 6.0);
  4416.                 }
  4417.                 else if(nRoll == 3)
  4418.                 {
  4419.                     ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING, 1.0, 6.0);
  4420.                 }
  4421.                 else
  4422.                 {
  4423.                     ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
  4424.                     ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
  4425.                 }
  4426.             }
  4427.             else if (nHDMe < nHDOther)
  4428.             {
  4429.                 if(nRoll == 1)
  4430.                 {
  4431.                     ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 6.0);
  4432.                 }
  4433.                 else if(nRoll == 2)
  4434.                 {
  4435.                     ActionPlayAnimation(ANIMATION_LOOPING_TALK_PLEADING, 1.0, 6.0);
  4436.                 }
  4437.                 else if(nRoll == 3)
  4438.                 {
  4439.                     ActionPlayAnimation(ANIMATION_FIREFORGET_SALUTE, 0.75);
  4440.                 }
  4441.                 else
  4442.                 {
  4443.                     ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
  4444.                     ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
  4445.                 }
  4446.             }
  4447.         }
  4448.     }
  4449. }
  4450.  
  4451. //::///////////////////////////////////////////////
  4452. //:: Check for Walkways
  4453. //:: Copyright (c) 2001 Bioware Corp.
  4454. //:://////////////////////////////////////////////
  4455. /*
  4456.     This function checks if the passed in object
  4457.     has waypoints using their tag.
  4458. */
  4459. //:://////////////////////////////////////////////
  4460. //:: Created By: Preston Watamaniuk
  4461. //:: Created On: MAy 13, 2002
  4462. //:://////////////////////////////////////////////
  4463. /*
  4464.     if(GetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING))
  4465.     {
  4466.         DayWayString = "WP_";
  4467.         NightWayString = "WN_";
  4468.         DayPostString = "POST_";
  4469.         NightPostString = "NIGHT_";
  4470.     }
  4471.     else
  4472.     {
  4473.         DayWayString = "WP_";
  4474.         NightWayString = "WP_";
  4475.         DayPostString = "POST_";
  4476.         NightPostString = "POST_";
  4477.     }
  4478. */
  4479. int GetIsPostOrWalking(object oWalker = OBJECT_SELF)
  4480. {
  4481.     string sTag = GetTag(oWalker);
  4482.     
  4483.     object oPost = GetWaypointByTag("POST_" + sTag);
  4484.     if(!GetIsObjectValid(oPost))
  4485.     {
  4486.         oPost = GetWaypointByTag("NIGHT_" + sTag);
  4487.         if(!GetIsObjectValid(oPost))
  4488.         {
  4489.             oPost = GetWaypointByTag("WP_" + sTag + "_01");
  4490.             if(!GetIsObjectValid(oPost))
  4491.             {
  4492.                 oPost = GetWaypointByTag("WN_" + sTag + "_01");
  4493.                 if(!GetIsObjectValid(oPost))
  4494.                 {
  4495.                     return FALSE;
  4496.                 }
  4497.             }
  4498.         }
  4499.     }
  4500.     return TRUE;
  4501. }
  4502. //:://////////////////////////////////////////////////////////////////////////////////////////////
  4503. //:: Special Behavior Functions
  4504. //:: Copyright (c) 2001 Bioware Corp.
  4505. //:://///////////////////////////////////////////////////////////////////////////////////////////
  4506. /*
  4507.     These commands handle the setting and getting of the Behavioral Master
  4508.     If these special behaviors are used they will override the normal behavior expected
  4509.     the animals normal Neutral Faction.
  4510. */
  4511. //:://///////////////////////////////////////////////////////////////////////////////////////////
  4512. //:: Created By: Preston Watamaniuk
  4513. //:: Created On: Dec 10, 2001
  4514. //:://///////////////////////////////////////////////////////////////////////////////////////////
  4515. void SetBehaviorState(int nCondition, int bValid = TRUE)
  4516. {
  4517.     int nPlot = GetLocalInt(OBJECT_SELF, "NW_BEHAVIOR_MASTER");
  4518.     if(bValid == TRUE)
  4519.     {
  4520.         nPlot = nPlot | nCondition;
  4521.         SetLocalInt(OBJECT_SELF, "NW_BEHAVIOR_MASTER", nPlot);
  4522.     }
  4523.     else if (bValid == FALSE)
  4524.     {
  4525.         nPlot = nPlot & ~nCondition;
  4526.         SetLocalInt(OBJECT_SELF, "NW_BEHAVIOR_MASTER", nPlot);
  4527.     }
  4528. }
  4529.  
  4530. int GetBehaviorState(int nCondition)
  4531. {
  4532.     int nPlot = GetLocalInt(OBJECT_SELF, "NW_BEHAVIOR_MASTER");
  4533.     if(nPlot & nCondition)
  4534.     {
  4535.         return TRUE;
  4536.     }
  4537.     return FALSE;
  4538. }
  4539.  
  4540. //::///////////////////////////////////////////////
  4541. //:: Determine Special Behavior
  4542. //:: Copyright (c) 2001 Bioware Corp.
  4543. //:://////////////////////////////////////////////
  4544. /*
  4545.     Determines the special behavior used by the NPC.
  4546.     Generally all NPCs who you want to behave differently
  4547.     than the defualt behavior.
  4548.     For these behaviors, passing in a valid object will
  4549.     cause the creature to become hostile the the attacker.
  4550. */
  4551. //:://////////////////////////////////////////////
  4552. //:: Created By: Preston Watamaniuk
  4553. //:: Created On: Dec 14, 2001
  4554. //:://////////////////////////////////////////////
  4555.  
  4556. void DetermineSpecialBehavior(object oIntruder = OBJECT_INVALID)
  4557. {
  4558.     object oTarget = GetNearestCreature(CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, OBJECT_SELF ,1, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
  4559.     if(GetBehaviorState(NW_FLAG_BEHAVIOR_OMNIVORE))
  4560.     {
  4561.         if(!GetIsObjectValid(oIntruder))
  4562.         {
  4563.             if(!GetIsObjectValid(GetAttemptedAttackTarget()) &&
  4564.                !GetIsObjectValid(GetAttemptedSpellTarget()) &&
  4565.                !GetIsObjectValid(GetAttackTarget()))
  4566.             {
  4567.                 if(GetIsObjectValid(oTarget) && GetDistanceToObject(oTarget) <= 5.0)
  4568.                 {
  4569.                     if(!GetIsFriend(oTarget))
  4570.                     {
  4571.                         if(GetLevelByClass(CLASS_TYPE_DRUID, oTarget) == 0 && GetLevelByClass(CLASS_TYPE_RANGER, oTarget) == 0)
  4572.                         {
  4573.                             SetIsTemporaryEnemy(oTarget, OBJECT_SELF, FALSE, 20.0);
  4574.                             DetermineCombatRound(oTarget);
  4575.                         }
  4576.                     }
  4577.                 }
  4578.             }
  4579.         }
  4580.         else if(!IsInConversation(OBJECT_SELF))
  4581.         {
  4582.             DetermineCombatRound(oIntruder);
  4583.         }
  4584.         else
  4585.         {
  4586.             ClearAllActions();
  4587.             ActionRandomWalk();
  4588.             return;
  4589.         }
  4590.     }
  4591.     else if(GetBehaviorState(NW_FLAG_BEHAVIOR_HERBIVORE))
  4592.     {
  4593.         if(!GetIsObjectValid(GetAttemptedAttackTarget()) &&
  4594.            !GetIsObjectValid(GetAttemptedSpellTarget()) &&
  4595.            !GetIsObjectValid(GetAttackTarget()))
  4596.         {
  4597.             if(GetIsObjectValid(oTarget) && GetDistanceToObject(oTarget) <= 6.0)
  4598.             {
  4599.                 if(!GetIsFriend(oTarget))
  4600.                 {
  4601.                     if(GetLevelByClass(CLASS_TYPE_DRUID, oTarget) == 0 && GetLevelByClass(CLASS_TYPE_RANGER, oTarget) == 0)
  4602.                     {
  4603.                         TalentFlee(oTarget);
  4604.                     }
  4605.                 }
  4606.             }
  4607.         }
  4608.         else if(!IsInConversation(OBJECT_SELF))
  4609.         {
  4610.             ClearAllActions();
  4611.             ActionRandomWalk();
  4612.             return;
  4613.         }
  4614.     }
  4615. }
  4616.  
  4617. //::///////////////////////////////////////////////
  4618. //:: Reset Henchmen
  4619. //:: Copyright (c) 2002 Bioware Corp.
  4620. //:://////////////////////////////////////////////
  4621. /*
  4622.     Sets the henchmen to commandable, deletes locals
  4623.     having to do with doors and clears actions
  4624. */
  4625. //:://////////////////////////////////////////////
  4626. //:: Created By: Preston Watamaniuk
  4627. //:: Created On: April 4, 2002
  4628. //:://////////////////////////////////////////////
  4629.  
  4630. void ResetHenchmenState()
  4631. {
  4632.     SetCommandable(TRUE);
  4633.     DeleteLocalObject(OBJECT_SELF, "NW_GENERIC_DOOR_TO_BASH");
  4634.     DeleteLocalInt(OBJECT_SELF, "NW_GENERIC_DOOR_TO_BASH_HP");
  4635.     SetAssociateState(NW_ASC_IS_BUSY, FALSE);
  4636.     ClearAllActions();
  4637. }
  4638.  
  4639. //::///////////////////////////////////////////////
  4640. //:: Bash Doors
  4641. //:: Copyright (c) 2002 Bioware Corp.
  4642. //:://////////////////////////////////////////////
  4643. /*
  4644.     Used in DetermineCombatRound to keep a
  4645.     henchmen bashing doors.
  4646. */
  4647. //:://////////////////////////////////////////////
  4648. //:: Created By: Preston Watamaniuk
  4649. //:: Created On: April 4, 2002
  4650. //:://////////////////////////////////////////////
  4651.  
  4652. int BashDoorCheck(object oIntruder = OBJECT_INVALID)
  4653. {
  4654.     int bDoor = FALSE;
  4655.     //This code is here to make sure that henchmen keep bashing doors and placables.
  4656.     object oDoor = GetLocalObject(OBJECT_SELF, "NW_GENERIC_DOOR_TO_BASH");
  4657.     if(GetIsObjectValid(oDoor))
  4658.     {
  4659.         int nDoorMax = GetMaxHitPoints(oDoor);
  4660.         int nDoorNow = GetCurrentHitPoints(oDoor);
  4661.         int nCnt = GetLocalInt(OBJECT_SELF,"NW_GENERIC_DOOR_TO_BASH_HP");
  4662.         if(!GetIsObjectValid(GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN))
  4663.            || (!GetIsObjectValid(oIntruder) && !GetIsObjectValid(GetMaster())))
  4664.         {
  4665.             if(GetLocked(oDoor))
  4666.             {
  4667.                 if(nDoorMax == nDoorNow)
  4668.                 {
  4669.                     nCnt++;
  4670.                     SetLocalInt(OBJECT_SELF,"NW_GENERIC_DOOR_TO_BASH_HP", nCnt);
  4671.                 }
  4672.                 if(nCnt <= 0)
  4673.                 {
  4674.                     bDoor = TRUE;
  4675.                     if(GetHasFeat(FEAT_IMPROVED_POWER_ATTACK))
  4676.                     {
  4677.                         ActionUseFeat(FEAT_IMPROVED_POWER_ATTACK, oDoor);
  4678.                     }
  4679.                     else if(GetHasFeat(FEAT_POWER_ATTACK))
  4680.                     {
  4681.                         ActionUseFeat(FEAT_POWER_ATTACK, oDoor);
  4682.                     }
  4683.                     else
  4684.                     {
  4685.                         ActionAttack(oDoor);
  4686.                     }
  4687.                 }
  4688.             }
  4689.         }
  4690.         if(bDoor == FALSE)
  4691.         {
  4692.             PlayVoiceChat(VOICE_CHAT_CUSS);
  4693.             DeleteLocalObject(OBJECT_SELF, "NW_GENERIC_DOOR_TO_BASH");
  4694.             DeleteLocalInt(OBJECT_SELF, "NW_GENERIC_DOOR_TO_BASH_HP");
  4695.         }
  4696.     }
  4697.     return bDoor;
  4698. }
  4699.  
  4700. //::///////////////////////////////////////////////
  4701. //:: Determine Class to Use
  4702. //:: Copyright (c) 2002 Bioware Corp.
  4703. //:://////////////////////////////////////////////
  4704. /*
  4705.     Determines which of a NPCs three classes to
  4706.     use in DetermineCombatRound
  4707. */
  4708. //:://////////////////////////////////////////////
  4709. //:: Created By: Preston Watamaniuk
  4710. //:: Created On: April 4, 2002
  4711. //:://////////////////////////////////////////////
  4712.  
  4713. int DetermineClassToUse()
  4714. {
  4715.     int nClass;
  4716.     int nTotal = GetCharacterLevel(OBJECT_SELF);
  4717.     float fTotal = IntToFloat(nTotal);
  4718.  
  4719.     int nState1 = FloatToInt((IntToFloat(GetLevelByClass(GetClassByPosition(1))) / fTotal) * 100);
  4720.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + GetTag(OBJECT_SELF) + "Class: " + IntToString(GetClassByPosition(1)) + " %" + IntToString(nState1));
  4721.  
  4722.     int nState2 = FloatToInt((IntToFloat(GetLevelByClass(GetClassByPosition(2))) / fTotal) * 100) + nState1;
  4723.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + GetTag(OBJECT_SELF) + "Class: " + IntToString(GetClassByPosition(2)) + " %" + IntToString(nState2));
  4724.  
  4725.     int nState3 = FloatToInt((IntToFloat(GetLevelByClass(GetClassByPosition(3))) / fTotal) * 100) + nState2;
  4726.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + GetTag(OBJECT_SELF) + "Class: " + IntToString(GetClassByPosition(3)) + " %" + IntToString(nState3));
  4727.  
  4728.     int nUseClass = d100();
  4729.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "D100 Roll " + IntToString(nUseClass));
  4730.  
  4731.     if(nUseClass <= nState1)
  4732.     {
  4733.         nClass = GetClassByPosition(1);
  4734.     }
  4735.     else if(nUseClass > nState1 && nUseClass <= nState2)
  4736.     {
  4737.         nClass = GetClassByPosition(2);
  4738.     }
  4739.     else
  4740.     {
  4741.         nClass = GetClassByPosition(3);
  4742.     }
  4743.     MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + GetName(OBJECT_SELF) + " Return Class = " + IntToString(nClass));
  4744.  
  4745.     return nClass;
  4746. }
  4747.  
  4748. //::///////////////////////////////////////////////
  4749. //:: Determine Enemies
  4750. //:: Copyright (c) 2001 Bioware Corp.
  4751. //:://////////////////////////////////////////////
  4752. /*
  4753.     Uses four general categories to determine what
  4754.     kinds of enemies the NPC is facing.
  4755. */
  4756. //:://////////////////////////////////////////////
  4757. //:: Created By: Preston Watamaniuk
  4758. //:: Created On: April 4, 2002
  4759. //:://////////////////////////////////////////////
  4760.  
  4761. struct sEnemies DetermineEnemies()
  4762. {
  4763.     struct sEnemies sEnemyCount;
  4764.     
  4765.     int nCnt = 1;
  4766.     int nClass;
  4767.     int nHD;
  4768.     object oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  4769.     while(GetIsObjectValid(oTarget) && GetDistanceToObject(oTarget) <= 40.0)
  4770.     {
  4771.         nClass = GetClassByPosition(1, oTarget);
  4772.         nHD = GetHitDice(oTarget);
  4773.         if(nClass == CLASS_TYPE_ANIMAL ||
  4774.            nClass == CLASS_TYPE_BARBARIAN ||
  4775.            nClass == CLASS_TYPE_BEAST ||
  4776.            nClass == CLASS_TYPE_COMMONER ||
  4777.            nClass == CLASS_TYPE_CONSTRUCT ||
  4778.            nClass == CLASS_TYPE_ELEMENTAL ||
  4779.            nClass == CLASS_TYPE_FIGHTER ||
  4780.            nClass == CLASS_TYPE_GIANT ||
  4781.            nClass == CLASS_TYPE_HUMANOID ||
  4782.            nClass == CLASS_TYPE_MONSTROUS ||
  4783.            nClass == CLASS_TYPE_PALADIN ||
  4784.            nClass == CLASS_TYPE_RANGER ||
  4785.            nClass == CLASS_TYPE_ROGUE ||
  4786.            nClass == CLASS_TYPE_VERMIN ||
  4787.            nClass == CLASS_TYPE_MONK ||
  4788.            nClass == CLASS_TYPE_SHAPECHANGER)
  4789.         {
  4790.             sEnemyCount.FIGHTERS += 1;
  4791.             sEnemyCount.FIGHTER_LEVELS += nHD;
  4792.         }
  4793.         else if(nClass == CLASS_TYPE_CLERIC ||
  4794.            nClass == CLASS_TYPE_DRUID)
  4795.         {
  4796.             sEnemyCount.CLERICS += 1;
  4797.             sEnemyCount.CLERIC_LEVELS += nHD;
  4798.         }
  4799.         else if(nClass == CLASS_TYPE_BARD ||
  4800.            nClass == CLASS_TYPE_FEY ||
  4801.            nClass == CLASS_TYPE_SORCERER ||
  4802.            nClass == CLASS_TYPE_WIZARD)
  4803.         {
  4804.            sEnemyCount.MAGES += 1;
  4805.            sEnemyCount.MAGE_LEVELS += nHD;
  4806.         }
  4807.         else if(nClass == CLASS_TYPE_ABERRATION ||
  4808.            nClass == CLASS_TYPE_DRAGON ||
  4809.            nClass == CLASS_TYPE_MAGICAL_BEAST ||
  4810.            nClass == CLASS_TYPE_OUTSIDER)
  4811.         {
  4812.            sEnemyCount.MONSTERS += 1;
  4813.            sEnemyCount.MONTERS_LEVELS += nHD;
  4814.         }
  4815.         sEnemyCount.TOTAL += 1;
  4816.         sEnemyCount.TOTAL_LEVELS += nHD;
  4817.         nCnt++;
  4818.         oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
  4819.     }
  4820.     return sEnemyCount;
  4821. }
  4822.  
  4823. //::///////////////////////////////////////////////
  4824. //:: Get Most Dangerious Class
  4825. //:: Copyright (c) 2001 Bioware Corp.
  4826. //:://////////////////////////////////////////////
  4827. /*
  4828.     Use the four archetypes to determine the
  4829.     most dangerous group type facing the NPC
  4830. */
  4831. //:://////////////////////////////////////////////
  4832. //:: Created By: Preston Watamaniuk
  4833. //:: Created On: April 4, 2002
  4834. //:://////////////////////////////////////////////
  4835.  
  4836. string GetMostDangerousClass(struct sEnemies sCount)
  4837. {
  4838.     string sClass;
  4839.     int nFighter = ((sCount.FIGHTER_LEVELS) * 13)/10;
  4840.     //SpeakString(IntToString(nFighter) + " " + IntToString(sCount.CLERIC_LEVELS) + " " + IntToString(sCount.MAGE_LEVELS) + " " + IntToString(sCount.MONTERS_LEVELS));
  4841.  
  4842.     if(nFighter >= sCount.CLERIC_LEVELS)
  4843.     {
  4844.         if(nFighter >= sCount.MAGE_LEVELS)
  4845.         {
  4846.             if(nFighter >= sCount.MONTERS_LEVELS)
  4847.             {
  4848.                 sClass = "FIGHTER";
  4849.             }
  4850.             else
  4851.             {   sClass = "MONSTER";
  4852.  
  4853.             }
  4854.         }
  4855.         else if(sCount.MAGE_LEVELS >= sCount.MONTERS_LEVELS)
  4856.         {
  4857.             sClass = "MAGE";
  4858.         }
  4859.         else
  4860.         {
  4861.             sClass = "MONSTER";
  4862.         }
  4863.     }
  4864.     else if(sCount.CLERIC_LEVELS >= sCount.MAGE_LEVELS)
  4865.     {
  4866.         if(sCount.CLERIC_LEVELS >= sCount.MONTERS_LEVELS)
  4867.         {
  4868.             sClass = "CLERIC";
  4869.         }
  4870.         else
  4871.         {
  4872.             sClass = "MONSTER";
  4873.         }
  4874.     }
  4875.     else if(sCount.MAGE_LEVELS >= sCount.MONTERS_LEVELS)
  4876.     {
  4877.         sClass = "MAGE";
  4878.     }
  4879.     else
  4880.     {
  4881.         sClass = "MONSTER";
  4882.     }
  4883.     return sClass;
  4884. }
  4885.  
  4886. //::///////////////////////////////////////////////
  4887. //:: Protection Matching Functions
  4888. //:: Copyright (c) 2001 Bioware Corp.
  4889. //:://////////////////////////////////////////////
  4890. /*
  4891.     These three functions break protections into
  4892.     3 categories COMBAT, SPELL and ELEMENTAL
  4893. */
  4894. //:://////////////////////////////////////////////
  4895. //:: Created By: Preston Watamaniuk
  4896. //:: Created On: April 4, 2002
  4897. //:://////////////////////////////////////////////
  4898.  
  4899. int GetMatchCompatibility(talent tUse, string sClass, int nType)
  4900. {
  4901.     int bValid;
  4902.     if(nType == NW_TALENT_PROTECT)
  4903.     {
  4904.         if(sClass == "FIGHTER")
  4905.         {
  4906.             if(MatchCombatProtections(tUse))
  4907.             {
  4908.                 bValid = TRUE;
  4909.             }
  4910.         }
  4911.         else if(sClass == "MAGE")
  4912.         {
  4913.             if(MatchSpellProtections(tUse))
  4914.             {
  4915.                 bValid = TRUE;
  4916.             }
  4917.             else if(MatchElementalProtections(tUse))
  4918.             {
  4919.                 bValid = TRUE;
  4920.             }
  4921.         }
  4922.         else if(sClass == "CLERIC" || sClass == "MONSTER")
  4923.         {
  4924.             if(MatchCombatProtections(tUse))
  4925.             {
  4926.                 bValid = TRUE;
  4927.             }
  4928.             else if(MatchElementalProtections(tUse))
  4929.             {
  4930.                 bValid = TRUE;
  4931.             }
  4932.         }
  4933.     }
  4934.  
  4935.     return bValid;
  4936. }
  4937.  
  4938. int MatchCombatProtections(talent tUse)
  4939. {
  4940.     int nIndex = GetIdFromTalent(tUse);
  4941.     
  4942.     if(nIndex == SPELL_PREMONITION ||
  4943.        nIndex == SPELL_ELEMENTAL_SHIELD ||
  4944.        nIndex == SPELL_GREATER_STONESKIN ||
  4945.        nIndex == SPELL_SHADOW_SHIELD ||
  4946.        nIndex == SPELL_ETHEREAL_VISAGE ||
  4947.        nIndex == SPELL_STONESKIN ||
  4948.        nIndex == SPELL_GHOSTLY_VISAGE)
  4949.     {
  4950.         return TRUE;
  4951.     }
  4952.     return FALSE;
  4953. }
  4954.  
  4955. int MatchSpellProtections(talent tUse)
  4956. {
  4957.     int nIndex = GetIdFromTalent(tUse);
  4958.  
  4959.     if(nIndex == SPELL_GREATER_SPELL_MANTLE ||
  4960.        nIndex == SPELL_SPELL_MANTLE ||
  4961.        nIndex == SPELL_LESSER_SPELL_MANTLE ||
  4962.        nIndex == SPELL_SHADOW_SHIELD ||
  4963.        nIndex == SPELL_GLOBE_OF_INVULNERABILITY ||
  4964.        nIndex == SPELL_MINOR_GLOBE_OF_INVULNERABILITY ||
  4965.        nIndex == SPELL_ETHEREAL_VISAGE ||
  4966.        nIndex == SPELL_GHOSTLY_VISAGE ||
  4967.        nIndex == SPELL_SPELL_RESISTANCE ||
  4968.        nIndex == SPELL_PROTECTION_FROM_SPELLS ||
  4969.        nIndex == SPELL_NEGATIVE_ENERGY_PROTECTION)
  4970.     {
  4971.         return TRUE;
  4972.     }
  4973.     return FALSE;
  4974. }
  4975.  
  4976. int MatchElementalProtections(talent tUse)
  4977. {
  4978.     int nIndex = GetIdFromTalent(tUse);
  4979.  
  4980.     if(nIndex == SPELL_ENERGY_BUFFER ||
  4981.        nIndex == SPELL_PROTECTION_FROM_ELEMENTS ||
  4982.        nIndex == SPELL_RESIST_ELEMENTS ||
  4983.        nIndex == SPELL_ENDURE_ELEMENTS)
  4984.     {
  4985.         return TRUE;
  4986.     }
  4987.     return FALSE;
  4988. }
  4989.  
  4990. talent StartProtectionLoop()
  4991. {
  4992.     talent tUse;
  4993.     tUse = GetCreatureTalentRandom(TALENT_CATEGORY_BENEFICIAL_PROTECTION_SELF);
  4994.     if(GetIsTalentValid(tUse))
  4995.     {
  4996.         return tUse;
  4997.     }
  4998.     else
  4999.     {
  5000.         tUse = GetCreatureTalentRandom(TALENT_CATEGORY_BENEFICIAL_PROTECTION_SINGLE);
  5001.         if(GetIsTalentValid(tUse))
  5002.         {
  5003.              return tUse;
  5004.         }
  5005.         else
  5006.         {
  5007.             tUse = GetCreatureTalentRandom(TALENT_CATEGORY_BENEFICIAL_PROTECTION_AREAEFFECT);
  5008.             if(GetIsTalentValid(tUse))
  5009.             {
  5010.                  return tUse;
  5011.             }
  5012.         }
  5013.     }
  5014.     return tUse;
  5015. }
  5016.  
  5017. void DubugPrintTalentID(talent tTalent)
  5018. {
  5019.     //int nID = GetIdFromTalent(tTalent);
  5020.     //MyPrintString("GENERIC SCRIPT DEBUG STRING ********** " + "Using Spell ID: " + IntToString(nID));
  5021. }
  5022. void MyPrintString(string sString)
  5023. {
  5024.     //PrintString(sString);
  5025. }
  5026.  
  5027.