From e24d82f0fedb9a7953bd9bbb4329f2ac79f5af8b Mon Sep 17 00:00:00 2001 From: Mitch Freeman <65987027+neckkola@users.noreply.github.com> Date: Sat, 5 Aug 2023 14:23:33 -0300 Subject: [PATCH] [Bug Fix] Bug fix for raid mark NPC across zones (#3525) * Fix for GENERIC_9_STRINGS * Add Bot Heal Message Display Creates a new rule to display Bot heal messages to the Bot Owner * 2021-03-25 11L04pm Spell and Heal Rule added to allow for Bot spell and heal damage to be sent to the Bot Owner's Group. Also added a check to remove duplicate message for #damage on self. * Update .gitignore * BOT work Added BOT logging damage/heals to owner Added BOT message to owner for harmony fails Made var Critical global to remove duplicate crit messages Added a NULL check to Mob:GetCleanname() * Bot Group Work Fixed botid=charid spawn on zone issue Added a group_list update on zone to refresh from database to fix a dangling pointer to a Bot object that was camped but was previously in a group within the zone being entered. Modified Bot::ProcessBotGroupInvite to use the client of the bot when doing the Bot initialization so that a leader can invite another owner's Bot * Jan 4 Basic structure in place for Raid::AddBot though not working * Basement Jan 5 * End of day Jan 5 Working Raid Invite to a Bot. * Update to Client::QueuePacket to not attempt to send a packet to a BoT. Not clean, but a broad solution. * Updated Raid::VerifyRaid * Some Bot Raid working * Before VS Crash * Use Case 1, 2, 3,4,7 working. Need to fix 5, 6, 8 * Work on usecase 5 * A few more use cases working * New work on Raid invite with a invitor having a group * Bot Raid inviting working for all use cases * A few changes * end of day jan 10 * Jan 11 * end of day Jan 11 * Bot Invite/Accept cleanup * Start of moving raid bot functions to their own methods * More bot raid changes * More raid spell work * end of day Jan 16 * spawn work * Spawn on login working * End of Day Jan 18 * Raid leader and mana/hp updates fixed * Spell Tracking * Issue with Bot Death in raid when casted upon. 1741 raid.cpp * Bot Death fixed and few other crashes * Working on botgroup removal * Bot Disbanding Work 90% * Looks like BOTs are working * Fixed a bot crash * bug tracing on entity list mismatch * safe_delete resoves problem. No to track down leak * seems to be working * Memory corruption found - sending packets to BoTs using Client class * added Raid::IsRaidMemberBot() * Update p_raid_instance * g3 * Final - Bot Raid Working * Fixed IsRaidMemberBot to remove memory leak Fixed altcombat crash though RaidMainAssist (428) needs fixing * add RaidMember.IsBot * Repaired IsBot function to be more preformant. Now works on standard performance machine * Fixed Bard AE Target Spells Removed assert for buffs * updated based on Feb 2022 master updates * Added bot_db_updates and version increment * Cleanup of bot raid work and inclusion of bot_raid in cmake * Fix repop crash * Bot databse change to not use view * Revert "Merge branch 'master' of https://github.com/neckkola/Server" This reverts commit 18268306378a34a6f0a9015cfcb4f48364bef013, reversing changes made to 7c1a1399918aeee1dc3f6f30e39044d7d1bec4c9. * Updated syntax for 9230 Updated this syntax as to run on maria 10.1 * Revert "Updated syntax for 9230" This reverts commit ffdd46c8b26a8607d41b95af3c3ab575c41f4231. * Fix for cross zone mark npc when entity ids are reused. * Fixed and tested added db change and tested across zones * Transition to direct attributes instead of encode Update the pattern to utilize direct raid object attributes for entity id, zone id and instance id instead of an encoded single field. --- common/database/database_update_manifest.cpp | 18 +++ .../base/base_raid_details_repository.h | 152 ++++++++++++------ common/repositories/raid_details_repository.h | 16 +- common/version.h | 2 +- zone/client_packet.cpp | 2 +- zone/command.h | 2 +- zone/raids.cpp | 77 +++++---- zone/raids.h | 8 +- 8 files changed, 193 insertions(+), 84 deletions(-) diff --git a/common/database/database_update_manifest.cpp b/common/database/database_update_manifest.cpp index d4d4f1f18..b93e79a31 100644 --- a/common/database/database_update_manifest.cpp +++ b/common/database/database_update_manifest.cpp @@ -4827,6 +4827,24 @@ UPDATE data_buckets SET bot_id = SUBSTRING_INDEX(SUBSTRING_INDEX( `key`, '-', 2 )" }, + ManifestEntry{ + .version = 9234, + .description = "2023_07_27_update_raid_details.sql", + .check = "SHOW COLUMNS FROM `raid_details` LIKE 'marked_npc_1_entity_id';", + .condition = "empty", + .match = "", + .sql = R"(ALTER TABLE `raid_details` + CHANGE COLUMN `marked_npc_1` `marked_npc_1_entity_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `motd`, + ADD COLUMN `marked_npc_1_zone_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_1_entity_id`, + ADD COLUMN `marked_npc_1_instance_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_1_zone_id`, + CHANGE COLUMN `marked_npc_2` `marked_npc_2_entity_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_1_instance_id`, + ADD COLUMN `marked_npc_2_zone_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_2_entity_id`, + ADD COLUMN `marked_npc_2_instance_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_2_zone_id`, + CHANGE COLUMN `marked_npc_3` `marked_npc_3_entity_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_2_instance_id`, + ADD COLUMN `marked_npc_3_zone_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_3_entity_id`, + ADD COLUMN `marked_npc_3_instance_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_3_zone_id`; + )" + }, // -- template; copy/paste this when you need to create a new entry // ManifestEntry{ diff --git a/common/repositories/base/base_raid_details_repository.h b/common/repositories/base/base_raid_details_repository.h index 5479595bd..616490dd5 100644 --- a/common/repositories/base/base_raid_details_repository.h +++ b/common/repositories/base/base_raid_details_repository.h @@ -24,9 +24,15 @@ public: int32_t loottype; int8_t locked; std::string motd; - uint16_t marked_npc_1; - uint16_t marked_npc_2; - uint16_t marked_npc_3; + uint32_t marked_npc_1_entity_id; + uint32_t marked_npc_1_zone_id; + uint32_t marked_npc_1_instance_id; + uint32_t marked_npc_2_entity_id; + uint32_t marked_npc_2_zone_id; + uint32_t marked_npc_2_instance_id; + uint32_t marked_npc_3_entity_id; + uint32_t marked_npc_3_zone_id; + uint32_t marked_npc_3_instance_id; }; static std::string PrimaryKey() @@ -41,9 +47,15 @@ public: "loottype", "locked", "motd", - "marked_npc_1", - "marked_npc_2", - "marked_npc_3", + "marked_npc_1_entity_id", + "marked_npc_1_zone_id", + "marked_npc_1_instance_id", + "marked_npc_2_entity_id", + "marked_npc_2_zone_id", + "marked_npc_2_instance_id", + "marked_npc_3_entity_id", + "marked_npc_3_zone_id", + "marked_npc_3_instance_id", }; } @@ -54,9 +66,15 @@ public: "loottype", "locked", "motd", - "marked_npc_1", - "marked_npc_2", - "marked_npc_3", + "marked_npc_1_entity_id", + "marked_npc_1_zone_id", + "marked_npc_1_instance_id", + "marked_npc_2_entity_id", + "marked_npc_2_zone_id", + "marked_npc_2_instance_id", + "marked_npc_3_entity_id", + "marked_npc_3_zone_id", + "marked_npc_3_instance_id", }; } @@ -97,13 +115,19 @@ public: { RaidDetails e{}; - e.raidid = 0; - e.loottype = 0; - e.locked = 0; - e.motd = ""; - e.marked_npc_1 = 0; - e.marked_npc_2 = 0; - e.marked_npc_3 = 0; + e.raidid = 0; + e.loottype = 0; + e.locked = 0; + e.motd = ""; + e.marked_npc_1_entity_id = 0; + e.marked_npc_1_zone_id = 0; + e.marked_npc_1_instance_id = 0; + e.marked_npc_2_entity_id = 0; + e.marked_npc_2_zone_id = 0; + e.marked_npc_2_instance_id = 0; + e.marked_npc_3_entity_id = 0; + e.marked_npc_3_zone_id = 0; + e.marked_npc_3_instance_id = 0; return e; } @@ -140,13 +164,19 @@ public: if (results.RowCount() == 1) { RaidDetails e{}; - e.raidid = static_cast(atoi(row[0])); - e.loottype = static_cast(atoi(row[1])); - e.locked = static_cast(atoi(row[2])); - e.motd = row[3] ? row[3] : ""; - e.marked_npc_1 = static_cast(strtoul(row[4], nullptr, 10)); - e.marked_npc_2 = static_cast(strtoul(row[5], nullptr, 10)); - e.marked_npc_3 = static_cast(strtoul(row[6], nullptr, 10)); + e.raidid = static_cast(atoi(row[0])); + e.loottype = static_cast(atoi(row[1])); + e.locked = static_cast(atoi(row[2])); + e.motd = row[3] ? row[3] : ""; + e.marked_npc_1_entity_id = static_cast(strtoul(row[4], nullptr, 10)); + e.marked_npc_1_zone_id = static_cast(strtoul(row[5], nullptr, 10)); + e.marked_npc_1_instance_id = static_cast(strtoul(row[6], nullptr, 10)); + e.marked_npc_2_entity_id = static_cast(strtoul(row[7], nullptr, 10)); + e.marked_npc_2_zone_id = static_cast(strtoul(row[8], nullptr, 10)); + e.marked_npc_2_instance_id = static_cast(strtoul(row[9], nullptr, 10)); + e.marked_npc_3_entity_id = static_cast(strtoul(row[10], nullptr, 10)); + e.marked_npc_3_zone_id = static_cast(strtoul(row[11], nullptr, 10)); + e.marked_npc_3_instance_id = static_cast(strtoul(row[12], nullptr, 10)); return e; } @@ -184,9 +214,15 @@ public: v.push_back(columns[1] + " = " + std::to_string(e.loottype)); v.push_back(columns[2] + " = " + std::to_string(e.locked)); v.push_back(columns[3] + " = '" + Strings::Escape(e.motd) + "'"); - v.push_back(columns[4] + " = " + std::to_string(e.marked_npc_1)); - v.push_back(columns[5] + " = " + std::to_string(e.marked_npc_2)); - v.push_back(columns[6] + " = " + std::to_string(e.marked_npc_3)); + v.push_back(columns[4] + " = " + std::to_string(e.marked_npc_1_entity_id)); + v.push_back(columns[5] + " = " + std::to_string(e.marked_npc_1_zone_id)); + v.push_back(columns[6] + " = " + std::to_string(e.marked_npc_1_instance_id)); + v.push_back(columns[7] + " = " + std::to_string(e.marked_npc_2_entity_id)); + v.push_back(columns[8] + " = " + std::to_string(e.marked_npc_2_zone_id)); + v.push_back(columns[9] + " = " + std::to_string(e.marked_npc_2_instance_id)); + v.push_back(columns[10] + " = " + std::to_string(e.marked_npc_3_entity_id)); + v.push_back(columns[11] + " = " + std::to_string(e.marked_npc_3_zone_id)); + v.push_back(columns[12] + " = " + std::to_string(e.marked_npc_3_instance_id)); auto results = db.QueryDatabase( fmt::format( @@ -212,9 +248,15 @@ public: v.push_back(std::to_string(e.loottype)); v.push_back(std::to_string(e.locked)); v.push_back("'" + Strings::Escape(e.motd) + "'"); - v.push_back(std::to_string(e.marked_npc_1)); - v.push_back(std::to_string(e.marked_npc_2)); - v.push_back(std::to_string(e.marked_npc_3)); + v.push_back(std::to_string(e.marked_npc_1_entity_id)); + v.push_back(std::to_string(e.marked_npc_1_zone_id)); + v.push_back(std::to_string(e.marked_npc_1_instance_id)); + v.push_back(std::to_string(e.marked_npc_2_entity_id)); + v.push_back(std::to_string(e.marked_npc_2_zone_id)); + v.push_back(std::to_string(e.marked_npc_2_instance_id)); + v.push_back(std::to_string(e.marked_npc_3_entity_id)); + v.push_back(std::to_string(e.marked_npc_3_zone_id)); + v.push_back(std::to_string(e.marked_npc_3_instance_id)); auto results = db.QueryDatabase( fmt::format( @@ -248,9 +290,15 @@ public: v.push_back(std::to_string(e.loottype)); v.push_back(std::to_string(e.locked)); v.push_back("'" + Strings::Escape(e.motd) + "'"); - v.push_back(std::to_string(e.marked_npc_1)); - v.push_back(std::to_string(e.marked_npc_2)); - v.push_back(std::to_string(e.marked_npc_3)); + v.push_back(std::to_string(e.marked_npc_1_entity_id)); + v.push_back(std::to_string(e.marked_npc_1_zone_id)); + v.push_back(std::to_string(e.marked_npc_1_instance_id)); + v.push_back(std::to_string(e.marked_npc_2_entity_id)); + v.push_back(std::to_string(e.marked_npc_2_zone_id)); + v.push_back(std::to_string(e.marked_npc_2_instance_id)); + v.push_back(std::to_string(e.marked_npc_3_entity_id)); + v.push_back(std::to_string(e.marked_npc_3_zone_id)); + v.push_back(std::to_string(e.marked_npc_3_instance_id)); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); } @@ -284,13 +332,19 @@ public: for (auto row = results.begin(); row != results.end(); ++row) { RaidDetails e{}; - e.raidid = static_cast(atoi(row[0])); - e.loottype = static_cast(atoi(row[1])); - e.locked = static_cast(atoi(row[2])); - e.motd = row[3] ? row[3] : ""; - e.marked_npc_1 = static_cast(strtoul(row[4], nullptr, 10)); - e.marked_npc_2 = static_cast(strtoul(row[5], nullptr, 10)); - e.marked_npc_3 = static_cast(strtoul(row[6], nullptr, 10)); + e.raidid = static_cast(atoi(row[0])); + e.loottype = static_cast(atoi(row[1])); + e.locked = static_cast(atoi(row[2])); + e.motd = row[3] ? row[3] : ""; + e.marked_npc_1_entity_id = static_cast(strtoul(row[4], nullptr, 10)); + e.marked_npc_1_zone_id = static_cast(strtoul(row[5], nullptr, 10)); + e.marked_npc_1_instance_id = static_cast(strtoul(row[6], nullptr, 10)); + e.marked_npc_2_entity_id = static_cast(strtoul(row[7], nullptr, 10)); + e.marked_npc_2_zone_id = static_cast(strtoul(row[8], nullptr, 10)); + e.marked_npc_2_instance_id = static_cast(strtoul(row[9], nullptr, 10)); + e.marked_npc_3_entity_id = static_cast(strtoul(row[10], nullptr, 10)); + e.marked_npc_3_zone_id = static_cast(strtoul(row[11], nullptr, 10)); + e.marked_npc_3_instance_id = static_cast(strtoul(row[12], nullptr, 10)); all_entries.push_back(e); } @@ -315,13 +369,19 @@ public: for (auto row = results.begin(); row != results.end(); ++row) { RaidDetails e{}; - e.raidid = static_cast(atoi(row[0])); - e.loottype = static_cast(atoi(row[1])); - e.locked = static_cast(atoi(row[2])); - e.motd = row[3] ? row[3] : ""; - e.marked_npc_1 = static_cast(strtoul(row[4], nullptr, 10)); - e.marked_npc_2 = static_cast(strtoul(row[5], nullptr, 10)); - e.marked_npc_3 = static_cast(strtoul(row[6], nullptr, 10)); + e.raidid = static_cast(atoi(row[0])); + e.loottype = static_cast(atoi(row[1])); + e.locked = static_cast(atoi(row[2])); + e.motd = row[3] ? row[3] : ""; + e.marked_npc_1_entity_id = static_cast(strtoul(row[4], nullptr, 10)); + e.marked_npc_1_zone_id = static_cast(strtoul(row[5], nullptr, 10)); + e.marked_npc_1_instance_id = static_cast(strtoul(row[6], nullptr, 10)); + e.marked_npc_2_entity_id = static_cast(strtoul(row[7], nullptr, 10)); + e.marked_npc_2_zone_id = static_cast(strtoul(row[8], nullptr, 10)); + e.marked_npc_2_instance_id = static_cast(strtoul(row[9], nullptr, 10)); + e.marked_npc_3_entity_id = static_cast(strtoul(row[10], nullptr, 10)); + e.marked_npc_3_zone_id = static_cast(strtoul(row[11], nullptr, 10)); + e.marked_npc_3_instance_id = static_cast(strtoul(row[12], nullptr, 10)); all_entries.push_back(e); } diff --git a/common/repositories/raid_details_repository.h b/common/repositories/raid_details_repository.h index 61030c2fd..d37a42434 100644 --- a/common/repositories/raid_details_repository.h +++ b/common/repositories/raid_details_repository.h @@ -47,17 +47,21 @@ public: static int UpdateRaidMarkedNPC( Database& db, int32_t raid_id, - uint8_t marked_npc_number, - uint8_t value + uint32_t marked_npc_entity_id, + uint32_t marked_npc_zone_id, + uint32_t marked_npc_instance_id, + uint32_t slot_number ) { auto results = db.QueryDatabase( fmt::format( - "UPDATE `{}` SET `marked_npc_{}` = '{}' WHERE raidid = '{}';", + "UPDATE `{0}` SET `marked_npc_{4}_entity_id` = '{1}',`marked_npc_{4}_zone_id` = '{2}',`marked_npc_{4}_instance_id` = '{3}' WHERE raidid = '{5}';", TableName(), - marked_npc_number, - value, + marked_npc_entity_id, + marked_npc_zone_id, + marked_npc_instance_id, + slot_number, raid_id - ) + ) ); return results.Success() ? results.RowsAffected() : 0; diff --git a/common/version.h b/common/version.h index faaaebaa7..d4f961c48 100644 --- a/common/version.h +++ b/common/version.h @@ -42,7 +42,7 @@ * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9233 +#define CURRENT_BINARY_DATABASE_VERSION 9234 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9039 diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index cd9a5202d..c983a30e1 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -15953,7 +15953,7 @@ void Client::Handle_OP_XTargetRequest(const EQApplicationPacket *app) if (t.type == Type) { Raid* r = GetRaid(); if (r) { - auto mm = entity_list.GetNPCByID(r->marked_npcs[t.assist_slot]); + auto mm = entity_list.GetNPCByID(r->marked_npcs[t.assist_slot].entity_id); if (mm) { UpdateXTargetType(t.type, mm->CastToMob(), mm->CastToMob()->GetName()); } diff --git a/zone/command.h b/zone/command.h index 4b20761ea..553c93c09 100644 --- a/zone/command.h +++ b/zone/command.h @@ -135,7 +135,7 @@ void command_petitems(Client *c, const Seperator *sep); void command_picklock(Client *c, const Seperator *sep); void command_profanity(Client *c, const Seperator *sep); void command_push(Client *c, const Seperator *sep); -void command_pvp(Client *c, const Seperator *sep);; +void command_pvp(Client *c, const Seperator *sep); void command_raidloot(Client* c, const Seperator* sep); void command_randomfeatures(Client *c, const Seperator *sep); void command_refreshgroup(Client *c, const Seperator *sep); diff --git a/zone/raids.cpp b/zone/raids.cpp index c0385167d..16a4a3f6c 100644 --- a/zone/raids.cpp +++ b/zone/raids.cpp @@ -55,7 +55,9 @@ Raid::Raid(uint32 raidID) for (int i = 0; i < MAX_NO_RAID_MAIN_ASSISTERS; i++) { memset(main_assister_pcs[i], 0, 64); memset(main_marker_pcs[i], 0, 64); - marked_npcs[i] = 0; + marked_npcs[i].entity_id = 0; + marked_npcs[i].zone_id = 0; + marked_npcs[i].instance_id = 0; } } @@ -80,7 +82,9 @@ Raid::Raid(Client* nLeader) for (int i = 0; i < MAX_NO_RAID_MAIN_ASSISTERS; i++) { memset(main_assister_pcs[i], 0, 64); memset(main_marker_pcs[i], 0, 64); - marked_npcs[i] = 0; + marked_npcs[i].entity_id = 0; + marked_npcs[i].zone_id = 0; + marked_npcs[i].instance_id = 0; } } @@ -1678,9 +1682,15 @@ void Raid::GetRaidDetails() locked = raid_details.locked; LootType = raid_details.loottype; motd = raid_details.motd; - marked_npcs[0] = raid_details.marked_npc_1; - marked_npcs[1] = raid_details.marked_npc_2; - marked_npcs[2] = raid_details.marked_npc_3; + marked_npcs[0].entity_id = raid_details.marked_npc_1_entity_id; + marked_npcs[0].zone_id = raid_details.marked_npc_1_zone_id; + marked_npcs[0].instance_id = raid_details.marked_npc_1_instance_id; + marked_npcs[1].entity_id = raid_details.marked_npc_2_entity_id; + marked_npcs[1].zone_id = raid_details.marked_npc_2_zone_id; + marked_npcs[1].instance_id = raid_details.marked_npc_2_instance_id; + marked_npcs[2].entity_id = raid_details.marked_npc_3_entity_id; + marked_npcs[2].zone_id = raid_details.marked_npc_3_zone_id; + marked_npcs[2].instance_id = raid_details.marked_npc_3_instance_id; } void Raid::SaveRaidMOTD() @@ -2419,8 +2429,8 @@ void Raid::UpdateRaidXTargets() }; for (auto& u : marked_updates) { - if (marked_npcs[u.slot]) { - auto m = entity_list.GetMob(marked_npcs[u.slot]); + if (marked_npcs[u.slot].entity_id) { + auto m = entity_list.GetMob(marked_npcs[u.slot].entity_id); if (m && m->GetHP() > 0) { UpdateXTargetType(u.mark_target, m, m->GetName()); } @@ -2562,13 +2572,17 @@ void Raid::RaidMarkNPC(Mob* mob, uint32 parameter) for (int i = 0; i < MAX_NO_RAID_MAIN_MARKERS; i++) { auto cname = c->GetCleanName(); if (strcasecmp(main_marker_pcs[i], cname) == 0 || strcasecmp(leadername, cname) == 0) { - marked_npcs[parameter - 1] = c->GetTarget()->GetID(); + marked_npcs[parameter - 1].entity_id = c->GetTarget()->GetID(); + marked_npcs[parameter - 1].zone_id = c->GetTarget()->GetZoneID(); + marked_npcs[parameter - 1].instance_id = c->GetTarget()->GetInstanceVersion(); auto result = RaidDetailsRepository::UpdateRaidMarkedNPC( database, GetID(), - parameter, - marked_npcs[parameter - 1] - ); + marked_npcs[parameter - 1].entity_id, + marked_npcs[parameter - 1].zone_id, + marked_npcs[parameter - 1].instance_id, + parameter + ); if (!result) { LogError("Unable to set MarkedNPC{} from slot: [{}] for guild [{}].", parameter, @@ -2579,7 +2593,7 @@ void Raid::RaidMarkNPC(Mob* mob, uint32 parameter) auto outapp = new EQApplicationPacket(OP_MarkRaidNPC, sizeof(MarkNPC_Struct)); MarkNPC_Struct* mnpcs = (MarkNPC_Struct*)outapp->pBuffer; - mnpcs->TargetID = marked_npcs[parameter - 1]; + mnpcs->TargetID = marked_npcs[parameter - 1].entity_id; mnpcs->Number = parameter; strcpy(mnpcs->Name, c->GetTarget()->GetCleanName()); QueuePacket(outapp); @@ -2596,7 +2610,7 @@ void Raid::RaidMarkNPC(Mob* mob, uint32 parameter) void Raid::UpdateXtargetMarkedNPC() { for (int i = 0; i < MAX_MARKED_NPCS; i++) { - auto mm = entity_list.GetNPCByID(marked_npcs[i]); + auto mm = entity_list.GetNPCByID(marked_npcs[i].entity_id); if (mm) { UpdateXTargetType(static_cast(RaidMarkTarget1 + i), mm->CastToMob(), mm->CastToMob()->GetName()); } @@ -2614,19 +2628,25 @@ void Raid::RaidClearNPCMarks(Client* c) Strings::EqualFold(main_marker_pcs[MAIN_MARKER_2_SLOT], c->GetCleanName()) || Strings::EqualFold(main_marker_pcs[MAIN_MARKER_3_SLOT], c->GetCleanName())) { for (int i = 0; i < MAX_MARKED_NPCS; i++) { - if (marked_npcs[i]) { - auto npc_name = entity_list.GetNPCByID(marked_npcs[i])->GetCleanName(); + if (marked_npcs[i].entity_id > 0 && marked_npcs[i].zone_id == c->GetZoneID() + && marked_npcs[i].instance_id == c->GetInstanceID()) + { + auto npc_name = entity_list.GetNPCByID(marked_npcs[i].entity_id)->GetCleanName(); RaidMessageString(nullptr, Chat::Cyan, RAID_NO_LONGER_MARKED, npc_name); - } - marked_npcs[i] = 0; - auto result = RaidDetailsRepository::UpdateRaidMarkedNPC( - database, - GetID(), - i + 1, - 0 - ); - if (!result) { - LogError("Unable to clear MarkedNPC{} from slot: [{}] for guild [{}].", i + 1, i, GetID()); + marked_npcs[i].entity_id = 0; + marked_npcs[i].zone_id = 0; + marked_npcs[i].instance_id = 0; + auto result = RaidDetailsRepository::UpdateRaidMarkedNPC( + database, + GetID(), + 0, + 0, + 0, + i + 1 + ); + if (!result) { + LogError("Unable to clear MarkedNPC{} from slot: [{}] for guild [{}].", i + 1, i, GetID()); + } } } @@ -2934,12 +2954,13 @@ void Raid::SendMarkTargets(Client* c) } for (int i = 0; i < MAX_MARKED_NPCS; i++) { - if (marked_npcs[i] > 0) { - auto marked_mob = entity_list.GetMob(marked_npcs[i]); + if (marked_npcs[i].entity_id > 0 && marked_npcs[i].zone_id == c->GetZoneID() + && marked_npcs[i].instance_id == c->GetInstanceID()) { + auto marked_mob = entity_list.GetMob(marked_npcs[i].entity_id); if (marked_mob) { auto outapp = new EQApplicationPacket(OP_MarkRaidNPC, sizeof(MarkNPC_Struct)); MarkNPC_Struct* mnpcs = (MarkNPC_Struct*)outapp->pBuffer; - mnpcs->TargetID = marked_npcs[i]; + mnpcs->TargetID = marked_mob->GetID(); mnpcs->Number = i + 1; strcpy(mnpcs->Name, marked_mob->GetCleanName()); QueuePacket(outapp); diff --git a/zone/raids.h b/zone/raids.h index 551b1fcaa..1c1dabc02 100644 --- a/zone/raids.h +++ b/zone/raids.h @@ -110,6 +110,12 @@ enum { DELEGATE_ON = 1 }; +struct Raid_Marked_NPC { + uint32 entity_id; + uint32 zone_id; + uint32 instance_id; +}; + constexpr uint8_t MAX_RAID_GROUPS = 12; constexpr uint8_t MAX_RAID_MEMBERS = 72; @@ -326,7 +332,7 @@ public: char leadername[64]; char main_assister_pcs[MAX_NO_RAID_MAIN_ASSISTERS][64]; char main_marker_pcs[MAX_NO_RAID_MAIN_MARKERS][64]; - uint32 marked_npcs[MAX_MARKED_NPCS]; + Raid_Marked_NPC marked_npcs[MAX_MARKED_NPCS]; protected: Client *leader; bool locked;