#include "jw_register_mobs" // Returns TRUE if oArea has been turned off, otherwise returns false int GetIsAreaTurnedOff(object oArea); // Turns this area off. Set nTurnoff to FALSE to turn the area back on void TurnOffArea(object oArea, int nTurnoff=TRUE); // Removes blight effects from this area void CleanUpBlight(object oArea); // oArea should be an area which is already blighted. On a one in 60 basis (once every 12 hours) // It will look at its neighbouring areas and spread blight to one of them randomly // changing the databse entry if needed void SpreadBlight(object oArea); // Gets the blight status of this area, BLIGHT_STATUS_ON or BLIGHT_STATUS_OFF // From the database, only needs doing on module load int GetBlightedStatusFromDatabase(object oArea); // Saves the blight status of this area to the database, only needs, BLIGHT_STATUS_ON or BLIGHT_STATUS_OFF // Doing when the status changes void SaveBlightedStatusToDatabase(object oArea, int nBlighted); // Sets the blight status of this area, BLIGHT_STATUS_ON or BLIGHT_STATUS_OFF void SetBlightStatus(object oArea, int nBlight); // Gets the blight status of this area, BLIGHT_STATUS_ON or BLIGHT_STATUS_OFF int GetBlightStatus(object oArea); // Gets what type of area this is, eg AREA_ICE, AREA_PERMANENT_BLIGHT int GetAreaType(object oArea); // Sets what type of area this is, eg AREA_ICE, AREA_PERMANENT_BLIGHT // However it is simply set using the reflex save of the area box void SetAreaType(object oArea, int nAreaType); // Sets oNeighbouringArea to be the neighbouring area number nCount of oArea void SetNeighbouringArea(object oArea, int nCount, object oNeighbouringArea); // Gets neighbouring area number nCount for oArea. Check how many neighbours oArea has with GetNeighbouringAreaNumber object GetNeighbouringArea(object oArea, int nCount); // Sets oArea to have nNumber of neighbouring areas void SetNeighbouringAreaNumber(object oArea, int nNumber); // Gives the amount of neighbouring areas next to the oArea int GetNeighbouringAreaNumber(object oArea); // Make the placeablebox spawn a single placeable void SpawnPlaceable(object oBox); // Returns TRUE if the placeable box has a placeable already, otherwise returns false int HasPlaceableAlready(object oObject); // Returns true of a PC is in the area, otherwise returns false // DMs are not counted as PCs int GetPCInArea(object oArea); // Reset traps and hidden doors, remove mobs and remove body bags void CleanUpArea(object oArea); // Spawn mobs in this area void SpawnArea(object oArea); /// Use this to check if the spawn boxes have a mob spawned int HasMobsAlready(object oObject); // Make the spawnbox spawn some mobs void SpawnMobs(object oBox); // Gets the current time, using nCurrentMinute = GetCalendarYear()-1)*12*28*24*60 + // (GetCalendarMonth()-1)*28*24*60 + // (GetCalendarDay()-1)*24 *60+ // GetTimeHour()*60+GetTimeMinute(); int GetCurrentTime(); // Use this to set the latest time the area spawned mobs and placeables // if nTime is left at 0 it will automatically set the current time, otherwise // it will set it as nTime void SetSpawnTime(object oArea, int nTime=0); // Gets the last time the area spawned mobs and placeables int GetSpawnTime(object oArea); // Cycles through all the relevant areas and resets mobs if needed // Areas are checked by looking for a placeable with // the tag jw_area_marker. // The WILL SAVE of this object is the mob set number of the area - // ie, it determines which sets spawn in the area . // A will save of 0 means mobs do not spawn // Every area MUST have a unique tag void CheckAreas(); // Returns the status of an area // AREA_ACTIVE means a player is in there, AREA_VACATED means no players are in there // and players recently left, which means it is time to clean it up // and change the status to AREA_INACTIVE, and AREA_INACTIVE means there is nobody there // and it is cleaned up int GetAreaStatus(object oArea); // Set the status of this area. // AREA_ACTIVE means a player is in there, AREA_VACATED means no players are in there // and players recently left, and AREA_INACTIVE means there is nobody there // and it is cleaned up void SetAreaStatus(object oArea, int nStatus); // Goes through all the areas and checks the databse to see what they should be spawning // if nothing has been stored in the database, randomly gets a new set for them void InitiateAreas(); const int SPAWN_DELAY = 10; const string SPAWN_BOX="jw_spawn_box"; const string PLACEABLES_BOX="jw_place_box"; const int AREA_ACTIVE = 1; const int AREA_VACATED = 2; const int AREA_INACTIVE = 3; const int RARE_SPAWN_CHANCE = 200; const int CHANGE_SPAWN_CHANCE = 240; const int RARE_SPAWN_INACTIVE = 1; const int RARE_SPAWN_PENDING = 2; const int RARE_SPAWN_SPAWNED = 3; const int AREA_TYPE_PLAIN = 1; const int AREA_TYPE_FOREST = 2; const int AREA_TYPE_DESERT = 3; const int AREA_TYPE_BEACH = 4; const int AREA_TYPE_ICE = 5; const int AREA_TYPE_SWAMP = 6; const int AREA_TYPE_PERMANENT_BLIGHT = 7; const int AREA_TYPE_DUNGEON_LEVEL1 = 8; const int AREA_TYPE_DUNGEON_LEVEL2 = 9; const int AREA_TYPE_DUNGEON_LEVEL3 = 10; const int AREA_TYPE_DUNGEON_LEVEL4 = 11; const int BLIGHT_STATUS_OFF = 0; const int BLIGHT_STATUS_ON = 1; // Returns TRUE if oArea has been turned off, otherwise returns false int GetIsAreaTurnedOff(object oArea) { int nTurnedoff=GetLocalInt(oArea,"turnedoff"); if (nTurnedoff==TRUE) { return TRUE; } return FALSE; } // Turns this area off. Set nTurnoff to FALSE to turn the area back on void TurnOffArea(object oArea, int nTurnoff=TRUE) { if (nTurnoff==TRUE) { SetLocalInt(oArea,"turnedoff",TRUE); } else { SetLocalInt(oArea,"turnedoff",FALSE); } } void InitiateAreas() { int nIdx=0; object oArea; int nAreaNumber; //int nRareGroupNumber; int nPlaceableSetNumber; int nAreaType; object oMarker=GetObjectByTag("jw_area_marker",nIdx); // Instead of using the database to save weather, we just // choose at random on module load int nWeatherType=Random(3); while (GetIsObjectValid(oMarker)) { oArea=GetArea(oMarker); nAreaType=GetReflexSavingThrow(oMarker); // Set the area to be nAreaType SetAreaType(oArea,nAreaType); nAreaNumber=GetWillSavingThrow(oMarker); nPlaceableSetNumber=GetFortitudeSavingThrow(oMarker); // Start basic spawn routine if (nAreaNumber!=0) { // Organise standard spawns int nSet=GetSpawnSetFromDatabase(oArea); // if nSet is 0 then this is probably a new module if (nSet==0) { // Make a new spawn set SetNewSpawnSet(oArea, nAreaNumber); } else { // Set the spawn set to be what we just got from teh databse SetSpawnSet(oArea,nSet); } } else { // This is what we do when nAreaNumber==0 // In this case, the area does not spawn SetSpawnSet(oArea,0); } // Start rare spawn routine if (nAreaNumber!=0) { // Now organise rare spawns int nRareStatus=GetRareSpawnStatusFromDatabase(oArea); // Start new module routine if (nRareStatus==0) { // This means it is probably a new module // Choose whether to make this a rarespawn area. We only do this if nRareGroupNumber !=0 if (Random(RARE_SPAWN_CHANCE)==1) { // We have decided to do one SetRareSpawnStatus(oArea,RARE_SPAWN_PENDING); SaveRareSpawnStatusToDatabase(oArea,RARE_SPAWN_PENDING); SaveRareSpawnTypeToDatabase(oArea,GetRareSpawn(nAreaNumber)); } else { // We have decided not to do one SetRareSpawnStatus(oArea,RARE_SPAWN_INACTIVE); SaveRareSpawnStatusToDatabase(oArea,RARE_SPAWN_INACTIVE); } } // ended new module routine // Rare spawn status was not 0, so we need now just to set the status on to the area else { SetRareSpawnStatus(oArea,nRareStatus); } } else { // This is what we do if nRareGroupNumber==0 SetRareSpawnStatus(oArea,RARE_SPAWN_INACTIVE); } // ended rare spawn routine // Do placeable routine if (nPlaceableSetNumber!=0) { // Organise standard placeable int nSet=GetPlaceableSetFromDatabase(oArea); // if nSet is 0 then this is probably a new module if (nSet==0) { // Make a new spawn set SetNewPlaceableSet(oArea, nPlaceableSetNumber); } else { // Set the spawn set to be what we just got from teh databse SetPlaceableSet(oArea,nSet); } } else { // This is what we do when nPlaceableSetNumber==0 // In this case, the area does not spawn placeables SetPlaceableSet(oArea,0); } // Set the correct blight status on this area int nBlight; if (nAreaType==AREA_TYPE_PERMANENT_BLIGHT) { nBlight=BLIGHT_STATUS_ON; } else { nBlight=GetBlightedStatusFromDatabase(oArea); } SetBlightStatus(oArea,nBlight); // Save fog settings it nBlight is on and change fog if (nBlight==BLIGHT_STATUS_ON) { SetLocalInt(oArea,"fog_day_colour",GetFogColor(FOG_TYPE_SUN,oArea)); SetLocalInt(oArea,"fog_night_colour",GetFogColor(FOG_TYPE_MOON,oArea)); SetLocalInt(oArea,"fog_day_amount",GetFogAmount(FOG_TYPE_SUN,oArea)); SetLocalInt(oArea,"fog_night_amount",GetFogAmount(FOG_TYPE_MOON,oArea)); // Then change to new fog settings SetFogColor(FOG_TYPE_SUN,FOG_COLOR_BROWN_DARK,oArea); SetFogColor(FOG_TYPE_MOON,FOG_COLOR_RED_DARK,oArea); SetFogAmount(FOG_TYPE_SUN,30,oArea); SetFogAmount(FOG_TYPE_MOON,30,oArea); } // set the weather if (nAreaType==AREA_TYPE_DUNGEON_LEVEL1||nAreaType==AREA_TYPE_DUNGEON_LEVEL2|| nAreaType==AREA_TYPE_DUNGEON_LEVEL3||nAreaType==AREA_TYPE_DUNGEON_LEVEL4||nAreaType==AREA_TYPE_DESERT) { // do nothing } else if (nAreaType==AREA_TYPE_ICE&&nWeatherType==WEATHER_RAIN) { SetWeather(oArea,WEATHER_SNOW); } else if (nAreaType==AREA_TYPE_SWAMP&&nWeatherType==WEATHER_SNOW) { SetWeather(oArea,WEATHER_RAIN); } else if ((nAreaType==AREA_TYPE_FOREST||nAreaType==AREA_TYPE_PLAIN)&&nWeatherType==WEATHER_SNOW) { //SetSkyBox(SKYBOX_GRASS_CLEAR,oArea); SetWeather(oArea,WEATHER_CLEAR); } else { SetWeather(oArea,nWeatherType); } // Start on next area nIdx=nIdx+1; oMarker=GetObjectByTag("jw_area_marker",nIdx); } // End of going through area boxes // Now do the neighbouring areas stuff string sName; int nCount; nIdx=0; oMarker=GetObjectByTag("jw_neighbour_wp",nIdx); while (GetIsObjectValid(oMarker)) { oArea=GetArea(oMarker); sName=GetName(oMarker); // The name of the WP should be area_tagofnextdoorarea // This gives us the name without area_ //sName=GetStringRight(sName,GetStringLength(sName)-5); // if the name of the area is the same as the area it is in, just ignore it if (GetTag(oArea)!=sName) { // We are looking at a different area - ok nCount=GetNeighbouringAreaNumber(oArea); nCount=nCount+1; SetNeighbouringAreaNumber(oArea,nCount); SetNeighbouringArea(oArea,nCount,GetObjectByTag(sName)); } // Start on next area nIdx=nIdx+1; oMarker=GetObjectByTag("jw_neighbour_wp",nIdx); } } void CheckAreas() { int nIdx=0; object oArea; int nAreaNumber; //int nRareGroupNumber; int nPlaceableSetNumber; object oMarker=GetObjectByTag("jw_area_marker",nIdx); // will we change the weather? int nChangeWeather=FALSE; int nWeatherType; /* int WEATHER_CLEAR = 0; int WEATHER_RAIN = 1; int WEATHER_SNOW = 2; */ if (Random(3)==1) { nChangeWeather=TRUE; nWeatherType=Random(3); } while (GetIsObjectValid(oMarker)) { oArea=GetArea(oMarker); nAreaNumber=GetWillSavingThrow(oMarker); //nRareGroupNumber=GetReflexSavingThrow(oMarker); nPlaceableSetNumber=GetFortitudeSavingThrow(oMarker); // We are doing this once every 12 minutes. 5 times an hour // We want areas to change every 3.4 days, that's around 1 in 340 // Start basic spawn routine if (Random(CHANGE_SPAWN_CHANCE)==1 && (nAreaNumber!=0)) { // Changes the spawn set of the area SetNewSpawnSet(oArea, nAreaNumber); } // ended basic spawn routine // Start rare spawn routine if ((Random(RARE_SPAWN_CHANCE)==1) && (nAreaNumber!=0)) { if (GetRareSpawnStatus(oArea)==RARE_SPAWN_INACTIVE) { // We have decided to do one int nRareSpawn=GetRareSpawn(nAreaNumber); if (nRareSpawn!=0) { SetRareSpawnStatus(oArea,RARE_SPAWN_PENDING); SaveRareSpawnStatusToDatabase(oArea,RARE_SPAWN_PENDING); SaveRareSpawnTypeToDatabase(oArea,nRareSpawn); } } else if ((GetRareSpawnStatus(oArea)==RARE_SPAWN_PENDING)) { // We have decided to do cancel one that was here SetRareSpawnStatus(oArea,RARE_SPAWN_INACTIVE); SaveRareSpawnStatusToDatabase(oArea,RARE_SPAWN_INACTIVE); } // if the rare spawn is spawned we just leave it } // end rare spawn routine // Start basic placeable routine if (Random(CHANGE_SPAWN_CHANCE)==1 && (nPlaceableSetNumber!=0)) { // Changes the spawn set of the area SetNewPlaceableSet(oArea, nPlaceableSetNumber); } // ended basic placeable routine // Ok now we just need to do the clean up if (GetAreaStatus(oArea)==AREA_ACTIVE) { if (GetPCInArea(oArea)) { // If the area is active we may respawn things depending on how long it has been // SendMessageToAllDMs("Area "+GetName(oArea)+" is active and we are doing spawn"); //SendMessageToPC(GetFirstPC(),"Area "+GetName(oArea)+" is active and we are doing spawn"); //SpawnArea(oArea); // Make the area do USD 80 to spawn it SignalEvent(oArea,EventUserDefined(80)); } else { SetAreaStatus(oArea,AREA_VACATED); } } if (GetAreaStatus(oArea)==AREA_VACATED) { // Make the area run our cleanup script // Note that this will kill all mobs that are encounter mobs // CleanUpArea(oArea); // Have the area execute the script instead // ExecuteScript("jw_area_cleanup",oArea); // Signal area event so it cleans up itself SignalEvent(oArea,EventUserDefined(70)); //SendMessageToAllDMs("Area "+GetName(oArea)+" is vacated and we are doing cleanup"); //SendMessageToPC(GetFirstPC(),"Area "+GetName(oArea)+" is vacated and we are doing cleanup"); // Set the area to inactive SetAreaStatus(oArea,AREA_INACTIVE); } int nAreaType=GetAreaType(oArea); // Now possibly change the weather if (nChangeWeather=TRUE) { // set the weather if (nAreaType==AREA_TYPE_DUNGEON_LEVEL1||nAreaType==AREA_TYPE_DUNGEON_LEVEL2|| nAreaType==AREA_TYPE_DUNGEON_LEVEL3||nAreaType==AREA_TYPE_DUNGEON_LEVEL4||nAreaType==AREA_TYPE_DESERT) { // do nothing } else if (nAreaType==AREA_TYPE_ICE&&nWeatherType==WEATHER_RAIN) { SetWeather(oArea,WEATHER_SNOW); } else if (nAreaType==AREA_TYPE_SWAMP&&nWeatherType==WEATHER_SNOW) { SetWeather(oArea,WEATHER_RAIN); } else if ((nAreaType==AREA_TYPE_FOREST||nAreaType==AREA_TYPE_PLAIN)&&nWeatherType==WEATHER_SNOW) { //SetSkyBox(SKYBOX_GRASS_CLEAR,oArea); SetWeather(oArea,WEATHER_CLEAR); } else { SetWeather(oArea,nWeatherType); } } // Check if it is blighted if (GetBlightStatus(oArea)==BLIGHT_STATUS_ON) { // Do this as a separate function SpreadBlight(oArea); } // Start on next area nIdx=nIdx+1; oMarker=GetObjectByTag("jw_area_marker",nIdx); } } int GetSpawnTime(object oArea) { int nLastSpawnMinute = GetLocalInt(oArea,"LAST_SPAWN_MINUTE"); return nLastSpawnMinute; } void SetSpawnTime(object oArea, int nTime=0) { int nCurrentMinute; if (nTime==0) { nCurrentMinute = GetCurrentTime(); } else { nCurrentMinute = nTime; } SetLocalInt(oArea,"LAST_SPAWN_MINUTE",nCurrentMinute); } int GetAreaStatus(object oArea) { int nStatus=GetLocalInt(oArea,"areastatus"); return nStatus; } void SetAreaStatus(object oArea, int nStatus) { SetLocalInt(oArea,"areastatus",nStatus); } int GetCurrentTime() { int nCurrentMinute = (GetCalendarYear()-1)*12*28*24*60 + (GetCalendarMonth()-1)*28*24*60 + (GetCalendarDay()-1)*24 *60+ GetTimeHour()*60+GetTimeMinute(); return nCurrentMinute; } void SpawnArea(object oArea) { //SendMessageToPC(GetFirstPC(),"Starting jw_area_spawn"); int nSet=GetSpawnSet(oArea); // If nSet==0 then NOTHING will spawn // Areas must have area numbers (will saves) even if they do not spawn mobs // if they are supposed to spawn placeables or indivudial mobs if (nSet==0) { return; } // If it is not long enough since our last spawn, just stop if (GetCurrentTime() < (GetSpawnTime(oArea) + SPAWN_DELAY)) { return; } if (GetIsAreaTurnedOff(oArea)) { SendMessageToAllDMs(GetName(oArea)+" would normally spawn now but it has been turned off"); return; } // We are going to spawn - set our new spawn time SetSpawnTime(oArea,GetCurrentTime()); // nIdx is needed here only for debug purposes int nIdx=1; object oObject = GetFirstObjectInArea(oArea); while (GetIsObjectValid(oObject)) { // We are looking for our spawn boxes if (GetTag(oObject)==SPAWN_BOX) { // This next section is for spawning mobs if (!HasMobsAlready(oObject)) { // No mobs exist - therefore we make some //SendMessageToPC(GetFirstPC(),"Doing SpawnMobs number "+IntToString(nIdx)+" because of object name "+GetName(oObject)); SpawnMobs(oObject); } } // We are looking for our placeable boxes if (GetTag(oObject)==PLACEABLES_BOX) { // This next section is for spawning placeables //SendMessageToPC(GetFirstPC(),"we found a placeable box"); if (!HasPlaceableAlready(oObject)) { // No placeable exists - therefore we make one //SendMessageToPC(GetFirstPC(),"Doing Spawnplaceable on a box we found as it has no placeable"); SpawnPlaceable(oObject); } } oObject=GetNextObjectInArea(oArea); } } int HasMobsAlready(object oObject) { string sMob="sMob"; string sCheckstring; int nIdx; int nNumber; int nMobsexist; //nNumber is the number of mobs spawned last time; nNumber=GetLocalInt(oObject,"nNumber"); // Start off by assuming mobs do not exist nMobsexist=FALSE; // if this is not the first time we have done it, check if any of our mobs are there if (nNumber>0) { // start counting through the mobs for (nIdx=1; nIdx<=nNumber; nIdx++) { sCheckstring=sMob+IntToString(nIdx); // cycle through the local objects if (GetIsObjectValid(GetLocalObject(oObject,sCheckstring))) { // if one is valid, set nMobsexist to 1 nMobsexist=TRUE; } } } return nMobsexist; } int HasPlaceableAlready(object oObject) { int nReturn=FALSE; object oPlace=GetLocalObject(oObject,"placeable"); if (GetIsObjectValid(oPlace)) { nReturn=TRUE; } return nReturn; } void SpawnMobs(object oBox) { object oPC=GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,oBox); if ((GetIsObjectValid(oPC))&&(GetDistanceBetween(oBox,oPC)<20.0)) { return; } string sResRef; object oMob; string sCheckstring; string sMob="sMob"; location lLoc=GetLocation(oBox); int nIdx=1; int nBlightStatus=GetBlightStatus(GetArea(oBox)); // Check if the box has a specific spawn if ((GetName(oBox)!="jw_spawn_box")&&(nBlightStatus==BLIGHT_STATUS_OFF)) { // Make a specific mob sResRef=GetName(oBox); // create the mob oMob=CreateObject(OBJECT_TYPE_CREATURE,sResRef,lLoc,FALSE); // make the mob act like an encounter creature SetLocalInt(oMob,"norw",2); // make the mob our box's local object sCheckstring=sMob+IntToString(1); SetLocalObject(oBox,sCheckstring,oMob); // Only one rare spawn SetLocalInt(oBox,"nNumber",1); return; } // We may make a rare spawn here if ((GetRareSpawnStatus(GetArea(oBox))==RARE_SPAWN_PENDING)&&(d4()==1)&&(nBlightStatus==BLIGHT_STATUS_OFF)) { sResRef=GetRareSpawnResRef(GetRareSpawnTypeFromDatabase(GetArea(oBox))); // create the mob oMob=CreateObject(OBJECT_TYPE_CREATURE,sResRef,lLoc,FALSE); // make the mob act like an encounter creature SetLocalInt(oMob,"norw",2); // make the mob our box's local object sCheckstring=sMob+IntToString(1); SetLocalObject(oBox,sCheckstring,oMob); // Only one rare spawn SetLocalInt(oBox,"nNumber",1); // Set that the mob has spawned in this area SetRareSpawnStatus(GetArea(oBox),RARE_SPAWN_SPAWNED); // Set the mob is a rare spawn SetIsRareSpawn(oMob); return; } // No rare mob, so move on to standard mobs int nSet=GetSpawnSet(GetArea(oBox)); //SendMessageToPC(GetFirstPC(),"We have stablished that our current spawn set is "+IntToString(nSet)); // if nSet is 0, we return if (nSet==0) { return; } int nGroup; // If the area is blighted we get a blight set instead if (nBlightStatus==BLIGHT_STATUS_OFF) { nGroup=GetSpawnGroupFromSet(nSet); } else { nGroup=GetBlightSpawnGroupFromSet(nSet); } //SendMessageToPC(GetFirstPC(),"We have chosen to spawn in group "+IntToString(nGroup)); // if nGroup is 0, we return if (nGroup==0) { return; } SetGroupDetails(nGroup, oBox); string sMobtype=GetLocalString(oBox, "GroupResRef"); //SendMessageToPC(GetFirstPC(),"The res ref of this group is "+sMobtype); int nMobMax=GetLocalInt(oBox, "MaxMobs"); //SendMessageToPC(GetFirstPC(),"Maximum number of mobs in this group is "+IntToString(nMobMax)); int nMobMin=GetLocalInt(oBox, "MinMobs"); //SendMessageToPC(GetFirstPC(),"Minimum number of mobs in this group is "+IntToString(nMobMin)); // Debug check if (nMobMin>nMobMax) { nMobMax=nMobMin; } // do a custom group if (GetStringLeft(sMobtype,5)=="group") { // this is the section for making groups //SendMessageToPC(GetFirstPC(),"We have established that this group is a custom group"); int nMobnumber=0; nIdx=1; // We find out our group number by checking the // three letters at the end of the group name string sGroupname=GetStringRight(sMobtype,3); //SendMessageToPC(GetFirstPC(),"The name of our custom group is "+sGroupname); int nGroupNumber=StringToInt(sGroupname); //SendMessageToPC(GetFirstPC(),"The name of our custom group in an interger is "+IntToString(nGroupNumber)); // Set our local ints SetCustomGroup(nGroupNumber, oBox); nMobMax=GetLocalInt(oBox,"group_number"); //SendMessageToPC(GetFirstPC(),"The total number of mobs we are making is "+IntToString(nMobMax)); for (nIdx=1; nIdx<=nMobMax; nIdx++) { //SendMessageToPC(GetFirstPC(),"Cycling through mobs to make - currently on "+IntToString(nIdx)); sMobtype="group_"+IntToString(nIdx); //SendMessageToPC(GetFirstPC(),"Checking the res ref of the mob by looking at the local string "+"group_"+IntToString(nIdx)); sResRef=GetLocalString(oBox,sMobtype); //SendMessageToPC(GetFirstPC(),"The res ref we got, and are about to make, is "+sResRef); // create the mob oMob=CreateObject(OBJECT_TYPE_CREATURE,sResRef,lLoc,FALSE); if (nBlightStatus==BLIGHT_STATUS_ON) { // Tell this mob it is blighted SetLocalInt(oMob,"blighted",TRUE); } // make the mob act like an encounter creature SetLocalInt(oMob,"norw",2); // make the mob our box's local object sCheckstring=sMob+IntToString(nIdx); SetLocalObject(oBox,sCheckstring,oMob); //SendMessageToPC(GetFirstPC(),"That should have worked and now on to the next one"); } SetLocalInt(oBox,"nNumber",nMobMax); } else // do a standard group { // this is the section for making individual mobs // choose how many mobs to create int nRandomnumber=Random((nMobMax-nMobMin)+1); int nMobnumber=nMobMin+nRandomnumber; //SendMessageToPC(GetFirstPC(),"We have established that this group is a standard group"); //SendMessageToPC(GetFirstPC(),"We are going to make "+IntToString(nMobnumber)+" of these"); SetLocalInt(oBox,"nNumber",nMobnumber); // start making the mobs for (nIdx=1; nIdx<=nMobnumber; nIdx++) { // create the mob oMob=CreateObject(OBJECT_TYPE_CREATURE,sMobtype,lLoc,FALSE); //SendMessageToPC(GetFirstPC(),"We have made mob number "+IntToString(nIdx)); if (nBlightStatus==BLIGHT_STATUS_ON) { // Tell this mob it is blighted SetLocalInt(oMob,"blighted",TRUE); } // make the mob act like an encounter creature SetLocalInt(oMob,"norw",2); // make the mob our new local object sCheckstring=sMob+IntToString(nIdx); SetLocalObject(oBox,sCheckstring,oMob); } } } void SpawnPlaceable(object oBox) { object oPC=GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,oBox); if ((GetIsObjectValid(oPC))&&(GetDistanceBetween(oBox,oPC)<20.0)) { return;//do not spawn in sight of PC } int nBlighted=GetBlightStatus(GetArea(oBox)); // Get our placeable set int nSet=GetPlaceableSet(GetArea(oBox)); // if nSet is 0, we return if (nSet==0) { //SendMessageToPC(GetFirstPC(),"Returning from place spawn as nSet==0"); return; } string sResRef; // If we have blight, just ignore all this and get a placeable from the blight set (fog) if (nBlighted==BLIGHT_STATUS_ON) { sResRef=GetPlaceableResRefFromBlightSet(); } else if (GetName(oBox)!="jw_place_box") { sResRef=GetName(oBox); } else { sResRef=GetPlaceableResRefFromSet(nSet); } // if sResRef is "", we return if (sResRef=="") { //SendMessageToPC(GetFirstPC(),"Returning from place spawn as sResRef=empty"); return; } location lLoc=GetLocation(oBox); object oPlaceable=CreateObject(OBJECT_TYPE_PLACEABLE,sResRef,lLoc,FALSE); // if blight is on, set anti light to it if (nBlighted==BLIGHT_STATUS_ON) { ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectVisualEffect(VFX_DUR_ANTI_LIGHT_10),oPlaceable); SetLocalInt(oPlaceable,"blighted",TRUE); } //SendMessageToPC(GetFirstPC(),"placeable is spawning "+sResRef); SetLocalObject(oBox,"placeable",oPlaceable); // Although our placeable will not be hidden, we set it as hidden so the clean // up script will destroy it SetLocalInt(oPlaceable,"jw_hidden_int",TRUE); // Make the placeable do its on spawn event SignalEvent(oPlaceable,EventUserDefined(50)); // Possibly lock the placeable if ((d3()==1)&&(GetLockLockable(oPlaceable))) { SetLocked(oPlaceable,TRUE); } } void CleanUpArea(object oArea) { // Set the last spawn time to be the current time - 60 // This is to ensure the area will spawn again if someone walks in SetSpawnTime(oArea,GetCurrentTime()-60); // If the area currently has a rare mob spawned, put it back to pending if (GetRareSpawnStatus(oArea)==RARE_SPAWN_SPAWNED) { SetRareSpawnStatus(oArea,RARE_SPAWN_PENDING); } object oItem; object oObject = GetFirstObjectInArea(oArea); while (GetIsObjectValid(oObject) == TRUE) { // Check if it is a custom encounter creature if (GetLocalInt(oObject,"norw")==2||GetIsEncounterCreature(oObject)) { //SetPlotFlag(oObject,FALSE); DestroyObject(oObject); } if (GetObjectType(oObject)==OBJECT_TYPE_DOOR) { if(!GetLocalInt(oObject, "destroyed")) //stops destroyed doors from having the door re-appear { AssignCommand(oObject,ActionCloseDoor(oObject)); if (GetLockLockable(oObject)) SetLocked(oObject,TRUE); } } if (GetTag(oObject) == "BodyBag"||GetLocalInt(oObject,"jw_hidden_int")==TRUE) { if (GetHasInventory(oObject)) { oItem = GetFirstItemInInventory(oObject); while (GetIsObjectValid(oItem) == TRUE) { DestroyObject(oItem); oItem=GetNextItemInInventory(oObject); } } //SetPlotFlag(oObject,FALSE); DestroyObject(oObject); } if (GetObjectType(oObject)==OBJECT_TYPE_TRIGGER) { SetLocalInt(oObject,"done",0); SetLocalInt(oObject,"triggered",FALSE); } if (GetResRef(oObject)=="jw_mobstransf_tr") { SignalEvent(oObject,EventUserDefined(50)); } oObject=GetNextObjectInArea(oArea); } } int GetPCInArea(object oArea) { int nPCinArea = FALSE; // Cycle through our PCs and see if any of them are still in the area object oTest=GetFirstPC(); while (GetIsObjectValid(oTest)) { if (GetArea(oTest) == oArea) { nPCinArea = TRUE; return nPCinArea; } oTest=GetNextPC(); } return nPCinArea; } void SetNeighbouringAreaNumber(object oArea, int nNumber) { SetLocalInt(oArea,"neighbours",nNumber); } int GetNeighbouringAreaNumber(object oArea) { return GetLocalInt(oArea,"neighbours"); } object GetNeighbouringArea(object oArea, int nCount) { return GetLocalObject(oArea,"neighbour"+IntToString(nCount)); } void SetNeighbouringArea(object oArea, int nCount, object oNeighbouringArea) { SetLocalObject(oArea,"neighbour"+IntToString(nCount),oNeighbouringArea); } // Gets what type of area this is, eg AREA_ICE, AREA_PERMANENT_BLIGHT int GetAreaType(object oArea) { return GetLocalInt(oArea,"areatype"); } // Sets what type of area this is, eg AREA_ICE, AREA_PERMANENT_BLIGHT // However it is simply set using the reflex save of the area box void SetAreaType(object oArea, int nAreaType) { SetLocalInt(oArea,"areatype",nAreaType); } // Sets the blight status of this area, BLIGHT_STATUS_ON or BLIGHT_STATUS_OFF void SetBlightStatus(object oArea, int nBlight) { SetLocalInt(oArea,"blighted",nBlight); int nRandom=d6(); SetLocalInt(oArea,"blightotal",nRandom+2); } // Gets the blight status of this area, BLIGHT_STATUS_ON or BLIGHT_STATUS_OFF int GetBlightStatus(object oArea) { return GetLocalInt(oArea,"blighted"); } // Gets the blight status of this area, BLIGHT_STATUS_ON or BLIGHT_STATUS_OFF // From the database, only needs doing on module load int GetBlightedStatusFromDatabase(object oArea) { int nSet=GetCampaignInt("NEW_WORLD","blighted"+GetTag(oArea)); return nSet; } // Saves the blight status of this area to the database, only needs, BLIGHT_STATUS_ON or BLIGHT_STATUS_OFF // Doing when the status changes void SaveBlightedStatusToDatabase(object oArea, int nBlighted) { SetCampaignInt("NEW_WORLD","blighted"+GetTag(oArea),nBlighted); } void SpreadBlight(object oArea) { // only one in 60 chance of spreading blight if (Random(60)!=1) { return; } int nNumberNeighbours=GetNeighbouringAreaNumber(oArea); int nRandom=Random(nNumberNeighbours)+1; object oNeighbour=GetNeighbouringArea(oArea,nRandom); if (GetBlightStatus(oNeighbour)!=BLIGHT_STATUS_ON) { SetBlightStatus(oNeighbour,BLIGHT_STATUS_ON); SaveBlightedStatusToDatabase(oNeighbour,BLIGHT_STATUS_ON); SetLocalInt(oNeighbour,"fog_day_colour",GetFogColor(FOG_TYPE_SUN,oNeighbour)); SetLocalInt(oNeighbour,"fog_night_colour",GetFogColor(FOG_TYPE_MOON,oNeighbour)); SetLocalInt(oNeighbour,"fog_day_amount",GetFogAmount(FOG_TYPE_SUN,oNeighbour)); SetLocalInt(oNeighbour,"fog_night_amount",GetFogAmount(FOG_TYPE_MOON,oNeighbour)); // Then change to new fog settings SetFogColor(FOG_TYPE_SUN,FOG_COLOR_BROWN_DARK,oNeighbour); SetFogColor(FOG_TYPE_MOON,FOG_COLOR_RED_DARK,oNeighbour); SetFogAmount(FOG_TYPE_SUN,30,oNeighbour); SetFogAmount(FOG_TYPE_MOON,30,oNeighbour); } } void CleanUpBlight(object oArea) { object oObject=GetFirstObjectInArea(oArea); while (GetIsObjectValid(oObject)) { if (GetLocalInt(oObject,"blighted")==TRUE) { //SetPlotFlag(oObject,0); DestroyObject(oObject); } oObject=GetNextObjectInArea(oArea); } // Reset fog levels to what they should be SetFogColor(FOG_TYPE_SUN,GetLocalInt(oArea,"fog_day_colour"),oArea); SetFogColor(FOG_TYPE_MOON,GetLocalInt(oArea,"fog_night_colour"),oArea); SetFogAmount(FOG_TYPE_SUN,GetLocalInt(oArea,"fog_day_amount"),oArea); SetFogAmount(FOG_TYPE_MOON,GetLocalInt(oArea,"fog_night_amount"),oArea); }