807 lines
36 KiB
Plaintext
807 lines
36 KiB
Plaintext
////////////////////////////////////////////////////////////////////////////////
|
|
// ders_oe_trigger - Deva's Encounter Replacement System
|
|
// By Deva B. Winblood. August 17th, 2008
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*------------------------------------------------------------------------------
|
|
[=== SYSTEM DEFINITION ===]
|
|
ON TRIGGER:
|
|
nWhoCanTrigger: 0=Anyone, 1=PCs Only, 2=if string value,3=if
|
|
specific Integer value, 4= PC and string, 5= PC and integer.
|
|
sStringTrigger: string variable name/value must equal
|
|
nIntegerTrigger: integer variable name/value must equal
|
|
nTriggerScaling: 0=Always the same, 1=Based on triggering Level,2=Based on
|
|
highest level PC connected to module's level.
|
|
sEncounterTableNight: This is the name of a variable on this trigger less a
|
|
value of 1 appended to end or it is the tag of a waypoint. The waypoint
|
|
must have a variable sEncounter1 on it.
|
|
sEncounterTableDay: Same as above. Only triggered during the day.
|
|
nSpawnLocations: Number of standard spawn locations
|
|
nSpawnInLocations: Number of spawn in at a distance and run to spawn location
|
|
locations
|
|
sSpawnLocation#: Either a waypoint tag or x/y coordinates
|
|
sSpawnInLocation#: Either a waypoint tag or x/y coordinates
|
|
nRespawnHours: Number of hours until respawn possible.
|
|
|
|
ENCOUNTER TABLE:
|
|
sEncounter# or variable# (see above): percentage/encounter.percentage/enc
|
|
# above should correspond to level of PC. Note: you can skip numbers and
|
|
it will pick the lowest # that is closest to the PC that it can find.
|
|
percentage = % chance this encounter happens
|
|
encounter = Waypoint Tag or a # on this trigger.
|
|
sEncNum#: Type/Despawn/SpawnIn/MinPop/MaxPop/Appear/Move/Identifier
|
|
# above will be the encounter number for the trigger or 1 if a waypoint.
|
|
Type = G for Group or C for Creature (see Identifier)
|
|
Despawn = D for day, N for night, P for when no PCs, # num hours, 0 never
|
|
SpawnIn = S for standard, A for ambush, D for distant using Spawn In
|
|
MinPop = Minimum number to spawn
|
|
MaxPop = Maximum number to spawn
|
|
Appear = S for standard, F for fly in if possible
|
|
Move = 0 for stationary, S for short (3 meters), M for medium (7 meters),
|
|
L for Long (14 meters), F for full area wander.
|
|
Identifier = Group Tag (variable or Waypoint tag) or ResRef for creature
|
|
sGroup1: or can be some other variable specified by identifier
|
|
MoveAs.Population/ResRef.Population/ResRef
|
|
MoveAs = How to move G for as group, S for separately
|
|
Population = How many to spawn
|
|
ResRef = ResRef of Creature
|
|
------------------------------------------------------------------------------*/
|
|
|
|
#include "x3_inc_string"
|
|
#include "x0_i0_position"
|
|
#include "lib_hos2_shpath"
|
|
|
|
/////////////////////////
|
|
// PROTOTYPES
|
|
/////////////////////////
|
|
|
|
int fnGetAbsoluteHour();
|
|
void fnSpawn(object oTrigger,object oCreature,string sTriggerID);
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void main()
|
|
{
|
|
object oTrigger=OBJECT_SELF;
|
|
object oCreature=GetEnteringObject();
|
|
vector vPosTrigger=GetPosition(oTrigger);
|
|
int nX=FloatToInt(vPosTrigger.x);
|
|
int nY=FloatToInt(vPosTrigger.y);
|
|
string sX=IntToString(nX);
|
|
string sY=IntToString(nY);
|
|
// Trigger ID is the tag assigned to all creatures spawned by this trigger
|
|
// which makes it easier to track populations.
|
|
string sTriggerID=GetResRef(GetArea(oTrigger));
|
|
if (GetStringLength(sTriggerID)>8) sTriggerID=GetStringLeft(sTriggerID,4)+GetStringRight(sTriggerID,4);
|
|
sTriggerID=sTriggerID+sX+"_"+sY;
|
|
if (!GetIsDM(oCreature))
|
|
{ // not a DM
|
|
int bTriggerOkay=FALSE;
|
|
int nWhoCanTrigger=GetLocalInt(oTrigger,"nWhoCanTrigger");
|
|
if (nWhoCanTrigger==0&&GetTag(oCreature)!=sTriggerID) bTriggerOkay=TRUE;
|
|
else if (nWhoCanTrigger==1&&GetIsPC(oCreature)) bTriggerOkay=TRUE;
|
|
else if (nWhoCanTrigger==2)
|
|
{ // specific string
|
|
string sValue=GetLocalString(oTrigger,"sStringTrigger");
|
|
string sString=StringParse(sValue,"/");
|
|
sValue=StringRemoveParsed(sString,sValue,"/");
|
|
if (GetLocalString(oCreature,sString)==sValue) bTriggerOkay=TRUE;
|
|
} // specific string
|
|
else if (nWhoCanTrigger==3)
|
|
{ // specific integer
|
|
string sValue=GetLocalString(oTrigger,"sIntegerTrigger");
|
|
string sString=StringParse(sValue,"/");
|
|
sValue=StringRemoveParsed(sString,sValue,"/");
|
|
if (GetLocalInt(oCreature,sString)==StringToInt(sValue)) bTriggerOkay=TRUE;
|
|
} // specific integer
|
|
else if (nWhoCanTrigger==4&&GetIsPC(oCreature))
|
|
{ // PC and specific string
|
|
string sValue=GetLocalString(oTrigger,"sStringTrigger");
|
|
string sString=StringParse(sValue,"/");
|
|
sValue=StringRemoveParsed(sString,sValue,"/");
|
|
if (GetLocalString(oCreature,sString)==sValue) bTriggerOkay=TRUE;
|
|
} // PC and specific string
|
|
else if (nWhoCanTrigger==5&&GetIsPC(oCreature))
|
|
{ // PC and specific integer
|
|
string sValue=GetLocalString(oTrigger,"sIntegerTrigger");
|
|
string sString=StringParse(sValue,"/");
|
|
sValue=StringRemoveParsed(sString,sValue,"/");
|
|
if (GetLocalInt(oCreature,sString)==StringToInt(sValue)) bTriggerOkay=TRUE;
|
|
} // PC and specific integer
|
|
if (bTriggerOkay)
|
|
{ // the entering target can trigger
|
|
object oOb=GetNearestObjectByTag(sTriggerID,oCreature);
|
|
if (!GetIsObjectValid(oOb))
|
|
{ // no spawned creatures left - okay to spawn if time is good
|
|
int nLast=GetLocalInt(oTrigger,"nNextSpawnHour");
|
|
if (fnGetAbsoluteHour()>=nLast)
|
|
{ // okay to spawn
|
|
fnSpawn(oTrigger,oCreature,sTriggerID);
|
|
} // okay to spawn
|
|
} // no spawned creatures left - okay to spawn if time is good
|
|
} // the entering target can trigger
|
|
} // not a DM
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
/////////////////////////
|
|
// FUNCTIONS
|
|
/////////////////////////
|
|
|
|
|
|
void fnPossessive()
|
|
{ // PURPOSE: Possessive script
|
|
object oMe=OBJECT_SELF;
|
|
location lHome=GetLocalLocation(oMe,"lHome");
|
|
string sDespawn=GetLocalString(oMe,"sDespawn");
|
|
string sMove=GetLocalString(oMe,"sMove");
|
|
object oTrigger=GetLocalObject(oMe,"oTrigger");
|
|
location lLastStood=GetLocalLocation(oMe,"lLastStood");
|
|
if (!GetIsInCombat(oMe)&&!IsInConversation(oMe)&&!GetIsDMPossessed(oMe))
|
|
{ // okay to proceed
|
|
object oOb=GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,oMe);
|
|
if (GetIsObjectValid(oOb))
|
|
{ // PC is in the area
|
|
// SendMessageToPC(oOb,"[ders_oe_trigger] fnPossessive("+GetName(oMe)+") sDespawn='"+sDespawn+"'");
|
|
if (!GetObjectSeen(oOb,oMe))
|
|
{ // PC cannot see - okay to despawn
|
|
//SendMessageToPC(oOb,"sDespawn='"+sDespawn+"' Day:"+IntToString(GetIsDay())+" Night:"+IntToString(GetIsNight())+" AbsoluteHour:"+IntToString(fnGetAbsoluteHour()));
|
|
if (sDespawn=="D"&&GetIsDay()) DestroyObject(oMe);
|
|
else if (sDespawn=="N"&&GetIsNight()) DestroyObject(oMe);
|
|
else if (StringToInt(sDespawn)>0)
|
|
{ // check time
|
|
if (fnGetAbsoluteHour()>=StringToInt(sDespawn)) DestroyObject(oMe);
|
|
} // check time
|
|
} // PC cannot see - okay to despawn
|
|
if (sMove=="S")
|
|
{ // short
|
|
if (GetDistanceBetweenLocations(GetLocation(oMe),lLastStood)<1.0)
|
|
{ // choose new
|
|
lHome=MoveGetRandomLocation(lHome,6);
|
|
ClearAllActions();
|
|
MoveToLocation(oMe,lHome,FALSE,1.0);
|
|
} // choose new
|
|
SetLocalLocation(oMe,"lLastStood",GetLocation(oMe));
|
|
} // short
|
|
else if (sMove=="M")
|
|
{ // medium
|
|
if (GetDistanceBetweenLocations(GetLocation(oMe),lLastStood)<1.0)
|
|
{ // choose new
|
|
lHome=MoveGetRandomLocation(lHome,14);
|
|
ClearAllActions();
|
|
MoveToLocation(oMe,lHome,FALSE,1.0);
|
|
} // choose new
|
|
SetLocalLocation(oMe,"lLastStood",GetLocation(oMe));
|
|
} // medium
|
|
else if (sMove=="L")
|
|
{ // long
|
|
if (GetDistanceBetweenLocations(GetLocation(oMe),lLastStood)<1.0)
|
|
{ // choose new
|
|
lHome=MoveGetRandomLocation(lHome,28);
|
|
ClearAllActions();
|
|
MoveToLocation(oMe,lHome,FALSE,1.0);
|
|
} // choose new
|
|
SetLocalLocation(oMe,"lLastStood",GetLocation(oMe));
|
|
} // long
|
|
else if (sMove=="F")
|
|
{ // free
|
|
if (GetDistanceBetweenLocations(GetLocation(oMe),lLastStood)<1.0)
|
|
{ // choose new
|
|
lHome=MoveGetRandomLocation(lHome,999);
|
|
ClearAllActions();
|
|
MoveToLocation(oMe,lHome,FALSE,1.0);
|
|
} // choose new
|
|
} // free
|
|
else if (sMove=="0")
|
|
{ // stationary at trigger
|
|
if (GetDistanceBetweenLocations(lHome,GetLocation(oMe))>5.0)
|
|
{ // move home
|
|
AssignCommand(oMe,ClearAllActions());
|
|
MoveToLocation(oMe,lHome,TRUE);
|
|
} // move home
|
|
} // stationary at trigger
|
|
DelayCommand(6.0,fnPossessive());
|
|
} // PC is in the area
|
|
else
|
|
{ // no PC in area
|
|
if (sDespawn=="D"&&GetIsDay()) DestroyObject(oMe);
|
|
else if (sDespawn=="N"&&GetIsNight()) DestroyObject(oMe);
|
|
else if (sDespawn=="P") DestroyObject(oMe);
|
|
else if (sDespawn!="0")
|
|
{ // check time
|
|
if (fnGetAbsoluteHour()>=StringToInt(sDespawn)) DestroyObject(oMe);
|
|
} // check time
|
|
DelayCommand(10.0,fnPossessive());
|
|
} // no PC in area
|
|
} // okay to proceed
|
|
else
|
|
{ // busy
|
|
DelayCommand(10.0,fnPossessive());
|
|
} // busy
|
|
} // fnPossessive()
|
|
|
|
|
|
void fnPossessiveGroup()
|
|
{ // PURPOSE: Possessive Group
|
|
object oMe=OBJECT_SELF;
|
|
object oTrigger=GetLocalObject(oMe,"oTrigger");
|
|
object oGroupLead=GetLocalObject(oTrigger,"oGroupLead");
|
|
if (!GetIsObjectValid(oGroupLead))
|
|
{ // I am leader
|
|
SetLocalObject(oTrigger,"oGroupLead",oMe);
|
|
oGroupLead=oMe;
|
|
} // I am leader
|
|
location lHome=GetLocalLocation(oMe,"lHome");
|
|
string sDespawn=GetLocalString(oMe,"sDespawn");
|
|
string sMove=GetLocalString(oMe,"sMove");
|
|
location lLastStood=GetLocalLocation(oMe,"lLastStood");
|
|
if (!GetIsInCombat(oMe)&&!IsInConversation(oMe)&&!GetIsDMPossessed(oMe))
|
|
{ // okay to proceed
|
|
object oOb=GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,oMe);
|
|
if (GetIsObjectValid(oOb))
|
|
{ // PC is in the area
|
|
if (!GetObjectSeen(oOb,oMe))
|
|
{ // PC cannot see - okay to despawn
|
|
if (sDespawn=="D"&&GetIsDay()) DestroyObject(oMe);
|
|
else if (sDespawn=="N"&&GetIsNight()) DestroyObject(oMe);
|
|
else if (StringToInt(sDespawn)>0)
|
|
{ // check time
|
|
if (fnGetAbsoluteHour()>=StringToInt(sDespawn)) DestroyObject(oMe);
|
|
} // check time
|
|
} // PC cannot see - okay to despawn
|
|
if (oGroupLead==oMe)
|
|
{ // I am leader
|
|
if (sMove=="S")
|
|
{ // short
|
|
if (GetDistanceBetweenLocations(GetLocation(oMe),lLastStood)<1.0)
|
|
{ // choose new
|
|
lHome=MoveGetRandomLocation(lHome,6);
|
|
ClearAllActions();
|
|
MoveToLocation(oMe,lHome,FALSE,1.0);
|
|
} // choose new
|
|
SetLocalLocation(oMe,"lLastStood",GetLocation(oMe));
|
|
} // short
|
|
else if (sMove=="M")
|
|
{ // medium
|
|
if (GetDistanceBetweenLocations(GetLocation(oMe),lLastStood)<1.0)
|
|
{ // choose new
|
|
lHome=MoveGetRandomLocation(lHome,14);
|
|
ClearAllActions();
|
|
MoveToLocation(oMe,lHome,FALSE,1.0);
|
|
} // choose new
|
|
SetLocalLocation(oMe,"lLastStood",GetLocation(oMe));
|
|
} // medium
|
|
else if (sMove=="L")
|
|
{ // long
|
|
if (GetDistanceBetweenLocations(GetLocation(oMe),lLastStood)<1.0)
|
|
{ // choose new
|
|
lHome=MoveGetRandomLocation(lHome,28);
|
|
ClearAllActions();
|
|
MoveToLocation(oMe,lHome,FALSE,1.0);
|
|
} // choose new
|
|
SetLocalLocation(oMe,"lLastStood",GetLocation(oMe));
|
|
} // long
|
|
else if (sMove=="F")
|
|
{ // free
|
|
if (GetDistanceBetweenLocations(GetLocation(oMe),lLastStood)<1.0)
|
|
{ // choose new
|
|
lHome=MoveGetRandomLocation(lHome,999);
|
|
ClearAllActions();
|
|
MoveToLocation(oMe,lHome,FALSE,1.0);
|
|
} // choose new
|
|
} // free
|
|
else if (sMove=="0")
|
|
{ // stationary at trigger
|
|
if (GetDistanceBetweenLocations(lHome,GetLocation(oMe))>5.0)
|
|
{ // move home
|
|
AssignCommand(oMe,ClearAllActions());
|
|
MoveToLocation(oMe,lHome,TRUE);
|
|
} // move home
|
|
} // stationary at trigger
|
|
} // I am leader
|
|
else
|
|
{ // follow leader
|
|
if (GetDistanceBetween(oMe,oGroupLead)>6.0)
|
|
{ // move
|
|
AssignCommand(oMe,ClearAllActions());
|
|
AssignCommand(oMe,ActionMoveToObject(oGroupLead,TRUE,4.0));
|
|
} // move
|
|
} // follow leader
|
|
DelayCommand(6.0,fnPossessive());
|
|
} // PC is in the area
|
|
else
|
|
{ // no PC in area
|
|
if (sDespawn=="D"&&GetIsDay()) DestroyObject(oMe);
|
|
else if (sDespawn=="N"&&GetIsNight()) DestroyObject(oMe);
|
|
else if (sDespawn=="P") DestroyObject(oMe);
|
|
else if (sDespawn!="0")
|
|
{ // check time
|
|
if (fnGetAbsoluteHour()>=StringToInt(sDespawn)) DestroyObject(oMe);
|
|
} // check time
|
|
DelayCommand(10.0,fnPossessive());
|
|
} // no PC in area
|
|
} // okay to proceed
|
|
else
|
|
{ // not okay
|
|
DelayCommand(10.0,fnPossessiveGroup());
|
|
} // not okay
|
|
} // fnPossessiveGroup()
|
|
|
|
|
|
|
|
int fnGetLevel(object oPC)
|
|
{ // PURPOSE: return this PCs level
|
|
return GetLevelByPosition(1,oPC)+GetLevelByPosition(2,oPC)+GetLevelByPosition(3,oPC);
|
|
} // fnGetLevel()
|
|
|
|
|
|
int fnGetHighestLevelofPCs()
|
|
{ // PURPOSE: Return the highest level of all PCs connected excluding DMs
|
|
int nHighest=1;
|
|
int nLevel;
|
|
object oPC=GetFirstPC();
|
|
while(GetIsObjectValid(oPC))
|
|
{ // traverse PCs
|
|
if (!GetIsDM(oPC))
|
|
{ // not a DM
|
|
nLevel=fnGetLevel(oPC);
|
|
if (nLevel>nHighest) nHighest=nLevel;
|
|
} // not a DM
|
|
oPC=GetNextPC();
|
|
} // traverse PCs
|
|
return nHighest;
|
|
} // fnGetHighestLevelofPCs()
|
|
|
|
|
|
location fnGetTheLocation(object oArea,object oTrigger,string sValue)
|
|
{ // PURPOSE: Get location from sValue
|
|
location lLoc=GetLocation(oTrigger);
|
|
vector vPos;
|
|
string sS;
|
|
string sParse;
|
|
int nX;
|
|
int nY;
|
|
vector vTriggerPos=GetPosition(oTrigger);
|
|
object oWP=GetNearestObjectByTag(sValue,oTrigger);
|
|
if (GetIsObjectValid(oWP)&&GetObjectType(oWP)==OBJECT_TYPE_WAYPOINT) return GetLocation(oWP);
|
|
sParse=StringParse(sValue,"/");
|
|
sS=StringRemoveParsed(sValue,sParse,"/");
|
|
nX=StringToInt(sParse);
|
|
nY=StringToInt(sS);
|
|
vPos.x=IntToFloat(nX);
|
|
vPos.y=IntToFloat(nY);
|
|
vPos.z=vTriggerPos.z;
|
|
lLoc=Location(oArea,vPos,IntToFloat(Random(360)));
|
|
return lLoc;
|
|
} // fnGetLocation()
|
|
|
|
|
|
location fnFindSpawnIn(object oTrigger,object oCreature,string sSpawnIn)
|
|
{ // PURPOSE: Return Location to spawn in at
|
|
location lLoc=GetLocation(oTrigger);
|
|
object oArea=GetArea(oCreature);
|
|
location lCreature=GetLocation(oCreature);
|
|
int nN;
|
|
int nChoice;
|
|
float fDist;
|
|
object oWP;
|
|
int nCount;
|
|
location lTest;
|
|
string sS;
|
|
string sParse;
|
|
vector vPos;
|
|
vPos=GetPosition(oCreature);
|
|
vPos.z=vPos.z+0.1;
|
|
if (sSpawnIn=="S")
|
|
{ // standard - farthest
|
|
fDist=0.0;
|
|
nCount=GetLocalInt(oTrigger,"nSpawnLocations");
|
|
nN=1;
|
|
sS=GetLocalString(oTrigger,"sSpawnLocation"+IntToString(nN));
|
|
while(GetStringLength(sS)>0&&nN<=nCount)
|
|
{ // purpose find farthest from oCreature
|
|
oWP=GetNearestObjectByTag(sS,oCreature);
|
|
if (GetIsObjectValid(oWP)&&GetObjectType(oWP)==OBJECT_TYPE_WAYPOINT)
|
|
{ // waypoint
|
|
if (GetDistanceBetweenLocations(lCreature,GetLocation(oWP))>fDist)
|
|
{ // farther
|
|
fDist=GetDistanceBetweenLocations(lCreature,GetLocation(oWP));
|
|
lLoc=GetLocation(oWP);
|
|
} // farther
|
|
} // waypoint
|
|
else
|
|
{ // coordinates
|
|
sParse=StringParse(sS,"/");
|
|
sS=StringRemoveParsed(sS,sParse,"/");
|
|
vPos.x=IntToFloat(StringToInt(sParse));
|
|
vPos.y=IntToFloat(StringToInt(sS));
|
|
//SendMessageToPC(oCreature," #"+IntToString(nN)+"/"+IntToString(nCount)+" x:"+FloatToString(vPos.x)+", y:"+FloatToString(vPos.y)+", z:"+FloatToString(vPos.z));
|
|
lTest=Location(oArea,vPos,0.0);
|
|
if (GetDistanceBetweenLocations(lTest,lCreature)>fDist)
|
|
{ // farther
|
|
fDist=GetDistanceBetweenLocations(lTest,lCreature);
|
|
lLoc=lTest;
|
|
} // farther
|
|
} // coordinates
|
|
nN++;
|
|
sS=GetLocalString(oTrigger,"sSpawnLocation"+IntToString(nN));
|
|
} // purpose find farthest from oCreature
|
|
} // standard - farthest
|
|
else if (sSpawnIn=="A")
|
|
{ // ambush - closest
|
|
fDist=9000.0;
|
|
nCount=GetLocalInt(oTrigger,"nSpawnLocations");
|
|
nN=1;
|
|
sS=GetLocalString(oTrigger,"sSpawnLocation"+IntToString(nN));
|
|
while(GetStringLength(sS)>0&&nN<=nCount)
|
|
{ // purpose find closest to oCreature
|
|
oWP=GetNearestObjectByTag(sS,oCreature);
|
|
if (GetIsObjectValid(oWP)&&GetObjectType(oWP)==OBJECT_TYPE_WAYPOINT)
|
|
{ // waypoint
|
|
if (GetDistanceBetweenLocations(lCreature,GetLocation(oWP))<fDist)
|
|
{ // closer
|
|
fDist=GetDistanceBetweenLocations(lCreature,GetLocation(oWP));
|
|
lLoc=GetLocation(oWP);
|
|
} // closer
|
|
} // waypoint
|
|
else
|
|
{ // coordinates
|
|
sParse=StringParse(sS,"/");
|
|
sS=StringRemoveParsed(sS,sParse,"/");
|
|
vPos.x=IntToFloat(StringToInt(sParse));
|
|
vPos.y=IntToFloat(StringToInt(sS));
|
|
lTest=Location(oArea,vPos,0.0);
|
|
if (GetDistanceBetweenLocations(lTest,lCreature)<fDist)
|
|
{ // closer
|
|
fDist=GetDistanceBetweenLocations(lTest,lCreature);
|
|
lLoc=lTest;
|
|
} // closer
|
|
} // coordinates
|
|
nN++;
|
|
sS=GetLocalString(oTrigger,"sSpawnLocation"+IntToString(nN));
|
|
} // purpose find closest to oCreature
|
|
} // ambush - closest
|
|
else if (sSpawnIn=="D")
|
|
{ // distant - move towards
|
|
nCount=GetLocalInt(oTrigger,"nSpawnInLocations");
|
|
if (nCount>0)
|
|
{ // count exists
|
|
nN=Random(nCount)+1;
|
|
sS=GetLocalString(oTrigger,"sSpawnInLocation"+IntToString(nN));
|
|
oWP=GetNearestObjectByTag(sS,oCreature);
|
|
if (GetIsObjectValid(oWP)&&GetObjectType(oWP)==OBJECT_TYPE_WAYPOINT) lLoc=GetLocation(oWP);
|
|
else
|
|
{ // coordinates
|
|
sParse=StringParse(sS,"/");
|
|
sS=StringRemoveParsed(sS,sParse,"/");
|
|
vPos.x=IntToFloat(StringToInt(sParse));
|
|
vPos.y=IntToFloat(StringToInt(sS));
|
|
lLoc=Location(oArea,vPos,IntToFloat(Random(360)));
|
|
} // coordinates
|
|
} // count exists
|
|
} // distant - move towards
|
|
//vPos=GetPositionFromLocation(lLoc);
|
|
//SendMessageToPC(oCreature," Location Returned: x:"+FloatToString(vPos.x)+", y:"+FloatToString(vPos.y)+", z:"+FloatToString(vPos.z));
|
|
return lLoc;
|
|
} // fnFindSpawnIn()
|
|
|
|
|
|
void fnProcess(object oTrigger,object oCreature,string sTriggerID,string sType,string sDespawn,string sSpawnIn,int nMinPop,int nMaxPop,string sAppear,string sMove,string sIdentifier,object oWP=OBJECT_INVALID)
|
|
{ // PROCESS: A specific encounter
|
|
int bUseWaypoint=FALSE;
|
|
if (GetIsObjectValid(oWP)&&GetTag(oWP)==sIdentifier) bUseWaypoint=TRUE;
|
|
int bAppear=FALSE;
|
|
int nCount=1;
|
|
int nN;
|
|
int nHour;
|
|
int nRandom=nMinPop+Random(nMaxPop-nMinPop);
|
|
if (nRandom<1) nRandom=1;
|
|
object oSpawn;
|
|
location lSpawn;
|
|
//SendMessageToPC(oCreature,"[ders_oe_trigger] sType='"+sType+"' sDespawn='"+sDespawn+"' sSpawnIn='"+sSpawnIn+"' nMinPop="+IntToString(nMinPop)+" nMaxPop="+IntToString(nMaxPop)+" sAppear='"+sAppear+"' sMove='"+sMove+"' sIdentifier='"+sIdentifier+"' oWP='"+GetTag(oWP)+"'");
|
|
if (sAppear=="F") bAppear=TRUE;
|
|
if (sType=="G")
|
|
{ // group
|
|
string sGroup;
|
|
if (GetIsObjectValid(oWP)) sGroup=GetLocalString(oWP,sIdentifier);
|
|
if (GetStringLength(sGroup)<1) sGroup=GetLocalString(oTrigger,sIdentifier);
|
|
if (GetStringLength(sGroup)<1)
|
|
{ // waypoint
|
|
oSpawn=GetWaypointByTag(sIdentifier);
|
|
if (GetIsObjectValid(oSpawn))
|
|
{ // waypoint found
|
|
sGroup=GetLocalString(oSpawn,"sGroup1");
|
|
} // waypoint found
|
|
} // waypoint
|
|
if (GetStringLength(sGroup)>0)
|
|
{ // group found
|
|
string sMoveAs=StringParse(sGroup,".");
|
|
string sRemains=StringRemoveParsed(sGroup,sMoveAs,".");
|
|
string sParse;
|
|
string sSection;
|
|
string sCount;
|
|
lSpawn=fnFindSpawnIn(oTrigger,oCreature,sSpawnIn);
|
|
nHour=fnGetAbsoluteHour()+StringToInt(sDespawn);
|
|
sParse=StringParse(sRemains,".");
|
|
while(GetStringLength(sRemains)>0)
|
|
{ // spawn group
|
|
sSection=sParse;
|
|
sCount=StringParse(sSection,"/");
|
|
sSection=StringRemoveParsed(sSection,sCount,"/");
|
|
nCount=StringToInt(sCount);
|
|
if (nCount>0&&GetStringLength(sSection)>0)
|
|
{ // spawn group members
|
|
nN=1;
|
|
while(nN<=nCount)
|
|
{ // spawn this group member
|
|
oSpawn=CreateObject(OBJECT_TYPE_CREATURE,sSection,lSpawn,bAppear,sTriggerID);
|
|
if (StringToInt(sDespawn)>0)
|
|
{ // set hour to despawn
|
|
DelayCommand(0.1,SetLocalString(oSpawn,"sDespawn",IntToString(nHour)));
|
|
} // set hour to despawn
|
|
else
|
|
{ // other
|
|
DelayCommand(0.1,SetLocalString(oSpawn,"sDespawn",sDespawn));
|
|
} // other
|
|
SetLocalString(oSpawn,"sMove",sMove);
|
|
SetLocalLocation(oSpawn,"lHome",lSpawn);
|
|
SetLocalObject(oSpawn,"oTrigger",oTrigger);
|
|
DelayCommand(1.0,AssignCommand(oSpawn,fnPossessiveGroup()));
|
|
nN++;
|
|
} // spawn this group member
|
|
} // spawn group members
|
|
sRemains=StringRemoveParsed(sRemains,sParse,".");
|
|
sParse=StringParse(sRemains,".");
|
|
} // spawn group
|
|
} // group found
|
|
else
|
|
{ // error
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Invalid group '"+sIdentifier+"'");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Invalid group '"+sIdentifier+"'");
|
|
return;
|
|
} // error
|
|
} // group
|
|
else
|
|
{ // creature
|
|
lSpawn=fnFindSpawnIn(oTrigger,oCreature,sSpawnIn);
|
|
vector vDebug=GetPositionFromLocation(lSpawn);
|
|
//SendMessageToPC(oCreature,"Spawn '"+sSpawnIn+"' x:"+FloatToString(vDebug.x)+", y:"+FloatToString(vDebug.y)+", z:"+FloatToString(vDebug.z));
|
|
while(nCount<=nRandom)
|
|
{ // spawn
|
|
//SendMessageToPC(oCreature," Spawn"+IntToString(nCount)+" '"+sIdentifier+"' bAppear="+IntToString(bAppear)+" sDespawn='"+sDespawn+"'");
|
|
oSpawn=CreateObject(OBJECT_TYPE_CREATURE,sIdentifier,lSpawn,bAppear,sTriggerID);
|
|
if (!GetIsObjectValid(oSpawn)) SendMessageToPC(oCreature," Failed to spawn.");
|
|
if (StringToInt(sDespawn)>0)
|
|
{ // set hour to despawn
|
|
nHour=fnGetAbsoluteHour()+StringToInt(sDespawn);
|
|
DelayCommand(0.1,SetLocalString(oSpawn,"sDespawn",IntToString(nHour)));
|
|
} // set hour to despawn
|
|
else
|
|
{ // other
|
|
DelayCommand(0.1,SetLocalString(oSpawn,"sDespawn",sDespawn));
|
|
} // other
|
|
SetLocalString(oSpawn,"sMove",sMove);
|
|
SetLocalLocation(oSpawn,"lHome",lSpawn);
|
|
SetLocalObject(oSpawn,"oTrigger",oTrigger);
|
|
DelayCommand(1.0,AssignCommand(oSpawn,fnPossessive()));
|
|
nCount++;
|
|
} // spawn
|
|
} // creature
|
|
} // fnProcess()
|
|
|
|
|
|
|
|
void fnProcessEncounter(object oTrigger,object oCreature,string sTriggerID,string sEncounter,object oWP=OBJECT_INVALID)
|
|
{ // PURPOSE: Process encounter
|
|
string sEnc;
|
|
int nN;
|
|
object oWaypoint=oWP;
|
|
object oOb;
|
|
nN=StringToInt(sEncounter);
|
|
if (nN>0)
|
|
{ // numeric
|
|
if (GetIsObjectValid(oWP)) sEnc=GetLocalString(oWaypoint,"sEncNum"+IntToString(nN));
|
|
if (GetStringLength(sEnc)<1) sEnc=GetLocalString(oTrigger,"sEncNum"+IntToString(nN));
|
|
} // numeric
|
|
else
|
|
{ // waypoint
|
|
oOb=GetWaypointByTag(sEncounter);
|
|
if (GetIsObjectValid(oOb))
|
|
{ // waypoint
|
|
sEnc=GetLocalString(oOb,"sEncNum1");
|
|
if (GetStringLength(sEnc)>0) oWaypoint=oOb;
|
|
} // waypoint
|
|
} // waypoint
|
|
if (GetStringLength(sEnc)>0)
|
|
{ // encounter found
|
|
// Type/Despawn/SpawnIn/MinPop/MaxPop/Appear/Move/Identifier
|
|
string sType;
|
|
string sDespawn;
|
|
string sSpawnIn;
|
|
string sMinPop;
|
|
string sMaxPop;
|
|
string sAppear;
|
|
string sMove;
|
|
string sIdentifier;
|
|
sType=GetStringUpperCase(StringParse(sEnc,"/"));
|
|
sEnc=StringRemoveParsed(sEnc,sType,"/");
|
|
sDespawn=GetStringUpperCase(StringParse(sEnc,"/"));
|
|
sEnc=StringRemoveParsed(sEnc,sDespawn,"/");
|
|
sSpawnIn=GetStringUpperCase(StringParse(sEnc,"/"));
|
|
sEnc=StringRemoveParsed(sEnc,sSpawnIn,"/");
|
|
sMinPop=StringParse(sEnc,"/");
|
|
sEnc=StringRemoveParsed(sEnc,sMinPop,"/");
|
|
sMaxPop=StringParse(sEnc,"/");
|
|
sEnc=StringRemoveParsed(sEnc,sMaxPop,"/");
|
|
sAppear=GetStringUpperCase(StringParse(sEnc,"/"));
|
|
sEnc=StringRemoveParsed(sEnc,sAppear,"/");
|
|
sMove=GetStringUpperCase(StringParse(sEnc,"/"));
|
|
sIdentifier=StringRemoveParsed(sEnc,sMove,"/");
|
|
if (sType!="G"&&sType!="C")
|
|
{ // error
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid type '"+sType+"'");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid type '"+sType+"'");
|
|
return;
|
|
} // error
|
|
else if (GetStringLength(sDespawn)<1)
|
|
{ // error
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid Despawn");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid Despawn");
|
|
return;
|
|
} // error
|
|
else if (sSpawnIn!="S"&&sSpawnIn!="A"&&sSpawnIn!="D")
|
|
{ // error
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid SpawnIn '"+sSpawnIn+"'");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid SpawnIn '"+sSpawnIn+"'");
|
|
return;
|
|
} // error
|
|
else if (StringToInt(sMinPop)<1)
|
|
{ // error
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid MinPop must at least be 1.");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid MinPop must at least be 1.");
|
|
return;
|
|
} // error
|
|
else if (StringToInt(sMaxPop)<1||StringToInt(sMaxPop)<StringToInt(sMinPop))
|
|
{ // error
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid MaxPop must at least be equal to MinPop.");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid MaxPop must at least be equal to MinPop.");
|
|
return;
|
|
} // error
|
|
else if (sAppear!="S"&&sAppear!="F")
|
|
{ // error
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid Appear '"+sAppear+"'");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid Appear '"+sAppear+"'");
|
|
return;
|
|
} // error
|
|
else if (sMove!="0"&&sMove!="S"&&sMove!="M"&&sMove!="L"&&sMove!="F")
|
|
{ // error
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid Move '"+sMove+"'");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid Move '"+sMove+"'");
|
|
return;
|
|
} // error
|
|
else if (GetStringLength(sIdentifier)<1)
|
|
{ // error
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid Identifier");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"' Invalid Identifier");
|
|
return;
|
|
} // error
|
|
if (sType=="G")
|
|
{ // group
|
|
oOb=GetWaypointByTag(sIdentifier);
|
|
if (GetIsObjectValid(oOb))
|
|
{ // possible new waypoint
|
|
string sGroup=GetLocalString(oOb,"sGroup1");
|
|
if (GetStringLength(sGroup)>0) oWaypoint=oOb;
|
|
} // possible new waypoint
|
|
} // group
|
|
// Type/Despawn/SpawnIn/MinPop/MaxPop/Appear/Move/Identifier
|
|
fnProcess(oTrigger,oCreature,sTriggerID,sType,sDespawn,sSpawnIn,StringToInt(sMinPop),StringToInt(sMaxPop),sAppear,sMove,sIdentifier,oWaypoint);
|
|
} // encounter found
|
|
else
|
|
{ // error
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"'");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' Encounter '+"+sEncounter+"'");
|
|
} // error
|
|
} // fnProcessEncounter()
|
|
|
|
|
|
void fnProcessEncounterTable(object oTrigger,object oCreature,string sTriggerID,string sTable,object oWP=OBJECT_INVALID)
|
|
{ // PURPOSE: Process encounter table
|
|
int nTriggerScaling=GetLocalInt(oTrigger,"nTriggerScaling");
|
|
int nPosition=1; // position to spawn from
|
|
int nN;
|
|
int nLevel=1;
|
|
string sTableToProcess;
|
|
string sS;
|
|
string sLast;
|
|
if (nTriggerScaling==1) nLevel=fnGetLevel(oCreature);
|
|
else if (nTriggerScaling==2) nLevel=fnGetHighestLevelofPCs();
|
|
if (GetIsObjectValid(oWP))
|
|
{ // encounters from a waypoint
|
|
nN=nLevel;
|
|
sS=GetLocalString(oWP,"sEncounter"+IntToString(nN));
|
|
while(GetStringLength(sTableToProcess)<1&&nN>0)
|
|
{ // find table
|
|
if (GetStringLength(sS)>0) sTableToProcess=sS;
|
|
nN=nN-1;
|
|
sS=GetLocalString(oWP,"sEncounter"+IntToString(nN));
|
|
} // find table
|
|
} // encounters from a waypoint
|
|
else
|
|
{ // specific variables on trigger
|
|
nN=nLevel;
|
|
sS=GetLocalString(oTrigger,sTable+IntToString(nN));
|
|
while(GetStringLength(sTableToProcess)<1&&nN>0)
|
|
{ // find table
|
|
if (GetStringLength(sS)>0) sTableToProcess=sS;
|
|
nN=nN-1;
|
|
sS=GetLocalString(oTrigger,sTable+IntToString(nN));
|
|
} // find table
|
|
} // specific variables on trigger
|
|
if (GetStringLength(sTableToProcess)>0)
|
|
{ // table found
|
|
int nRoll=d100();
|
|
string sParse;
|
|
string sPercentage;
|
|
string sEncounter;
|
|
sParse=StringParse(sTableToProcess,".");
|
|
while(GetStringLength(sTableToProcess)>0)
|
|
{ // find encounter
|
|
sPercentage=StringParse(sParse,"/");
|
|
sEncounter=StringRemoveParsed(sParse,sPercentage,"/");
|
|
nN=StringToInt(sPercentage);
|
|
nRoll=nRoll-nN;
|
|
if (nRoll<1)
|
|
{ // process encounter
|
|
fnProcessEncounter(oTrigger,oCreature,sTriggerID,sEncounter,oWP);
|
|
return;
|
|
} // process encounter
|
|
sTableToProcess=StringRemoveParsed(sTableToProcess,sParse,".");
|
|
sParse=StringParse(sTableToProcess,".");
|
|
} // find encounter
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' table '+"+sTable+"' Encounter Table % failure.");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' table '+"+sTable+"' Encounter Table % failure.");
|
|
} // table found
|
|
else
|
|
{ // error
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' table '"+sTable+"'");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table error '"+sTriggerID+"' table '"+sTable+"'");
|
|
} // error
|
|
} // fnProcessEncounterTable()
|
|
|
|
|
|
void fnSpawn(object oTrigger,object oCreature,string sTriggerID)
|
|
{ // PURPOSE: Handle spawning the results of the trigger
|
|
int nRespawnHours=GetLocalInt(oTrigger,"nRespawnHours");
|
|
SetLocalInt(oTrigger,"nNextSpawnHour",fnGetAbsoluteHour()+nRespawnHours);
|
|
string sTable;
|
|
if (GetIsDay()) sTable=GetLocalString(oTrigger,"sEncounterTableDay");
|
|
else { sTable=GetLocalString(oTrigger,"sEncounterTableNight"); }
|
|
string sValue=GetLocalString(oTrigger,sTable+"1");
|
|
if (GetStringLength(sValue)>0)
|
|
{ // table found
|
|
//SendMessageToPC(oCreature,"[ders_oe_trigger] fnSpawn() sValue='"+sValue+"'");
|
|
fnProcessEncounterTable(oTrigger,oCreature,sTriggerID,sTable);
|
|
return;
|
|
} // table found
|
|
object oWP=GetWaypointByTag(sTable);
|
|
if (GetIsObjectValid(oWP))
|
|
{ // waypoint exists
|
|
sValue=GetLocalString(oWP,"sEncounter1");
|
|
if (GetStringLength(sValue)>0)
|
|
{ // table found
|
|
fnProcessEncounterTable(oTrigger,oCreature,sTriggerID,sValue,oWP);
|
|
return;
|
|
} // table found
|
|
} // waypoint exists
|
|
SendMessageToPC(oCreature,"Error [ders_oe_trigger] - Encounter table missing '"+sTriggerID+"'");
|
|
PrintString("Error [ders_oe_trigger] - Encounter table missing '"+sTriggerID+"'");
|
|
} // fnSpawn()
|
|
|
|
|
|
int fnGetAbsoluteHour()
|
|
{ // PURPOSE: Return Absolute Hour
|
|
return GetTimeHour()+(GetCalendarDay()*24)+(GetCalendarMonth()*24*30)+(GetCalendarYear()*24*30*12);
|
|
} // fnGetAbsoluteHour()
|