ff_u_rename

Copy the localized name of the configured language to all languages.

The localized name of the configured language is copied to all other languages. If the object has a description, it is also copied.

Copied texts are converted like the TLK overrides (eos_tlk_ovr.2da…): color aliases such as <cGreen> and <cDefault> are replaced by their custom tokens, and \\n by a new line. This is needed for texts read from the TLK, such as base item descriptions, as TLK overrides do not apply to them.

Areas are renamed when they are created. The objects of an area, with their inventory and equipped items, are renamed when a PC first enters the area.

Variables

ENABLE__FF_U_RENAME: (string) (opt-in) Set to "Y" on module to enable the unit.

PLAYER_LANGUAGE_NAME: (int) PLAYER_LANGUAGE_* for the object name.

PLAYER_LANGUAGE_DESCRIPTION: (int) PLAYER_LANGUAGE_* for the object description.

Source code

// @code

#include "ff_i_core"


const string ENABLE__FF_U_RENAME = "ENABLE__FF_U_RENAME";

const string PLAYER_LANGUAGE_NAME = "PLAYER_LANGUAGE_NAME";

const string PLAYER_LANGUAGE_DESCRIPTION = "PLAYER_LANGUAGE_DESCRIPTION";


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

//! @brief Return the PLAYER_LANGUAGE_* to use for naming, or FALSE if naming is not needed.
//! @param oObject An object.
int LanguageToUse(object oObject);
int LanguageToUse(object oObject)
{
  if (!GetIsObjectValid(oObject))
    return FALSE;

  int nType = NWNX_Object_GetInternalObjectType(oObject);
  switch (nType)
  {
    case NWNX_OBJECT_TYPE_INTERNAL_AREA:      break;
    case NWNX_OBJECT_TYPE_INTERNAL_WAYPOINT:  break;

    case NWNX_OBJECT_TYPE_INTERNAL_CREATURE:  break;
    case NWNX_OBJECT_TYPE_INTERNAL_DOOR:      break;
    case NWNX_OBJECT_TYPE_INTERNAL_ITEM:      break;
    case NWNX_OBJECT_TYPE_INTERNAL_PLACEABLE:
      // No need to change name if not displayed
      if (NWNX_Object_GetPlaceableIsStatic(oObject))
        return FALSE;
      break;
    case NWNX_OBJECT_TYPE_INTERNAL_SOUND:     return FALSE;
    case NWNX_OBJECT_TYPE_INTERNAL_ENCOUNTER: return FALSE;
    case NWNX_OBJECT_TYPE_INTERNAL_STORE:     return FALSE;
    case NWNX_OBJECT_TYPE_INTERNAL_TRIGGER:   return FALSE;
  }

  // Use a translated language as primary language?
  // PLAYER_LANGUAGE_ENGLISH is 0, so if unset, it's also 0
  int nLanguage = GetLocalInt(GetModule(), PLAYER_LANGUAGE_NAME);
  if (nLanguage == PLAYER_LANGUAGE_ENGLISH)
    return FALSE;

  return nLanguage;
}


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

//! @brief Copy the configured localized name/description to all other languages for oObject.
//! @param oObject An object.
void SetNameEx(object oObject);
void SetNameEx(object oObject)
{
  int nLanguage = LanguageToUse(oObject);
  if (nLanguage == FALSE)
    return;

  // SetName should take priority. If empty, only localized values are shown
  string sValue = NWNX_Object_GetLocalizedName(oObject, nLanguage);
  // No translation: keep the current names (OnVerify warns about it)
  if (sValue == "")
    return;
  sValue = GetTLKColored(sValue);
  SetName(oObject, sValue);

  int i;
  for (i = PLAYER_LANGUAGE_ENGLISH; i <= PLAYER_LANGUAGE_POLISH; i++)
  {
    NWNX_Object_SetLocalizedName(oObject, sValue, i, 0);
    NWNX_Object_SetLocalizedName(oObject, sValue, i, 1);
  }

  // Areas, stores, triggers don't have descriptions
  int nType = NWNX_Object_GetInternalObjectType(oObject);
  switch (nType)
  {
    case NWNX_OBJECT_TYPE_INTERNAL_AREA:
    case NWNX_OBJECT_TYPE_INTERNAL_STORE:
    case NWNX_OBJECT_TYPE_INTERNAL_TRIGGER:
      return;
  }

  // Same reasons as above
  nLanguage = GetLocalInt(GetModule(), PLAYER_LANGUAGE_DESCRIPTION);
  sValue = NWNX_Object_GetLocalizedDescription(oObject, nLanguage, 0, TRUE);
  if (sValue != "")
  {
    sValue = GetTLKColored(sValue);
    SetDescription(oObject, sValue, TRUE);
    for (i = PLAYER_LANGUAGE_ENGLISH; i <= PLAYER_LANGUAGE_POLISH; i++)
    {
      if (nLanguage != i)
        NWNX_Object_SetLocalizedDescription(oObject, sValue, i, 0, TRUE);
    }
  }

  // Items have identified and non-identified descriptions.
  if (nType != NWNX_OBJECT_TYPE_INTERNAL_ITEM)
    return;

  sValue = NWNX_Object_GetLocalizedDescription(oObject, nLanguage, 0, FALSE);
  if (sValue == "")
    return;
  sValue = GetTLKColored(sValue);
  SetDescription(oObject, sValue, FALSE);
  for (i = PLAYER_LANGUAGE_ENGLISH; i <= PLAYER_LANGUAGE_POLISH; i++)
  {
    if (nLanguage != i)
      NWNX_Object_SetLocalizedDescription(oObject, sValue, i, 0, FALSE);
  }
}


//! @brief Call SetNameEx on oObject and its content.
//! @param oObject An area or an object.
void SetRecursiveNameEx(object oObject)
{
  SetNameEx(oObject);
  object oItem = GetFirstItemInInventory(oObject);
  while (GetIsObjectValid(oItem))
  {
    SetNameEx(oItem);
    oItem = GetNextItemInInventory(oObject);
  }

  // Equipped items are not part of the inventory
  if (GetObjectType(oObject) == OBJECT_TYPE_CREATURE)
  {
    int nSlot;
    for (nSlot = 0; nSlot < NUM_INVENTORY_SLOTS; nSlot++)
    {
      oItem = GetItemInSlot(nSlot, oObject);
      if (GetIsObjectValid(oItem))
        SetNameEx(oItem);
    }
  }
}


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

void OnArea(object oArea);
void OnArea(object oArea)
{
  object oObject = GetFirstObjectInArea(oArea);
  while (GetIsObjectValid(oObject))
  {
    SetRecursiveNameEx(oObject);
    oObject = GetNextObjectInArea(oArea);
  }
}


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

//! @brief Warn if oObject has no translation text for the configured language.
//! @param oObject An object.
void OnVerify(object oObject);
void OnVerify(object oObject)
{
  // Use a translated language as primary language?
  // PLAYER_LANGUAGE_ENGLISH is 0, so if unset, it's also 0
  int nLanguage = LanguageToUse(oObject);
  if (nLanguage == FALSE)
    return;

  string sValue = NWNX_Object_GetLocalizedName(oObject, nLanguage);
  if (sValue == "")
  {
    LogWarning("Object " + GetObjectInfo(oObject) + " in " + GetObjectInfo(GetArea(oObject)) + " has no translation text");
    return;
  }
}


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

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

    SubscribeToEvent(ON_OBJECT_VERIFY, __FILE__);
    SubscribeToEvent(ON_AREA_CREATED, __FILE__);
    SubscribeToEvent(ON_DEFAULT_AREA_ENTER_ONCE, __FILE__);
  }
  else if (sEvent == ON_OBJECT_VERIFY)
    OnVerify(OBJECT_SELF);
  else if (sEvent == ON_AREA_CREATED)
    SetNameEx(OBJECT_SELF);
  else if (sEvent == ON_DEFAULT_AREA_ENTER_ONCE)
    OnArea(OBJECT_SELF);
}