/////////////////////////////////////////////////////////////////////////////////// // REAL TIME STRATEGY ADVENTURE - Kit // FILE: rtsa_ai_healn // NAME: Heal Nearby Units // SCRIPTED BY: Deva Bryson Winblood // DATE: 7/27/2003 //////////////////////////////////////////////////////////////////////////////// /////////////////// // Prototypes /////////////////// int fnIsUndead(object oCreature); // returns TRUE is has undead classes /////////////////////////////////////////////////////// MAIN //////////////// void main() { object oMe=OBJECT_SELF; object oMod=GetModule(); object oEnemy=GetNearestCreature(CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,OBJECT_SELF,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_IS_ALIVE,TRUE); object oTarg; int nSS=GetLocalInt(oMe,"nSState"); int nFriends; // count of friendly units string sID=GetLocalString(oMe,"sTeamID"); float fDist; int nCHP; int nMHP; float fDHP; object oDest=GetLocalObject(oMe,"oDest"); switch(nSS) { // Heal Nearby Units - Substate Switch case 0: { // assess the situation SetLocalInt(oMe,"nAggression",1); // Peaceful do not engage oTarg=GetNearestCreature(CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,OBJECT_SELF,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND); if (oTarg==OBJECT_INVALID) { // no friends SetLocalInt(oMe,"nSState",6); if (GetAbilityScore(oMe,ABILITY_INTELLIGENCE)>7) AssignCommand(oMe,SpeakString("There is no one nearby for me to heal.")); } // no friends else if(oEnemy!=OBJECT_INVALID&&GetDistanceToObject(oEnemy)<11.0) { // too close move away SetLocalInt(oMe,"nSState",1); } // too close move away else { // check other priorities fDist=GetDistanceToObject(oTarg); // friend if (fDist!=-1.0&&fDist>11.0) ActionMoveToObject(oTarg,TRUE,3.0); oTarg=GetLocalObject(oMod,"oTeamLead"+sID); if (oTarg!=OBJECT_INVALID) { // check to see if PC is nearby fDist=GetDistanceToObject(oTarg); if (fDist!=-1.0&&fDist<20.0) { // check PC nCHP=GetCurrentHitPoints(oTarg); nMHP=GetMaxHitPoints(oTarg); fDHP=(IntToFloat(nCHP)/IntToFloat(nMHP)); if (fDHP<0.51) { // heal the PC SetLocalObject(oMe,"oDest",oTarg); SetLocalInt(oMe,"nSState",2); nSS=2; } // heal the PC } // check PC } // check to see if PC is nearby if (nSS==0) { // keep checking priorities if (fnIsUndead(oEnemy)==TRUE) { // nearby enemy is undead if (GetDistanceToObject(oEnemy)<21.0&&GetHasFeatEffect(FEAT_TURN_UNDEAD,oEnemy)==FALSE) { // turn undead maybe if (GetHasFeat(FEAT_TURN_UNDEAD,oMe)==TRUE) { // turn undead SetLocalInt(oMe,"nSState",5); SetLocalObject(oMe,"oDest",oEnemy); nSS=5; } // turn undead } // turn undead maybe } // nearby enemy is undead if (nSS==0) { // still checking oTarg=GetNearestCreature(CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,OBJECT_SELF,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND,CREATURE_TYPE_IS_ALIVE,FALSE); if (oTarg!=OBJECT_INVALID) { // possible res or raise candidate if (GetChallengeRating(oTarg)>2.9||GetIsPC(oTarg)==TRUE) { // valid target if (GetHasSpell(SPELL_RESURRECTION,oMe)==TRUE) { // res SetLocalInt(oMe,"nSState",3); SetLocalObject(oMe,"oDest",oTarg); } // res else if (GetHasSpell(SPELL_RAISE_DEAD,oMe)==TRUE) { // raise SetLocalInt(oMe,"nSState",4); SetLocalObject(oMe,"oDest",oTarg); } // raise } // valid target } // possible res or raise candidate } // still checking } // keep checking priorities } // check other priorities oTarg=GetWaypointByTag("RTSA_CUSTOM_HEALN"); if (oTarg!=OBJECT_INVALID) // custom script support ExecuteScript(GetName(oTarg),oMe); break; } // assess the situation case 1: { // move away from enemy Priority 1 fDist=GetDistanceToObject(oEnemy); if (fDist!=-1.0&&fDist<11.0) { // move away AssignCommand(oMe,ClearAllActions(TRUE)); AssignCommand(oMe,ActionMoveAwayFromObject(oEnemy,TRUE,15.0)); } // move away else SetLocalInt(oMe,"nSState",0); // assess break; } // move away from enemy Priority 1 case 2: { // heal PC Priority 2 if (GetIsDead(oDest)==TRUE) { // see if can raise dead if (GetHasSpell(SPELL_RESURRECTION,oMe)==TRUE) SetLocalInt(oMe,"nSState",3); else if (GetHasSpell(SPELL_RAISE_DEAD,oMe)==TRUE) SetLocalInt(oMe,"nSState",4); } // see if can raise dead else { // heal spells nCHP=0; if (GetHasSpell(SPELL_HEAL,oMe)==TRUE) nCHP=SPELL_HEAL; else if (GetHasSpell(SPELL_CURE_CRITICAL_WOUNDS,oMe)==TRUE) nCHP=SPELL_CURE_CRITICAL_WOUNDS; else if (GetHasSpell(SPELL_CURE_SERIOUS_WOUNDS,oMe)==TRUE) nCHP=SPELL_CURE_SERIOUS_WOUNDS; else if (GetHasSpell(SPELL_CURE_MODERATE_WOUNDS,oMe)==TRUE) nCHP=SPELL_CURE_MODERATE_WOUNDS; else if (GetHasSpell(SPELL_CURE_LIGHT_WOUNDS,oMe)==TRUE) nCHP=SPELL_CURE_LIGHT_WOUNDS; else if (GetHasSpell(SPELL_CURE_MINOR_WOUNDS,oMe)==TRUE) nCHP=SPELL_CURE_MINOR_WOUNDS; else if (GetHasSpell(SPELL_HEALING_CIRCLE,oMe)==TRUE) nCHP=SPELL_HEALING_CIRCLE; else if (GetHasSpell(SPELL_MASS_HEAL,oMe)==TRUE) nCHP=SPELL_MASS_HEAL; else if (GetHasSpell(SPELL_REGENERATE,oMe)==TRUE) nCHP=SPELL_REGENERATE; if (nCHP!=0) { // has spell AssignCommand(oMe,ClearAllActions(TRUE)); AssignCommand(oMe,ActionCastSpellAtObject(nCHP,oDest)); SetLocalInt(oMe,"nSState",0); } // has spell else { // cannot heal AssignCommand(oMe,ClearAllActions(TRUE)); if (GetAbilityScore(oMe,ABILITY_INTELLIGENCE)>7) AssignCommand(oMe,SpeakString("Alas, I have no more heal spells.")); SetLocalInt(oMe,"nSState",6); } // cannot heal } // heal spells break; } // heal PC Priority 2 case 3: { // ressurrect Priority 4 AssignCommand(oMe,ClearAllActions(TRUE)); AssignCommand(oMe,ActionCastSpellAtObject(SPELL_RESURRECTION,oDest)); SetLocalInt(oMe,"nSState",0); break; } // ressurrect Priority 4 case 4: { // raise dead Priority 5 AssignCommand(oMe,ClearAllActions(TRUE)); AssignCommand(oMe,ActionCastSpellAtObject(SPELL_RAISE_DEAD,oDest)); SetLocalInt(oMe,"nSState",0); break; } // raise dead Priority 5 case 5: { // turn undead Priority 3 AssignCommand(oMe,ClearAllActions(TRUE)); AssignCommand(oMe,ActionUseFeat(FEAT_TURN_UNDEAD,oDest)); SetLocalInt(oMe,"nSState",0); break; } // turn undead Priority 3 case 6: { // all alone - switch back to previous task SetLocalInt(oMe,"nMState",GetLocalInt(oMe,"nPrev")); SetLocalObject(oMe,"oDest",GetLocalObject(oMe,"oPrev")); SetLocalInt(oMe,"nSState",0); SetLocalInt(oMe,"nAggression",GetLocalInt(oMe,"nParm")); break; } // all alone - switch back to previous task case 7: { // custom routine oTarg=GetWaypointByTag("RTSA_CUSTOM_HEALN7"); ExecuteScript(GetName(oTarg),oMe); // custom script support break; } // custom routine } // Heal Nearby Units - Substate Switch } ////////////////// // Functions ////////////////// int fnIsUndead(object oCreature) { // returns TRUE if the creature has undead levels int nRet=FALSE; return nRet; } // fnIsUndead()