generated from Jaysyn/ModuleTemplate
149 lines
5.2 KiB
Plaintext
149 lines
5.2 KiB
Plaintext
float GetEnemyCR(object oEnemy, float fEnemyCR);
|
|
float GetTheirCR(object oEnemy, float f_TheirCR, float fRange, object oTheirs);
|
|
float GetOurCR(float f_OurCR, float fRange, object oMine);
|
|
void SignalFlee(object oEnemy, float fRange);
|
|
|
|
float GetEnemyCR (object oEnemy, float fEnemyCR)
|
|
//Gets enemy's HD or CR as appropriate.
|
|
{
|
|
if (GetIsPC(oEnemy))
|
|
{
|
|
return IntToFloat(GetHitDice(oEnemy));
|
|
}
|
|
else
|
|
{
|
|
return GetChallengeRating(oEnemy);
|
|
}
|
|
}
|
|
|
|
//Adds up all the HD or CRs from enemies within fRange.
|
|
float GetTheirCR(object oEnemy, float f_TheirCR, float fRange, object oTheirs)
|
|
{
|
|
oTheirs = GetFirstObjectInShape(SHAPE_SPHERE,fRange,GetLocation(OBJECT_SELF));
|
|
while (GetIsObjectValid(oTheirs))
|
|
{
|
|
if (GetObjectType(oTheirs) == OBJECT_TYPE_CREATURE && GetIsEnemy(oTheirs,OBJECT_SELF))
|
|
{
|
|
if (GetIsPC(oTheirs))
|
|
{
|
|
f_TheirCR = f_TheirCR + IntToFloat(GetHitDice(oTheirs));
|
|
}
|
|
else
|
|
{
|
|
f_TheirCR = f_TheirCR + GetChallengeRating(oTheirs);
|
|
}
|
|
}
|
|
oTheirs = GetNextObjectInShape(SHAPE_SPHERE,fRange,GetLocation(OBJECT_SELF));
|
|
}
|
|
return f_TheirCR;
|
|
}
|
|
|
|
//Determines CR of caller's party by scanning for all
|
|
//friends within fRange. Does NOT include any friends that
|
|
//have retreated.
|
|
float GetOurCR(float f_OurCR, float fRange, object oMine)
|
|
{
|
|
f_OurCR = GetChallengeRating(OBJECT_SELF);
|
|
oMine = GetFirstObjectInShape(SHAPE_SPHERE,fRange,GetLocation(OBJECT_SELF));
|
|
|
|
while (GetIsObjectValid(oMine))
|
|
{
|
|
if (GetObjectType(oMine) == OBJECT_TYPE_CREATURE
|
|
&& GetIsFriend(oMine,OBJECT_SELF)
|
|
&& GetLocalInt(oMine,"RETREATED") != 1
|
|
&& GetLocalInt(OBJECT_SELF,"FOF_DEAD") != 1)
|
|
|
|
{
|
|
f_OurCR = f_OurCR + GetChallengeRating(oMine);
|
|
}
|
|
oMine = GetNextObjectInShape(SHAPE_SPHERE,fRange,GetLocation(OBJECT_SELF));
|
|
}
|
|
return f_OurCR;
|
|
}
|
|
|
|
//The act of retreating.
|
|
//Looks for leaders or rallying points and makes for those,
|
|
//when present. Otherwise, they run all over the place.
|
|
void SignalFlee(object oEnemy, float fRange)
|
|
{
|
|
object oTest;
|
|
|
|
//Is there a leader within fRange + 20.0?
|
|
//looks only for creatures now
|
|
oTest = GetFirstObjectInShape(SHAPE_SPHERE,fRange + 20.0,GetLocation(OBJECT_SELF),OBJECT_TYPE_CREATURE);
|
|
while (GetIsObjectValid(oTest))
|
|
{
|
|
if (GetLocalInt(oTest,"I_AM_A_LEADER") == 1)
|
|
{
|
|
//when we have found a leader we brake
|
|
//out of the loop to "save" the leader object.
|
|
break;
|
|
}
|
|
oTest = GetNextObjectInShape(SHAPE_SPHERE,fRange + 20.0,GetLocation(OBJECT_SELF),OBJECT_TYPE_CREATURE);
|
|
}
|
|
|
|
//if we found no leader (the oTest is still a invalid object)
|
|
//then we check if there is a rallying point sowehere in the area.
|
|
//Requires a waypoint or object with the tag "RallyingPoint".
|
|
if (GetIsObjectValid(oTest) == FALSE)
|
|
{
|
|
//because GetNearestObjectByTag checks
|
|
//for objects only in the same area, it's useful here
|
|
oTest = GetNearestObjectByTag("RallyingPoint", OBJECT_SELF);
|
|
}
|
|
|
|
//Retreat to leader or rallying point, or scatter.
|
|
|
|
//we don't need to check if the object oTest is valid
|
|
//here because GetLocalInt always returns 0 on error
|
|
if (GetLocalInt(oTest,"I_AM_A_LEADER") == 1 && GetDistanceToObject(oTest) >= 10.0)
|
|
{
|
|
ClearAllActions();
|
|
//SpeakString("Boss! Help me!");
|
|
SetLocalInt(OBJECT_SELF,"RETREATED",1);
|
|
ActionMoveToObject(oTest,TRUE,2.0);
|
|
ActionDoCommand(SetLocalInt(OBJECT_SELF,"RETREATED",0));
|
|
ActionDoCommand(SetCommandable(TRUE,OBJECT_SELF));
|
|
SetCommandable(FALSE,OBJECT_SELF);
|
|
}
|
|
else
|
|
|
|
//is oTest a valid object?
|
|
//(if there wasn't a leader, maybe there is a rally point?)
|
|
//Are we meaningfully far away from it?
|
|
if (GetIsObjectValid(oTest) == TRUE && GetDistanceToObject(oTest) >= 10.0)
|
|
{
|
|
ClearAllActions();
|
|
//SpeakString("Fall back and regroup!");
|
|
SetLocalInt(OBJECT_SELF,"RETREATED",1);
|
|
ActionMoveToObject(oTest,TRUE,2.0);
|
|
ActionDoCommand(SetLocalInt(OBJECT_SELF,"RETREATED",0));
|
|
ActionDoCommand(SetCommandable(TRUE,OBJECT_SELF));
|
|
SetCommandable(FALSE,OBJECT_SELF);
|
|
}
|
|
else
|
|
{
|
|
//Destroys the caller, provided it can put some
|
|
//distance behind it and simply "melt away."
|
|
ClearAllActions();
|
|
//SpeakString("It ain't worth it!");
|
|
SetLocalInt(OBJECT_SELF,"RETREATED",1);
|
|
ActionMoveAwayFromObject(oEnemy,TRUE,fRange + 100.0);
|
|
ActionDoCommand(SetLocalInt(OBJECT_SELF,"RETREATED",0));
|
|
ActionDoCommand(DestroyObject(OBJECT_SELF));
|
|
SetCommandable(FALSE,OBJECT_SELF);
|
|
}
|
|
|
|
//Shout a RETREAT_CHECK, but not if you're the one making the
|
|
//check based on an ally's call. Reads an int set in
|
|
//nw_c2_default4.
|
|
if (GetLocalInt(OBJECT_SELF,"HEARD_THE_CALL") == 1)
|
|
{
|
|
SetLocalInt(OBJECT_SELF,"HEARD_THE_CALL",0);
|
|
}
|
|
else
|
|
{
|
|
SpeakString("RETREAT_CHECK",TALKVOLUME_SILENT_TALK);
|
|
}
|
|
}
|