[File Paths] Implement Path Manager (#2440)

* Push up branch for testing

* Path manager

* Tweaks

* Changes

* More path work

* Update paths for eqemu_server.pl

* More path work

* Import and export client files

* Path remove

* More path work

* Update eqemu_config.h

* Fix tests

* Tests disable temp

* Update eqemu_config.h

* Update .drone.yml

* Hook tests back up

* Update main.cpp

* Platform tests

* Fix include

* Use std::filesystem on windows

* Fix IPCMutex name on windows

* std::filesystem changes

* Update path_manager.cpp

* Explicit string cast

* Explicit string cast

* Update path_manager.cpp

* Windows fixes

* Mapped files

* Relative fixes

* Use relative paths off of cwd

* Update Debian image to Debian 11 (updates GCC)

Co-authored-by: hg <4683435+hgtw@users.noreply.github.com>
This commit is contained in:
Chris Miles
2022-09-28 04:08:59 -05:00
committed by GitHub
parent 19791195e5
commit f8e7576ae7
53 changed files with 641 additions and 502 deletions
+3 -3
View File
@@ -19,7 +19,7 @@
#include "../common/strings.h"
#include "../common/say_link.h"
#include "../common/net/eqstream.h"
#include "../common/file_util.h"
#include "../common/file.h"
#include "../common/repositories/dynamic_zones_repository.h"
#include "data_bucket.h"
@@ -811,7 +811,7 @@ void command_hotfix(Client *c, const Seperator *sep)
#ifdef WIN32
shared_memory_path = "shared_memory";
if (file_exists("bin/shared_memory.exe")) {
if (File::Exists("bin/shared_memory.exe")) {
shared_memory_path = "bin\\shared_memory.exe";
}
@@ -827,7 +827,7 @@ void command_hotfix(Client *c, const Seperator *sep)
if (system(hotfix_command.c_str())) {}
#else
shared_memory_path = "./shared_memory";
if (file_exists("./bin/shared_memory")) {
if (File::Exists("./bin/shared_memory")) {
shared_memory_path = "./bin/shared_memory";
}
+5 -3
View File
@@ -18,6 +18,8 @@ Eglin
#include "embperl.h"
#include "embxs.h"
#include "../common/features.h"
#include "../common/path_manager.h"
#ifndef GvCV_set
#define GvCV_set(gv,cv) (GvCV(gv) = (cv))
#endif
@@ -79,7 +81,7 @@ void Embperl::DoInit() {
perl_run(my_perl);
//a little routine we use a lot.
eval_pv("sub my_eval { eval $_[0];}", TRUE); //dies on error
eval_pv("sub my_eval { eval $_[0];}", TRUE); //dies on error
//ruin the perl exit and command:
eval_pv("sub my_exit {}",TRUE);
@@ -146,11 +148,11 @@ void Embperl::DoInit() {
//should probably read the directory in c, instead, so that
//I can echo filenames as I do it, but c'mon... I'm lazy and this 1 line reads in all the plugins
std::string perl_command =
"if(opendir(D,'" + Config->PluginDir +"')) { "
"if(opendir(D,'" + path.GetPluginsPath() +"')) { "
" my @d = readdir(D);"
" closedir(D);"
" foreach(@d){ "
" main::eval_file('plugin','" + Config->PluginDir + "/'.$_)if/\\.pl$/;"
" main::eval_file('plugin','" + path.GetPluginsPath() + "/'.$_)if/\\.pl$/;"
" }"
"}";
eval_pv(perl_command.c_str(),FALSE);
+27 -30
View File
@@ -39,6 +39,7 @@
#include "lua_general.h"
#include "lua_encounter.h"
#include "lua_stat_bonuses.h"
#include "../common/path_manager.h"
#ifdef BOTS
#include "lua_bot.h"
@@ -927,11 +928,11 @@ void LuaParser::ReloadQuests() {
lua_getglobal(L, "package");
lua_getfield(L, -1, "path");
std::string module_path = lua_tostring(L,-1);
module_path += ";./" + Config->LuaModuleDir + "?.lua;./" + Config->LuaModuleDir + "?/init.lua";
module_path += ";" + path.GetLuaModulesPath() + "/?.lua;" + path.GetLuaModulesPath() + "/?/init.lua";
// luarock paths using lua_modules as tree
// to path it adds foo/share/lua/5.1/?.lua and foo/share/lua/5.1/?/init.lua
module_path += ";./" + Config->LuaModuleDir + "share/lua/" + lua_version + "/?.lua";
module_path += ";./" + Config->LuaModuleDir + "share/lua/" + lua_version + "/?/init.lua";
module_path += ";" + path.GetLuaModulesPath() + "/share/lua/" + lua_version + "/?.lua";
module_path += ";" + path.GetLuaModulesPath() + "/share/lua/" + lua_version + "/?/init.lua";
lua_pop(L, 1);
lua_pushstring(L, module_path.c_str());
lua_setfield(L, -2, "path");
@@ -940,10 +941,10 @@ void LuaParser::ReloadQuests() {
lua_getglobal(L, "package");
lua_getfield(L, -1, "cpath");
module_path = lua_tostring(L, -1);
module_path += ";./" + Config->LuaModuleDir + "?" + libext;
module_path += ";" + path.GetLuaModulesPath() + "/?" + libext;
// luarock paths using lua_modules as tree
// luarocks adds foo/lib/lua/5.1/?.so for cpath
module_path += ";./" + Config->LuaModuleDir + "lib/lua/" + lua_version + "/?" + libext;
module_path += ";" + path.GetLuaModulesPath() + "/lib/lua/" + lua_version + "/?" + libext;
lua_pop(L, 1);
lua_pushstring(L, module_path.c_str());
lua_setfield(L, -2, "cpath");
@@ -951,17 +952,14 @@ void LuaParser::ReloadQuests() {
MapFunctions(L);
//load init
std::string path = Config->QuestDir;
path += "/";
path += QUEST_GLOBAL_DIRECTORY;
path += "/script_init.lua";
// load init
std::string filename = fmt::format("{}/{}/script_init.lua", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY);
FILE *f = fopen(path.c_str(), "r");
FILE *f = fopen(filename.c_str(), "r");
if(f) {
fclose(f);
if(luaL_dofile(L, path.c_str())) {
if(luaL_dofile(L, filename.c_str())) {
std::string error = lua_tostring(L, -1);
AddError(error);
}
@@ -969,12 +967,13 @@ void LuaParser::ReloadQuests() {
//zone init - always loads after global
if(zone) {
std::string zone_script = Config->QuestDir;
zone_script += "/";
zone_script += zone->GetShortName();
zone_script += "/script_init_v";
zone_script += std::to_string(zone->GetInstanceVersion());
zone_script += ".lua";
std::string zone_script = fmt::format(
"{}/{}/script_init_v{}.lua",
path.GetQuestsPath(),
zone->GetShortName(),
zone->GetInstanceVersion()
);
f = fopen(zone_script.c_str(), "r");
if(f) {
fclose(f);
@@ -985,10 +984,8 @@ void LuaParser::ReloadQuests() {
}
}
else {
zone_script = Config->QuestDir;
zone_script += "/";
zone_script += zone->GetShortName();
zone_script += "/script_init.lua";
zone_script = fmt::format("{}/{}/script_init.lua", path.GetQuestsPath(), zone->GetShortName());
f = fopen(zone_script.c_str(), "r");
if (f) {
fclose(f);
@@ -1001,20 +998,20 @@ void LuaParser::ReloadQuests() {
}
}
FILE *load_order = fopen("mods/load_order.txt", "r");
FILE *load_order = fopen(fmt::format("{}/load_order.txt", path.GetLuaModsPath()).c_str(), "r");
if (load_order) {
char file_name[256] = { 0 };
while (fgets(file_name, 256, load_order) != nullptr) {
for (int i = 0; i < 256; ++i) {
auto c = file_name[i];
for (char & i : file_name) {
auto c = i;
if (c == '\n' || c == '\r' || c == ' ') {
file_name[i] = 0;
i = 0;
break;
}
}
LoadScript("mods/" + std::string(file_name), file_name);
mods_.push_back(LuaMod(L, this, file_name));
LoadScript(fmt::format("{}{}", path.GetLuaModsPath(), std::string(file_name)), file_name);
mods_.emplace_back(L, this, file_name);
}
fclose(load_order);
@@ -1107,8 +1104,8 @@ bool LuaParser::HasEncounterSub(const std::string& package_name, QuestEventID ev
{
auto it = lua_encounter_events_registered.find(package_name);
if (it != lua_encounter_events_registered.end()) {
for (auto riter = it->second.begin(); riter != it->second.end(); ++riter) {
if (riter->event_id == evt) {
for (auto & riter : it->second) {
if (riter.event_id == evt) {
return true;
}
}
+24 -15
View File
@@ -78,7 +78,6 @@
#else
#include <pthread.h>
#include "../common/unix.h"
#include "zone_event_scheduler.h"
#endif
@@ -89,21 +88,28 @@ volatile bool RunLoops = true;
extern volatile bool is_zone_loaded;
EntityList entity_list;
#include "zone_event_scheduler.h"
#include "../common/file.h"
#include "../common/path_manager.h"
EntityList entity_list;
WorldServer worldserver;
ZoneStore zone_store;
uint32 numclients = 0;
char errorname[32];
extern Zone* zone;
npcDecayTimes_Struct npcCorpseDecayTimes[100];
TitleManager title_manager;
QueryServ *QServ = 0;
TaskManager *task_manager = 0;
NpcScaleManager *npc_scale_manager;
QuestParserCollection *parse = 0;
EQEmuLogSys LogSys;
ZoneEventScheduler event_scheduler;
WorldContentService content_service;
ZoneStore zone_store;
uint32 numclients = 0;
char errorname[32];
extern Zone *zone;
npcDecayTimes_Struct npcCorpseDecayTimes[100];
TitleManager title_manager;
QueryServ *QServ = 0;
TaskManager *task_manager = 0;
NpcScaleManager *npc_scale_manager;
QuestParserCollection *parse = 0;
EQEmuLogSys LogSys;
ZoneEventScheduler event_scheduler;
WorldContentService content_service;
PathManager path;
const SPDat_Spell_Struct* spells;
int32 SPDAT_RECORDS = -1;
const ZoneConfig *Config;
@@ -121,6 +127,8 @@ int main(int argc, char** argv) {
set_exception_handler();
path.LoadPaths();
#ifdef USE_MAP_MMFS
if (argc == 3 && strcasecmp(argv[1], "convert_map") == 0) {
if (!ZoneConfig::LoadConfig())
@@ -255,6 +263,7 @@ int main(int argc, char** argv) {
/* Register Log System and Settings */
LogSys.SetDatabase(&database)
->SetLogPath(path.GetLogPath())
->LoadLogDatabaseSettings()
->SetGMSayHandler(&Zone::GMSayHookCallBackProcess)
->StartFileLogs();
+31 -48
View File
@@ -5,6 +5,8 @@
#include "map.h"
#include "raycast_mesh.h"
#include "zone.h"
#include "../common/file.h"
#include "../common/path_manager.h"
#include <algorithm>
#include <map>
@@ -46,16 +48,16 @@ float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result) const {
if(hit) {
return result->z;
}
// Find nearest Z above us
to.z = -BEST_Z_INVALID;
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
if (hit)
{
return result->z;
}
return BEST_Z_INVALID;
}
@@ -64,25 +66,25 @@ float Map::FindClosestZ(glm::vec3 &start, glm::vec3 *result) const {
//
if (!imp)
return false;
float ClosestZ = BEST_Z_INVALID;
glm::vec3 tmp;
if (!result)
result = &tmp;
glm::vec3 from(start.x, start.y, start.z);
glm::vec3 to(start.x, start.y, BEST_Z_INVALID);
float hit_distance;
bool hit = false;
// first check is below us
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
if (hit) {
ClosestZ = result->z;
}
// Find nearest Z above us
to.z = -BEST_Z_INVALID;
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
@@ -103,7 +105,7 @@ bool Map::LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::ve
bool Map::LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const {
if (!imp)
return false;
float z = BEST_Z_INVALID;
glm::vec3 step;
glm::vec3 cur;
@@ -200,28 +202,9 @@ bool Map::DoCollisionCheck(glm::vec3 myloc, glm::vec3 oloc, glm::vec3 &outnorm,
return imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, (RmReal *)&outnorm, (RmReal *)&distance);
}
inline bool file_exists(const std::string& name) {
std::ifstream f(name.c_str());
return f.good();
}
Map *Map::LoadMapFile(std::string file) {
std::string filename = "";
if (file_exists("maps")) {
filename = "maps";
}
else if (file_exists("Maps")) {
filename = "Maps";
}
else {
filename = Config->MapDir;
}
std::transform(file.begin(), file.end(), file.begin(), ::tolower);
filename += "/base/";
filename += file;
filename += ".map";
std::string filename = fmt::format("{}/base/{}.map", path.GetMapsPath(), file);
LogInfo("Attempting to load Map File [{}]", filename.c_str());
@@ -308,19 +291,19 @@ bool Map::LoadV1(FILE *f) {
uint32 face_count;
uint16 node_count;
uint32 facelist_count;
if(fread(&face_count, sizeof(face_count), 1, f) != 1) {
return false;
}
if(fread(&node_count, sizeof(node_count), 1, f) != 1) {
return false;
}
if(fread(&facelist_count, sizeof(facelist_count), 1, f) != 1) {
return false;
}
std::vector<glm::vec3> verts;
std::vector<uint32> indices;
for(uint32 i = 0; i < face_count; ++i) {
@@ -354,22 +337,22 @@ bool Map::LoadV1(FILE *f) {
verts.push_back(c);
indices.push_back((uint32)sz + 2);
}
if(imp) {
imp->rm->release();
imp->rm = nullptr;
} else {
imp = new impl;
}
imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0]);
if(!imp->rm) {
delete imp;
imp = nullptr;
return false;
}
return true;
}
@@ -978,7 +961,7 @@ bool Map::LoadMMF(const std::string& map_file_name, bool force_mmf_overwrite)
LogInfo("Failed to load Map MMF file: [{}] - f@file_version", mmf_file_name.c_str());
return false;
}
uint32 rm_buffer_size;
if (fread(&rm_buffer_size, sizeof(uint32), 1, f) != 1) {
fclose(f);
@@ -1011,7 +994,7 @@ bool Map::LoadMMF(const std::string& map_file_name, bool force_mmf_overwrite)
LogInfo("Failed to load Map MMF file: [{}] - f@mmf_buffer", mmf_file_name.c_str());
return false;
}
fclose(f);
std::vector<char> rm_buffer(rm_buffer_size);
@@ -1055,14 +1038,14 @@ bool Map::SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite)
LogInfo("Failed to save Map MMF file: [{}]", mmf_file_name.c_str());
return false;
}
FILE* f = fopen(mmf_file_name.c_str(), "rb");
if (f) {
fclose(f);
if (!force_mmf_overwrite)
return true;
}
std::vector<char> rm_buffer; // size set in MyRaycastMesh::serialize()
serializeRaycastMesh(imp->rm, rm_buffer);
if (rm_buffer.empty()) {
@@ -1074,19 +1057,19 @@ bool Map::SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite)
uint32 mmf_buffer_size = EstimateDeflateBuffer(rm_buffer.size());
std::vector<char> mmf_buffer(mmf_buffer_size);
mmf_buffer_size = DeflateData(rm_buffer.data(), rm_buffer.size(), mmf_buffer.data(), mmf_buffer.size());
if (!mmf_buffer_size) {
LogInfo("Failed to save Map MMF file: [{}] - null MMF buffer size", mmf_file_name.c_str());
return false;
}
f = fopen(mmf_file_name.c_str(), "wb");
if (!f) {
LogInfo("Failed to save Map MMF file: [{}] - could not open file", mmf_file_name.c_str());
return false;
}
uint32 file_version = 0;
if (fwrite(&file_version, sizeof(uint32), 1, f) != 1) {
fclose(f);
@@ -1094,7 +1077,7 @@ bool Map::SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite)
LogInfo("Failed to save Map MMF file: [{}] - f@file_version", mmf_file_name.c_str());
return false;
}
if (fwrite(&rm_buffer_size, sizeof(uint32), 1, f) != 1) {
fclose(f);
std::remove(mmf_file_name.c_str());
@@ -1116,7 +1099,7 @@ bool Map::SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite)
LogInfo("Failed to save Map MMF file: [{}] - f@mmf_buffer_size", mmf_file_name.c_str());
return false;
}
if (fwrite(mmf_buffer.data(), mmf_buffer_size, 1, f) != 1) {
fclose(f);
std::remove(mmf_file_name.c_str());
@@ -1125,7 +1108,7 @@ bool Map::SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite)
}
fclose(f);
return true;
}
+3 -2
View File
@@ -3,15 +3,16 @@
#include "pathfinder_null.h"
#include "pathfinder_nav_mesh.h"
#include "pathfinder_waypoint.h"
#include "../common/path_manager.h"
#include <fmt/format.h>
#include <sys/stat.h>
IPathfinder *IPathfinder::Load(const std::string &zone) {
struct stat statbuffer;
std::string navmesh_path = fmt::format("maps/nav/{0}.nav", zone);
std::string navmesh_path = fmt::format("{}/maps/nav/{}.nav", path.GetServerPath(), zone);
if (stat(navmesh_path.c_str(), &statbuffer) == 0) {
return new PathfinderNavmesh(navmesh_path);
}
return new PathfinderNull();
}
+48 -48
View File
@@ -34,19 +34,19 @@ PathfinderNavmesh::~PathfinderNavmesh()
IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck, int flags)
{
partial = false;
if (!m_impl->nav_mesh) {
return IPath();
}
if (!m_impl->query) {
m_impl->query = dtAllocNavMeshQuery();
}
m_impl->query->init(m_impl->nav_mesh, RuleI(Pathing, MaxNavmeshNodes));
glm::vec3 current_location(start.x, start.z, start.y);
glm::vec3 dest_location(end.x, end.z, end.y);
dtQueryFilter filter;
filter.setIncludeFlags(flags);
filter.setAreaCost(0, 1.0f); //Normal
@@ -59,48 +59,48 @@ IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const gl
filter.setAreaCost(8, 1.0f); //General Area
filter.setAreaCost(9, 0.1f); //Portal
filter.setAreaCost(10, 0.1f); //Prefer
dtPolyRef start_ref;
dtPolyRef end_ref;
glm::vec3 ext(5.0f, 100.0f, 5.0f);
m_impl->query->findNearestPoly(&current_location[0], &ext[0], &filter, &start_ref, 0);
m_impl->query->findNearestPoly(&dest_location[0], &ext[0], &filter, &end_ref, 0);
if (!start_ref || !end_ref) {
return IPath();
}
int npoly = 0;
dtPolyRef path[1024] = { 0 };
auto status = m_impl->query->findPath(start_ref, end_ref, &current_location[0], &dest_location[0], &filter, path, &npoly, 1024);
if (npoly) {
glm::vec3 epos = dest_location;
if (path[npoly - 1] != end_ref) {
m_impl->query->closestPointOnPoly(path[npoly - 1], &dest_location[0], &epos[0], 0);
partial = true;
auto dist = DistanceSquared(epos, current_location);
if (dist < 10000.0f) {
stuck = true;
}
}
float straight_path[2048 * 3];
unsigned char straight_path_flags[2048];
int n_straight_polys;
dtPolyRef straight_path_polys[2048];
status = m_impl->query->findStraightPath(&current_location[0], &epos[0], path, npoly,
straight_path, straight_path_flags,
straight_path_polys, &n_straight_polys, 2048, DT_STRAIGHTPATH_AREA_CROSSINGS);
if (dtStatusFailed(status)) {
return IPath();
}
if (n_straight_polys) {
IPath Route;
for (int i = 0; i < n_straight_polys; ++i)
@@ -109,9 +109,9 @@ IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const gl
node.x = straight_path[i * 3];
node.z = straight_path[i * 3 + 1];
node.y = straight_path[i * 3 + 2];
Route.push_back(node);
unsigned short flag = 0;
if (dtStatusSucceed(m_impl->nav_mesh->getPolyFlags(straight_path_polys[i], &flag))) {
if (flag & 512) {
@@ -119,11 +119,11 @@ IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const gl
}
}
}
return Route;
}
}
IPath Route;
Route.push_back(end);
return Route;
@@ -132,19 +132,19 @@ IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const gl
IPathfinder::IPath PathfinderNavmesh::FindPath(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck, const PathfinderOptions &opts)
{
partial = false;
if (!m_impl->nav_mesh) {
return IPath();
}
if (!m_impl->query) {
m_impl->query = dtAllocNavMeshQuery();
}
m_impl->query->init(m_impl->nav_mesh, RuleI(Pathing, MaxNavmeshNodes));
glm::vec3 current_location(start.x, start.z, start.y);
glm::vec3 dest_location(end.x, end.z, end.y);
dtQueryFilter filter;
filter.setIncludeFlags(opts.flags);
filter.setAreaCost(0, opts.flag_cost[0]); //Normal
@@ -157,83 +157,83 @@ IPathfinder::IPath PathfinderNavmesh::FindPath(const glm::vec3 &start, const glm
filter.setAreaCost(8, opts.flag_cost[7]); //General Area
filter.setAreaCost(9, opts.flag_cost[8]); //Portal
filter.setAreaCost(10, opts.flag_cost[9]); //Prefer
static const int max_polys = 256;
dtPolyRef start_ref;
dtPolyRef end_ref;
glm::vec3 ext(10.0f, 200.0f, 10.0f);
m_impl->query->findNearestPoly(&current_location[0], &ext[0], &filter, &start_ref, 0);
m_impl->query->findNearestPoly(&dest_location[0], &ext[0], &filter, &end_ref, 0);
if (!start_ref || !end_ref) {
return IPath();
}
int npoly = 0;
dtPolyRef path[max_polys] = { 0 };
auto status = m_impl->query->findPath(start_ref, end_ref, &current_location[0], &dest_location[0], &filter, path, &npoly, max_polys);
if (npoly) {
glm::vec3 epos = dest_location;
if (path[npoly - 1] != end_ref) {
m_impl->query->closestPointOnPoly(path[npoly - 1], &dest_location[0], &epos[0], 0);
partial = true;
auto dist = DistanceSquared(epos, current_location);
if (dist < 10000.0f) {
stuck = true;
}
}
int n_straight_polys;
glm::vec3 straight_path[max_polys];
unsigned char straight_path_flags[max_polys];
dtPolyRef straight_path_polys[max_polys];
auto status = m_impl->query->findStraightPath(&current_location[0], &epos[0], path, npoly,
(float*)&straight_path[0], straight_path_flags,
straight_path_polys, &n_straight_polys, 2048, DT_STRAIGHTPATH_AREA_CROSSINGS | DT_STRAIGHTPATH_ALL_CROSSINGS);
if (dtStatusFailed(status)) {
return IPath();
}
if (n_straight_polys) {
if (opts.smooth_path) {
IPath Route;
//Add the first point
{
auto &flag = straight_path_flags[0];
if (flag & DT_STRAIGHTPATH_OFFMESH_CONNECTION) {
auto &p = straight_path[0];
Route.push_back(glm::vec3(p.x, p.z, p.y));
}
else {
auto &p = straight_path[0];
float h = 0.0f;
if (dtStatusSucceed(GetPolyHeightOnPath(path, npoly, p, &h))) {
p.y = h + opts.offset;
}
Route.push_back(glm::vec3(p.x, p.z, p.y));
}
}
for (int i = 0; i < n_straight_polys - 1; ++i)
{
auto &flag = straight_path_flags[i];
if (flag & DT_STRAIGHTPATH_OFFMESH_CONNECTION) {
auto &poly = straight_path_polys[i];
auto &p2 = straight_path[i + 1];
glm::vec3 node(p2.x, p2.z, p2.y);
Route.push_back(node);
unsigned short pflag = 0;
if (dtStatusSucceed(m_impl->nav_mesh->getPolyFlags(straight_path_polys[i], &pflag))) {
if (pflag & 512) {
@@ -248,12 +248,12 @@ IPathfinder::IPath PathfinderNavmesh::FindPath(const glm::vec3 &start, const glm
auto dir = glm::normalize(p2 - p1);
float total = 0.0f;
glm::vec3 previous_pt = p1;
while (total < dist) {
glm::vec3 current_pt;
float dist_to_move = opts.step_size;
float ff = opts.step_size / 2.0f;
if (total + dist_to_move + ff >= dist) {
current_pt = p2;
total = dist;
@@ -262,18 +262,18 @@ IPathfinder::IPath PathfinderNavmesh::FindPath(const glm::vec3 &start, const glm
total += dist_to_move;
current_pt = p1 + dir * total;
}
float h = 0.0f;
if (dtStatusSucceed(GetPolyHeightOnPath(path, npoly, current_pt, &h))) {
current_pt.y = h + opts.offset;
}
Route.push_back(glm::vec3(current_pt.x, current_pt.z, current_pt.y));
previous_pt = current_pt;
}
}
}
return Route;
}
else {
@@ -283,7 +283,7 @@ IPathfinder::IPath PathfinderNavmesh::FindPath(const glm::vec3 &start, const glm
auto &current = straight_path[i];
glm::vec3 node(current.x, current.z, current.y);
Route.push_back(node);
unsigned short flag = 0;
if (dtStatusSucceed(m_impl->nav_mesh->getPolyFlags(straight_path_polys[i], &flag))) {
if (flag & 512) {
@@ -291,7 +291,7 @@ IPathfinder::IPath PathfinderNavmesh::FindPath(const glm::vec3 &start, const glm
}
}
}
return Route;
}
}
+57 -119
View File
@@ -25,7 +25,7 @@
#include "quest_interface.h"
#include "zone.h"
#include "questmgr.h"
#include "zone_config.h"
#include "../common/path_manager.h"
#include <stdio.h>
@@ -166,7 +166,7 @@ bool QuestParserCollection::PlayerHasEncounterSub(QuestEventID evt) {
bool QuestParserCollection::PlayerHasQuestSubLocal(QuestEventID evt) {
if(_player_quest_status == QuestUnloaded) {
std::string filename;
std::string filename;
QuestInterface *qi = GetQIByPlayerQuest(filename);
if(qi) {
_player_quest_status = qi->GetIdentifier();
@@ -182,7 +182,7 @@ bool QuestParserCollection::PlayerHasQuestSubLocal(QuestEventID evt) {
bool QuestParserCollection::PlayerHasQuestSubGlobal(QuestEventID evt) {
if(_global_player_quest_status == QuestUnloaded) {
std::string filename;
std::string filename;
QuestInterface *qi = GetQIByGlobalPlayerQuest(filename);
if(qi) {
_global_player_quest_status = qi->GetIdentifier();
@@ -292,7 +292,7 @@ int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std::
int rd = DispatchEventNPC(evt, npc, init, data, extra_data, extra_pointers);
int rl = EventNPCLocal(evt, npc, init, data, extra_data, extra_pointers);
int rg = EventNPCGlobal(evt, npc, init, data, extra_data, extra_pointers);
//Local quests returning non-default values have priority over global quests
if(rl != 0) {
return rl;
@@ -301,7 +301,7 @@ int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std::
} else if(rd != 0) {
return rd;
}
return 0;
}
@@ -333,7 +333,7 @@ int QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init,
if(_global_npc_quest_status != QuestUnloaded && _global_npc_quest_status != QuestFailedToLoad) {
auto qiter = _interfaces.find(_global_npc_quest_status);
return qiter->second->EventGlobalNPC(evt, npc, init, data, extra_data, extra_pointers);
}
}
else if(_global_npc_quest_status != QuestFailedToLoad){
std::string filename;
QuestInterface *qi = GetQIByGlobalNPCQuest(filename);
@@ -353,7 +353,7 @@ int QuestParserCollection::EventPlayer(QuestEventID evt, Client *client, std::st
int rd = DispatchEventPlayer(evt, client, data, extra_data, extra_pointers);
int rl = EventPlayerLocal(evt, client, data, extra_data, extra_pointers);
int rg = EventPlayerGlobal(evt, client, data, extra_data, extra_pointers);
//Local quests returning non-default values have priority over global quests
if(rl != 0) {
return rl;
@@ -362,7 +362,7 @@ int QuestParserCollection::EventPlayer(QuestEventID evt, Client *client, std::st
} else if(rd != 0) {
return rd;
}
return 0;
}
@@ -376,7 +376,7 @@ int QuestParserCollection::EventPlayerLocal(QuestEventID evt, Client *client, st
qi->LoadPlayerScript(filename);
return qi->EventPlayer(evt, client, data, extra_data, extra_pointers);
}
} else {
} else {
if(_player_quest_status != QuestFailedToLoad) {
auto iter = _interfaces.find(_player_quest_status);
return iter->second->EventPlayer(evt, client, data, extra_data, extra_pointers);
@@ -395,7 +395,7 @@ int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, s
qi->LoadGlobalPlayerScript(filename);
return qi->EventGlobalPlayer(evt, client, data, extra_data, extra_pointers);
}
} else {
} else {
if(_global_player_quest_status != QuestFailedToLoad) {
auto iter = _interfaces.find(_global_player_quest_status);
return iter->second->EventGlobalPlayer(evt, client, data, extra_data, extra_pointers);
@@ -407,7 +407,7 @@ int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, s
int QuestParserCollection::EventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
std::vector<std::any> *extra_pointers) {
// needs pointer validation check on 'item' argument
std::string item_script;
if(item->GetItem()->ScriptFileID != 0) {
item_script = "script_";
@@ -467,7 +467,7 @@ int QuestParserCollection::EventSpell(QuestEventID evt, NPC* npc, Client *client
return ret;
}
return DispatchEventSpell(evt, npc, client, spell_id, data, extra_data, extra_pointers);
}
}
else if (_spell_quest_status[spell_id] != QuestFailedToLoad) {
std::string filename;
QuestInterface *qi = GetQIBySpellQuest(spell_id, filename);
@@ -513,11 +513,9 @@ int QuestParserCollection::EventEncounter(QuestEventID evt, std::string encounte
}
QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string &filename) {
//first look for /quests/zone/npcid.ext (precedence)
filename = Config->QuestDir;
filename += zone->GetShortName();
filename += "/";
filename += itoa(npcid);
// first look for /quests/zone/npcid.ext (precedence)
filename = fmt::format("{}/{}/{}", path.GetQuestsPath(), zone->GetShortName(), npcid);
std::string tmp;
FILE *f = nullptr;
@@ -549,7 +547,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
}
else{
npc_name = npc_type->name;
}
}
int sz = static_cast<int>(npc_name.length());
for(int i = 0; i < sz; ++i) {
if(npc_name[i] == '`') {
@@ -557,10 +555,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
}
}
filename = Config->QuestDir;
filename += zone->GetShortName();
filename += "/";
filename += npc_name;
filename = fmt::format("{}/{}/{}", path.GetQuestsPath(), zone->GetShortName(), npc_name);
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
@@ -578,11 +573,8 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
++iter;
}
//third look for /quests/global/npcid.ext (precedence)
filename = Config->QuestDir;
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/";
filename += itoa(npcid);
// third look for /quests/global/npcid.ext (precedence)
filename = fmt::format("{}/{}/{}", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY, npcid);
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
tmp = filename;
@@ -599,11 +591,8 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
++iter;
}
//fourth look for /quests/global/npcname.ext (precedence)
filename = Config->QuestDir;
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/";
filename += npc_name;
// fourth look for /quests/global/npcname.ext (precedence)
filename = fmt::format("{}/{}/{}", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY, npc_name);
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
tmp = filename;
@@ -620,11 +609,8 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
++iter;
}
//fifth look for /quests/zone/default.ext (precedence)
filename = Config->QuestDir;
filename += zone->GetShortName();
filename += "/";
filename += "default";
// fifth look for /quests/zone/default.ext (precedence)
filename = fmt::format("{}/{}/default", path.GetQuestsPath(), zone->GetShortName());
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
tmp = filename;
@@ -641,11 +627,8 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
++iter;
}
//last look for /quests/global/default.ext (precedence)
filename = Config->QuestDir;
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/";
filename += "default";
// last look for /quests/global/default.ext (precedence)
filename = fmt::format("{}/{}/default", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY);
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
tmp = filename;
@@ -669,12 +652,8 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename)
if(!zone || !zone->IsLoaded())
return nullptr;
//first look for /quests/zone/player_v[instance_version].ext (precedence)
filename = Config->QuestDir;
filename += zone->GetShortName();
filename += "/";
filename += "player_v";
filename += itoa(zone->GetInstanceVersion());
// first look for /quests/zone/player_v[instance_version].ext (precedence)
filename = fmt::format("{}/{}/player_v{}", path.GetQuestsPath(), zone->GetShortName(), zone->GetInstanceVersion());
std::string tmp;
FILE *f = nullptr;
@@ -694,11 +673,8 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename)
++iter;
}
//second look for /quests/zone/player.ext (precedence)
filename = Config->QuestDir;
filename += zone->GetShortName();
filename += "/";
filename += "player";
// second look for /quests/zone/player.ext (precedence)
filename = fmt::format("{}/{}/player", path.GetQuestsPath(), zone->GetShortName());
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
@@ -716,11 +692,8 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename)
++iter;
}
//third look for /quests/global/player.ext (precedence)
filename = Config->QuestDir;
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/";
filename += "player";
// third look for /quests/global/player.ext (precedence)
filename = fmt::format("{}/{}/player", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY);
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
tmp = filename;
@@ -742,15 +715,11 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename)
QuestInterface *QuestParserCollection::GetQIByGlobalNPCQuest(std::string &filename) {
// simply look for /quests/global/global_npc.ext
filename = Config->QuestDir;
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/";
filename += "global_npc";
filename = fmt::format("{}/{}/global_npc", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY);
std::string tmp;
FILE *f = nullptr;
auto iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
tmp = filename;
@@ -772,11 +741,8 @@ QuestInterface *QuestParserCollection::GetQIByGlobalNPCQuest(std::string &filena
}
QuestInterface *QuestParserCollection::GetQIByGlobalPlayerQuest(std::string &filename) {
//first look for /quests/global/player.ext (precedence)
filename = Config->QuestDir;
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/";
filename += "global_player";
// first look for /quests/global/player.ext (precedence)
filename = fmt::format("{}/{}/global_player", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY);
std::string tmp;
FILE *f = nullptr;
@@ -801,10 +767,7 @@ QuestInterface *QuestParserCollection::GetQIByGlobalPlayerQuest(std::string &fil
QuestInterface *QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::string &filename) {
//first look for /quests/zone/spells/spell_id.ext (precedence)
filename = Config->QuestDir;
filename += zone->GetShortName();
filename += "/spells/";
filename += itoa(spell_id);
filename = fmt::format("{}/{}/spells/{}", path.GetQuestsPath(), zone->GetShortName(), spell_id);
std::string tmp;
FILE *f = nullptr;
@@ -824,11 +787,8 @@ QuestInterface *QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::s
++iter;
}
//second look for /quests/global/spells/spell_id.ext (precedence)
filename = Config->QuestDir;
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/spells/";
filename += itoa(spell_id);
// second look for /quests/global/spells/spell_id.ext (precedence)
filename = fmt::format("{}/{}/spells/{}", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY, spell_id);
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
@@ -846,10 +806,8 @@ QuestInterface *QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::s
++iter;
}
//third look for /quests/zone/spells/default.ext (precedence)
filename = Config->QuestDir;
filename += zone->GetShortName();
filename += "/spells/default";
// third look for /quests/zone/spells/default.ext (precedence)
filename = fmt::format("{}/{}/spells/default", path.GetQuestsPath(), zone->GetShortName());
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
@@ -867,10 +825,8 @@ QuestInterface *QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::s
++iter;
}
//last look for /quests/global/spells/default.ext (precedence)
filename = Config->QuestDir;
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/spells/default";
// last look for /quests/global/spells/default.ext (precedence)
filename = fmt::format("{}/{}/spells/default", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY);
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
@@ -892,11 +848,8 @@ QuestInterface *QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::s
}
QuestInterface *QuestParserCollection::GetQIByItemQuest(std::string item_script, std::string &filename) {
//first look for /quests/zone/items/item_script.ext (precedence)
filename = Config->QuestDir;
filename += zone->GetShortName();
filename += "/items/";
filename += item_script;
// first look for /quests/zone/items/item_script.ext (precedence)
filename = fmt::format("{}/{}/items/{}", path.GetQuestsPath(), zone->GetShortName(), item_script);
std::string tmp;
FILE *f = nullptr;
@@ -915,12 +868,9 @@ QuestInterface *QuestParserCollection::GetQIByItemQuest(std::string item_script,
++iter;
}
//second look for /quests/global/items/item_script.ext (precedence)
filename = Config->QuestDir;
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/items/";
filename += item_script;
// second look for /quests/global/items/item_script.ext (precedence)
filename = fmt::format("{}/{}/items/{}", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY, item_script);
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
@@ -938,11 +888,8 @@ QuestInterface *QuestParserCollection::GetQIByItemQuest(std::string item_script,
++iter;
}
//third look for /quests/zone/items/default.ext (precedence)
filename = Config->QuestDir;
filename += zone->GetShortName();
filename += "/items/default";
// third look for /quests/zone/items/default.ext (precedence)
filename = fmt::format("{}/{}/items/default", path.GetQuestsPath(), zone->GetShortName());
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
tmp = filename;
@@ -959,11 +906,8 @@ QuestInterface *QuestParserCollection::GetQIByItemQuest(std::string item_script,
++iter;
}
//last look for /quests/global/items/default.ext (precedence)
filename = Config->QuestDir;
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/items/default";
// last look for /quests/global/items/default.ext (precedence)
filename = fmt::format("{}/{}/items/default", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY);
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
tmp = filename;
@@ -984,11 +928,8 @@ QuestInterface *QuestParserCollection::GetQIByItemQuest(std::string item_script,
}
QuestInterface *QuestParserCollection::GetQIByEncounterQuest(std::string encounter_name, std::string &filename) {
//first look for /quests/zone/encounters/encounter_name.ext (precedence)
filename = Config->QuestDir;
filename += zone->GetShortName();
filename += "/encounters/";
filename += encounter_name;
// first look for /quests/zone/encounters/encounter_name.ext (precedence)
filename = fmt::format("{}/{}/encounters/{}", path.GetQuestsPath(), zone->GetShortName(), encounter_name);
std::string tmp;
FILE *f = nullptr;
@@ -1007,12 +948,9 @@ QuestInterface *QuestParserCollection::GetQIByEncounterQuest(std::string encount
++iter;
}
//second look for /quests/global/encounters/encounter_name.ext (precedence)
filename = Config->QuestDir;
filename += QUEST_GLOBAL_DIRECTORY;
filename += "/encounters/";
filename += encounter_name;
// second look for /quests/global/encounters/encounter_name.ext (precedence)
filename = fmt::format("{}/{}/encounters/{}", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY, encounter_name);
iter = _load_precedence.begin();
while(iter != _load_precedence.end()) {
@@ -1099,7 +1037,7 @@ int QuestParserCollection::DispatchEventSpell(QuestEventID evt, NPC* npc, Client
}
void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings* perl_event_export_settings) {
LogInfo("Loading Perl Event Export Settings...");
/* Write Defaults First (All Enabled) */
+1 -1
View File
@@ -192,7 +192,7 @@ void QuestManager::summonitem(uint32 itemid, int16 charges) {
void QuestManager::write(const char *file, const char *str) {
FILE * pFile;
pFile = fopen (file, "a");
pFile = fopen (fmt::format("{}/{}", path.GetServerPath(), file).c_str(), "a");
if(!pFile)
return;
fprintf(pFile, "%s\n", str);
+7 -25
View File
@@ -4,21 +4,14 @@
#include "water_map_v1.h"
#include "water_map_v2.h"
#include "../common/eqemu_logsys.h"
#include "../common/file.h"
#include "../common/path_manager.h"
#include <algorithm>
#include <cctype>
#include <stdio.h>
#include <string.h>
/**
* @param name
* @return
*/
inline bool file_exists(const std::string& name) {
std::ifstream f(name.c_str());
return f.good();
}
/**
* @param zone_name
* @return
@@ -26,18 +19,7 @@ inline bool file_exists(const std::string& name) {
WaterMap* WaterMap::LoadWaterMapfile(std::string zone_name) {
std::transform(zone_name.begin(), zone_name.end(), zone_name.begin(), ::tolower);
std::string filename;
if (file_exists("maps")) {
filename = "maps";
}
else if (file_exists("Maps")) {
filename = "Maps";
}
else {
filename = Config->MapDir;
}
std::string file_path = filename + "/water/" + zone_name + std::string(".wtr");
std::string file_path = fmt::format("{}/water/{}.wtr", path.GetMapsPath(), zone_name);
LogDebug("Attempting to load water map with path [{}]", file_path.c_str());
FILE *f = fopen(file_path.c_str(), "rb");
if(f) {
@@ -48,19 +30,19 @@ WaterMap* WaterMap::LoadWaterMapfile(std::string zone_name) {
fclose(f);
return nullptr;
}
if(strncmp(magic, "EQEMUWATER", 10)) {
LogDebug("Failed to load water map, bad magic string in header");
fclose(f);
return nullptr;
}
if(fread(&version, sizeof(version), 1, f) != 1) {
LogDebug("Failed to load water map, error reading version");
fclose(f);
return nullptr;
}
LogDebug("Attempting to V[{}] load water map [{}]", version, file_path.c_str());
if(version == 1) {
auto wm = new WaterMapV1();
@@ -90,7 +72,7 @@ WaterMap* WaterMap::LoadWaterMapfile(std::string zone_name) {
return nullptr;
}
}
LogDebug("Failed to load water map, could not open file for reading [{}]", file_path.c_str());
return nullptr;
}
+2 -2
View File
@@ -43,13 +43,13 @@ class ZoneConfig : public EQEmuConfig {
}
// Load the config
static bool LoadConfig() {
static bool LoadConfig(const std::string& path = "") {
if (_zone_config != nullptr)
delete _zone_config;
_zone_config=new ZoneConfig;
_config=_zone_config;
return _config->parseFile();
return _config->parseFile(path);
}
// Accessors for the static private object