From ecd695ff9b40a389a7708d0761e98fd6cfd26f18 Mon Sep 17 00:00:00 2001 From: Uleat Date: Fri, 9 Oct 2015 21:34:31 -0400 Subject: [PATCH] Script and server code query updates for bots_updater --- common/database.cpp | 8 +- common/database.h | 1 - common/database_conversions.cpp | 158 --- common/guild_base.cpp | 16 +- common/ruletypes.h | 18 +- common/shareddb.cpp | 29 +- common/shareddb.h | 7 +- .../sql/git/bots/bots_db_update_manifest.txt | 2 +- .../drop_bots (pre-update script).sql | 88 ++ utils/sql/git/bots/drop_bots.sql | 119 +- .../sql/git/bots/required/2015_09_30_bots.sql | 959 ++++++++++---- zone/bot.cpp | 1110 ++++++++++++----- zone/botspellsai.cpp | 2 +- zone/questmgr.cpp | 8 +- 14 files changed, 1722 insertions(+), 803 deletions(-) create mode 100644 utils/sql/git/bots/deprecated/drop_bots (pre-update script).sql diff --git a/common/database.cpp b/common/database.cpp index 570bcbb43..475b48258 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -348,11 +348,11 @@ bool Database::DeleteCharacter(char *name) { query = StringFormat("DELETE FROM `character_inspect_messages` WHERE `id` = %u", charid); QueryDatabase(query); query = StringFormat("DELETE FROM `character_leadership_abilities` WHERE `id` = %u", charid); QueryDatabase(query); query = StringFormat("DELETE FROM `character_alt_currency` WHERE `char_id` = '%d'", charid); QueryDatabase(query); -#ifdef BOTS - query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d' AND GetMobTypeById(%i) = 'C'", charid); -#else +#ifdef BOTS + query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d' AND GetMobTypeById(%i) = 'C'", charid); // note: only use of GetMobTypeById() +#else query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d'", charid); -#endif +#endif QueryDatabase(query); return true; diff --git a/common/database.h b/common/database.h index 1543a14e3..c3771f67c 100644 --- a/common/database.h +++ b/common/database.h @@ -209,7 +209,6 @@ public: /* Database Conversions 'database_conversions.cpp' */ bool CheckDatabaseConversions(); - bool CheckDatabaseConvertBotsPostPPDeblob(); bool CheckDatabaseConvertCorpseDeblob(); bool CheckDatabaseConvertPPDeblob(); diff --git a/common/database_conversions.cpp b/common/database_conversions.cpp index c3c54cde5..aa772c8b1 100644 --- a/common/database_conversions.cpp +++ b/common/database_conversions.cpp @@ -470,7 +470,6 @@ static inline void loadbar(unsigned int x, unsigned int n, unsigned int w = 50) bool Database::CheckDatabaseConversions() { CheckDatabaseConvertPPDeblob(); - CheckDatabaseConvertBotsPostPPDeblob(); CheckDatabaseConvertCorpseDeblob(); /* Fetch Automatic Upgrade Script */ @@ -1491,163 +1490,6 @@ bool Database::CheckDatabaseConvertPPDeblob(){ return true; } -bool Database::CheckDatabaseConvertBotsPostPPDeblob(){ -#ifdef BOTS - int runbotsconvert = 0; - - /* Check For Legacy Bot References */ - std::string rquery = StringFormat("SHOW CREATE VIEW `vwBotCharacterMobs`"); - auto results = QueryDatabase(rquery); - if (results.RowCount() == 1){ - auto row = results.begin(); - std::string table_check = row[1]; - - if (table_check.find("character_data") == -1){ - runbotsconvert = 1; - printf("\n\n::: Legacy Bot Views and Function Detected... \n"); - printf("----------------------------------------------------------\n\n"); - printf(" Database currently has bot view/function linkage to obselete \n"); - printf(" table references and will now be converted...\n\n"); - printf(" It is recommended that you backup your database \n"); - printf(" before continuing the automatic conversion process...\n\n"); - printf("----------------------------------------------------------\n\n"); - std::cout << "Press ENTER to continue....." << std::endl << std::endl; - std::cin.ignore(1); - } - } - - if (runbotsconvert == 1){ - printf("Running bot views/function database conversion... \n"); - - /* Update view `vwbotcharactermobs` */ - rquery = StringFormat("DROP VIEW `vwBotCharacterMobs`;"); - results = QueryDatabase(rquery); - - rquery = StringFormat( - "CREATE VIEW `vwBotCharacterMobs` AS\n" - "SELECT _utf8'C' AS mobtype,\n" // Natedog: '_utf8' - "c.`id`,\n" - "c.`name`,\n" - "c.`class`,\n" - "c.`level`,\n" - "c.`last_login`,\n" - "c.`zone_id`\n" - "FROM `character_data` AS c\n" - "UNION ALL\n" - "SELECT _utf8'B' AS mobtype,\n" // Natedog: '_utf8' - "b.`BotID` AS id,\n" - "b.`Name` AS name,\n" - "b.`Class` AS class,\n" - "b.`BotLevel` AS level,\n" - "0 AS timelaston,\n" - "0 AS zoneid\n" - "FROM bots AS b;" - ); - results = QueryDatabase(rquery); - - - /* Update function `GetMobType` */ - rquery = StringFormat("DROP FUNCTION IF EXISTS `GetMobType`;"); - results = QueryDatabase(rquery); - - rquery = StringFormat( - "CREATE FUNCTION `GetMobType` (mobname VARCHAR(64)) RETURNS CHAR(1)\n" - "BEGIN\n" - " DECLARE Result CHAR(1);\n" - "\n" - " SET Result = NULL;\n" - "\n" - " IF (SELECT COUNT(*) FROM `character_data` WHERE `name` = mobname) > 0 THEN\n" - " SET Result = 'C';\n" - " ELSEIF (SELECT COUNT(*) FROM `bots` WHERE `Name` = mobname) > 0 THEN\n" - " SET Result = 'B';\n" - " END IF;\n " - "\n" - " RETURN Result;\n" - "END" - ); - results = QueryDatabase(rquery); - - - /* Update view `vwgroups` */ - rquery = StringFormat("DROP VIEW IF EXISTS `vwGroups`;"); - results = QueryDatabase(rquery); - - rquery = StringFormat( - "CREATE VIEW `vwGroups` AS\n" - "SELECT g.`groupid` AS groupid,\n" - "GetMobType(g.`name`) AS mobtype,\n" - "g.`name` AS name,\n" - "g.`charid` AS mobid,\n" - "IFNULL(c.`level`, b.`BotLevel`) AS level\n" - "FROM `group_id` AS g\n" - "LEFT JOIN `character_data` AS c ON g.`name` = c.`name`\n" - "LEFT JOIN `bots` AS b ON g.`name` = b.`Name`;" - ); - results = QueryDatabase(rquery); - - - /* Update view `vwbotgroups` */ - rquery = StringFormat("DROP VIEW IF EXISTS `vwBotGroups`;"); - results = QueryDatabase(rquery); - - rquery = StringFormat( - "CREATE VIEW `vwBotGroups` AS\n" - "SELECT g.`BotGroupId`,\n" - "g.`BotGroupName`,\n" - "g.`BotGroupLeaderBotId`,\n" - "b.`Name` AS BotGroupLeaderName,\n" - "b.`BotOwnerCharacterId`,\n" - "c.`name` AS BotOwnerCharacterName\n" - "FROM `botgroup` AS g\n" - "JOIN `bots` AS b ON g.`BotGroupLeaderBotId` = b.`BotID`\n" - "JOIN `character_data` AS c ON b.`BotOwnerCharacterID` = c.`id`\n" - "ORDER BY b.`BotOwnerCharacterId`, g.`BotGroupName`;" - ); - results = QueryDatabase(rquery); - - - /* Update view `vwguildmembers` */ - rquery = StringFormat("DROP VIEW IF EXISTS `vwGuildMembers`;"); - results = QueryDatabase(rquery); - - rquery = StringFormat( - "CREATE VIEW `vwGuildMembers` AS\n" - "SELECT 'C' AS mobtype,\n" - "cm.`char_id`,\n" - "cm.`guild_id`,\n" - "cm.`rank`,\n" - "cm.`tribute_enable`,\n" - "cm.`total_tribute`,\n" - "cm.`last_tribute`,\n" - "cm.`banker`,\n" - "cm.`public_note`,\n" - "cm.`alt`\n" - "FROM `guild_members` AS cm\n" - "UNION ALL\n" - "SELECT 'B' AS mobtype,\n" - "bm.`char_id`,\n" - "bm.`guild_id`,\n" - "bm.`rank`,\n" - "bm.`tribute_enable`,\n" - "bm.`total_tribute`,\n" - "bm.`last_tribute`,\n" - "bm.`banker`,\n" - "bm.`public_note`,\n" - "bm.`alt`\n" - "FROM `botguildmembers` AS bm;" - ); - results = QueryDatabase(rquery); - } - - if (runbotsconvert == 1){ - printf("\n\nBot views/function conversion complete, continuing world bootup...\n"); - } - -#endif - return true; -} - bool Database::CheckDatabaseConvertCorpseDeblob(){ Convert::DBPlayerCorpse_Struct_temp* dbpc; Convert::classic_db_temp::DBPlayerCorpse_Struct_temp* dbpc_c; diff --git a/common/guild_base.cpp b/common/guild_base.cpp index bfd9f4126..58e7675c5 100644 --- a/common/guild_base.cpp +++ b/common/guild_base.cpp @@ -867,16 +867,16 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) { //factored out so I dont have to copy this crap. #ifdef BOTS #define GuildMemberBaseQuery \ -"SELECT c.id,c.name,c.class,c.level,c.last_login,c.zone_id," \ -" g.guild_id,g.rank,g.tribute_enable,g.total_tribute,g.last_tribute," \ -" g.banker,g.public_note,g.alt" \ -" FROM vwBotCharacterMobs AS c LEFT JOIN vwGuildMembers AS g ON c.id=g.char_id AND c.mobtype = g.mobtype " +"SELECT c.`id`, c.`name`, c.`class`, c.`level`, c.`last_login`, c.`zone_id`," \ +" g.`guild_id`, g.`rank`, g.`tribute_enable`, g.`total_tribute`, g.`last_tribute`," \ +" g.`banker`, g.`public_note`, g.`alt`" \ +" FROM `vw_bot_character_mobs` AS c LEFT JOIN `vw_guild_members` AS g ON c.`id` = g.`char_id` AND c.`mob_type` = g.`mob_type` " #else #define GuildMemberBaseQuery \ -"SELECT c.id,c.name,c.class,c.level,c.last_login,c.zone_id," \ -" g.guild_id,g.rank,g.tribute_enable,g.total_tribute,g.last_tribute," \ -" g.banker,g.public_note,g.alt " \ -" FROM `character_data` AS c LEFT JOIN guild_members AS g ON c.id=g.char_id " +"SELECT c.`id`, c.`name`, c.`class`, c.`level`, c.`last_login`, c.`zone_id`," \ +" g.`guild_id`, g.`rank`, g.`tribute_enable`, g.`total_tribute`, g.`last_tribute`," \ +" g.`banker`, g.`public_note`, g.`alt` " \ +" FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` " #endif static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) { //fields from `characer_` diff --git a/common/ruletypes.h b/common/ruletypes.h index 8cb2ed0db..1b4baa371 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -502,16 +502,16 @@ RULE_CATEGORY_END() #ifdef BOTS RULE_CATEGORY(Bots) -RULE_REAL(Bots, BotManaRegen, 2.0) // Adjust mana regen for bots, 1 is fast and higher numbers slow it down 3 is about the same as players. -RULE_BOOL(Bots, BotFinishBuffing, false) // Allow for buffs to complete even if the bot caster is out of mana. Only affects buffing out of combat. -RULE_INT(Bots, CreateBotCount, 150) // Number of bots that each account can create -RULE_INT(Bots, SpawnBotCount, 71) // Number of bots a character can have spawned at one time, You + 71 bots is a 12 group raid -RULE_BOOL(Bots, BotQuest, false) // Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl -RULE_BOOL(Bots, BotGroupBuffing, false) // Bots will cast single target buffs as group buffs, default is false for single. Does not make single target buffs work for MGB. -RULE_BOOL(Bots, BotSpellQuest, false) // Anita Thrall's (Anita_Thrall.pl) Bot Spell Scriber quests. -RULE_INT(Bots, BotAAExpansion, 8) // Bots get AAs through this expansion +RULE_INT(Bots, AAExpansion, 8) // Bots get AAs through this expansion +RULE_INT(Bots, CreationLimit, 150) // Number of bots that each account can create +RULE_BOOL(Bots, FinishBuffing, false) // Allow for buffs to complete even if the bot caster is out of mana. Only affects buffing out of combat. +RULE_BOOL(Bots, GroupBuffing, false) // Bots will cast single target buffs as group buffs, default is false for single. Does not make single target buffs work for MGB. +RULE_REAL(Bots, ManaRegen, 2.0) // Adjust mana regen for bots, 1 is fast and higher numbers slow it down 3 is about the same as players. +RULE_BOOL(Bots, QuestableSpawnLimit, false) // Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl +RULE_BOOL(Bots, QuestableSpells, false) // Anita Thrall's (Anita_Thrall.pl) Bot Spell Scriber quests. +RULE_INT(Bots, SpawnLimit, 71) // Number of bots a character can have spawned at one time, You + 71 bots is a 12 group raid RULE_BOOL(Bots, BotGroupXP, false) // Determines whether client gets xp for bots outside their group. -RULE_BOOL(Bots, BotBardUseOutOfCombatSongs, true) // Determines whether bard bots use additional out of combat songs. +RULE_BOOL(Bots, BotBardUseOutOfCombatSongs, true) // Determines whether bard bots use additional out of combat songs (optional script) RULE_BOOL(Bots, BotLevelsWithOwner, false) // Auto-updates spawned bots as owner levels/de-levels (false is original behavior) RULE_BOOL(Bots, BotCharacterLevelEnabled, false) // Enables required level to spawn bots RULE_INT(Bots, BotCharacterLevel, 0) // 0 as default (if level > this value you can spawn bots if BotCharacterLevelEnabled is true) diff --git a/common/shareddb.cpp b/common/shareddb.cpp index d5d42a174..7ccfa5cbd 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -2007,24 +2007,21 @@ void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const Insp auto results = QueryDatabase(query); } -void SharedDatabase::GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message) { - - std::string query = StringFormat("SELECT BotInspectMessage FROM bots WHERE BotID = %i", botid); +#ifdef BOTS +void SharedDatabase::GetBotInspectMessage(uint32 bot_id, InspectMessage_Struct* message) +{ + std::string query = StringFormat("SELECT `inspect_message` FROM `bot_inspect_messages` WHERE `bot_id` = %i LIMIT 1", bot_id); auto results = QueryDatabase(query); - if (!results.Success()) { - return; + auto row = results.begin(); + memset(message, '\0', sizeof(InspectMessage_Struct)); + for (auto row = results.begin(); row != results.end(); ++row) { + memcpy(message, row[0], sizeof(InspectMessage_Struct)); } - - if (results.RowCount() != 1) - return; - - auto row = results.begin(); - memcpy(message, row[0], sizeof(InspectMessage_Struct)); - } -void SharedDatabase::SetBotInspectMessage(uint32 botid, const InspectMessage_Struct* message) { - std::string msg = EscapeString(message->text); - std::string query = StringFormat("UPDATE bots SET BotInspectMessage = '%s' WHERE BotID = %i", msg.c_str(), botid); - QueryDatabase(query); +void SharedDatabase::SetBotInspectMessage(uint32 bot_id, const InspectMessage_Struct* message) +{ + std::string query = StringFormat("REPLACE INTO `bot_inspect_messages` (bot_id, inspect_message) VALUES (%u, '%s')", bot_id, EscapeString(message->text).c_str()); + auto results = QueryDatabase(query); } +#endif diff --git a/common/shareddb.h b/common/shareddb.h index 923e5b775..36239bc35 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -51,8 +51,6 @@ class SharedDatabase : public Database int32 DeleteStalePlayerCorpses(); void LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message); void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message); - void GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message); - void SetBotInspectMessage(uint32 botid, const InspectMessage_Struct* message); bool GetCommandSettings(std::map &commands); uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID); @@ -128,6 +126,11 @@ class SharedDatabase : public Database void LoadBaseData(void *data, int max_level); const BaseDataStruct* GetBaseData(int lvl, int cl); +#ifdef BOTS + void GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message); + void SetBotInspectMessage(uint32 botid, const InspectMessage_Struct* message); +#endif + protected: std::unique_ptr skill_caps_mmf; diff --git a/utils/sql/git/bots/bots_db_update_manifest.txt b/utils/sql/git/bots/bots_db_update_manifest.txt index 91cdd7b69..1612046dd 100644 --- a/utils/sql/git/bots/bots_db_update_manifest.txt +++ b/utils/sql/git/bots/bots_db_update_manifest.txt @@ -1,4 +1,4 @@ -9000|2015_09_30_bots.sql|SHOW TABLES LIKE 'bot%'|empty| +9000|2015_09_30_bots.sql|SHOW TABLES LIKE 'bot_data'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/bots/deprecated/drop_bots (pre-update script).sql b/utils/sql/git/bots/deprecated/drop_bots (pre-update script).sql new file mode 100644 index 000000000..9699c157a --- /dev/null +++ b/utils/sql/git/bots/deprecated/drop_bots (pre-update script).sql @@ -0,0 +1,88 @@ +-- 'drop_bots (pre-update script)' sql script file +-- current as of 10/09/2015 +-- +-- Note: This file will remove bot schema loaded by 'load_bots' sql scripts. +-- There may still be remnants of bot activity in tables `guild_members` and +-- `group_id`. If these entries are causing issues, you may need to manually +-- remove them. + + +SELECT "dropping views..."; +DROP VIEW IF EXISTS `vwGuildMembers`; +DROP VIEW IF EXISTS `vwGroups`; +DROP VIEW IF EXISTS `vwBotGroups`; +DROP VIEW IF EXISTS `vwBotCharacterMobs`; + + +SELECT "dropping functions..."; +DROP FUNCTION IF EXISTS `GetMobTypeByName`; +DROP FUNCTION IF EXISTS `GetMobTypeByID`; +DROP FUNCTION IF EXISTS `GetMobType`; + + +SELECT "dropping tables..."; +DROP TABLE IF EXISTS `botguildmembers`; +DROP TABLE IF EXISTS `botgroupmembers`; +DROP TABLE IF EXISTS `botgroup`; +DROP TABLE IF EXISTS `botgroups`; -- this table is not a part of 'load_bots.sql' +DROP TABLE IF EXISTS `botpetinventory`; +DROP TABLE IF EXISTS `botpetbuffs`; +DROP TABLE IF EXISTS `botpets`; +DROP TABLE IF EXISTS `botinventory`; +DROP TABLE IF EXISTS `botbuffs`; +DROP TABLE IF EXISTS `bottimers`; +DROP TABLE IF EXISTS `botstances`; +DROP TABLE IF EXISTS `bots`; + +DROP PROCEDURE IF EXISTS `DropBotsSchema`; + + +DELIMITER $$ + +CREATE PROCEDURE `DropBotsSchema` () +BEGIN + + SELECT "deleting rules..."; + DELETE FROM `rule_values` WHERE `rule_name` LIKE 'Bots%'; + + + SELECT "deleting command..."; + DELETE FROM `commands` WHERE `command` LIKE 'bot'; + + + SELECT "restoring keys..."; + IF ((SELECT COUNT(*) FROM `information_schema`.`KEY_COLUMN_USAGE` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'group_id' AND `CONSTRAINT_NAME` = 'PRIMARY') > 0) THEN + -- IF ((SHOW KEYS IN `group_id` WHERE `Key_name` LIKE 'PRIMARY') != '') THEN + ALTER TABLE `group_id` DROP PRIMARY KEY; + END IF; + ALTER TABLE `group_id` ADD PRIMARY KEY (`groupid`, `charid`, `ismerc`); + + IF ((SELECT COUNT(*) FROM `information_schema`.`KEY_COLUMN_USAGE` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'guild_members' AND `CONSTRAINT_NAME` = 'PRIMARY') > 0) THEN + -- IF ((SHOW KEYS IN `guild_members` WHERE `Key_name` LIKE 'PRIMARY') != '') THEN + ALTER TABLE `guild_members` DROP PRIMARY KEY; + END IF; + ALTER TABLE `guild_members` ADD PRIMARY KEY (`char_id`); + + SELECT "de-activating spawns..."; + UPDATE `spawn2` SET `enabled` = 0 WHERE `id` IN (59297,59298); + + + SELECT "clearing database version..."; + IF ((SELECT COUNT(*) FROM `information_schema`.`COLUMNS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'db_version' AND `COLUMN_NAME` = 'bots_version') > 0) THEN + -- IF ((SHOW COLUMNS FROM `db_version` LIKE 'bots_version') != '') THEN + UPDATE `db_version` + SET `bots_version` = 0; + END IF; + +END$$ + +DELIMITER ; + + +CALL `DropBotsSchema`(); + +SELECT "dropping procedure..."; +DROP PROCEDURE IF EXISTS `DropBotsSchema`; + + +-- End of File diff --git a/utils/sql/git/bots/drop_bots.sql b/utils/sql/git/bots/drop_bots.sql index df8ca4fa8..5645a38b5 100644 --- a/utils/sql/git/bots/drop_bots.sql +++ b/utils/sql/git/bots/drop_bots.sql @@ -1,41 +1,100 @@ -- 'drop_bots' sql script file --- current as of 10/15/2014 +-- current as of 10/09/2015 -- --- Note: This file will revert all changes made by either 'load_bots' sql file. +-- Note: This file will remove bot schema loaded by 'load_bots' sql scripts. -- There may still be remnants of bot activity in tables `guild_members` and -- `group_id`. If these entries are causing issues, you may need to manually -- remove them. --- --- If this script fails due to a 'SQL Error (1068): Multiple primary key defined' --- error, run this query: ALTER TABLE `guild_members` DROP PRIMARY KEY; --- and it should remove the key so this script will process in its entirety. -ALTER TABLE `guild_members` ADD PRIMARY KEY (`char_id`); -ALTER TABLE `group_id` DROP PRIMARY KEY, ADD PRIMARY KEY (`groupid`, `charid`, `ismerc`); +SELECT "dropping views..."; +DROP VIEW IF EXISTS `vw_guild_members`; +DROP VIEW IF EXISTS `vw_groups`; +DROP VIEW IF EXISTS `vw_bot_groups`; +DROP VIEW IF EXISTS `vw_bot_character_mobs`; -UPDATE `spawn2` SET `enabled` = 0 WHERE `id` IN (59297,59298); - -DELETE FROM `commands` WHERE `command` = 'bot'; -DELETE FROM `rule_values` WHERE `rule_name` LIKE 'Bots%'; - -DROP VIEW IF EXISTS `vwBotCharacterMobs`; -DROP VIEW IF EXISTS `vwBotGroups`; -DROP VIEW IF EXISTS `vwGroups`; -DROP VIEW IF EXISTS `vwGuildMembers`; +SELECT "dropping functions..."; +DROP FUNCTION IF EXISTS `GetMobTypeByName`; +DROP FUNCTION IF EXISTS `GetMobTypeByID`; DROP FUNCTION IF EXISTS `GetMobType`; -DROP TABLE IF EXISTS `botguildmembers`; -DROP TABLE IF EXISTS `botgroupmembers`; --- this table is not a part of 'load_bots.sql' -DROP TABLE IF EXISTS `botgroups`; -DROP TABLE IF EXISTS `botgroup`; -DROP TABLE IF EXISTS `botpetinventory`; -DROP TABLE IF EXISTS `botpetbuffs`; -DROP TABLE IF EXISTS `botpets`; -DROP TABLE IF EXISTS `botinventory`; -DROP TABLE IF EXISTS `botbuffs`; -DROP TABLE IF EXISTS `bottimers`; -DROP TABLE IF EXISTS `botstances`; -DROP TABLE IF EXISTS `bots`; + +SELECT "dropping tables..."; +DROP TABLE IF EXISTS `botguildmembers_old`; +DROP TABLE IF EXISTS `botgroupmembers_old`; +DROP TABLE IF EXISTS `botgroup_old`; +DROP TABLE IF EXISTS `botpetinventory_old`; +DROP TABLE IF EXISTS `botpetbuffs_old`; +DROP TABLE IF EXISTS `botpets_old`; +DROP TABLE IF EXISTS `botinventory_old`; +DROP TABLE IF EXISTS `botbuffs_old`; +DROP TABLE IF EXISTS `bottimers_old`; +DROP TABLE IF EXISTS `botstances_old`; +DROP TABLE IF EXISTS `bots_old`; + +DROP TABLE IF EXISTS `bot_guild_members`; +DROP TABLE IF EXISTS `bot_group_members`; +DROP TABLE IF EXISTS `bot_groups`; +DROP TABLE IF EXISTS `bot_pet_inventories`; +DROP TABLE IF EXISTS `bot_pet_buffs`; +DROP TABLE IF EXISTS `bot_pets`; +DROP TABLE IF EXISTS `bot_inventories`; +DROP TABLE IF EXISTS `bot_buffs`; +DROP TABLE IF EXISTS `bot_timers`; +DROP TABLE IF EXISTS `bot_stances`; +DROP TABLE IF EXISTS `bot_inspect_messages`; +DROP TABLE IF EXISTS `bot_data`; + +DROP PROCEDURE IF EXISTS `DropBotsSchema`; + + +DELIMITER $$ + +CREATE PROCEDURE `DropBotsSchema` () +BEGIN + + SELECT "deleting rules..."; + DELETE FROM `rule_values` WHERE `rule_name` LIKE 'Bots%'; + + + SELECT "deleting command..."; + DELETE FROM `commands` WHERE `command` LIKE 'bot'; + + + SELECT "restoring keys..."; + IF ((SELECT COUNT(*) FROM `information_schema`.`KEY_COLUMN_USAGE` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'group_id' AND `CONSTRAINT_NAME` = 'PRIMARY') > 0) THEN + -- IF ((SHOW KEYS IN `group_id` WHERE `Key_name` LIKE 'PRIMARY') != '') THEN + ALTER TABLE `group_id` DROP PRIMARY KEY; + END IF; + ALTER TABLE `group_id` ADD PRIMARY KEY (`groupid`, `charid`, `ismerc`); + + IF ((SELECT COUNT(*) FROM `information_schema`.`KEY_COLUMN_USAGE` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'guild_members' AND `CONSTRAINT_NAME` = 'PRIMARY') > 0) THEN + -- IF ((SHOW KEYS IN `guild_members` WHERE `Key_name` LIKE 'PRIMARY') != '') THEN + ALTER TABLE `guild_members` DROP PRIMARY KEY; + END IF; + ALTER TABLE `guild_members` ADD PRIMARY KEY (`char_id`); + + SELECT "de-activating spawns..."; + UPDATE `spawn2` SET `enabled` = 0 WHERE `id` IN (59297,59298); + + + SELECT "clearing database version..."; + IF ((SELECT COUNT(*) FROM `information_schema`.`COLUMNS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'db_version' AND `COLUMN_NAME` = 'bots_version') > 0) THEN + -- IF ((SHOW COLUMNS FROM `db_version` LIKE 'bots_version') != '') THEN + UPDATE `db_version` + SET `bots_version` = 0; + END IF; + +END$$ + +DELIMITER ; + + +CALL `DropBotsSchema`(); + +SELECT "dropping procedure..."; +DROP PROCEDURE IF EXISTS `DropBotsSchema`; + + +-- End of File diff --git a/utils/sql/git/bots/required/2015_09_30_bots.sql b/utils/sql/git/bots/required/2015_09_30_bots.sql index 0dd030545..5551b8a30 100644 --- a/utils/sql/git/bots/required/2015_09_30_bots.sql +++ b/utils/sql/git/bots/required/2015_09_30_bots.sql @@ -1,220 +1,724 @@ --- 'load_bots' sql script file --- current as of 10/15/2014 +-- '2015_09_30_bots' sql script file +-- current as of 10/09/2015 -- --- Use this file on databases where the player profile blob has been converted. --- --- Note: This file assumes a database free of bot remnants. If you have a prior --- bot installation and wish to reload the default schema and entries, then --- source 'drop_bots.sql' before sourcing this file. +-- Use eqemu_update.pl to administer this script -ALTER TABLE `guild_members` DROP PRIMARY KEY; -ALTER TABLE `group_id` DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(`groupid`, `charid`, `name`, `ismerc`); +-- Clean-up +DROP VIEW IF EXISTS `vwBotCharacterMobs`; +DROP VIEW IF EXISTS `vwBotGroups`; +DROP VIEW IF EXISTS `vwGroups`; +DROP VIEW IF EXISTS `vwGuildMembers`; -UPDATE `spawn2` SET `enabled` = 1 WHERE `id` IN (59297,59298); +DROP VIEW IF EXISTS `vw_bot_character_mobs`; +DROP VIEW IF EXISTS `vw_bot_groups`; +DROP VIEW IF EXISTS `vw_groups`; +DROP VIEW IF EXISTS `vw_guild_members`; --- old command kept for reference (`commands` now only has 2 columns - `command` and `access`) --- INSERT INTO `commands` VALUES ('bot', '0', 'Type \"#bot help\" to the see the list of available commands for bots.'); -INSERT INTO `commands` VALUES ('bot', '0'); +DROP FUNCTION IF EXISTS `GetMobType`; +DROP FUNCTION IF EXISTS `GetMobTypeByName`; +DROP FUNCTION IF EXISTS `GetMobTypeByID`; -INSERT INTO `rule_values` VALUES - ('1', 'Bots:BotAAExpansion', '8', 'The expansion through which bots will obtain AAs'), - ('1', 'Bots:BotFinishBuffing', 'false', 'Allow for buffs to complete even if the bot caster is out of mana. Only affects buffing out of combat.'), - ('1', 'Bots:BotGroupBuffing', 'false', 'Bots will cast single target buffs as group buffs, default is false for single. Does not make single target buffs work for MGB.'), - ('1', 'Bots:BotManaRegen', '3.0', 'Adjust mana regen for bots, 1 is fast and higher numbers slow it down 3 is about the same as players.'), - ('1', 'Bots:BotQuest', 'false', 'Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl'), - ('1', 'Bots:BotSpellQuest', 'false', 'Anita Thrall\'s (Anita_Thrall.pl) Bot Spell Scriber quests.'), - ('1', 'Bots:CreateBotCount', '150', 'Number of bots that each account can create'), - ('1', 'Bots:SpawnBotCount', '71', 'Number of bots a character can have spawned at one time, You + 71 bots is a 12 group raid'); +DROP PROCEDURE IF EXISTS `LoadBotsSchema`; -CREATE TABLE `bots` ( - `BotID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `BotOwnerCharacterID` INT(10) UNSIGNED NOT NULL, - `BotSpellsID` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `Name` VARCHAR(64) NOT NULL, - `LastName` VARCHAR(32) DEFAULT NULL, - `BotLevel` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0', - `Race` SMALLINT(5) NOT NULL DEFAULT '0', - `Class` TINYINT(2) NOT NULL DEFAULT '0', - `Gender` TINYINT(2) NOT NULL DEFAULT '0', - `Size` FLOAT NOT NULL DEFAULT '0', - `Face` INT(10) NOT NULL DEFAULT '1', - `LuclinHairStyle` INT(10) NOT NULL DEFAULT '1', - `LuclinHairColor` INT(10) NOT NULL DEFAULT '1', - `LuclinEyeColor` INT(10) NOT NULL DEFAULT '1', - `LuclinEyeColor2` INT(10) NOT NULL DEFAULT '1', - `LuclinBeardColor` INT(10) NOT NULL DEFAULT '1', - `LuclinBeard` INT(10) NOT NULL DEFAULT '0', - `DrakkinHeritage` INT(10) NOT NULL DEFAULT '0', - `DrakkinTattoo` INT(10) NOT NULL DEFAULT '0', - `DrakkinDetails` INT(10) NOT NULL DEFAULT '0', - `HP` INTEGER NOT NULL DEFAULT '0', - `Mana` INTEGER NOT NULL DEFAULT '0', - `MR` SMALLINT(5) NOT NULL DEFAULT '0', - `CR` SMALLINT(5) NOT NULL DEFAULT '0', - `DR` SMALLINT(5) NOT NULL DEFAULT '0', - `FR` SMALLINT(5) NOT NULL DEFAULT '0', - `PR` SMALLINT(5) NOT NULL DEFAULT '0', - `Corrup` SMALLINT(5) NOT NULL DEFAULT '0', - `AC` SMALLINT(5) NOT NULL DEFAULT '0', - `STR` MEDIUMINT(8) NOT NULL DEFAULT '75', - `STA` MEDIUMINT(8) NOT NULL DEFAULT '75', - `DEX` MEDIUMINT(8) NOT NULL DEFAULT '75', - `AGI` MEDIUMINT(8) NOT NULL DEFAULT '75', - `_INT` MEDIUMINT(8) NOT NULL DEFAULT '80', - `WIS` MEDIUMINT(8) NOT NULL DEFAULT '75', - `CHA` MEDIUMINT(8) NOT NULL DEFAULT '75', - `ATK` MEDIUMINT(9) NOT NULL DEFAULT '0', - `BotCreateDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - `LastSpawnDate` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', - `TotalPlayTime` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `LastZoneId` SMALLINT(6) NOT NULL DEFAULT '0', - `BotInspectMessage` VARCHAR(256) NOT NULL DEFAULT '', - PRIMARY KEY (`BotID`) -) ENGINE=InnoDB; - -CREATE TABLE `botstances` ( - `BotID` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `StanceID` TINYINT UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (`BotID`), - CONSTRAINT `FK_botstances_1` FOREIGN KEY (`BotID`) REFERENCES `bots` (`BotID`) -); - -CREATE TABLE `bottimers` ( - `BotID` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `TimerID` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `Value` INT(10) UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (`BotID`), - CONSTRAINT `FK_bottimers_1` FOREIGN KEY (`BotID`) REFERENCES `bots` (`BotID`) -); - -CREATE TABLE `botbuffs` ( - `BotBuffId` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `BotId` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `SpellId` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `CasterLevel` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `DurationFormula` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `TicsRemaining` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `PoisonCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `DiseaseCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `CurseCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `CorruptionCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `HitCount` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `MeleeRune` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `MagicRune` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `DeathSaveSuccessChance` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `CasterAARank` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `Persistent` TINYINT(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`BotBuffId`), - KEY `FK_botbuff_1` (`BotId`), - CONSTRAINT `FK_botbuff_1` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`) -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; - -CREATE TABLE `botinventory` ( - `BotInventoryID` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, - `BotID` INTEGER UNSIGNED NOT NULL DEFAULT '0', - `SlotID` INTEGER SIGNED NOT NULL DEFAULT '0', - `ItemID` INTEGER UNSIGNED NOT NULL DEFAULT '0', - `charges` TINYINT(3) UNSIGNED DEFAULT 0, - `color` INTEGER UNSIGNED NOT NULL DEFAULT 0, - `augslot1` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT 0, - `augslot2` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT 0, - `augslot3` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT 0, - `augslot4` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT 0, - `augslot5` MEDIUMINT(7) UNSIGNED DEFAULT 0, - `instnodrop` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0, - PRIMARY KEY (`BotInventoryID`), - KEY `FK_botinventory_1` (`BotID`), - CONSTRAINT `FK_botinventory_1` FOREIGN KEY (`BotID`) REFERENCES `bots` (`BotID`) -) ENGINE=InnoDB; - -CREATE TABLE `botpets` ( - `BotPetsId` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, - `PetId` INTEGER UNSIGNED NOT NULL DEFAULT '0', - `BotId` INTEGER UNSIGNED NOT NULL DEFAULT '0', - `Name` VARCHAR(64) NULL, - `Mana` INTEGER NOT NULL DEFAULT '0', - `HitPoints` INTEGER NOT NULL DEFAULT '0', - PRIMARY KEY (`BotPetsId`), - KEY `FK_botpets_1` (`BotId`), - CONSTRAINT `FK_botpets_1` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`), - CONSTRAINT `U_botpets_1` UNIQUE (`BotId`) -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; - -CREATE TABLE `botpetbuffs` ( - `BotPetBuffId` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `BotPetsId` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `SpellId` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `CasterLevel` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `Duration` INT(11) UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (`BotPetBuffId`), - KEY `FK_botpetbuffs_1` (`BotPetsId`), - CONSTRAINT `FK_botpetbuffs_1` FOREIGN KEY (`BotPetsId`) REFERENCES `botpets` (`BotPetsID`) -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; - -CREATE TABLE `botpetinventory` ( - `BotPetInventoryId` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, - `BotPetsId` INTEGER UNSIGNED NOT NULL DEFAULT '0', - `ItemId` INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (`BotPetInventoryId`), - KEY `FK_botpetinventory_1` (`BotPetsId`), - CONSTRAINT `FK_botpetinventory_1` FOREIGN KEY (`BotPetsId`) REFERENCES `botpets` (`BotPetsID`) -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; - -CREATE TABLE `botgroup` ( - `BotGroupId` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, - `BotGroupLeaderBotId` INTEGER UNSIGNED NOT NULL DEFAULT '0', - `BotGroupName` VARCHAR(64) NOT NULL, - PRIMARY KEY (`BotGroupId`), - KEY `FK_botgroup_1` (`BotGroupLeaderBotId`), - CONSTRAINT `FK_botgroup_1` FOREIGN KEY (`BotGroupLeaderBotId`) REFERENCES `bots` (`BotID`) -) ENGINE=InnoDB; - -CREATE TABLE `botgroupmembers` ( - `BotGroupMemberId` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, - `BotGroupId` INTEGER UNSIGNED NOT NULL DEFAULT '0', - `BotId` INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (`BotGroupMemberId`), - KEY `FK_botgroupmembers_1` (`BotGroupId`), - CONSTRAINT `FK_botgroupmembers_1` FOREIGN KEY (`BotGroupId`) REFERENCES `botgroup` (`BotGroupId`), - KEY `FK_botgroupmembers_2` (`BotId`), - CONSTRAINT `FK_botgroupmembers_2` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`) -) ENGINE=InnoDB; - -CREATE TABLE `botguildmembers` ( - `char_id` INT(11) NOT NULL DEFAULT '0', - `guild_id` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0', - `rank` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', - `tribute_enable` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', - `total_tribute` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `last_tribute` INT(10) UNSIGNED NOT NULL DEFAULT '0', - `banker` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', - `public_note` TEXT NULL, - `alt` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (`char_id`) -) ENGINE=InnoDB; DELIMITER $$ -CREATE FUNCTION `GetMobType` (mobname VARCHAR(64)) RETURNS CHAR(1) +CREATE PROCEDURE `LoadBotsSchema` () +BEGIN + -- Activate + UPDATE `spawn2` SET `enabled` = 1 WHERE `id` IN (59297,59298); + + + -- Alter + IF ((SELECT COUNT(*) FROM `information_schema`.`KEY_COLUMN_USAGE` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'guild_members' AND `CONSTRAINT_NAME` = 'PRIMARY') > 0) THEN + -- IF ((SHOW KEYS IN `guild_members` WHERE `Key_name` LIKE 'PRIMARY') != '') THEN + ALTER TABLE `guild_members` DROP PRIMARY KEY; + END IF; + + IF ((SELECT COUNT(*) FROM `information_schema`.`KEY_COLUMN_USAGE` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'group_id' AND `CONSTRAINT_NAME` = 'PRIMARY') > 0) THEN + -- IF ((SHOW KEYS IN `group_id` WHERE `Key_name` LIKE 'PRIMARY') != '') THEN + ALTER TABLE `group_id` DROP PRIMARY KEY; + END IF; + ALTER TABLE `group_id` ADD PRIMARY KEY USING BTREE(`groupid`, `charid`, `name`, `ismerc`); + -- + -- From original bots.sql (for reference) + -- ALTER TABLE `group_id` DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(`groupid`, `charid`, `name`); + -- ALTER TABLE `guild_members` DROP PRIMARY KEY; + -- ALTER TABLE `group_id` ADD UNIQUE INDEX `U_group_id_1`(`name`); + -- ALTER TABLE `group_leaders` ADD UNIQUE INDEX `U_group_leaders_1`(`leadername`); + + + -- Commands + IF ((SELECT COUNT(`command`) FROM `commands` WHERE `command` LIKE 'bot') = 0) THEN + INSERT INTO `commands` VALUES ('bot', '0'); + END IF; + + + -- Rules + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:BotAAExpansion') > 0) THEN + UPDATE `rule_values` SET `rule_name` = 'Bots:AAExpansion' WHERE `rule_name` LIKE 'Bots:BotAAExpansion'; + END IF; + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:AAExpansion') = 0) THEN + INSERT INTO `rule_values` VALUES ('1', 'Bots:AAExpansion', '8', 'The expansion through which bots will obtain AAs'); + END IF; + + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:CreateBotCount') > 0) THEN + UPDATE `rule_values` SET `rule_name` = 'Bots:CreationLimit' WHERE `rule_name` LIKE 'Bots:CreateBotCount'; + END IF; + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:CreationLimit') = 0) THEN + INSERT INTO `rule_values` VALUES ('1', 'Bots:CreationLimit', '150', 'Number of bots that each account can create'); + END IF; + + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:BotFinishBuffing') > 0) THEN + UPDATE `rule_values` SET `rule_name` = 'Bots:FinishBuffing' WHERE `rule_name` LIKE 'Bots:BotFinishBuffing'; + END IF; + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:FinishBuffing') = 0) THEN + INSERT INTO `rule_values` VALUES ('1', 'Bots:FinishBuffing', 'false', 'Allow for buffs to complete even if the bot caster is out of mana. Only affects buffing out of combat.'); + END IF; + + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:BotGroupBuffing') > 0) THEN + UPDATE `rule_values` SET `rule_name` = 'Bots:GroupBuffing' WHERE `rule_name` LIKE 'Bots:BotGroupBuffing'; + END IF; + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:GroupBuffing') = 0) THEN + INSERT INTO `rule_values` VALUES ('1', 'Bots:GroupBuffing', 'false', 'Bots will cast single target buffs as group buffs, default is false for single. Does not make single target buffs work for MGB.'); + END IF; + + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:BotManaRegen') > 0) THEN + UPDATE `rule_values` SET `rule_name` = 'Bots:ManaRegen' WHERE `rule_name` LIKE 'Bots:BotManaRegen'; + END IF; + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:ManaRegen') = 0) THEN + INSERT INTO `rule_values` VALUES ('1', 'Bots:ManaRegen', '3.0', 'Adjust mana regen for bots, 1 is fast and higher numbers slow it down 3 is about the same as players.'); + END IF; + + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:BotQuest') > 0) THEN + UPDATE `rule_values` SET `rule_name` = 'Bots:QuestableSpawnLimit' WHERE `rule_name` LIKE 'Bots:BotQuest'; + END IF; + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:QuestableSpawnLimit') = 0) THEN + INSERT INTO `rule_values` VALUES ('1', 'Bots:QuestableSpawnLimit', 'false', 'Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl'); + END IF; + + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:BotSpellQuest') > 0) THEN + UPDATE `rule_values` SET `rule_name` = 'Bots:QuestableSpells' WHERE `rule_name` LIKE 'Bots:BotSpellQuest'; + END IF; + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:QuestableSpells') = 0) THEN + INSERT INTO `rule_values` VALUES ('1', 'Bots:QuestableSpells', 'false', 'Anita Thrall\'s (Anita_Thrall.pl) Bot Spell Scriber quests.'); + END IF; + + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:SpawnBotCount') > 0) THEN + UPDATE `rule_values` SET `rule_name` = 'Bots:SpawnLimit' WHERE `rule_name` LIKE 'Bots:SpawnBotCount'; + END IF; + IF ((SELECT COUNT(`rule_name`) FROM `rule_values` WHERE `rule_name` LIKE 'Bots:SpawnLimit') = 0) THEN + INSERT INTO `rule_values` VALUES ('1', 'Bots:SpawnLimit', '71', 'Number of bots a character can have spawned at one time, You + 71 bots is a 12 group raid'); + END IF; + + + -- Tables + CREATE TABLE `bot_data` ( + `bot_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `owner_id` INT(11) UNSIGNED NOT NULL, + `spells_id` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `name` VARCHAR(64) NOT NULL DEFAULT '', + `last_name` VARCHAR(64) NOT NULL DEFAULT '', -- Change unused (64) from (32) + `title` VARCHAR(32) NOT NULL DEFAULT '', -- Unused + `suffix` VARCHAR(32) NOT NULL DEFAULT '', -- Unused + `zone_id` SMALLINT(6) NOT NULL DEFAULT '0', + `gender` TINYINT(2) NOT NULL DEFAULT '0', + `race` SMALLINT(5) NOT NULL DEFAULT '0', + `class` TINYINT(2) NOT NULL DEFAULT '0', + `level` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0', + `deity` INT(11) UNSIGNED NOT NULL DEFAULT '0', -- Unused + `creation_day` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `last_spawn` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `time_spawned` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `size` FLOAT NOT NULL DEFAULT '0', + `face` INT(10) NOT NULL DEFAULT '1', + `hair_color` INT(10) NOT NULL DEFAULT '1', + `hair_style` INT(10) NOT NULL DEFAULT '1', + `beard` INT(10) NOT NULL DEFAULT '0', + `beard_color` INT(10) NOT NULL DEFAULT '1', + `eye_color_1` INT(10) NOT NULL DEFAULT '1', + `eye_color_2` INT(10) NOT NULL DEFAULT '1', + `drakkin_heritage` INT(10) NOT NULL DEFAULT '0', + `drakkin_tattoo` INT(10) NOT NULL DEFAULT '0', + `drakkin_details` INT(10) NOT NULL DEFAULT '0', + `ac` SMALLINT(5) NOT NULL DEFAULT '0', + `atk` MEDIUMINT(9) NOT NULL DEFAULT '0', + `hp` INTEGER NOT NULL DEFAULT '0', + `mana` INTEGER NOT NULL DEFAULT '0', + `str` MEDIUMINT(8) NOT NULL DEFAULT '75', + `sta` MEDIUMINT(8) NOT NULL DEFAULT '75', + `cha` MEDIUMINT(8) NOT NULL DEFAULT '75', + `dex` MEDIUMINT(8) NOT NULL DEFAULT '75', + `int` MEDIUMINT(8) NOT NULL DEFAULT '75', + `agi` MEDIUMINT(8) NOT NULL DEFAULT '75', + `wis` MEDIUMINT(8) NOT NULL DEFAULT '75', + `fire` SMALLINT(5) NOT NULL DEFAULT '0', + `cold` SMALLINT(5) NOT NULL DEFAULT '0', + `magic` SMALLINT(5) NOT NULL DEFAULT '0', + `poison` SMALLINT(5) NOT NULL DEFAULT '0', + `disease` SMALLINT(5) NOT NULL DEFAULT '0', + `corruption` SMALLINT(5) NOT NULL DEFAULT '0', + `show_helm` INT(11) UNSIGNED NOT NULL DEFAULT '0', -- Unused + PRIMARY KEY (`bot_id`) + ) ENGINE=InnoDB; + CREATE TABLE `bot_inspect_messages` ( + `bot_id` INT(11) UNSIGNED NOT NULL, + `inspect_message` VARCHAR(256) NOT NULL DEFAULT '', + PRIMARY KEY (`bot_id`), + INDEX `bot_id` (`bot_id`) + ) ENGINE=InnoDB; + IF ((SELECT COUNT(*) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'bots') > 0) THEN + -- IF ((SHOW TABLES LIKE 'bots') != '') THEN + INSERT INTO `bot_data` ( + `bot_id`, + `owner_id`, + `spells_id`, + `name`, + `last_name`, + `zone_id`, + `gender`, + `race`, + `class`, + `level`, + `creation_day`, + `last_spawn`, + `time_spawned`, + `size`, + `face`, + `hair_color`, + `hair_style`, + `beard`, + `beard_color`, + `eye_color_1`, + `eye_color_2`, + `drakkin_heritage`, + `drakkin_tattoo`, + `drakkin_details`, + `ac`, + `atk`, + `hp`, + `mana`, + `str`, + `sta`, + `cha`, + `dex`, + `int`, + `agi`, + `wis`, + `fire`, + `cold`, + `magic`, + `poison`, + `disease`, + `corruption` + ) + SELECT + `BotID`, + `BotOwnerCharacterID`, + `BotSpellsID`, + `Name`, + `LastName`, + `LastZoneId`, + `Gender`, + `Race`, + `Class`, + `BotLevel`, + `BotCreateDate`, + `LastSpawnDate`, + `TotalPlayTime`, + `Size`, + `Face`, + `LuclinHairColor`, + `LuclinHairStyle`, + `LuclinBeard`, + `LuclinBeardColor`, + `LuclinEyeColor`, + `LuclinEyeColor2`, + `DrakkinHeritage`, + `DrakkinTattoo`, + `DrakkinDetails`, + `AC`, + `ATK`, + `HP`, + `Mana`, + `STR`, + `STA`, + `CHA`, + `DEX`, + `_INT`, + `AGI`, + `WIS`, + `FR`, + `CR`, + `MR`, + `PR`, + `DR`, + `Corrup` + FROM `bots`; + + INSERT INTO `bot_inspect_messages` ( + `bot_id`, + `inspect_message` + ) + SELECT + `BotID`, + `BotInspectMessage` + FROM `bots`; + + RENAME TABLE `bots` TO `bots_old`; + END IF; + + CREATE TABLE `bot_stances` ( + `bot_id` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `stance_id` TINYINT UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`bot_id`), + CONSTRAINT `FK_bot_stances_1` FOREIGN KEY (`bot_id`) REFERENCES `bot_data` (`bot_id`) + ); + IF ((SELECT COUNT(*) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botstances') > 0) THEN + -- IF ((SHOW TABLES LIKE 'botstances') != '') THEN + INSERT INTO `bot_stances` ( + `bot_id`, + `stance_id` + ) + SELECT + `BotID`, + `StanceID` + FROM `botstances`; + + RENAME TABLE `botstances` TO `botstances_old`; + END IF; + + CREATE TABLE `bot_timers` ( + `bot_id` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `timer_id` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `timer_value` INT(11) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`bot_id`), + CONSTRAINT `FK_bot_timers_1` FOREIGN KEY (`bot_id`) REFERENCES `bot_data` (`bot_id`) + ); + IF ((SELECT COUNT(*) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'bottimers') > 0) THEN + -- IF ((SHOW TABLES LIKE 'bottimers') != '') THEN + INSERT INTO `bot_timers` ( + `bot_id`, + `timer_id`, + `timer_value` + ) + SELECT + `BotID`, + `TimerID`, + `Value` + FROM `bottimers`; + + RENAME TABLE `bottimers` TO `bottimers_old`; + END IF; + + CREATE TABLE `bot_buffs` ( + `buffs_index` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `bot_id` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `spell_id` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `caster_level` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', + `duration_formula` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `tics_remaining` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `poison_counters` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `disease_counters` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `curse_counters` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `corruption_counters` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `numhits` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `melee_rune` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `magic_rune` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `dot_rune` INT(10) UNSIGNED NOT NULL DEFAULT '0', -- Fix + `persistent` TINYINT(1) NOT NULL DEFAULT '0', + `caston_x` INT(10) NOT NULL DEFAULT '0', -- Fix + `caston_y` INT(10) NOT NULL DEFAULT '0', -- Fix + `caston_z` INT(10) NOT NULL DEFAULT '0', -- Fix + `extra_di_chance` INT(10) UNSIGNED NOT NULL DEFAULT '0', -- Fix + `instrument_mod` INT(10) NOT NULL DEFAULT '10', -- Unused + PRIMARY KEY (`buffs_index`), + KEY `FK_bot_buffs_1` (`bot_id`), + CONSTRAINT `FK_bot_buffs_1` FOREIGN KEY (`bot_id`) REFERENCES `bot_data` (`bot_id`) + ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; + IF ((SELECT COUNT(*) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botbuffs') > 0) THEN + -- IF ((SHOW TABLES LIKE 'botbuffs') != '') THEN + INSERT INTO `bot_buffs` ( + `buffs_index`, + `bot_id`, + `spell_id`, + `caster_level`, + `duration_formula`, + `tics_remaining`, + `poison_counters`, + `disease_counters`, + `curse_counters`, + `corruption_counters`, + `numhits`, + `melee_rune`, + `magic_rune`, + `persistent` + ) + SELECT + `BotBuffId`, + `BotId`, + `SpellId`, + `CasterLevel`, + `DurationFormula`, + `TicsRemaining`, + `PoisonCounters`, + `DiseaseCounters`, + `CurseCounters`, + `CorruptionCounters`, + `HitCount`, + `MeleeRune`, + `MagicRune`, + `Persistent` + FROM `botbuffs`; + + IF ((SELECT COUNT(*) FROM `information_schema`.`COLUMNS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botbuffs' AND `COLUMN_NAME` = 'dot_rune') > 0) THEN + -- IF ((SHOW COLUMNS FROM `botbuffs` LIKE 'dot_rune') != '') THEN + UPDATE `bot_buffs` + SET `dot_rune` = `botbuffs`.`dot_rune` + WHERE `buffs_index` = `botbuffs`.`BotBuffId` AND `bot_id` = `botbuffs`.`BotID`; + END IF; + + IF ((SELECT COUNT(*) FROM `information_schema`.`COLUMNS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botbuffs' AND `COLUMN_NAME` = 'caston_x') > 0) THEN + -- IF ((SHOW COLUMNS FROM `botbuffs` LIKE 'caston_x') != '') THEN + UPDATE `bot_buffs` + SET `caston_x` = `botbuffs`.`caston_x` + WHERE `buffs_index` = `botbuffs`.`BotBuffId` AND `bot_id` = `botbuffs`.`BotID`; + END IF; + + IF ((SELECT COUNT(*) FROM `information_schema`.`COLUMNS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botbuffs' AND `COLUMN_NAME` = 'caston_y') > 0) THEN + -- IF ((SHOW COLUMNS FROM `botbuffs` LIKE 'caston_y') != '') THEN + UPDATE `bot_buffs` + SET `caston_y` = `botbuffs`.`caston_y` + WHERE `buffs_index` = `botbuffs`.`BotBuffId` AND `bot_id` = `botbuffs`.`BotID`; + END IF; + + IF ((SELECT COUNT(*) FROM `information_schema`.`COLUMNS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botbuffs' AND `COLUMN_NAME` = 'caston_z') > 0) THEN + -- IF ((SHOW COLUMNS FROM `botbuffs` LIKE 'caston_z') != '') THEN + UPDATE `bot_buffs` + SET `caston_z` = `botbuffs`.`caston_z` + WHERE `buffs_index` = `botbuffs`.`BotBuffId` AND `bot_id` = `botbuffs`.`BotID`; + END IF; + + IF ((SELECT COUNT(*) FROM `information_schema`.`COLUMNS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botbuffs' AND `COLUMN_NAME` = 'ExtraDIChance') > 0) THEN + -- IF ((SHOW COLUMNS FROM `botbuffs` LIKE 'ExtraDIChance') != '') THEN + UPDATE `bot_buffs` + SET `extra_di_chance` = `botbuffs`.`ExtraDIChance` + WHERE `buffs_index` = `botbuffs`.`BotBuffId` AND `bot_id` = `botbuffs`.`BotID`; + END IF; + + RENAME TABLE `botbuffs` TO `botbuffs_old`; + END IF; + + CREATE TABLE `bot_inventories` ( + `inventories_index` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + `bot_id` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `slot_id` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `item_id` INT(11) UNSIGNED NULL DEFAULT '0', + `inst_charges` TINYINT(3) UNSIGNED DEFAULT 0, + `inst_color` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `inst_no_drop` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0', + `inst_custom_data` TEXT NULL, -- Unused + `ornament_icon` INT(11) UNSIGNED NOT NULL DEFAULT '0', -- Unused + `ornament_id_file` INT(11) UNSIGNED NOT NULL DEFAULT '0', -- Unused + `ornament_hero_model` INT(11) NOT NULL DEFAULT '0', -- Unused + `augment_1` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augment_2` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augment_3` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augment_4` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augment_5` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augment_6` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', -- Unused + PRIMARY KEY (`inventories_index`), + KEY `FK_bot_inventories_1` (`bot_id`), + CONSTRAINT `FK_bot_inventories_1` FOREIGN KEY (`bot_id`) REFERENCES `bot_data` (`bot_id`) + ) ENGINE=InnoDB; + IF ((SELECT COUNT(*) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botinventory') > 0) THEN + -- IF ((SHOW TABLES LIKE 'botinventory') != '') THEN + INSERT INTO `bot_inventories` ( + `inventories_index`, + `bot_id`, + `slot_id`, + `item_id`, + `inst_charges`, + `inst_color`, + `inst_no_drop`, + `augment_1`, + `augment_2`, + `augment_3`, + `augment_4`, + `augment_5` + ) + SELECT + `BotInventoryID`, + `BotID`, + `SlotID`, + `ItemID`, + `charges`, + `color`, + `instnodrop`, + `augslot1`, + `augslot2`, + `augslot3`, + `augslot4`, + `augslot5` + FROM `botinventory`; + + IF ((SELECT COUNT(*) FROM `information_schema`.`COLUMNS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botinventory' AND `COLUMN_NAME` = 'augslot6') > 0) THEN + -- IF ((SHOW COLUMNS FROM `botinventory` LIKE 'augslot6') != '') THEN + UPDATE `bot_inventories` + SET `augment_6` = `botinventory`.`augslot6` + WHERE `inventories_index` = `botinventory`.`BotInventoryID` AND `bot_id` = `botinventory`.`BotID`; + END IF; + + RENAME TABLE `botinventory` TO `botinventory_old`; + END IF; + + CREATE TABLE `bot_pets` ( + `pets_index` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + `pet_id` INTEGER UNSIGNED NOT NULL DEFAULT '0', + `bot_id` INTEGER UNSIGNED NOT NULL DEFAULT '0', + `name` VARCHAR(64) NULL, + `mana` INTEGER NOT NULL DEFAULT '0', + `hp` INTEGER NOT NULL DEFAULT '0', + PRIMARY KEY (`pets_index`), + KEY `FK_bot_pets_1` (`bot_id`), + CONSTRAINT `FK_bot_pets_1` FOREIGN KEY (`bot_id`) REFERENCES `bot_data` (`bot_id`), + CONSTRAINT `U_bot_pets_1` UNIQUE (`bot_id`) + ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; + IF ((SELECT COUNT(*) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botpets') > 0) THEN + -- IF ((SHOW TABLES LIKE 'botpets') != '') THEN + INSERT INTO `bot_pets` ( + `pets_index`, + `pet_id`, + `bot_id`, + `name`, + `mana`, + `hp` + ) + SELECT + `BotPetsId`, + `PetId`, + `BotId`, + `Name`, + `Mana`, + `HitPoints` + FROM `botpets`; + + RENAME TABLE `botpets` TO `botpets_old`; + END IF; + + CREATE TABLE `bot_pet_buffs` ( + `pet_buffs_index` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + `pets_index` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `spell_id` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `caster_level` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `duration` INT(11) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`pet_buffs_index`), + KEY `FK_bot_pet_buffs_1` (`pets_index`), + CONSTRAINT `FK_bot_pet_buffs_1` FOREIGN KEY (`pets_index`) REFERENCES `bot_pets` (`pets_index`) + ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; + IF ((SELECT COUNT(*) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botpetbuffs') > 0) THEN + -- IF ((SHOW TABLES LIKE 'botpetbuffs') != '') THEN + INSERT INTO `bot_pet_buffs` ( + `pet_buffs_index`, + `pets_index`, + `spell_id`, + `caster_level`, + `duration` + ) + SELECT + `BotPetBuffId`, + `BotPetsId`, + `SpellId`, + `CasterLevel`, + `Duration` + FROM `botpetbuffs`; + + RENAME TABLE `botpetbuffs` TO `botpetbuffs_old`; + END IF; + + CREATE TABLE `bot_pet_inventories` ( + `pet_inventories_index` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + `pets_index` INTEGER UNSIGNED NOT NULL DEFAULT '0', + `item_id` INTEGER UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`pet_inventories_index`), + KEY `FK_bot_pet_inventories_1` (`pets_index`), + CONSTRAINT `FK_bot_pet_inventories_1` FOREIGN KEY (`pets_index`) REFERENCES `bot_pets` (`pets_index`) + ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; + IF ((SELECT COUNT(*) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botpetinventory') > 0) THEN + -- IF ((SHOW TABLES LIKE 'botpetinventory') != '') THEN + INSERT INTO `bot_pet_inventories` ( + `pet_inventories_index`, + `pets_index`, + `item_id` + ) + SELECT + `BotPetInventoryId`, + `BotPetsId`, + `ItemId` + FROM `botpetinventory`; + + RENAME TABLE `botpetinventory` TO `botpetinventory_old`; + END IF; + + CREATE TABLE `bot_groups` ( + `groups_index` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + `group_leader_id` INTEGER UNSIGNED NOT NULL DEFAULT '0', + `group_name` VARCHAR(64) NOT NULL, + PRIMARY KEY (`groups_index`), + KEY `FK_bot_groups_1` (`group_leader_id`), + CONSTRAINT `FK_bot_groups_1` FOREIGN KEY (`group_leader_id`) REFERENCES `bot_data` (`bot_id`) + ) ENGINE=InnoDB; + IF ((SELECT COUNT(*) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botgroup') > 0) THEN + -- IF ((SHOW TABLES LIKE 'botgroup') != '') THEN + INSERT INTO `bot_groups` ( + `groups_index`, + `group_leader_id`, + `group_name` + ) + SELECT + `BotGroupId`, + `BotGroupLeaderBotId`, + `BotGroupName` + FROM `botgroup`; + + RENAME TABLE `botgroup` TO `botgroup_old`; + END IF; + + CREATE TABLE `bot_group_members` ( + `group_members_index` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + `groups_index` INTEGER UNSIGNED NOT NULL DEFAULT '0', + `bot_id` INTEGER UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`group_members_index`), + KEY `FK_bot_group_members_1` (`groups_index`), + CONSTRAINT `FK_bot_group_members_1` FOREIGN KEY (`groups_index`) REFERENCES `bot_groups` (`groups_index`), + KEY `FK_bot_group_members_2` (`bot_id`), + CONSTRAINT `FK_bot_group_members_2` FOREIGN KEY (`bot_id`) REFERENCES `bot_data` (`bot_id`) + ) ENGINE=InnoDB; + IF ((SELECT COUNT(*) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botgroupmembers') > 0) THEN + -- IF ((SHOW TABLES LIKE 'botgroupmembers') != '') THEN + INSERT INTO `bot_group_members` ( + `group_members_index`, + `groups_index`, + `bot_id` + ) + SELECT + `BotGroupMemberId`, + `BotGroupId`, + `BotId` + FROM `botgroupmembers`; + + RENAME TABLE `botgroupmembers` TO `botgroupmembers_old`; + END IF; + + CREATE TABLE `bot_guild_members` ( + `bot_id` INT(11) NOT NULL DEFAULT '0', + `guild_id` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0', + `rank` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', + `tribute_enable` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', + `total_tribute` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `last_tribute` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `banker` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', + `public_note` TEXT NULL, + `alt` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`bot_id`) + ) ENGINE=InnoDB; + IF ((SELECT COUNT(*) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'botguildmembers') > 0) THEN + -- IF ((SHOW TABLES LIKE 'botguildmembers') != '') THEN + INSERT INTO `bot_guild_members` ( + `bot_id`, + `guild_id`, + `rank`, + `tribute_enable`, + `total_tribute`, + `last_tribute`, + `banker`, + `public_note`, + `alt` + ) + SELECT + `char_id`, + `guild_id`, + `rank`, + `tribute_enable`, + `total_tribute`, + `last_tribute`, + `banker`, + `public_note`, + `alt` + FROM `botguildmembers`; + + RENAME TABLE `botguildmembers` TO `botguildmembers_old`; + END IF; + +END$$ + +DELIMITER ; + + +CALL `LoadBotsSchema`(); + +DROP PROCEDURE IF EXISTS `LoadBotsSchema`; + + +-- Functions +DELIMITER $$ + +-- (no code references) +CREATE FUNCTION `GetMobType` (mob_name VARCHAR(64)) RETURNS CHAR(1) BEGIN DECLARE Result CHAR(1); SET Result = NULL; - IF (SELECT COUNT(*) FROM `character_data` WHERE `name` = mobname) > 0 THEN + IF ((SELECT COUNT(*) FROM `character_data` WHERE `name` = mob_name) > 0) THEN SET Result = 'C'; - ELSEIF (SELECT COUNT(*) FROM `bots` WHERE `Name` = mobname) > 0 THEN + ELSEIF ((SELECT COUNT(*) FROM `bot_data` WHERE `name` = mob_name) > 0) THEN SET Result = 'B'; END IF; RETURN Result; END$$ +-- (one code reference in /common/database.cpp) +CREATE FUNCTION `GetMobTypeById` (mob_id INTEGER UNSIGNED) RETURNS CHAR(1) +BEGIN + DECLARE Result CHAR(1); + + SET Result = NULL; + + IF ((select `id` from `character_data` where `id` = mob_id) > 0) THEN + SET Result = 'C'; + ELSEIF ((select `bot_id` from `bot_data` where `bot_id` = mob_id) > 0) THEN + SET Result = 'B'; + END IF; + + RETURN Result; +END$$ + +-- (for reference only) +-- CREATE FUNCTION `GetMobTypeByName` (mob_name VARCHAR(64)) RETURNS CHAR(1) +-- BEGIN +-- DECLARE Result CHAR(1); +-- +-- SET Result = NULL; +-- +-- IF (select `id` from `character_data` where `name` = mob_name) > 0 THEN +-- SET Result = 'C'; +-- ELSEIF (select `bot_id` from `bot_data` where `name` = mob_name) > 0 THEN +-- SET Result = 'B'; +-- END IF; +-- +-- RETURN Result; +-- END $$ + DELIMITER ; -CREATE VIEW `vwBotCharacterMobs` AS -SELECT _utf8'C' AS mobtype, + +-- Views +CREATE VIEW `vw_bot_character_mobs` AS +SELECT +_utf8'C' AS mob_type, c.`id`, c.`name`, c.`class`, @@ -223,39 +727,42 @@ c.`last_login`, c.`zone_id` FROM `character_data` AS c UNION ALL -SELECT _utf8'B' AS mobtype, -b.`BotID` AS id, -b.`Name` AS name, -b.`Class` AS class, -b.`BotLevel` AS level, -0 AS timelaston, -0 AS zoneid -FROM bots AS b; +SELECT _utf8'B' AS mob_type, +b.`bot_id` AS id, +b.`name`, +b.`class`, +b.`level`, +b.`last_spawn` AS last_login, +b.`zone_id` +FROM `bot_data` AS b; -CREATE VIEW `vwGroups` AS -SELECT g.`groupid` AS groupid, -GetMobType(g.`name`) AS mobtype, +CREATE VIEW `vw_bot_groups` AS +SELECT +g.`groups_index`, +g.`group_name`, +g.`group_leader_id`, +b.`name` AS group_leader_name, +b.`owner_id`, +c.`name` AS owner_name +FROM `bot_groups` AS g +JOIN `bot_data` AS b ON g.`group_leader_id` = b.`bot_id` +JOIN `character_data` AS c ON b.`owner_id` = c.`id` +ORDER BY b.`owner_id`, g.`group_name`; + +CREATE VIEW `vw_groups` AS +SELECT +g.`groupid` AS group_id, +GetMobType(g.`name`) AS mob_type, g.`name` AS name, -g.`charid` AS mobid, -IFNULL(c.`level`, b.`BotLevel`) AS level +g.`charid` AS mob_id, +IFNULL(c.`level`, b.`level`) AS level FROM `group_id` AS g LEFT JOIN `character_data` AS c ON g.`name` = c.`name` -LEFT JOIN `bots` AS b ON g.`name` = b.`Name`; +LEFT JOIN `bot_data` AS b ON g.`name` = b.`name`; -CREATE VIEW `vwBotGroups` AS -SELECT g.`BotGroupId`, -g.`BotGroupName`, -g.`BotGroupLeaderBotId`, -b.`Name` AS BotGroupLeaderName, -b.`BotOwnerCharacterId`, -c.`name` AS BotOwnerCharacterName -FROM `botgroup` AS g -JOIN `bots` AS b ON g.`BotGroupLeaderBotId` = b.`BotID` -JOIN `character_data` AS c ON b.`BotOwnerCharacterID` = c.`id` -ORDER BY b.`BotOwnerCharacterId`, g.`BotGroupName`; - -CREATE VIEW `vwGuildMembers` AS -SELECT 'C' AS mobtype, +CREATE VIEW `vw_guild_members` AS +SELECT +'C' AS mob_type, cm.`char_id`, cm.`guild_id`, cm.`rank`, @@ -267,8 +774,9 @@ cm.`public_note`, cm.`alt` FROM `guild_members` AS cm UNION ALL -SELECT 'B' AS mobtype, -bm.`char_id`, +SELECT +'B' AS mob_type, +bm.`bot_id` AS char_id, bm.`guild_id`, bm.`rank`, bm.`tribute_enable`, @@ -277,4 +785,7 @@ bm.`last_tribute`, bm.`banker`, bm.`public_note`, bm.`alt` -FROM `botguildmembers` AS bm; +FROM `bot_guild_members` AS bm; + + +-- End of File diff --git a/zone/bot.cpp b/zone/bot.cpp index cbc951c34..d515303e7 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -1260,7 +1260,7 @@ int32 Bot::GenerateBaseHitPoints() { } void Bot::LoadAAs() { - int maxAAExpansion = RuleI(Bots, BotAAExpansion); //get expansion to get AAs up to + int maxAAExpansion = RuleI(Bots, AAExpansion); //get expansion to get AAs up to aa_ranks.clear(); int id = 0; @@ -1535,7 +1535,7 @@ bool Bot::IsBotNameAvailable(char *botName, std::string* errorMessage) { if (botName == "" || strlen(botName) > 15 || !database.CheckNameFilter(botName) || !database.CheckUsedName(botName)) return false; - std::string query = StringFormat("SELECT id FROM vwBotCharacterMobs WHERE name LIKE '%s'", botName); + std::string query = StringFormat("SELECT `id` FROM `vw_bot_character_mobs` WHERE `name` LIKE '%s'", botName); auto results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); @@ -1548,78 +1548,248 @@ bool Bot::IsBotNameAvailable(char *botName, std::string* errorMessage) { return true; //We made it with a valid name! } -bool Bot::Save() { +bool Bot::Save() +{ if(this->GetBotID() == 0) { // New bot record - std::string query = StringFormat("INSERT INTO bots (BotOwnerCharacterID, BotSpellsID, Name, LastName, " - "BotLevel, Race, Class, Gender, Size, Face, LuclinHairStyle, " - "LuclinHairColor, LuclinEyeColor, LuclinEyeColor2, LuclinBeardColor, " - "LuclinBeard, DrakkinHeritage, DrakkinTattoo, DrakkinDetails, HP, Mana, " - "MR, CR, DR, FR, PR, Corrup, AC, STR, STA, DEX, AGI, _INT, WIS, CHA, ATK, " - "LastSpawnDate, TotalPlayTime, LastZoneId) " - "VALUES('%u', '%u', '%s', '%s', '%u', '%i', '%i', '%i', '%f', '%i', '%i', " - "'%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', " - "'%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', " - "'%i', NOW(), 0, %i)", - this->_botOwnerCharacterID, this->GetBotSpellID(), this->GetCleanName(), - this->lastname, this->GetLevel(), GetRace(), GetClass(), GetGender(), - GetSize(), this->GetLuclinFace(), this->GetHairStyle(), GetHairColor(), - this->GetEyeColor1(), this->GetEyeColor2(), this->GetBeardColor(), - this->GetBeard(), this->GetDrakkinHeritage(), this->GetDrakkinTattoo(), - this->GetDrakkinDetails(), GetHP(), GetMana(), GetMR(), GetCR(), GetDR(), - GetFR(), GetPR(), GetCorrup(), GetAC(), GetSTR(), GetSTA(), GetDEX(), - GetAGI(), GetINT(), GetWIS(), GetCHA(), GetATK(), _lastZoneId); - auto results = database.QueryDatabase(query); + std::string query = StringFormat( + "INSERT INTO `bot_data` (" + " `owner_id`," + " `spells_id`," + " `name`," + " `last_name`," + " `zone_id`," + " `gender`," + " `race`," + " `class`," + " `level`," + /*creation_day - not needed for bot creation*/ + " `last_spawn`," + " `time_spawned`," + " `size`," + " `face`," + " `hair_color`," + " `hair_style`," + " `beard`," + " `beard_color`," + " `eye_color_1`," + " `eye_color_2`," + " `drakkin_heritage`," + " `drakkin_tattoo`," + " `drakkin_details`," + " `ac`," + " `atk`," + " `hp`," + " `mana`," + " `str`," + " `sta`," + " `cha`," + " `dex`," + " `int`," + " `agi`," + " `wis`," + " `fire`," + " `cold`," + " `magic`," + " `poison`," + " `disease`," + " `corruption`" + ")" + " VALUES (" + "'%u'," /*owner_id*/ + " '%u'," /*spells_id*/ + " '%s'," /*name*/ + " '%s'," /*last_name*/ + " '%i'," /*zone_id*/ + " '%i'," /*gender*/ + " '%i'," /*race*/ + " '%i'," /*class*/ + " '%u'," /*level*/ + /*creation_day*/ + " NOW()," /*last_spawn*/ + " 0," /*time_spawned*/ + " '%f'," /*size*/ + " '%i'," /*face*/ + " '%i'," /*hair_color*/ + " '%i'," /*hair_style*/ + " '%i'," /*beard*/ + " '%i'," /*beard_color*/ + " '%i'," /*eye_color_1*/ + " '%i'," /*eye_color_2*/ + " '%i'," /*drakkin_heritage*/ + " '%i'," /*drakkin_tattoo*/ + " '%i'," /*drakkin_details*/ + " '%i'," /*ac*/ + " '%i'," /*atk*/ + " '%i'," /*hp*/ + " '%i'," /*mana*/ + " '%i'," /*str*/ + " '%i'," /*sta*/ + " '%i'," /*cha*/ + " '%i'," /*dex*/ + " '%i'," /*int*/ + " '%i'," /*agi*/ + " '%i'," /*wis*/ + " '%i'," /*fire*/ + " '%i'," /*cold*/ + " '%i'," /*magic*/ + " '%i'," /*poison*/ + " '%i'," /*disease*/ + " '%i'" /*corruption*/ + ")", + this->_botOwnerCharacterID, + this->GetBotSpellID(), + this->GetCleanName(), + this->lastname, + _lastZoneId, + GetGender(), + GetRace(), + GetClass(), + this->GetLevel(), + GetSize(), + this->GetLuclinFace(), + GetHairColor(), + this->GetHairStyle(), + this->GetBeard(), + this->GetBeardColor(), + this->GetEyeColor1(), + this->GetEyeColor2(), + this->GetDrakkinHeritage(), + this->GetDrakkinTattoo(), + this->GetDrakkinDetails(), + GetAC(), + GetATK(), + GetHP(), + GetMana(), + GetSTR(), + GetSTA(), + GetCHA(), + GetDEX(), + GetINT(), + GetAGI(), + GetWIS(), + GetFR(), + GetCR(), + GetMR(), + GetPR(), + GetDR(), + GetCorrup() + ); + auto results = database.QueryDatabase(query); if(!results.Success()) { - auto botOwner = GetBotOwner(); + auto botOwner = GetBotOwner(); if (botOwner) - botOwner->Message(13, results.ErrorMessage().c_str()); - - return false; + botOwner->Message(13, results.ErrorMessage().c_str()); + + return false; } - - SetBotID(results.LastInsertedID()); - SaveBuffs(); + + SetBotID(results.LastInsertedID()); + SaveBuffs(); SavePet(); SaveStance(); SaveTimers(); - return true; + return true; } - - // Update existing bot record - std::string query = StringFormat("UPDATE bots SET BotOwnerCharacterID = '%u', BotSpellsID = '%u', " - "Name = '%s', LastName = '%s', BotLevel = '%u', Race = '%i', " - "Class = '%i', Gender = '%i', Size = '%f', Face = '%i', " - "LuclinHairStyle = '%i', LuclinHairColor = '%i', " - "LuclinEyeColor = '%i', LuclinEyeColor2 = '%i', " - "LuclinBeardColor = '%i', LuclinBeard = '%i', DrakkinHeritage = '%i', " - "DrakkinTattoo = '%i', DrakkinDetails = '%i', HP = '%i', Mana = '%i', " - "MR = '%i', CR = '%i', DR = '%i', FR = '%i', PR = '%i', " - "Corrup = '%i', AC = '%i', STR = '%i', STA = '%i', DEX = '%i', " - "AGI = '%i', _INT = '%i', WIS = '%i', CHA = '%i', ATK = '%i', " - "LastSpawnDate = NOW(), TotalPlayTime = '%u', LastZoneId = %i " - "WHERE BotID = '%u'", - _botOwnerCharacterID, this->GetBotSpellID(), this->GetCleanName(), - this->lastname, this->GetLevel(), _baseRace, this->GetClass(), - _baseGender, GetSize(), this->GetLuclinFace(), this->GetHairStyle(), - GetHairColor(), this->GetEyeColor1(), this->GetEyeColor2(), - this->GetBeardColor(), this->GetBeard(), this->GetDrakkinHeritage(), - GetDrakkinTattoo(), GetDrakkinDetails(), GetHP(), GetMana(), - _baseMR, _baseCR, _baseDR, _baseFR, _basePR, _baseCorrup, _baseAC, - _baseSTR, _baseSTA, _baseDEX, _baseAGI, _baseINT, _baseWIS, _baseCHA, - _baseATK, GetTotalPlayTime(), _lastZoneId, GetBotID()); - auto results = database.QueryDatabase(query); - if(!results.Success()) { - auto botOwner = GetBotOwner(); - if (botOwner) - botOwner->Message(13, results.ErrorMessage().c_str()); - - return false; - } - SaveBuffs(); - SavePet(); - SaveStance(); - SaveTimers(); + + // Update existing bot record + std::string query = StringFormat( + "UPDATE `bot_data`" + " SET" + " `owner_id` = '%u'," + " `spells_id` = '%u'," + " `name` = '%s'," + " `last_name` = '%s'," + " `zone_id` = '%i'," + " `gender` = '%i'," + " `race` = '%i'," + " `class` = '%i'," + " `level` = '%u'," + /*creation_day - check to see how client is handled*/ + " `last_spawn` = NOW()," + " `time_spawned` = '%u'," + " `size` = '%f'," + " `face` = '%i'," + " `hair_color` = '%i'," + " `hair_style` = '%i'," + " `beard` = '%i'," + " `beard_color` = '%i'," + " `eye_color_1` = '%i'," + " `eye_color_2` = '%i'," + " `drakkin_heritage` = '%i'," + " `drakkin_tattoo` = '%i'," + " `drakkin_details` = '%i'," + " `ac` = '%i'," + " `atk` = '%i'," + " `hp` = '%i'," + " `mana` = '%i'," + " `str` = '%i'," + " `sta` = '%i'," + " `cha` = '%i'," + " `dex` = '%i'," + " `int` = '%i'," + " `agi` = '%i'," + " `wis` = '%i'," + " `fire` = '%i'," + " `cold` = '%i'," + " `magic` = '%i'," + " `poison` = '%i'," + " `disease` = '%i'," + " `corruption` = '%i'," + " WHERE `bot_id` = '%u'", + _botOwnerCharacterID, + this->GetBotSpellID(), + this->GetCleanName(), + this->lastname, + _lastZoneId, + _baseGender, + _baseRace, + this->GetClass(), + this->GetLevel(), + /*creation_day*/ + GetTotalPlayTime(), + GetSize(), + this->GetLuclinFace(), + GetHairColor(), + this->GetHairStyle(), + this->GetBeard(), + this->GetBeardColor(), + this->GetEyeColor1(), + this->GetEyeColor2(), + this->GetDrakkinHeritage(), + GetDrakkinTattoo(), + GetDrakkinDetails(), + _baseAC, + _baseATK, + GetHP(), + GetMana(), + _baseSTR, + _baseSTA, + _baseCHA, + _baseDEX, + _baseINT, + _baseAGI, + _baseWIS, + _baseFR, + _baseCR, + _baseMR, + _basePR, + _baseDR, + _baseCorrup, + GetBotID() + ); + auto results = database.QueryDatabase(query); + if(!results.Success()) { + auto botOwner = GetBotOwner(); + if (botOwner) + botOwner->Message(13, results.ErrorMessage().c_str()); + + return false; + } + SaveBuffs(); + SavePet(); + SaveStance(); + SaveTimers(); return true; } @@ -1634,82 +1804,152 @@ uint32 Bot::GetTotalPlayTime() { return Result; } -void Bot::SaveBuffs() { - // Remove any existing buff saves - std::string query = StringFormat("DELETE FROM botbuffs WHERE BotId = %u", GetBotID()); - auto results = database.QueryDatabase(query); - if(!results.Success()) - return; - - for (int buffIndex = 0; buffIndex < BUFF_COUNT; buffIndex++) { - if (buffs[buffIndex].spellid <= 0 || buffs[buffIndex].spellid == SPELL_UNKNOWN) - continue; - - int isPersistent = buffs[buffIndex].persistant_buff? 1: 0; - query = StringFormat("INSERT INTO botbuffs (BotId, SpellId, CasterLevel, DurationFormula, " - "TicsRemaining, PoisonCounters, DiseaseCounters, CurseCounters, " - "CorruptionCounters, HitCount, MeleeRune, MagicRune, dot_rune, " - "caston_x, Persistent, caston_y, caston_z, ExtraDIChance) " - "VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %i, %u, " - "%i, %i, %i)", - GetBotID(), buffs[buffIndex].spellid, buffs[buffIndex].casterlevel, - spells[buffs[buffIndex].spellid].buffdurationformula, - buffs[buffIndex].ticsremaining, - CalculatePoisonCounters(buffs[buffIndex].spellid) > 0 ? buffs[buffIndex].counters : 0, - CalculateDiseaseCounters(buffs[buffIndex].spellid) > 0 ? buffs[buffIndex].counters : 0, - CalculateCurseCounters(buffs[buffIndex].spellid) > 0 ? buffs[buffIndex].counters : 0, - CalculateCorruptionCounters(buffs[buffIndex].spellid) > 0 ? buffs[buffIndex].counters : 0, - buffs[buffIndex].numhits, buffs[buffIndex].melee_rune, - buffs[buffIndex].magic_rune, buffs[buffIndex].dot_rune, - buffs[buffIndex].caston_x, isPersistent, buffs[buffIndex].caston_y, - buffs[buffIndex].caston_z, buffs[buffIndex].ExtraDIChance); - auto results = database.QueryDatabase(query); - if(!results.Success()) - return; - } -} - -void Bot::LoadBuffs() { - std::string query = StringFormat("SELECT SpellId, CasterLevel, DurationFormula, TicsRemaining, PoisonCounters, DiseaseCounters, CurseCounters, CorruptionCounters, HitCount, MeleeRune, MagicRune, dot_rune, caston_x, Persistent, caston_y, caston_z, ExtraDIChance FROM botbuffs WHERE BotId = %u", GetBotID()); - auto results = database.QueryDatabase(query); +void Bot::SaveBuffs() +{ + // Remove any existing buff saves + std::string query = StringFormat("DELETE FROM `bot_buffs` WHERE `bot_id` = %u", GetBotID()); + auto results = database.QueryDatabase(query); if(!results.Success()) return; - - int buffCount = 0; - for (auto row = results.begin(); row != results.end(); ++row) { - if(buffCount == BUFF_COUNT) - break; - - buffs[buffCount].spellid = atoi(row[0]); - buffs[buffCount].casterlevel = atoi(row[1]); - buffs[buffCount].ticsremaining = atoi(row[3]); - if(CalculatePoisonCounters(buffs[buffCount].spellid) > 0) - buffs[buffCount].counters = atoi(row[4]); - else if(CalculateDiseaseCounters(buffs[buffCount].spellid) > 0) - buffs[buffCount].counters = atoi(row[5]); - else if(CalculateCurseCounters(buffs[buffCount].spellid) > 0) - buffs[buffCount].counters = atoi(row[6]); - else if(CalculateCorruptionCounters(buffs[buffCount].spellid) > 0) - buffs[buffCount].counters = atoi(row[7]); - - buffs[buffCount].numhits = atoi(row[8]); - buffs[buffCount].melee_rune = atoi(row[9]); - buffs[buffCount].magic_rune = atoi(row[10]); - buffs[buffCount].dot_rune = atoi(row[11]); - buffs[buffCount].caston_x = atoi(row[12]); - buffs[buffCount].casterid = 0; - buffs[buffCount].persistant_buff = atoi(row[13])? true: false; - buffs[buffCount].caston_y = atoi(row[14]); - buffs[buffCount].caston_z = atoi(row[15]); - buffs[buffCount].ExtraDIChance = atoi(row[16]); - buffCount++; - } - query = StringFormat("DELETE FROM botbuffs WHERE BotId = %u", GetBotID()); - results = database.QueryDatabase(query); + + for (int buffIndex = 0; buffIndex < BUFF_COUNT; buffIndex++) { + if (buffs[buffIndex].spellid <= 0 || buffs[buffIndex].spellid == SPELL_UNKNOWN) + continue; + + int isPersistent = buffs[buffIndex].persistant_buff ? 1 : 0; + query = StringFormat( + "INSERT INTO `bot_buffs` (" + "`bot_id`," + " `spell_id`," + " `caster_level`," + " `duration_formula`," + " `tics_remaining`," + " `poison_counters`," + " `disease_counters`," + " `curse_counters`," + " `corruption_counters`," + " `numhits`," + " `melee_rune`," + " `magic_rune`," + " `dot_rune`," + " `persistent`," + " `caston_x`," + " `caston_y`," + " `caston_z`," + " `extra_di_chance`" + ")" + " VALUES (" + "%u," /*bot_id*/ + " %u," /*spell_id*/ + " %u," /*caster_level*/ + " %u," /*duration_formula*/ + " %u," /*tics_remaining*/ + " %u," /*poison_counters*/ + " %u," /*disease_counters*/ + " %u," /*curse_counters*/ + " %u," /*corruption_counters*/ + " %u," /*numhits*/ + " %u," /*melee_rune*/ + " %u," /*magic_rune*/ + " %u," /*dot_rune*/ + " %u," /*persistent*/ + " %i," /*caston_x*/ + " %i," /*caston_y*/ + " %i," /*caston_z*/ + " %i" /*extra_di_chance*/ + ")", + GetBotID(), + buffs[buffIndex].spellid, + buffs[buffIndex].casterlevel, + spells[buffs[buffIndex].spellid].buffdurationformula, + buffs[buffIndex].ticsremaining, + CalculatePoisonCounters(buffs[buffIndex].spellid) > 0 ? buffs[buffIndex].counters : 0, + CalculateDiseaseCounters(buffs[buffIndex].spellid) > 0 ? buffs[buffIndex].counters : 0, + CalculateCurseCounters(buffs[buffIndex].spellid) > 0 ? buffs[buffIndex].counters : 0, + CalculateCorruptionCounters(buffs[buffIndex].spellid) > 0 ? buffs[buffIndex].counters : 0, + buffs[buffIndex].numhits, + buffs[buffIndex].melee_rune, + buffs[buffIndex].magic_rune, + buffs[buffIndex].dot_rune, + isPersistent, + buffs[buffIndex].caston_x, + buffs[buffIndex].caston_y, + buffs[buffIndex].caston_z, + buffs[buffIndex].ExtraDIChance + ); + auto results = database.QueryDatabase(query); + if(!results.Success()) + return; + } } -uint32 Bot::GetPetSaveId() { - std::string query = StringFormat("SELECT BotPetsId FROM botpets WHERE BotId = %u", GetBotID()); +void Bot::LoadBuffs() +{ + std::string query = StringFormat( + "SELECT" + " `spell_id`," + " `caster_level`," + " `duration_formula`," + " `tics_remaining`," + " `poison_counters`," + " `disease_counters," + " `curse_counters`," + " `corruption_counters`," + " `numhits`," + " `melee_rune`," + " `magic_rune`," + " `dot_rune`," + " `persistent`," + " `caston_x`," + " `caston_y`," + " `caston_z`," + " `extra_di_chance`" + " FROM `bot_buffs`" + " WHERE `bot_id` = %u", + GetBotID() + ); + auto results = database.QueryDatabase(query); + if(!results.Success()) + return; + + int buffCount = 0; + for (auto row = results.begin(); row != results.end(); ++row) { + if(buffCount == BUFF_COUNT) + break; + + buffs[buffCount].spellid = atoi(row[0]); + buffs[buffCount].casterlevel = atoi(row[1]); + //row[2] (duration_formula) can probably be removed + buffs[buffCount].ticsremaining = atoi(row[3]); + + if(CalculatePoisonCounters(buffs[buffCount].spellid) > 0) + buffs[buffCount].counters = atoi(row[4]); + else if(CalculateDiseaseCounters(buffs[buffCount].spellid) > 0) + buffs[buffCount].counters = atoi(row[5]); + else if(CalculateCurseCounters(buffs[buffCount].spellid) > 0) + buffs[buffCount].counters = atoi(row[6]); + else if(CalculateCorruptionCounters(buffs[buffCount].spellid) > 0) + buffs[buffCount].counters = atoi(row[7]); + + buffs[buffCount].numhits = atoi(row[8]); + buffs[buffCount].melee_rune = atoi(row[9]); + buffs[buffCount].magic_rune = atoi(row[10]); + buffs[buffCount].dot_rune = atoi(row[11]); + buffs[buffCount].persistant_buff = atoi(row[12]) ? true : false; + buffs[buffCount].caston_x = atoi(row[13]); + buffs[buffCount].caston_y = atoi(row[14]); + buffs[buffCount].caston_z = atoi(row[15]); + buffs[buffCount].ExtraDIChance = atoi(row[16]); + buffs[buffCount].casterid = 0; + ++buffCount; + } + query = StringFormat("DELETE FROM `bot_buffs` WHERE `bot_id` = %u", GetBotID()); + results = database.QueryDatabase(query); +} + +uint32 Bot::GetPetSaveId() +{ + std::string query = StringFormat("SELECT `pets_index` FROM `bot_pets` WHERE `bot_id` = %u", GetBotID()); auto results = database.QueryDatabase(query); if(!results.Success() || results.RowCount() == 0) return 0; @@ -1745,11 +1985,12 @@ void Bot::LoadPet() { } } -void Bot::LoadPetStats(std::string* petName, uint32* petMana, uint32* petHitPoints, uint32* botPetId, uint32 botPetSaveId) { +void Bot::LoadPetStats(std::string* petName, uint32* petMana, uint32* petHitPoints, uint32* botPetId, uint32 botPetSaveId) +{ if(botPetSaveId == 0) return; - std::string query = StringFormat("SELECT PetId, Name, Mana, HitPoints FROM botpets WHERE BotPetsId = %u", botPetSaveId); + std::string query = StringFormat("SELECT `pet_id`, `name`, `mana`, `hp` FROM `bot_pets` WHERE `pets_index` = %u", botPetSaveId); auto results = database.QueryDatabase(query); if(!results.Success() || results.RowCount() == 0) return; @@ -1765,7 +2006,7 @@ void Bot::LoadPetBuffs(SpellBuff_Struct* petBuffs, uint32 botPetSaveId) { if(!petBuffs || botPetSaveId == 0) return; - std::string query = StringFormat("SELECT SpellId, CasterLevel, Duration FROM botpetbuffs WHERE BotPetsId = %u;", botPetSaveId); + std::string query = StringFormat("SELECT `spell_id`, `caster_level`, `duration` FROM `bot_pet_buffs` WHERE `pets_index` = %u;", botPetSaveId); auto results = database.QueryDatabase(query); if(!results.Success()) return; @@ -1780,7 +2021,7 @@ void Bot::LoadPetBuffs(SpellBuff_Struct* petBuffs, uint32 botPetSaveId) { petBuffs[buffIndex].duration = atoi(row[2]); buffIndex++; } - query = StringFormat("DELETE FROM botpetbuffs WHERE BotPetsId = %u;", botPetSaveId); + query = StringFormat("DELETE FROM `bot_pet_buffs` WHERE `pets_index` = %u;", botPetSaveId); results = database.QueryDatabase(query); } @@ -1788,7 +2029,7 @@ void Bot::LoadPetItems(uint32* petItems, uint32 botPetSaveId) { if(!petItems || botPetSaveId == 0) return; - std::string query = StringFormat("SELECT ItemId FROM botpetinventory WHERE BotPetsId = %u;", botPetSaveId); + std::string query = StringFormat("SELECT `item_id` FROM `bot_pet_inventories` WHERE `pets_index` = %u;", botPetSaveId); auto results = database.QueryDatabase(query); if(!results.Success()) return; @@ -1801,7 +2042,7 @@ void Bot::LoadPetItems(uint32* petItems, uint32 botPetSaveId) { petItems[itemIndex] = atoi(row[0]); itemIndex++; } - query = StringFormat("DELETE FROM botpetinventory WHERE BotPetsId = %u", botPetSaveId); + query = StringFormat("DELETE FROM `bot_pet_inventories` WHERE `pets_index` = %u", botPetSaveId); results = database.QueryDatabase(query); } @@ -1833,28 +2074,58 @@ void Bot::SavePet() { } } -uint32 Bot::SavePetStats(std::string petName, uint32 petMana, uint32 petHitPoints, uint32 botPetId) { - std::string query = StringFormat("REPLACE INTO botpets SET PetId = %u, BotId = %u, Name = '%s', Mana = %u, HitPoints = %u", botPetId, GetBotID(), petName.c_str(), petMana, petHitPoints); - auto results = database.QueryDatabase(query); +uint32 Bot::SavePetStats(std::string petName, uint32 petMana, uint32 petHitPoints, uint32 botPetId) +{ + std::string query = StringFormat( + "REPLACE INTO `bot_pets`" + " SET" + " `pet_id` = %u," + " `bot_id` = %u," + " `name` = '%s'," + " `mana` = %u," + " `hp` = %u", + botPetId, + GetBotID(), + petName.c_str(), + petMana, + petHitPoints + ); + auto results = database.QueryDatabase(query); return 0; } -void Bot::SavePetBuffs(SpellBuff_Struct* petBuffs, uint32 botPetSaveId) { +void Bot::SavePetBuffs(SpellBuff_Struct* petBuffs, uint32 botPetSaveId) +{ if(!petBuffs || botPetSaveId == 0) - return; - + return; + int buffIndex = 0; while(buffIndex < BUFF_COUNT) { - if(petBuffs[buffIndex].spellid > 0 && petBuffs[buffIndex].spellid != SPELL_UNKNOWN) { - - std::string query = StringFormat("INSERT INTO botpetbuffs (BotPetsId, SpellId, CasterLevel, Duration) VALUES(%u, %u, %u, %u)", botPetSaveId, petBuffs[buffIndex].spellid, petBuffs[buffIndex].level, petBuffs[buffIndex].duration); - auto results = database.QueryDatabase(query); - if(!results.Success()) - break; - } - buffIndex++; - } - + if(petBuffs[buffIndex].spellid > 0 && petBuffs[buffIndex].spellid != SPELL_UNKNOWN) { + std::string query = StringFormat( + "INSERT INTO `bot_pet_buffs` (" + "`pets_index`," + " `spell_id`," + " `caster_level`," + " `duration`" + ")" + " VALUES (" + "%u," + " %u," + " %u," + " %u" + ")", + botPetSaveId, + petBuffs[buffIndex].spellid, + petBuffs[buffIndex].level, + petBuffs[buffIndex].duration + ); + auto results = database.QueryDatabase(query); + if(!results.Success()) + break; + } + buffIndex++; + } } void Bot::SavePetItems(uint32* petItems, uint32 botPetSaveId) { @@ -1865,7 +2136,7 @@ void Bot::SavePetItems(uint32* petItems, uint32 botPetSaveId) { if(petItems[itemIndex] == 0) continue; - std::string query = StringFormat("INSERT INTO botpetinventory (BotPetsId, ItemId) VALUES(%u, %u)", botPetSaveId, petItems[itemIndex]); + std::string query = StringFormat("INSERT INTO `bot_pet_inventories` (`pets_index`, `item_id`) VALUES (%u, %u)", botPetSaveId, petItems[itemIndex]); auto results = database.QueryDatabase(query); if(!results.Success()) break; @@ -1876,7 +2147,7 @@ void Bot::DeletePetBuffs(uint32 botPetSaveId) { if(botPetSaveId == 0) return; - std::string query = StringFormat("DELETE FROM botpetbuffs WHERE BotPetsId = %u", botPetSaveId); + std::string query = StringFormat("DELETE FROM `bot_pet_buffs` WHERE `pets_index` = %u", botPetSaveId); auto results = database.QueryDatabase(query); } @@ -1884,7 +2155,7 @@ void Bot::DeletePetItems(uint32 botPetSaveId) { if(botPetSaveId == 0) return; - std::string query = StringFormat("DELETE FROM botpetinventory WHERE BotPetsId = %u", botPetSaveId); + std::string query = StringFormat("DELETE FROM `bot_pet_inventories` WHERE `pets_index` = %u", botPetSaveId); auto results = database.QueryDatabase(query); } @@ -1892,12 +2163,13 @@ void Bot::DeletePetStats(uint32 botPetSaveId) { if(botPetSaveId == 0) return; - std::string query = StringFormat("DELETE from botpets where BotPetsId = %u", botPetSaveId); + std::string query = StringFormat("DELETE FROM `bot_pets` WHERE `pets_index` = %u", botPetSaveId); auto results = database.QueryDatabase(query); } -void Bot::LoadStance() { - std::string query = StringFormat("SELECT StanceID FROM botstances WHERE BotID = %u", GetBotID()); +void Bot::LoadStance() +{ + std::string query = StringFormat("SELECT `stance_id` FROM `bot_stances` WHERE `bot_id` = %u", GetBotID()); auto results = database.QueryDatabase(query); if(!results.Success() || results.RowCount() == 0) { Log.Out(Logs::General, Logs::Error, "Error in Bot::LoadStance()"); @@ -1912,42 +2184,54 @@ void Bot::SaveStance() { if(_baseBotStance == _botStance) return; - std::string query = StringFormat("REPLACE INTO botstances (BotID, StanceId) VALUES(%u, %u)", GetBotID(), GetBotStance()); + std::string query = StringFormat("REPLACE INTO `bot_stances` (`bot_id`, `stance_id`) VALUES (%u, %u)", GetBotID(), GetBotStance()); auto results = database.QueryDatabase(query); if(!results.Success()) Log.Out(Logs::General, Logs::Error, "Error in Bot::SaveStance()"); } -void Bot::LoadTimers() { - std::string query = StringFormat("SELECT IfNull(bt.TimerID, 0) As TimerID, IfNull(bt.Value, 0) As Value, " - "IfNull(MAX(sn.recast_time), 0) AS MaxTimer FROM bottimers bt, spells_new sn " - "WHERE bt.BotID = %u AND sn.EndurTimerIndex = " - "(SELECT case WHEN TimerID > %i THEN TimerID - %i ELSE TimerID END AS TimerID " - "FROM bottimers WHERE TimerID = bt.TimerID AND BotID = bt.BotID ) " - "AND sn.classes%i <= %i", - GetBotID(), DisciplineReuseStart-1, DisciplineReuseStart-1, GetClass(), GetLevel()); - auto results = database.QueryDatabase(query); +void Bot::LoadTimers() +{ + std::string query = StringFormat( + "SELECT" + " IfNull(bt.`timer_id`, 0) As timer_id," + " IfNull(bt.`timer_value`, 0) As timer_value," + " IfNull(MAX(sn.`recast_time`), 0) AS MaxTimer" + " FROM `bot_timers` bt, `spells_new` sn" + " WHERE bt.`bot_id` = %u AND sn.`EndurTimerIndex` = (" + "SELECT case" + " WHEN timer_id > %i THEN timer_id - %i" + " ELSE timer_id END AS timer_id" + " FROM `bot_timers` WHERE `timer_id` = bt.`timer_id` AND `bot_id` = bt.`bot_id`" // double-check validity + ")" + " AND sn.`classes%i` <= %i", + GetBotID(), + (DisciplineReuseStart - 1), + (DisciplineReuseStart - 1), + GetClass(), + GetLevel() + ); + auto results = database.QueryDatabase(query); if(!results.Success()) { Log.Out(Logs::General, Logs::Error, "Error in Bot::LoadTimers()"); return; } - - int timerID = 0; - uint32 value = 0; - uint32 maxValue = 0; - for (auto row = results.begin(); row != results.end(); ++row) { - timerID = atoi(row[0]) - 1; - value = atoi(row[1]); - maxValue = atoi(row[2]); - if(timerID >= 0 && timerID < MaxTimer && value < (Timer::GetCurrentTime() + maxValue)) - timers[timerID] = value; - } - + + int timerID = 0; + uint32 value = 0; + uint32 maxValue = 0; + for (auto row = results.begin(); row != results.end(); ++row) { + timerID = atoi(row[0]) - 1; + value = atoi(row[1]); + maxValue = atoi(row[2]); + if(timerID >= 0 && timerID < MaxTimer && value < (Timer::GetCurrentTime() + maxValue)) + timers[timerID] = value; + } } void Bot::SaveTimers() { bool hadError = false; - std::string query = StringFormat("DELETE FROM bottimers WHERE BotID = %u", GetBotID()); + std::string query = StringFormat("DELETE FROM `bot_timers` WHERE `bot_id` = %u", GetBotID()); auto results = database.QueryDatabase(query); if(!results.Success()) hadError = true; @@ -1956,7 +2240,7 @@ void Bot::SaveTimers() { if(timers[timerIndex] <= Timer::GetCurrentTime()) continue; - query = StringFormat("REPLACE INTO bottimers (BotID, TimerID, Value) VALUES(%u, %u, %u)", GetBotID(), timerIndex + 1, timers[timerIndex]); + query = StringFormat("REPLACE INTO `bot_timers` (`bot_id`, `timer_id`, `timer_value`) VALUES (%u, %u, %u)", GetBotID(), timerIndex + 1, timers[timerIndex]); results = database.QueryDatabase(query); if(!results.Success()) hadError = true; @@ -2975,28 +3259,28 @@ bool Bot::DeleteBot(std::string* errorMessage) { return false; // TODO: These queries need to be ran together as a transaction.. ie, if one or more fail then they all will fail to commit to the database. - std::string query = StringFormat("DELETE FROM botinventory WHERE botid = '%u'", this->GetBotID()); + std::string query = StringFormat("DELETE FROM `bot_inventories` WHERE `bot_id` = '%u'", this->GetBotID()); auto results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); hadError = true; } - query = StringFormat("DELETE FROM botbuffs WHERE botid = '%u'", this->GetBotID()); + query = StringFormat("DELETE FROM `bot_buffs` WHERE `bot_id` = '%u'", this->GetBotID()); results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); hadError = true; } - query = StringFormat("DELETE FROM botstances WHERE BotID = '%u'", this->GetBotID()); + query = StringFormat("DELETE FROM `bot_stances` WHERE `bot_id` = '%u'", this->GetBotID()); results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); hadError = true; } - query = StringFormat("DELETE FROM bots WHERE BotID = '%u'", this->GetBotID()); + query = StringFormat("DELETE FROM `bot_data` WHERE `bot_id` = '%u'", this->GetBotID()); results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); @@ -3052,28 +3336,61 @@ void Bot::Spawn(Client* botCharacterOwner, std::string* errorMessage) { } // Saves the specified item as an inventory record in the database for this bot. -void Bot::SetBotItemInSlot(uint32 slotID, uint32 itemID, const ItemInst* inst, std::string *errorMessage) { +void Bot::SetBotItemInSlot(uint32 slotID, uint32 itemID, const ItemInst* inst, std::string *errorMessage) +{ uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM }; if (this->GetBotID() == 0 || slotID < EmuConstants::EQUIPMENT_BEGIN || itemID <= NO_ITEM) - return; + return; - if (inst && inst->IsType(ItemClassCommon)) { - for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) { - ItemInst* auginst = inst->GetItem(i); - augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : 0; - } - } + if (inst && inst->IsType(ItemClassCommon)) { + for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) { + ItemInst* auginst = inst->GetItem(i); + augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : 0; + } + } - std::string query = StringFormat("REPLACE INTO botinventory (botid, slotid, itemid, charges, instnodrop, color, " - "augslot1, augslot2, augslot3, augslot4, augslot5) " - "VALUES(%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu)", - (unsigned long)this->GetBotID(), (unsigned long)slotID, (unsigned long)itemID, - (unsigned long)inst->GetCharges(), (unsigned long)(inst->IsAttuned()? 1: 0), - (unsigned long)inst->GetColor(), (unsigned long)augslot[0], (unsigned long)augslot[1], - (unsigned long)augslot[2], (unsigned long)augslot[3], (unsigned long)augslot[4]); - auto results = database.QueryDatabase(query); - if(!results.Success()) - *errorMessage = std::string(results.ErrorMessage()); + std::string query = StringFormat( + "REPLACE INTO `bot_inventories` (" + "`bot_id`," + " `slot_id`," + " `item_id`," + " `inst_charges`," + " `inst_color`," + " `inst_no_drop`," + " `augment_1`," + " `augment_2`," + " `augment_3`," + " `augment_4`," + " `augment_5`" + ")" + " VALUES (" + "%lu," /*bot_id*/ + " %lu," /*slot_id*/ + " %lu," /*item_id*/ + " %lu," /*inst_charges*/ + " %lu," /*inst_color*/ + " %lu," /*inst_no_drop*/ + " %lu," /*augment_1*/ + " %lu," /*augment_2*/ + " %lu," /*augment_3*/ + " %lu," /*augment_4*/ + " %lu" /*augment_5*/ + ")", + (unsigned long)this->GetBotID(), + (unsigned long)slotID, + (unsigned long)itemID, + (unsigned long)inst->GetCharges(), + (unsigned long)inst->GetColor(), + (unsigned long)(inst->IsAttuned()? 1: 0), // does this match the current flag implementation? + (unsigned long)augslot[0], + (unsigned long)augslot[1], + (unsigned long)augslot[2], + (unsigned long)augslot[3], + (unsigned long)augslot[4] + ); + auto results = database.QueryDatabase(query); + if(!results.Success()) + *errorMessage = std::string(results.ErrorMessage()); } // Deletes the inventory record for the specified item from the database for this bot. @@ -3081,7 +3398,7 @@ void Bot::RemoveBotItemBySlot(uint32 slotID, std::string *errorMessage) { if(this->GetBotID() == 0) return; - std::string query = StringFormat("DELETE FROM botinventory WHERE botid = %i AND slotid = %i", this->GetBotID(), slotID); + std::string query = StringFormat("DELETE FROM `bot_inventories` WHERE `bot_id` = %i AND `slot_id` = %i", this->GetBotID(), slotID); auto results = database.QueryDatabase(query); if(!results.Success()) *errorMessage = std::string(results.ErrorMessage()); @@ -3091,61 +3408,75 @@ void Bot::RemoveBotItemBySlot(uint32 slotID, std::string *errorMessage) { } // Retrieves all the inventory records from the database for this bot. -void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) { +void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) +{ if(this->GetBotID() == 0) - return; + return; - std::string query = StringFormat("SELECT slotid, itemid, charges, color, " - "augslot1, augslot2, augslot3, augslot4, " - "augslot5, instnodrop FROM botinventory " - "WHERE botid = %i ORDER BY slotid", this->GetBotID()); - auto results = database.QueryDatabase(query); - if (!results.Success()) { - *errorMessage = std::string(results.ErrorMessage()); - return; - } - - for (auto row = results.begin(); row != results.end(); ++row) { - int16 slot_id = atoi(row[0]); - uint32 item_id = atoi(row[1]); - uint16 charges = atoi(row[2]); - uint32 color = atoul(row[3]); - uint32 aug[EmuConstants::ITEM_COMMON_SIZE]; - aug[0] = (uint32)atoul(row[4]); - aug[1] = (uint32)atoul(row[5]); - aug[2] = (uint32)atoul(row[6]); - aug[3] = (uint32)atoul(row[7]); - aug[4] = (uint32)atoul(row[8]); - bool instnodrop = (row[9] && (uint16)atoi(row[9])) ? true : false; - ItemInst* inst = database.CreateItem(item_id, charges, aug[0], aug[1], aug[2], aug[3], aug[4]); - if (!inst) { - Log.Out(Logs::General, Logs::Error, "Warning: botid %i has an invalid item_id %i in inventory slot %i", this->GetBotID(), item_id, slot_id); - continue; - } - - int16 put_slot_id = INVALID_INDEX; - - if (instnodrop || (((slot_id >= EmuConstants::EQUIPMENT_BEGIN) && (slot_id <= EmuConstants::EQUIPMENT_END) || slot_id == 9999) && inst->GetItem()->Attuneable)) - inst->SetAttuned(true); - - if (color > 0) - inst->SetColor(color); - - if (charges == 255) - inst->SetCharges(-1); - else - inst->SetCharges(charges); - - if (slot_id < 8000 || slot_id > 8999) - put_slot_id = inv.PutItem(slot_id, *inst); - - safe_delete(inst); - - // Save ptr to item in inventory - if (put_slot_id == INVALID_INDEX) - Log.Out(Logs::General, Logs::Error, "Warning: Invalid slot_id for item in inventory: botid=%i, item_id=%i, slot_id=%i",this->GetBotID(), item_id, slot_id); - } + std::string query = StringFormat( + "SELECT" + " `slot_id`," + " `item_id`," + " `inst_charges`," + " `inst_color`," + " `augment_1`," + " `augment_2`," + " `augslot_3`," + " `augslot_4`, " + " `augslot_5`," + " `inst_no_drop`" + " FROM `bot_inventories`" + " WHERE `bot_id` = %i" + " ORDER BY `slot_id`", + this->GetBotID() + ); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + *errorMessage = std::string(results.ErrorMessage()); + return; + } + for (auto row = results.begin(); row != results.end(); ++row) { + int16 slot_id = atoi(row[0]); + uint32 item_id = atoi(row[1]); + uint16 charges = atoi(row[2]); + uint32 color = atoul(row[3]); + uint32 aug[EmuConstants::ITEM_COMMON_SIZE]; + aug[0] = (uint32)atoul(row[4]); + aug[1] = (uint32)atoul(row[5]); + aug[2] = (uint32)atoul(row[6]); + aug[3] = (uint32)atoul(row[7]); + aug[4] = (uint32)atoul(row[8]); + bool instnodrop = (row[9] && (uint16)atoi(row[9])) ? true : false; + ItemInst* inst = database.CreateItem(item_id, charges, aug[0], aug[1], aug[2], aug[3], aug[4]); + if (!inst) { + Log.Out(Logs::General, Logs::Error, "Warning: bot_id %i has an invalid item_id %i in inventory slot %i", this->GetBotID(), item_id, slot_id); + continue; + } + + int16 put_slot_id = INVALID_INDEX; + + if (instnodrop || (((slot_id >= EmuConstants::EQUIPMENT_BEGIN) && (slot_id <= EmuConstants::EQUIPMENT_END) || slot_id == 9999) && inst->GetItem()->Attuneable)) + inst->SetAttuned(true); + + if (color > 0) + inst->SetColor(color); + + if (charges == 255) + inst->SetCharges(-1); + else + inst->SetCharges(charges); + + if (slot_id < 8000 || slot_id > 8999) + put_slot_id = inv.PutItem(slot_id, *inst); + + safe_delete(inst); + + // Save ptr to item in inventory + if (put_slot_id == INVALID_INDEX) + Log.Out(Logs::General, Logs::Error, "Warning: Invalid slot_id for item in inventory: bot_id=%i, item_id=%i, slot_id=%i",this->GetBotID(), item_id, slot_id); + } + UpdateEquipmentLight(); } @@ -3154,7 +3485,7 @@ uint32 Bot::GetBotItemBySlot(uint32 slotID) { if(this->GetBotID() == 0 || slotID < EmuConstants::EQUIPMENT_BEGIN) return 0; - std::string query = StringFormat("SELECT itemid FROM botinventory WHERE botid = %i AND slotid = %i", GetBotID(), slotID); + std::string query = StringFormat("SELECT `item_id` FROM `bot_inventories` WHERE `bot_id` = %i AND `slot_id` = %i", GetBotID(), slotID); auto results = database.QueryDatabase(query); if(!results.Success() || results.RowCount() != 1) return 0; @@ -3168,7 +3499,7 @@ uint32 Bot::GetBotItemsCount(std::string *errorMessage) { if(this->GetBotID() == 0) return 0; - std::string query = StringFormat("SELECT COUNT(*) FROM botinventory WHERE botid = %i", this->GetBotID()); + std::string query = StringFormat("SELECT COUNT(*) FROM `bot_inventories` WHERE `bot_id` = %i", this->GetBotID()); auto results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); @@ -3302,7 +3633,7 @@ uint32 Bot::GetBotIDByBotName(std::string botName) { if(botName.empty()) return 0; - std::string query = StringFormat("SELECT BotID FROM bots WHERE Name = '%s'", botName.c_str()); + std::string query = StringFormat("SELECT `bot_id` FROM `bot_data` WHERE `name` = '%s'", botName.c_str()); auto results = database.QueryDatabase(query); if(!results.Success() || results.RowCount() == 0) return 0; @@ -3311,58 +3642,134 @@ uint32 Bot::GetBotIDByBotName(std::string botName) { return atoi(row[0]); } -Bot* Bot::LoadBot(uint32 botID, std::string* errorMessage) { +Bot* Bot::LoadBot(uint32 botID, std::string* errorMessage) +{ Bot* loadedBot = nullptr; if(botID == 0) - return nullptr; + return nullptr; + + std::string query = StringFormat( + "SELECT" + " `owner_id`," + " `spells_id`," + " `name`," + " `last_name`," + " `level`," + " `race`," + " `class`," + " `gender`," + " `size`," + " `face`," + " `hair_style`," + " `hair_color`," + " `eye_color_1`," + " `eye_color_2`," + " `beard_color`," + " `beard`," + " `drakkin_heritage`," + " `drakkin_tattoo`," + " `drakkin_details`," + " `hp`," + " `mana`," + " `magic`," + " `cold`," + " `disease`," + " `fire`," + " `poison`," + " `corruption`," + " `ac`," + " `str`," + " `sta`," + " `dex`," + " `agi`," + " `int`," + " `wis`," + " `cha`," + " `atk`," + " `creation_day`," + " `last_spawn`," + " `time_spawned`," + " `zone_id`" + " FROM `bot_data`" + " WHERE `bot_id` = '%u'", + botID + ); + auto results = database.QueryDatabase(query); + if(!results.Success()) { + *errorMessage = std::string(results.ErrorMessage()); + return nullptr; + } - std::string query = StringFormat("SELECT BotOwnerCharacterID, BotSpellsID, Name, LastName, BotLevel, " - "Race, Class, Gender, Size, Face, LuclinHairStyle, LuclinHairColor, " - "LuclinEyeColor, LuclinEyeColor2, LuclinBeardColor, LuclinBeard, " - "DrakkinHeritage, DrakkinTattoo, DrakkinDetails, HP, Mana, MR, CR, " - "DR, FR, PR, Corrup, AC, STR, STA, DEX, AGI, _INT, WIS, CHA, ATK, " - "BotCreateDate, LastSpawnDate, TotalPlayTime, LastZoneId " - "FROM bots WHERE BotID = '%u'", botID); - auto results = database.QueryDatabase(query); - if(!results.Success()) { - *errorMessage = std::string(results.ErrorMessage()); - return nullptr; - } - - if (results.RowCount() == 0) - return nullptr; - - auto row = results.begin(); - NPCType defaultNPCTypeStruct = CreateDefaultNPCTypeStructForBot(std::string(row[2]), std::string(row[3]), atoi(row[4]), atoi(row[5]), atoi(row[6]), atoi(row[7])); - NPCType tempNPCStruct = FillNPCTypeStruct(atoi(row[1]), std::string(row[2]), std::string(row[3]), atoi(row[4]), - atoi(row[5]), atoi(row[6]), atoi(row[7]), atof(row[8]), atoi(row[9]), - atoi(row[10]), atoi(row[11]), atoi(row[12]), atoi(row[13]), atoi(row[14]), - atoi(row[15]), atoi(row[16]), atoi(row[17]), atoi(row[18]), atoi(row[19]), - atoi(row[20]), defaultNPCTypeStruct.MR, defaultNPCTypeStruct.CR, - defaultNPCTypeStruct.DR, defaultNPCTypeStruct.FR, defaultNPCTypeStruct.PR, - defaultNPCTypeStruct.Corrup, defaultNPCTypeStruct.AC, defaultNPCTypeStruct.STR, - defaultNPCTypeStruct.STA, defaultNPCTypeStruct.DEX, defaultNPCTypeStruct.AGI, - defaultNPCTypeStruct.INT, defaultNPCTypeStruct.WIS, defaultNPCTypeStruct.CHA, - defaultNPCTypeStruct.ATK); - loadedBot = new Bot(botID, atoi(row[0]), atoi(row[1]), atof(row[38]), atoi(row[39]), tempNPCStruct); + if (results.RowCount() == 0) + return nullptr; + + auto row = results.begin(); + NPCType defaultNPCTypeStruct = CreateDefaultNPCTypeStructForBot(std::string(row[2]), std::string(row[3]), atoi(row[4]), atoi(row[5]), atoi(row[6]), atoi(row[7])); + NPCType tempNPCStruct = FillNPCTypeStruct( + atoi(row[1]), + std::string(row[2]), + std::string(row[3]), + atoi(row[4]), + atoi(row[5]), + atoi(row[6]), + atoi(row[7]), + atof(row[8]), + atoi(row[9]), + atoi(row[10]), + atoi(row[11]), + atoi(row[12]), + atoi(row[13]), + atoi(row[14]), + atoi(row[15]), + atoi(row[16]), + atoi(row[17]), + atoi(row[18]), + atoi(row[19]), + atoi(row[20]), + defaultNPCTypeStruct.MR, + defaultNPCTypeStruct.CR, + defaultNPCTypeStruct.DR, + defaultNPCTypeStruct.FR, + defaultNPCTypeStruct.PR, + defaultNPCTypeStruct.Corrup, + defaultNPCTypeStruct.AC, + defaultNPCTypeStruct.STR, + defaultNPCTypeStruct.STA, + defaultNPCTypeStruct.DEX, + defaultNPCTypeStruct.AGI, + defaultNPCTypeStruct.INT, + defaultNPCTypeStruct.WIS, + defaultNPCTypeStruct.CHA, + defaultNPCTypeStruct.ATK + ); + loadedBot = new Bot(botID, atoi(row[0]), atoi(row[1]), atof(row[38]), atoi(row[39]), tempNPCStruct); return loadedBot; } -std::list Bot::GetGroupedBotsByGroupId(uint32 groupId, std::string* errorMessage) { +std::list Bot::GetGroupedBotsByGroupId(uint32 groupId, std::string* errorMessage) +{ std::list groupedBots; if(groupId == 0) - return groupedBots; - - std::string query = StringFormat("SELECT g.mobid AS BotID FROM vwGroups AS g JOIN bots AS b ON g.mobid = b.BotId AND g.mobtype = 'B' WHERE g.groupid = %u", groupId); - auto results = database.QueryDatabase(query); + return groupedBots; + + std::string query = StringFormat( + "SELECT g.`mob_id` AS bot_id" + " FROM `vw_groups` AS g" + " JOIN `bot_data` AS b" + " ON g.`mob_id` = b.`bot_id`" + " AND g.`mob_type` = 'B'" + " WHERE g.`group_id` = %u", + groupId + ); + auto results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); return groupedBots; } - for (auto row = results.begin(); row != results.end(); ++row) - groupedBots.push_back(atoi(row[0])); - + for (auto row = results.begin(); row != results.end(); ++row) + groupedBots.push_back(atoi(row[0])); + return groupedBots; } @@ -3421,7 +3828,7 @@ std::list Bot::GetBotList(uint32 botOwnerCharacterID, std::st if(botOwnerCharacterID == 0) return ownersBots; - std::string query = StringFormat("SELECT BotID, Name, Class, BotLevel, Race FROM bots WHERE BotOwnerCharacterID = '%u'", botOwnerCharacterID); + std::string query = StringFormat("SELECT `bot_id`, `name`, `class`, `level`, `race` FROM `bot_data` WHERE `owner_id` = '%u'", botOwnerCharacterID); auto results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); @@ -3442,9 +3849,10 @@ std::list Bot::GetBotList(uint32 botOwnerCharacterID, std::st std::list Bot::ListSpawnedBots(uint32 characterID, std::string* errorMessage) { std::list spawnedBots; - if(characterID == 0) - return spawnedBots; + //if(characterID == 0) + return spawnedBots; + // Dead table..function needs to be updated or removed (no calls listed to Bot::ListSpawnedBots()) std::string query = StringFormat("SELECT bot_name, zone_name FROM botleader WHERE leaderid = %i", characterID); auto results = database.QueryDatabase(query); if(!results.Success()) { @@ -3473,7 +3881,7 @@ void Bot::SaveBotGroup(Group* botGroup, std::string botGroupName, std::string* e uint32 botGroupId = 0; uint32 botGroupLeaderBotId = tempGroupLeader->CastToBot()->GetBotID(); - std::string query = StringFormat("INSERT INTO botgroup (BotGroupLeaderBotId, BotGroupName) VALUES (%u, '%s')", botGroupLeaderBotId, botGroupName.c_str()); + std::string query = StringFormat("INSERT INTO `bot_groups` (`group_leader_id`, `group_name`) VALUES (%u, '%s')", botGroupLeaderBotId, botGroupName.c_str()); auto results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); @@ -3489,7 +3897,7 @@ void Bot::SaveBotGroup(Group* botGroup, std::string botGroupName, std::string* e continue; uint32 botGroupMemberBotId = tempBot->CastToBot()->GetBotID(); - query = StringFormat("INSERT INTO botgroupmembers (BotGroupId, BotId) VALUES (%u, %u)", botGroupId, botGroupMemberBotId); + query = StringFormat("INSERT INTO `bot_group_members` (`groups_index`, `bot_id`) VALUES (%u, %u)", botGroupId, botGroupMemberBotId); results = database.QueryDatabase(query); if(!results.Success()) *errorMessage = std::string(results.ErrorMessage()); @@ -3505,14 +3913,14 @@ void Bot::DeleteBotGroup(std::string botGroupName, std::string* errorMessage) { if(!errorMessage->empty() || botGroupId== 0) return; - std::string query = StringFormat("DELETE FROM botgroupmembers WHERE BotGroupId = %u", botGroupId); + std::string query = StringFormat("DELETE FROM `bot_group_members` WHERE `groups_index` = %u", botGroupId); auto results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); return; } - query = StringFormat("DELETE FROM botgroup WHERE BotGroupId = %u", botGroupId); + query = StringFormat("DELETE FROM `bot_groups` WHERE `groups_index` = %u", botGroupId); results = database.QueryDatabase(query); if(!results.Success()) *errorMessage = std::string(results.ErrorMessage()); @@ -3527,7 +3935,7 @@ std::list Bot::LoadBotGroup(std::string botGroupName, std::string* err if(botGroupId == 0) return botGroup; - std::string query = StringFormat("SELECT BotId FROM botgroupmembers WHERE BotGroupId = %u", botGroupId); + std::string query = StringFormat("SELECT `bot_id` FROM `bot_group_members` WHERE `groups_index` = %u", botGroupId); auto results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); @@ -3548,7 +3956,7 @@ std::list Bot::GetBotGroupListByBotOwnerCharacterId(uint32 botOwne if(botOwnerCharacterId == 0) return botGroups; - std::string query = StringFormat("SELECT BotGroupName, BotGroupLeaderName FROM vwBotGroups WHERE BotOwnerCharacterId = %u", botOwnerCharacterId); + std::string query = StringFormat("SELECT `group_name`, `group_leader_name` FROM `vw_bot_groups` WHERE `owner_id` = %u", botOwnerCharacterId); auto results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); @@ -3568,7 +3976,7 @@ bool Bot::DoesBotGroupNameExist(std::string botGroupName) { if(botGroupName.empty()) return false; - std::string query = StringFormat("SELECT BotGroupId FROM vwBotGroups WHERE BotGroupName = '%s'", botGroupName.c_str()); + std::string query = StringFormat("SELECT `groups_index` FROM `vw_bot_groups` WHERE `group_name` = '%s'", botGroupName.c_str()); auto results = database.QueryDatabase(query); if (!results.Success() || results.RowCount() == 0) return false; @@ -3587,7 +3995,7 @@ uint32 Bot::CanLoadBotGroup(uint32 botOwnerCharacterId, std::string botGroupName if(botOwnerCharacterId == 0 || botGroupName.empty()) return 0; - std::string query = StringFormat("SELECT BotGroupId, BotGroupName FROM vwBotGroups WHERE BotOwnerCharacterId = %u", botOwnerCharacterId); + std::string query = StringFormat("SELECT `groups_index`, `group_name` FROM `vw_bot_groups` WHERE `owner_id` = %u", botOwnerCharacterId); auto results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); @@ -3611,7 +4019,7 @@ uint32 Bot::GetBotGroupIdByBotGroupName(std::string botGroupName, std::string* e if(botGroupName.empty()) return 0; - std::string query = StringFormat("SELECT BotGroupId FROM vwBotGroups WHERE BotGroupName = '%s'", botGroupName.c_str()); + std::string query = StringFormat("SELECT `groups_index` FROM `vw_bot_groups` WHERE `group_name` = '%s'", botGroupName.c_str()); auto results = database.QueryDatabase(query); if(!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); @@ -3629,7 +4037,7 @@ uint32 Bot::GetBotGroupLeaderIdByBotGroupName(std::string botGroupName) { if(botGroupName.empty()) return 0; - std::string query = StringFormat("SELECT BotGroupLeaderBotId FROM vwBotGroups WHERE BotGroupName = '%s'", botGroupName.c_str()); + std::string query = StringFormat("SELECT `group_leader_id` FROM `vw_bot_groups` WHERE `group_name` = '%s'", botGroupName.c_str()); auto results = database.QueryDatabase(query); if (!results.Success() || results.RowCount() == 0) return 0; @@ -3669,7 +4077,7 @@ uint32 Bot::CreatedBotCount(uint32 botOwnerCharacterID, std::string* errorMessag if(botOwnerCharacterID == 0) return 0; - std::string query = StringFormat("SELECT COUNT(BotID) FROM bots WHERE BotOwnerCharacterID=%i", botOwnerCharacterID); + std::string query = StringFormat("SELECT COUNT(`bot_id`) FROM `bot_data` WHERE `owner_id` = %i", botOwnerCharacterID); auto results = database.QueryDatabase(query); if (!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); @@ -3688,7 +4096,7 @@ uint32 Bot::GetBotOwnerCharacterID(uint32 botID, std::string* errorMessage) { if(botID == 0) return 0; - std::string query = StringFormat("SELECT BotOwnerCharacterID FROM bots WHERE BotID = %u", botID); + std::string query = StringFormat("SELECT `owner_id` FROM `bot_data` WHERE `bot_id` = %u", botID); auto results = database.QueryDatabase(query); if (!results.Success()) { *errorMessage = std::string(results.ErrorMessage()); @@ -6415,28 +6823,40 @@ void Bot::SetBotGuildMembership(uint32 botId, uint32 guildid, uint8 rank) { return; if(guildid > 0) { - std::string query = StringFormat("REPLACE INTO botguildmembers SET char_id = %u, guild_id = %u, rank = %u", botId, guildid, rank); + std::string query = StringFormat("REPLACE INTO `bot_guild_members` SET `bot_id` = %u, `guild_id` = %u, `rank` = %u", botId, guildid, rank); auto results = database.QueryDatabase(query); return; } - std::string query = StringFormat("DELETE FROM botguildmembers WHERE char_id = %u", botId); + std::string query = StringFormat("DELETE FROM `bot_guild_members` WHERE `bot_id` = %u", botId); auto results = database.QueryDatabase(query); } -void Bot::LoadGuildMembership(uint32* guildId, uint8* guildRank, std::string* guildName) { +void Bot::LoadGuildMembership(uint32* guildId, uint8* guildRank, std::string* guildName) +{ if(guildId == nullptr || guildRank == nullptr || guildName == nullptr) - return; - - std::string query = StringFormat("SELECT gm.guild_id, gm.rank, g.name FROM vwGuildMembers AS gm JOIN guilds AS g ON gm.guild_id = g.id WHERE gm.char_id = %u AND gm.mobtype = 'B'", GetBotID()); - auto results = database.QueryDatabase(query); - if(!results.Success() || results.RowCount() == 0) - return; - - auto row = results.begin(); - *guildId = atoi(row[0]); - *guildRank = atoi(row[1]); - *guildName = std::string(row[2]); + return; + + std::string query = StringFormat( + "SELECT" + " gm.`guild_id`," + " gm.`rank`," + " g.`name`" + " FROM `vw_guild_members` AS gm" + " JOIN `guilds` AS g" + " ON gm.`guild_id` = g.`id`" + " WHERE gm.`char_id` = %u" + " AND gm.`mob_type` = 'B'", + GetBotID() + ); + auto results = database.QueryDatabase(query); + if(!results.Success() || results.RowCount() == 0) + return; + + auto row = results.begin(); + *guildId = atoi(row[0]); + *guildRank = atoi(row[1]); + *guildName = std::string(row[2]); } int32 Bot::CalcMaxMana() { @@ -7189,7 +7609,7 @@ bool Bot::DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, uint16 slot bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, uint16 slot, bool& stopLogic) { if(spellTarget) { - if(IsGrouped() && (spellTarget->IsBot() || spellTarget->IsClient()) && RuleB(Bots, BotGroupBuffing)) { + if(IsGrouped() && (spellTarget->IsBot() || spellTarget->IsClient()) && RuleB(Bots, GroupBuffing)) { bool noGroupSpell = false; uint16 thespell = spell_id; for(int i = 0; i < AIspells.size(); i++) { @@ -7725,7 +8145,7 @@ int32 Bot::CalcManaRegen() { regen += aabonuses.ManaRegen; regen = ((regen * RuleI(Character, ManaRegenMultiplier)) / 100); - float mana_regen_rate = RuleR(Bots, BotManaRegen); + float mana_regen_rate = RuleR(Bots, ManaRegen); if(mana_regen_rate < 0.0f) mana_regen_rate = 0.0f; @@ -8847,7 +9267,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { std::string query; if (setslot == -1) { int slots[] = { 2, 7, 9, 12, 17, 18, 19 }; - query = StringFormat("UPDATE botinventory SET color = %u WHERE slotID IN (2, 7, 9, 12, 17, 18, 19) AND botID = %u", setcolor, botid); + query = StringFormat("UPDATE `bot_inventories` SET `inst_color` = %u WHERE `slot_id` IN (2, 7, 9, 12, 17, 18, 19) AND `bot_id` = %u", setcolor, botid); auto results = database.QueryDatabase(query); if (!results.Success()) return; @@ -8857,7 +9277,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { c->GetTarget()->CastToBot()->SendWearChange(slotmaterial); } } else { - query = StringFormat("UPDATE botinventory SET color = %u WHERE slotID = %i AND botID = %u", setcolor, setslot, botid); + query = StringFormat("UPDATE `bot_inventories` SET `inst_color` = %u WHERE `slot_id` = %i AND `bot_id` = %u", setcolor, setslot, botid); auto results = database.QueryDatabase(query); if (!results.Success()) return; @@ -8934,7 +9354,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { return; } - uint32 MaxBotCreate = RuleI(Bots, CreateBotCount); + uint32 MaxBotCreate = RuleI(Bots, CreationLimit); if(CreatedBotCount(c->CharacterID(), &TempErrorMessage) >= MaxBotCreate) { c->Message(0, "You cannot create more than %i bots.", MaxBotCreate); return; @@ -9135,7 +9555,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { return; } - if(RuleB(Bots, BotQuest) && !c->GetGM()) { + if(RuleB(Bots, QuestableSpawnLimit) && !c->GetGM()) { const int allowedBots = AllowedBotSpawns(c->CharacterID(), &TempErrorMessage); if(!TempErrorMessage.empty()) { c->Message(13, "Database Error: %s", TempErrorMessage.c_str()); @@ -9154,7 +9574,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { } - if(spawnedBotCount >= RuleI(Bots, SpawnBotCount) && !c->GetGM()) { + if(spawnedBotCount >= RuleI(Bots, SpawnLimit) && !c->GetGM()) { c->Message(0, "You cannot spawn more than %i bots.", spawnedBotCount); return; } @@ -11206,7 +11626,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { return; } - if(RuleB(Bots, BotQuest)) { + if(RuleB(Bots, QuestableSpawnLimit)) { const int allowedBotsBQ = AllowedBotSpawns(c->CharacterID(), &TempErrorMessage); if(!TempErrorMessage.empty()) { c->Message(13, "Database Error: %s", TempErrorMessage.c_str()); @@ -11224,7 +11644,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { } } - const int allowedBotsSBC = RuleI(Bots, SpawnBotCount); + const int allowedBotsSBC = RuleI(Bots, SpawnLimit); if(spawnedBots >= allowedBotsSBC || spawnedBots + (int)botGroup.size() > allowedBotsSBC) { c->Message(0, "You can't spawn more than %i bots.", allowedBotsSBC); return; @@ -12651,7 +13071,7 @@ uint32 Bot::GetEquipmentColor(uint8 material_slot) const { if (slotid == INVALID_INDEX) return 0; - std::string query = StringFormat("SELECT color FROM botinventory WHERE BotID = %u AND SlotID = %u", botid, slotid); + std::string query = StringFormat("SELECT `inst_color` FROM `bot_inventories` WHERE `bot_id` = %u AND `slot_id` = %u", botid, slotid); auto results = database.QueryDatabase(query); if (!results.Success() || results.RowCount() != 1) return 0; diff --git a/zone/botspellsai.cpp b/zone/botspellsai.cpp index cd8d28275..66afc345d 100644 --- a/zone/botspellsai.cpp +++ b/zone/botspellsai.cpp @@ -883,7 +883,7 @@ bool Bot::AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain int32 hasMana = GetMana(); // Allow bots to cast buff spells even if they are out of mana - if(RuleB(Bots, BotFinishBuffing)) { + if(RuleB(Bots, FinishBuffing)) { if(manaCost > hasMana) { // Let's have the bots complete the buff time process if(AIspells[i].type & SpellType_Buff) { diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index a15724325..fd157f372 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -2041,23 +2041,23 @@ void QuestManager::popup(const char *title, const char *text, uint32 popupid, ui #ifdef BOTS int QuestManager::createbotcount() { - return RuleI(Bots, CreateBotCount); + return RuleI(Bots, CreationLimit); } int QuestManager::spawnbotcount() { - return RuleI(Bots, SpawnBotCount); + return RuleI(Bots, SpawnLimit); } bool QuestManager::botquest() { - return RuleB(Bots, BotQuest); + return RuleB(Bots, QuestableSpawnLimit); } bool QuestManager::createBot(const char *name, const char *lastname, uint8 level, uint16 race, uint8 botclass, uint8 gender) { QuestManagerCurrentQuestVars(); std::string TempErrorMessage; - uint32 MaxBotCreate = RuleI(Bots, CreateBotCount); + uint32 MaxBotCreate = RuleI(Bots, CreationLimit); if (initiator && initiator->IsClient()) {