HoS_PRC8/_mod/_module/nss/slaver_and_slave.nss
Jaysyn904 04165202c0 Initial upload
Initial upload
2024-11-25 19:36:07 -05:00

925 lines
40 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
// Slaver and slaves - AI Routines for movement, camping, etc.
// By Deva Bryson Winblood. 12/28/2003
////////////////////////////////////////////////////////////////////////////////
#include "prc_inc_racial"
//////////////////////////
// PROTOTYPES
//////////////////////////
#include "antistuck_h"
void fnDespawn(object oCr); // despawn creatures if not talking or in combat
void fnCheckHealSelf(object oCr); // if hurt bad heal yourself
void fnSorceressDefense(object oTarg); // deal with danger to caravan master
void fnGuardFollow(object oMaster,float fDist=5.0); // follow routine for slaver guards
void fnDespawnIfNoSlavers(); // for campfire and cage
int fnClosestTransition(object oDest,object oSCM); // use closest transition
void fnRelaunch(int nCompare)
{
if (GetLocalInt(GetModule(),"nSlaverLaunch")==nCompare) ExecuteScript("slaver_and_slave",OBJECT_SELF);
} // recall program
/////////////////////////////////////////////////////////////// MAIN ///////////
void main()
{
object oMod=GetModule();
object oSCM=GetLocalObject(oMod,"oSCM");
object oSG1=GetLocalObject(oMod,"oSG1");
object oSG2=GetLocalObject(oMod,"oSG2");
object oSG3=GetLocalObject(oMod,"oSG3");
object oSG4=GetLocalObject(oMod,"oSG4");
object oSSO=GetLocalObject(oMod,"oSSO");
object oSIL=GetLocalObject(oMod,"oSIL");
object oSFire;
object oSlave;
object oDest=GetLocalObject(oMod,"oSlaverDest");
int nSLAVEC=GetLocalInt(oMod,"nSLAVEC");
int nSlaverPower=GetLocalInt(oMod,"nSlaverPower");
int nSState=GetLocalInt(oMod,"nSlaverState");
int nSDestNum=GetLocalInt(oMod,"nSlaverDestNum");
int nSHuntNum=GetLocalInt(oMod,"nSlaverHuntNum");
int nSpeed=GetLocalInt(oMod,"nSlaverSpeed");
int nC;
int nR;
int nP;
int nSNS=GetLocalInt(oMod,"nSlaverLaunch");
float fDist;
float fLDist=GetLocalFloat(oMod,"fSlaverLDist");
object oDistTest=GetLocalObject(oMod,"oSlaverDistTest");
object oTarg;
object oWP=GetWaypointByTag("SLAVER_SPAWN");
float fClosest=GetLocalFloat(oMod,"fSlaverClosest");
int nDisableNonEssential=GetLocalInt(oMod,"nDisableNonEssential");
if (nDisableNonEssential!=TRUE)
{ // it is not disabled
nC=GetCalendarDay();
if (oSCM!=OBJECT_INVALID&&GetIsDead(oSCM)!=TRUE)
{ // caravan master still lives
SetLocalInt(oMod,"nSLVDay",nC);
nC=FALSE; // in combat/conversation
if (GetIsInCombat(oSCM)==TRUE||IsInConversation(oSCM)==TRUE) nC=TRUE;
if (GetIsInCombat(oSG1)==TRUE||IsInConversation(oSG1)==TRUE) nC=TRUE;
if (GetIsInCombat(oSG2)==TRUE||IsInConversation(oSG2)==TRUE) nC=TRUE;
if (GetIsInCombat(oSG3)==TRUE||IsInConversation(oSG3)==TRUE) nC=TRUE;
if (GetIsInCombat(oSG4)==TRUE||IsInConversation(oSG4)==TRUE) nC=TRUE;
if (GetIsInCombat(oSSO)==TRUE||IsInConversation(oSSO)==TRUE) nC=TRUE;
if (GetIsInCombat(oSIL)==TRUE||IsInConversation(oSIL)==TRUE) nC=TRUE;
if (nC!=TRUE)
{ // not in conversation or combat
switch(nSState)
{ // Main slaver caravan switch
case 0: { // initialize
SetLocalInt(oMod,"nSlaverState",1);
SetLocalInt(oMod,"nSlaverSpeed",0);
break;
} // initialize
case 1: { // pick next SLAVER_# destination
nSDestNum++;
oWP=GetWaypointByTag("SLAVER_"+IntToString(nSDestNum));
SetLocalFloat(oMod,"fSlaverClosest",999.0);
while(oWP==OBJECT_INVALID&&nSDestNum<40)
{ // OI
nSDestNum++;
oWP=GetWaypointByTag("SLAVER_"+IntToString(nSDestNum));
} // OI
if (oWP!=OBJECT_INVALID&&GetArea(oWP)==GetArea(oSCM))
{ // target found
SetLocalObject(oMod,"oSlaverDest",oWP);
SetLocalInt(oMod,"nSlaverState",2);
SetLocalInt(oMod,"nSlaverDestNum",nSDestNum);
AssignCommand(oSCM,ASActionMoveToObject(oWP,FALSE,1.0));
} // target found
else if (oWP!=OBJECT_INVALID)
{ // different areas
SetLocalObject(oMod,"oSlaverDest",oWP);
SetLocalInt(oMod,"nSlaverState",11);
SetLocalInt(oMod,"nSlaverDestNum",nSDestNum);
nSpeed=1;
} // different areas
else
{ //
AssignCommand(oSCM,SpeakString("I am broken!! Slaver destinations not working!"));
SetLocalInt(oMod,"nSlaverState",10);
} //
break;
} // pick next SLAVER_# destination
case 2: { // move to destination with anti-stuck
if (GetArea(oDest)==GetArea(oSCM))
{ // same area movement
fDist=GetDistanceBetween(oSCM,oDest);
if (fDist<=2.0)
{ // arrived
SetLocalInt(oMod,"nSlaverState",3);
AssignCommand(oSCM,SetFacing(GetFacing(oDest)));
SetLocalInt(oMod,"nSlaverASC",0);
} // arrived
else
{ // move
AssignCommand(oSCM,ASActionMoveToObject(oDest,FALSE,1.0));
} // move
SetLocalFloat(oMod,"fSlaverLDist",fDist);
} // same area movement
else
{ // moving to another area
if(oDistTest==OBJECT_INVALID)
{ // find arbitrary nearby object for distance comparisons
oDistTest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oSCM,d20());
if (oDistTest==OBJECT_INVALID) oDistTest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oSCM,1);
SetLocalObject(oMod,"oSlaverDistTest",oDistTest);
} // find arbitrary nearby object for distance comparisons
fDist=GetDistanceBetween(oDistTest,oSCM);
AssignCommand(oSCM,ASActionMoveToObject(oDest,FALSE,1.0));
SetLocalFloat(oMod,"fSlaverLDist",fDist);
} // moving to another area
break;
} // move to destination with anti-stuck
case 3: { // arrived at and interpret destination
if (GetName(oDest)=="END")
{ SetLocalInt(oMod,"nSlaverState",10); }
else if (GetName(oDest)=="CAMP")
{ SetLocalInt(oMod,"nSlaverState",4); }
else if (GetName(oDest)=="HUNT")
{ SetLocalInt(oMod,"nSlaverState",7); }
else { SetLocalInt(oMod,"nSlaverState",1); }
nSpeed=2;
break;
} // arrived at and interpret destination
case 4: { // setup camp
oWP=GetNearestObjectByTag("SLAVER_FIRE",oSCM,1);
oSFire=CreateObject(OBJECT_TYPE_PLACEABLE,"plc_campfrwpot",GetLocation(oWP));
SetLocalObject(oSFire,"oMaster",oSCM);
AssignCommand(oSFire,fnDespawnIfNoSlavers());
oWP=GetNearestObjectByTag("SLAVER_CAGE",oSCM,1);
oSFire=CreateObject(OBJECT_TYPE_PLACEABLE,"cage",GetLocation(oWP));
AssignCommand(oSFire,fnDespawnIfNoSlavers());
SetLocalObject(oSFire,"oMaster",oSCM);
oWP=GetNearestObjectByTag("SLAVER_GUARD1",oSCM,1);
if (oSG1!=OBJECT_INVALID) { AssignCommand(oSG1,ClearAllActions()); AssignCommand(oSG1,ASActionMoveToObject(oWP,TRUE,1.0)); SetLocalInt(oSG1,"nMode",1); }
oWP=GetNearestObjectByTag("SLAVER_GUARD2",oSCM,1);
if (oSG2!=OBJECT_INVALID) { AssignCommand(oSG2,ClearAllActions()); AssignCommand(oSG2,ASActionMoveToObject(oWP,TRUE,1.0)); SetLocalInt(oSG2,"nMode",1); }
oWP=GetNearestObjectByTag("SLAVER_GUARD3",oSCM,1);
if (oSG3!=OBJECT_INVALID) { AssignCommand(oSG3,ClearAllActions()); AssignCommand(oSG3,ASActionMoveToObject(oWP,TRUE,1.0)); SetLocalInt(oSG3,"nMode",1); }
oWP=GetNearestObjectByTag("SLAVER_GUARD4",oSCM,1);
if (oSG4!=OBJECT_INVALID) { AssignCommand(oSG4,ClearAllActions()); AssignCommand(oSG4,ASActionMoveToObject(oWP,TRUE,1.0)); SetLocalInt(oSG4,"nMode",1); }
nC=0;
oWP=GetNearestObjectByTag("SLAVER_CAGE",oSCM,1);
while(nC<nSLAVEC)
{ // move slaves into cage
nC++;
oSlave=GetLocalObject(oMod,"oSLAVE"+IntToString(nC));
if (oSlave!=OBJECT_INVALID) { AssignCommand(oSlave,ClearAllActions()); AssignCommand(oSlave,JumpToObject(oWP)); SetLocalInt(oSlave,"nMode",1); }
} // move slaves into cage
SetLocalInt(oMod,"nSlaverState",5);
DelayCommand(HoursToSeconds(4),SetLocalInt(oMod,"nSlaverState",6));
break;
} // setup camp
case 5: { // camping
break;
} // camping
case 6: { // take down camp
oDest=GetNearestObjectByTag("Cage",oSCM,1); // cage
DestroyObject(oDest);
oDest=GetNearestObjectByTag("CampfireCauldron",oSCM,1); // campfire
DestroyObject(oDest);
if (oSG1!=OBJECT_INVALID) SetLocalInt(oSG1,"nMode",0);
if (oSG2!=OBJECT_INVALID) SetLocalInt(oSG2,"nMode",0);
if (oSG3!=OBJECT_INVALID) SetLocalInt(oSG3,"nMode",0);
if (oSG4!=OBJECT_INVALID) SetLocalInt(oSG4,"nMode",0);
nC=0;
while(nC<nSLAVEC)
{ // make slaves follow again
nC++;
oDest=GetLocalObject(oMod,"oSLAVE"+IntToString(nC));
if (oDest!=OBJECT_INVALID) SetLocalInt(oDest,"nMode",0);
} // make slaves follow again
SetLocalInt(oMod,"nSlaverState",1);
break;
} // take down camp
case 7: { // pick hunt destination
nSHuntNum++;
oWP=GetNearestObjectByTag("SLAVER_HUNT"+IntToString(nSHuntNum),oSCM,1);
SetLocalFloat(oMod,"fSlaverClosest",999.0);
if (oWP!=OBJECT_INVALID)
{ // target found
SetLocalObject(oMod,"oSlaverDest",oWP);
SetLocalInt(oMod,"nSlaverState",8);
SetLocalInt(oMod,"nSlaverHuntNum",nSHuntNum);
} // target found
else
{ //
SetLocalInt(oMod,"nSlaverState",1); // done hunting
} //
break;
} // pick hunt destination
case 8: { // move to hunt destination
if (GetArea(oDest)==GetArea(oSCM))
{ // same area movement
fDist=GetDistanceBetween(oSCM,oDest);
if (fDist<=2.0)
{ // arrived
SetLocalInt(oMod,"nSlaverState",9);
AssignCommand(oSCM,SetFacing(GetFacing(oDest)));
SetLocalInt(oMod,"nSlaverASC",0);
} // arrived
else
{ // move
AssignCommand(oSCM,ASActionMoveToObject(oDest,FALSE,1.0));
} // move
SetLocalFloat(oMod,"fSlaverLDist",fDist);
} // same area movement
else
{ // moving to another area
if(oDistTest==OBJECT_INVALID)
{ // find arbitrary nearby object for distance comparisons
oDistTest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oSCM,d20());
if (oDistTest==OBJECT_INVALID) oDistTest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oSCM,1);
SetLocalObject(oMod,"oSlaverDistTest",oDistTest);
} // find arbitrary nearby object for distance comparisons
fDist=GetDistanceBetween(oDistTest,oSCM);
AssignCommand(oSCM,ActionMoveToObject(oDest,FALSE,1.0));
SetLocalFloat(oMod,"fSlaverLDist",fDist);
} // moving to another area
break;
} // move to hunt destination
case 9: { // arrived at hunt destination look for nearby potential slaves
if (nSLAVEC>4)
{ // have plenty of slaves
SetLocalInt(oMod,"nSlaverState",1);
} // have plenty of slaves
else
{ // hunt
nC=1;
oWP=GetWaypointByTag("DWF_RESOURCES");
oDest=CreateObject(OBJECT_TYPE_CREATURE,"mancommon",GetLocation(oWP));
oWP=OBJECT_INVALID;
oTarg=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oSCM,nC,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_NEUTRAL,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
while(oWP==OBJECT_INVALID&&oTarg!=OBJECT_INVALID)
{ // !OI
if(GetFactionEqual(oTarg,oDest)==TRUE) oWP=oTarg;
nC++;
oTarg=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oSCM,nC,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_NEUTRAL,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
} // !OI
if (oWP==OBJECT_INVALID)
{ // check enemy types
nC=1;
oTarg=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oSCM,nC,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
while(oWP==OBJECT_INVALID&&oTarg!=OBJECT_INVALID)
{ // !OI
if(GetFactionEqual(oTarg,oDest)==TRUE) oWP=oTarg;
nC++;
oTarg=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oSCM,nC,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
} // !OI
} // check enemy types
DestroyObject(oDest);
if (oWP!=OBJECT_INVALID)
{ // have a target
nC=0;
if (oSG1!=OBJECT_INVALID) { AssignCommand(oSG1,ClearAllActions()); AssignCommand(oSG1,ActionAttack(oWP)); nC++;}
if (oSG2!=OBJECT_INVALID) { AssignCommand(oSG2,ClearAllActions()); AssignCommand(oSG2,ActionAttack(oWP)); nC++;}
if (oSG3!=OBJECT_INVALID) { AssignCommand(oSG3,ClearAllActions()); AssignCommand(oSG3,ActionAttack(oWP)); nC++;}
if (oSG4!=OBJECT_INVALID) { AssignCommand(oSG4,ClearAllActions()); AssignCommand(oSG4,ActionAttack(oWP)); nC++;}
if (oSSO!=OBJECT_INVALID) { AssignCommand(oSSO,ClearAllActions()); AssignCommand(oSSO,ActionAttack(oWP)); nC++;}
if (oSIL!=OBJECT_INVALID) { AssignCommand(oSIL,ClearAllActions()); AssignCommand(oSIL,ActionAttack(oWP)); nC++;}
if (nC<2) {AssignCommand(oSCM,ClearAllActions()); AssignCommand(oSCM,ActionAttack(oWP)); }
} // have a target
else
{ // nothing left to hunt
SetLocalInt(oMod,"nSlaverState",7);
} // nothing left to hunt
} // hunt
break;
} // arrived at hunt destination look for nearby potential slaves
case 10: { // disband slave caravan
if (oSCM!=OBJECT_INVALID) fnDespawn(oSCM);
if (oSG1!=OBJECT_INVALID) fnDespawn(oSG1);
if (oSG2!=OBJECT_INVALID) fnDespawn(oSG2);
if (oSG3!=OBJECT_INVALID) fnDespawn(oSG3);
if (oSG4!=OBJECT_INVALID) fnDespawn(oSG4);
if (oSSO!=OBJECT_INVALID) fnDespawn(oSSO);
if (oSIL!=OBJECT_INVALID) fnDespawn(oSIL);
nR=GetLocalInt(oMod,"nSLAVEC");
nC=1;
nP=0;
while(nC<=nR)
{ // despawn the slaves
oTarg=GetLocalObject(oMod,"oSLAVE"+IntToString(nC));
if (oTarg!=OBJECT_INVALID) { fnDespawn(oTarg); nP++; }
nC++;
} // despawn the slaves
nC=GetLocalInt(oMod,"nSlaverPower");
nC=nC+(nP*2);
SetLocalInt(oMod,"nSlaverPower",nC);
SetLocalInt(oMod,"nSLAVEC",0);
SetLocalInt(oMod,"nSlaverState",0);
SetLocalInt(oMod,"nSlaverDestNum",0);
SetLocalInt(oMod,"nSlaverHuntNum",0);
SetLocalInt(oMod,"nSlaverSpeed",36);
nSpeed=36;
break;
} // disband slave caravan
case 11: { // look for nearest area transition
nC=fnClosestTransition(oDest,oSCM);
if (nC==TRUE)
{
SetLocalInt(oMod,"nSlaverState",2);
AssignCommand(oSCM,ClearAllActions());
AssignCommand(oSCM,ASActionMoveToObject(oDest,FALSE,1.0));
}
nSpeed=4;
break;
} // look for nearest area transition
} // Main slaver caravan switch
} // not in conversation or combate
else
{ // conversation or combat
if (GetIsInCombat(oSCM)==TRUE)
{ // keep caravan master protected
oTarg=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oSCM,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY);
if (GetDistanceBetween(oTarg,oSCM)<10.0)
{ // move away
AssignCommand(oSCM,ClearAllActions(TRUE));
AssignCommand(oSCM,ActionMoveAwayFromObject(oTarg,TRUE,15.0));
nSpeed=6;
// look for nearby guards not engaged in combat
if (oSG1!=OBJECT_INVALID&&GetIsInCombat(oSG1)!=TRUE)
{ // move this guard to intercept nearest enemy
AssignCommand(oSG1,ClearAllActions());
AssignCommand(oSG1,ASActionMoveToObject(oTarg,TRUE,3.0));
AssignCommand(oSG1,ActionAttack(oTarg));
AssignCommand(oSG1,SpeakString("Protect the caravan master!"));
} // move this guard to intercept nearest enemy
if (oSG2!=OBJECT_INVALID&&GetIsInCombat(oSG1)!=TRUE)
{ // move this guard to intercept nearest enemy
AssignCommand(oSG2,ClearAllActions());
AssignCommand(oSG2,ASActionMoveToObject(oTarg,TRUE,3.0));
AssignCommand(oSG2,ActionAttack(oTarg));
AssignCommand(oSG2,SpeakString("Protect the caravan master!"));
} // move this guard to intercept nearest enemy
if (oSG3!=OBJECT_INVALID&&GetIsInCombat(oSG1)!=TRUE)
{ // move this guard to intercept nearest enemy
AssignCommand(oSG3,ClearAllActions());
AssignCommand(oSG3,ASActionMoveToObject(oTarg,TRUE,3.0));
AssignCommand(oSG3,ActionAttack(oTarg));
AssignCommand(oSG3,SpeakString("Protect the caravan master!"));
} // move this guard to intercept nearest enemy
if (oSG4!=OBJECT_INVALID&&GetIsInCombat(oSG1)!=TRUE)
{ // move this guard to intercept nearest enemy
AssignCommand(oSG4,ClearAllActions());
AssignCommand(oSG4,ASActionMoveToObject(oTarg,TRUE,3.0));
AssignCommand(oSG4,ActionAttack(oTarg));
AssignCommand(oSG4,SpeakString("Protect the caravan master!"));
} // move this guard to intercept nearest enemy
if (oSSO!=OBJECT_INVALID&&GetIsInCombat(oSSO)!=TRUE)
{ // move this guard to intercept nearest enemy
AssignCommand(oSSO,ClearAllActions());
AssignCommand(oSSO,SpeakString("Those that attack the caravan master are mine to kill!"));
AssignCommand(oSSO,fnSorceressDefense(oTarg));
} // move this guard to intercept nearest enemy
} // Move Away
fnCheckHealSelf(oSCM);
} // keep caravan master protected
} // conversation or combat
} // caravan master still lives
else
{ // caravan master is either dead or does not exist
nC=FALSE;
if (oSG1!=OBJECT_INVALID||oSG2!=OBJECT_INVALID||oSG3!=OBJECT_INVALID||oSG4!=OBJECT_INVALID) nC=TRUE;
if (oSSO!=OBJECT_INVALID||oSIL!=OBJECT_INVALID) nC=TRUE;
if (nC==TRUE)
{ // remenants of a caravan still exists
if (oSG1!=OBJECT_INVALID) fnDespawn(oSG1);
if (oSG2!=OBJECT_INVALID) fnDespawn(oSG2);
if (oSG3!=OBJECT_INVALID) fnDespawn(oSG3);
if (oSG4!=OBJECT_INVALID) fnDespawn(oSG4);
if (oSSO!=OBJECT_INVALID) fnDespawn(oSSO);
if (oSIL!=OBJECT_INVALID) fnDespawn(oSIL);
SetLocalInt(oMod,"nSlaverState",0);
SetLocalInt(oMod,"nSLAVEC",0);
} // remenants of a caravan still exists
else
{ // create a new caravan
SetLocalInt(oMod,"nSlaverState",0);
SetLocalInt(oMod,"nSLAVEC",0);
SetLocalObject(oMod,"oSlaverDest",OBJECT_INVALID);
SetLocalObject(oMod,"oSlaverDistTest",OBJECT_INVALID);
SetLocalInt(oMod,"nSlaverDestNum",0);
SetLocalInt(oMod,"nSlaverHuntNum",0);
SetLocalFloat(oMod,"fSlaverLDist",0.0);
oSCM=CreateObject(OBJECT_TYPE_CREATURE,"slv",GetLocation(oWP));
SetLocalObject(oMod,"oSCM",oSCM);
SetAILevel(oSCM,AI_LEVEL_NORMAL);
SetLocalInt(oMod,"nSlaverSpeed",0);
if (nSlaverPower<21)
{ // less than 21
oSG1=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG1",oSG1);
SetAILevel(oSG1,AI_LEVEL_NORMAL);
AssignCommand(oSG1,fnGuardFollow(oSCM));
SetLocalInt(oSG1,"nMode",0);
oSG2=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG2",oSG2);
SetAILevel(oSG2,AI_LEVEL_NORMAL);
AssignCommand(oSG2,fnGuardFollow(oSCM));
SetLocalInt(oSG2,"nMode",0);
oSG3=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG3",oSG3);
SetAILevel(oSG3,AI_LEVEL_NORMAL);
AssignCommand(oSG3,fnGuardFollow(oSCM));
SetLocalInt(oSG3,"nMode",0);
oSG4=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG4",oSG4);
SetAILevel(oSG4,AI_LEVEL_NORMAL);
AssignCommand(oSG4,fnGuardFollow(oSCM));
SetLocalInt(oSG4,"nMode",0);
} // less than 21
else if (nSlaverPower<41)
{ // less than 41
oSG1=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG1",oSG1);
SetAILevel(oSG1,AI_LEVEL_NORMAL);
AssignCommand(oSG1,fnGuardFollow(oSCM));
SetLocalInt(oSG1,"nMode",0);
oSG2=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG2",oSG2);
SetAILevel(oSG2,AI_LEVEL_NORMAL);
AssignCommand(oSG2,fnGuardFollow(oSCM));
SetLocalInt(oSG2,"nMode",0);
oSG3=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG3",oSG3);
SetAILevel(oSG3,AI_LEVEL_NORMAL);
AssignCommand(oSG3,fnGuardFollow(oSCM));
SetLocalInt(oSG3,"nMode",0);
oSG4=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG4",oSG4);
SetAILevel(oSG4,AI_LEVEL_NORMAL);
AssignCommand(oSG4,fnGuardFollow(oSCM));
SetLocalInt(oSG4,"nMode",0);
oSSO=CreateObject(OBJECT_TYPE_CREATURE,"slvg2",GetLocation(oWP));
SetLocalObject(oMod,"oSSO",oSSO);
SetAILevel(oSSO,AI_LEVEL_NORMAL);
AssignCommand(oSSO,fnGuardFollow(oSCM,3.0));
SetLocalInt(oSSO,"nMode",0);
} // less than 41
else if (nSlaverPower<61)
{ // less than 61
oSG1=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG1",oSG1);
SetAILevel(oSG1,AI_LEVEL_NORMAL);
AssignCommand(oSG1,fnGuardFollow(oSCM));
SetLocalInt(oSG1,"nMode",0);
oSG2=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG2",oSG2);
SetAILevel(oSG2,AI_LEVEL_NORMAL);
AssignCommand(oSG2,fnGuardFollow(oSCM));
SetLocalInt(oSG2,"nMode",0);
oSG3=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG3",oSG3);
SetAILevel(oSG3,AI_LEVEL_NORMAL);
AssignCommand(oSG3,fnGuardFollow(oSCM));
SetLocalInt(oSG3,"nMode",0);
oSG4=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG4",oSG4);
SetAILevel(oSG4,AI_LEVEL_NORMAL);
AssignCommand(oSG4,fnGuardFollow(oSCM));
SetLocalInt(oSG4,"nMode",0);
oSSO=CreateObject(OBJECT_TYPE_CREATURE,"slvg2",GetLocation(oWP));
SetLocalObject(oMod,"oSSO",oSSO);
SetAILevel(oSSO,AI_LEVEL_NORMAL);
AssignCommand(oSSO,fnGuardFollow(oSCM,3.0));
SetLocalInt(oSSO,"nMode",0);
} // less than 61
else if (nSlaverPower<81)
{ // less than 81
oSG1=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG1",oSG1);
SetAILevel(oSG1,AI_LEVEL_NORMAL);
AssignCommand(oSG1,fnGuardFollow(oSCM));
SetLocalInt(oSG1,"nMode",0);
oSG2=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG2",oSG2);
SetAILevel(oSG2,AI_LEVEL_NORMAL);
AssignCommand(oSG2,fnGuardFollow(oSCM));
SetLocalInt(oSG2,"nMode",0);
oSG3=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG3",oSG3);
SetAILevel(oSG3,AI_LEVEL_NORMAL);
AssignCommand(oSG3,fnGuardFollow(oSCM));
SetLocalInt(oSG3,"nMode",0);
oSG4=CreateObject(OBJECT_TYPE_CREATURE,"slvg1",GetLocation(oWP));
SetLocalObject(oMod,"oSG4",oSG4);
SetAILevel(oSG4,AI_LEVEL_NORMAL);
AssignCommand(oSG4,fnGuardFollow(oSCM));
SetLocalInt(oSG4,"nMode",0);
oSSO=CreateObject(OBJECT_TYPE_CREATURE,"slvg2",GetLocation(oWP));
SetLocalObject(oMod,"oSSO",oSSO);
SetAILevel(oSSO,AI_LEVEL_NORMAL);
AssignCommand(oSSO,fnGuardFollow(oSCM,3.0));
SetLocalInt(oSSO,"nMode",0);
} // less than 41
else if (nSlaverPower<61)
{ // less than 61
oSG1=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG1",oSG1);
SetAILevel(oSG1,AI_LEVEL_NORMAL);
AssignCommand(oSG1,fnGuardFollow(oSCM));
SetLocalInt(oSG1,"nMode",0);
oSG2=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG2",oSG2);
SetAILevel(oSG2,AI_LEVEL_NORMAL);
AssignCommand(oSG2,fnGuardFollow(oSCM));
SetLocalInt(oSG2,"nMode",0);
oSG3=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG3",oSG3);
SetAILevel(oSG3,AI_LEVEL_NORMAL);
AssignCommand(oSG3,fnGuardFollow(oSCM));
SetLocalInt(oSG3,"nMode",0);
oSG4=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG4",oSG4);
SetAILevel(oSG4,AI_LEVEL_NORMAL);
AssignCommand(oSG4,fnGuardFollow(oSCM));
SetLocalInt(oSG4,"nMode",0);
oSSO=CreateObject(OBJECT_TYPE_CREATURE,"slvg2",GetLocation(oWP));
SetLocalObject(oMod,"oSSO",oSSO);
SetAILevel(oSSO,AI_LEVEL_NORMAL);
AssignCommand(oSSO,fnGuardFollow(oSCM,3.0));
SetLocalInt(oSSO,"nMode",0);
} // less than 61
else if (nSlaverPower<81)
{ // less than 81
oSG1=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG1",oSG1);
SetAILevel(oSG1,AI_LEVEL_NORMAL);
AssignCommand(oSG1,fnGuardFollow(oSCM));
SetLocalInt(oSG1,"nMode",0);
oSG2=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG2",oSG2);
SetAILevel(oSG2,AI_LEVEL_NORMAL);
AssignCommand(oSG2,fnGuardFollow(oSCM));
SetLocalInt(oSG2,"nMode",0);
oSG3=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG3",oSG3);
SetAILevel(oSG3,AI_LEVEL_NORMAL);
AssignCommand(oSG3,fnGuardFollow(oSCM));
SetLocalInt(oSG3,"nMode",0);
oSG4=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG4",oSG4);
SetAILevel(oSG4,AI_LEVEL_NORMAL);
AssignCommand(oSG4,fnGuardFollow(oSCM));
SetLocalInt(oSG4,"nMode",0);
oSSO=CreateObject(OBJECT_TYPE_CREATURE,"slvg2",GetLocation(oWP));
SetLocalObject(oMod,"oSSO",oSSO);
SetAILevel(oSSO,AI_LEVEL_NORMAL);
AssignCommand(oSSO,fnGuardFollow(oSCM,3.0));
SetLocalInt(oSSO,"nMode",0);
oSIL=CreateObject(OBJECT_TYPE_CREATURE,"slvg4",GetLocation(oWP));
SetLocalObject(oMod,"oSIL",oSIL);
SetAILevel(oSIL,AI_LEVEL_NORMAL);
AssignCommand(oSIL,fnGuardFollow(oSCM,3.0));
SetLocalInt(oSIL,"nMode",0);
} // less than 81
else
{ // most powerful slave caravan
oSG1=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG1",oSG1);
SetAILevel(oSG1,AI_LEVEL_NORMAL);
AssignCommand(oSG1,fnGuardFollow(oSCM));
SetLocalInt(oSG1,"nMode",0);
oSG2=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG2",oSG2);
SetAILevel(oSG2,AI_LEVEL_NORMAL);
AssignCommand(oSG2,fnGuardFollow(oSCM));
SetLocalInt(oSG2,"nMode",0);
oSG3=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG3",oSG3);
SetAILevel(oSG3,AI_LEVEL_NORMAL);
AssignCommand(oSG3,fnGuardFollow(oSCM));
SetLocalInt(oSG3,"nMode",0);
oSG4=CreateObject(OBJECT_TYPE_CREATURE,"slvg3",GetLocation(oWP));
SetLocalObject(oMod,"oSG4",oSG4);
SetAILevel(oSG4,AI_LEVEL_NORMAL);
AssignCommand(oSG4,fnGuardFollow(oSCM));
SetLocalInt(oSG4,"nMode",0);
oSSO=CreateObject(OBJECT_TYPE_CREATURE,"slvg2",GetLocation(oWP));
SetLocalObject(oMod,"oSSO",oSSO);
SetAILevel(oSSO,AI_LEVEL_NORMAL);
AssignCommand(oSSO,fnGuardFollow(oSCM,3.0));
SetLocalInt(oSSO,"nMode",0);
oSIL=CreateObject(OBJECT_TYPE_CREATURE,"slvg5",GetLocation(oWP));
SetLocalObject(oMod,"oSIL",oSIL);
SetAILevel(oSIL,AI_LEVEL_NORMAL);
AssignCommand(oSIL,fnGuardFollow(oSCM,3.0));
SetLocalInt(oSIL,"nMode",0);
} // most powerful slave caravan
nSpeed=3;
} // create a new caravan
} // caravan master is either dead or does not exist
//////// End
if (nSpeed<1) DelayCommand(8.0,fnRelaunch(nSNS));
else { DelayCommand(IntToFloat(nSpeed),fnRelaunch(nSNS)); }
} // it is not disabled
else
{ // disabled
if (oSCM!=OBJECT_INVALID) fnDespawn(oSCM);
if (oSG1!=OBJECT_INVALID) fnDespawn(oSG1);
if (oSG2!=OBJECT_INVALID) fnDespawn(oSG2);
if (oSG3!=OBJECT_INVALID) fnDespawn(oSG3);
if (oSG4!=OBJECT_INVALID) fnDespawn(oSG4);
if (oSSO!=OBJECT_INVALID) fnDespawn(oSSO);
if (oSIL!=OBJECT_INVALID) fnDespawn(oSIL);
} // disabled
}
////////////////////////////////////////////////////////////// MAIN ////////////
//////////////////////
// FUNCTIONS
//////////////////////
void fnDespawn(object oCr)
{ // despawn object
if (oCr!=OBJECT_INVALID)
{ // !OI
if (IsInConversation(oCr)==TRUE||GetIsInCombat(oCr)==TRUE)
{ DelayCommand(10.0,fnDespawn(oCr)); } // wait for conv/combat end
else { DestroyObject(oCr); }
} // !OI
} // fnDespawn()
void fnCheckHealSelf(object oCr)
{ // if hurt bad try to heal self
if(GetCurrentHitPoints(oCr)<(GetMaxHitPoints(oCr)/2))
{ // 50% health or less - heal self
if (GetHasSpell(SPELL_CURE_SERIOUS_WOUNDS,oCr)!=0)
{ // cast cure serious wounds
ActionCastSpellAtObject(SPELL_CURE_SERIOUS_WOUNDS,oCr);
} // cast cure serious wounds
else if (GetHasSpell(SPELL_CURE_MODERATE_WOUNDS,oCr)!=0)
{ // cast cure moderate wounds
ActionCastSpellAtObject(SPELL_CURE_MODERATE_WOUNDS,oCr);
} // cast cure moderate wounds
else if (GetHasSpell(SPELL_CURE_LIGHT_WOUNDS,oCr)!=0)
{ // cure light wounds
ActionCastSpellAtObject(SPELL_CURE_LIGHT_WOUNDS,oCr);
} // cure light wounds
else if (GetHasSpell(SPELL_CURE_MINOR_WOUNDS,oCr)!=0)
{ // cure minor wounds
ActionCastSpellAtObject(SPELL_CURE_MINOR_WOUNDS,oCr);
} // cure minor wounds
} // 50% health or less - heal self
} // fnCheckHealSelf()
int mod_GetHasEffect(object oTarg,effect eE)
{ // returns TRUE if has the effect
int nRet=FALSE;
effect eEff=GetFirstEffect(oTarg);
while(GetEffectType(eEff)!=EFFECT_TYPE_INVALIDEFFECT&&nRet!=TRUE)
{ // check effects
if (eEff==eE) nRet=TRUE;
eEff=GetNextEffect(oTarg);
} // check effects
return nRet;
} // GetHasEffect()
int fnGetIsPerson(object oTarg)
{ // returns TRUE if this creature can be classified as a person
int nRet=FALSE;
if (MyPRCGetRacialType(oTarg)==RACIAL_TYPE_DWARF||MyPRCGetRacialType(oTarg)==RACIAL_TYPE_ELF||MyPRCGetRacialType(oTarg)==RACIAL_TYPE_GNOME||MyPRCGetRacialType(oTarg)==RACIAL_TYPE_HALFELF) nRet=TRUE;
else if (MyPRCGetRacialType(oTarg)==RACIAL_TYPE_HALFLING||MyPRCGetRacialType(oTarg)==RACIAL_TYPE_HALFORC||MyPRCGetRacialType(oTarg)==RACIAL_TYPE_HUMAN) nRet=TRUE;
else if (MyPRCGetRacialType(oTarg)==RACIAL_TYPE_HUMANOID_GOBLINOID||MyPRCGetRacialType(oTarg)==RACIAL_TYPE_HUMANOID_ORC) nRet=TRUE;
return nRet;
} // fnGetIsPerson()
void fnSorceressDefense(object oTarg)
{ // check oTarg and disable it - protect caravan master
if (GetChallengeRating(oTarg)<2.1)
{ // lesser target
if (GetHasSpellEffect(SPELL_SLEEP,oTarg)!=TRUE&&GetHasSpell(SPELL_SLEEP,OBJECT_SELF)!=0&&MyPRCGetRacialType(oTarg)!=RACIAL_TYPE_UNDEAD&&MyPRCGetRacialType(oTarg)!=RACIAL_TYPE_CONSTRUCT)
{ // cast sleep
ActionCastSpellAtObject(SPELL_SLEEP,oTarg);
} // cast sleep
else
{ // next spell
if(GetHasSpellEffect(SPELL_SLEEP,oTarg)==TRUE)
{ // sleeping
ActionAttack(oTarg); // attack with light crossbow and poisoned bolts
} // sleeping
else
{ // not sleeping
if(GetHasSpellEffect(SPELL_DAZE,oTarg)!=TRUE&&GetHasSpell(SPELL_DAZE,OBJECT_SELF)!=0&&MyPRCGetRacialType(oTarg)!=RACIAL_TYPE_UNDEAD&&MyPRCGetRacialType(oTarg)!=RACIAL_TYPE_CONSTRUCT)
{ // cast daze
ActionCastSpellAtObject(SPELL_DAZE,oTarg);
} // cast daze
else
{ // next spell
if(GetHasSpell(SPELL_MAGIC_MISSILE,oTarg)!=0)
{ // cast magic missile
ActionCastSpellAtObject(SPELL_MAGIC_MISSILE,oTarg);
} // cast magic missile
else if (GetHasSpell(SPELL_ACID_SPLASH,oTarg)!=0)
{ // cast acid splash
ActionCastSpellAtObject(SPELL_ACID_SPLASH,oTarg);
} // cast acid splash
else if (GetHasSpell(SPELL_MELFS_ACID_ARROW,oTarg)!=0)
{ // cast MELFS ACID ARROW
ActionCastSpellAtObject(SPELL_MELFS_ACID_ARROW,oTarg);
} // cast MELFS ACID ARROW
else if (GetHasSpell(SPELL_LIGHTNING_BOLT,oTarg)!=0)
{ // cast Lightning Bolt
ActionCastSpellAtObject(SPELL_LIGHTNING_BOLT,oTarg);
} // cast Lightning Bolt
else
{ // no spells - use light crossbow w/ poison
ActionAttack(oTarg);
} // no spells - use light crossbow w/ poison
} // next spell
} // not sleeping
} // next spell
} // lesser target
else if (GetChallengeRating(oTarg)<6.1)
{ // medium target
if (GetHasSpellEffect(SPELL_HOLD_PERSON,oTarg)!=TRUE&&GetHasSpell(SPELL_HOLD_PERSON,OBJECT_SELF)!=0&&fnGetIsPerson(oTarg)==TRUE)
{ // cast hold person
ActionCastSpellAtObject(SPELL_HOLD_PERSON,oTarg);
} // cast hold person
else
{ // might be held or other spell
if (GetHasSpellEffect(SPELL_HOLD_PERSON,oTarg)==TRUE)
{ // held - shoot with crossbow
ActionAttack(oTarg);
} // held - shoot with crossbow
else
{ // not held - use tentacles
if (GetHasSpellEffect(SPELL_EVARDS_BLACK_TENTACLES,oTarg)!=TRUE&&GetHasSpell(SPELL_EVARDS_BLACK_TENTACLES,OBJECT_SELF)!=0)
{ // evard's black tentacles
ActionCastSpellAtObject(SPELL_EVARDS_BLACK_TENTACLES,oTarg);
} // evard's black tentacles
else
{ // blast them
if (GetHasSpell(SPELL_LIGHTNING_BOLT,OBJECT_SELF)!=0)
{ // lightning bolt
ActionCastSpellAtObject(SPELL_LIGHTNING_BOLT,oTarg);
} // lightning bolt
else if (GetHasSpell(SPELL_MELFS_ACID_ARROW,OBJECT_SELF)!=0)
{ // Melf's Acid Arrow
ActionCastSpellAtObject(SPELL_MELFS_ACID_ARROW,oTarg);
} // Melf's Acid Arrow
else if (GetHasSpell(SPELL_MAGIC_MISSILE,OBJECT_SELF)!=0)
{ // Magic Missile
ActionCastSpellAtObject(SPELL_MAGIC_MISSILE,oTarg);
} // Magic Missile
else if (GetHasSpell(SPELL_ACID_SPLASH,OBJECT_SELF)!=0)
{ // Acid Splash
ActionCastSpellAtObject(SPELL_ACID_SPLASH,oTarg);
} // Acid Splash
else
{ // attack with crossbow
ActionAttack(oTarg);
} // attack with crossbow
} // blast them
} // not held - use tentacles
} // might be held or other spell
} // medium target
else
{ // Dangerous target
if (GetHasSpellEffect(SPELL_EVARDS_BLACK_TENTACLES,oTarg)!=TRUE&&GetHasSpell(SPELL_EVARDS_BLACK_TENTACLES,OBJECT_SELF)!=0)
{ // evard's black tentacles
ActionCastSpellAtObject(SPELL_EVARDS_BLACK_TENTACLES,oTarg);
} // evard's black tentacles
else
{ // blast them
if (GetHasSpell(SPELL_LIGHTNING_BOLT,OBJECT_SELF)!=0)
{ // lightning bolt
ActionCastSpellAtObject(SPELL_LIGHTNING_BOLT,oTarg);
} // lightning bolt
else if (GetHasSpell(SPELL_MELFS_ACID_ARROW,OBJECT_SELF)!=0)
{ // Melf's Acid Arrow
ActionCastSpellAtObject(SPELL_MELFS_ACID_ARROW,oTarg);
} // Melf's Acid Arrow
else if (GetHasSpell(SPELL_MAGIC_MISSILE,OBJECT_SELF)!=0)
{ // Magic Missile
ActionCastSpellAtObject(SPELL_MAGIC_MISSILE,oTarg);
} // Magic Missile
else if (GetHasSpell(SPELL_ACID_SPLASH,OBJECT_SELF)!=0)
{ // Acid Splash
ActionCastSpellAtObject(SPELL_ACID_SPLASH,oTarg);
} // Acid Splash
else
{ // attack with crossbow
ActionAttack(oTarg);
} // attack with crossbow
} // blast them
} // dangerous target
} // fnSorceressDefense()
void fnGuardFollow(object oMaster,float fDist=5.0)
{ // follow the master 5.0 distance
object oMe=OBJECT_SELF;
float fCDist=GetDistanceBetween(oMaster,oMe);
int nLagCount=GetLocalInt(oMe,"nLagCount");
if (GetLocalInt(oMe,"nMode")==0&&GetIsInCombat(oMe)!=TRUE)
{ // follow
if (GetArea(oMaster)!=GetArea(oMe))
{ // teleport
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,JumpToObject(oMaster));
} // teleport
else if (fCDist>=(fDist*2.0))
{ // run
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,ASActionMoveToObject(oMaster,TRUE,fDist));
nLagCount++;
SetLocalInt(oMe,"nLagCount",nLagCount);
if (nLagCount>15)
{ // can't catch up - teleport
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,JumpToObject(oMaster));
} // can't catch up - teleport
} // run
else if (fCDist>fDist)
{ // walk
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,ASActionMoveToObject(oMaster,FALSE,fDist));
SetLocalInt(oMe,"nLagCount",0);
} // walk
else { SetLocalInt(oMe,"nLagCount",0); }
} // follow
DelayCommand(5.0,fnGuardFollow(oMaster,fDist));
} // fnGuardFollow()
void fnDespawnIfNoSlavers()
{
object oMaster=GetLocalObject(OBJECT_SELF,"oMaster");
if (oMaster==OBJECT_INVALID||GetIsDead(oMaster)==TRUE) DestroyObject(OBJECT_SELF);
DelayCommand(30.0,fnDespawnIfNoSlavers());
} // fnDespawnIfNoSlavers()
int fnClosestTransition(object oDest,object oSCM)
{ // For some reason Bioware Pathing doesn't always use the closest transition
// to an area.... even when the NPC is standing directly next to the correct
// door. This overrides that... returns TRUE when it reaches the area oDest
// is in.
int nRet=FALSE;
object oNearT;
object oNearD;
object oTT;
int nC=1;
float fDist;
int bFound=FALSE;
if (GetArea(oDest)==GetArea(oSCM)) return TRUE;
oNearT=GetNearestObject(OBJECT_TYPE_TRIGGER,oSCM,nC);
oNearD=GetNearestObject(OBJECT_TYPE_DOOR,oSCM,nC);
while((oNearT!=OBJECT_INVALID||oNearD!=OBJECT_INVALID)&&bFound!=TRUE)
{ // find transition
if (oNearT!=OBJECT_INVALID)
{ // !OI NT
oTT=GetTransitionTarget(oNearT);
if (oTT!=OBJECT_INVALID&&GetArea(oTT)==GetArea(oDest))
{ // move
bFound=TRUE;
fDist=GetDistanceBetween(oNearT,oSCM);
if (fDist<3.0)
{ // transition
AssignCommand(oSCM,ClearAllActions());
AssignCommand(oSCM,JumpToObject(oTT));
} // transition
else
{
AssignCommand(oSCM,ASActionMoveToObject(oNearT,FALSE,2.5));
}
return FALSE;
} // move
} // !OI NT
if (oNearD!=OBJECT_INVALID)
{ // !OI ND
oTT=GetTransitionTarget(oNearD);
if (oTT!=OBJECT_INVALID&&GetArea(oTT)==GetArea(oDest))
{ // move
bFound=TRUE;
fDist=GetDistanceBetween(oNearD,oSCM);
if (fDist<3.0)
{ // transition
AssignCommand(oSCM,ClearAllActions());
AssignCommand(oNearD,ActionOpenDoor(oNearD));
AssignCommand(oSCM,ActionPlayAnimation(ANIMATION_LOOPING_GET_MID,1.0,2.0));
AssignCommand(oSCM,JumpToObject(oTT));
} // transition
else
{
AssignCommand(oSCM,ASActionMoveToObject(oNearD,FALSE,2.5));
}
return FALSE;
} // move
} // !OI ND
// next pair
nC++;
oNearT=GetNearestObject(OBJECT_TYPE_TRIGGER,oSCM,nC);
oNearD=GetNearestObject(OBJECT_TYPE_DOOR,oSCM,nC);
} // find transition
if (bFound==FALSE)
{ // could not find area transition
AssignCommand(oSCM,SpeakString("I could not find the nearest path."));
return TRUE;
} // could not find area transition
return nRet;
} // fnClosestTransition()