//Written by Thanatos the Loonie (thanatostheloonie@hotmail.com) //This script is my attempt to reduce database access.... //A wrapper for the campaign DB functions... //Woot! Great success! Moahahaha! - Thanatos the Loonie! //I normally don't comment much, LOL, but I have a feeling that //this script might be studied... it rocks!! LOL //Hence, I actually use a little more variables than I needed.. //for readability... ;) ENJOY //Version 1.01 - added scripted server resetting features. //Just don't use the following in Actual DB name or Var name... LOL... //Key //~DB~ = DB, ~VN~ = Var, ~TP~ = Type, ~NM~ = Name, ~PN~ = PCName, ~XX~ = Internal DB/Var //~~OBLITERATE~~ = Internal DestroyDB ~DX~ = Destroyed DBs //Config //Enable for max efficiency and speed.... Wheee const int TTL_DBCACHE_ENABLED = TRUE; //MAX number of DB Commands (NOT VARIABLES...COMMANDS) to Cache... const int TTL_MAXCACHE = 1000; //ttl_campaign_hb empties the DB Cache on a regular basis change these config //constants to specify how it should behave. //*IMPORTANT* IF YOUR SERVER RESETS WHEN THERE ARE NO PLAYERS. READ THE COMMENTS //FOR FUNCTION: TTL_DBClearCache() //TTL_DBCACHE_PHEARTS is the number of heartbeats between gradual cache writes //when there are players in the game. 1 heatbeat can be anything from 6 to 15sec const int TTL_DBCACHE_PHEARTS = 5; //TTL_DBCACHE_PCLEAR is the number of cached writes to clear per gradual cache //write when there are players in the game. const int TTL_DBCACHE_PCLEAR = 1; //TTL_DBCACHE_EHEARTS is the number of heartbeats between gradual cache //writes when the module is empty. const int TTL_DBCACHE_EHEARTS = 1; //TTL_DBCACHE_ECLEAR is the number of cached writes to clear per gradual cache //write when the module is empty. const int TTL_DBCACHE_ECLEAR = 5; //New Version 1.01 extra configs. //Because servers which auto reset don't seem to trigger onclientleave of //the module (or perhaps it triggers them, but stops execution of the script //midway... hmm)... I have added scripted server resetting ability to my //DB Caching scripts. const int TTL_SERVER_RESET_ON_EMPTY = TRUE; //This constant is only applicable if TTL_SERVER_RESET_ON_EMPTY is True... //Waits the configured heartbeats when empty before resetting. //1 heartbeat should be about 6secs const int TTL_SERVER_RESET_ON_EMPTY_HEART_PAUSES = 10; //All must log off for about 1min for reset //This constant is only applicable if TTL_SERVER_RESET_ON_EMPTY is True... //It stops the server resetting cheats... i.e. complete a simple and profitable //quest, quit, wait for server reset, come back on, repeat quest, etc... //It only allows the server to be reset after it's been up and running without //resets for a certain number of game days. (Normal NWN config, 1 hr = 2mins //so 1 game day = 48 mins const int TTL_SERVER_RESET_MIN_GAME_DAYS_APART = 2; //resets will be at least 1hr 36mins apart! //Module Name.. used only with TTL_SERVER_RESET_ON_EMPTY is TRUE //If blank... the script will try to get the module name via GetName(GetModule()) //a method which I'm sure will not work in all instances (especially if your module name and //the actual filename of the module are different!!!! const string TTL_SERVER_RESET_MODULE_NAME = "AutoHomes"; //PUT THE FILENAME!!!! (minus the .mod) //Constants const int TTL_TYPE_NOTFOUND = 0; const int TTL_TYPE_INT = 1; const int TTL_TYPE_FLOAT = 2; const int TTL_TYPE_STRING = 3; const int TTL_TYPE_LOCATION = 4; const int TTL_TYPE_VECTOR = 5; const int TTL_TYPE_OBJECT = 6; const int TTL_TYPE_DELETED = 9; //My Persistent DB Name string TTL_DB = "THANDB"; //The Placeable ttl_monitor object in my reserved area. object TTL_MON = GetObjectByTag("ThanatosTheLoonieDBCacheItem"); location TTL_LOC = GetLocation(TTL_MON); object TTL_AREA = GetArea(TTL_MON); int TTL_ISDBCACHE = TTL_DBCACHE_ENABLED && !GetLocalInt(GetModule(), "TTL_ModShuttingDown"); //Global Variable Used in Unq int iInUnq; //Functions //Clears the DB Cache - good for using in module event on client exit //And no players are left in game. //(IMPORTANT AND NEEDED IF YOUR SERVER RESETS WHEN THERE ARE NO PLAYERS LEFT!!!) //Just add the line ExecuteScript("ttl_campaign_clr", OBJECT_SELF) in your //onclientexit script of your module.... //If your server is a pure persistent world and does not reset even when there //are no players in the game, then there is no need to ever use this DB clearing //function as ttl_campaign_hb autoclears the DB Cache on a regular basis... //more so when it detects no players in the game. void TTL_DBClearCache(); //Include ttl_campaign_inc in your scripts, then //Replace every instance of GetCampaignInt with TTL_GetCampaignInt //And have more efficient DB access... int TTL_GetCampaignInt(string sDB, string sVar, object oPlr = OBJECT_INVALID); //Include ttl_campaign_inc in your scripts, then //Replace every instance of GetCampaignFloat with TTL_GetCampaignFloat //And have more efficient DB access... float TTL_GetCampaignFloat(string sDB, string sVar, object oPlr = OBJECT_INVALID); //Include ttl_campaign_inc in your scripts, then //Replace every instance of GetCampaignString with TTL_GetCampaignString //And have more efficient DB access... string TTL_GetCampaignString(string sDB, string sVar, object oPlr = OBJECT_INVALID); //Include ttl_campaign_inc in your scripts, then //Replace every instance of GetCampaignLocation with TTL_GetCampaignLocation //And have more efficient DB access... location TTL_GetCampaignLocation(string sDB, string sVar, object oPlr = OBJECT_INVALID); //Include ttl_campaign_inc in your scripts, then //Replace every instance of GetCampaignVector with TTL_GetCampaignVector //And have more efficient DB access... vector TTL_GetCampaignVector(string sDB, string sVar, object oPlr = OBJECT_INVALID); //Include ttl_campaign_inc in your scripts, then //Replace every instance of RetrieveCampaignObject with TTL_RetrieveCampaignObject //And have more efficient DB access... object TTL_RetrieveCampaignObject(string sDB, string sVar, location lLoc, object oOwner = OBJECT_INVALID, object oPlr = OBJECT_INVALID); //Include ttl_campaign_inc in your scripts, then //Replace every instance of SetCampaignInt with TTL_SetCampaignInt //And have more efficient DB access... void TTL_SetCampaignInt(string sDB, string sVar, int iVal, object oPlr = OBJECT_INVALID); //Include ttl_campaign_inc in your scripts, then //Replace every instance of SetCampaignFloat with TTL_SetCampaignFloat //And have more efficient DB access... void TTL_SetCampaignFloat(string sDB, string sVar, float fVal, object oPlr = OBJECT_INVALID); //Include ttl_campaign_inc in your scripts, then //Replace every instance of SetCampaignString with TTL_SetCampaignString //And have more efficient DB access... void TTL_SetCampaignString(string sDB, string sVar, string sVal, object oPlr = OBJECT_INVALID); //Include ttl_campaign_inc in your scripts, then //Replace every instance of SetCampaignLocation with TTL_SetCampaignLocation //And have more efficient DB access... void TTL_SetCampaignLocation(string sDB, string sVar, location lVal, object oPlr = OBJECT_INVALID); //Include ttl_campaign_inc in your scripts, then //Replace every instance of SetCampaignVector with TTL_SetCampaignVector //And have more efficient DB access... void TTL_SetCampaignVector(string sDB, string sVar, vector vVal, object oPlr = OBJECT_INVALID); //Include ttl_campaign_inc in your scripts, then //Replace every instance of StoreCampaignObject with TTL_StoreCampaignObject //And have more efficient DB access... int TTL_StoreCampaignObject(string sDB, string sVar, object oObj, object oPlr = OBJECT_INVALID); //Made to solve NWN DB's Var Name limit or 32 chars. //Assigns a unique campaign database variable name if the variable name //is greater than 30 letters... //(max of 4096 unique names for every vars with same initial 30 chars.. it should never run out!!!) //Solves the problem with trying to use Long Var name for DBs //e.g. GetName or GetPCPlayerName for a player with loooong names.. LOL...it works.. I rock ;) string TTL_UniqueCampaignVar(string sVar); //Integer to Unq (unique last 2 variable characters, uses 0-9, a-z, A-Z, symbols //with 0 = 00 and 4095 = ##... I really really don't think I need more.. //Though I could make more... I really really don't think I need more.. (no negatives please... absolutes only) string TTL_IntToUnq(int iUnq); //Second part of my Int To Unq function string TTL_IntToUnqChar(int iUnqChar); //Tracks Vars in Local DB (Internal functions) int TTL_GetDBVars(string sDB, string sVar, int iType); int TTL_SetDBVars(string sDB, string sVar, int iType); //Internal Caching of DB commands... makes NWN DB efficient - MOAHAHAHA void TTL_DBCache(string sDB, string sVar); //Internal Caching of DB commands... makes NWN DB efficient - MOAHAHAHA void TTL_DBCacheDestroyDB(string sDB); //Internal Caching of DB commands... makes NWN DB efficient - MOAHAHAHA void TTL_DBWriteOldCache(int iSkips); //===========WHEEEEEEEEEEEEEEEEEEEEEEEEEEE============== //Include ttl_campaign_inc in your scripts, then //Replace every instance of GetCampaignInt with TTL_GetCampaignInt //And have more efficient DB access... int TTL_GetCampaignInt(string sDB, string sVar, object oPlr = OBJECT_INVALID) { if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_GetDBVars(sDB, sVar, TTL_TYPE_INT)) { case TTL_TYPE_NOTFOUND: SetLocalInt(TTL_MON, "~DB~" + sDB + "~VN~" + sVar, GetCampaignInt(sDB, sVar)); case TTL_TYPE_INT: return GetLocalInt(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; default: return 0; break; } return 0; } //Include ttl_campaign_inc in your scripts, then //Replace every instance of GetCampaignFloat with TTL_GetCampaignFloat //And have more efficient DB access... float TTL_GetCampaignFloat(string sDB, string sVar, object oPlr = OBJECT_INVALID) { if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_GetDBVars(sDB, sVar, TTL_TYPE_FLOAT)) { case TTL_TYPE_NOTFOUND: SetLocalFloat(TTL_MON, "~DB~" + sDB + "~VN~" + sVar, GetCampaignFloat(sDB, sVar)); case TTL_TYPE_FLOAT: return GetLocalFloat(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; default: return 0.0; break; } return 0.0; } //Include ttl_campaign_inc in your scripts, then //Replace every instance of GetCampaignString with TTL_GetCampaignString //And have more efficient DB access... string TTL_GetCampaignString(string sDB, string sVar, object oPlr = OBJECT_INVALID) { if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_GetDBVars(sDB, sVar, TTL_TYPE_STRING)) { case TTL_TYPE_NOTFOUND: SetLocalString(TTL_MON, "~DB~" + sDB + "~VN~" + sVar, GetCampaignString(sDB, sVar)); case TTL_TYPE_STRING: return GetLocalString(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; default: return ""; break; } return ""; } //Include ttl_campaign_inc in your scripts, then //Replace every instance of GetCampaignLocation with TTL_GetCampaignLocation //And have more efficient DB access... location TTL_GetCampaignLocation(string sDB, string sVar, object oPlr = OBJECT_INVALID) { if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_GetDBVars(sDB, sVar, TTL_TYPE_LOCATION)) { case TTL_TYPE_NOTFOUND: SetLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar, GetCampaignLocation(sDB, sVar)); case TTL_TYPE_LOCATION: return GetLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; default: return Location(OBJECT_INVALID, Vector(0.0, 0.0, 0.0), 0.0); break; } return Location(OBJECT_INVALID, Vector(0.0, 0.0, 0.0), 0.0); } //Include ttl_campaign_inc in your scripts, then //Replace every instance of GetCampaignVector with TTL_GetCampaignVector //And have more efficient DB access... vector TTL_GetCampaignVector(string sDB, string sVar, object oPlr = OBJECT_INVALID) { if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_GetDBVars(sDB, sVar, TTL_TYPE_VECTOR)) { case TTL_TYPE_NOTFOUND: SetLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar, Location(TTL_AREA, GetCampaignVector(sDB, sVar), 0.0)); case TTL_TYPE_VECTOR: return GetPositionFromLocation(GetLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); break; default: return Vector(0.0, 0.0, 0.0); break; } return Vector(0.0, 0.0, 0.0); } //Include ttl_campaign_inc in your scripts, then //Replace every instance of RetrieveCampaignObject with TTL_RetrieveCampaignObject //And have more efficient DB access... object TTL_RetrieveCampaignObject(string sDB, string sVar, location lLoc, object oOwner = OBJECT_INVALID, object oPlr = OBJECT_INVALID) { object oObject; if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_GetDBVars(sDB, sVar, TTL_TYPE_OBJECT)) { case TTL_TYPE_NOTFOUND: oObject = RetrieveCampaignObject(sDB, sVar, TTL_LOC, TTL_MON); ApplyEffectToObject(DURATION_TYPE_PERMANENT, ExtraordinaryEffect(EffectPetrify()), oObject); SetLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar, oObject); case TTL_TYPE_OBJECT: return CopyObject(GetLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar), lLoc, oOwner); break; default: return OBJECT_INVALID; break; } return OBJECT_INVALID; } //Include ttl_campaign_inc in your scripts, then //Replace every instance of SetCampaignInt with TTL_SetCampaignInt //And have more efficient DB access... void TTL_SetCampaignInt(string sDB, string sVar, int iVal, object oPlr = OBJECT_INVALID) { if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_SetDBVars(sDB, sVar, TTL_TYPE_INT)) { case TTL_TYPE_INT: break; case TTL_TYPE_FLOAT: DeleteLocalFloat(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_STRING: DeleteLocalString(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_LOCATION: case TTL_TYPE_VECTOR: DeleteLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_OBJECT: DestroyObject(GetLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); DeleteLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; } SetLocalInt(TTL_MON, "~DB~" + sDB + "~VN~" + sVar, iVal); if(TTL_ISDBCACHE)TTL_DBCache(sDB, sVar); else SetCampaignInt(sDB, sVar, iVal); } //Include ttl_campaign_inc in your scripts, then //Replace every instance of SetCampaignFloat with TTL_SetCampaignFloat //And have more efficient DB access... void TTL_SetCampaignFloat(string sDB, string sVar, float fVal, object oPlr = OBJECT_INVALID) { if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_SetDBVars(sDB, sVar, TTL_TYPE_FLOAT)) { case TTL_TYPE_INT: DeleteLocalInt(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_FLOAT: break; case TTL_TYPE_STRING: DeleteLocalString(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_LOCATION: case TTL_TYPE_VECTOR: DeleteLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_OBJECT: DestroyObject(GetLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); DeleteLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; } SetLocalFloat(TTL_MON, "~DB~" + sDB + "~VN~" + sVar, fVal); if(TTL_ISDBCACHE)TTL_DBCache(sDB, sVar); else SetCampaignFloat(sDB, sVar, fVal); } //Include ttl_campaign_inc in your scripts, then //Replace every instance of SetCampaignString with TTL_SetCampaignString //And have more efficient DB access... void TTL_SetCampaignString(string sDB, string sVar, string sVal, object oPlr = OBJECT_INVALID) { if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_SetDBVars(sDB, sVar, TTL_TYPE_STRING)) { case TTL_TYPE_INT: DeleteLocalInt(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_FLOAT: DeleteLocalFloat(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_STRING: break; case TTL_TYPE_LOCATION: case TTL_TYPE_VECTOR: DeleteLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_OBJECT: DestroyObject(GetLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); DeleteLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; } SetLocalString(TTL_MON, "~DB~" + sDB + "~VN~" + sVar, sVal); if(TTL_ISDBCACHE)TTL_DBCache(sDB, sVar); else SetCampaignString(sDB, sVar, sVal); } //Include ttl_campaign_inc in your scripts, then //Replace every instance of SetCampaignLocation with TTL_SetCampaignLocation //And have more efficient DB access... void TTL_SetCampaignLocation(string sDB, string sVar, location lVal, object oPlr = OBJECT_INVALID) { if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_SetDBVars(sDB, sVar, TTL_TYPE_LOCATION)) { case TTL_TYPE_INT: DeleteLocalInt(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_FLOAT: DeleteLocalFloat(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_STRING: DeleteLocalString(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_LOCATION: case TTL_TYPE_VECTOR: break; case TTL_TYPE_OBJECT: DestroyObject(GetLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); DeleteLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; } SetLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar, lVal); if(TTL_ISDBCACHE)TTL_DBCache(sDB, sVar); else SetCampaignLocation(sDB, sVar, lVal); } //Include ttl_campaign_inc in your scripts, then //Replace every instance of SetCampaignVector with TTL_SetCampaignVector //And have more efficient DB access... void TTL_SetCampaignVector(string sDB, string sVar, vector vVal, object oPlr = OBJECT_INVALID) { if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_SetDBVars(sDB, sVar, TTL_TYPE_VECTOR)) { case TTL_TYPE_INT: DeleteLocalInt(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_FLOAT: DeleteLocalFloat(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_STRING: DeleteLocalString(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_LOCATION: case TTL_TYPE_VECTOR: break; case TTL_TYPE_OBJECT: DestroyObject(GetLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); DeleteLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; } SetLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar, Location(TTL_AREA, vVal, 0.0)); if(TTL_ISDBCACHE)TTL_DBCache(sDB, sVar); else SetCampaignVector(sDB, sVar, vVal); } //Include ttl_campaign_inc in your scripts, then //Replace every instance of StoreCampaignObject with TTL_StoreCampaignObject //And have more efficient DB access... int TTL_StoreCampaignObject(string sDB, string sVar, object oObj, object oPlr = OBJECT_INVALID) { object oObject; if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_SetDBVars(sDB, sVar, TTL_TYPE_OBJECT)) { case TTL_TYPE_INT: DeleteLocalInt(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_FLOAT: DeleteLocalFloat(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_STRING: DeleteLocalString(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_LOCATION: case TTL_TYPE_VECTOR: DeleteLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_OBJECT: DestroyObject(GetLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); break; } oObject = CopyObject(oObj, TTL_LOC); ApplyEffectToObject(DURATION_TYPE_PERMANENT, ExtraordinaryEffect(EffectPetrify()), oObject); SetLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar, oObject); if(TTL_ISDBCACHE)TTL_DBCache(sDB, sVar); else return StoreCampaignObject(sDB, sVar, oObj); return 1; } void TTL_DeleteCampaignVariable(string sDB, string sVar, object oPlr = OBJECT_INVALID) { sVar = TTL_UniqueCampaignVar(sVar); if(GetIsPC(oPlr))sVar = sVar + "~NM~" + GetName(oPlr) + "~PN~" + GetPCPlayerName(oPlr); sVar = TTL_UniqueCampaignVar(sVar); switch (TTL_SetDBVars(sDB, sVar, TTL_TYPE_DELETED)) { case TTL_TYPE_INT: DeleteLocalInt(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_FLOAT: DeleteLocalFloat(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_STRING: DeleteLocalString(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_LOCATION: case TTL_TYPE_VECTOR: DeleteLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_OBJECT: DestroyObject(GetLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); DeleteLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; } if(TTL_ISDBCACHE)TTL_DBCache(sDB, sVar); else DeleteCampaignVariable(sDB, sVar); } void TTL_DestroyCampaignDatabase(string sDB) { string sVarsInDB = GetLocalString(TTL_MON, "~DB~" + sDB); string sVar; int iVPos; sVarsInDB = GetStringRight(sVarsInDB, GetStringLength(sVarsInDB) - 2); while(GetStringLength(sVarsInDB)) { iVPos = FindSubString(sVarsInDB, "~TP~"); sVar = GetStringLeft(sVarsInDB, iVPos); switch (StringToInt(GetSubString(sVarsInDB, iVPos + 2, 1))) { case TTL_TYPE_INT: DeleteLocalInt(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_FLOAT: DeleteLocalFloat(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_STRING: DeleteLocalString(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_LOCATION: case TTL_TYPE_VECTOR: DeleteLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; case TTL_TYPE_OBJECT: DestroyObject(GetLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); DeleteLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar); break; } sVarsInDB = GetStringRight(sVarsInDB, GetStringLength(sVarsInDB) - iVPos - 9); } DeleteLocalString(TTL_MON, "~DB~" + sDB); SetLocalInt(TTL_MON, "~DX~" + sDB, TRUE); if(TTL_ISDBCACHE)TTL_DBCacheDestroyDB(sDB); else DestroyCampaignDatabase(sDB); } //Made to solve NWN DB's Var Name limit of 32 chars. //Assigns a unique campaign database variable name if the variable name //is greater than 30 letters... //(max of 4096 unique names for every vars with same initial 29 chars.. it should never run out!!!) // I HOPE... LOL //Solves the problem with trying to use Long Var name for DBs //e.g. GetName or GetPCPlayerName for a player with loooong names.. LOL...it works.. I rock ;) string TTL_UniqueCampaignVar(string sVar) { if(iInUnq || GetStringLength(sVar)<=30)return sVar; iInUnq = TRUE; int i; string sUnq; string sVar30 = GetStringLeft(sVar, 30); int iUnqs = TTL_GetCampaignInt(TTL_DB, sVar30); for(i = 1; i<= iUnqs; i++) { sUnq = TTL_IntToUnq(i - 1); if(sVar == TTL_GetCampaignString(TTL_DB, sVar30 + sUnq))break; } if(i > iUnqs) { sUnq = TTL_IntToUnq(i - 1); TTL_SetCampaignInt(TTL_DB, sVar30, i); TTL_SetCampaignString(TTL_DB, sVar30 + sUnq, sVar); } iInUnq = FALSE; return sVar30 + sUnq; } //Integer to Unq (unique last 2 variable characters, uses 0-9, a-z, A-Z, symbols @# //with 0 = 00 and 4095 = ##... I really really don't think I need more.. //Though I could make more... I really really don't think I need more.. (no negatives please... absolutes only) string TTL_IntToUnq(int iUnq) { int iRightChar = iUnq % 64; int iLeftChar = iUnq / 64; return TTL_IntToUnqChar(iLeftChar) + TTL_IntToUnqChar(iRightChar); } //Second part of my Int To Unq function - no negatives please... string TTL_IntToUnqChar(int iUnqChar) { return GetSubString("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@#", iUnqChar, 1); } //Tracks Vars in Local DB int TTL_GetDBVars(string sDB, string sVar, int iType) { if(GetLocalInt(TTL_MON, "~DX~" + sDB)) { return TTL_TYPE_NOTFOUND; } string sVarsInDB = GetLocalString(TTL_MON, "~DB~" + sDB); int iVPos = FindSubString(sVarsInDB, "~VN~" + sVar + "~TP~"); if(iVPos >=0) { return StringToInt(GetSubString(sVarsInDB, iVPos + GetStringLength(sVar) + 8, 1)); } SetLocalString(TTL_MON, "~DB~" + sDB, sVarsInDB + "~VN~" + sVar + "~TP~" + IntToString(iType)); return TTL_TYPE_NOTFOUND; } //Tracks Vars in Local DB int TTL_SetDBVars(string sDB, string sVar, int iType) { if(GetLocalInt(TTL_MON, "~DX~" + sDB)) { DeleteLocalInt(TTL_MON, "~DX~" + sDB); SetLocalString(TTL_MON, "~DB~" + sDB, "~VN~" + sVar + "~TP~" + IntToString(iType)); return TTL_TYPE_NOTFOUND; } string sVarsInDB = GetLocalString(TTL_MON, "~DB~" + sDB); int iVPos = FindSubString(sVarsInDB, "~VN~" + sVar + "~TP~"); int iOldType; //Readability.. LOL if(iVPos >=0) { iVPos = iVPos + GetStringLength(sVar) + 8; iOldType = StringToInt(GetSubString(sVarsInDB, iVPos, 1)); sVarsInDB = GetStringLeft(sVarsInDB,iVPos) + IntToString(iType) + GetStringRight(sVarsInDB,GetStringLength(sVarsInDB)-iVPos-1); return iOldType; } SetLocalString(TTL_MON, "~DB~" + sDB, sVarsInDB + "~VN~" + sVar + "~TP~" + IntToString(iType)); return TTL_TYPE_NOTFOUND; } //WOOT! Caching! Skips old writes to same DB & Var... void TTL_DBCache(string sDB, string sVar) { int iDBWrites = GetLocalInt(TTL_MON, "iDBWrites"); int iSkips = GetLocalInt(TTL_MON, "iSkips"); DeleteLocalInt(TTL_MON, "iSkips"); int iFirstValidWrite = iSkips + 1; int i, iVPos; string sTempWrite; string sThisWrite = sDB + "~XX~" + sVar; for(i = iFirstValidWrite; i <= iDBWrites; i++) { sTempWrite = GetLocalString(TTL_MON, "sDBCache" + IntToString(i)); if(sThisWrite == sTempWrite)iSkips++; else if(iSkips>0)SetLocalString(TTL_MON, "sDBCache" + IntToString(i - iSkips),sTempWrite); } iDBWrites = iDBWrites - iSkips + 1; SetLocalInt(TTL_MON, "iDBWrites", iDBWrites); SetLocalString(TTL_MON, "sDBCache" + IntToString(iDBWrites), sThisWrite); if(iDBWrites > TTL_MAXCACHE) TTL_DBWriteOldCache(TTL_MAXCACHE - iDBWrites);//Should always be 1.. but.. what the heck.. } void TTL_DBCacheDestroyDB(string sDB) { int iDBWrites = GetLocalInt(TTL_MON, "iDBWrites"); int iSkips = GetLocalInt(TTL_MON, "iSkips"); DeleteLocalInt(TTL_MON, "iSkips"); int iFirstValidWrite = iSkips + 1; int i, iVPos; string sTempWrite; string sThisWrite = sDB + "~XX~"; for(i = iFirstValidWrite; i <= iDBWrites; i++) { sTempWrite = GetLocalString(TTL_MON, "sDBCache" + IntToString(i)); if(FindSubString(sTempWrite, sThisWrite) == 0)iSkips++; else if(iSkips>0)SetLocalString(TTL_MON, "sDBCache" + IntToString(i - iSkips),sTempWrite); } iDBWrites = iDBWrites - iSkips + 1; SetLocalInt(TTL_MON, "iDBWrites", iDBWrites); SetLocalString(TTL_MON, "sDBCache" + IntToString(iDBWrites), sThisWrite + "~~OBLITERATE~~"); if(iDBWrites > TTL_MAXCACHE) TTL_DBWriteOldCache(TTL_MAXCACHE - iDBWrites);//Should always be 1.. but.. what the heck.. } void TTL_DBWriteOldCache(int iToWrite) { int i, iVPos; int iSkips = GetLocalInt(TTL_MON, "iSkips"); int iFirstValidWrite = iSkips + 1; iSkips = iSkips + iToWrite; int iDBWrites = GetLocalInt(TTL_MON, "iDBWrites"); if(iSkips > iDBWrites)iSkips = iDBWrites; string sDB, sVar, sTempWrite; for(i = iFirstValidWrite; i <= iSkips; i++) { sTempWrite = GetLocalString(TTL_MON, "sDBCache" + IntToString(i)); iVPos = FindSubString(sTempWrite, "~XX~"); sDB = GetStringLeft(sTempWrite, iVPos); sVar = GetStringRight(sTempWrite, GetStringLength(sTempWrite) -iVPos - 4); if(sVar == "~~OBLITERATE~~") { DestroyCampaignDatabase(sDB); } else { switch (TTL_GetDBVars(sDB, sVar, TTL_TYPE_LOCATION)) { case TTL_TYPE_INT: SetCampaignInt(sDB, sVar, GetLocalInt(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); break; case TTL_TYPE_FLOAT: SetCampaignFloat(sDB, sVar, GetLocalFloat(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); break; case TTL_TYPE_STRING: SetCampaignString(sDB, sVar, GetLocalString(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); break; case TTL_TYPE_LOCATION: SetCampaignLocation(sDB, sVar, GetLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); break; case TTL_TYPE_VECTOR: SetCampaignVector(sDB, sVar, GetPositionFromLocation(GetLocalLocation(TTL_MON, "~DB~" + sDB + "~VN~" + sVar))); break; case TTL_TYPE_OBJECT: StoreCampaignObject(sDB, sVar, GetLocalObject(TTL_MON, "~DB~" + sDB + "~VN~" + sVar)); break; case TTL_TYPE_DELETED: DeleteCampaignVariable(sDB, sVar); break; } } } if(iSkips == iDBWrites) { DeleteLocalInt(TTL_MON, "iDBWrites"); DeleteLocalInt(TTL_MON, "iSkips"); } else SetLocalInt(TTL_MON, "iSkips", iSkips); } void TTL_DBClearCache() { TTL_DBWriteOldCache(GetLocalInt(TTL_MON, "iDBWrites")); }