RE: Indexing Game Clock OnPlayerRest in Multi-Player

Normally, in SP modules, I index the game clock 8 hours when the player rests. I am currently looking at implementing this in my Lan PW.

I had a conversation with someone last fall (maybe @Shadooow ) and he gave me this function to Set the campaign time in the OnclientEnter.

void SetCampaignTime()
{
    int nDate = GetCampaignInt("NWR_SERVER","TIME");
    if(nDate > 0)
    {
        int nYear  = (nDate/8064)+START_YEAR;
        int nMonth = (nDate%8064)/672+1;
        int nDay   = (nDate%672)/24+1;
        int nHour  = nDate%24;
//        WriteTimestampedLogEntry("Y M D H "+IntToString(nYear)+" "+IntToString(nMonth)+" "+IntToString(nDay)+" "+IntToString(nHour));
        SetTime(nHour,0,0,0);
        SetCalendar(nYear,nMonth,nDay);
    }
}

void SaveModuleTimePseudoHB()
{
    if(GetFirstPC() != OBJECT_INVALID || STORE_TIME_EVEN_IF_THERE_ARE_NO_PLAYERS)
    {
        SetCampaignInt("NWR_SERVER","TIME",GetTimeHour()+(GetCalendarDay()-1)*24+(GetCalendarMonth()-1)*672+(GetCalendarYear()-START_YEAR)*8064);
    }
    DelayCommand(HoursToSeconds(1), SaveModuleTimePseudoHB());
}

I have this block of code I got years ago that I use to index the game clock.

void rs_IndexGameClock(int nHr = 0, int nMin = 0, int nSec = 0, int nMil =0)
{
    int nHour = GetTimeHour() + nHr;
    int nMinute = GetTimeMinute() + nMin;
    int nSecond = GetTimeSecond() + nSec;
    int nMillisecond = GetTimeMillisecond() + nMil;
    SetTime(nHour, nMinute, nSecond, nMillisecond);
}

Do I need to do something with the stored value for the Campaign Time, or will my current method of indexing persist through a server reset?

I don’t think I’ve ever seen the word “index” used like that :slight_smile:

For MP it’s not generally a good idea to move time forward since the clock is global. I suppose if you have a single party in your MP and they all rest at the same time, all the time, it would be fine.

What you have there should just work, from a coding perspective.

That should all work, though it’s bit heavy-handed. If you’d like, I have a set of time manipulation functions that can probably do exactly what you want with this code:

void SetServerTime()
{
    string sTime = GetDatabseString("SERVER_TIME");
    if (sTime != "")
        _SetCalendar(sTime, TRUE, TRUE);
}

void SaveServerTime()
{
    if (GetFirstPC() != OBJECT_INVALID || STORE_TIME_EVEN_IF_THERE_ARE_NO_PLAYERS)
        SetDatabaseString("SERVER_TIME", GetSystemTime());
}

The database calls are functions I use. You can replace those with whatever you use to store persistent data.

Also, for you heartbeat, if you want to drop that delaycommand, you can add this instead (to your current heartbeat script). Obviously, if you don’t use a heartbeat script, then the current delaycommand method will work fine:

        int nHour    = GetTimeHour();
        int nOldHour = GetLocalInt(OBJECT_SELF, CURRENT_HOUR);

        if (nHour != nOldHour)
        {
            SetLocalInt(OBJECT_SELF, CURRENT_HOUR, nHour);
            SaveServerTime();
        }

Then, to advance time at some point:

void AdvanceServerTime(int nHours)
{
    string sNewTime = AddSystemTimeElement(TIME_HOURS, nHours, GetSystemTime());
    _SetCalendar(sNewTime, TRUE, TRUE);
}

If you want these functions, let me know. I’ve never tried to add files here, but I can get them to you on discord.

1 Like

Didn’t think of the clock being global. Thanks for that.