diff --git a/common/repositories/base/base_character_buffs_repository.h b/common/repositories/base/base_character_buffs_repository.h index 90003f746..10b1c0d9e 100644 --- a/common/repositories/base/base_character_buffs_repository.h +++ b/common/repositories/base/base_character_buffs_repository.h @@ -36,6 +36,7 @@ public: int32_t caston_z; int32_t ExtraDIChance; int32_t instrument_mod; + uint8_t suppressed; }; static std::string PrimaryKey() @@ -63,6 +64,7 @@ public: "caston_z", "ExtraDIChance", "instrument_mod", + "suppressed", }; } @@ -86,6 +88,7 @@ public: "caston_z", "ExtraDIChance", "instrument_mod", + "suppressed", }; } @@ -143,6 +146,7 @@ public: e.caston_z = 0; e.ExtraDIChance = 0; e.instrument_mod = 10; + e.suppressed = 0; return e; } @@ -196,6 +200,7 @@ public: e.caston_z = row[14] ? static_cast(atoi(row[14])) : 0; e.ExtraDIChance = row[15] ? static_cast(atoi(row[15])) : 0; e.instrument_mod = row[16] ? static_cast(atoi(row[16])) : 10; + e.suppressed = row[17] ? static_cast(strtoul(row[17], nullptr, 10)) : 0; return e; } @@ -246,6 +251,7 @@ public: v.push_back(columns[14] + " = " + std::to_string(e.caston_z)); v.push_back(columns[15] + " = " + std::to_string(e.ExtraDIChance)); v.push_back(columns[16] + " = " + std::to_string(e.instrument_mod)); + v.push_back(columns[17] + " = " + std::to_string(e.suppressed)); auto results = db.QueryDatabase( fmt::format( @@ -284,6 +290,7 @@ public: v.push_back(std::to_string(e.caston_z)); v.push_back(std::to_string(e.ExtraDIChance)); v.push_back(std::to_string(e.instrument_mod)); + v.push_back(std::to_string(e.suppressed)); auto results = db.QueryDatabase( fmt::format( @@ -330,6 +337,7 @@ public: v.push_back(std::to_string(e.caston_z)); v.push_back(std::to_string(e.ExtraDIChance)); v.push_back(std::to_string(e.instrument_mod)); + v.push_back(std::to_string(e.suppressed)); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); } @@ -380,6 +388,7 @@ public: e.caston_z = row[14] ? static_cast(atoi(row[14])) : 0; e.ExtraDIChance = row[15] ? static_cast(atoi(row[15])) : 0; e.instrument_mod = row[16] ? static_cast(atoi(row[16])) : 10; + e.suppressed = row[17] ? static_cast(strtoul(row[17], nullptr, 10)) : 0; all_entries.push_back(e); } @@ -421,6 +430,7 @@ public: e.caston_z = row[14] ? static_cast(atoi(row[14])) : 0; e.ExtraDIChance = row[15] ? static_cast(atoi(row[15])) : 0; e.instrument_mod = row[16] ? static_cast(atoi(row[16])) : 10; + e.suppressed = row[17] ? static_cast(strtoul(row[17], nullptr, 10)) : 0; all_entries.push_back(e); } @@ -512,6 +522,7 @@ public: v.push_back(std::to_string(e.caston_z)); v.push_back(std::to_string(e.ExtraDIChance)); v.push_back(std::to_string(e.instrument_mod)); + v.push_back(std::to_string(e.suppressed)); auto results = db.QueryDatabase( fmt::format( @@ -551,6 +562,7 @@ public: v.push_back(std::to_string(e.caston_z)); v.push_back(std::to_string(e.ExtraDIChance)); v.push_back(std::to_string(e.instrument_mod)); + v.push_back(std::to_string(e.suppressed)); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); } diff --git a/utils/sql/git/optional/2025_06_27_add_suppressed_to_character_buffs.sql b/utils/sql/git/optional/2025_06_27_add_suppressed_to_character_buffs.sql new file mode 100644 index 000000000..d13f6de58 --- /dev/null +++ b/utils/sql/git/optional/2025_06_27_add_suppressed_to_character_buffs.sql @@ -0,0 +1,2 @@ +-- Add suppressed column to character_buffs to persist buff suppression state across zones +ALTER TABLE `character_buffs` ADD COLUMN `suppressed` tinyint(1) unsigned NOT NULL DEFAULT 0 AFTER `instrument_mod`; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 810a20137..ee932e9a1 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -2928,6 +2928,7 @@ void ZoneDatabase::SaveBuffs(Client *client) e.caston_z = buffs[slot_id].caston_z; e.ExtraDIChance = buffs[slot_id].ExtraDIChance; e.instrument_mod = buffs[slot_id].instrument_mod; + e.suppressed = suppressed ? 1 : 0; v.emplace_back(e); } @@ -2999,14 +3000,26 @@ void ZoneDatabase::LoadBuffs(Client *client) buffs[e.slot_id].virus_spread_time = 0; buffs[e.slot_id].UpdateClient = false; buffs[e.slot_id].instrument_mod = e.instrument_mod; - buffs[e.slot_id].suppressedid = 0; - buffs[e.slot_id].suppressedticsremaining = -1; + + if (e.suppressed) { + buffs[e.slot_id].suppressedid = e.spell_id; + buffs[e.slot_id].suppressedticsremaining = e.ticsremaining; + buffs[e.slot_id].spellid = SPELL_SUPPRESSED; + buffs[e.slot_id].ticsremaining = 0; + } else { + buffs[e.slot_id].suppressedid = 0; + buffs[e.slot_id].suppressedticsremaining = -1; + } } // We load up to the most our client supports max_buff_slots = EQ::spells::StaticLookup(client->ClientVersion())->LongBuffs; for (int slot_id = 0; slot_id < max_buff_slots; ++slot_id) { + if (buffs[slot_id].spellid == SPELL_SUPPRESSED) { + continue; + } + if (!IsValidSpell(buffs[slot_id].spellid)) { continue; }