Skip to content

Commit

Permalink
refactor(Core/Event): Load event vendors seperatly (azerothcore#20906)
Browse files Browse the repository at this point in the history
  • Loading branch information
Exitare authored Dec 22, 2024
1 parent 7714ca3 commit b4d04b1
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 63 deletions.
3 changes: 3 additions & 0 deletions data/sql/updates/pending_db_world/rev_1734055142233360300.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--
DELETE FROM `command` where `name` = 'reload game_event_npc_vendor';
INSERT INTO `command` (`name`, `security`, `help`) VALUES ('reload game_event_npc_vendor', 3, 'Syntax: .reload game_event_npc_vendor\r Reload game_event_npc_vendor table.');
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
150 changes: 87 additions & 63 deletions src/server/game/Events/GameEventMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
{
Expand Down Expand Up @@ -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...");
{
Expand Down
2 changes: 2 additions & 0 deletions src/server/game/Events/GameEventMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ class GameEventMgr
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);
Expand Down
9 changes: 9 additions & 0 deletions src/server/scripts/Commands/cs_reload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class reload_commandscript : public CommandScript
{ "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 },
Expand Down Expand Up @@ -765,6 +766,14 @@ class reload_commandscript : public CommandScript
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!");
Expand Down

0 comments on commit b4d04b1

Please sign in to comment.