ff_u_cal_p_time

Persistent game date and time.

Keeps the game date and time across server restarts. They are saved every game hour, at module shutdown, and whenever a script signals that the time was changed (ON_CALENDAR_TIME_CHANGED). They are restored at module startup; on the first run, when nothing is saved yet, the module’s starting date and time are saved instead.

The data is stored in the campaign database <campaign name>_calendar (see ff_i_campaign). If it is deleted, the next startup begins again from the module’s starting date and time.

Variables

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

Source code

// @code

#include "ff_i_core"

const string LOCAL_CAMPAIGN_NAME = "calendar";

const string ENABLE__FF_U_CAL_P_TIME = "ENABLE__FF_U_CAL_P_TIME";


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

//! @brief Save the date and time to the campaign database.
void SaveCalendar();
void SaveCalendar()
{
  string sCampaign = GetCampaignName(LOCAL_CAMPAIGN_NAME);

  SetCampaignInt(sCampaign, "YEAR",   GetCalendarYear());
  SetCampaignInt(sCampaign, "MONTH",  GetCalendarMonth());
  SetCampaignInt(sCampaign, "DAY",    GetCalendarDay());
  SetCampaignInt(sCampaign, "HOUR",   GetTimeHour());
  SetCampaignInt(sCampaign, "MINUTE", GetTimeMinute());

  DelayCommand(0.0f, LogNotice("Persistent date & time saved: " + GetGameDate() + " " + GetGameTime()));
}


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

//! @brief Restore the date and time from the campaign database, then signal ON_CALENDAR_TIME_CHANGED.
//! If nothing is saved yet, save the current date and time first.
void LoadCalendar();
void LoadCalendar()
{
  string sCampaign = GetCampaignName(LOCAL_CAMPAIGN_NAME);

  int nYear    = GetCampaignInt(sCampaign, "YEAR");
  int nMonth   = GetCampaignInt(sCampaign, "MONTH");
  int nDay     = GetCampaignInt(sCampaign, "DAY");
  int nHour    = GetCampaignInt(sCampaign, "HOUR");
  int nMinute  = GetCampaignInt(sCampaign, "MINUTE");

  if (nYear == 0)
  {
    SaveCalendar();
    LoadCalendar();
  }
  else
  {
    // Delay so the log gets shown after module load.
    DelayCommand(0.0001f, LogNotice("Current date & time: " + GetGameDate() + " " + GetGameTime()));
    DelayCommand(0.0002f, LogNotice("Persistent date & time loaded: " + GetDateString(nYear, nMonth, nDay) + " " + GetTimeString(nHour, nMinute, 0)));

    // WARNING:
    // SetTime makes DelayCommand execute all delayed commands at once.
    //
    // Since this is only executed once, ensure it is executed before other delays
    // go off by having it before the module start.

    // SetTime can make the day advance, so do it first.
    SetTime(nHour, nMinute, 0, 0);
    SetCalendar(nYear, nMonth, nDay);

    NWNX_Events_SignalEvent(ON_CALENDAR_TIME_CHANGED, GetModule());
  }
}


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

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

    LoadCalendar();
    SubscribeToEvent(ON_CALENDAR_HOUR, __FILE__);
    SubscribeToEvent(ON_CALENDAR_TIME_CHANGED, __FILE__);
    SubscribeToEvent(ON_MODULE_SHUTDOWN, __FILE__);
  }
  else if (sEvent == ON_MODULE_SHUTDOWN)
    SaveCalendar();
  else
    DelayCommand(0.0f, SaveCalendar());
}