diff --git a/common/version.h b/common/version.h index f7a161dc1..c9bb6d361 100644 --- a/common/version.h +++ b/common/version.h @@ -34,7 +34,7 @@ #define CURRENT_BINARY_DATABASE_VERSION 9141 #ifdef BOTS - #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9024 + #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9025 #else #define CURRENT_BINARY_BOTS_DATABASE_VERSION 0 // must be 0 #endif diff --git a/utils/sql/git/bots/bots_db_update_manifest.txt b/utils/sql/git/bots/bots_db_update_manifest.txt index 982200f2a..405cf3f5c 100644 --- a/utils/sql/git/bots/bots_db_update_manifest.txt +++ b/utils/sql/git/bots/bots_db_update_manifest.txt @@ -23,6 +23,7 @@ 9022|2019_02_07_bots_stance_type_update.sql|SELECT * FROM `bot_spell_casting_chances` WHERE `spell_type_index` = '255' AND `class_id` = '255' AND `stance_index` = '0'|not_empty| 9023|2019_06_22_bots_owner_option_stats_update.sql|SHOW COLUMNS FROM `bot_owner_options` LIKE 'stats_update'|empty| 9024|2019_06_27_bots_pet_get_lost.sql|SELECT `bot_command` FROM `bot_command_settings` WHERE `bot_command` LIKE 'petgetlost'|empty| +9025|2019_08_26_bots_owner_option_spawn_message.sql|SHOW COLUMNS FROM `bot_owner_options` LIKE 'spawn_message_enabled'|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/required/2019_08_26_bots_owner_option_spawn_message.sql b/utils/sql/git/bots/required/2019_08_26_bots_owner_option_spawn_message.sql new file mode 100644 index 000000000..04910cd10 --- /dev/null +++ b/utils/sql/git/bots/required/2019_08_26_bots_owner_option_spawn_message.sql @@ -0,0 +1,2 @@ +ALTER TABLE `bot_owner_options` ADD COLUMN `spawn_message_enabled` SMALLINT(3) UNSIGNED NULL DEFAULT '1' AFTER `stats_update`; +ALTER TABLE `bot_owner_options` ADD COLUMN `spawn_message_type` SMALLINT(3) UNSIGNED NULL DEFAULT '1' AFTER `spawn_message_enabled`; diff --git a/zone/bot_command.cpp b/zone/bot_command.cpp index 37c11e882..31270cc0f 100644 --- a/zone/bot_command.cpp +++ b/zone/bot_command.cpp @@ -95,6 +95,7 @@ namespace enum { EffectIDFirst = 1, EffectIDLast = 12 }; +#define VALIDATECLASSID(x) ((x >= WARRIOR && x <= BERSERKER) ? (x) : (0)) #define CLASSIDTOINDEX(x) ((x >= WARRIOR && x <= BERSERKER) ? (x - 1) : (0)) #define EFFECTIDTOINDEX(x) ((x >= EffectIDFirst && x <= EffectIDLast) ? (x - 1) : (0)) #define AILMENTIDTOINDEX(x) ((x >= BCEnum::AT_Blindness && x <= BCEnum::AT_Corruption) ? (x - 1) : (0)) @@ -3443,16 +3444,17 @@ void bot_command_owner_option(Client *c, const Seperator *sep) { if (helper_is_help_or_usage(sep->arg[1])) { c->Message(m_usage, "usage: %s [deathmarquee | statsupdate] (argument: enable | disable | null (toggles))", sep->arg[0]); + c->Message(m_usage, "usage: %s [spawnmessage] [argument: say | tell | silent | class | default]", sep->arg[0]); return; } std::string owner_option = sep->arg[1]; - std::string flag = sep->arg[2]; + std::string argument = sep->arg[2]; if (!owner_option.compare("deathmarquee")) { - if (!flag.compare("enable")) + if (!argument.compare("enable")) c->SetBotOptionDeathMarquee(true); - else if (!flag.compare("disable")) + else if (!argument.compare("disable")) c->SetBotOptionDeathMarquee(false); else c->SetBotOptionDeathMarquee(!c->GetBotOptionDeathMarquee()); @@ -3461,9 +3463,9 @@ void bot_command_owner_option(Client *c, const Seperator *sep) c->Message(m_action, "Bot 'death marquee' is now %s.", (c->GetBotOptionDeathMarquee() == true ? "enabled" : "disabled")); } else if (!owner_option.compare("statsupdate")) { - if (!flag.compare("enable")) + if (!argument.compare("enable")) c->SetBotOptionStatsUpdate(true); - else if (!flag.compare("disable")) + else if (!argument.compare("disable")) c->SetBotOptionStatsUpdate(false); else c->SetBotOptionStatsUpdate(!c->GetBotOptionStatsUpdate()); @@ -3471,6 +3473,35 @@ void bot_command_owner_option(Client *c, const Seperator *sep) database.botdb.SaveOwnerOptionStatsUpdate(c->CharacterID(), c->GetBotOptionStatsUpdate()); c->Message(m_action, "Bot 'stats update' is now %s.", (c->GetBotOptionStatsUpdate() == true ? "enabled" : "disabled")); } + else if (!owner_option.compare("spawnmessage")) { + if (!argument.compare("say")) { + c->SetBotOptionSpawnMessageSay(); + } + else if (!argument.compare("tell")) { + c->SetBotOptionSpawnMessageTell(); + } + else if (!argument.compare("silent")) { + c->SetBotOptionSpawnMessageSilent(); + } + else if (!argument.compare("class")) { + c->SetBotOptionSpawnMessageClassSpecific(true); + } + else if (!argument.compare("default")) { + c->SetBotOptionSpawnMessageClassSpecific(false); + } + else { + c->Message(m_fail, "Owner option '%s' argument '%s' is not recognized.", owner_option.c_str(), argument.c_str()); + return; + } + + database.botdb.SaveOwnerOptionSpawnMessage( + c->CharacterID(), + c->GetBotOptionSpawnMessageSay(), + c->GetBotOptionSpawnMessageTell(), + c->GetBotOptionSpawnMessageClassSpecific() + ); + c->Message(m_action, "Bot 'spawn message' is now %s.", argument.c_str()); + } else { c->Message(m_fail, "Owner option '%s' is not recognized.", owner_option.c_str()); } @@ -5169,8 +5200,9 @@ void bot_subcommand_bot_spawn(Client *c, const Seperator *sep) return; } - static const char* bot_spawn_message[16] = { - "A solid weapon is my ally!", // WARRIOR / 'generic' + static const char* bot_spawn_message[17] = { + "I am ready to fight!", // DEFAULT + "A solid weapon is my ally!", // WARRIOR "The pious shall never die!", // CLERIC "I am the symbol of Light!", // PALADIN "There are enemies near!", // RANGER @@ -5188,7 +5220,14 @@ void bot_subcommand_bot_spawn(Client *c, const Seperator *sep) "My bloodthirst shall not be quenched!" // BERSERKER }; - Bot::BotGroupSay(my_bot, "%s", bot_spawn_message[CLASSIDTOINDEX(my_bot->GetClass())]); + uint8 message_index = 0; + if (c->GetBotOptionSpawnMessageClassSpecific()) + message_index = VALIDATECLASSID(my_bot->GetClass()); + + if (c->GetBotOptionSpawnMessageSay()) + Bot::BotGroupSay(my_bot, "%s", bot_spawn_message[message_index]); + else if (c->GetBotOptionSpawnMessageTell()) + c->Message(Chat::Tell, "%s tells you, \"%s\"", my_bot->GetCleanName(), bot_spawn_message[message_index]); } void bot_subcommand_bot_stance(Client *c, const Seperator *sep) diff --git a/zone/bot_database.cpp b/zone/bot_database.cpp index 2aaf677bb..29d0f37e9 100644 --- a/zone/bot_database.cpp +++ b/zone/bot_database.cpp @@ -2157,7 +2157,7 @@ bool BotDatabase::LoadOwnerOptions(Client *owner) return false; query = StringFormat( - "SELECT `death_marquee`, `stats_update` FROM `bot_owner_options`" + "SELECT `death_marquee`, `stats_update`, `spawn_message_enabled`, `spawn_message_type` FROM `bot_owner_options`" " WHERE `owner_id` = '%u'", owner->CharacterID() ); @@ -2174,6 +2174,18 @@ bool BotDatabase::LoadOwnerOptions(Client *owner) auto row = results.begin(); owner->SetBotOptionDeathMarquee((atoi(row[0]) != 0)); owner->SetBotOptionStatsUpdate((atoi(row[1]) != 0)); + switch (atoi(row[2])) { + case 2: + owner->SetBotOptionSpawnMessageSay(); + break; + case 1: + owner->SetBotOptionSpawnMessageTell(); + break; + default: + owner->SetBotOptionSpawnMessageSilent(); + break; + } + owner->SetBotOptionSpawnMessageClassSpecific((atoi(row[3]) != 0)); return true; } @@ -2216,6 +2228,38 @@ bool BotDatabase::SaveOwnerOptionStatsUpdate(const uint32 owner_id, const bool f return true; } +bool BotDatabase::SaveOwnerOptionSpawnMessage(const uint32 owner_id, const bool say, const bool tell, const bool class_specific) +{ + if (!owner_id) + return false; + + uint8 enabled_value = 0; + if (say) + enabled_value = 2; + else if (tell) + enabled_value = 1; + + uint8 type_value = 0; + if (class_specific) + type_value = 1; + + query = StringFormat( + "UPDATE `bot_owner_options`" + " SET" + " `spawn_message_enabled` = '%u'," + " `spawn_message_type` = '%u'" + " WHERE `owner_id` = '%u'", + enabled_value, + type_value, + owner_id + ); + auto results = database.QueryDatabase(query); + if (!results.Success()) + return false; + + return true; +} + /* Bot bot-group functions */ bool BotDatabase::QueryBotGroupExistence(const std::string& group_name, bool& extant_flag) diff --git a/zone/bot_database.h b/zone/bot_database.h index a94d2a902..0c18eade5 100644 --- a/zone/bot_database.h +++ b/zone/bot_database.h @@ -141,6 +141,7 @@ public: bool LoadOwnerOptions(Client *owner); bool SaveOwnerOptionDeathMarquee(const uint32 owner_id, const bool flag); bool SaveOwnerOptionStatsUpdate(const uint32 owner_id, const bool flag); + bool SaveOwnerOptionSpawnMessage(const uint32 owner_id, const bool say, const bool tell, const bool class_specific); /* Bot bot-group functions */ bool QueryBotGroupExistence(const std::string& botgroup_name, bool& extant_flag); diff --git a/zone/client.h b/zone/client.h index bb80e7ffc..88bee0b03 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1629,21 +1629,34 @@ private: struct BotOwnerOptions { bool death_marquee; bool stats_update; + bool spawn_message_say; + bool spawn_message_tell; + bool spawn_message_class_specific; }; BotOwnerOptions bot_owner_options; const BotOwnerOptions DefaultBotOwnerOptions = { false, // death_marquee - false // stats_update + false, // stats_update + false, // spawn_message_say + true, // spawn_message_tell + true // spawn_message_class_specific }; public: void SetBotOptionDeathMarquee(bool flag) { bot_owner_options.death_marquee = flag; } void SetBotOptionStatsUpdate(bool flag) { bot_owner_options.stats_update = flag; } + void SetBotOptionSpawnMessageSay() { bot_owner_options.spawn_message_say = true; bot_owner_options.spawn_message_tell = false; } + void SetBotOptionSpawnMessageTell() { bot_owner_options.spawn_message_say = false; bot_owner_options.spawn_message_tell = true; } + void SetBotOptionSpawnMessageSilent() { bot_owner_options.spawn_message_say = false; bot_owner_options.spawn_message_tell = false; } + void SetBotOptionSpawnMessageClassSpecific(bool flag) { bot_owner_options.spawn_message_class_specific = flag; } bool GetBotOptionDeathMarquee() const { return bot_owner_options.death_marquee; } bool GetBotOptionStatsUpdate() const { return bot_owner_options.stats_update; } + bool GetBotOptionSpawnMessageSay() const { return bot_owner_options.spawn_message_say; } + bool GetBotOptionSpawnMessageTell() const { return bot_owner_options.spawn_message_tell; } + bool GetBotOptionSpawnMessageClassSpecific() const { return bot_owner_options.spawn_message_class_specific; } private: #endif