If I get the Idea of what you are tring to do. Here is the include I used for area Quakes, If it is of any help.
// Time Delays are is rounds.
// Min Should be at least the amount of time of the quakes.
// There are 10 rounds per minute
int MIN_RND_BETWEEN_QUAKES = 5; // 0.5 min
int MAX_RND_BETWEEN_QUAKES = 100; // 10 min
int MAX_LENGHT_OF_QUAKE = 4; // 9 sec
int INCREAS_DC_PER_LENGTH = 5; // For evey extra round the quake lasts add 5 to the DC.
// @ nDuration - the number of rounds the effect lasts for.
// creatures make a save every round.
// @ nDC - The DC for the reflex save to not fall down.
// @ oCenter - The Object the effect is centered at.
// - if oCenter is an area the function will pick an object to center on.
void QuakeEarth( int nDuration = 1, int nDC = 20 , object oCenter=OBJECT_SELF );
// If any of the arguments are set thy will override the Defaults set in the Include file.
void RandomQuakes(int nMinRnd = -1,int nMaxRnd = -1,int nMaxLength = -1 ,int IncDc = -1);
//Returns true if a PC is in the area.
int GetIsPCInArea(object oArea=OBJECT_SELF);
// Sets up a Delayed Quake Per the Constants above.
void SetUpQuake(int bForce= FALSE);
// Private function to the QuakeEarth function
void Fall( );
// @ nDuration - the number of rounds the effect lasts for.
// creatures make a save every round.
// @ nDC - The DC for the reflex save to not fall down.
// @ oCenter - The Object the effect is centered at.
// - if oCenter is an area the function will pick an object to center on.
void QuakeEarth( int nDuration = 1, int nDC = 20 , object oCenter=OBJECT_SELF );
// Privat function to make sure the Effect is seen buy all PC's in the area.
void ApplyShakeToArea(object oArea)
{
object oPC = GetFirstPC();
effect eShake = EffectVisualEffect(356);
int nCount= 0;
int i;
int bNotSeen;
while(GetIsObjectValid(oPC))
{
if (GetArea(oPC) == oArea)
{
bNotSeen=TRUE;
for(i=0;i<nCount;i++)
{
if (LineOfSightObject(GetLocalObject(OBJECT_SELF,"ShLoc"+IntToString(i)),oPC))
{
bNotSeen = FALSE;
break;
}
}
if (bNotSeen)
{
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eShake, GetLocation(oPC),4.5);
//fill in effect Dead spot if running more then one round.
DelayCommand(4.5,ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eShake, GetLocation(oPC),1.5));
SetLocalObject(OBJECT_SELF,"ShLoc"+IntToString(i),oPC);
nCount++;
}
}
oPC=GetNextPC();
}
// clean up unneeded locals
for (i=0;i<nCount;i++) DeleteLocalObject( OBJECT_SELF,"ShLoc"+IntToString(i));
}
void QuakeEarth( int nDuration = 1, int nDC = 20 , object oCenter=OBJECT_SELF )
{
int nCount;
int nSave;
float fDelay;
object oCreature;
// Adjust for if oCenter is running on the area and not an object.
if (GetArea( oCenter) == oCenter) oCenter=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,GetFirstObjectInArea(oCenter) ,1) ;
if (oCenter==OBJECT_INVALID) return;
ApplyShakeToArea(GetArea(oCenter));
// Set up for first time through kd loop.
if(GetObjectType(oCenter)== OBJECT_TYPE_CREATURE)
{
oCreature = oCenter;
nCount= 0;
}
else
{
oCreature = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oCenter ,1);
nCount = 1;
}
//Loop through creatures to see who falls down.
do
{
if (!ReflexSave(oCreature, nDC ))
{
fDelay= GetDistanceBetween (oCreature,oCenter);
fDelay= (fDelay /5 - FloatToInt(fDelay/5))*4;
DelayCommand ( fDelay ,AssignCommand (oCreature,Fall()));
}
nCount++;
oCreature=GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oCenter ,nCount );
}
while (GetIsObjectValid(oCreature));
nDuration--;
if( nDuration ) DelayCommand(6.0,QuakeEarth(nDuration, nDC-INCREAS_DC_PER_LENGTH, oCenter));
}
void Fall( )
{
int nAnination;
float fDelay=IntToFloat(Random(4)+2);
int nRoll = d4();
switch (nRoll)
{
case 1: nAnination = ANIMATION_LOOPING_DEAD_BACK; break;
case 2: nAnination = ANIMATION_LOOPING_DEAD_FRONT; break;
case 3: nAnination = ANIMATION_LOOPING_SIT_CROSS; break;
case 4: nAnination = ANIMATION_LOOPING_PAUSE_DRUNK; fDelay=fDelay/2; break;
}
ClearAllActions();
PlayAnimation(nAnination, 1.0 ,fDelay);
SetCommandable(FALSE);
DelayCommand( fDelay, SetCommandable(TRUE));
}
void SetUpQuake(int bForce= FALSE)
{
// set a random delay for PC just entering or still in the area.
if (( bForce || GetIsPCInArea()) && GetArea(OBJECT_SELF)== GetLocalObject(OBJECT_SELF,"QuakeArea") )
{
float fDelay = RoundsToSeconds( Random ( MAX_RND_BETWEEN_QUAKES - MIN_RND_BETWEEN_QUAKES )+ MIN_RND_BETWEEN_QUAKES);
int nLength = Random(MAX_LENGHT_OF_QUAKE)+1;
int nDC = INCREAS_DC_PER_LENGTH * (nLength-1) + 20;
DelayCommand (fDelay, QuakeEarth( nLength,nDC));
DelayCommand (fDelay+ 0.5 , SetUpQuake());
}
// no PC here so end the quakes
else
{
SetLocalInt(OBJECT_SELF,"TimmerRunning",FALSE);
//SendMessageToPC(GetFirstPC(),"quakes shutting down");
}
}
int GetIsPCInArea(object oArea=OBJECT_SELF)
{
object oPC = GetFirstPC();
oArea = GetArea(oArea);
while (GetIsObjectValid(oPC))
{
if (GetArea(oPC) == oArea) return TRUE;
oPC = GetNextPC();
}
return FALSE;
}
// If any of the arguments are set thy will override the Defaults set in the Include file.
void RandomQuakes(int nMinRnd = -1,int nMaxRnd = -1,int nMaxLength = -1 ,int IncDc = -1)
{
object oPC = GetEnteringObject();
int bTimmer = GetLocalInt(OBJECT_SELF,"TimmerRunning");
// exit if the timmer is already running or it is not a PC unless it is not being ran from the area.
if ( bTimmer || (!GetIsPC(oPC) && (GetArea(OBJECT_SELF)==OBJECT_SELF)) ) return;
// Set a Flag that the timmer is running.
SetLocalInt(OBJECT_SELF,"TimmerRunning",TRUE);
if(nMinRnd != -1) MIN_RND_BETWEEN_QUAKES = nMinRnd;
if(nMaxRnd != -1) MAX_RND_BETWEEN_QUAKES = nMaxRnd;
if(nMaxLength != -1) MAX_LENGHT_OF_QUAKE = nMaxLength;
if(IncDc != -1) INCREAS_DC_PER_LENGTH = IncDc;
SetLocalObject(OBJECT_SELF,"QuakeArea",GetArea(OBJECT_SELF));
SetUpQuake( TRUE );
}