// Created by Zunath #include "inc_system_const" #include "inc_mysql_tables" #include "colors_inc" /////////////// // CONSTANTS // /////////////// // Absolute limit to the number of items a single bank table can hold. // By default, this is 100. Not sure what the exact limit is, but I wouldn't // try raising this too much or you'll get some lag when PCs open their banks. const int BANK_HARD_ITEM_CAP = 100; //////////////////// // BANK FUNCTIONS // //////////////////// // Returns oPC's unique ID number. int BANK_GetPCIDNumber(object oPC); // Creates bank tables if they do not exist in the MySQL // database. Call this on module load. void BANK_CreateTables(); // Returns the max number of items oPC can store in bank // sBank. int BANK_GetPCMaxSize(object oPC, string sBank); // Checks PC's bank list to see if their max item size is at least // 10. If it is lower, then they are set to 10. This is done for // each bank in the game. // Call this function on module client enter void BANK_UpdatePCBankList(object oPC); // Removes all stored item data from bank table sTable. // This is called when a PC dies, or when PC is adding/removing // new items. void BANK_RemovePCBankData(object oPC, string sTable); // Cycles through bank placeable and stores items in the database. // If PC's max item limit is reached, all items afterwards are returned // to their inventory. // If no items are in the container, nothing is stored void BANK_UpdatePCBank(object oPC, object oBank); // Call on the bank terminal's OnOpen event. // Loads stored bank items and locks terminal so that other PCs cannot steal // user's items. void BANK_BankOnOpened(); // Call on the bank terminal's OnClosed event. // Destroys all of the bank;s inventory items and unlocks it for the next PC's use. void BANK_BankOnClosed(); // Sets oPC's item limit for sBank to iLimit. // oPC must be a player object // sBank must be a valid bank table name (in MySQL) // iLimit must be the new item limit for oPC. // NOTE: Do not set LOWER than PC's current item limit or they may lose items // NOTE 2: If iLimit is set lower than 1, it will be set to 1. If it is set above the cap, // it will be set to the cap. (Determined by BANK_HARD_ITEM_CAP constant above) void BANK_SetPCBankLimit(object oPC, string sBank, int iLimit); // Internal function - Creates the necessary code to make // a new bank table. Do not call this on its own. void BANK_CreateTable(string sTableName); ///////////////////////////////////////////////////////////// int BANK_GetPCIDNumber(object oPC) { object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE); return GetLocalInt(oDatabase, PC_ID_NUMBER); } int BANK_GetPCMaxSize(object oPC, string sBank) { object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE); int iAmount = GetLocalInt(oDatabase, sBank); return iAmount; } void BANK_UpdatePCBankList(object oPC) { object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE); if(GetLocalInt(oDatabase, "BANK_INGLES_WAREHOUSE") < 5) { SetLocalInt(oDatabase, "BANK_INGLES_WAREHOUSE", 5); } if(GetLocalInt(oDatabase, "BANK_UBCS_CAMPSITE") < 5) { SetLocalInt(oDatabase, "BANK_UBCS_CAMPSITE", 5); } } void BANK_RemovePCBankData(object oPC, string sTable) { int iID = BANK_GetPCIDNumber(oPC); string sSQL = "DELETE FROM " + sTable + " WHERE ID=" + IntToString(iID) + ";"; SQLExecDirect(sSQL); } void BANK_UpdatePCBank(object oPC, object oBank) { string sTable = GetTag(oBank); int iMaxItems = BANK_GetPCMaxSize(oPC, sTable); int iID = BANK_GetPCIDNumber(oPC); string sSQL = "INSERT INTO " + sTable + "(ID, Name, Account, CDKey) VALUES (" + IntToString(iID) + ", '" + SQLEncodeSpecialChars(GetName(oPC)) + "', '" + SQLEncodeSpecialChars(GetPCPlayerName(oPC)) + "', '" + GetPCPublicCDKey(oPC) + "')"; int iCurItem = 1; int iReachedLimit = FALSE; // First remove existing data BANK_RemovePCBankData(oPC, sTable); // Cycle through bank inventory and store items object oItem = GetFirstItemInInventory(oBank); while(GetIsObjectValid(oItem)) { // Haven't reached the limit yet. if(iMaxItems >= iCurItem) { // Create a new row using their ID, if this is the first item in the bank if(iCurItem == 1) { SQLExecDirect(sSQL); } sSQL = "UPDATE " + sTable + " SET Item" + IntToString(iCurItem) + "=%s WHERE ID=" + IntToString(iID) + ";"; SetLocalString(GetModule(), "NWNX!ODBC!SETSCORCOSQL", sSQL); StoreCampaignObject ("NWNX", "-", oItem); } // Reached the limit - return the item else { AssignCommand(oBank, ActionGiveItem(oItem, oPC)); iReachedLimit = TRUE; } // Add one to the tally and move to the next item in bank's inventory iCurItem = iCurItem + 1; oItem = GetNextItemInInventory(oBank); } if(iReachedLimit == TRUE) { SendMessageToPC(oPC, ColorTokenRed() + "You have reached your item limit for this item box. Excess items have been returned to you." + ColorTokenEnd()); } else { SendMessageToPC(oPC, ColorTokenWhite() + "Item Limit: " + IntToString(iCurItem-1) + " / " + ColorTokenRed() + IntToString(iMaxItems)); } } void BANK_BankOnOpened() { object oBank = OBJECT_SELF; object oPC = GetLastOpenedBy(); object oItem; string sBank = GetTag(oBank); string sSQL; int iCurItem = 1; int iMaxItems = BANK_GetPCMaxSize(oPC, sBank); int iID = BANK_GetPCIDNumber(oPC); // Locks bank so other PC's can't steal player's items SetLocked(oBank, TRUE); // Load all bank items into bank terminal's inventory while(iCurItem <= iMaxItems) { sSQL = "SELECT Item" + IntToString(iCurItem) + " FROM " + sBank + " WHERE ID=" + IntToString(iID) +";"; SetLocalString(GetModule(), "NWNX!ODBC!SETSCORCOSQL", sSQL); oItem = RetrieveCampaignObject ("NWNX", "-", GetLocation(oBank), oBank); // No need to keep checking the table - there are no more items being stored at the moment if(!GetIsObjectValid(oItem)){break;} // Prevent duplication of items in containers if(GetHasInventory(oItem)) { object oCycle = GetFirstItemInInventory(oItem); while(GetIsObjectValid(oCycle)) { DestroyObject(oCycle); oCycle = GetNextItemInInventory(oItem); } } iCurItem = iCurItem + 1; } // Inform player of how to quit banking SendMessageToPC(oPC, "To quit storing items, walk away from the item box."); } void BANK_BankOnClosed() { object oBank = OBJECT_SELF; object oPC = GetLastClosedBy(); object oInventory = GetFirstItemInInventory(); while(GetIsObjectValid(oInventory)) { DestroyObject(oInventory); oInventory = GetNextItemInInventory(); } // Allow another PC to use it. SetLocked(oBank, FALSE); } void BANK_SetPCBankLimit(object oPC, string sBank, int iLimit) { object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE); // Prevent from going out of the 1-BANK_HARD_ITEM_CAP range if(iLimit < 1){iLimit = 1;} else if(iLimit > BANK_HARD_ITEM_CAP){iLimit = BANK_HARD_ITEM_CAP;} SetLocalInt(oDatabase, sBank, iLimit); } void BANK_CreateTable(string sTableName) { // Table exists - cancel if(DoesMySQLTableExist(sTableName)){return;} int iLoop; string sSQL = "CREATE TABLE `" + sTableName + "` (" + "`ID` INTEGER NULL," + "`Name` TEXT DEFAULT NULL," + "`Account` TEXT DEFAULT NULL," + "`CDKey` TEXT DEFAULT NULL," + "PRIMARY KEY (`ID`))" + "ENGINE = MyISAM;"; SQLExecDirect(sSQL); sSQL = "ALTER TABLE `" + sTableName + "` ADD COLUMN `Item1` BLOB DEFAULT NULL AFTER `CDKey`;"; SQLExecDirect(sSQL); // Now cycle through, creating more columns until the hard cap is reached. // Probably not the most efficient way, but a single create table call only got me // to 50 items. for(iLoop = 1; iLoop <= BANK_HARD_ITEM_CAP; iLoop++) { sSQL = "ALTER TABLE `" + sTableName + "` ADD COLUMN `Item" + IntToString(iLoop) + "` BLOB DEFAULT NULL AFTER `Item" + IntToString(iLoop-1) + "`;"; SQLExecDirect(sSQL); } } void BANK_CreateTables() { // Add more tables as more banks are created BANK_CreateTable("BANK_INGLES_WAREHOUSE"); BANK_CreateTable("BANK_UBCS_CAMPSITE"); } // Error checking //void main(){}