diff --git a/common/version.h b/common/version.h
index 0c6dea2b5..5640a63fe 100644
--- a/common/version.h
+++ b/common/version.h
@@ -34,7 +34,7 @@
#define CURRENT_BINARY_DATABASE_VERSION 9142
#ifdef BOTS
- #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9025
+ #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9026
#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 405cf3f5c..0a1e4466a 100644
--- a/utils/sql/git/bots/bots_db_update_manifest.txt
+++ b/utils/sql/git/bots/bots_db_update_manifest.txt
@@ -24,6 +24,7 @@
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|
+9026|2019_09_09_bots_owner_options_rework.sql|SHOW COLUMNS FROM `bot_owner_options` LIKE 'option_type'|empty|
# Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not
diff --git a/zone/bot.cpp b/zone/bot.cpp
index 971c1d1b6..d70c0ffe8 100644
--- a/zone/bot.cpp
+++ b/zone/bot.cpp
@@ -3499,7 +3499,7 @@ void Bot::LevelBotWithClient(Client* client, uint8 level, bool sendlvlapp) {
Bot* bot = *biter;
if(bot && (bot->GetLevel() != client->GetLevel())) {
bot->SetPetChooser(false); // not sure what this does, but was in bot 'update' code
- bot->CalcBotStats(client->GetBotOptionStatsUpdate());
+ bot->CalcBotStats(client->GetBotOption(Client::booStatsUpdate));
if(sendlvlapp)
bot->SendLevelAppearance();
// modified from Client::SetLevel()
@@ -4178,7 +4178,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
client->Message(Chat::Lime, "Trade with '%s' resulted in %i accepted item%s, %i returned item%s.", GetCleanName(), accepted_count, ((accepted_count == 1) ? "" : "s"), returned_count, ((returned_count == 1) ? "" : "s"));
if (accepted_count)
- CalcBotStats(client->GetBotOptionStatsUpdate());
+ CalcBotStats(client->GetBotOption(Client::booStatsUpdate));
}
bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) {
@@ -4188,7 +4188,7 @@ bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, EQEmu::skills::Sk
Save();
Mob *my_owner = GetBotOwner();
- if (my_owner && my_owner->IsClient() && my_owner->CastToClient()->GetBotOptionDeathMarquee()) {
+ if (my_owner && my_owner->IsClient() && my_owner->CastToClient()->GetBotOption(Client::booDeathMarquee)) {
if (killerMob)
my_owner->CastToClient()->SendMarqueeMessage(Chat::Yellow, 510, 0, 1000, 3000, StringFormat("%s has been slain by %s", GetCleanName(), killerMob->GetCleanName()));
else
diff --git a/zone/bot_command.cpp b/zone/bot_command.cpp
index 31270cc0f..661a902b3 100644
--- a/zone/bot_command.cpp
+++ b/zone/bot_command.cpp
@@ -3443,63 +3443,180 @@ void bot_command_movement_speed(Client *c, const Seperator *sep)
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]);
+
+ c->Message(m_usage, "usage: %s [option] [argument | null]", sep->arg[0]);
+
+ std::string window_title = "Bot Owner Options";
+ std::string window_text =
+ "
"
+ ""
+ "| Option | "
+ "Argument | "
+ "Notes | "
+ "
"
+ ""
+ "| deathmarquee | "
+ "enable | "
+ " | "
+ "
"
+ ""
+ " | "
+ "disable | "
+ " | "
+ "
"
+ ""
+ " | "
+ "null | "
+ "(toggles) | "
+ "
"
+ ""
+ "| statsupdate | "
+ "enable | "
+ " | "
+ "
"
+ ""
+ " | "
+ "disable | "
+ " | "
+ "
"
+ ""
+ " | "
+ "null | "
+ "(toggles) | "
+ "
"
+ ""
+ "| spawnmessage | "
+ "say | "
+ " | "
+ "
"
+ ""
+ " | "
+ "tell | "
+ " | "
+ "
"
+ ""
+ " | "
+ "silent | "
+ " | "
+ "
"
+ ""
+ " | "
+ "class | "
+ " | "
+ "
"
+ ""
+ " | "
+ "default | "
+ " | "
+ "
"
+ "
";
+
+ c->SendPopupToClient(window_title.c_str(), window_text.c_str());
+
return;
}
- std::string owner_option = sep->arg[1];
- std::string argument = sep->arg[2];
+ std::string owner_option(sep->arg[1]);
+ std::string argument(sep->arg[2]);
if (!owner_option.compare("deathmarquee")) {
- if (!argument.compare("enable"))
- c->SetBotOptionDeathMarquee(true);
- else if (!argument.compare("disable"))
- c->SetBotOptionDeathMarquee(false);
- else
- c->SetBotOptionDeathMarquee(!c->GetBotOptionDeathMarquee());
-
- database.botdb.SaveOwnerOptionDeathMarquee(c->CharacterID(), c->GetBotOptionDeathMarquee());
- c->Message(m_action, "Bot 'death marquee' is now %s.", (c->GetBotOptionDeathMarquee() == true ? "enabled" : "disabled"));
- }
- else if (!owner_option.compare("statsupdate")) {
- if (!argument.compare("enable"))
- c->SetBotOptionStatsUpdate(true);
- else if (!argument.compare("disable"))
- c->SetBotOptionStatsUpdate(false);
- else
- c->SetBotOptionStatsUpdate(!c->GetBotOptionStatsUpdate());
- 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();
+ if (!argument.compare("enable")) {
+ c->SetBotOption(Client::booDeathMarquee, true);
}
- 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 if (!argument.compare("disable")) {
+ c->SetBotOption(Client::booDeathMarquee, false);
}
else {
+ c->SetBotOption(Client::booDeathMarquee, !c->GetBotOption(Client::booDeathMarquee));
+ }
+
+ database.botdb.SaveOwnerOption(c->CharacterID(), Client::booDeathMarquee, c->GetBotOption(Client::booDeathMarquee));
+
+ c->Message(m_action, "Bot 'death marquee' is now %s.", (c->GetBotOption(Client::booDeathMarquee) == true ? "enabled" : "disabled"));
+ }
+ else if (!owner_option.compare("statsupdate")) {
+
+ if (!argument.compare("enable")) {
+ c->SetBotOption(Client::booStatsUpdate, true);
+ }
+ else if (!argument.compare("disable")) {
+ c->SetBotOption(Client::booStatsUpdate, false);
+ }
+ else {
+ c->SetBotOption(Client::booStatsUpdate, !c->GetBotOption(Client::booStatsUpdate));
+ }
+
+ database.botdb.SaveOwnerOption(c->CharacterID(), Client::booStatsUpdate, c->GetBotOption(Client::booStatsUpdate));
+
+ c->Message(m_action, "Bot 'stats update' is now %s.", (c->GetBotOption(Client::booStatsUpdate) == true ? "enabled" : "disabled"));
+ }
+ else if (!owner_option.compare("spawnmessage")) {
+
+ Client::BotOwnerOption boo = Client::_booCount;
+
+ if (!argument.compare("say")) {
+
+ boo = Client::booSpawnMessageSay;
+ c->SetBotOption(Client::booSpawnMessageSay, true);
+ c->SetBotOption(Client::booSpawnMessageTell, false);
+ }
+ else if (!argument.compare("tell")) {
+
+ boo = Client::booSpawnMessageSay;
+ c->SetBotOption(Client::booSpawnMessageSay, false);
+ c->SetBotOption(Client::booSpawnMessageTell, true);
+ }
+ else if (!argument.compare("silent")) {
+
+ boo = Client::booSpawnMessageSay;
+ c->SetBotOption(Client::booSpawnMessageSay, false);
+ c->SetBotOption(Client::booSpawnMessageTell, false);
+ }
+ else if (!argument.compare("class")) {
+
+ boo = Client::booSpawnMessageClassSpecific;
+ c->SetBotOption(Client::booSpawnMessageClassSpecific, true);
+ }
+ else if (!argument.compare("default")) {
+
+ boo = Client::booSpawnMessageClassSpecific;
+ c->SetBotOption(Client::booSpawnMessageClassSpecific, 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()
- );
+ if (boo == Client::booSpawnMessageSay) {
+
+ database.botdb.SaveOwnerOption(
+ c->CharacterID(),
+ std::pair(
+ Client::booSpawnMessageSay,
+ Client::booSpawnMessageTell
+ ),
+ std::pair(
+ c->GetBotOption(Client::booSpawnMessageSay),
+ c->GetBotOption(Client::booSpawnMessageTell)
+ )
+ );
+ }
+ else if (boo == Client::booSpawnMessageClassSpecific) {
+
+ database.botdb.SaveOwnerOption(
+ c->CharacterID(),
+ Client::booSpawnMessageClassSpecific,
+ c->GetBotOption(Client::booSpawnMessageClassSpecific)
+ );
+ }
+ else {
+
+ c->Message(m_action, "Bot 'spawn message' is now ERROR.");
+ return;
+ }
+
c->Message(m_action, "Bot 'spawn message' is now %s.", argument.c_str());
}
else {
@@ -5221,13 +5338,16 @@ void bot_subcommand_bot_spawn(Client *c, const Seperator *sep)
};
uint8 message_index = 0;
- if (c->GetBotOptionSpawnMessageClassSpecific())
+ if (c->GetBotOption(Client::booSpawnMessageClassSpecific)) {
message_index = VALIDATECLASSID(my_bot->GetClass());
+ }
- if (c->GetBotOptionSpawnMessageSay())
+ if (c->GetBotOption(Client::booSpawnMessageSay)) {
Bot::BotGroupSay(my_bot, "%s", bot_spawn_message[message_index]);
- else if (c->GetBotOptionSpawnMessageTell())
+ }
+ else if (c->GetBotOption(Client::booSpawnMessageTell)) {
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)
@@ -5607,7 +5727,7 @@ void bot_subcommand_bot_update(Client *c, const Seperator *sep)
continue;
bot_iter->SetPetChooser(false);
- bot_iter->CalcBotStats(c->GetBotOptionStatsUpdate());
+ bot_iter->CalcBotStats(c->GetBotOption(Client::booStatsUpdate));
bot_iter->SendAppearancePacket(AT_WhoLevel, bot_iter->GetLevel(), true, true);
++bot_count;
}
@@ -7396,7 +7516,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
}
my_bot->BotRemoveEquipItem(slotId);
- my_bot->CalcBotStats(c->GetBotOptionStatsUpdate());
+ my_bot->CalcBotStats(c->GetBotOption(Client::booStatsUpdate));
}
switch (slotId) {
diff --git a/zone/bot_database.cpp b/zone/bot_database.cpp
index 29d0f37e9..abf4fa44c 100644
--- a/zone/bot_database.cpp
+++ b/zone/bot_database.cpp
@@ -27,6 +27,8 @@
#include "bot.h"
#include "client.h"
+#include
+
bool BotDatabase::LoadBotCommandSettings(std::map>> &bot_command_settings)
{
@@ -2153,111 +2155,92 @@ bool BotDatabase::SaveStopMeleeLevel(const uint32 owner_id, const uint32 bot_id,
bool BotDatabase::LoadOwnerOptions(Client *owner)
{
- if (!owner || !owner->CharacterID())
- return false;
-
- query = StringFormat(
- "SELECT `death_marquee`, `stats_update`, `spawn_message_enabled`, `spawn_message_type` FROM `bot_owner_options`"
- " WHERE `owner_id` = '%u'",
- owner->CharacterID()
- );
- auto results = database.QueryDatabase(query);
- if (!results.Success())
- return false;
- if (!results.RowCount()) {
- query = StringFormat("REPLACE INTO `bot_owner_options` (`owner_id`) VALUES ('%u')", owner->CharacterID());
- results = database.QueryDatabase(query);
-
+ if (!owner || !owner->CharacterID()) {
return false;
}
- 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;
+ query = fmt::format("SELECT `option_type`, `option_value` FROM `bot_owner_options` WHERE `owner_id` = '{}'", owner->CharacterID());
+
+ auto results = database.QueryDatabase(query);
+ if (!results.Success()) {
+ return false;
+ }
+
+ for (auto row : results) {
+
+ owner->SetBotOption(static_cast(atoul(row[0])), (atoul(row[1]) != 0));
+ }
+
+ return true;
+}
+
+bool BotDatabase::SaveOwnerOption(const uint32 owner_id, size_t type, const bool flag)
+{
+ if (!owner_id) {
+ return false;
+ }
+
+ switch (static_cast(type)) {
+ case Client::booDeathMarquee:
+ case Client::booStatsUpdate:
+ case Client::booSpawnMessageClassSpecific: {
+
+ query = fmt::format(
+ "REPLACE INTO `bot_owner_options`(`owner_id`, `option_type`, `option_value`) VALUES ('{}', '{}', '{}')",
+ owner_id,
+ type,
+ (flag == true ? 1 : 0)
+ );
+
+ auto results = database.QueryDatabase(query);
+ if (!results.Success()) {
+ return false;
+ }
+
+ return true;
+ }
default:
- owner->SetBotOptionSpawnMessageSilent();
- break;
+ return false;
}
- owner->SetBotOptionSpawnMessageClassSpecific((atoi(row[3]) != 0));
-
- return true;
}
-bool BotDatabase::SaveOwnerOptionDeathMarquee(const uint32 owner_id, const bool flag)
+bool BotDatabase::SaveOwnerOption(const uint32 owner_id, const std::pair type, const std::pair flag)
{
- if (!owner_id)
+ if (!owner_id) {
return false;
+ }
- query = StringFormat(
- "UPDATE `bot_owner_options`"
- " SET `death_marquee` = '%u'"
- " WHERE `owner_id` = '%u'",
- (flag == true ? 1 : 0),
- owner_id
- );
- auto results = database.QueryDatabase(query);
- if (!results.Success())
+ switch (static_cast(type.first)) {
+ case Client::booSpawnMessageSay:
+ case Client::booSpawnMessageTell: {
+ switch (static_cast(type.second)) {
+ case Client::booSpawnMessageSay:
+ case Client::booSpawnMessageTell: {
+
+ query = fmt::format(
+ "REPLACE INTO `bot_owner_options`(`owner_id`, `option_type`, `option_value`) VALUES ('{}', '{}', '{}'), ('{}', '{}', '{}')",
+ owner_id,
+ type.first,
+ (flag.first == true ? 1 : 0),
+ owner_id,
+ type.second,
+ (flag.second == true ? 1 : 0)
+ );
+
+ auto results = database.QueryDatabase(query);
+ if (!results.Success()) {
+ return false;
+ }
+
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+ default:
return false;
-
- return true;
-}
-
-bool BotDatabase::SaveOwnerOptionStatsUpdate(const uint32 owner_id, const bool flag)
-{
- if (!owner_id)
- return false;
-
- query = StringFormat(
- "UPDATE `bot_owner_options`"
- " SET `stats_update` = '%u'"
- " WHERE `owner_id` = '%u'",
- (flag == true ? 1 : 0),
- owner_id
- );
- auto results = database.QueryDatabase(query);
- if (!results.Success())
- return false;
-
- 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;
+ }
}
diff --git a/zone/bot_database.h b/zone/bot_database.h
index 0c18eade5..1c1a8b88d 100644
--- a/zone/bot_database.h
+++ b/zone/bot_database.h
@@ -139,10 +139,9 @@ public:
bool SaveStopMeleeLevel(const uint32 owner_id, const uint32 bot_id, const uint8 sml_value);
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);
-
+ bool SaveOwnerOption(const uint32 owner_id, size_t type, const bool flag);
+ bool SaveOwnerOption(const uint32 owner_id, const std::pair type, const std::pair flag);
+
/* Bot bot-group functions */
bool QueryBotGroupExistence(const std::string& botgroup_name, bool& extant_flag);
diff --git a/zone/client.cpp b/zone/client.cpp
index c1293be3f..ba65695c9 100644
--- a/zone/client.cpp
+++ b/zone/client.cpp
@@ -347,7 +347,11 @@ Client::Client(EQStreamInterface* ieqs)
dev_tools_window_enabled = true;
#ifdef BOTS
- bot_owner_options = DefaultBotOwnerOptions;
+ bot_owner_options[booDeathMarquee] = false;
+ bot_owner_options[booStatsUpdate] = false;
+ bot_owner_options[booSpawnMessageSay] = false;
+ bot_owner_options[booSpawnMessageTell] = true;
+ bot_owner_options[booSpawnMessageClassSpecific] = true;
#endif
AI_Init();
@@ -9134,4 +9138,24 @@ glm::vec4 &Client::GetLastPositionBeforeBulkUpdate()
void Client::SetLastPositionBeforeBulkUpdate(glm::vec4 in_last_position_before_bulk_update)
{
Client::last_position_before_bulk_update = in_last_position_before_bulk_update;
-}
\ No newline at end of file
+}
+
+#ifdef BOTS
+
+bool Client::GetBotOption(BotOwnerOption boo) const {
+
+ if (boo < _booCount) {
+ return bot_owner_options[boo];
+ }
+
+ return false;
+}
+
+void Client::SetBotOption(BotOwnerOption boo, bool flag) {
+
+ if (boo < _booCount) {
+ bot_owner_options[boo] = flag;
+ }
+}
+
+#endif
diff --git a/zone/client.h b/zone/client.h
index 88bee0b03..54a1260ae 100644
--- a/zone/client.h
+++ b/zone/client.h
@@ -1626,39 +1626,26 @@ private:
int client_max_level;
#ifdef BOTS
- 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, // 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; }
+ enum BotOwnerOption : size_t {
+ booDeathMarquee,
+ booStatsUpdate,
+ booSpawnMessageSay,
+ booSpawnMessageTell,
+ booSpawnMessageClassSpecific,
+ _booCount
+ };
- 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; }
+ bool GetBotOption(BotOwnerOption boo) const;
+ void SetBotOption(BotOwnerOption boo, bool flag = true);
+
+private:
+ bool bot_owner_options[_booCount];
-private:
#endif
};