ff_u_v_respawn

Recreate placeables when destroyed.

Todo

Change the default to NO, and set variable on module. Edit GetEligibleFlagInt.

Variables

ENABLE__FF_U_V_RESPAWN: (string) (opt-out) Set to “N” on module to disable.

RESPAWN: (string) Set to x multiplier of NWNX_Util_GetMinutesPerHour to recreate placeable when destroyed.

Source code

// @code

#include "ff_i_core"

const string ENABLE__FF_U_V_RESPAWN = "ENABLE__FF_U_V_RESPAWN";

const string RESPAWN = "RESPAWN";

const string RESPAWN_DURATION = "RESPAWN_DURATION";

const int DEFAULT_DURATION = 60; // minutes

// -----------------------------------------------------------------------------

//! @brief Return TRUE if oObject is a non-static placeable or door with the RESPAWN flag set.
//! @param oObject An object.
int IsEligible(object oObject);
int IsEligible(object oObject)
{
  if (!GetObjectFlag(oObject, RESPAWN))
    return FALSE;

  int nObjectType = GetObjectType(oObject);
  if (nObjectType != OBJECT_TYPE_PLACEABLE && nObjectType != OBJECT_TYPE_DOOR)
    return FALSE;

  if (nObjectType == OBJECT_TYPE_PLACEABLE && NWNX_Object_GetPlaceableIsStatic(oObject))
    return FALSE;

  return TRUE;
}


// -----------------------------------------------------------------------------

//! @brief Internal: create the respawned object.
//! @param oArea The area the object belongs to (validity-checked before creating).
//! @param nObjectType An OBJECT_TYPE_* constant.
//! @param sTemplate Blueprint resref.
//! @param sTag Tag to assign.
//! @param lLocation Spawn location.
void _DelayedCreateObject(object oArea, int nObjectType, string sTemplate, string sTag, location lLocation);
void _DelayedCreateObject(object oArea, int nObjectType, string sTemplate, string sTag, location lLocation)
{
  if (!GetIsObjectValid(oArea))
    return;

  object oObject = CreateObjectEx(nObjectType, sTemplate, lLocation, FALSE, sTag);
}


// -----------------------------------------------------------------------------

//! @brief Schedule a delayed object recreation.
//! @param nDelay Delay in seconds.
//! @param oArea The area the object belongs to.
//! @param nObjectType An OBJECT_TYPE_* constant.
//! @param sTemplate Blueprint resref.
//! @param sTag Tag to assign.
//! @param lLocation Spawn location.
void DelayedCreateObject(int nDelay, object oArea, int nObjectType, string sTemplate, string sTag, location lLocation);
void DelayedCreateObject(int nDelay, object oArea, int nObjectType, string sTemplate, string sTag, location lLocation)
{
  if (!GetIsObjectValid(oArea))
    return;

  LogInfo(sTemplate + " will be recreated in " + IntToString(nDelay / 60) + " minutes");
  DelayCommand(IntToFloat(nDelay), _DelayedCreateObject(oArea, nObjectType, sTemplate, sTag, lLocation));
}


// -----------------------------------------------------------------------------

//! @brief Schedule recreation of oObject after RESPAWN_DURATION seconds.
//! @param oObject The destroyed placeable or door.
void OnDestroyed(object oObject);
void OnDestroyed(object oObject)
{
  if (!GetIsObjectValid(oObject))
    return;

  int nDuration = GetRecursiveInt(oObject, RESPAWN_DURATION, DEFAULT_DURATION);
  nDuration = max(nDuration, 1);
  nDuration = nDuration * 60;

  int nObjectType = GetObjectType(oObject);
  string sResRef  = GetResRef(oObject);
  string sTag     = GetTag(oObject);
  location locWhere = GetLocation(oObject);
  AssignCommand(GetModule(), DelayedCreateObject(nDuration, GetArea(oObject), nObjectType, sResRef, sTag, locWhere));
}


// -----------------------------------------------------------------------------
void main()
{
  if (!GetModuleFlag(ENABLE__FF_U_V_RESPAWN, TRUE))
    return;

  string sEvent = GetCurrentEvent();
  if (sEvent == ON_REGISTER)
    SubscribeToEvent(ON_OBJECT_CREATED, __FILE__);
  else if ((sEvent == ON_OBJECT_CREATED) && IsEligible(OBJECT_SELF))
    SubscribeToEvent(ON_DEFAULT_OBJECT_DEATH, __FILE__, OBJECT_SELF);
  else if (sEvent == ON_DEFAULT_OBJECT_DEATH)
    OnDestroyed(OBJECT_SELF);
}