[Commands] [Hotfix] Fix Illusion Block (#4666)

* [Commands] [Hotfix] Fix Illusion Block

This wasn't properly being set or saved if bots were not enabled, moved to extended character profile for players.

* Move out of EPP

* ValueWithin

* I learned a new word today - idempotent

I'm dumb. Will forget it tomorrow.

* Move saving to ZoneDatabase, inline SetIllusionBlock
This commit is contained in:
nytmyr 2025-02-12 00:18:34 -06:00 committed by GitHub
parent ac4ffefa09
commit d9d2d5d47c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 54 additions and 11 deletions

View File

@ -6747,6 +6747,29 @@ COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;
)"
},
ManifestEntry{
.version = 9302,
.description = "2025_02_09_illusion_block.sql",
.check = "SHOW COLUMNS FROM `character_data` LIKE 'illusion_block'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `character_data`
ADD COLUMN `illusion_block` TINYINT(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `deleted_at`;
UPDATE `command_settings`
SET `aliases` =
CASE
WHEN LENGTH(`aliases`) > 0 AND `aliases` NOT LIKE '%|ib%'
THEN CONCAT(`aliases`, '|ib')
WHEN LENGTH(`aliases`) = 0
THEN 'ib'
ELSE `aliases`
END
WHERE `command` = 'illusionblock'
AND `aliases` NOT LIKE '%ib%';
)",
}
// -- template; copy/paste this when you need to create a new entry
// ManifestEntry{

View File

@ -123,6 +123,7 @@ public:
uint32_t aa_points_old;
uint32_t e_last_invsnapshot;
time_t deleted_at;
uint8_t illusion_block;
};
static std::string PrimaryKey()
@ -237,6 +238,7 @@ public:
"aa_points_old",
"e_last_invsnapshot",
"deleted_at",
"illusion_block",
};
}
@ -347,6 +349,7 @@ public:
"aa_points_old",
"e_last_invsnapshot",
"UNIX_TIMESTAMP(deleted_at)",
"illusion_block",
};
}
@ -491,6 +494,7 @@ public:
e.aa_points_old = 0;
e.e_last_invsnapshot = 0;
e.deleted_at = 0;
e.illusion_block = 0;
return e;
}
@ -631,6 +635,7 @@ public:
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.illusion_block = row[104] ? static_cast<uint8_t>(strtoul(row[104], nullptr, 10)) : 0;
return e;
}
@ -767,6 +772,7 @@ public:
v.push_back(columns[101] + " = " + std::to_string(e.aa_points_old));
v.push_back(columns[102] + " = " + std::to_string(e.e_last_invsnapshot));
v.push_back(columns[103] + " = FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(columns[104] + " = " + std::to_string(e.illusion_block));
auto results = db.QueryDatabase(
fmt::format(
@ -892,6 +898,7 @@ public:
v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.illusion_block));
auto results = db.QueryDatabase(
fmt::format(
@ -1025,6 +1032,7 @@ public:
v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.illusion_block));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@ -1162,6 +1170,7 @@ public:
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.illusion_block = row[104] ? static_cast<uint8_t>(strtoul(row[104], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@ -1290,6 +1299,7 @@ public:
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.illusion_block = row[104] ? static_cast<uint8_t>(strtoul(row[104], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@ -1468,6 +1478,7 @@ public:
v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.illusion_block));
auto results = db.QueryDatabase(
fmt::format(
@ -1594,6 +1605,7 @@ public:
v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.illusion_block));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}

View File

@ -42,7 +42,7 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9301
#define CURRENT_BINARY_DATABASE_VERSION 9302
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
#endif

View File

@ -2345,6 +2345,7 @@ bool BotDatabase::SaveBotSettings(Mob* m)
}
if (m->IsClient()) {
/* Currently unused
if (m->CastToClient()->GetDefaultBotSettings(BotSettingCategories::BaseSetting, BotBaseSettings::IllusionBlock) != m->CastToClient()->GetIllusionBlock()) { // Only illusion block supported
auto e = BotSettingsRepository::BotSettings{
.character_id = character_id,
@ -2361,6 +2362,7 @@ bool BotDatabase::SaveBotSettings(Mob* m)
LogBotSettings("{} says, 'Saving {} [{}] - set to [{}] default [{}].'", m->GetCleanName(), Bot::GetBotSettingCategoryName(BotBaseSettings::IllusionBlock), BotBaseSettings::IllusionBlock, e.value, m->CastToClient()->GetIllusionBlock());
}
*/
for (uint16 i = BotSettingCategories::START_CLIENT; i <= BotSettingCategories::END_CLIENT; ++i) {
for (uint16 x = BotSpellTypes::START; x <= BotSpellTypes::END; ++x) {

View File

@ -13596,4 +13596,4 @@ void Client::CheckItemDiscoverability(uint32 item_id)
}
DiscoverItem(item_id);
}
}

View File

@ -2346,8 +2346,8 @@ public:
inline bool SpellTypeRecastCheck(uint16 spellType) { return !m_bot_spell_settings[spellType].recast_timer.GetRemainingTime(); }
void SetSpellTypeRecastTimer(uint16 spell_type, uint32 recast_time) { m_bot_spell_settings[spell_type].recast_timer.Start(recast_time); }
void SetIllusionBlock(bool value) { _illusionBlock = value; }
bool GetIllusionBlock() const override { return _illusionBlock; }
void SetIllusionBlock(bool value) { _illusion_block = value; }
bool GetIllusionBlock() const override { return _illusion_block; }
private:
bool bot_owner_options[_booCount];
@ -2355,7 +2355,7 @@ private:
bool m_bot_precombat;
uint32 bot_assistee;
std::vector<BotSpellSettings> m_bot_spell_settings;
bool _illusionBlock;
bool _illusion_block;
bool CanTradeFVNoDropItem();
void SendMobPositions();

View File

@ -223,9 +223,10 @@ void Client::CampAllBots(uint8 class_id) {
void Client::LoadDefaultBotSettings() {
m_bot_spell_settings.clear();
// Only illusion block supported currently
/* No longer used, left as example.
SetBotSetting(BotSettingCategories::BaseSetting, BotBaseSettings::IllusionBlock, GetDefaultBotSettings(BotSettingCategories::BaseSetting, BotBaseSettings::IllusionBlock));
LogBotSettingsDetail("{} says, 'Setting default {} [{}] to [{}]'", GetCleanName(), CastToBot()->GetBotSettingCategoryName(BotBaseSettings::IllusionBlock), BotBaseSettings::IllusionBlock, GetDefaultBotSettings(BotSettingCategories::BaseSetting, BotBaseSettings::IllusionBlock));
*/
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
BotSpellSettings t;
@ -263,7 +264,7 @@ int Client::GetDefaultBotSettings(uint8 setting_type, uint16 bot_setting) {
int Client::GetBotSetting(uint8 setting_type, uint16 bot_setting) {
switch (setting_type) {
case BotSettingCategories::BaseSetting:
return GetIllusionBlock(); // only setting supported currently
return 0; // unused currently
case BotSettingCategories::SpellDelay:
return GetSpellTypeDelay(bot_setting);
case BotSettingCategories::SpellMinThreshold:
@ -276,8 +277,7 @@ int Client::GetBotSetting(uint8 setting_type, uint16 bot_setting) {
void Client::SetBotSetting(uint8 setting_type, uint16 bot_setting, uint32 setting_value) {
switch (setting_type) {
case BotSettingCategories::BaseSetting:
SetIllusionBlock(setting_value); // only setting supported currently
break;
break; // unused currently
case BotSettingCategories::SpellDelay:
SetSpellTypeDelay(bot_setting, setting_value);
break;

View File

@ -1299,7 +1299,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
/* Load Character Data */
query = fmt::format(
"SELECT `lfp`, `lfg`, `xtargets`, `firstlogon`, `guild_id`, `rank`, `exp_enabled`, `tribute_enable`, `extra_haste` FROM `character_data` LEFT JOIN `guild_members` ON `id` = `char_id` WHERE `id` = {}",
"SELECT `lfp`, `lfg`, `xtargets`, `firstlogon`, `guild_id`, `rank`, `exp_enabled`, `tribute_enable`, `extra_haste`, `illusion_block` FROM `character_data` LEFT JOIN `guild_members` ON `id` = `char_id` WHERE `id` = {}",
cid
);
auto results = database.QueryDatabase(query);
@ -1312,6 +1312,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
SetEXPEnabled(Strings::ToBool(row[6]));
SetExtraHaste(Strings::ToInt(row[8]), false);
SetIllusionBlock(Strings::ToBool(row[9]));
if (LFP) { LFP = Strings::ToInt(row[0]); }
if (LFG) { LFG = Strings::ToInt(row[1]); }

View File

@ -7,6 +7,10 @@ void command_illusion_block(Client* c, const Seperator* sep)
BotCommandHelpParams p;
p.description = { "Toggles whether or not you will block the illusion effects of spells cast by players or bots." };
p.notes = {
"- This will still allow other portions of a spell to land on you.",
"- Spells cast by NPCs will ignore this setting and land as normal."
};
p.example_format = { fmt::format("{} [value]", sep->arg[0]) };
p.examples_one =
{
@ -35,7 +39,7 @@ void command_illusion_block(Client* c, const Seperator* sep)
if (sep->IsNumber(1)) {
int set_status = atoi(sep->arg[1]);
if (set_status == 0 || set_status == 1) {
if (EQ::ValueWithin(set_status, 0, 1)) {
c->SetIllusionBlock(set_status);
c->Message(Chat::Green, "Your Illusion Block has been %s.", (set_status ? "enabled" : "disabled"));
}

View File

@ -1158,6 +1158,7 @@ bool ZoneDatabase::SaveCharacterData(
e.e_expended_aa_spent = m_epp->expended_aa;
e.e_last_invsnapshot = m_epp->last_invsnapshot_time;
e.mailkey = c->GetMailKeyFull();
e.illusion_block = c->GetIllusionBlock();
const int replaced = CharacterDataRepository::ReplaceOne(database, e);