refactor(Core/Event): Load event vendors seperatly (#20906)

This commit is contained in:
Exitare
2024-12-22 00:44:50 -08:00
committed by GitHub
parent 7714ca31a2
commit b4d04b1af1
6 changed files with 103 additions and 63 deletions

View File

@@ -86,6 +86,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_INS_CREATURE, "INSERT INTO creature (guid, id1, id2, id3, map, spawnMask, phaseMask, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, currentwaypoint, curhealth, curmana, MovementType, npcflag, unit_flags, dynamicflags) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_DEL_GAME_EVENT_CREATURE, "DELETE FROM game_event_creature WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_DEL_GAME_EVENT_MODEL_EQUIP, "DELETE FROM game_event_model_equip WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_GAME_EVENT_NPC_VENDOR, "SELECT eventEntry, guid, item, maxcount, incrtime, ExtendedCost FROM game_event_npc_vendor ORDER BY guid, slot ASC", CONNECTION_SYNCH);
PrepareStatement(WORLD_INS_GAMEOBJECT, "INSERT INTO gameobject (guid, id, map, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_INS_DISABLES, "INSERT INTO disables (entry, sourceType, flags, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_DISABLES, "SELECT entry FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_SYNCH);

View File

@@ -92,6 +92,7 @@ enum WorldDatabaseStatements : uint32
WORLD_INS_CREATURE,
WORLD_DEL_GAME_EVENT_CREATURE,
WORLD_DEL_GAME_EVENT_MODEL_EQUIP,
WORLD_SEL_GAME_EVENT_NPC_VENDOR,
WORLD_INS_GAMEOBJECT,
WORLD_SEL_DISABLES,
WORLD_INS_DISABLES,

View File

@@ -236,6 +236,92 @@ void GameEventMgr::StopEvent(uint16 event_id, bool overwrite)
sScriptMgr->OnGameEventStop(event_id);
}
void GameEventMgr::LoadEventVendors()
{
uint32 oldMSTime = getMSTime();
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_GAME_EVENT_NPC_VENDOR);
PreparedQueryResult result = WorldDatabase.Query(stmt);
if (!result)
{
LOG_WARN("server.loading", ">> Loaded 0 Vendor Additions In Game Events. DB Table `game_event_npc_vendor` Is Empty.");
LOG_INFO("server.loading", " ");
return;
}
uint32 count = 0;
std::unordered_set<uint8> processedEvents;
do
{
Field* fields = result->Fetch();
uint8 eventId = fields[0].Get<uint8>();
ObjectGuid::LowType guid = fields[1].Get<uint32>();
if (eventId >= mGameEventVendors.size())
{
LOG_ERROR("sql.sql", "Table `game_event_npc_vendor` has invalid eventEntry ({}) for GUID ({}), skipped.", eventId, guid);
continue;
}
// Clear existing vendors for this event only once
if (processedEvents.find(eventId) == processedEvents.end())
{
// Remove vendor items from in-memory data
for (auto& entry : mGameEventVendors[eventId])
{
sObjectMgr->RemoveVendorItem(entry.entry, entry.item, false);
}
mGameEventVendors[eventId].clear();
processedEvents.insert(eventId);
}
NPCVendorList& vendors = mGameEventVendors[eventId];
NPCVendorEntry newEntry;
newEntry.item = fields[2].Get<uint32>();
newEntry.maxcount = fields[3].Get<uint32>();
newEntry.incrtime = fields[4].Get<uint32>();
newEntry.ExtendedCost = fields[5].Get<uint32>();
// Get the event NPC flag for validity check
uint32 event_npc_flag = 0;
NPCFlagList& flist = mGameEventNPCFlags[eventId];
for (NPCFlagList::const_iterator itr = flist.begin(); itr != flist.end(); ++itr)
{
if (itr->first == guid)
{
event_npc_flag = itr->second;
break;
}
}
// Get creature entry
newEntry.entry = 0;
if (CreatureData const* data = sObjectMgr->GetCreatureData(guid))
newEntry.entry = data->id1;
// Validate vendor item
if (!sObjectMgr->IsVendorItemValid(newEntry.entry, newEntry.item, newEntry.maxcount, newEntry.incrtime, newEntry.ExtendedCost, nullptr, nullptr, event_npc_flag))
{
LOG_ERROR("sql.sql", "Table `game_event_npc_vendor` has invalid item ({}) for guid ({}) for event ({}), skipped.",
newEntry.item, newEntry.entry, eventId);
continue;
}
// Add the item to the vendor if event is active
if (IsEventActive(eventId))
sObjectMgr->AddVendorItem(newEntry.entry, newEntry.item, newEntry.maxcount, newEntry.incrtime, newEntry.ExtendedCost, false);
vendors.push_back(newEntry);
++count;
} while (result->NextRow());
LOG_INFO("server.loading", ">> Loaded {} Vendor Additions In Game Events in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
LOG_INFO("server.loading", " ");
}
void GameEventMgr::LoadFromDB()
{
{
@@ -852,69 +938,7 @@ void GameEventMgr::LoadFromDB()
}
LOG_INFO("server.loading", "Loading Game Event Vendor Additions Data...");
{
uint32 oldMSTime = getMSTime();
// 0 1 2 3 4 5
QueryResult result = WorldDatabase.Query("SELECT eventEntry, guid, item, maxcount, incrtime, ExtendedCost FROM game_event_npc_vendor ORDER BY guid, slot ASC");
if (!result)
{
LOG_WARN("server.loading", ">> Loaded 0 Vendor Additions In Game Events. DB Table `game_event_npc_vendor` Is Empty.");
LOG_INFO("server.loading", " ");
}
else
{
uint32 count = 0;
do
{
Field* fields = result->Fetch();
uint8 event_id = fields[0].Get<uint8>();
if (event_id >= mGameEventVendors.size())
{
LOG_ERROR("sql.sql", "`game_event_npc_vendor` game event id ({}) is out of range compared to max event id in `game_event`", event_id);
continue;
}
NPCVendorList& vendors = mGameEventVendors[event_id];
NPCVendorEntry newEntry;
ObjectGuid::LowType guid = fields[1].Get<uint32>();
newEntry.item = fields[2].Get<uint32>();
newEntry.maxcount = fields[3].Get<uint32>();
newEntry.incrtime = fields[4].Get<uint32>();
newEntry.ExtendedCost = fields[5].Get<uint32>();
// get the event npc flag for checking if the npc will be vendor during the event or not
uint32 event_npc_flag = 0;
NPCFlagList& flist = mGameEventNPCFlags[event_id];
for (NPCFlagList::const_iterator itr = flist.begin(); itr != flist.end(); ++itr)
{
if (itr->first == guid)
{
event_npc_flag = itr->second;
break;
}
}
// get creature entry
newEntry.entry = 0;
if (CreatureData const* data = sObjectMgr->GetCreatureData(guid))
newEntry.entry = data->id1;
// check validity with event's npcflag
if (!sObjectMgr->IsVendorItemValid(newEntry.entry, newEntry.item, newEntry.maxcount, newEntry.incrtime, newEntry.ExtendedCost, nullptr, nullptr, event_npc_flag))
continue;
vendors.push_back(newEntry);
++count;
} while (result->NextRow());
LOG_INFO("server.loading", ">> Loaded {} Vendor Additions In Game Events in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
LOG_INFO("server.loading", " ");
}
}
LoadEventVendors();
LOG_INFO("server.loading", "Loading Game Event Battleground Data...");
{

View File

@@ -121,6 +121,8 @@ public:
void StopEvent(uint16 event_id, bool overwrite = false);
void HandleQuestComplete(uint32 quest_id); // called on world event type quest completions
uint32 GetNPCFlag(Creature* cr);
// Load the game event npc vendor table from the DB
void LoadEventVendors();
[[nodiscard]] uint32 GetHolidayEventId(uint32 holidayId) const;
private:
void SendWorldStateUpdate(Player* player, uint16 event_id);

View File

@@ -135,6 +135,7 @@ public:
{ "npc_spellclick_spells", HandleReloadSpellClickSpellsCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "npc_trainer", HandleReloadNpcTrainerCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "npc_vendor", HandleReloadNpcVendorCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "game_event_npc_vendor", HandleReloadGameEventNPCVendorCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "page_text", HandleReloadPageTextsCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "pickpocketing_loot_template", HandleReloadLootTemplatesPickpocketingCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "points_of_interest", HandleReloadPointsOfInterestCommand, SEC_ADMINISTRATOR, Console::Yes },
@@ -765,6 +766,14 @@ public:
return true;
}
static bool HandleReloadGameEventNPCVendorCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Reloading `game_event_npc_vendor` Table!");
sGameEventMgr->LoadEventVendors();
handler->SendGlobalGMSysMessage("DB table `game_event_npc_vendor` reloaded.");
return true;
}
static bool HandleReloadPointsOfInterestCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Reloading `points_of_interest` Table!");