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

409 lines
15 KiB
Plaintext

// RTS - Harvest of Souls (scout routine)
// By Deva Bryson Winblood
// 11/29/2003
/////////////////////////////////////////
#include "rts_header"
/////////////////
// PROTOTYPES
/////////////////
object fnObjectOfInterest();
object fnMakeMessenger(object oMsg,string sID);
object fnRandomTrans(object oArea);
object fnRandomObjects(object oArea);
int fnNotValid(object oArea);
//////////////////////////////////////////////////////////////// MAIN
void main()
{
object oMe=OBJECT_SELF;
object oMod=GetModule();
string sID=GetLocalString(oMe,"sTeamID");
object oHome=GetWaypointByTag(sID+"_START");
int nSState=GetLocalInt(oMe,"nSState");
object oH;
object oDest=GetLocalObject(oMe,"oDestWP");
float fDist;
object oLArea1=GetLocalObject(oMe,"oLArea1");
object oLArea2=GetLocalObject(oMe,"oLArea2");
int nN;
int nR;
object oMsg;
string sMsg;
object oBird;
object oArea=GetArea(oMe);
int nRun=GetLocalInt(oMe,"nRun");
float fFacing=GetFacing(oMe);
switch(nSState)
{ // the scout main switch
case 0: { // look for anything interesting
//SendMessageToPC(GetFirstPC(),GetName(oMe)+" looking for items of interest.");
fFacing=fFacing+90.0;
if (fFacing>=360.0) fFacing=fFacing-360.0;
SetFacing(fFacing);
ActionPlayAnimation(ANIMATION_LOOPING_LOOK_FAR,1.0,4.0);
oH=fnObjectOfInterest();
if (oH!=OBJECT_INVALID)
{ // item of interest
nN=GetObjectType(oH);
SetLocalObject(oMe,"oDestWP",oH);
if (nN==OBJECT_TYPE_CREATURE) SetLocalInt(oMe,"nSState",3);
else if (nN==OBJECT_TYPE_PLACEABLE) SetLocalInt(oMe,"nSState",4);
else if (nN==OBJECT_TYPE_ITEM) SetLocalInt(oMe,"nSState",5);
} // item of interest
else
{ // move on
SetLocalInt(oMe,"nSState",1);
} // move on
break;
} // look for anything interesting
case 1: { // find next destination
//SendMessageToPC(GetFirstPC(),GetName(oMe)+" looking for destination.");
if(oArea==oHome||(d6()<4))
{ // seek next area
//SendMessageToPC(GetFirstPC(),GetName(oMe)+" area transition.");
oH=fnRandomTrans(oArea);
oH=GetTransitionTarget(oH);
oArea=GetArea(oH);
nN=0;
while((oH==OBJECT_INVALID||(oArea==oLArea1||oArea==oLArea2||fnNotValid(oH)==TRUE))&&nN<3)
{ // while find
oH=fnRandomTrans(GetArea(oMe));
oH=GetTransitionTarget(oH);
oArea=GetArea(oH);
nN++;
} // while find
if (oArea==oLArea1||oArea==oLArea2||fnNotValid(oH)==TRUE)
{
if (GetLocalInt(GetArea(oMe),"nPathingTC")!=1)
{ oH=OBJECT_INVALID; }
}
if (oH!=OBJECT_INVALID)
{ // pick destination
nN=d4();
if (d4()<4) oDest=GetNearestObject(OBJECT_TYPE_PLACEABLE,oH,nN);
else { oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oH,nN); }
nN--;
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_PLACEABLE,oH,nN);
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oH,nN);
nN--;
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_PLACEABLE,oH,nN);
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oH,nN);
nN--;
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_PLACEABLE,oH,nN);
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oH,nN);
if (oDest!=OBJECT_INVALID)
{ // success
SetLocalObject(oMe,"oDestWP",oDest);
SetLocalInt(oMe,"nSState",2);
SetLocalObject(oMe,"oLArea2",oLArea1);
SetLocalObject(oMe,"oLArea1",GetArea(oMe));
} // success
} // pick destination
else
{ // couldn't find a way - let's just move through one anyway
oArea=GetArea(oMe);
oH=fnRandomTrans(oArea);
oH=GetTransitionTarget(oH);
nN=d4();
if (d4()<4) oDest=GetNearestObject(OBJECT_TYPE_PLACEABLE,oH,nN);
else { oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oH,nN); }
nN--;
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_PLACEABLE,oH,nN);
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oH,nN);
nN--;
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_PLACEABLE,oH,nN);
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oH,nN);
nN--;
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_PLACEABLE,oH,nN);
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oH,nN);
if (oDest!=OBJECT_INVALID)
{ // success
SetLocalObject(oMe,"oDestWP",oDest);
SetLocalInt(oMe,"nSState",2);
SetLocalObject(oMe,"oLArea2",oLArea1);
SetLocalObject(oMe,"oLArea1",GetArea(oMe));
} // success
} // couldn't find a way - let's just move through one anyway
} // seek next area
else
{ // seek random object
oDest=fnRandomObjects(GetArea(oMe));
if (oDest!=OBJECT_INVALID)
{ // success
SetLocalObject(oMe,"oDestWP",oDest);
SetLocalInt(oMe,"nSState",2);
} // success
} // seek random object
break;
} // find next destination
case 2: { // move to destination
nN=fnMoveToDestination(oDest,nRun);
//SendMessageToPC(GetFirstPC(),GetName(oMe)+" moving to "+GetTag(oDest)+" in area "+GetName(GetArea(oDest))+".");
if (nN==1||(GetArea(oDest)==GetArea(oMe)&&GetDistanceBetween(oMe,oDest)<3.1))
{ // should have arrived
SetLocalInt(oMe,"nSState",0);
} // should have arrived
else if (nN==-1)
{ // error
if(GetAbilityScore(oMe,ABILITY_INTELLIGENCE)>9) AssignCommand(oMe,SpeakString("I can't seem to reach "+GetName(oDest)+" in this area."));
SetLocalInt(oMe,"nSState",0);
} // error
break;
} // move to destination
case 3: { // message - merchant or plot creature
oMsg=CreateItemOnObject("rtsa_message",oMe);
sMsg="I encountered an interesting individual by the name of "+GetName(oDest)+" in area "+GetName(GetArea(oDest))+".";
SetLocalObject(oDest,"oLastSeen"+sID,GetArea(oDest));
SetLocalString(oMsg,"sMsg",sMsg);
SetLocalObject(oMsg,"oDest",GetWaypointByTag(sID+"_START"));
oDest=GetLocalObject(oMod,"oTeamLead"+sID);
SetLocalString(oMsg,"sTo",GetName(oDest));
SetLocalString(oMsg,"sName",GetName(oMe));
oBird=fnMakeMessenger(oMsg,sID);
AssignCommand(oBird,ClearAllActions());
DelayCommand(5.0,AssignCommand(oBird,ExecuteScript("rtsa_ai_birdmsg",oBird)));
SetLocalInt(oMe,"nSState",0);
break;
} // message - merchant or plot creature
case 4: { // message - mana pool
sMsg="I saw a "+GetName(oDest)+" in area ";
sMsg=sMsg+GetName(GetArea(oDest))+".";
oMsg=CreateItemOnObject("rtsa_message",oMe);
SetLocalObject(oDest,"oLastSeen"+sID,GetArea(oDest));
SetLocalString(oMsg,"sMsg",sMsg);
SetLocalObject(oMsg,"oDest",GetWaypointByTag(sID+"_START"));
oDest=GetLocalObject(oMod,"oTeamLead"+sID);
SetLocalString(oMsg,"sTo",GetName(oDest));
SetLocalString(oMsg,"sName",GetName(oMe));
oBird=fnMakeMessenger(oMsg,sID);
AssignCommand(oBird,ClearAllActions());
DelayCommand(5.0,AssignCommand(oBird,ExecuteScript("rtsa_ai_birdmsg",oBird)));
SetLocalInt(oMe,"nSState",0);
break;
} // message - mana pool
case 5: { // message - item of value
sMsg="I saw what looked to be an interesting item lying on the ground in "+GetName(GetArea(oDest))+".";
sMsg=" I did not attempt to take it because, I thought I should report it first.";
oH=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oDest,1);
if (GetDistanceBetween(oH,oDest)<3.0) sMsg=sMsg+"It appears to be guarded by a "+GetName(oH)+".";
SetLocalObject(oDest,"oLastSeen"+sID,GetArea(oDest));
SetLocalString(oMsg,"sMsg",sMsg);
SetLocalObject(oMsg,"oDest",GetWaypointByTag(sID+"_START"));
oDest=GetLocalObject(oMod,"oTeamLead"+sID);
SetLocalString(oMsg,"sTo",GetName(oDest));
SetLocalString(oMsg,"sName",GetName(oMe));
oBird=fnMakeMessenger(oMsg,sID);
AssignCommand(oBird,ClearAllActions());
DelayCommand(5.0,AssignCommand(oBird,ExecuteScript("rtsa_ai_birdmsg",oBird)));
SetLocalInt(oMe,"nSState",0);
break;
} // message - item of value
} // the scout main switch
}
//////////////////////////////////////////////////////////////// MAIN
/////////////////////////
// FUNCTIONS
/////////////////////////
//// Randoms
void fnBuildTransRand(object oArea)
{ // build a list of transitions from this area
int nC=0;
int nL=1;
object oFirst=GetFirstObjectInArea(oArea);
object oTrans;
oFirst=GetNearestObject(OBJECT_TYPE_WAYPOINT,oFirst,1);
//SendMessageToPC(GetFirstPC(),"fnBuildTransRand()");
if (oFirst!=OBJECT_INVALID)
{
oTrans=GetNearestObject(OBJECT_TYPE_TRIGGER,oFirst,nL);
while(oTrans!=OBJECT_INVALID)
{ // triggers
if(GetTransitionTarget(oTrans)!=OBJECT_INVALID)
{ // transition
nC++;
SetLocalObject(oArea,"oPathingTrans"+IntToString(nC),oTrans);
} // transition
nL++;
oTrans=GetNearestObject(OBJECT_TYPE_TRIGGER,oFirst,nL);
} // triggers
nL=1;
oTrans=GetNearestObject(OBJECT_TYPE_DOOR,oFirst,nL);
while(oTrans!=OBJECT_INVALID)
{ // doors
if(GetTransitionTarget(oTrans)!=OBJECT_INVALID)
{ // transition
nC++;
SetLocalObject(oArea,"oPathingTrans"+IntToString(nC),oTrans);
} // transition
nL++;
oTrans=GetNearestObject(OBJECT_TYPE_DOOR,oFirst,nL);
} // doors
SetLocalInt(oArea,"nPathingTC",nC);
}
else
{
AssignCommand(OBJECT_SELF,SpeakString("This area is impossible to escape!!!"));
SendMessageToPC(GetFirstPC(),"RTS SETUP ERROR: Area "+GetName(oArea)+" has no transitions!");
}
} // fnBuildTransRand()
void fnBuildObjectRand(object oArea)
{ // build a list of objects
int nC=0;
int nL=1;
object oFirst=GetFirstObjectInArea(oArea);
object oTrans;
//SendMessageToPC(GetFirstPC(),"fnBuildObjectRand()");
oFirst=GetNearestObject(OBJECT_TYPE_WAYPOINT,oFirst,1);
if (oFirst!=OBJECT_INVALID)
{
oTrans=GetNearestObject(OBJECT_TYPE_PLACEABLE,oFirst,nL);
while(oTrans!=OBJECT_INVALID)
{ // placeables
nC++;
SetLocalObject(oArea,"oPathingObs"+IntToString(nC),oTrans);
nL++;
oTrans=GetNearestObject(OBJECT_TYPE_PLACEABLE,oFirst,nL);
} // placeables
nL=1;
oTrans=GetNearestObject(OBJECT_TYPE_WAYPOINT,oFirst,nL);
while(oTrans!=OBJECT_INVALID)
{ // waypoints
nC++;
SetLocalObject(oArea,"oPathingObs"+IntToString(nC),oTrans);
nL++;
oTrans=GetNearestObject(OBJECT_TYPE_WAYPOINT,oFirst,nL);
} // waypoints
nC++;
SetLocalObject(oArea,"oPathingObs"+IntToString(nC),oFirst);
SetLocalInt(oArea,"nPathingOC",nC);
}
} // fnBuildObjectRand()
object fnRandomTrans(object oArea)
{ // return a random transition door or trigger
object oRet=OBJECT_INVALID;
int nC=GetLocalInt(oArea,"nPathingTC");
if (nC<1)
{
fnBuildTransRand(oArea);
return OBJECT_INVALID;
}
else
{
nC=Random(nC)+1;
oRet=GetLocalObject(oArea,"oPathingTrans"+IntToString(nC));
}
return oRet;
} // fnRandomTrans()
object fnRandomObjects(object oArea)
{ // return an object in this area
object oRet=OBJECT_INVALID;
int nC=GetLocalInt(oArea,"nPathingOC");
if (nC<1)
{
fnBuildObjectRand(oArea);
return OBJECT_INVALID;
}
else
{
nC=Random(nC)+1;
oRet=GetLocalObject(oArea,"oPathingObs"+IntToString(nC));
}
return oRet;
} // fnRandomObjects()
//////////// messenger
object fnMakeMessenger(object oMsg,string sID)
{ // return messenger bird
object oBird=OBJECT_INVALID;
string sResRef=sID+"_bird";
object oSource=GetItemPossessor(oMsg);
//fnDebug(" [SCOUT]fnMakeMessenger("+GetName(oMsg)+")");
if (oMsg!=OBJECT_INVALID)
{ // valid message
oBird=CreateObject(OBJECT_TYPE_CREATURE,sResRef,GetLocation(oSource),FALSE);
ChangeFaction(oBird,oSource);
SetLocalString(oBird,"sTeamID",GetLocalString(oSource,"sTeamID"));
SetLocalObject(oBird,"oDest",GetLocalObject(oMsg,"oDest"));
SetLocalFloat(oBird,"fDelay",10.0);
AssignCommand(oSource,ClearAllActions());
AssignCommand(oSource,ActionGiveItem(oMsg,oBird));
//fnDebug(" Bird:"+GetName(oBird));
SetAILevel(oBird,AI_LEVEL_NORMAL);
SetDroppableFlag(oMsg,TRUE);
} // valid message
return oBird;
} // fnMakeMessenger()
/////////// find
float fnGetVisionRange(object oMe)
{ // return distance can notice
float fRet=25.0;
return fRet;
} // fnGetVisionRange()
object fnObjectOfInterest()
{ // return objects of interest
object oRet=OBJECT_INVALID;
object oMe=OBJECT_SELF;
string sID=GetLocalString(oMe,"sTeamID");
object oH;
int nC;
int nType;
string sT;
float fRange=fnGetVisionRange(oMe);
object oMerch=GetObjectByTag("Wizard");
if (GetNearestObjectByTag(sID+"_START")!=OBJECT_INVALID) return OBJECT_INVALID; // in your own lair
if (oMerch==OBJECT_INVALID)
oMerch=GetObjectByTag("Rotund");
if (oMerch==OBJECT_INVALID)
oMerch=GetObjectByTag("Fence");
if (oMerch==OBJECT_INVALID)
oMerch=GetObjectByTag("Smith");
if (oMerch==OBJECT_INVALID)
oMerch=GetObjectByTag("Apothecary");
nC=1;
oH=GetNearestObject(OBJECT_TYPE_ALL,oMe,nC);
while(oH!=OBJECT_INVALID&&GetDistanceBetween(oH,oMe)<=fRange)
{ // poll nearby items
if(GetLocalInt(oH,"nScouted"+sID)!=TRUE)
{ // possible target
SetLocalInt(oH,"nScouted"+sID,TRUE);
nType=GetObjectType(oH);
sT=GetTag(oH);
if (nType==OBJECT_TYPE_CREATURE&&(GetPlotFlag(oH)==TRUE||GetFactionEqual(oMerch,oH)==TRUE))
return oH;
if (nType==OBJECT_TYPE_PLACEABLE&&(sT=="MinorManaPool"||sT=="ManaPool"||sT=="StrongManaPool"))
return oH;
if (nType==OBJECT_TYPE_ITEM&&(GetPlotFlag(oH)==TRUE||GetGoldPieceValue(oH)>2000||sT==""))
return oH;
} // possible target
// next item
nC++;
oH=GetNearestObject(OBJECT_TYPE_ALL,oMe,nC);
} // poll nearby items
return oRet;
} // fnObjectOfInterest()
int fnNotValid(object oArea)
{ // if not a valid area return TRUE
object oFirst=GetFirstObjectInArea(oArea);
object oPath=GetNearestObjectByTag("PATHINGA",oFirst,1);
if (oPath==OBJECT_INVALID) oPath=GetNearestObjectByTag("PATHINGB",oFirst,1);
if (oPath==OBJECT_INVALID)
{ //
if (GetTag(oFirst)=="PATHINGA"||GetTag(oFirst)=="PATHINGB") oPath=oFirst;
} //
if (oPath==OBJECT_INVALID) return TRUE;
if (GetName(oPath)=="AVOID") return TRUE;
return FALSE;
} // fnNotValid()