ff_u_area_map
Persistent minimaps.
Explored tiles of an area are stored per player, in a persistent variable on
the PC named after the area tag (NWNX_Object persistent string), holding a json
array of explored tiles:
[{"x": 0, "y": 0}, ...].
The minimap is restored on area enter, and saved on area exit, on logout and on rest.
Only areas flagged PERSISTENT_MINIMAP are handled, and only for PCs (DMs are ignored).
Variables
ENABLE__FF_U_AREA_MAP: (string) (opt-out) Set to "N" on module to disable the unit.
PERSISTENT_MINIMAP: (string) (opt-in) Set to "Y" on an area to persist its
minimap.
Source code
// @code
#include "ff_i_core"
#include "nwnx_object"
const string ENABLE__FF_U_AREA_MAP = "ENABLE__FF_U_AREA_MAP";
const string PERSISTENT_MINIMAP = "PERSISTENT_MINIMAP";
const string MINIMAP_VAR_PREFIX = "MINIMAP_";
// -----------------------------------------------------------------------------
//! @brief Return TRUE if oArea is flagged PERSISTENT_MINIMAP.
//! @param oArea An area.
int IsEligible(object oArea);
int IsEligible(object oArea)
{
return GetObjectFlag(oArea, PERSISTENT_MINIMAP, FALSE);
}
// -----------------------------------------------------------------------------
//! @brief Return TRUE if oPC is a player character, not a DM.
//! @param oPC An object.
int IsPlayer(object oPC);
int IsPlayer(object oPC)
{
return GetIsPC(oPC) && !GetIsDM(oPC);
}
// -----------------------------------------------------------------------------
//! @brief Return the persistent variable name holding the minimap of oArea.
//! @param oArea An eligible area.
string GetVarName(object oArea);
string GetVarName(object oArea)
{
return MINIMAP_VAR_PREFIX + GetStringUpperCase(GetTag(oArea));
}
// -----------------------------------------------------------------------------
//! @brief Restore the stored minimap of oArea onto oPC.
//! @param oPC A player character.
//! @param oArea An eligible area.
void LoadMinimap(object oPC, object oArea);
void LoadMinimap(object oPC, object oArea)
{
if (!IsEligible(oArea))
return;
json jTiles = JsonParse(NWNX_Object_GetString(oPC, GetVarName(oArea)));
if (JsonGetType(jTiles) != JSON_TYPE_ARRAY)
return;
int nCount = JsonGetLength(jTiles);
int i;
for (i = 0; i < nCount; i++)
{
json jTile = JsonArrayGet(jTiles, i);
SetTileExplored(oPC, oArea, JsonGetInt(JsonObjectGet(jTile, "x")), JsonGetInt(JsonObjectGet(jTile, "y")), TRUE);
}
if (nCount)
LogInfo(__FILE__ + ": Restored " + IntToString(nCount) + " tile(s) of " + GetTag(oArea) + " for " + GetName(oPC));
}
// -----------------------------------------------------------------------------
//! @brief Save the minimap of oArea as currently known by oPC.
//! @param oPC A player character.
//! @param oArea An eligible area.
void SaveMinimap(object oPC, object oArea);
void SaveMinimap(object oPC, object oArea)
{
if (!IsEligible(oArea))
return;
int nWidth = GetAreaSize(AREA_WIDTH, oArea);
int nHeight = GetAreaSize(AREA_HEIGHT, oArea);
json jTiles = JsonArray();
int nX, nY;
for (nY = 0; nY < nHeight; nY++)
for (nX = 0; nX < nWidth; nX++)
if (GetTileExplored(oPC, oArea, nX, nY))
{
json jTile = JsonObjectSet(JsonObject(), "x", JsonInt(nX));
jTile = JsonObjectSet(jTile, "y", JsonInt(nY));
jTiles = JsonArrayInsert(jTiles, jTile);
}
NWNX_Object_SetString(oPC, GetVarName(oArea), JsonDump(jTiles), TRUE);
LogDebug(__FILE__, "SaveMinimap (" + GetName(oPC) + ") saved " + GetTag(oArea));
}
// -----------------------------------------------------------------------------
void OnVerify(object oArea);
void OnVerify(object oArea)
{
if (!IsEligible(oArea))
return;
ExpectUniqueTag(oArea);
}
// -----------------------------------------------------------------------------
void main()
{
string sEvent = NWNX_Events_GetCurrentEvent();
if (sEvent == ON_REGISTER)
{
if (!GetModuleFlag(ENABLE__FF_U_AREA_MAP, TRUE))
return;
SubscribeToEvent(ON_OBJECT_VERIFY, __FILE__);
SubscribeToEvent(ON_DEFAULT_AREA_ENTER, __FILE__);
SubscribeToEvent(ON_DEFAULT_CLIENT_EXIT, __FILE__);
SubscribeToEvent(ON_DEFAULT_AREA_EXIT, __FILE__);
SubscribeToEvent(ON_DEFAULT_PC_REST_START, __FILE__);
}
else if (sEvent == ON_OBJECT_VERIFY)
OnVerify(OBJECT_SELF);
else if (sEvent == ON_DEFAULT_AREA_ENTER)
{
object oPC = GetEnteringObject();
if (IsPlayer(oPC))
LoadMinimap(oPC, OBJECT_SELF);
}
else if (sEvent == ON_DEFAULT_AREA_EXIT)
{
object oPC = GetExitingObject();
if (IsPlayer(oPC))
SaveMinimap(oPC, OBJECT_SELF);
}
else if (sEvent == ON_DEFAULT_CLIENT_EXIT)
{
object oPC = GetExitingObject();
if (IsPlayer(oPC))
SaveMinimap(oPC, GetArea(oPC));
}
else if (sEvent == ON_DEFAULT_PC_REST_START)
{
object oPC = GetLastPCRested();
if (IsPlayer(oPC))
SaveMinimap(oPC, GetArea(oPC));
}
}