Implemented bot owner options

This commit is contained in:
Uleat 2018-10-09 22:04:47 -04:00
parent a836baac32
commit 43aaaf7f26
12 changed files with 124 additions and 1 deletions

View File

@ -1,5 +1,12 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 10/09/2018 ==
Uleat: Added bot owner options
- usage: ^owneroption [option] (or aliased as: ^oo [option])
- options are saved in the database and therefore, persistent
- Implemented option 'deathmarquee'
-- toggles client owner flag to show marquee message when a bot dies (default: disabled)
== 10/07/2018 ==
Uleat: Fixed a few bot issues..
- Fix for bot item trades not attuning

View File

@ -32,7 +32,7 @@
#define CURRENT_BINARY_DATABASE_VERSION 9129
#ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9020
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9021
#else
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 0 // must be 0
#endif

View File

@ -19,6 +19,7 @@
9018|2018_02_02_Bot_Spells_Min_Max_HP.sql|SHOW COLUMNS FROM `bot_spells_entries` LIKE 'min_hp'|empty|
9019|2018_04_12_bots_stop_melee_level.sql|SHOW COLUMNS FROM `bot_data` LIKE 'stop_melee_level'|empty|
9020|2018_08_13_bots_inventory_update.sql|SELECT * FROM `inventory_versions` WHERE `version` = 2 and `bot_step` = 0|not_empty|
9021|2018_10_09_bots_owner_options.sql|SHOW TABLES LIKE 'bot_owner_options'|empty|
# Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not

View File

@ -0,0 +1,11 @@
DROP TABLE IF EXISTS `bot_owner_options`;
CREATE TABLE `bot_owner_options` (
`owner_id` INT(11) UNSIGNED NOT NULL,
`death_marquee` SMALLINT(3) UNSIGNED NULL DEFAULT '0',
PRIMARY KEY (`owner_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=MyISAM;
INSERT INTO `bot_command_settings`(`bot_command`, `access`, `aliases`) VALUES ('owneroption', '0', 'oo');

View File

@ -4042,6 +4042,15 @@ bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, EQEmu::skills::Sk
return false;
Save();
Mob *my_owner = GetBotOwner();
if (my_owner && my_owner->IsClient() && my_owner->CastToClient()->GetBotOptionDeathMarquee()) {
if (killerMob)
my_owner->CastToClient()->SendMarqueeMessage(CC_Yellow, 510, 0, 1000, 3000, StringFormat("%s has been slain by %s", GetCleanName(), killerMob->GetCleanName()));
else
my_owner->CastToClient()->SendMarqueeMessage(CC_Yellow, 510, 0, 1000, 3000, StringFormat("%s has been slain", GetCleanName()));
}
Mob *give_exp = hate_list.GetDamageTopOnHateList(this);
Client *give_exp_client = nullptr;
if(give_exp && give_exp->IsClient())

View File

@ -1399,6 +1399,7 @@ int bot_command_init(void)
bot_command_add("lull", "Orders a bot to cast a pacification spell", 0, bot_command_lull) ||
bot_command_add("mesmerize", "Orders a bot to cast a mesmerization spell", 0, bot_command_mesmerize) ||
bot_command_add("movementspeed", "Orders a bot to cast a movement speed enhancement spell", 0, bot_command_movement_speed) ||
bot_command_add("owneroption", "Sets options available to bot owners", 0, bot_command_owner_option) ||
bot_command_add("pet", "Lists the available bot pet [subcommands]", 0, bot_command_pet) ||
bot_command_add("petremove", "Orders a bot to remove its pet", 0, bot_subcommand_pet_remove) ||
bot_command_add("petsettype", "Orders a Magician bot to use a specified pet type", 0, bot_subcommand_pet_set_type) ||
@ -3437,6 +3438,25 @@ void bot_command_movement_speed(Client *c, const Seperator *sep)
helper_no_available_bots(c, my_bot);
}
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]", sep->arg[0]);
return;
}
std::string owner_option = sep->arg[1];
if (!owner_option.compare("deathmarquee")) {
c->SetBotOptionDeathMarquee(!c->GetBotOptionDeathMarquee());
c->Message(m_action, "Bot death marquee is now %s.", (c->GetBotOptionDeathMarquee() == true ? "enabled" : "disabled"));
botdb.SaveOwnerOptionDeathMarquee(c->CharacterID(), c->GetBotOptionDeathMarquee());
}
else {
c->Message(m_fail, "Owner option '%s' is not recognized.", owner_option.c_str());
}
}
void bot_command_pet(Client *c, const Seperator *sep)
{
/* VS2012 code - begin */

View File

@ -575,6 +575,7 @@ void bot_command_levitation(Client *c, const Seperator *sep);
void bot_command_lull(Client *c, const Seperator *sep);
void bot_command_mesmerize(Client *c, const Seperator *sep);
void bot_command_movement_speed(Client *c, const Seperator *sep);
void bot_command_owner_option(Client *c, const Seperator *sep);
void bot_command_pet(Client *c, const Seperator *sep);
void bot_command_pick_lock(Client *c, const Seperator *sep);
void bot_command_pull(Client *c, const Seperator *sep);

View File

@ -25,6 +25,7 @@
#include "bot_database.h"
#include "bot.h"
#include "client.h"
BotDatabase botdb;
@ -2185,6 +2186,51 @@ bool BotDatabase::SaveStopMeleeLevel(const uint32 owner_id, const uint32 bot_id,
return true;
}
bool BotDatabase::LoadOwnerOptions(Client *owner)
{
if (!owner || !owner->CharacterID())
return false;
query = StringFormat(
"SELECT `death_marquee` FROM `bot_owner_options`"
" WHERE `owner_id` = '%u'",
owner->CharacterID()
);
auto results = QueryDatabase(query);
if (!results.Success())
return false;
if (!results.RowCount()) {
query = StringFormat("REPLACE INTO `bot_owner_options` (`owner_id`) VALUES ('%u')", owner->CharacterID());
results = QueryDatabase(query);
return false;
}
auto row = results.begin();
owner->SetBotOptionDeathMarquee((atoi(row[0]) != 0));
return true;
}
bool BotDatabase::SaveOwnerOptionDeathMarquee(const uint32 owner_id, const bool flag)
{
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 = QueryDatabase(query);
if (!results.Success())
return false;
return true;
}
/* Bot bot-group functions */
bool BotDatabase::QueryBotGroupExistence(const std::string& group_name, bool& extant_flag)

View File

@ -32,6 +32,7 @@
class Bot;
struct BotsAvailableList;
class Client;
namespace EQEmu
{
@ -145,6 +146,8 @@ 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);
/* Bot bot-group functions */
bool QueryBotGroupExistence(const std::string& botgroup_name, bool& extant_flag);

View File

@ -335,6 +335,10 @@ Client::Client(EQStreamInterface* ieqs)
temp_pvp = false;
is_client_moving = false;
#ifdef BOTS
bot_owner_options = DefaultBotOwnerOptions;
#endif
AI_Init();
}

View File

@ -1641,6 +1641,25 @@ private:
void InterrogateInventory_(bool errorcheck, Client* requester, int16 head, int16 index, const EQEmu::ItemInstance* inst, const EQEmu::ItemInstance* parent, bool log, bool silent, bool &error, int depth);
bool InterrogateInventory_error(int16 head, int16 index, const EQEmu::ItemInstance* inst, const EQEmu::ItemInstance* parent, int depth);
#ifdef BOTS
struct BotOwnerOptions {
bool death_marquee;
};
BotOwnerOptions bot_owner_options;
const BotOwnerOptions DefaultBotOwnerOptions = {
false // death_marquee
};
public:
void SetBotOptionDeathMarquee(bool flag) { bot_owner_options.death_marquee = flag; }
bool GetBotOptionDeathMarquee() const { return bot_owner_options.death_marquee; }
private:
#endif
};
#endif

View File

@ -1599,6 +1599,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
}
#ifdef BOTS
botdb.LoadOwnerOptions(this);
// TODO: mod below function for loading spawned botgroups
Bot::LoadAndSpawnAllZonedBots(this);
#endif