mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-29 05:41:29 +00:00
Bulk load grids at repop and zone init instead of 2 costly individual selects per NPC, create repositories to decouple database logic from business logic
This commit is contained in:
parent
128cc458fd
commit
43716332aa
@ -197,6 +197,8 @@ SET(common_headers
|
||||
races.h
|
||||
random.h
|
||||
repositories/character_recipe_list_repository.h
|
||||
repositories/grid_repository.h
|
||||
repositories/grid_entries_repository.h
|
||||
repositories/tradeskill_recipe_repository.h
|
||||
rdtsc.h
|
||||
rulesys.h
|
||||
|
||||
126
common/repositories/grid_entries_repository.h
Normal file
126
common/repositories/grid_entries_repository.h
Normal file
@ -0,0 +1,126 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_GRID_ENTRIES_REPOSITORY_H
|
||||
#define EQEMU_GRID_ENTRIES_REPOSITORY_H
|
||||
|
||||
#include "../database.h"
|
||||
#include "../string_util.h"
|
||||
|
||||
class GridEntriesRepository {
|
||||
public:
|
||||
struct GridEntry {
|
||||
int gridid;
|
||||
int zoneid;
|
||||
int number;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float heading;
|
||||
int pause;
|
||||
int8 centerpoint;
|
||||
};
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"gridid",
|
||||
"zoneid",
|
||||
"number",
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
"heading",
|
||||
"pause",
|
||||
"centerpoint",
|
||||
};
|
||||
}
|
||||
|
||||
static std::string ColumnsRaw()
|
||||
{
|
||||
return std::string(implode(", ", Columns()));
|
||||
}
|
||||
|
||||
static std::string TableName()
|
||||
{
|
||||
return std::string("grid_entries");
|
||||
}
|
||||
|
||||
static std::string BaseSelect()
|
||||
{
|
||||
return std::string(
|
||||
fmt::format(
|
||||
"SELECT {} FROM {}",
|
||||
ColumnsRaw(),
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static GridEntry Default()
|
||||
{
|
||||
GridEntry entry{};
|
||||
|
||||
entry.gridid = 0;
|
||||
entry.zoneid = 0;
|
||||
entry.number = 0;
|
||||
entry.x = 0;
|
||||
entry.y = 0;
|
||||
entry.z = 0;
|
||||
entry.heading = 0;
|
||||
entry.pause = 0;
|
||||
entry.centerpoint = 0;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static std::vector<GridEntry> GetZoneGridEntries(int zone_id)
|
||||
{
|
||||
std::vector<GridEntry> grid_entries;
|
||||
|
||||
auto results = content_db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE zoneid = {} ORDER BY gridid, number",
|
||||
BaseSelect(),
|
||||
zone_id
|
||||
)
|
||||
);
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
GridEntry entry{};
|
||||
|
||||
entry.gridid = atoi(row[0]);
|
||||
entry.zoneid = atoi(row[1]);
|
||||
entry.number = atoi(row[2]);
|
||||
entry.x = atof(row[3]);
|
||||
entry.y = atof(row[4]);
|
||||
entry.z = atof(row[5]);
|
||||
entry.heading = atof(row[6]);
|
||||
entry.pause = atoi(row[7]);
|
||||
entry.centerpoint = atoi(row[8]);
|
||||
|
||||
grid_entries.push_back(entry);
|
||||
}
|
||||
|
||||
return grid_entries;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
121
common/repositories/grid_repository.h
Normal file
121
common/repositories/grid_repository.h
Normal file
@ -0,0 +1,121 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_GRID_REPOSITORY_H
|
||||
#define EQEMU_GRID_REPOSITORY_H
|
||||
|
||||
#include "../database.h"
|
||||
#include "../string_util.h"
|
||||
|
||||
class GridRepository {
|
||||
public:
|
||||
struct Grid {
|
||||
int id;
|
||||
int zoneid;
|
||||
int type;
|
||||
int type2;
|
||||
};
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"zoneid",
|
||||
"type",
|
||||
"type2",
|
||||
};
|
||||
}
|
||||
|
||||
static std::string ColumnsRaw()
|
||||
{
|
||||
return std::string(implode(", ", Columns()));
|
||||
}
|
||||
|
||||
static std::string TableName()
|
||||
{
|
||||
return std::string("grid");
|
||||
}
|
||||
|
||||
static std::string BaseSelect()
|
||||
{
|
||||
return std::string(
|
||||
fmt::format(
|
||||
"SELECT {} FROM {}",
|
||||
ColumnsRaw(),
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static Grid Default()
|
||||
{
|
||||
Grid entry{};
|
||||
|
||||
entry.id = 0;
|
||||
entry.zoneid = 0;
|
||||
entry.type = 0;
|
||||
entry.type2 = 0;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static std::vector<Grid> GetZoneGrids(int zone_id)
|
||||
{
|
||||
std::vector<Grid> grids;
|
||||
|
||||
auto results = content_db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE zoneid = {}",
|
||||
BaseSelect(),
|
||||
zone_id
|
||||
)
|
||||
);
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
Grid entry{};
|
||||
|
||||
entry.id = atoi(row[0]);
|
||||
entry.zoneid = atoi(row[1]);
|
||||
entry.type = atoi(row[2]);
|
||||
entry.type2 = atoi(row[3]);
|
||||
|
||||
grids.push_back(entry);
|
||||
}
|
||||
|
||||
return grids;
|
||||
}
|
||||
|
||||
static Grid GetGrid(
|
||||
const std::vector<Grid>& grids,
|
||||
int grid_id
|
||||
)
|
||||
{
|
||||
for (auto &row : grids) {
|
||||
if (row.id == grid_id) {
|
||||
return row;
|
||||
}
|
||||
}
|
||||
|
||||
return Default();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -303,7 +303,7 @@ public:
|
||||
int GetMaxWp() const { return max_wp; }
|
||||
void DisplayWaypointInfo(Client *to);
|
||||
void CalculateNewWaypoint();
|
||||
void AssignWaypoints(int32 grid, int start_wp = 0);
|
||||
void AssignWaypoints(int32 grid_id, int start_wp = 0);
|
||||
void SetWaypointPause();
|
||||
void UpdateWaypoint(int wp_index);
|
||||
|
||||
|
||||
@ -561,62 +561,54 @@ void Mob::StopNavigation() {
|
||||
mMovementManager->StopNavigation(this);
|
||||
}
|
||||
|
||||
void NPC::AssignWaypoints(int32 grid, int start_wp)
|
||||
void NPC::AssignWaypoints(int32 grid_id, int start_wp)
|
||||
{
|
||||
if (grid == 0)
|
||||
if (grid_id == 0)
|
||||
return; // grid ID 0 not supported
|
||||
|
||||
if (grid < 0) {
|
||||
if (grid_id < 0) {
|
||||
// Allow setting negative grid values for pausing pathing
|
||||
this->CastToNPC()->SetGrid(grid);
|
||||
this->CastToNPC()->SetGrid(grid_id);
|
||||
return;
|
||||
}
|
||||
|
||||
Waypoints.clear();
|
||||
roamer = false;
|
||||
|
||||
// Retrieve the wander and pause types for this grid
|
||||
std::string query = StringFormat("SELECT `type`, `type2` FROM `grid` WHERE `id` = %i AND `zoneid` = %i", grid,
|
||||
zone->GetZoneID());
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
auto grid_entry = GridRepository::GetGrid(zone->grids, grid_id);
|
||||
if (grid_entry.id == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return;
|
||||
wandertype = grid_entry.type;
|
||||
pausetype = grid_entry.type2;
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
wandertype = atoi(row[0]);
|
||||
pausetype = atoi(row[1]);
|
||||
|
||||
SetGrid(grid); // Assign grid number
|
||||
|
||||
// Retrieve all waypoints for this grid
|
||||
query = StringFormat("SELECT `x`,`y`,`z`,`pause`,`heading`, `centerpoint` "
|
||||
"FROM grid_entries WHERE `gridid` = %i AND `zoneid` = %i "
|
||||
"ORDER BY `number`", grid, zone->GetZoneID());
|
||||
results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
SetGrid(grid_id); // Assign grid number
|
||||
|
||||
roamer = true;
|
||||
max_wp = 0; // Initialize it; will increment it for each waypoint successfully added to the list
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row, ++max_wp)
|
||||
{
|
||||
wplist newwp;
|
||||
newwp.index = max_wp;
|
||||
newwp.x = atof(row[0]);
|
||||
newwp.y = atof(row[1]);
|
||||
newwp.z = atof(row[2]);
|
||||
for (auto &entry : zone->grid_entries) {
|
||||
if (entry.gridid == grid_id) {
|
||||
wplist new_waypoint{};
|
||||
new_waypoint.index = max_wp;
|
||||
new_waypoint.x = entry.x;
|
||||
new_waypoint.y = entry.y;
|
||||
new_waypoint.z = entry.z;
|
||||
new_waypoint.pause = entry.pause;
|
||||
new_waypoint.heading = entry.heading;
|
||||
new_waypoint.centerpoint = entry.centerpoint;
|
||||
|
||||
newwp.pause = atoi(row[3]);
|
||||
newwp.heading = atof(row[4]);
|
||||
newwp.centerpoint = atobool(row[5]);
|
||||
Waypoints.push_back(newwp);
|
||||
LogPathing(
|
||||
"Loading Grid [{}] number [{}] name [{}]",
|
||||
grid_id,
|
||||
entry.number,
|
||||
GetCleanName()
|
||||
);
|
||||
|
||||
Waypoints.push_back(new_waypoint);
|
||||
max_wp++;
|
||||
}
|
||||
}
|
||||
|
||||
cur_wp = start_wp;
|
||||
@ -628,8 +620,9 @@ void NPC::AssignWaypoints(int32 grid, int start_wp)
|
||||
patrol = cur_wp;
|
||||
}
|
||||
|
||||
if (wandertype == GridRandom10 || wandertype == GridRandom || wandertype == GridRand5LoS)
|
||||
if (wandertype == GridRandom10 || wandertype == GridRandom || wandertype == GridRand5LoS) {
|
||||
CalculateNewWaypoint();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -737,7 +730,7 @@ void Mob::FixZ(int32 z_find_offset /*= 5*/, bool fix_client_z /*= false*/) {
|
||||
if (IsClient() && !fix_client_z) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (flymode == GravityBehavior::Flying) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1023,6 +1023,7 @@ bool Zone::Init(bool iStaticZone) {
|
||||
|
||||
LogInfo("Init Finished: ZoneID = [{}], Time Offset = [{}]", zoneid, zone->zone_time.getEQTimeZone());
|
||||
|
||||
LoadGrids();
|
||||
LoadTickItems();
|
||||
|
||||
//MODDING HOOK FOR ZONE INIT
|
||||
@ -1610,6 +1611,8 @@ void Zone::Repop(uint32 delay)
|
||||
if (!content_db.PopulateZoneSpawnList(zoneid, spawn2_list, GetInstanceVersion(), delay))
|
||||
LogDebug("Error in Zone::Repop: database.PopulateZoneSpawnList failed");
|
||||
|
||||
LoadGrids();
|
||||
|
||||
initgrids_timer.Start();
|
||||
|
||||
entity_list.UpdateAllTraps(true, true);
|
||||
@ -2481,3 +2484,9 @@ void Zone::SetQuestHotReloadQueued(bool in_quest_hot_reload_queued)
|
||||
{
|
||||
quest_hot_reload_queued = in_quest_hot_reload_queued;
|
||||
}
|
||||
|
||||
void Zone::LoadGrids()
|
||||
{
|
||||
grids = GridRepository::GetZoneGrids(GetZoneID());
|
||||
grid_entries = GridEntriesRepository::GetZoneGridEntries(GetZoneID());
|
||||
}
|
||||
|
||||
@ -24,6 +24,9 @@
|
||||
#include "../common/types.h"
|
||||
#include "../common/random.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "zonedb.h"
|
||||
#include "../common/repositories/grid_repository.h"
|
||||
#include "../common/repositories/grid_entries_repository.h"
|
||||
#include "qglobals.h"
|
||||
#include "spawn2.h"
|
||||
#include "spawngroup.h"
|
||||
@ -202,6 +205,9 @@ public:
|
||||
std::unordered_map<int, std::unique_ptr<AA::Ability>> aa_abilities;
|
||||
std::unordered_map<int, std::unique_ptr<AA::Rank>> aa_ranks;
|
||||
|
||||
std::vector<GridRepository::Grid> grids;
|
||||
std::vector<GridEntriesRepository::GridEntry> grid_entries;
|
||||
|
||||
time_t weather_timer;
|
||||
Timer spawn2_timer;
|
||||
Timer hot_reload_timer;
|
||||
@ -239,6 +245,7 @@ public:
|
||||
void LoadLDoNTrapEntries();
|
||||
void LoadLDoNTraps();
|
||||
void LoadLevelEXPMods();
|
||||
void LoadGrids();
|
||||
void LoadMercSpells();
|
||||
void LoadMercTemplates();
|
||||
void LoadNewMerchantData(uint32 merchantid);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user