Considering NWN's limitations with variables/data, I find STRUCTS useful. The code above was just a dummy so as to focus on what I wanted to understand.
I doubt this is of interest to many but I'll share what i am doing with STRUCTS. Rather than just use NESS to handle my spawns, I decided to write my own spawning code. With STRUCTS I can track the state of the creatures I am spawning. In the mod I am writing, I have a creature which spawns and despawns a few times, and I wanted to track their hitpoints in a data object as well as control whether or not they would spawn (eg. no spawning if they are dead). This is for a single player mod. i'm sure there are better ways to do this, but I like to roll my own code so as to get better at this.
// STRUCTS
struct NPC
{
// these are used for unique individuals
int bUnique; // TRUE = NPC is an individual
int nHP; // track hitpoints
object oSelf; // object identifier
// these are used by both individuals and populations
object oData;
int nDeaths; // track deaths
int nLives; // maximum deaths. 0 == unlimited.
int nSpawned; // track spawns. count of how many currently spawned.
// these are used by populations
int nSpawn_limit; // maximum spawns at once in the area. 0 == untracked.
};
// SUB FUNCTIONS ---------------------------------------------------------------
void SpawnCreature(string sRef, location lSpawn);
struct NPC GetCreatureData(object oCreature);
int InitializeCreature(struct NPC Creature);
void SpawnCreature(string sRef, location lSpawn)
{
object oCreature = CreateObject(OBJECT_TYPE_CREATURE, sRef, lSpawn, TRUE, sRef);
struct NPC Creature = GetCreatureData(oCreature); // load data from data object
if(GetIsObjectValid(Creature.oData) && !InitializeCreature(Creature))
DestroyObject(oCreature);
}
struct NPC GetCreatureData(object oCreature)
{
struct NPC Creature;
object oData = GetObjectByTag("data_"+GetTag(oCreature));
Creature.oSelf = oCreature;
Creature.oData = oData;
if (!GetIsObjectValid(oData))
{
if(DEBUG) SpeakString("data object not found", TALKVOLUME_SHOUT);
return Creature;
}
Creature.bUnique = GetLocalInt(oData,"bUnique");
Creature.nHP = GetLocalInt(oData,"nHP");
Creature.nDeaths = GetLocalInt(oData,"nDeaths");
Creature.nLives = GetLocalInt(oData,"nLives");
Creature.nSpawned = GetLocalInt(oData,"nSpawned");
Creature.nSpawn_limit = GetLocalInt(oData,"nSpawn_limit");
return Creature;
}
int InitializeCreature(struct NPC Creature)
{
if ( Creature.bUnique )
{
if (Creature.nDeaths == 0 && Creature.nSpawned == 0)
{
int nMaxHP = GetMaxHitPoints(Creature.oSelf);
if ( Creature.nHP > 0 && Creature.nHP < nMaxHP )
{
int nDamage = nMaxHP - Creature.nHP;
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamage), Creature.oSelf);
}
SetLocalInt(Creature.oData, "nSpawned", ++Creature.nSpawned);
return TRUE;
}
return FALSE; // creature is dead or already spawned
}
else if(
(Creature.nDeaths < Creature.nLives || Creature.nLives == 0)
&&
(Creature.nSpawned < Creature.nSpawn_limit || Creature.nSpawn_limit == 0)
)
{
if(Creature.nSpawn_limit != 0) // we are tracking spawns
SetLocalInt(Creature.oData, "nSpawned", ++Creature.nSpawned);
return TRUE;
}
return FALSE; // population is exhausted
}
pastebin:
http://pastebin.com/MJT7XfiC
Modifié par henesua, 15 juillet 2011 - 03:01 .