556 lines
21 KiB
Plaintext
556 lines
21 KiB
Plaintext
|
//////////////////////////////////////////////////////////////////
|
||
|
// rts_ai_raid - This is the raid AI command set
|
||
|
//----------------------------------------------------------------
|
||
|
// By Deva Bryson Winblood. 12/01/2003
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
#include "rts_wp_header"
|
||
|
#include "rts_header"
|
||
|
|
||
|
void fnBuffUp(); // cast any buffing spells
|
||
|
void fnStealth(); // cast invis or other spells
|
||
|
void fnAntiStuck(); // Why am I standing here up on this roof top?
|
||
|
void fnConsolidate(object oMe,string sID,int nMS,string sTTR);
|
||
|
void fnDeconsolidate(object oMe);
|
||
|
|
||
|
void main()
|
||
|
{
|
||
|
object oMe=OBJECT_SELF;
|
||
|
object oMod=GetModule();
|
||
|
int nState=GetLocalInt(oMe,"nSState");
|
||
|
int nParm=GetLocalInt(oMe,"nParm");
|
||
|
object oH;
|
||
|
object oDest=GetLocalObject(oMe,"oDestWP");
|
||
|
float fDist;
|
||
|
int nHas=GetLocalInt(oMe,"nHasRaidGoods");
|
||
|
string sDID=GetLocalString(oMe,"sTeamToRaid");
|
||
|
string sID=GetLocalString(oMe,"sTeamID");
|
||
|
int nRun=GetLocalInt(oMe,"nRun");
|
||
|
object oLeader=GetLocalObject(oMod,"oTeamLead"+sID);
|
||
|
int nC;
|
||
|
int nMethod=0;
|
||
|
string sMsg;
|
||
|
object oItem;
|
||
|
object oDestA=GetWaypointByTag(sDID+"_START");
|
||
|
object oAlly=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
|
||
|
object oEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
|
||
|
object oFEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY);
|
||
|
object oFPC=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,1,CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC);
|
||
|
int bConsolidationLeader=GetLocalInt(oMe,"bConsolidationLeader");
|
||
|
if ((oFPC==OBJECT_INVALID||GetDistanceBetween(oFPC,oMe)>45.0)&&(oFEnemy==OBJECT_INVALID||GetDistanceBetween(oMe,oFEnemy)>50.0)&&GetArea(oMe)!=GetArea(oDestA))
|
||
|
{ // possibly consolidate forces
|
||
|
fnConsolidate(oMe,sID,GetLocalInt(oMe,"nMState"),sDID);
|
||
|
} // possibly consolidate forces
|
||
|
else if (bConsolidationLeader==TRUE)
|
||
|
{ // deconsolidate forces
|
||
|
fnDeconsolidate(oMe);
|
||
|
} // deconsolidate forces
|
||
|
if (sID=="SPID") nMethod=3;
|
||
|
else if (sID=="DWF") nMethod=2;
|
||
|
else if (sID=="UNC") nMethod=1;
|
||
|
else if (sID=="UND") nMethod=3;
|
||
|
if (GetLocalInt(oMod,GetResRef(oMe)+"_light")==2) nMethod=4; // light fatal
|
||
|
switch(nState)
|
||
|
{ // main switch
|
||
|
case 0: { // initialize raid
|
||
|
SetAILevel(oMe,AI_LEVEL_NORMAL);
|
||
|
SetLocalInt(oMe,"nSState",1);
|
||
|
break;
|
||
|
} // initialize raid
|
||
|
case 1: { // travel to enemy lair
|
||
|
oH=GetObjectByTag(sDID+"_START");
|
||
|
if (GetArea(oH)!=GetArea(oMe))
|
||
|
{ // path
|
||
|
oH=fnPathNextDestination(GetArea(oMe),sDID,nMethod);
|
||
|
if(fDist>0.5||GetArea(oH)!=GetArea(oMe)&&GetCurrentAction(oMe)!=ACTION_MOVETOPOINT)
|
||
|
{ AssignCommand(oMe,ActionMoveToObject(oH,nRun,1.0)); }
|
||
|
} // path
|
||
|
else
|
||
|
{ // arrived
|
||
|
SetLocalInt(oMe,"nSState",2);
|
||
|
} // arrived
|
||
|
fnAntiStuck();
|
||
|
break;
|
||
|
} // travel to enemy lair
|
||
|
case 2: { // at enemy lair
|
||
|
if (nParm==3)
|
||
|
fnBuffUp();
|
||
|
else { fnStealth(); }
|
||
|
if(nParm==0) SetLocalInt(oMe,"nSState",3);
|
||
|
else if (nParm==1) SetLocalInt(oMe,"nSState",4);
|
||
|
else if (nParm==2) SetLocalInt(oMe,"nSState",5);
|
||
|
else if (nParm==3) SetLocalInt(oMe,"nSState",6);
|
||
|
else { SetLocalInt(oMe,"nSState",4); }
|
||
|
fnAntiStuck();
|
||
|
break;
|
||
|
} // at enemy lair
|
||
|
case 3: { // information raid
|
||
|
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_LOOK_FAR,2.0,6.0));
|
||
|
sMsg="I made it to the "+GetName(GetArea(oMe))+" and looked at their units. This is what I noticed";
|
||
|
nC=1;
|
||
|
oH=GetNearestObject(OBJECT_TYPE_CREATURE,oMe,nC);
|
||
|
while (oH!=OBJECT_INVALID)
|
||
|
{ //!OI
|
||
|
sMsg=sMsg+", "+GetName(oH);
|
||
|
nC++;
|
||
|
oH=GetNearestObject(OBJECT_TYPE_CREATURE,oMe,nC);
|
||
|
} //!OI
|
||
|
sMsg=sMsg+". I then left to try to make it back to our lair to report.";
|
||
|
oItem=CreateItemOnObject("rtsa_message",oMe);
|
||
|
oDest=GetLocalObject(oMod,"oTeamLead"+sID);
|
||
|
SetLocalString(oItem,"sMsg",sMsg);
|
||
|
SetLocalObject(oItem,"oDest",GetWaypointByTag(sID+"_START"));
|
||
|
SetLocalString(oItem,"sTo",GetName(oDest));
|
||
|
SetLocalString(oItem,"sName",GetName(oMe));
|
||
|
SetLocalObject(oMe,"oMsg",oItem);
|
||
|
SetLocalInt(oMe,"nSState",10);
|
||
|
fnAntiStuck();
|
||
|
break;
|
||
|
} // information raid
|
||
|
case 4: { // attack raid
|
||
|
if (oEnemy==OBJECT_INVALID)
|
||
|
{ // check for ally to help
|
||
|
if (oAlly!=OBJECT_INVALID)
|
||
|
{ // ally present
|
||
|
if (GetMaxHitPoints(oAlly)>GetCurrentHitPoints(oAlly))
|
||
|
{ // heal
|
||
|
if (GetHasSpell(SPELL_CURE_MINOR_WOUNDS)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_MINOR_WOUNDS,oAlly));
|
||
|
} // cast
|
||
|
else if (GetHasSpell(SPELL_CURE_LIGHT_WOUNDS)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_LIGHT_WOUNDS,oAlly));
|
||
|
} // cast
|
||
|
else if (GetHasSpell(SPELL_CURE_MODERATE_WOUNDS)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_MODERATE_WOUNDS,oAlly));
|
||
|
} // cast
|
||
|
else if (GetHasSpell(SPELL_CURE_SERIOUS_WOUNDS)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_SERIOUS_WOUNDS,oAlly));
|
||
|
} // cast
|
||
|
else if (GetHasSpell(SPELL_CURE_CRITICAL_WOUNDS)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_CRITICAL_WOUNDS,oAlly));
|
||
|
} // cast
|
||
|
else if (GetHasSpell(SPELL_HEAL)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_HEAL,oAlly));
|
||
|
} // cast
|
||
|
else if (GetHasSpell(SPELL_HEALING_CIRCLE)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_HEALING_CIRCLE,oAlly));
|
||
|
} // cast
|
||
|
else
|
||
|
{ // seek enemies
|
||
|
oH=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d20());
|
||
|
if (oH!=OBJECT_INVALID) AssignCommand(oMe,ActionMoveToObject(oH,nRun,4.0));
|
||
|
} // seek enemies
|
||
|
} // heal
|
||
|
else if (GetMaxHitPoints(oMe)>GetCurrentHitPoints(oMe))
|
||
|
{ // I am wounded
|
||
|
if (GetHasSpell(SPELL_CURE_MINOR_WOUNDS)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_MINOR_WOUNDS,oMe));
|
||
|
} // cast
|
||
|
else if (GetHasSpell(SPELL_CURE_LIGHT_WOUNDS)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_LIGHT_WOUNDS,oMe));
|
||
|
} // cast
|
||
|
else if (GetHasSpell(SPELL_CURE_MODERATE_WOUNDS)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_MODERATE_WOUNDS,oMe));
|
||
|
} // cast
|
||
|
else if (GetHasSpell(SPELL_CURE_SERIOUS_WOUNDS)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_SERIOUS_WOUNDS,oMe));
|
||
|
} // cast
|
||
|
else if (GetHasSpell(SPELL_CURE_CRITICAL_WOUNDS)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_CRITICAL_WOUNDS,oMe));
|
||
|
} // cast
|
||
|
else if (GetHasSpell(SPELL_HEAL)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_HEAL,oMe));
|
||
|
} // cast
|
||
|
else if (GetHasSpell(SPELL_HEALING_CIRCLE)>0)
|
||
|
{ // cast
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_HEALING_CIRCLE,oMe));
|
||
|
} // cast
|
||
|
else
|
||
|
{ // seek enemies
|
||
|
oH=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d20());
|
||
|
if (oH!=OBJECT_INVALID) AssignCommand(oMe,ActionMoveToObject(oH,nRun,4.0));
|
||
|
} // seek enemies
|
||
|
} // I am wounded
|
||
|
else
|
||
|
{ // seek enemies
|
||
|
oH=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d20());
|
||
|
if (oH!=OBJECT_INVALID) AssignCommand(oMe,ActionMoveToObject(oH,nRun,4.0));
|
||
|
} // seek enemies
|
||
|
} // ally present
|
||
|
} // check for ally to help
|
||
|
else
|
||
|
{ // enemy present
|
||
|
if (GetRacialType(oEnemy)==RACIAL_TYPE_UNDEAD)
|
||
|
{ // Turn undead
|
||
|
if(GetHasFeat(FEAT_TURN_UNDEAD)==TRUE)
|
||
|
{ // try to turn undead
|
||
|
AssignCommand(oMe,ActionUseFeat(FEAT_TURN_UNDEAD,oMe));
|
||
|
} // try to turn undead
|
||
|
} // Turn Undead
|
||
|
} // enemy present
|
||
|
fnAntiStuck();
|
||
|
break;
|
||
|
} // attack raid
|
||
|
case 5: { // steal mana raid
|
||
|
oH=GetObjectByTag(sDID+"_VAULT");
|
||
|
fDist=GetDistanceBetween(oH,oMe);
|
||
|
if (fDist>5.0&&GetCurrentAction()!=ACTION_MOVETOPOINT)
|
||
|
{ // move
|
||
|
AssignCommand(oMe,ActionMoveToObject(oH,nRun,2.0));
|
||
|
} // move
|
||
|
else
|
||
|
{ // near vault
|
||
|
if (GetObjectType(oDest)==OBJECT_TYPE_ITEM)
|
||
|
{ // have targeted an item
|
||
|
if (GetItemPossessor(oDest)==oMe)
|
||
|
{ // I have the object
|
||
|
SetLocalInt(oMe,"nHasRaidGoods",TRUE);
|
||
|
SetLocalInt(oMe,"nSState",10);
|
||
|
} // I have the object
|
||
|
else if (GetObjectType(GetItemPossessor(oDest))==OBJECT_TYPE_CREATURE)
|
||
|
{ // someone else picked it up
|
||
|
SetLocalObject(oMe,"oDestWP",OBJECT_INVALID); // look for more
|
||
|
} // someone else picked it up
|
||
|
else if (GetDistanceBetween(oDest,oMe)>1.2)
|
||
|
{
|
||
|
if (GetCurrentAction(oMe)!=ACTION_MOVETOPOINT)
|
||
|
AssignCommand(oMe,ActionMoveToObject(oDest,nRun,1.0));
|
||
|
}
|
||
|
else
|
||
|
{ // pick it up
|
||
|
AssignCommand(oMe,ActionPickUpItem(oDest));
|
||
|
} // pick it up
|
||
|
} // have targeted an item
|
||
|
else
|
||
|
{ // find target
|
||
|
oH=GetNearestObjectByTag("MANA_CRYSTAL_5",oMe,1);
|
||
|
if (oH==OBJECT_INVALID) oH=GetNearestObjectByTag("MANA_CRYSTAL_2",oMe,1);
|
||
|
if (oH==OBJECT_INVALID) oH=GetNearestObjectByTag("MANA_CRYSTAL_1",oMe,1);
|
||
|
if (oH==OBJECT_INVALID) SetLocalInt(oMe,"nSState",10); // no mana to steal
|
||
|
if (oH!=OBJECT_INVALID) SetLocalObject(oMe,"oDestWP",oH);
|
||
|
} // find target
|
||
|
} // near vault
|
||
|
fnAntiStuck();
|
||
|
break;
|
||
|
} // steal mana raid
|
||
|
case 6: { // steal gold raid
|
||
|
oH=GetObjectByTag(sDID+"_CHEST");
|
||
|
if (oH==OBJECT_INVALID) oH=GetObjectByTag(sDID+"_TAXES");
|
||
|
fDist=GetDistanceBetween(oH,oMe);
|
||
|
if (fDist>2.0&&GetCurrentAction()!=ACTION_MOVETOPOINT)
|
||
|
{ // move
|
||
|
AssignCommand(oMe,ActionMoveToObject(oH,nRun,1.0));
|
||
|
} // move
|
||
|
else if (fDist<2.0&&GetArea(oH)==GetArea(oMe))
|
||
|
{ // steal from chest
|
||
|
if (GetIsTrapped(oH)==TRUE)
|
||
|
{ // trapped
|
||
|
if (GetHasSkill(SKILL_DISABLE_TRAP,oMe)==TRUE)
|
||
|
{ // disarm
|
||
|
AssignCommand(oMe,ActionUseSkill(SKILL_DISABLE_TRAP,oH));
|
||
|
} // disarm
|
||
|
else
|
||
|
{ // cannot disarm
|
||
|
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW,1.0,3.0));
|
||
|
AssignCommand(oMe,ActionInteractObject(oH));
|
||
|
} // cannot disarm
|
||
|
} // trapped
|
||
|
else
|
||
|
{ // not trapped
|
||
|
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW,1.0,3.0));
|
||
|
AssignCommand(oMe,ActionInteractObject(oH));
|
||
|
oItem=GetFirstItemInInventory(oH);
|
||
|
while(oItem!=OBJECT_INVALID)
|
||
|
{
|
||
|
if (GetResRef(oItem)=="nw_it_gold001")
|
||
|
{ // take gold
|
||
|
SetLocalInt(oMe,"nHasRaidGoods",TRUE);
|
||
|
nC=GetItemStackSize(oItem);
|
||
|
DestroyObject(oItem);
|
||
|
oItem=CreateItemOnObject("nw_it_gold001",oMe,nC);
|
||
|
SetLocalInt(oMe,"nSState",10);
|
||
|
} // take gold
|
||
|
oItem=GetNextItemInInventory(oH);
|
||
|
}
|
||
|
} // not trapped
|
||
|
SetLocalInt(oMe,"nSState",10);
|
||
|
} // steal from chest
|
||
|
fnAntiStuck();
|
||
|
break;
|
||
|
} // steal gold raid
|
||
|
case 10: { // return home
|
||
|
oH=GetObjectByTag(sID+"_START");
|
||
|
if (GetArea(oH)!=GetArea(oMe))
|
||
|
{ // path
|
||
|
oH=fnPathNextDestination(GetArea(oMe),sID,nMethod);
|
||
|
if (GetCurrentAction(oMe)!=ACTION_MOVETOPOINT)
|
||
|
AssignCommand(oMe,ActionMoveToObject(oH,nRun,8.0));
|
||
|
} // path
|
||
|
else
|
||
|
{ // arrived
|
||
|
SetLocalInt(oMe,"nSState",11);
|
||
|
} // arrived
|
||
|
fnAntiStuck();
|
||
|
break;
|
||
|
} // return home
|
||
|
case 11: { // deliveries
|
||
|
if (nParm==0)
|
||
|
{ // message
|
||
|
oItem=GetLocalObject(oMe,"oMsg");
|
||
|
if (GetItemPossessor(oItem)==oMe)
|
||
|
{ // drop it
|
||
|
AssignCommand(oMe,ActionPutDownItem(oItem));
|
||
|
} // drop it
|
||
|
else
|
||
|
{ SetLocalInt(oMe,"nSState",12); DeleteLocalObject(oMe,"oMsg"); }
|
||
|
} // message
|
||
|
else if (nParm==2)
|
||
|
{ // mana
|
||
|
oH=GetObjectByTag(sID+"_VAULT");
|
||
|
oItem=GetLocalObject(oMe,"oDestWP");
|
||
|
fDist=GetDistanceBetween(oH,oMe);
|
||
|
if (fDist>2.0)
|
||
|
{ // move to vault
|
||
|
if (GetCurrentAction()!=ACTION_MOVETOPOINT)
|
||
|
AssignCommand(oMe,ActionMoveToObject(oH,nRun,1.0));
|
||
|
} // move to vault
|
||
|
else
|
||
|
{ // deposit mana
|
||
|
if (GetItemPossessor(oItem)==oMe)
|
||
|
{ // move away and try again
|
||
|
AssignCommand(oMe,ClearAllActions());
|
||
|
AssignCommand(oMe,ActionMoveAwayFromObject(oH,TRUE,8.0));
|
||
|
} // move away and try again
|
||
|
else
|
||
|
{
|
||
|
SendMessageToPC(oLeader,GetName(oMe)+" deposited stolen mana into your mana vault.");
|
||
|
SetLocalInt(oMe,"nSState",12);
|
||
|
}
|
||
|
} // deposit mana
|
||
|
} // mana
|
||
|
else if (nParm==3)
|
||
|
{ // gold
|
||
|
oH=GetObjectByTag(sID+"_CHEST");
|
||
|
nC=GetGold(oMe);
|
||
|
TakeGoldFromCreature(nC,oMe,TRUE);
|
||
|
oItem=CreateItemOnObject("nw_it_gold001",oH,nC);
|
||
|
SendMessageToPC(oLeader,GetName(oMe)+" deposited "+IntToString(nC)+" stolen gold into your tax chest.");
|
||
|
SetLocalInt(oMe,"nSState",12);
|
||
|
} // gold
|
||
|
else
|
||
|
{ //
|
||
|
SetLocalInt(oMe,"nSState",12);
|
||
|
} //
|
||
|
fnAntiStuck();
|
||
|
break;
|
||
|
} // deliveries
|
||
|
case 12: { // done
|
||
|
SetAILevel(oMe,AI_LEVEL_DEFAULT);
|
||
|
SetLocalInt(oMe,"nMState",0);
|
||
|
SetLocalInt(oMe,"nSState",0);
|
||
|
DeleteLocalObject(oMe,"oDestWP");
|
||
|
break;
|
||
|
} // done
|
||
|
default: break;
|
||
|
} // main switch
|
||
|
}
|
||
|
|
||
|
///////////////
|
||
|
// Functions
|
||
|
///////////////
|
||
|
void fnBuffUp()
|
||
|
{ // cast buff spells if have any
|
||
|
object oMe=OBJECT_SELF;
|
||
|
object oAlly=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
|
||
|
object oEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
|
||
|
if (GetHasSpell(SPELL_STONESKIN)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_STONESKIN,oMe));
|
||
|
} //
|
||
|
else if (GetHasSpell(SPELL_BARKSKIN)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_BARKSKIN,oMe));
|
||
|
} //
|
||
|
else if (GetHasSpell(SPELL_GLOBE_OF_INVULNERABILITY)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_GLOBE_OF_INVULNERABILITY,oMe));
|
||
|
} //
|
||
|
else if (GetHasSpell(SPELL_ETHEREAL_VISAGE)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_ETHEREAL_VISAGE,oMe));
|
||
|
} //
|
||
|
else if (GetHasSpell(SPELL_GHOSTLY_VISAGE)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_GHOSTLY_VISAGE,oMe));
|
||
|
} //
|
||
|
else if (GetHasSpell(SPELL_MAGE_ARMOR)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_MAGE_ARMOR,oMe));
|
||
|
} //
|
||
|
if (GetHasSpell(SPELL_SHIELD)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_SHIELD,oMe));
|
||
|
} //
|
||
|
if (GetHasSpell(SPELL_BLESS)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_BLESS,oMe));
|
||
|
} //
|
||
|
// Nearby friends
|
||
|
if (oAlly!=OBJECT_INVALID&&(oEnemy==OBJECT_INVALID||GetDistanceBetween(oEnemy,oMe)>25.0))
|
||
|
{ // buff up ally
|
||
|
if (GetHasSpell(SPELL_BULLS_STRENGTH)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_BULLS_STRENGTH,oAlly));
|
||
|
} //
|
||
|
if (GetCurrentHitPoints(oAlly)<GetMaxHitPoints(oAlly))
|
||
|
{ // heal?
|
||
|
if (GetHasSpell(SPELL_CURE_LIGHT_WOUNDS)>0)
|
||
|
{ // heal
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_LIGHT_WOUNDS,oAlly));
|
||
|
} // heal
|
||
|
else if (GetHasSpell(SPELL_CURE_MODERATE_WOUNDS)>0)
|
||
|
{ // heal
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_MODERATE_WOUNDS,oAlly));
|
||
|
} // heal
|
||
|
else if (GetHasSpell(SPELL_CURE_MINOR_WOUNDS)>0)
|
||
|
{ // heal
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_CURE_MINOR_WOUNDS,oAlly));
|
||
|
} // heal
|
||
|
} // heal?
|
||
|
} // buff up ally
|
||
|
} // cast buff spells if have any
|
||
|
|
||
|
void fnStealth()
|
||
|
{ // cast stealth spells
|
||
|
object oMe=OBJECT_SELF;
|
||
|
object oAlly=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
|
||
|
object oEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
|
||
|
if (GetHasSpell(SPELL_INVISIBILITY_SPHERE)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_INVISIBILITY_SPHERE,oMe));
|
||
|
} //
|
||
|
else if (GetHasSpell(SPELL_IMPROVED_INVISIBILITY)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_IMPROVED_INVISIBILITY,oMe));
|
||
|
} //
|
||
|
else if (GetHasSpell(SPELL_INVISIBILITY)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_INVISIBILITY,oMe));
|
||
|
} //
|
||
|
if (GetHasSpell(SPELL_HASTE)>0)
|
||
|
{ //
|
||
|
AssignCommand(oMe,ActionCastSpellAtObject(SPELL_HASTE,oMe));
|
||
|
} //
|
||
|
} // fnStealth()
|
||
|
|
||
|
void fnAntiStuck()
|
||
|
{ // this function makes sure to get the NPC moving if they have not moved in
|
||
|
// quite awhile
|
||
|
object oMe=OBJECT_SELF;
|
||
|
float fStoredX=GetLocalFloat(oMe,"fStoredX");
|
||
|
float fStoredY=GetLocalFloat(oMe,"fStoredY");
|
||
|
object oWP;
|
||
|
int nSC=GetLocalInt(oMe,"nStuckCount");
|
||
|
vector vPos=GetPosition(oMe);
|
||
|
if (vPos.x!=fStoredX||vPos.y!=fStoredY)
|
||
|
{ // not stuck
|
||
|
SetLocalFloat(oMe,"fStoredX",vPos.x);
|
||
|
SetLocalFloat(oMe,"fStoredY",vPos.y);
|
||
|
DeleteLocalInt(oMe,"nStuckCount");
|
||
|
} // not stuck
|
||
|
else if (vPos.x==fStoredX&&vPos.y==fStoredY)
|
||
|
{ // might be stuck
|
||
|
nSC++;
|
||
|
if (nSC>5)
|
||
|
{ // get unstuck
|
||
|
oWP=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d6());
|
||
|
if (oWP==OBJECT_INVALID) oWP=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d4());
|
||
|
if (oWP==OBJECT_INVALID) oWP=GetNearestObject(OBJECT_TYPE_PLACEABLE,oMe,d4());
|
||
|
if (oWP==OBJECT_INVALID) oWP=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d4());
|
||
|
if (oWP==OBJECT_INVALID)
|
||
|
{ // go home
|
||
|
oWP=GetWaypointByTag(GetLocalString(oMe,"sTeamID")+"_START");
|
||
|
} // go home
|
||
|
if (oWP!=OBJECT_INVALID&&GetIsInCombat(oMe)==FALSE&&IsInConversation(oMe)==FALSE)
|
||
|
{
|
||
|
AssignCommand(oMe,ClearAllActions(TRUE));
|
||
|
AssignCommand(oMe,JumpToObject(oWP));
|
||
|
}
|
||
|
} // get unstuck
|
||
|
else if (GetIsInCombat(oMe)==FALSE)
|
||
|
{
|
||
|
SetLocalInt(oMe,"nStuckCount",nSC);
|
||
|
}
|
||
|
else
|
||
|
{ // not stuck because, in combat
|
||
|
DeleteLocalInt(oMe,"nStuckCount");
|
||
|
} // not stuck because, in combat
|
||
|
} // might be stuck
|
||
|
} // fnAntiStuck()
|
||
|
|
||
|
void fnConsolidate(object oMe,string sID,int nMS,string sTTR)
|
||
|
{ // consolidate
|
||
|
object oCL=GetWaypointByTag(sID+"_HOLDING");
|
||
|
int nC=1;
|
||
|
int nCD=0;
|
||
|
object oF=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,nC,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND);
|
||
|
float fDist=GetDistanceBetween(oMe,oF);
|
||
|
int nSS;
|
||
|
int nMS;
|
||
|
string sDID;
|
||
|
while(oF!=OBJECT_INVALID&&fDist<70.0)
|
||
|
{ // look at friends within 40 meters
|
||
|
nSS=GetLocalInt(oF,"nSState");
|
||
|
nMS=GetLocalInt(oF,"nMState");
|
||
|
sDID=GetLocalString(oF,"sTeamToRaid");
|
||
|
if (GetLocalInt(oF,"bConsolidationLeader")==FALSE)
|
||
|
{ // not a consolidation leader
|
||
|
if (nMS==17&&nSS<3&&sDID==sTTR&&GetStringLength(sDID)>0)
|
||
|
{ // consolidate this unit
|
||
|
AssignCommand(oF,ClearAllActions(TRUE));
|
||
|
SetLocalInt(oF,"nSState",0);
|
||
|
AssignCommand(oF,JumpToObject(oCL));
|
||
|
DelayCommand(2.0,SetAILevel(oF,AI_LEVEL_VERY_LOW));
|
||
|
DelayCommand(2.5,SetCommandable(FALSE,oF));
|
||
|
SetLocalObject(oF,"oConsolidationLeader",oMe);
|
||
|
nCD++;
|
||
|
SetLocalObject(oMe,"oConsolidated"+IntToString(nCD),oF);
|
||
|
} // consolidate this unit
|
||
|
} // not a consolidation leader
|
||
|
nC++;
|
||
|
oF=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,nC,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND);
|
||
|
fDist=GetDistanceBetween(oMe,oF);
|
||
|
} // look at friends within 40 meters
|
||
|
if (nCD>0) SetLocalInt(oMe,"bConsolidationLeader",TRUE);
|
||
|
} // fnConsolidate()
|
||
|
|
||
|
void fnDeconsolidate(object oMe)
|
||
|
{ // deconsolidate
|
||
|
int nC=1;
|
||
|
object oF=GetLocalObject(oMe,"oConsolidated"+IntToString(nC));
|
||
|
while(oF!=OBJECT_INVALID)
|
||
|
{ // bring consolidated forces back out
|
||
|
SetCommandable(TRUE,oF);
|
||
|
SetAILevel(oF,AI_LEVEL_NORMAL);
|
||
|
DelayCommand(0.1,AssignCommand(oF,ClearAllActions()));
|
||
|
DelayCommand(0.2,AssignCommand(oF,JumpToObject(oMe)));
|
||
|
SetLocalInt(oF,"nSState",0);
|
||
|
DeleteLocalObject(oMe,"oConsolidated"+IntToString(nC));
|
||
|
nC++;
|
||
|
oF=GetLocalObject(oMe,"oConsolidated"+IntToString(nC));
|
||
|
} // bring consolidated forces back out
|
||
|
DeleteLocalInt(oMe,"bConsolidationLeader");
|
||
|
} // fnDeconsolidate()
|