PRC8/nwn/nwnprc/trunk/include/inc_time.nss
Jaysyn904 6ec137a24e Updated AMS marker feats
Updated AMS marker feats.  Removed arcane & divine marker feats.  Updated Dread Necromancer for epic progression. Updated weapon baseitem models.  Updated new weapons for crafting & npc equip.
 Updated prefix.  Updated release archive.
2024-02-11 14:01:05 -05:00

502 lines
15 KiB
Plaintext

/** @file
This set of functions controlls time for players.
When recalculate time is called, the clock advances to that of the most behind player.
This system works best with single party modules. If you have multiple parties and player
you may find that when the server catches up it may disorent players for a time.
This is disabled unless the switch PRC_PLAYER_TIME is true
Also in this include is a time struct and various functions for expressing time
As part of this, there is some custom tokens that can be setup
//82001 part of day
//82002 date
//82003 month
//82004 year
//82005 hour
//82006 minutes
//82007 seconds
@author Primogenitor
*/
//////////////////////////////////////////////////
/* Function Prototypes */
//////////////////////////////////////////////////
struct time
{
int nYear;
int nMonth;
int nDay;
int nHour;
int nMinute;
int nSecond;
int nMillisecond;
};
struct time TimeCheck(struct time tTime);
struct time GetLocalTime(object oObject, string sName);
void SetLocalTime(object oObject, string sName, struct time tTime);
void DeleteLocalTime(object oObject, string sName);
struct time GetPersistantLocalTime(object oObject, string sName);
void SetPersistantLocalTime(object oObject, string sName, struct time tTime);
string TimeToString(struct time tTime);
struct time StringToTime(string sIn);
void SetTimeAndDate(struct time tTime);
int GetIsTimeAhead(struct time tTime1, struct time tTime2);
void RecalculateTime(int nMaxStep = 6);
void AdvanceTimeForPlayer(object oPC, float fSeconds);
//////////////////////////////////////////////////
/* Include section */
//////////////////////////////////////////////////
//#include "prc_inc_switch"
#include "inc_persist_loca"
//////////////////////////////////////////////////
/* Function Definitions */
//////////////////////////////////////////////////
struct time TimeAdd(struct time tTime1, struct time tTime2)
{
tTime1 = TimeCheck(tTime1);
tTime2 = TimeCheck(tTime2);
tTime1.nYear += tTime2.nYear;
tTime1.nMonth += tTime2.nMonth;
tTime1.nDay += tTime2.nDay;
tTime1.nHour += tTime2.nHour;
tTime1.nMinute += tTime2.nMinute;
tTime1.nSecond += tTime2.nSecond;
tTime1.nMillisecond += tTime2.nMillisecond;
tTime1 = TimeCheck(tTime1);
return tTime1;
}
struct time TimeSubtract(struct time tTime1, struct time tTime2)
{
tTime1 = TimeCheck(tTime1);
tTime2 = TimeCheck(tTime2);
tTime1.nYear -= tTime2.nYear;
tTime1.nMonth -= tTime2.nMonth;
tTime1.nDay -= tTime2.nDay;
tTime1.nHour -= tTime2.nHour;
tTime1.nMinute -= tTime2.nMinute;
tTime1.nSecond -= tTime2.nSecond;
tTime1.nMillisecond -= tTime2.nMillisecond;
tTime1 = TimeCheck(tTime1);
return tTime1;
}
struct time GetLocalTime(object oObject, string sName)
{
struct time tTime;
tTime.nYear = GetLocalInt(oObject, sName+".nYear");
tTime.nMonth = GetLocalInt(oObject, sName+".nMonth");
tTime.nDay = GetLocalInt(oObject, sName+".nDay");
tTime.nHour = GetLocalInt(oObject, sName+".nHour");
tTime.nMinute = GetLocalInt(oObject, sName+".nMinute");
tTime.nSecond = GetLocalInt(oObject, sName+".nSecond");
tTime.nMillisecond = GetLocalInt(oObject, sName+".nMillisecond");
tTime = TimeCheck(tTime);
return tTime;
}
void SetLocalTime(object oObject, string sName, struct time tTime)
{
tTime = TimeCheck(tTime);
SetLocalInt(oObject, sName+".nYear", tTime.nYear);
SetLocalInt(oObject, sName+".nMonth", tTime.nMonth);
SetLocalInt(oObject, sName+".nDay", tTime.nDay);
SetLocalInt(oObject, sName+".nHour", tTime.nHour);
SetLocalInt(oObject, sName+".nMinute", tTime.nMinute);
SetLocalInt(oObject, sName+".nSecond", tTime.nSecond);
SetLocalInt(oObject, sName+".nMillisecond", tTime.nMillisecond);
}
void DeleteLocalTime(object oObject, string sName)
{
DeleteLocalInt(oObject, sName+".nYear");
DeleteLocalInt(oObject, sName+".nMonth");
DeleteLocalInt(oObject, sName+".nDay");
DeleteLocalInt(oObject, sName+".nHour");
DeleteLocalInt(oObject, sName+".nMinute");
DeleteLocalInt(oObject, sName+".nSecond");
DeleteLocalInt(oObject, sName+".nMillisecond");
}
struct time GetPersistantLocalTime(object oObject, string sName)
{
struct time tTime;
tTime.nYear = GetPersistantLocalInt(oObject, sName+".nYear");
tTime.nMonth = GetPersistantLocalInt(oObject, sName+".nMonth");
tTime.nDay = GetPersistantLocalInt(oObject, sName+".nDay");
tTime.nHour = GetPersistantLocalInt(oObject, sName+".nHour");
tTime.nMinute = GetPersistantLocalInt(oObject, sName+".nMinute");
tTime.nSecond = GetPersistantLocalInt(oObject, sName+".nSecond");
tTime.nMillisecond = GetPersistantLocalInt(oObject, sName+".nMillisecond");
tTime = TimeCheck(tTime);
return tTime;
}
void SetPersistantLocalTime(object oObject, string sName, struct time tTime)
{
tTime = TimeCheck(tTime);
SetPersistantLocalInt(oObject, sName+".nYear", tTime.nYear);
SetPersistantLocalInt(oObject, sName+".nMonth", tTime.nMonth);
SetPersistantLocalInt(oObject, sName+".nDay", tTime.nDay);
SetPersistantLocalInt(oObject, sName+".nHour", tTime.nHour);
SetPersistantLocalInt(oObject, sName+".nMinute", tTime.nMinute);
SetPersistantLocalInt(oObject, sName+".nSecond", tTime.nSecond);
SetPersistantLocalInt(oObject, sName+".nMillisecond", tTime.nMillisecond);
}
string TimeToString(struct time tTime)
{
string sReturn;
sReturn += IntToString(tTime.nYear)+"|";
sReturn += IntToString(tTime.nMonth)+"|";
sReturn += IntToString(tTime.nDay)+"|";
sReturn += IntToString(tTime.nHour)+"|";
sReturn += IntToString(tTime.nMinute)+"|";
sReturn += IntToString(tTime.nSecond)+"|";
sReturn += IntToString(tTime.nMillisecond);
return sReturn;
}
struct time StringToTime(string sIn)
{
struct time tTime;
int nPos;
string sID;
nPos = FindSubString(sIn, "|");
tTime.nYear = StringToInt(GetStringLeft(sIn, nPos));
sIn = GetStringRight(sIn, GetStringLength(sIn)-nPos-1);
nPos = FindSubString(sIn, "|");
tTime.nMonth = StringToInt(GetStringLeft(sIn, nPos));
sIn = GetStringRight(sIn, GetStringLength(sIn)-nPos-1);
nPos = FindSubString(sIn, "|");
tTime.nDay = StringToInt(GetStringLeft(sIn, nPos));
sIn = GetStringRight(sIn, GetStringLength(sIn)-nPos-1);
nPos = FindSubString(sIn, "|");
tTime.nHour = StringToInt(GetStringLeft(sIn, nPos));
sIn = GetStringRight(sIn, GetStringLength(sIn)-nPos-1);
nPos = FindSubString(sIn, "|");
tTime.nMinute = StringToInt(GetStringLeft(sIn, nPos));
sIn = GetStringRight(sIn, GetStringLength(sIn)-nPos-1);
nPos = FindSubString(sIn, "|");
tTime.nSecond = StringToInt(GetStringLeft(sIn, nPos));
sIn = GetStringRight(sIn, GetStringLength(sIn)-nPos-1);
nPos = FindSubString(sIn, "|");
tTime.nMillisecond = StringToInt(GetStringLeft(sIn, nPos));
sIn = GetStringRight(sIn, GetStringLength(sIn)-nPos-1);
return tTime;
}
struct time TimeCheck(struct time tTime)
{
while(tTime.nMillisecond > 1000)
{
tTime.nSecond += 1;
tTime.nMillisecond -= 1000;
}
while(tTime.nSecond > 60)
{
tTime.nMinute += 1;
tTime.nSecond -= 60;
}
while(tTime.nMinute > FloatToInt(HoursToSeconds(1))/60)
{
tTime.nHour += 1;
tTime.nMinute -= FloatToInt(HoursToSeconds(1))/60;
}
while(tTime.nHour > 24)
{
tTime.nDay += 1;
tTime.nHour -= 24;
}
while(tTime.nDay > 28)
{
tTime.nMonth += 1;
tTime.nDay -= 28;
}
while(tTime.nMonth > 12)
{
tTime.nYear += 1;
tTime.nMonth -= 12;
}
//decreases
while(tTime.nMillisecond < 1)
{
tTime.nSecond -= 1;
tTime.nMillisecond += 1000;
}
while(tTime.nSecond < 1)
{
tTime.nMinute -= 1;
tTime.nSecond += 60;
}
while(tTime.nMinute < 1)
{
tTime.nHour -= 1;
tTime.nMinute += FloatToInt(HoursToSeconds(1))/60;
}
while(tTime.nHour < 1)
{
tTime.nDay -= 1;
tTime.nHour += 24;
}
while(tTime.nDay < 1)
{
tTime.nMonth -= 1;
tTime.nDay += 28;
}
while(tTime.nMonth < 1)
{
tTime.nYear -= 1;
tTime.nMonth += 12;
}
return tTime;
}
struct time GetTimeAndDate()
{
struct time tTime;
tTime.nYear = GetCalendarYear();
tTime.nMonth = GetCalendarMonth();
tTime.nDay = GetCalendarDay();
tTime.nHour = GetTimeHour();
tTime.nMinute = GetTimeMinute();
tTime.nSecond = GetTimeSecond();
tTime.nMillisecond = GetTimeMillisecond();
tTime = TimeCheck(tTime);
return tTime;
}
void SetTimeAndDate(struct time tTime)
{
tTime = TimeCheck(tTime);
SetCalendar(tTime.nYear, tTime.nMonth, tTime.nDay);
SetTime(tTime.nHour, tTime.nMinute, tTime.nSecond, tTime.nMillisecond);
}
int GetIsTimeAhead(struct time tTime1, struct time tTime2)
{
if(tTime1.nYear > tTime2.nYear)
return TRUE;
else if(tTime1.nYear < tTime2.nYear)
return FALSE;
//equal
if(tTime1.nMonth > tTime2.nMonth)
return TRUE;
else if(tTime1.nMonth < tTime2.nMonth)
return FALSE;
//equal
if(tTime1.nDay > tTime2.nDay)
return TRUE;
else if(tTime1.nDay < tTime2.nDay)
return FALSE;
//equal
if(tTime1.nHour > tTime2.nHour)
return TRUE;
else if(tTime1.nHour < tTime2.nHour)
return FALSE;
//equal
if(tTime1.nMinute > tTime2.nMinute)
return TRUE;
else if(tTime1.nMinute < tTime2.nMinute)
return FALSE;
//equal
if(tTime1.nSecond > tTime2.nSecond)
return TRUE;
else if(tTime1.nSecond < tTime2.nSecond)
return FALSE;
//equal
if(tTime1.nMillisecond > tTime2.nMillisecond)
return TRUE;
else if(tTime1.nMillisecond < tTime2.nMillisecond)
return FALSE;
//must be exactly the same
return FALSE;
}
void RecalculateTime(int nMaxStep = 6)
{
if(!GetPRCSwitch(PRC_PLAYER_TIME))
return;
//get the earliest time ahead of all PCs
object oPC = GetFirstPC();
struct time tTimeAhead = GetLocalTime(oPC, "TimeAhead");
while(GetIsObjectValid(oPC))
{
struct time tTest = GetLocalTime(oPC, "TimeAhead");
if(!GetIsTimeAhead(tTimeAhead, tTest))
tTimeAhead = tTest;
oPC = GetNextPC();
}
//if its zero, abort
struct time tNULL;
if(tNULL == tTimeAhead)
return;
//if its not zero, recalulate it till it is
DelayCommand(0.01, RecalculateTime());//do it again until caught up
//create the steps to use
struct time tStep;
tStep.nSecond = nMaxStep;
//make sure you dont skip more than a step at a time
if(GetIsTimeAhead(tTimeAhead, tStep))
tTimeAhead = tStep;
//set the new real time
struct time tNewTime = GetTimeAndDate();
tNewTime = TimeAdd(tNewTime, tTimeAhead);
SetTimeAndDate(tNewTime);
//update the stored values
oPC = GetFirstPC();
while(GetIsObjectValid(oPC))
{
struct time tTest = GetLocalTime(oPC, "TimeAhead");
tTest = TimeSubtract(tTest, tTimeAhead);
SetLocalTime(oPC, "TimeAhead", tTest);
oPC = GetNextPC();
}
}
void AdvanceTimeForPlayer(object oPC, float fSeconds)
{
struct time tTime = GetLocalTime(oPC, "TimeAhead");
tTime.nSecond += FloatToInt(fSeconds);
SetLocalTime(oPC, "TimeAhead", tTime);
DelayCommand(0.01, RecalculateTime());
}
void AssembleTokens(struct time tTime)
{
tTime = TimeCheck(tTime);
//setup time tokens
//82001 part of day
//82002 date
//82003 month
//82004 year
//82005 hour
//82006 minutes
//82007 seconds
//82008 24 hour clock
//82009 timer
//this assumes default time settings
//Dawn, 06:00
//Dusk, 18:00
if(tTime.nHour == 6)
SetCustomToken(82001, "dawn");
else if(tTime.nHour == 18)
SetCustomToken(82001, "dusk");
else if(tTime.nHour >= 19 || tTime.nHour <= 5)
SetCustomToken(82001, "night");
else if(tTime.nHour >= 7 && tTime.nHour < 13)
SetCustomToken(82001, "morning");
else if(tTime.nHour >= 13 && tTime.nHour < 18)
SetCustomToken(82001, "afternoon");
string sDay = IntToString(tTime.nDay);
if(tTime.nDay == 1
//|| tTime.nDay == 11 //this is 11th
|| tTime.nDay == 21)
sDay += "st";
else if(tTime.nDay == 2
//|| tTime.nDay == 12 //this is 12th
|| tTime.nDay == 22)
sDay += "nd";
else if(tTime.nDay == 3
//|| tTime.nDay == 13 //this is 13th
|| tTime.nDay == 23)
sDay += "rd";
else
sDay += "th";
SetCustomToken(82002, sDay);
string sMonth;
switch(tTime.nMonth)
{
case 1: sMonth = "January"; break;
case 2: sMonth = "Febuary"; break;
case 3: sMonth = "March"; break;
case 4: sMonth = "April"; break;
case 5: sMonth = "May"; break;
case 6: sMonth = "June"; break;
case 7: sMonth = "July"; break;
case 8: sMonth = "August"; break;
case 9: sMonth = "September"; break;
case 10: sMonth = "October"; break;
case 11: sMonth = "November"; break;
case 12: sMonth = "December"; break;
}
SetCustomToken(82003, sMonth);
SetCustomToken(82004, IntToString(tTime.nYear));
SetCustomToken(82005, IntToString(tTime.nHour));
SetCustomToken(82006, IntToString(tTime.nMinute));
SetCustomToken(82007, IntToString(tTime.nSecond));
SetCustomToken(82008, IntToString(tTime.nHour)+":"+IntToString(tTime.nMinute));
string sTimer;
if(!tTime.nYear)
{
if(tTime.nYear > 1)
sTimer += IntToString(tTime.nYear)+" years";
else
sTimer += IntToString(tTime.nYear)+" year";
}
if(!tTime.nMonth)
{
if(sTimer != "")
sTimer += ", ";
if(tTime.nMonth > 1)
sTimer += IntToString(tTime.nMonth)+" months";
else
sTimer += IntToString(tTime.nMonth)+" month";
}
if(!tTime.nDay)
{
if(sTimer != "")
sTimer += ", ";
if(tTime.nDay > 1)
sTimer += IntToString(tTime.nDay)+" days";
else
sTimer += IntToString(tTime.nMonth)+" day";
}
if(!tTime.nHour)
{
if(sTimer != "")
sTimer += ", ";
if(tTime.nHour > 1)
sTimer += IntToString(tTime.nHour)+" hours";
else
sTimer += IntToString(tTime.nMonth)+" hour";
}
if(!tTime.nMinute)
{
if(sTimer != "")
sTimer += ", ";
if(tTime.nMinute > 1)
sTimer += IntToString(tTime.nMinute)+" minutes";
else
sTimer += IntToString(tTime.nMonth)+" minute";
}
SetCustomToken(82009, sTimer);
}