PWE_PRC8/_module/nss/ff_include.nss
Jaysyn904 ee1dc35889 Initial Commit
Initial Commit
2025-04-03 10:29:41 -04:00

624 lines
24 KiB
Plaintext
Raw Permalink Blame History

///*************************************
//* NWN-MySQL 4.0 (c) 2004 FastFrench *
//*************************************
// This file is licensed under the terms of the
// GNU GENERAL PUBLIC LICENSE (GPL) Version 2
// ********************
// ** ff_include.nss **
// ********************
// ** include this file at the beginning of any of your scripts that uses NWN-MySQL stuff
#include "ff_inc_options"
#include "aps_include"
const int LV_PC = 79;
const int LV_VAMPIRE = 99;
const int LV_ANIM1 = 199;
const int LV_ANIM2 = 299;
const int LV_DM = 399;
const int LV_ADMIN = 999;
const int SPEECHVOLUME_INVALID = 0;
const int SPEECHVOLUME_TALK = 1;
const int SPEECHVOLUME_SHOUT = 2;
const int SPEECHVOLUME_WHISPER = 3;
const int SPEECHVOLUME_TELL = 4;
const int SPEECHVOLUME_TELL_PLAYER = 5;
const int SPEECHVOLUME_PARTY = 6;
const int SPEECHVOLUME_DM = 14;
#include "ff_include_other"
#include "ff_inc_addons"
/*****************************************************************************************/
/* Function prototypes */
/* All those functions are specific to NWN-MySQL, and need one of the NWN-MySQL main dll */
/* to be used */
/*****************************************************************************************/
/****************************************************************
************** Non-database related functions ******************
* You don't need to use any DataBase to use those functions *
* But you need to run one of the NWN-MySQL main dll to support *
* them *********************************************************
****************************************************************/
int SQLGetTime(); // Gives the number of micro-seconds since NWServer started (used for precise Benchmarks)
string SQLGetVersion(); // Returns version string for NWN-MySQL
int SQLGetRLDate(); // Returns the number of second since january 1st 2001 (in RL world)
void SQLSetIGDate(); // This function can be put in OnModuleLoad event to automatically synchronize IG and IRL times
/***************************************************************
* DataBase related advanced and optimised NWN-MySQL functions *
* Most of them need either a database main dll from NWN-MySQL *
* package, or a database APS/NWNX plugin dll provided with *
* NWN-MySQL *
***************************************************************/
int SQLExecAndFetchDirect(string sSQL);
/********************************************************************
* very fast functions to retrieve a single value from the DataBase *
********************************************************************/
string SQLExecAndFetchSingle(string sSQL, string DefaultValue=""); // FAST and Safe for result sets under (size of request) characters long AND ONLY ONE VALUE RETURNED
int SQLExecAndFetchSingleInt(string sSQL, int DefaultValue=0); // FAST and Safe for result sets under (size of request) characters long AND ONLY ONE VALUE RETURNED
float SQLExecAndFetchSingleFloat(string sSQL, float DefaultValue=0.0); // FAST and Safe for result sets under (size of request) characters long AND ONLY ONE VALUE RETURNED
string SQLEatData();
void SQLSkipData();
// Functions for initializing APS and working with result sets
object oSpecific=OBJECT_INVALID;
object GetNWNMySQLWP();
object GetNWNMySQLWP()
{
if (oSpecific != OBJECT_INVALID) return oSpecific;
return oSpecific = GetWaypointByTag("NWN_MySQL_WP");
}
/* Because all SQLLocalXXXX functions share a global variable,
all such functions related to the same request should better
be used within a single script. Avoid for instance to call
SQLLocalExecAndFetchDirect in a function and then corresponding
SQLLocalEatData within other functions called with AssignCommand,
ExecuteScript or DelayCommand. Except in this case, you should
always try to use this set of function instead of those described
within previous sections. */
int SQLLocalFetch();
int SQLLocalExecAndFetchDirect(string sSQL);
string SQLLocalEatData();
string SQLLocalEatDataString();
int SQLLocalEatDataInt();
location SQLLocalEatDataLocation();
vector SQLLocalEatDataVector();
float SQLLocalEatDataFloat();
void SQLLocalSkipData();
// Conversion routines
string ff_LocationToString(location lLocation);
location ff_StringToLocation(string sLocation);
string ff_VectorToString(vector vVector);
vector ff_StringToVector(string sVector);
string ff_GetPersistentString(string ValueName, string sTable="global", string DefaultValue="");
int ff_GetPersistentInt(string ValueName, string sTable="global", int DefaultValue=0);
float ff_GetPersistentFloat(string ValueName, string sTable="global", float DefaultValue=0.0);
location ff_GetPersistentLocation(string ValueName, string sTable="global");
vector ff_GetPersistentVector(string ValueName, string sTable="global");
void ff_SetPersistentString(string ValueName, string sValue, string sTable="global");
void ff_SetPersistentInt(string ValueName, int iValue, string sTable="global");
void ff_SetPersistentFloat(string ValueName, float fValue, string sTable="global");
void ff_SetPersistentLocation(string ValueName, location lValue, string sTable="global");
void ff_SetPersistentVector(string ValueName, vector vValue, string sTable="global");
void ff_DeletePersistentVariable(string ValueName, string sTable="global");
string ff_GetPCPersistentString(object oPC, string ValueName);
int ff_GetPCPersistentInt(object oPC, string ValueName);
float ff_GetPCPersistentFloat(object oPC, string ValueName);
location ff_GetPCPersistentLocation(object oPC, string ValueName);
vector ff_GetPCPersistentVector(object oPC, string ValueName);
void ff_SetPCPersistentString(object oPC, string ValueName, string sValue);
void ff_SetPCPersistentInt(object oPC, string ValueName, int iValue);
void ff_SetPCPersistentFloat(object oPC, string ValueName, float fValue);
void ff_SetPCPersistentLocation(object oPC, string ValueName, location lValue);
void ff_SetPCPersistentVector(object oPC, string ValueName, vector lValue);
void ff_DeletePCPersistentVariable(object oPC, string ValueName);
#include "ff_inc_server"
/************************************/
/* Implementation */
/************************************/
string LOCAL_BUFFER;
/*
* Most functions could easily be simulated with NWNX2 (but with decreased performances)
* Only SQLGetTime is really very specific and can't be done without NWN-MySQL. With older version, it will
* simply return 0 all the time (good hint to check if you're using NWN-MySQL).
*/
/********************************************
* (c) FastFrench 2004 - Optimized functions *
*********$$$$********************************/
// *** NWN-MySQL SPECIFIC. Won't work with NWNX version 2.0.3 or older ***
int SQLLocalFetch()
{
object oLocal = GetNWNMySQLWP();
SetLocalString(oLocal, "NWNX!ODBC!FETCH", GetLocalString(oLocal, "NWNX!ODBC!SPACER"));
LOCAL_BUFFER = GetLocalString(oLocal, "NWNX!ODBC!FETCH");
if (GetStringLength(LOCAL_BUFFER) > 0)
return SQL_SUCCESS;
else
return SQL_ERROR;
}
int SQLExecAndFetchDirect(string sSQL) // Safe for results sets under 4096 characters (4KB) long
{
object oLocal = GetNWNMySQLWP();
string sBuf = sSQL + GetLocalString(oLocal, "NWNX!ODBC!SPACER");
SetLocalString(oLocal, "NWNX!ODBC!EXEC_AND_FETCH", sBuf);
sBuf = GetLocalString(oLocal, "NWNX!ODBC!EXEC_AND_FETCH");
if (GetStringLength(sBuf) > 0)
{
SetLocalString(oLocal, "NWNX_ODBC_CurrentRow", sBuf);
return SQL_SUCCESS;
}
else
{
DeleteLocalString(oLocal, "NWNX_ODBC_CurrentRow");
return SQL_ERROR;
}
}
// *** NWN-MySQL SPECIFIC. Won't work with NWNX version 2.0.3 or older ***
string SQLExecAndFetchSingle(string sSQL, string DefaultValue="") // FAST and Safe for result sets under (size of request) characters long AND ONLY ONE VALUE RETURNED
{
SetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC_AND_FETCH", sSQL);
string sRes = GetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC_AND_FETCH");
if (sRes == "") return DefaultValue;
return sRes;
}
// *** NWN-MySQL SPECIFIC. Won't work with NWNX version 2.0.3 or older ***
int SQLExecAndFetchSingleInt(string sSQL, int DefaultValue=0) // FAST and Safe for result sets under (size of request) characters long AND ONLY ONE VALUE RETURNED
{
SetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC_AND_FETCH", sSQL);
string sRes = GetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC_AND_FETCH");
if (sRes == "") return DefaultValue;
return StringToInt(sRes);
}
float SQLExecAndFetchSingleFloat(string sSQL, float DefaultValue=0.0) // FAST and Safe for result sets under (size of request) characters long AND ONLY ONE VALUE RETURNED
{
SetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC_AND_FETCH", sSQL);
string sRes = GetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC_AND_FETCH");
if (sRes == "") return DefaultValue;
return StringToFloat(sRes);
}
// *** NWN-MySQL SPECIFIC. Won't work with NWNX version 2.0.3 or older ***
int SQLGetTime() // Gives the number of micro-seconds since NWServer started
{
SetLocalString(GetNWNMySQLWP(), "NWNX!TIMER", "000000000000");
return StringToInt(GetLocalString(GetNWNMySQLWP(), "NWNX!TIMER"));
}
string SQLGetVersion() // Returns version string for NWN-MySQL
{
SetLocalString(GetNWNMySQLWP(), "NWNX!VERSION", "APS/NWNX");
return GetLocalString(GetNWNMySQLWP(), "NWNX!VERSION");
}
int SQLGetRLDate() // Returns the number of second since january 1st 2001 (in RL world)
{
SetLocalString(GetNWNMySQLWP(), "NWNX!RLDATE", "000000000000000000000000000000000");
return StringToInt(GetLocalString(GetNWNMySQLWP(), "NWNX!RLDATE"));
}
void SQLSetIGDate()
{
int GetRLDate=SQLGetRLDate();
int NbMinPerHour = FloatToInt(HoursToSeconds(1)) / 60;
int iSecond = GetRLDate % 60;
GetRLDate = GetRLDate / 60;
int iMinute = GetRLDate % NbMinPerHour;
GetRLDate = GetRLDate / NbMinPerHour;
int iHour = GetRLDate % 24;
GetRLDate = GetRLDate / 24;
int iDay = GetRLDate % 28 + 1;
GetRLDate = GetRLDate / 28;
int iMonth = GetRLDate % 12 + 1;
GetRLDate = GetRLDate / 12;
int iYear = 1001+GetRLDate;
SetTime(iHour, iMinute, iSecond, 0);
SetCalendar(iYear, iMonth, iDay);
//WriteTimestampedLogEntry("Set IG time: "+IntToString(iDay)+"/"+IntToString(iMonth)+"/"+IntToString(iYear)+" - "+IntToString(iHour)+":"+IntToString(iMinute)+":"+IntToString(iSecond));
}
// Get Next Data
string SQLEatData()
{
string sResultSet = GetLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow");
// find column in current row
int iPos = FindSubString(sResultSet, "<22>");
if (iPos == -1) // Une seule colonne
{
// only one column, return value immediately et efface la chaine
DeleteLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow");
return sResultSet;
}
else
{
SetLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow", GetStringRight(sResultSet,GetStringLength(sResultSet) - iPos - 1));
return GetStringLeft(sResultSet, iPos);
}
}
// Skip next data (like SQLEatData, except it returns nothing)
void SQLSkipData()
{
string sResultSet = GetLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow");
int iPos = FindSubString(sResultSet, "<22>");
if (iPos == -1) // Une seule colonne
// only one column, return value immediately et efface la chaine
DeleteLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow");
else
SetLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow", GetStringRight(sResultSet,GetStringLength(sResultSet) - iPos - 1));
}
/* All related SQLLocalXXXX functions need to be used within a single file.
It means for instance that if you make a call to SQLLocalExecAndFetchDirect and several calls to SQLLocalEatData to get corresponding results,
then you have to put all those instruction in the same scipt file (to make it easier, let say all call should better be in a single script) - using shared string
if you can't, then better use the less optimized SQLXXX equivalent (SQLExecAndFetchDirect and SQLEatData for instance), not the very optimized SQLLocalXXXX */
// *** NWN-MySQL SPECIFIC. Won't work with NWNX version 2.0.3 or older ***
int SQLLocalExecAndFetchDirect(string sSQL) // Safe for result sets under 4096 characters (4KB) - store result locally
{
object oLocal = GetNWNMySQLWP();
SetLocalString(oLocal, "NWNX!ODBC!EXEC_AND_FETCH", sSQL + GetLocalString(oLocal, "NWNX!ODBC!SPACER"));
LOCAL_BUFFER = GetLocalString(oLocal, "NWNX!ODBC!EXEC_AND_FETCH");
if (GetStringLength(LOCAL_BUFFER) > 0)
return SQL_SUCCESS;
else
return SQL_ERROR;
}
// Get Next Data
string SQLLocalEatData()
{
int iPos;
// find column in current row
//int iCount = 0;
string Result;
iPos = FindSubString(LOCAL_BUFFER, "<22>");
if (iPos == -1) // Une seule colonne
{
// only one column, return value immediately et efface la chaine
Result = LOCAL_BUFFER;
LOCAL_BUFFER = "";
return Result;
}
else
{
Result = GetStringLeft(LOCAL_BUFFER, iPos);
LOCAL_BUFFER = GetStringRight(LOCAL_BUFFER,GetStringLength(LOCAL_BUFFER) - iPos - 1);
return Result;
}
}
string SQLLocalEatDataString() {return SQLDecodeSpecialChars(SQLLocalEatData());}
// Get Next Data
void SQLLocalSkipData()
{
int iPos;
// find column in current row
//int iCount = 0;
string Result;
iPos = FindSubString(LOCAL_BUFFER, "<22>");
if (iPos == -1) // Une seule colonne
{
// only one column, return value immediately et efface la chaine
LOCAL_BUFFER = "";
}
else
{
LOCAL_BUFFER = GetStringRight(LOCAL_BUFFER,GetStringLength(LOCAL_BUFFER) - iPos - 1);
}
}
// Get Next Data as an int
int SQLLocalEatDataInt()
{
int iPos;
int Result;
iPos = FindSubString(LOCAL_BUFFER, "<22>");
if (iPos == -1) // Une seule colonne
{
// only one column, return value immediately et efface la chaine
Result = StringToInt(LOCAL_BUFFER);
LOCAL_BUFFER = "";
return Result;
}
else
{
Result = StringToInt(GetStringLeft(LOCAL_BUFFER, iPos));
LOCAL_BUFFER = GetStringRight(LOCAL_BUFFER,GetStringLength(LOCAL_BUFFER) - iPos - 1);
return Result;
}
}
location SQLLocalEatDataLocation()
{
return ff_StringToLocation(SQLLocalEatData());
}
vector SQLLocalEatDataVector()
{
return ff_StringToVector(SQLLocalEatData());
}
float SQLLocalEatDataFloat()
{
int iPos;
float Result;
iPos = FindSubString(LOCAL_BUFFER, "<22>");
if (iPos == -1) // Une seule colonne
{
// only one column, return value immediately et efface la chaine
Result = StringToFloat(LOCAL_BUFFER);
LOCAL_BUFFER = "";
return Result;
}
else
{
Result = StringToFloat(GetStringLeft(LOCAL_BUFFER, iPos));
LOCAL_BUFFER = GetStringRight(LOCAL_BUFFER,GetStringLength(LOCAL_BUFFER) - iPos - 1);
return Result;
}
}
string ff_LocationToString(location lLocation)
{
object oArea = GetAreaFromLocation(lLocation);
string sReturnValue;
if (GetIsObjectValid(oArea))
{
vector vPosition = GetPositionFromLocation(lLocation);
float fOrientation = GetFacingFromLocation(lLocation);
sReturnValue = "#A#" + GetTag(oArea) + "#X#" + FloatToString(vPosition.x,8,4) + "#Y#" + FloatToString(vPosition.y,8,4) + "#Z#" + FloatToString(vPosition.z,8,4) + "#O#" + FloatToString(fOrientation,8,4) + "#E#";
}
else
sReturnValue = "#A##X#0.0#Y#0.0#Z#0.0#O#0.0#E#";
return sReturnValue;
}
location ff_StringToLocation(string sLocation)
{
location lReturnValue=Location(OBJECT_INVALID, Vector(),0.0);
object oArea;
vector vPosition;
float fOrientation, fX, fY, fZ;
int iPos, iCount;
int iLen = GetStringLength(sLocation);
if (iLen > 0)
{
iPos = FindSubString(sLocation, "#A#") + 3;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
if (iCount > 0)
{
oArea = GetObjectByTag(GetSubString(sLocation, iPos, iCount));
if (GetIsObjectValid(oArea))
{
iPos = FindSubString(sLocation, "#X#") + 3;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fX = StringToFloat(GetSubString(sLocation, iPos, iCount));
iPos = FindSubString(sLocation, "#Y#") + 3;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fY = StringToFloat(GetSubString(sLocation, iPos, iCount));
iPos = FindSubString(sLocation, "#Z#") + 3;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fZ = StringToFloat(GetSubString(sLocation, iPos, iCount));
vPosition = Vector(fX, fY, fZ);
iPos = FindSubString(sLocation, "#O#") + 3;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fOrientation = StringToFloat(GetSubString(sLocation, iPos, iCount));
lReturnValue = Location(oArea, vPosition, fOrientation);
}
}
}
return lReturnValue;
}
string ff_VectorToString(vector vVector)
{
return "#X#" + FloatToString(vVector.x,8,4) + "#Y#" + FloatToString(vVector.y,8,4) + "#Z#" + FloatToString(vVector.z,8,4) + "#E#";
}
vector ff_StringToVector(string sVector)
{
float fX=0.0, fY=0.0, fZ=0.0;
int iPos, iCount;
int iLen = GetStringLength(sVector);
if (iLen > 0)
{
iPos = FindSubString(sVector, "#X#") + 3;
iCount = FindSubString(GetSubString(sVector, iPos, iLen - iPos), "#");
fX = StringToFloat(GetSubString(sVector, iPos, iCount));
iPos = FindSubString(sVector, "#Y#") + 3;
iCount = FindSubString(GetSubString(sVector, iPos, iLen - iPos), "#");
fY = StringToFloat(GetSubString(sVector, iPos, iCount));
iPos = FindSubString(sVector, "#Z#") + 3;
iCount = FindSubString(GetSubString(sVector, iPos, iLen - iPos), "#");
fZ = StringToFloat(GetSubString(sVector, iPos, iCount));
}
return Vector(fX, fY, fZ);
}
int ff_GetPersistentInt(string ValueName, string sTable="global", int DefaultValue=0)
{
return SQLExecAndFetchSingleInt("SELECT Value FROM "+sTable+" WHERE VarName='"+ValueName+"'",DefaultValue);
}
float ff_GetPersistentFloat(string ValueName, string sTable="global", float DefaultValue=0.0)
{
return SQLExecAndFetchSingleFloat("SELECT Value FROM "+sTable+" WHERE VarName='"+ValueName+"'",DefaultValue);
}
string ff_GetPersistentString(string ValueName, string sTable="global", string DefaultValue="")
{
return SQLDecodeSpecialChars(SQLExecAndFetchSingle("SELECT Value FROM "+sTable+" WHERE VarName='"+ValueName+"'<27>................................................................................................................................................................................................................",DefaultValue));
}
location ff_GetPersistentLocation(string ValueName, string sTable="global")
{
return ff_StringToLocation(SQLExecAndFetchSingle("SELECT Value FROM "+sTable+" WHERE VarName='"+ValueName+"'"));
}
vector ff_GetPersistentVector(string ValueName, string sTable="global")
{
return ff_StringToVector(SQLExecAndFetchSingle("SELECT Value FROM "+sTable+" WHERE VarName='"+ValueName+"'"));
}
void ff_SetPersistentInt(string ValueName, int iValue, string sTable="global")
{
SQLExecDirect("REPLACE "+sTable+" SET Value="+IntToString(iValue)+", VarName='"+ValueName+"'");
}
void ff_SetPersistentFloat(string ValueName, float fValue, string sTable="global")
{
SQLExecDirect("REPLACE "+sTable+" SET Value="+FloatToString(fValue)+", VarName='"+ValueName+"'");
}
void ff_SetPersistentString(string ValueName, string sValue, string sTable="global")
{
SQLExecDirect("REPLACE "+sTable+" SET Value='"+SQLEncodeSpecialChars(sValue)+"', VarName='"+ValueName+"'");
}
void ff_SetPersistentLocation(string ValueName, location lValue, string sTable="global")
{
SQLExecDirect("REPLACE "+sTable+" SET Value='"+ff_LocationToString(lValue)+"', VarName='"+ValueName+"'");
}
void ff_SetPersistentVector(string ValueName, vector vValue, string sTable="global")
{
SQLExecDirect("REPLACE "+sTable+" SET Value='"+ff_VectorToString(vValue)+"', VarName='"+ValueName+"'");
}
void ff_DeletePersistentVariable(string ValueName, string sTable="global")
{
SQLExecDirect("DELETE from "+sTable+" WHERE VarName='"+ValueName+"'");
}
string ff_GetPCPersistentString(object oPC, string ValueName)
{
string sId = GetLocalString(oPC, "PWId");
if (sId=="") return "";
return SQLDecodeSpecialChars(SQLExecAndFetchSingle("SELECT Value FROM PCData WHERE VarName='"+ValueName+"' AND Id="+sId+"<22>................................................................................................................................................................................................................"));
}
int ff_GetPCPersistentInt(object oPC, string ValueName)
{
string sId = GetLocalString(oPC, "PWId");
if (sId=="") return 0;
return SQLExecAndFetchSingleInt("SELECT Value FROM PCData WHERE VarName='"+ValueName+"' AND Id="+sId);
}
float ff_GetPCPersistentFloat(object oPC, string ValueName)
{
string sId = GetLocalString(oPC, "PWId");
if (sId=="") return 0.0;
return StringToFloat(SQLExecAndFetchSingle("SELECT Value FROM PCData WHERE VarName='"+ValueName+"' AND Id="+sId));
}
location ff_GetPCPersistentLocation(object oPC, string ValueName)
{
string sId = GetLocalString(oPC, "PWId");
if (sId=="") return Location(OBJECT_INVALID, Vector(), 0.0);
return ff_StringToLocation(SQLExecAndFetchSingle("SELECT Value FROM PCData WHERE VarName='"+ValueName+"' AND Id="+sId+"<22>................................................................................................................................................................................................................"));
}
vector ff_GetPCPersistentVector(object oPC, string ValueName)
{
string sId = GetLocalString(oPC, "PWId");
if (sId=="") return Vector();
return ff_StringToVector(SQLExecAndFetchSingle("SELECT Value FROM PCData WHERE VarName='"+ValueName+"' AND Id="+sId+"<22>................................................................................................................................................................................................................"));
}
void ff_SetPCPersistentString(object oPC, string ValueName, string sValue)
{
string sId = GetLocalString(oPC, "PWId");
if (sId=="") return;
SQLExecDirect("REPLACE PCData SET Value='"+SQLEncodeSpecialChars(sValue)+"', VarName='"+ValueName+"', Id="+sId);
}
void ff_SetPCPersistentInt(object oPC, string ValueName, int iValue)
{
string sId = GetLocalString(oPC, "PWId");
if (sId=="") return;
SQLExecDirect("REPLACE PCData SET Value='"+IntToString(iValue)+"', VarName='"+ValueName+"', Id="+sId);
}
void ff_SetPCPersistentFloat(object oPC, string ValueName, float fValue)
{
string sId = GetLocalString(oPC, "PWId");
if (sId=="") return;
SQLExecDirect("REPLACE PCData SET Value='"+FloatToString(fValue)+"', VarName='"+ValueName+"', Id="+sId);
}
void ff_SetPCPersistentLocation(object oPC, string ValueName, location lValue)
{
string sId = GetLocalString(oPC, "PWId");
if (sId=="") return;
SQLExecDirect("REPLACE PCData SET Value='"+ff_LocationToString(lValue)+"', VarName='"+ValueName+"', Id="+sId);
}
void ff_SetPCPersistentVector(object oPC, string ValueName, vector vValue)
{
string sId = GetLocalString(oPC, "PWId");
if (sId=="") return;
SQLExecDirect("REPLACE PCData SET Value='"+ff_VectorToString(vValue)+"', VarName='"+ValueName+"', Id="+sId);
}
void ff_DeletePCPersistentVariable(object oPC, string ValueName)
{
string sId = GetLocalString(oPC, "PWId");
if (sId=="") return;
SQLExecDirect("DELETE from PCData WHERE VarName='"+ValueName+"' AND Id="+sId);
}