View previous topic :: View next topic |
Author |
Message |
David
Joined: 30 Mar 2005 Posts: 12 Location: Netherlands
|
Posted: Wed Mar 30, 2005 12:10 Post subject: Persistent Journal Entries |
|
|
Hey all,
I have been using NWNX/ASP (2) for awhile now and I can get along with most of the scripts regarding it. But unfortunately I'm getting stuck on creating a Persistent Journal Entries. I have looked through the NWVault and didn't find anything suitable for me...
I'd like a script that saves the PC's journals in the database and returns them once the PC enters the mod again. Is that possible, I'm sure it is! I hope one can help me out. Thanks in advance,
David |
|
Back to top |
|
|
TulipVorlax
Joined: 14 Feb 2005 Posts: 14 Location: Montreal, Quebec, Canada, third rock from the sun
|
Posted: Wed Mar 30, 2005 18:10 Post subject: |
|
|
Yes it is possible.
I'll write one myself soon.
Basically, it would require that in the OnEnter a fonction "scan" the player table. Yes, i wil be using a table per player or per character in fact. Still, one table to store data about all player character would also be used...
See ya. _________________ My comps.
My little forum.
|
|
Back to top |
|
|
David
Joined: 30 Mar 2005 Posts: 12 Location: Netherlands
|
Posted: Wed Mar 30, 2005 22:21 Post subject: |
|
|
Nice. If you could keep me updated about your work, please. |
|
Back to top |
|
|
Mikel of Avalon
Joined: 29 Dec 2004 Posts: 72 Location: Germany
|
|
Back to top |
|
|
TulipVorlax
Joined: 14 Feb 2005 Posts: 14 Location: Montreal, Quebec, Canada, third rock from the sun
|
Posted: Thu Mar 31, 2005 1:03 Post subject: |
|
|
It use only one table for all characters of all players.
Not quite what i want.
And why wouldn't i do things myself. I'm a programmer. Although not officially. But i also want to reprogram the entire APS bescause it do not coresspond to what i need.
I need a way to clean up the base from inside the game using DROP TABLE when caracters BIC files aren't flaggued to say "that is not a new character".
But i'm currently on a team working on another PW (in french) and my APS (should i drop de "a" ?) will not be complete before 2 month or so.
If by that time if someone is still interested, i might consider give it to him but i hope he will be able to understand it by himself because i'll have so much to do at that time...
See ya. _________________ My comps.
My little forum.
|
|
Back to top |
|
|
David
Joined: 30 Mar 2005 Posts: 12 Location: Netherlands
|
Posted: Thu Mar 31, 2005 20:15 Post subject: |
|
|
I have succesfully implented that script. There is only one problem though... The script above does store journal entries etc in the database, but will not save the journal list a PC has. So the list of unfinished quests will be gone after the server restarted.
Is there a way to save them and once a PC joined after a server-restart give them back? |
|
Back to top |
|
|
Mikel of Avalon
Joined: 29 Dec 2004 Posts: 72 Location: Germany
|
Posted: Thu Mar 31, 2005 20:48 Post subject: |
|
|
Ok - its importend to give or update all the entries through the new function InsertUpdateJournalEntry and not via the journal entry inside a dialog. Make ist per script so insert, update or delete. To restore the journal entries for the player at server restart call the function RestoreJournalEntries only once. I wrote a new function to check a given entry to prevent empty messages in the server status window.
Code: |
int CheckJournalEntry(object oObject, string sJournalEntry="")
{
string sSQL;
string sPCTag;
string sPCName;
if (GetIsPC(oObject))
{
sPCName = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sPCTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPCName = "~";
sPCTag = GetTag(oObject);
}
sSQL = "SELECT COUNT(*) FROM tJournal "
+ " WHERE tag='" + sPCTag + "' "
+ " AND player='" + sPCName + "' ";
if (sJournalEntry !="") sSQL += " AND JournalEntry='" + sJournalEntry + "' ";
SQLExecDirect(sSQL);
if(SQLFirstRow()==SQL_SUCCESS)
return StringToInt(SQLGetData(1));
else
return 0;
}
|
With this you can check the journals and only restore them when a player has any entries or a specific entry. |
|
Back to top |
|
|
David
Joined: 30 Mar 2005 Posts: 12 Location: Netherlands
|
Posted: Fri Apr 01, 2005 17:56 Post subject: |
|
|
Thanks a lot! One question though, where does that script go? |
|
Back to top |
|
|
Mikel of Avalon
Joined: 29 Dec 2004 Posts: 72 Location: Germany
|
Posted: Sat Apr 02, 2005 0:36 Post subject: |
|
|
Simply add it at the end of your aps_include where the other journal scripts are present (i have done so) |
|
Back to top |
|
|
David
Joined: 30 Mar 2005 Posts: 12 Location: Netherlands
|
Posted: Wed Apr 06, 2005 21:07 Post subject: |
|
|
Ok, I've seen to stumble against a problem. My conversations are journal-entry related. So when PC A has accepted a quest, PC B (whoms in the same party as PC A) will get the journal entry/update as well.
The problem is that my conversations and quests rewards (items) can only be given once to each PC, that is the PC who ends the ques for basicly his whole party.
My questions is if it is possible to make this system work for individual PC's, so not every party members get the quests entry/update, but only the one who accepted it etc.
My aps_include looks like this:
Code: |
// Name : Avlis Persistence System include
// Purpose : Various APS/NWNX2 related functions
// Authors : Ingmar Stieger, Adam Colon, Josh Simon
// Modified : December 21, 2003
// This file is licensed under the terms of the
// GNU GENERAL PUBLIC LICENSE (GPL) Version 2
/************************************/
/* Return codes */
/************************************/
int SQL_ERROR = 0;
int SQL_SUCCESS = 1;
/************************************/
/* Function prototypes */
/************************************/
// Setup placeholders for ODBC requests and responses
void SQLInit();
// Execute statement in sSQL
void SQLExecDirect(string sSQL);
// Position cursor on next row of the resultset
// Call this before using SQLGetData().
// returns: SQL_SUCCESS if there is a row
// SQL_ERROR if there are no more rows
int SQLFetch();
// * deprecated. Use SQLFetch instead.
// Position cursor on first row of the resultset and name it sResultSetName
// Call this before using SQLNextRow() and SQLGetData().
// returns: SQL_SUCCESS if result set is not empty
// SQL_ERROR is result set is empty
int SQLFirstRow();
// * deprecated. Use SQLFetch instead.
// Position cursor on next row of the result set sResultSetName
// returns: SQL_SUCCESS if cursor could be advanced to next row
// SQL_ERROR if there was no next row
int SQLNextRow();
// Return value of column iCol in the current row of result set sResultSetName
string SQLGetData(int iCol);
// Return a string value when given a location
string APSLocationToString(location lLocation);
// Return a location value when given the string form of the location
location APSStringToLocation(string sLocation);
// Return a string value when given a vector
string APSVectorToString(vector vVector);
// Return a vector value when given the string form of the vector
vector APSStringToVector(string sVector);
// Set oObject's persistent string variable sVarName to sValue
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
void SetPersistentString(object oObject, string sVarName, string sValue, int iExpiration =
0, string sTable = "pwdata");
// Set oObject's persistent integer variable sVarName to iValue
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
void SetPersistentInt(object oObject, string sVarName, int iValue, int iExpiration =
0, string sTable = "pwdata");
// Set oObject's persistent float variable sVarName to fValue
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
void SetPersistentFloat(object oObject, string sVarName, float fValue, int iExpiration =
0, string sTable = "pwdata");
// Set oObject's persistent location variable sVarName to lLocation
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
// This function converts location to a string for storage in the database.
void SetPersistentLocation(object oObject, string sVarName, location lLocation, int iExpiration =
0, string sTable = "pwdata");
// Set oObject's persistent vector variable sVarName to vVector
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
// This function converts vector to a string for storage in the database.
void SetPersistentVector(object oObject, string sVarName, vector vVector, int iExpiration =
0, string sTable = "pwdata");
// Get oObject's persistent string variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: ""
string GetPersistentString(object oObject, string sVarName, string sTable = "pwdata");
// Get oObject's persistent integer variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: 0
int GetPersistentInt(object oObject, string sVarName, string sTable = "pwdata");
// Get oObject's persistent float variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: 0
float GetPersistentFloat(object oObject, string sVarName, string sTable = "pwdata");
// Get oObject's persistent location variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: 0
location GetPersistentLocation(object oObject, string sVarname, string sTable = "pwdata");
// Get oObject's persistent vector variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: 0
vector GetPersistentVector(object oObject, string sVarName, string sTable = "pwdata");
// Delete persistent variable sVarName stored on oObject
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
void DeletePersistentVariable(object oObject, string sVarName, string sTable = "pwdata");
// (private function) Replace special character ' with ~
string SQLEncodeSpecialChars(string sString);
// (private function)Replace special character ' with ~
string SQLDecodeSpecialChars(string sString);
/************************************/
/* Implementation */
/************************************/
// Functions for initializing APS and working with result sets
void SQLInit()
{
int i;
// Placeholder for ODBC persistence
string sMemory;
for (i = 0; i < 8; i++) // reserve 8*128 bytes
sMemory +=
"................................................................................................................................";
SetLocalString(GetModule(), "NWNX!ODBC!SPACER", sMemory);
}
void SQLExecDirect(string sSQL)
{
SetLocalString(GetModule(), "NWNX!ODBC!EXEC", sSQL);
}
int SQLFetch()
{
string sRow;
object oModule = GetModule();
SetLocalString(oModule, "NWNX!ODBC!FETCH", GetLocalString(oModule, "NWNX!ODBC!SPACER"));
sRow = GetLocalString(oModule, "NWNX!ODBC!FETCH");
if (GetStringLength(sRow) > 0)
{
SetLocalString(oModule, "NWNX_ODBC_CurrentRow", sRow);
return SQL_SUCCESS;
}
else
{
SetLocalString(oModule, "NWNX_ODBC_CurrentRow", "");
return SQL_ERROR;
}
}
// deprecated. use SQLFetch().
int SQLFirstRow()
{
return SQLFetch();
}
// deprecated. use SQLFetch().
int SQLNextRow()
{
return SQLFetch();
}
string SQLGetData(int iCol)
{
int iPos;
string sResultSet = GetLocalString(GetModule(), "NWNX_ODBC_CurrentRow");
// find column in current row
int iCount = 0;
string sColValue = "";
iPos = FindSubString(sResultSet, "");
if ((iPos == -1) && (iCol == 1))
{
// only one column, return value immediately
sColValue = sResultSet;
}
else if (iPos == -1)
{
// only one column but requested column > 1
sColValue = "";
}
else
{
// loop through columns until found
while (iCount != iCol)
{
iCount++;
if (iCount == iCol)
sColValue = GetStringLeft(sResultSet, iPos);
else
{
sResultSet = GetStringRight(sResultSet, GetStringLength(sResultSet) - iPos - 1);
iPos = FindSubString(sResultSet, "");
}
// special case: last column in row
if (iPos == -1)
iPos = GetStringLength(sResultSet);
}
}
return sColValue;
}
// These functions deal with various data types. Ultimately, all information
// must be stored in the database as strings, and converted back to the proper
// form when retrieved.
string APSVectorToString(vector vVector)
{
return "#POSITION_X#" + FloatToString(vVector.x) + "#POSITION_Y#" + FloatToString(vVector.y) +
"#POSITION_Z#" + FloatToString(vVector.z) + "#END#";
}
vector APSStringToVector(string sVector)
{
float fX, fY, fZ;
int iPos, iCount;
int iLen = GetStringLength(sVector);
if (iLen > 0)
{
iPos = FindSubString(sVector, "#POSITION_X#") + 12;
iCount = FindSubString(GetSubString(sVector, iPos, iLen - iPos), "#");
fX = StringToFloat(GetSubString(sVector, iPos, iCount));
iPos = FindSubString(sVector, "#POSITION_Y#") + 12;
iCount = FindSubString(GetSubString(sVector, iPos, iLen - iPos), "#");
fY = StringToFloat(GetSubString(sVector, iPos, iCount));
iPos = FindSubString(sVector, "#POSITION_Z#") + 12;
iCount = FindSubString(GetSubString(sVector, iPos, iLen - iPos), "#");
fZ = StringToFloat(GetSubString(sVector, iPos, iCount));
}
return Vector(fX, fY, fZ);
}
string APSLocationToString(location lLocation)
{
object oArea = GetAreaFromLocation(lLocation);
vector vPosition = GetPositionFromLocation(lLocation);
float fOrientation = GetFacingFromLocation(lLocation);
string sReturnValue;
if (GetIsObjectValid(oArea))
sReturnValue =
"#AREA#" + GetTag(oArea) + "#POSITION_X#" + FloatToString(vPosition.x) +
"#POSITION_Y#" + FloatToString(vPosition.y) + "#POSITION_Z#" +
FloatToString(vPosition.z) + "#ORIENTATION#" + FloatToString(fOrientation) + "#END#";
return sReturnValue;
}
location APSStringToLocation(string sLocation)
{
location lReturnValue;
object oArea;
vector vPosition;
float fOrientation, fX, fY, fZ;
int iPos, iCount;
int iLen = GetStringLength(sLocation);
if (iLen > 0)
{
iPos = FindSubString(sLocation, "#AREA#") + 6;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
oArea = GetObjectByTag(GetSubString(sLocation, iPos, iCount));
iPos = FindSubString(sLocation, "#POSITION_X#") + 12;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fX = StringToFloat(GetSubString(sLocation, iPos, iCount));
iPos = FindSubString(sLocation, "#POSITION_Y#") + 12;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fY = StringToFloat(GetSubString(sLocation, iPos, iCount));
iPos = FindSubString(sLocation, "#POSITION_Z#") + 12;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fZ = StringToFloat(GetSubString(sLocation, iPos, iCount));
vPosition = Vector(fX, fY, fZ);
iPos = FindSubString(sLocation, "#ORIENTATION#") + 13;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fOrientation = StringToFloat(GetSubString(sLocation, iPos, iCount));
lReturnValue = Location(oArea, vPosition, fOrientation);
}
return lReturnValue;
}
// These functions are responsible for transporting the various data types back
// and forth to the database.
void SetPersistentString(object oObject, string sVarName, string sValue, int iExpiration =
0, string sTable = "pwdata")
{
string sPlayer;
string sTag;
if (GetIsPC(oObject))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPlayer = "~";
sTag = GetTag(oObject);
}
sVarName = SQLEncodeSpecialChars(sVarName);
sValue = SQLEncodeSpecialChars(sValue);
string sSQL = "SELECT player FROM " + sTable + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SQLExecDirect(sSQL);
if (SQLFirstRow() == SQL_SUCCESS)
{
// row exists
sSQL = "UPDATE " + sTable + " SET val='" + sValue +
"',expire=" + IntToString(iExpiration) + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SQLExecDirect(sSQL);
}
else
{
// row doesn't exist
sSQL = "INSERT INTO " + sTable + " (player,tag,name,val,expire) VALUES" +
"('" + sPlayer + "','" + sTag + "','" + sVarName + "','" +
sValue + "'," + IntToString(iExpiration) + ")";
SQLExecDirect(sSQL);
}
}
string GetPersistentString(object oObject, string sVarName, string sTable = "pwdata")
{
string sPlayer;
string sTag;
if (GetIsPC(oObject))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPlayer = "~";
sTag = GetTag(oObject);
}
sVarName = SQLEncodeSpecialChars(sVarName);
string sSQL = "SELECT val FROM " + sTable + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SQLExecDirect(sSQL);
if (SQLFirstRow() == SQL_SUCCESS)
return SQLDecodeSpecialChars(SQLGetData(1));
else
{
return "";
// If you want to convert your existing persistent data to APS, this
// would be the place to do it. The requested variable was not found
// in the database, you should
// 1) query it's value using your existing persistence functions
// 2) save the value to the database using SetPersistentString()
// 3) return the string value here.
}
}
void SetPersistentInt(object oObject, string sVarName, int iValue, int iExpiration =
0, string sTable = "pwdata")
{
SetPersistentString(oObject, sVarName, IntToString(iValue), iExpiration, sTable);
}
int GetPersistentInt(object oObject, string sVarName, string sTable = "pwdata")
{
return StringToInt(GetPersistentString(oObject, sVarName, sTable));
}
void SetPersistentFloat(object oObject, string sVarName, float fValue, int iExpiration =
0, string sTable = "pwdata")
{
SetPersistentString(oObject, sVarName, FloatToString(fValue), iExpiration, sTable);
}
float GetPersistentFloat(object oObject, string sVarName, string sTable = "pwdata")
{
return StringToFloat(GetPersistentString(oObject, sVarName, sTable));
}
void SetPersistentLocation(object oObject, string sVarName, location lLocation, int iExpiration =
0, string sTable = "pwdata")
{
SetPersistentString(oObject, sVarName, APSLocationToString(lLocation), iExpiration, sTable);
}
location GetPersistentLocation(object oObject, string sVarName, string sTable = "pwdata")
{
return APSStringToLocation(GetPersistentString(oObject, sVarName, sTable));
}
void SetPersistentVector(object oObject, string sVarName, vector vVector, int iExpiration =
0, string sTable = "pwdata")
{
SetPersistentString(oObject, sVarName, APSVectorToString(vVector), iExpiration, sTable);
}
vector GetPersistentVector(object oObject, string sVarName, string sTable = "pwdata")
{
return APSStringToVector(GetPersistentString(oObject, sVarName, sTable));
}
void DeletePersistentVariable(object oObject, string sVarName, string sTable = "pwdata")
{
string sPlayer;
string sTag;
if (GetIsPC(oObject))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPlayer = "~";
sTag = GetTag(oObject);
}
sVarName = SQLEncodeSpecialChars(sVarName);
string sSQL = "DELETE FROM " + sTable + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SQLExecDirect(sSQL);
}
// Problems can arise with SQL commands if variables or values have single quotes
// in their names. These functions are a replace these quote with the tilde character
string SQLEncodeSpecialChars(string sString)
{
if (FindSubString(sString, "'") == -1) // not found
return sString;
int i;
string sReturn = "";
string sChar;
// Loop over every character and replace special characters
for (i = 0; i < GetStringLength(sString); i++)
{
sChar = GetSubString(sString, i, 1);
if (sChar == "'")
sReturn += "~";
else
sReturn += sChar;
}
return sReturn;
}
string SQLDecodeSpecialChars(string sString)
{
if (FindSubString(sString, "~") == -1) // not found
return sString;
int i;
string sReturn = "";
string sChar;
// Loop over every character and replace special characters
for (i = 0; i < GetStringLength(sString); i++)
{
sChar = GetSubString(sString, i, 1);
if (sChar == "~")
sReturn += "'";
else
sReturn += sChar;
}
return sReturn;
}
int CheckJournalEntry(object oObject, string sJournalEntry="")
{
string sSQL;
string sPCTag;
string sPCName;
if (GetIsPC(oObject))
{
sPCName = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sPCTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPCName = "~";
sPCTag = GetTag(oObject);
}
sSQL = "SELECT COUNT(*) FROM tJournal "
+ " WHERE tag='" + sPCTag + "' "
+ " AND player='" + sPCName + "' ";
if (sJournalEntry !="") sSQL += " AND JournalEntry='" + sJournalEntry + "' ";
SQLExecDirect(sSQL);
if(SQLFirstRow()==SQL_SUCCESS)
return StringToInt(SQLGetData(1));
else
return 0;
}
|
My #include "gh_pqj_db_inc" stayed intact (I didn't touch it).
Hope someone can help me out. |
|
Back to top |
|
|
Lokey
Joined: 02 Jan 2005 Posts: 158
|
Posted: Fri Apr 08, 2005 13:58 Post subject: |
|
|
Don't see code where you give the journal entry. The BioScript function defaults to giving it to everyone in the party.
Code: | void AddJournalQuestEntry(string szPlotID, int nState, object oCreature, int bAllPartyMembers=TRUE, int bAllPlayers=FALSE, int bAllowOverrideHigher=FALSE) |
_________________ Neversummer PW NWNx powered mayhem |
|
Back to top |
|
|
David
Joined: 30 Mar 2005 Posts: 12 Location: Netherlands
|
Posted: Sun Apr 10, 2005 16:46 Post subject: |
|
|
So can I change it? And if yes, where? |
|
Back to top |
|
|
Mikel of Avalon
Joined: 29 Dec 2004 Posts: 72 Location: Germany
|
Posted: Sun Apr 10, 2005 23:59 Post subject: |
|
|
I dont see any persistent journal function in your post. Maybe the must a sumilar function in your include "gh_pqj_db_inc"...
In my modified aps_include from Lanthar are different...
Code: | // Name : Avlis Persistence System include
// Purpose : Various APS/NWNX2 related functions
// Authors : Ingmar Stieger, Adam Colon, Josh Simon
// Modified : February 16, 2003
// This file is licensed under the terms of the
// GNU GENERAL PUBLIC LICENSE (GPL) Version 2
/************************************/
/* Return codes */
/************************************/
int SQL_ERROR = 0;
int SQL_SUCCESS = 1;
int USE_DATABASE = TRUE;
/************************************/
/* Function prototypes */
/************************************/
// Setup placeholders for ODBC requests and responses
void SQLInit();
// Check to be certain database is up and available
int SQLCheckDB();
// Execute statement in sSQL
void SQLExecDirect(string sSQL);
// Position cursor on next row of the resultset
// Call this before using SQLGetData().
// returns: SQL_SUCCESS if there is a row
// SQL_ERROR if there are no more rows
int SQLFetch();
// * deprecated. Use SQLFetch instead.
// Position cursor on first row of the resultset and name it sResultSetName
// Call this before using SQLNextRow() and SQLGetData().
// returns: SQL_SUCCESS if result set is not empty
// SQL_ERROR is result set is empty
int SQLFirstRow();
// * deprecated. Use SQLFetch instead.
// Position cursor on next row of the result set sResultSetName
// returns: SQL_SUCCESS if cursor could be advanced to next row
// SQL_ERROR if there was no next row
int SQLNextRow();
// Return value of column iCol in the current row of result set sResultSetName
string SQLGetData(int iCol);
// Return a string value when given a location
string aps_LocationToString(location lLocation);
// Return a location value when given the string form of the location
location StringToLocation(string sLocation);
// Return a string value when given a vector
string aps_VectorToString(vector vVector);
// Return a vector value when given the string form of the vector
vector StringToVector(string sVector);
// Set oObject's persistent string variable sVarName to sValue
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
void SetPersistentString(object oObject, string sVarName, string sValue, int iExpiration=0, string sTable="pwdata");
// Set oObject's persistent integer variable sVarName to iValue
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
void SetPersistentInt(object oObject, string sVarName, int iValue, int iExpiration=0, string sTable="pwdata");
// Set oObject's persistent float variable sVarName to fValue
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
void SetPersistentFloat(object oObject, string sVarName, float fValue, int iExpiration=0, string sTable="pwdata");
// Set oObject's persistent location variable sVarName to lLocation
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
// This function converts location to a string for storage in the database.
void SetPersistentLocation(object oObject, string sVarName, location lLocation, int iExpiration=0, string sTable="pwdata");
// Set oObject's persistent vector variable sVarName to vVector
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
// This function converts vector to a string for storage in the database.
void SetPersistentVector(object oObject, string sVarName, vector vVector, int iExpiration=0, string sTable ="pwdata");
// Get oObject's persistent string variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: ""
string GetPersistentString(object oObject, string sVarName, string sTable="pwdata");
// Get oObject's persistent integer variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: 0
int GetPersistentInt(object oObject, string sVarName, string sTable="pwdata");
// Get oObject's persistent float variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: 0
float GetPersistentFloat(object oObject, string sVarName, string sTable="pwdata");
// Get oObject's persistent location variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: 0
location GetPersistentLocation(object oObject, string sVarname, string sTable="pwdata");
// Get oObject's persistent vector variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: 0
vector GetPersistentVector(object oObject, string sVarName, string sTable = "pwdata");
// Delete persistent variable sVarName stored on oObject
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
void DeletePersistentVariable(object oObject, string sVarName, string sTable="pwdata");
// (private function) Replace special character ' with ~
string SQLEncodeSpecialChars(string sString);
// (private function)Replace special character ' with ~
string SQLDecodeSpecialChars(string sString);
//adds a journal entry if not present. updates state if it is.
void InsertUpdateJournalEntry(object oPC, string sJournalEntry, int nState, int bAllPartyMembers=TRUE, int bAllPlayers=FALSE, int bAllowOverrideHigher=FALSE);
//restores journal entries when client enters module.
void RestoreJournalEntries(object oPC);
//deletes journal entries.
void DeleteJournalEntry(object oPC, string sJournalEntry);
//checks count of a given or all journal entries
int CheckJournalEntry(object oObject, string sJournalEntry="");
/************************************/
/* Implementation */
/************************************/
// Functions for initializing APS and working with result sets
void SQLInit()
{
if(!USE_DATABASE)
return;
SetLocalString(GetModule(), "NWNX!INIT", "1");
int i;
// Placeholder for ODBC persistence
string sMemory;
for (i = 0; i < 8; i++) // reserve 8*128 bytes
sMemory += "................................................................................................................................";
SetLocalString(GetModule(), "NWNX!ODBC!SPACER", sMemory);
}
int SQLCheckDB()
{
if(!USE_DATABASE)
return 0;
string sSQL="select count(*) pwdata";
SQLExecDirect(sSQL);
if(SQLFirstRow()==SQL_SUCCESS)
return 1;
else
return 0;
}
void SQLExecDirect(string sSQL)
{
if(!USE_DATABASE)
return;
SetLocalString(GetModule(), "NWNX!ODBC!EXEC", sSQL);
}
int SQLFetch()
{
if(!USE_DATABASE)
return SQL_ERROR;
string sRow;
object oModule = GetModule();
SetLocalString(oModule, "NWNX!ODBC!FETCH", GetLocalString(oModule, "NWNX!ODBC!SPACER"));
sRow = GetLocalString(oModule, "NWNX!ODBC!FETCH");
if (GetStringLength(sRow) > 0)
{
SetLocalString(oModule, "NWNX_ODBC_CurrentRow", sRow);
return SQL_SUCCESS;
}
else
{
SetLocalString(oModule, "NWNX_ODBC_CurrentRow", "");
return SQL_ERROR;
}
}
// deprecated. use SQLFetch().
int SQLFirstRow()
{
return SQLFetch();
}
// deprecated. use SQLFetch().
int SQLNextRow()
{
return SQLFetch();
}
string SQLGetData(int iCol)
{
if(!USE_DATABASE)
return "";
int iPos;
string sResultSet = GetLocalString(GetModule(), "NWNX_ODBC_CurrentRow");
// find column in current row
int iCount = 0;
string sColValue = "";
iPos = FindSubString(sResultSet, "¬");
if ((iPos == -1) && (iCol == 1))
{
// only one column, return value immediately
sColValue = sResultSet;
}
else if (iPos == -1)
{
// only one column but requested column > 1
sColValue = "";
}
else
{
// loop through columns until found
while (iCount != iCol)
{
iCount++;
if (iCount == iCol)
sColValue = GetStringLeft(sResultSet, iPos);
else
{
sResultSet = GetStringRight(sResultSet,GetStringLength(sResultSet) - iPos - 1);
iPos = FindSubString(sResultSet, "¬");
}
// special case: last column in row
if (iPos == -1)
iPos = GetStringLength(sResultSet);
}
}
return sColValue;
}
// These functions deal with various data types. Ultimately, all information
// must be stored in the database as strings, and converted back to the proper
// form when retrieved.
string aps_VectorToString(vector vVector)
{
return "#POSITION_X#" + FloatToString(vVector.x) + "#POSITION_Y#" + FloatToString(vVector.y) + "#POSITION_Z#" + FloatToString(vVector.z) + "#END#";
}
vector StringToVector(string sVector)
{
float fX, fY, fZ;
int iPos, iCount;
int iLen = GetStringLength(sVector);
if (iLen > 0)
{
iPos = FindSubString(sVector, "#POSITION_X#") + 12;
iCount = FindSubString(GetSubString(sVector, iPos, iLen - iPos), "#");
fX = StringToFloat(GetSubString(sVector, iPos, iCount));
iPos = FindSubString(sVector, "#POSITION_Y#") + 12;
iCount = FindSubString(GetSubString(sVector, iPos, iLen - iPos), "#");
fY = StringToFloat(GetSubString(sVector, iPos, iCount));
iPos = FindSubString(sVector, "#POSITION_Z#") + 12;
iCount = FindSubString(GetSubString(sVector, iPos, iLen - iPos), "#");
fZ = StringToFloat(GetSubString(sVector, iPos, iCount));
}
return Vector(fX, fY, fZ);
}
string aps_LocationToString(location lLocation)
{
object oArea = GetAreaFromLocation(lLocation);
vector vPosition = GetPositionFromLocation(lLocation);
float fOrientation = GetFacingFromLocation(lLocation);
string sReturnValue;
if (GetIsObjectValid(oArea))
sReturnValue = "#AREA#" + GetTag(oArea) + "#POSITION_X#" + FloatToString(vPosition.x) + "#POSITION_Y#" + FloatToString(vPosition.y) + "#POSITION_Z#" + FloatToString(vPosition.z) + "#ORIENTATION#" + FloatToString(fOrientation) + "#END#";
return sReturnValue;
}
location StringToLocation(string sLocation)
{
location lReturnValue;
object oArea;
vector vPosition;
float fOrientation, fX, fY, fZ;
int iPos, iCount;
int iLen = GetStringLength(sLocation);
if (iLen > 0)
{
iPos = FindSubString(sLocation, "#AREA#") + 6;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
oArea = GetObjectByTag(GetSubString(sLocation, iPos, iCount));
iPos = FindSubString(sLocation, "#POSITION_X#") + 12;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fX = StringToFloat(GetSubString(sLocation, iPos, iCount));
iPos = FindSubString(sLocation, "#POSITION_Y#") + 12;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fY = StringToFloat(GetSubString(sLocation, iPos, iCount));
iPos = FindSubString(sLocation, "#POSITION_Z#") + 12;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fZ = StringToFloat(GetSubString(sLocation, iPos, iCount));
vPosition = Vector(fX, fY, fZ);
iPos = FindSubString(sLocation, "#ORIENTATION#") + 13;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fOrientation = StringToFloat(GetSubString(sLocation, iPos, iCount));
lReturnValue = Location(oArea, vPosition, fOrientation);
}
return lReturnValue;
}
// These functions are responsible for transporting the various data types back
// and forth to the database.
void SetPersistentString(object oObject, string sVarName, string sValue, int iExpiration=0, string sTable="pwdata")
{
if(!USE_DATABASE)
{
SetLocalString(oObject, sVarName, sValue);
return;
}
string sPlayer;
string sTag;
if (GetIsPC(oObject))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPlayer = "~";
sTag = GetTag(oObject);
}
sVarName = SQLEncodeSpecialChars(sVarName);
sValue = SQLEncodeSpecialChars(sValue);
string sSQL = "SELECT player FROM " + sTable + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SQLExecDirect(sSQL);
if (SQLFirstRow() == SQL_SUCCESS)
{
// row exists
sSQL = "UPDATE " + sTable + " SET val='" + sValue +
"',expire=" + IntToString(iExpiration) + " WHERE player='"+ sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SQLExecDirect(sSQL);
}
else
{
// row doesn't exist
sSQL = "INSERT INTO " + sTable + " (player,tag,name,val,expire) VALUES" +
"('" + sPlayer + "','" + sTag + "','" + sVarName + "','" +
sValue + "'," + IntToString(iExpiration) + ")";
SQLExecDirect(sSQL);
}
}
string GetPersistentString(object oObject, string sVarName, string sTable="pwdata")
{
if(!USE_DATABASE)
return GetLocalString(oObject, sVarName);
string sPlayer;
string sTag;
if (GetIsPC(oObject))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPlayer = "~";
sTag = GetTag(oObject);
}
sVarName = SQLEncodeSpecialChars(sVarName);
string sSQL = "SELECT val FROM " + sTable + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SQLExecDirect(sSQL);
if (SQLFirstRow() == SQL_SUCCESS)
return SQLDecodeSpecialChars(SQLGetData(1));
else
{
return "";
// If you want to convert your existing persistent data to APS, this
// would be the place to do it. The requested variable was not found
// in the database, you should
// 1) query it's value using your existing persistence functions
// 2) save the value to the database using SetPersistentString()
// 3) return the string value here.
}
}
void SetPersistentInt(object oObject, string sVarName, int iValue, int iExpiration=0, string sTable="pwdata")
{
if(!USE_DATABASE)
SetLocalInt(oObject, sVarName, iValue);
else
SetPersistentString(oObject, sVarName, IntToString(iValue), iExpiration, sTable);
}
int GetPersistentInt(object oObject, string sVarName, string sTable="pwdata")
{
if(!USE_DATABASE)
return GetLocalInt(oObject, sVarName);
else
return StringToInt(GetPersistentString(oObject, sVarName, sTable));
}
void SetPersistentFloat(object oObject, string sVarName, float fValue, int iExpiration=0, string sTable="pwdata")
{
if(!USE_DATABASE)
SetLocalFloat(oObject, sVarName, fValue);
else
SetPersistentString(oObject, sVarName, FloatToString(fValue), iExpiration, sTable);
}
float GetPersistentFloat(object oObject, string sVarName, string sTable="pwdata")
{
if(!USE_DATABASE)
return GetLocalFloat(oObject, sVarName);
else
return StringToFloat(GetPersistentString(oObject, sVarName, sTable));
}
void SetPersistentLocation(object oObject, string sVarName, location lLocation, int iExpiration=0, string sTable="pwdata")
{
if(!USE_DATABASE)
SetLocalLocation(oObject, sVarName, lLocation);
else
SetPersistentString(oObject, sVarName, aps_LocationToString(lLocation), iExpiration, sTable);
}
location GetPersistentLocation(object oObject, string sVarName, string sTable="pwdata")
{
if(!USE_DATABASE)
return GetLocalLocation(oObject, sVarName);
else
return StringToLocation(GetPersistentString(oObject, sVarName, sTable));
}
void SetPersistentVector(object oObject, string sVarName, vector vVector, int iExpiration=0, string sTable ="pwdata")
{
if(USE_DATABASE)
SetPersistentString(oObject, sVarName, aps_VectorToString(vVector), iExpiration, sTable);
else
SetLocalString(oObject, sVarName, aps_VectorToString(vVector));
}
vector GetPersistentVector(object oObject, string sVarName, string sTable = "pwdata")
{
if(USE_DATABASE)
return StringToVector(GetPersistentString(oObject, sVarName, sTable));
else
return StringToVector(GetLocalString(oObject, sVarName));
}
void DeletePersistentVariable(object oObject, string sVarName, string sTable="pwdata")
{
if(!USE_DATABASE) //try all 5 types to be certain. unfortunate side effect of killing shared name vars.
{
DeleteLocalFloat(oObject, sVarName);
DeleteLocalInt(oObject, sVarName);
DeleteLocalLocation(oObject, sVarName);
DeleteLocalObject(oObject, sVarName);
DeleteLocalString(oObject, sVarName);
}
else
{
string sPlayer;
string sTag;
if (GetIsPC(oObject))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPlayer = "~";
sTag = GetTag(oObject);
}
sVarName = SQLEncodeSpecialChars(sVarName);
string sSQL = "DELETE FROM " + sTable + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SQLExecDirect(sSQL);
}
}
// Problems can arise with SQL commands if variables or values have single quotes
// in their names. These functions are a replace these quote with the tilde character
string SQLEncodeSpecialChars(string sString)
{
if (FindSubString(sString, "'") == -1) // not found
return sString;
int i;
string sReturn = "";
string sChar;
// Loop over every character and replace special characters
for (i = 0; i < GetStringLength(sString); i++)
{
sChar = GetSubString(sString, i, 1);
if (sChar == "'")
sReturn += "~";
else
sReturn += sChar;
}
return sReturn;
}
string SQLDecodeSpecialChars(string sString)
{
if (FindSubString(sString, "~") == -1) // not found
return sString;
int i;
string sReturn = "";
string sChar;
// Loop over every character and replace special characters
for (i = 0; i < GetStringLength(sString); i++)
{
sChar = GetSubString(sString, i, 1);
if (sChar == "~")
sReturn += "'";
else
sReturn += sChar;
}
return sReturn;
}
// Use this method in your onClientEnter event.
void RestoreJournalEntries(object oPC)
{
string sSQL;
string sJournalEntry;
int iJournalValue;
string sPCTag;
string sPCName;
sPCTag = SQLEncodeSpecialChars(GetName(oPC));
sPCName = SQLEncodeSpecialChars(GetPCPlayerName(oPC));
sSQL = "SELECT vJournalEntry, iJournalValue FROM tJournal "
+ " WHERE vPCTag='" + sPCTag + "' "
+ " AND vPCName='" + sPCName + "' ";
SQLExecDirect(sSQL);
int rc;
rc = SQLFirstRow();
while(rc == SQL_SUCCESS)
{
sJournalEntry = SQLGetData(1);
iJournalValue = StringToInt(SQLGetData(2));
AddJournalQuestEntry(sJournalEntry, iJournalValue, oPC, FALSE, FALSE, FALSE);
//SendMessageToPC(oPC, "Restoring::JournalEntryData::" + sJournalEntry + " " + IntToString(iJournalValue));
SetLocalInt(oPC, "NW_JOURNAL_ENTRY" + sJournalEntry, iJournalValue);
rc = SQLNextRow();
}
}
// This method will update/insert a journal entry.
void InsertUpdateJournalEntry(object oPC, string sJournalEntry, int nState, int bAllPartyMembers, int bAllPlayers, int bAllowOverrideHigher)
{
if(bAllPartyMembers)
{
object oPartyMember = GetFirstFactionMember(oPC, TRUE);
while (oPartyMember != OBJECT_INVALID)
{
InsertUpdateJournalEntry(oPartyMember, sJournalEntry, nState, FALSE, FALSE, bAllowOverrideHigher);
oPartyMember = GetNextFactionMember(oPC, TRUE);
}
return;
}
else if(bAllPlayers)
{
object oPartyMember=GetFirstPC();
while(GetIsObjectValid(oPartyMember))
{
InsertUpdateJournalEntry(oPartyMember, sJournalEntry, nState, FALSE, FALSE, bAllowOverrideHigher);
oPartyMember=GetNextPC();
}
return;
}
//handles one at a time.
string sSQL;
string sUpdateSQL;
string sPCTag;
string sPCName;
sPCTag = SQLEncodeSpecialChars(GetName(oPC));
sPCName = SQLEncodeSpecialChars(GetPCPlayerName(oPC));
sSQL = "SELECT vPCTag FROM tJournal "
+ " WHERE vPCTag='" + sPCTag + "' "
+ " AND vPCName='" + sPCName + "' "
+ " AND vJournalEntry='" + sJournalEntry + "' ";
SQLExecDirect(sSQL);
if (SQLFirstRow() == SQL_SUCCESS)
{
sUpdateSQL = "UPDATE tJournal "
+ " SET iJournalValue='"+ IntToString(nState) + "' "
+ " WHERE vPCTag='" + sPCTag + "' "
+ " AND vPCName='" + sPCName + "' "
+ " AND vJournalEntry='" + sJournalEntry + "' ";
}
else
{
sUpdateSQL = "INSERT INTO tJournal (vPCName, vPCTag, vJournalEntry, iJournalValue) "
+ " VALUES ('" + sPCName + "', "
+ " '" + sPCTag + "', "
+ " '" + sJournalEntry + "', "
+ " '" + IntToString(nState) + "') ";
}
SQLExecDirect(sUpdateSQL);
AddJournalQuestEntry(sJournalEntry, nState, oPC, FALSE, FALSE, bAllowOverrideHigher);
SetLocalInt(oPC, "NW_JOURNAL_ENTRY" + sJournalEntry, nState);
}
void DeleteJournalEntry(object oPC, string sJournalEntry)
{
string sSQL;
string sPCTag;
string sPCName;
sPCTag = SQLEncodeSpecialChars(GetName(oPC));
sPCName = SQLEncodeSpecialChars(GetPCPlayerName(oPC));
sSQL = "DELETE FROM tJournal "
+ " WHERE vPCTag='" + sPCTag + "' "
+ " AND vPCName='" + sPCName + "' "
+ " AND vJournalEntry='" + sJournalEntry + "' ";
SQLExecDirect(sSQL);
RemoveJournalQuestEntry(sJournalEntry, oPC, FALSE, FALSE);
DeleteLocalInt(oPC, "NW_JOURNAL_ENTRY" + sJournalEntry);
}
int CheckJournalEntry(object oObject, string sJournalEntry="")
{
string sSQL;
string sPCTag;
string sPCName;
if (GetIsPC(oObject))
{
sPCName = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sPCTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPCName = "~";
sPCTag = GetTag(oObject);
}
sSQL = "SELECT COUNT(*) FROM tJournal "
+ " WHERE tag='" + sPCTag + "' "
+ " AND player='" + sPCName + "' ";
if (sJournalEntry !="") sSQL += " AND JournalEntry='" + sJournalEntry + "' ";
SQLExecDirect(sSQL);
if(SQLFirstRow()==SQL_SUCCESS)
return StringToInt(SQLGetData(1));
else
return 0;
} |
Btw, you need the right sql defination as follows...
Code: | CREATE TABLE `tJournal` (
`id` int(11) NOT NULL auto_increment,
`vPCName` varchar(64) NOT NULL default '',
`vPCTag` varchar(64) NOT NULL default '',
`vJournalEntry` varchar(64) NOT NULL default '',
`iJournalValue` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `vPCName` (`vPCName`,`vPCTag`,`vJournalEntry`)
) TYPE=MyISAM; |
|
|
Back to top |
|
|
WrathPhoenix
Joined: 24 May 2005 Posts: 2
|
Posted: Thu May 26, 2005 4:31 Post subject: |
|
|
Im pretty lost on this persistant journal entry stuff... or any of the nwnx usage thus far. I namely use the toolset stuff to create the world were making now but we will need a database backend.. Is there any kind of script out there that can catch and auto update certain things like journal entries, location, hp, variables, status conditions ect? I am really really lost... lol |
|
Back to top |
|
|
|
|
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
|