Was working on this for my own purposes, but figured I'd share in case folks were looking for something similar to CoA's CARES.
/////////////Escape From Underdark Randomized-Encounters (EFURY)
/////////////Author : RavenBlackRose/Seth Carter
/////////////Date: 07/10/2005
/////////////Updated for Isles of Elysium
////////////////////////////////////////////////////
/////////////New Version Akylonor 2010, d100 Odds.
/////////////Called From:Area OnEnter
void SpawnEncounter(string sSpawn, location lSpawn)
{
string sDebugSpawn = "Encounter String:'" + sSpawn + "', ";
string sSubstring;
string sCritter;
//string reading function
int iPositionInString = 0;
int iStringLength = GetStringLength(sSpawn);
int iPositionInSubString = 0;
int iSubStringLength;
int iLastStop = 0;
int iMultipleCreatures;
int iCounter;
int iFoundInSubstring;
//read through the string
while(iPositionInString != iStringLength)
{
//stop at |
if(GetSubString(sSpawn, iPositionInString, 1) == "|")
{
//get the creature substring
sSubstring = GetSubString(sSpawn, iLastStop, iPositionInString-iLastStop);
sDebugSpawn += "Creature Substring: '" + sSubstring +"', ";
iLastStop = iPositionInString+1; //move the stop to the character after "|"
iMultipleCreatures = 1; //reset the check for a multiple creatures
//read through the substring
iPositionInSubString = 0;
iSubStringLength = GetStringLength(sSubstring);
iFoundInSubstring = 0;
while(iPositionInSubString != iSubStringLength)
{
if(GetSubString(sSubstring, iPositionInSubString, 1) == "*")
{
sCritter = GetSubString(sSubstring, 0, iPositionInSubString);
iMultipleCreatures = StringToInt(GetSubString(sSubstring, GetStringLength(sCritter)+1, GetStringLength(sSubstring)-(GetStringLength(sCritter)+1)));
iFoundInSubstring =1;
}
else
{
if(iFoundInSubstring != 1)
{
sCritter = sSubstring;
}
}
iPositionInSubString++;
}
//spawning function (complex, ain't it)
if(iMultipleCreatures == 1)
{
CreateObject(OBJECT_TYPE_CREATURE, sCritter, lSpawn, FALSE);
}
else
{
for(iCounter = 0; iCounter < iMultipleCreatures; iCounter++)
{
CreateObject(OBJECT_TYPE_CREATURE, sCritter, lSpawn, FALSE);
}
}
}
iPositionInString ++;
}
WriteTimestampedLogEntry(sDebugSpawn);
}
void main()
{
string sLocationDebug;
//load area, and dice
object oArea = OBJECT_SELF;
object oPC = GetEnteringObject();
int iLocationDice = GetLocalInt(oArea, "efury_spawnpoints");
int iSpawnDice = d100(1);
int iCondition = iLocationDice;
int iCounter = 0;
int iEncounterOdds;
int nOddsCounter;
int iEncounterChosen = 0;
//avoid bombarding parties
if(GetLocalInt(oArea, "RecentSpawned") == 0)
{
if(GetIsPC(oPC)) //prevents multispawns from companions, other monsters, DM's wandering about, etc
{
//run for as many times as there are possible spawnpoints
iCounter = 1;
while(iCounter <= iLocationDice)
{
string sLocation = "efury_spawnpoint_" + IntToString(iCounter);
sLocationDebug = "Area:'" + GetName(oArea) + "', " + "Location: '" + sLocation + "', ";
object oSomethingInArea = GetFirstObjectInArea(oArea);
object oSpawnPoint = GetNearestObjectByTag(sLocation, oPC);
location lToSpawn = GetLocation(oSpawnPoint);
//check around for creatures already spawned or PCs, so we don't doublespawn or drop on their heads
object oNearby = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, lToSpawn, TRUE, OBJECT_TYPE_CREATURE);
int iAnyoneAround = 0;
if(oNearby == OBJECT_INVALID) //no creatures/PCs in radius
{
nOddsCounter = 1;
iEncounterOdds = GetLocalInt (oArea, "efury_enc_chance_" + IntToString(nOddsCounter));
iEncounterChosen = 0;
iSpawnDice = d100(1); WriteTimestampedLogEntry("Spawn Roll =" + IntToString(iSpawnDice));
while(iEncounterOdds > 0 && iEncounterOdds < 101 && iEncounterChosen != 1)
{
if(iSpawnDice <= iEncounterOdds)
{
string sEncounter = "efury_encounter_" + IntToString(nOddsCounter);
sEncounter = GetLocalString(oArea, sEncounter);
if(sEncounter != "null" && sEncounter != "")
{
SpawnEncounter(sEncounter, lToSpawn);
}
else
{
sLocationDebug += "Encounter '" + sEncounter + "' is null, blank, or missing";
if(sEncounter == "null")
{
iEncounterChosen = 1;
}
}
iEncounterChosen = 1;
}
nOddsCounter = nOddsCounter +1;
iEncounterOdds = GetLocalInt (oArea, "efury_enc_chance_" + IntToString(nOddsCounter));
}
}
else
{
sLocationDebug += "Encounter not spawned due to creatures already present.";
}
iCounter = iCounter +1;
WriteTimestampedLogEntry(sLocationDebug);
SetLocalInt(oArea, "RecentSpawned", 1);
//2 minute delay before it will spawn another
DelayCommand(120.0, ActionDoCommand(SetLocalInt(oArea, "RecentSpawned", 0)));
}
}
}
}
The below picture shows set area variables for 12 possible spawn points, with a trio of bugbears (25% 1-25 roll) guarding a shaman, a pair of ravens (35%, 26-60 roll), a family of wyverns (10%, 61-70), and a lone mountain giant (10%, 71-80) as possibles (and a 20% chance of nothing spawning).
The syntax is```
(RESREF)*(Number of them)|(next creature type in encounter)|(next creature)|
Waypoints tagged "efury_spawnpoint_XX" where XX is relevant number serve as spawn positions. ![](http://img715.imageshack.us/img715/8021/efury.jpg)
Modifying it to look at 2das isn't too hard if one wishes broad category tables over specific area dynamics either.