ff_u_v_cycle_act

Activate placeables at specific times (dawn, day, dusk, night).

Non-static placeables with at least one CYCLE_ACTIVATE__* variable are activated during the selected periods, and deactivated otherwise. Placeables are updated when a player enters their area, and, in the areas that have players, every game hour.

Variables

ENABLE__FF_U_V_CYCLE_ACTIVATE: (string) (opt-out) Set to "N" on module to disable the unit.

CYCLE_ACTIVATE__DAWN: (int) Set to 1 on the placeable to activate it at dawn.

CYCLE_ACTIVATE__DAY: (int) Set to 1 on the placeable to activate it during the day.

CYCLE_ACTIVATE__DUSK: (int) Set to 1 on the placeable to activate it at dusk.

CYCLE_ACTIVATE__NIGHT: (int) Set to 1 on the placeable to activate it during the night.

Examples

Set CYCLE_ACTIVATE__NIGHT to 1 on a torch bracket to light the torch during the night, and put it out during the day.

Source code

// @code

#include "ff_i_core"


const string ENABLE__FF_U_V_CYCLE_ACTIVATE = "ENABLE__FF_U_V_CYCLE_ACTIVATE";


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

//! @brief Activate or deactivate oObject from its CYCLE_ACTIVATE__* local variables and the current time.
//! Objects other than non-static placeables, or without any CYCLE_ACTIVATE__* variable, are left as is.
//! @param oObject A placeable.
void ActivateObject(object oObject);
void ActivateObject(object oObject)
{
  if (GetObjectType(oObject) != OBJECT_TYPE_PLACEABLE)
    return;

  if (NWNX_Object_GetPlaceableIsStatic(oObject))
    return;

  int nDawn  = GetLocalInt(oObject, "CYCLE_ACTIVATE__DAWN");
  int nDay   = GetLocalInt(oObject, "CYCLE_ACTIVATE__DAY");
  int nDusk  = GetLocalInt(oObject, "CYCLE_ACTIVATE__DUSK");
  int nNight = GetLocalInt(oObject, "CYCLE_ACTIVATE__NIGHT");

  if (nDawn || nDay || nDusk || nNight)
    {}
  else
    return;

  int nActivate = FALSE;
  nActivate |= (GetIsDawn()  && nDawn);
  nActivate |= (GetIsDay()   && nDay);
  nActivate |= (GetIsDusk()  && nDusk);
  nActivate |= (GetIsNight() && nNight);

  if (nActivate)
    SetObjectState(oObject, PLACEABLE_STATE_ACTIVATED);
  else
    SetObjectState(oObject, PLACEABLE_STATE_DEACTIVATED);
}


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

//! @brief Call ActivateObject on every object in oArea (skipped when the area has no players).
//! @param oArea An area.
void ActivateArea(object oArea);
void ActivateArea(object oArea)
{
  int nCount = NWNX_Area_GetNumberOfPlayersInArea(oArea);
  if (nCount == 0)
    return;

  object oObject = GetFirstObjectInArea(oArea);
  while (GetIsObjectValid(oObject))
  {
    ActivateObject(oObject);
    oObject = GetNextObjectInArea(oArea);
  }
}


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

//! @brief Call ActivateArea on the area of every player, after a random delay.
void ActivateModule();
void ActivateModule()
{
  // Instead of looping through all areas, just loop on players
  object oPC = GetFirstPC();
  while (GetIsObjectValid(oPC))
  {
    DelayCommand(GetRandomMaxDelay(MINUTE_MAX_DELAY), ActivateArea(GetArea(oPC)));
    oPC = GetNextPC();
  }
}


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

void main()
{
  string sEvent = NWNX_Events_GetCurrentEvent();
  if (sEvent == ON_REGISTER)
  {
    if (!GetModuleFlag(ENABLE__FF_U_V_CYCLE_ACTIVATE, TRUE))
      return;

    SubscribeToEvent(ON_DEFAULT_AREA_ENTER, __FILE__);
    SubscribeToEvent(ON_CALENDAR_HOUR, __FILE__);
    SubscribeToEvent(ON_CALENDAR_TIME_CHANGED, __FILE__);
  }
  else if (sEvent == ON_DEFAULT_AREA_ENTER)
    ActivateArea(OBJECT_SELF);
  else if (sEvent == ON_CALENDAR_HOUR)
    ActivateModule();
  else if (sEvent == ON_CALENDAR_TIME_CHANGED) // This event is only sent manually.
    ActivateModule();
}