Jaysyn904 04165202c0 Initial upload
Initial upload
2024-11-25 19:36:07 -05:00

446 lines
19 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
// ai_raid_v2 - Version 2.0 of the Raid command for units
// By Deva Bryson Winblood. 03/05/2005
// Modified April 9th, 2009
////////////////////////////////////////////////////////////////////////////////
#include "rts_header"
#include "rts_wp_header"
#include "rts_h_moving"
#include "nw_i0_generic"
#include "consolidate_h"
#include "antistuck_h"
//////////////////////////////
// PROTOTYPES
//////////////////////////////
object fnDetermineNearestPathType(object oMe);
object fnDetermineNextPath(string sID,string sDID,int nMode,int nCurrent);
/////////////////////////////////////////////////////////////////////////// MAIN
void main()
{
object oMe=OBJECT_SELF;
int nSState=GetLocalInt(oMe,"nSState");
object oDest=GetLocalObject(oMe,"oDest");
object oItem;
string sDID=GetLocalString(oMe,"sTeamToRaid");
string sID=GetLocalString(oMe,"sTeamID");
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");
int nMode=GetLocalInt(oMe,"nRaidMode");
int nParm=GetLocalInt(oMe,"nParm");
object oMod=GetModule();
int nRun=GetLocalInt(oMe,"nRun");
object oNearestPathType;
object oH;
int bEnemy=FALSE;
int nN;
string sMsg;
int nC;
int bShouldDeconsolidate=FALSE;
int nLight=GetLocalInt(oMod,GetTag(oMe)+"_light");
if (GetLocalInt(oMod,"bUnitConsolidationOn"))
{ // consolidation is on
if (nSState==1||nSState>3) bShouldDeconsolidate=TRUE;
if (!bShouldDeconsolidate)
{ // test for should be consolidated
nN=GetShouldConsolidate(oMe);
if (nN==FALSE) bShouldDeconsolidate=TRUE;
} // test for should be consolidated
if (bConsolidationLeader&&bShouldDeconsolidate)
{ // deconsolidate
ConsolidateFreeLeader(oMe);
} // deconsolidate
else if (!bShouldDeconsolidate)
{ // consolidate
sMsg=sID+"_HOLDING";
if (GetStringLength(sID)<3) sMsg="NEUTRAL_HOLDING";
Consolidate(oMe,sMsg,"sTeamToRaid",40.0);
} // consolidate
} // consolidation is on
if (oEnemy!=OBJECT_INVALID&&GetStringLength(GetLocalString(oEnemy,"sTeamID"))>0) bEnemy=TRUE;
if (!bEnemy)
{ // enemy not present
if (nMode>0) oNearestPathType=fnDetermineNearestPathType(oMe);
switch(nSState)
{ // main switch
case 0: { // determine type of pathing want
if (GetIsDay()||GetIsDawn())
{ // day time
nN=d4();
if (nN<3) SetLocalInt(oMe,"nRaidMode",2);
else { SetLocalInt(oMe,"nRaidMode",1); }
if (nLight>0) SetLocalInt(oMe,"nRaidMode",2);
} // day time
else
{ // night time
nN=d4();
if (nN==1) SetLocalInt(oMe,"nRaidMode",2);
else { SetLocalInt(oMe,"nRaidMode",1); }
} // night time
if (oNearestPathType!=OBJECT_INVALID) SetLocalInt(oMe,"nSState",2);
else { SetLocalInt(oMe,"nSState",1); }
break;
} // determine type of pathing want
case 1: { // return to the lair
if (oNearestPathType!=OBJECT_INVALID) SetLocalInt(oMe,"nSState",2);
else
{ // return to lair
oDest=GetWaypointByTag(sID+"_START");
if (GetArea(oDest)!=GetArea(oMe))
{ // need to move
oDest=fnPathNextDestination(GetArea(oMe),sID,0);
if (oDest!=OBJECT_INVALID)
{ // move
fnMoveToDestinationB(oMe,oDest,3.0);
} // move
} // need to move
else { SetLocalInt(oMe,"nSState",2); }
} // return to lair
break;
} // return to the lair
case 2: { // pick waypoint
nN=StringToInt(GetStringRight(GetTag(oNearestPathType),1));
if (oNearestPathType==oDestA)
{ // arrived at enemy lair // nParm
if (nParm==0) SetLocalInt(oMe,"nSState",5); // 0 = informative
else if (nParm==1) SetLocalInt(oMe,"nSState",4); // 1 = attack
else if (nParm==2) SetLocalInt(oMe,"nSState",7); // 2 = steal gold
else if (nParm==3) SetLocalInt(oMe,"nSState",6); // 3 = steal mana
} // arrived at enemy lair
else
{ // need to do moving
oDest=fnDetermineNextPath(sID,sDID,nMode,nN);
if (oDest!=OBJECT_INVALID)
{ // path found
SetLocalInt(oMe,"nSState",3);
SetLocalObject(oMe,"oDest",oDest);
} // path found
else
{ // error
AssignCommand(oMe,SpeakString("cannot find path "+sID+","+sDID+","+IntToString(nMode)+","+IntToString(nN)));
} // error
} // need to do moving
break;
} // pick waypoint
case 3: { // move to waypoint
if (GetArea(oMe)!=GetArea(oDest)||GetDistanceBetween(oMe,oDest)>6.0)
{ // move
fnMoveToDestinationB(oMe,oDest,1.0);
} // move
else
{ // arrived
SetLocalInt(oMe,"nSState",2);
} // arrived
break;
} // move to waypoint
case 4: { // raid attack
DeleteLocalInt(oMe,"bDisguised"); // just in case disguised undead
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,d100());
if (oH!=OBJECT_INVALID) AssignCommand(oMe,ASActionMoveToObject(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,d100());
if (oH!=OBJECT_INVALID) AssignCommand(oMe,ASActionMoveToObject(oH,nRun,4.0));
} // seek enemies
} // I am wounded
else
{ // seek enemies
oH=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d100());
if (oH!=OBJECT_INVALID) AssignCommand(oMe,ASActionMoveToObject(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
break;
} // raid attack
case 5: { // informative
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",8);
break;
} // informative
case 6: { // steal gold
SetActionMode(oMe,ACTION_MODE_STEALTH,TRUE);
oDest=GetObjectByTag(sDID+"_CHEST");
if (GetDistanceBetween(oDest,oMe)>4.0)
{ // move
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,ActionMoveToObject(oDest,TRUE,3.0));
} // move
else
{ // steal gold
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_GET_MID,1.0,3.0));
oH=GetItemPossessedBy(oDest,"NW_IT_GOLD001");
if (GetIsObjectValid(oH))
{ // give gold
GiveGoldToCreature(oMe,GetItemStackSize(oH));
DestroyObject(oH);
} // give gold
SetLocalInt(oMe,"nSState",8);
} // steal gold
break;
} // steal gold
case 7: { // steal mana
SetActionMode(oMe,ACTION_MODE_STEALTH,TRUE);
oDest=GetWaypointByTag(sDID+"_VAULT");
if (oDest!=OBJECT_INVALID)
{ // mana vault found
if (GetDistanceBetween(oDest,oMe)>3.0)
{ // move
fnMoveToDestinationB(oMe,oDest,1.0);
} // move
else
{ // pick up mana
oDest=GetNearestObjectByTag("StrongManaPool",oMe,1);
if (oDest==OBJECT_INVALID) oDest=GetNearestObjectByTag("ManaPool",oMe,1);
if (oDest==OBJECT_INVALID) oDest=GetNearestObjectByTag("MinorManaPool",oMe,1);
if (oDest!=OBJECT_INVALID)
{ // steal mana
string sMTag=GetTag(oDest);
string sMRes="mana_crystal_1";
if (sMTag=="StrongManaPool") sMRes="mana_crystal_5";
else if (sMTag=="ManaPool") sMRes="mana_crystal_2";
CreateItemOnObject(sMRes,oMe,1);
DestroyObject(oDest);
SetLocalInt(oMe,"nSState",8);
} // steal mana
else
{ SetLocalInt(oMe,"nSState",8); }
} // pick up mana
} // mana vault found
else
{ // not found
SetLocalInt(oMe,"nParm",0);
SetLocalInt(oMe,"nSState",8);
} // not found
break;
} // steal mana
case 8: { // return to lair
oDest=GetWaypointByTag(sID+"_START");
if (GetArea(oDest)!=GetArea(oMe))
{ // need to move
oDest=fnPathNextDestination(GetArea(oMe),sID,0);
if (oDest!=OBJECT_INVALID)
{ // move
fnMoveToDestinationB(oMe,oDest,3.0);
} // move
} // need to move
else
{ // arrived
if (nParm==0) SetLocalInt(oMe,"nSState",11);
else if (nParm==2) SetLocalInt(oMe,"nSState",10);
else if (nParm==3) SetLocalInt(oMe,"nSState",9);
else { DeleteLocalInt(oMe,"nSState"); }
} // arrived
break;
} // return to lair
case 9: { // go to mana vault
oDest=GetWaypointByTag(sID+"_VAULT");
if (GetDistanceBetween(oMe,oDest)>2.0)
{ // move
fnMoveToDestinationB(oMe,oDest,1.0);
} // move
else
{ // arrived
SetLocalInt(oMe,"nSState",0);
} // arrived
break;
} // go to mana vault
case 10: { // give gold
nN=GetGold(oMe);
oDest=GetObjectByTag(sID+"_CHEST");
if (oDest!=OBJECT_INVALID)
{ // chest exists
if (GetDistanceBetween(oMe,oDest)<3.0)
{ // deposit
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_GET_MID,1.0,3.0));
CreateItemOnObject("nw_it_gold001",oDest,nN);
TakeGoldFromCreature(nN,oMe,TRUE);
SetLocalInt(oMe,"nSState",0);
} // deposit
else
{ // move
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,ActionMoveToObject(oDest,TRUE,2.0));
} // move
} // chest exists
else
{
DeleteLocalInt(oMe,"nSState");
}
break;
} // give gold
case 11: { // deliver message
oDest=GetWaypointByTag(sID+"_START");
if (oDest!=OBJECT_INVALID)
{ // move
if (GetDistanceBetween(oMe,oDest)>2.5)
{ // move
fnMoveToDestinationB(oMe,oDest,1.0);
} // move
else
{ // drop item
oItem=GetLocalObject(oMe,"oMsg");
if (GetItemPossessor(oItem)==oMe) AssignCommand(oMe,ActionPutDownItem(oItem));
else { DeleteLocalInt(oMe,"nSState"); DeleteLocalObject(oMe,"oMsg"); }
} // drop item
} // move
else { DeleteLocalInt(oMe,"nSState"); }
break;
} // deliver message
default: { DeleteLocalInt(oMe,"nSState"); break; }
} // main switch
} // enemy not present
else
{ // enemy is present
if (!GetIsInCombat(oMe))DetermineCombatRound(oEnemy);
DeleteLocalInt(oMe,"nSState");
} // enemy is present
}
/////////////////////////////////////////////////////////////////////////// MAIN
//////////////////////////
// FUNCTIONS
//////////////////////////
object fnDetermineNearestPathType(object oMe)
{ // PURPOSE: To check the nearest waypoints
object oRet=OBJECT_INVALID;
string sID=GetLocalString(oMe,"sTeamID");
string sDID=GetLocalString(oMe,"sTeamToRaid");
int nMode=GetLocalInt(oMe,"nRaidMode");
string sMode="N";
if (nMode==2) sMode="S";
oRet=GetNearestObjectByTag(sDID+"_START",oMe);
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_"+sDID+"_7");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_7");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_"+sDID+"_6");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_6");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_"+sDID+"_5");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_5");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_"+sDID+"_4");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_4");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_"+sDID+"_3");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_3");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_"+sDID+"_2");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_2");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_"+sDID+"_1");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_1");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_"+sDID+"_0");
if (oRet==OBJECT_INVALID) oRet=GetNearestObjectByTag(sID+"_RAID"+sMode+"_0");
return oRet;
} // fnDetermineNearestPathType()
object fnDetermineNextPath(string sID,string sDID,int nMode,int nCurrent)
{ // PURPOSE: return information about the next destination
object oRet=OBJECT_INVALID;
int nN=nCurrent+1;
string sMode="N";
if (nMode==2) sMode="S";
oRet=GetWaypointByTag(sID+"_RAID"+sMode+"_"+sDID+"_"+IntToString(nN));
if (oRet==OBJECT_INVALID) oRet=GetWaypointByTag(sID+"_RAID"+sMode+"_"+IntToString(nN));
return oRet;
} // fnDetermineNextPath()