<b> Dynamic Respawning </b>
Using the heartbeat and some creative variable creation, this script will
allow provide great respawning with very low overhead.
Each object records its location on spawn.
When it dies, it sets a few variables, its spawn location, its tag, and how
many heartbeats before it should respawn.
The heartbeat script runs like a queue, with 40 slots available for
spawning. If 40 mobs have been killed before any could respawn, killing a
41'st mob would force pop the first mob in the queue.
I have this running and I think it works great. I have a forest and I had no
static mobs, only Single Shot encounters spawning mobs with my onspawn/ondeath.
Now they are static mobs until the server goes down, and they respawn every
2 minutes. And the boss mob repawns every 8.
Any mobs's OnSpawn:
NWScript:
#include "NW_O2_CONINCLUDE"
#include "NW_I0_GENERIC"
void main()
{
SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
SetListeningPatterns();
WalkWayPoints();
GenerateNPCTreasure();
SetLocalLocation(OBJECT_SELF,"myspawn",GetLocation(OBJECT_SELF));
}
OnDeath:
NWScript:
#include "NW_I0_GENERIC"
void main()
{
int spawnqueue;
int sq;
object curarea;
int nClass = GetLevelByClass(CLASS_TYPE_COMMONER);
int nAlign = GetAlignmentGoodEvil(OBJECT_SELF);
if(nClass > 0 && (nAlign == ALIGNMENT_GOOD || nAlign == ALIGNMENT_NEUTRAL))
{
object oKiller = GetLastKiller();
AdjustAlignment(oKiller, ALIGNMENT_EVIL, 5);
}
curarea = GetArea(OBJECT_SELF);
spawnqueue = GetLocalInt(curarea,"spawnqueue");
if (spawnqueue >= 1) {
sq = spawnqueue+1;
if (sq == 41) { sq = 1; SetLocalInt(curarea,"rollover",1); }
} else {
sq = 1;
}
if (GetLocalInt(curarea,"rollover") == 1) {
if (GetLocalInt(curarea,"sqtdone" + IntToString(sq)) == 0 && GetLocalInt(curarea,"sqt" + IntToString(sq)) > 0) {
CreateObject(OBJECT_TYPE_CREATURE,GetLocalString(curarea,"sqc" + IntToString(sq)),GetLocalLocation(curarea,"sqt"+IntToString(sq)),TRUE);
}
}
SetLocalInt(curarea,"spawnqueue",sq);
SetLocalInt(curarea,"sqt" + IntToString(sq),20);
SetLocalInt(curarea,"sqtdone" + IntToString(sq),0);
SetLocalString(curarea,"sqc" + IntToString(sq), GetTag(OBJECT_SELF));
SetLocalLocation(curarea,"sqt" + IntToString(sq),GetLocalLocation(OBJECT_SELF,"myspawn"));
SpeakString("NW_I_AM_DEAD", TALKVOLUME_SILENT_TALK);
SpeakString("NW_ATTACK_MY_TARGET", TALKVOLUME_SILENT_TALK);
if(GetSpawnInCondition(NW_FLAG_DEATH_EVENT))
{
SignalEvent(OBJECT_SELF, EventUserDefined(1007));
}
}
AREA event OnHeartbeat:
NWScript: void main()
{
int sq,x,sqt,sqdone,rr;
string sqc;
location sql;
object curarea;
curarea = GetArea(OBJECT_SELF);
sq = GetLocalInt(curarea,"spawnqueue");
if (sq >= 1) {
x = 1;
if (GetLocalInt(curarea,"rollover") == 1) {
rr = 40;
} else {
rr = sq;
}
while (x <= rr) {
sqt = GetLocalInt(curarea,"sqt" + IntToString(x));
sqdone = GetLocalInt(curarea,"sqtdone" + IntToString(x));
if (sqt == 0 || sqdone == 1) { }
else {
if (sqt > 1) {
SetLocalInt(curarea,"sqt" + IntToString(x), sqt-1);
} else {
sqc = GetLocalString(curarea,"sqc" + IntToString(x));
sql = GetLocalLocation(curarea,"sqt" + IntToString(x));
CreateObject(OBJECT_TYPE_CREATURE,sqc,sql,TRUE);
SetLocalInt(curarea,"sqtdone" + IntToString(x),1);
}
}
x++;
}
}
}
Probably could be optimized a bit, but I find it to look really nice. My
server is at: 24.49.78.122, running dedicated server 24/7, with a constantly
updated module.
NOTE: To control respawn timer
in the OnDeath script, the line that says:
SetLocalInt(curarea,"sqt" + IntToString(sq),20);
20 is the # of heartbeats before respawn.
Fash
|