logo logo

 Back to main page

The NWNX Community Forum

 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 
Real World Time
Goto page 1, 2, 3, 4, 5  Next
 
Post new topic   Reply to topic    nwnx.org Forum Index -> Database related
View previous topic :: View next topic  
Author Message
Zunath



Joined: 06 Jul 2006
Posts: 183

PostPosted: Thu Jun 07, 2007 1:49    Post subject: Real World Time Reply with quote

Is it possible to get the real world time and base things within NWN off of it? Through the use of an external program of some such?

I'd like to be able to spawn certain monsters depending on what time it might be or what day of the week it is.

Anyone have any idea on how to accomplish this?
Back to top
View user's profile Send private message
FunkySwerve



Joined: 02 Jun 2005
Posts: 377

PostPosted: Thu Jun 07, 2007 8:34    Post subject: Reply with quote

In mod heartbeat:
Code:
void main () {
    int nUptime = GetLocalInt(OBJECT_SELF, "uptime");

    SQLExecDirect("SELECT UNIX_TIMESTAMP() - " + IntToString(GetLocalInt(OBJECT_SELF, "boottime")));
    if (SQLFetch() == SQL_SUCCESS) {
        nUptime = StringToInt(SQLGetData(1));
        SetLocalInt(OBJECT_SELF, "uptime", nUptime);
    }
}


"boottime" is set onmodload:
Code:
    // load boot time into the boottime variable
    SQLExecDirect("SELECT UNIX_TIMESTAMP()");
    if (SQLFetch() == SQL_SUCCESS)
        SetLocalInt(GetModule(), "boottime", StringToInt(SQLGetData(1)));
    SetLocalInt(GetModule(), "uptime", 0);


This link should help:
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html

HTH,
Funky
Back to top
View user's profile Send private message
nosfe



Joined: 25 Apr 2007
Posts: 22

PostPosted: Thu Jun 07, 2007 14:25    Post subject: Reply with quote

mhh,

I am not convinced to make a select in the heartbeat, every 6 seconds that made a little much;

especially if you use a trigger which suits him to make Select and to see what time it is really then lance or not the spawn;

very more light
Back to top
View user's profile Send private message
TroveLord



Joined: 22 Nov 2006
Posts: 136
Location: Italy

PostPosted: Thu Jun 07, 2007 16:13    Post subject: Reply with quote

Assuming that you use a database can't you it for the purpose?

Here's what you need
Code:

SELECT CURRENT_TIME
SELECT CURRENT_DATE
SELECT CURRENT_TIMESTAMP
Back to top
View user's profile Send private message
Papillon
x-man


Joined: 28 Dec 2004
Posts: 1060
Location: Germany

PostPosted: Thu Jun 07, 2007 16:19    Post subject: Reply with quote

There is a NWNX Clock plugin by kungfoowiz which gets the date as well. It will have to be updated for the upcoming NWNX4 1.08, though (read: it will only work up to NWNX 1.07).

http://nwnx.org/index.php?id=65
_________________
Papillon
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Zunath



Joined: 06 Jul 2006
Posts: 183

PostPosted: Thu Jun 07, 2007 20:13    Post subject: Reply with quote

Thanks guys, I use NWNX2 for NWN1 though so some of your suggestions I won't be able to use.

Trovelord, that does seem pretty easy to do. Where in the script would I place those constants? Would I use the SQLExecDirect function?

Sorry, I've only gotten used to using the Get and Set PersistentObjects.

Funky, thanks for the suggestion but I think a heartbeat script will be a bit too much for the PW I am making.

Thanks again all!

EDIT: Also, I am using SQLite for my database. I couldn't figure out regular MySQL Smile
Back to top
View user's profile Send private message
TroveLord



Joined: 22 Nov 2006
Posts: 136
Location: Italy

PostPosted: Thu Jun 07, 2007 22:33    Post subject: Reply with quote

Zunath wrote:
that does seem pretty easy to do. Where in the script would I place those constants?

Wherever you need, you might want to check the local time as if statement before creating a monster.

Zunath wrote:
Would I use the SQLExecDirect function?

Yes like this

Code:
string GetSQLTime()
{
    string sSQL = "SELECT CURRENT_TIME";
    SQLExecDirect(sSQL);
    if(SQLFetch() == SQL_SUCCESS)
    {
        return SQLGetData(1);
    }
    else
    {
        return "Database error";
    }
}

string GetSQLDate()
{
    string sSQL = "SELECT CURRENT_DATE";
    SQLExecDirect(sSQL);
    if(SQLFetch() == SQL_SUCCESS)
    {
        return SQLGetData(1);
    }
    else
    {
        return "Database error";
    }
}

string GetSQLTimeStamp()
{
    string sSQL = "SELECT CURRENT_TIMESTAMP";
    SQLExecDirect(sSQL);
    if(SQLFetch() == SQL_SUCCESS)
    {
        return SQLGetData(1);
    }
    else
    {
        return "Database error";
    }
}
Back to top
View user's profile Send private message
Zunath



Joined: 06 Jul 2006
Posts: 183

PostPosted: Fri Jun 08, 2007 4:50    Post subject: Reply with quote

I included what you wrote into another file. It looks like this:

Code:
 #include "aps_include"

// Gets the current REAL WORLD time, uses NWNX2
string GetSQLTime();
string GetSQLTime()
{
    string sSQL = "SELECT CURRENT_TIME";
    SQLExecDirect(sSQL);
    if(SQLFetch() == SQL_SUCCESS)
    {
        return SQLGetData(1);
    }
    else
    {
        return "Database error";
    }
}

// Gets the current REAL WORLD date, uses NWNX2
string GetSQLDate();
string GetSQLDate()
{
    string sSQL = "SELECT CURRENT_DATE";
    SQLExecDirect(sSQL);
    if(SQLFetch() == SQL_SUCCESS)
    {
        return SQLGetData(1);
    }
    else
    {
        return "Database error";
    }
}

// Gets the current REAL WORLD time stamp, uses NWNX2
string GetSQLTimeStamp();
string GetSQLTimeStamp()
{
    string sSQL = "SELECT CURRENT_TIMESTAMP";
    SQLExecDirect(sSQL);
    if(SQLFetch() == SQL_SUCCESS)
    {
        return SQLGetData(1);
    }
    else
    {
        return "Database error";
    }
}

//void main(){}



I placed this test script on the OnUsed of a placeable to test everything.

Code:


#include "aps_include"
#include "rwt_include"

void main()
{
    object oSelf = OBJECT_SELF;
    object oPC = GetLastUsedBy();
    string sTime = GetSQLTime();
    string sDate = GetSQLDate();
    string sTimeStamp = GetSQLTimeStamp();

    SendMessageToPC(oPC, sTime);
    SendMessageToPC(oPC, sDate);
    SendMessageToPC(oPC, sTimeStamp);

}



It returned "database error" in game. What did I do wrong? Is this not compatible with a SQLite database?

Thanks again, sorry to cause problems.[/code]
Back to top
View user's profile Send private message
FunkySwerve



Joined: 02 Jun 2005
Posts: 377

PostPosted: Fri Jun 08, 2007 5:27    Post subject: Reply with quote

Zunath wrote:
Thanks guys, I use NWNX2 for NWN1 though so some of your suggestions I won't be able to use.

Funky, thanks for the suggestion but I think a heartbeat script will be a bit too much for the PW I am making.


Lol, didn't expect to find myself advocating this position, but the hearbeat is probably the most efficient solution here. I'm a nut when it comes to script efficiency, just take a look at the bioboards if you doubt it. Razz I have used and abused the profiler to no end. And, I can assure you, the impact of that heatbeat on your mod will be about null. Not quite, but so close to it as to be insubstantial. HG is a huge mod, 110M at last count, with about 470 areas chock full of content, and runs smoothly, with a more substantial heartbeat than that. And please, don't mistake me for a heartbeat apologist, it's the only one in my mod (other than the ones on a few creatures) becuase I use psuedos for everything else. Psuedos take roughly 5x as long to run, so I only use them for scripts that run less than 20% of the time - but that's nothing in my mod. Just food for thought. Oh, a SELECT every 6 seconds is nothing in terms of machine time.

Here's our full mod heartbeat, which, again, has almost no overhead and no noticeable impact on the mod:

Code:
#include "aps_include"

object GetMessenger()
{
    return GetLocalObject(GetModule(), "FKY_CHT_MESSENGER");
}
void SendChatLogMessage(object oRecipient, string sMessage, object oSender = OBJECT_INVALID, int nChannel = 4)
{
    if (!GetIsObjectValid(oSender)) return;
    if (FindSubString(sMessage, "¬")!=-1) return;
    if (nChannel == 4 && !GetIsObjectValid(oRecipient)) return;
    SetLocalString(oSender, "NWNX!CHAT!SPEAK", ObjectToString(oSender)+"¬"+ObjectToString(oRecipient)+"¬"+IntToString(nChannel)+"¬"+sMessage);
}
object FindAddressee(string sPlayername)
{
    string sCheck;
    object oPC = GetFirstPC();
    while (GetIsObjectValid(oPC))
    {
        sCheck = GetPCPlayerName(oPC);
        if (sCheck == sPlayername) return oPC;
        oPC = GetNextPC();
    }
    return OBJECT_INVALID;
}

void main () {
    int nUptime = GetLocalInt(OBJECT_SELF, "uptime");

    SQLExecDirect("SELECT UNIX_TIMESTAMP() - " + IntToString(GetLocalInt(OBJECT_SELF, "boottime")));
    if (SQLFetch() == SQL_SUCCESS) {
        nUptime = StringToInt(SQLGetData(1));
        SetLocalInt(OBJECT_SELF, "uptime", nUptime);
    }

    int nLastMinute = GetLocalInt(OBJECT_SELF, "lastminute");

    if (nUptime >= nLastMinute + 60) {
        string sServer = GetLocalString(OBJECT_SELF, "ServerNumber");
        string sSQL = "SELECT name, sender, message FROM messages WHERE server = '" + sServer + "'";
        string sMessage, sName, sLocalString;
        object oAddressee, oPC;
        string sSender;
        int nCount = 1;
        int nX;
        object oMod = GetModule();

        SQLExecDirect(sSQL);
        while(SQLFetch() != SQL_ERROR)
        {
            sMessage = SQLDecodeSpecialChars(SQLGetData(3));
            sName = SQLDecodeSpecialChars(SQLGetData(1));
            sSender = SQLDecodeSpecialChars(SQLGetData(2));
            PrintString(sMessage+sName+sSender);
            if (sName == "None") AssignCommand(oMod, SpeakString(sMessage, TALKVOLUME_SHOUT));
            else
            {
                oAddressee = FindAddressee(sName);
                if (GetIsObjectValid(oAddressee))
                {
                    FloatingTextStringOnCreature("<c þ >Interserver message received from " + sSender + "!</c>", oAddressee, FALSE);
                    //SendMessageToPC(oAddressee, "<c þ >" + sMessage + "</c>");
                    SendChatLogMessage(oAddressee, "<c þ >" + sMessage + "</c>", GetMessenger());
                }
            }
        }
        sSQL = "DELETE FROM messages WHERE server = '" + sServer + "'";
        SQLExecDirect(sSQL);

        SetLocalInt(OBJECT_SELF, "lastminute", nUptime);
    }
}


As you can see there's a much heftier select than the one I suggested. And with accurate time you can do all kinds of cool timestamping. We use it for temporary casterlevel increases, for example.


Funky
Back to top
View user's profile Send private message
FunkySwerve



Joined: 02 Jun 2005
Posts: 377

PostPosted: Fri Jun 08, 2007 8:49    Post subject: Reply with quote

Zunath wrote:

It returned "database error" in game. What did I do wrong? Is this not compatible with a SQLite database?

Thanks again, sorry to cause problems.


Yes, as far as I know those are MySQL functions only. If you'd like help setting it up just let us know.
Funky
Back to top
View user's profile Send private message
TroveLord



Joined: 22 Nov 2006
Posts: 136
Location: Italy

PostPosted: Fri Jun 08, 2007 9:33    Post subject: Reply with quote

FunkySwerve wrote:
Zunath wrote:

It returned "database error" in game. What did I do wrong? Is this not compatible with a SQLite database?

Thanks again, sorry to cause problems.


Yes, as far as I know those are MySQL functions only. If you'd like help setting it up just let us know.
Funky

I've actually tested them with SQLite and they work. What won't work is SELECT VERSION() because SQLite has its own function for that: SELECT sqlite_version()
Back to top
View user's profile Send private message
Gryphyn



Joined: 20 Jan 2005
Posts: 431

PostPosted: Fri Jun 08, 2007 10:53    Post subject: Reply with quote

How would these work?

Strings
Code:
   if (function == wxT("REALTIME"))
   {
      wxDateTime CallTime = wxDateTime::Now();
      wxTimeSpan SpanTime = CallTime.Subtract(LoadTime);
      if (timerName == wxT("DATE"))
      {
         wxLogMessage(wxT("o Date is %s"), CallTime.FormatISODate());
         sprintf_s(returnBuffer, MAX_BUFFER, "%s", CallTime.FormatISODate());
      }
      if (timerName == wxT("TIME"))
      {
         wxLogMessage(wxT("o Time is %s"), CallTime.FormatISODate());
         sprintf_s(returnBuffer, MAX_BUFFER, "%s", CallTime.FormatISOTime());
      }
      if (timerName == wxT("UPTIME"))
      {
         wxLogMessage(wxT("o Uptime is %s"), SpanTime.Format());
         sprintf_s(returnBuffer, MAX_BUFFER, "%s", SpanTime.Format());
      }
      else
      {
         wxLogMessage(wxT("* Unknown RealTime option '%s' called"));
         return NULL;
      }
   }

ISODate = YYYY-MM-DD
ISOTime = HH:MM:SS

Integers
Code:
   if (function == wxT("REALTIME"))
   {
      wxDateTime CallTime = wxDateTime::Now();
      wxTimeSpan SpanTime = CallTime.Subtract(LoadTime);

      if (timerName == wxT("YEAR")) return CallTime.GetYear();
      else if (timerName == wxT("MONTH")) return CallTime.GetMonth();
      else if (timerName == wxT("MON")) return CallTime.GetMonth();
      else if (timerName == wxT("DAY")) return CallTime.GetDay();
      else if (timerName == wxT("HOUR")) return CallTime.GetHour();
      else if (timerName == wxT("HR")) return CallTime.GetHour();
      else if (timerName == wxT("MINUTE")) return CallTime.GetMinute();
      else if (timerName == wxT("MIN")) return CallTime.GetMinute();
      else if (timerName == wxT("MILLI")) return CallTime.GetMillisecond();
      else if (timerName == wxT("MILLISECOND")) return CallTime.GetMillisecond();
      else if (timerName == wxT("UPDAYS")) return SpanTime.GetDays();
      else if (timerName == wxT("UPHOURS")) return SpanTime.GetHours();
      else if (timerName == wxT("UPMINUTES")) return SpanTime.GetMinutes();
      else
      {
         wxLogMessage(wxT("* Unknown RealTime option '%s' called"));
      }
   }

OK, there's a bit more that what's shown, and some liberties taken (an assumption that when the plug-in is loaded is when the server starts)

Your post got me thinking about extending functionality of the Timer plug-in. So far this stuff is working with the 1.08 build.

Want more?

Cheers
Gryphyn
Back to top
View user's profile Send private message
Papillon
x-man


Joined: 28 Dec 2004
Posts: 1060
Location: Germany

PostPosted: Fri Jun 08, 2007 12:27    Post subject: Reply with quote

Gryphyn, this seems to be a fine addition to the time plugin. Do you want to add your code to the "offical" version ?
_________________
Papillon
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Gryphyn



Joined: 20 Jan 2005
Posts: 431

PostPosted: Fri Jun 08, 2007 13:02    Post subject: Reply with quote

Papillon wrote:
Gryphyn, this seems to be a fine addition to the time plugin. Do you want to add your code to the "offical" version ?

It was a 10 min 'knock-up', but works fine.
Sure, if you want it for the real - Timer plug-in - the source is yours.
I'll send an e-mail.
I'm not sure what other functions may be requested (hence the post) but they are dead simple to add in.

PS. In the aether...
I've also done some re-naming but the essence is there...

Cheers
Gryphyn
Back to top
View user's profile Send private message
Zunath



Joined: 06 Jul 2006
Posts: 183

PostPosted: Tue Jul 03, 2007 1:42    Post subject: Reply with quote

I've decided it would be better to go with MySQL instead of SQLite since it seems there's a lot more functionality with MySQL.

However, I'm not too sure how to set it up. I've downloaded the SQL server 5.0 and the GUI tools, but as far as actually getting it functional I'm at a loss. And the OBDC documentation didn't help much either. Sad

Thanks guys, can't wait to use real world time. Smile
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    nwnx.org Forum Index -> Database related All times are GMT + 2 Hours
Goto page 1, 2, 3, 4, 5  Next
Page 1 of 5

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group