ff_u_store_pers

Persistent stores.

Saves and restores the inventory of eligible stores across server restarts.

On area enter, the store saved in the database is merged into the store from the toolset: the toolset settings and infinite items are kept, and the saved non-infinite items are added.

A store is not meant to have non-infinite items in the toolset (instance or template).

Eligibility requires all of the following on the store:

  • Has a unique tag.

  • PERSISTENT flag set to "Y".

Variables

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

PERSISTENT: (string) Set to "Y" on a store to opt in.

Source code

// @code

#include "ff_i_core"


const string ENABLE__FF_U_STORE_PERSISTENT = "ENABLE__FF_U_STORE_PERSISTENT";

const string PERSISTENT = "PERSISTENT";

const string LOCAL_CAMPAIGN_NAME = "p_store";

const string TABLE_NAME = "stores";

//! Local int set on a store once its items were restored, so they are never restored twice.
const string FF_U_STORE_PERSISTENT = "__FF_U_STORE_PERSISTENT";

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

//! @brief Return TRUE if oObject is a PERSISTENT store with a unique tag.
//! @param oObject An object.
int IsEligible(object oObject);
int IsEligible(object oObject)
{
  if (GetObjectType(oObject) != OBJECT_TYPE_STORE)
    return FALSE;

  if (!GetObjectFlag(oObject, PERSISTENT))
    return FALSE;

  if (!IsTagUnique(oObject))
    return FALSE;

  return TRUE;
}


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

//! @brief Restore persisted items from the campaign database into oObject.
//! @param oObject An eligible store.
void LoadItems(object oObject);
void LoadItems(object oObject)
{
  if (!IsEligible(oObject))
    return;

  if (GetLocalInt(oObject, FF_U_STORE_PERSISTENT))
    return;
  SetLocalInt(oObject, FF_U_STORE_PERSISTENT, TRUE);

  int nCount = LoadPersistentItems(oObject, LOCAL_CAMPAIGN_NAME, TABLE_NAME);
  if (nCount)
    LogInfo(__FILE__ + ": Restored " + IntToString(nCount) + " item(s) into " + GetTag(oObject));
}


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

//! @brief Save the current inventory of oObject to the campaign database.
//! @param oObject An eligible store.
void SaveItems(object oObject);
void SaveItems(object oObject)
{
  if (!IsEligible(oObject))
    return;

  SavePersistentItems(oObject, LOCAL_CAMPAIGN_NAME, TABLE_NAME);
}


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

//! @brief Restore the items of every eligible store in oArea.
//! @param oArea An area.
void OnArea(object oArea);
void OnArea(object oArea)
{
  object oObject = GetFirstObjectInArea(oArea);
  while (GetIsObjectValid(oObject))
  {
    LoadItems(oObject);
    oObject = GetNextObjectInArea(oArea);
  }
}


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

//! @brief Check that an eligible store has a unique tag, identical to its resref.
//! @param oStore A store.
void OnVerify(object oStore);
void OnVerify(object oStore)
{
  if (!IsEligible(oStore))
    return;

  ExpectIdenticalTagAndResRef(oStore);
  ExpectUniqueTag(oStore);
}


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

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

    SubscribeToEvent(ON_MODULE_CREATED, __FILE__);
    SubscribeToEvent(ON_AFTER_OBJECT_CREATED, __FILE__);
    SubscribeToEvent(ON_OBJECT_VERIFY, __FILE__);
    SubscribeToEvent(ON_DEFAULT_STORE_CLOSED, __FILE__);
    SubscribeToEvent(ON_DEFAULT_AREA_ENTER_ONCE, __FILE__);
  }
  else if (sEvent == ON_MODULE_CREATED)
    CreatePersistentDatabase(LOCAL_CAMPAIGN_NAME, TABLE_NAME);
  else if (sEvent == ON_OBJECT_VERIFY)
    OnVerify(OBJECT_SELF);
  else if (sEvent == ON_AFTER_OBJECT_CREATED)
    LoadItems(OBJECT_SELF);
  else if (sEvent == ON_DEFAULT_STORE_CLOSED)
    SaveItems(OBJECT_SELF);
  else if (sEvent == ON_DEFAULT_AREA_ENTER_ONCE)
    OnArea(OBJECT_SELF);
}