Partial port of der's map rewrite, no new azone format yet but it's coming. Will convert legacy map formats on the fly atm.

This commit is contained in:
KimLS 2014-02-23 21:17:28 -08:00
parent eabea6ea16
commit 951c321ba6
17 changed files with 517 additions and 842 deletions

View File

@ -66,7 +66,7 @@ SET(zone_sources
horse.cpp horse.cpp
inventory.cpp inventory.cpp
loottables.cpp loottables.cpp
Map.cpp map.cpp
merc.cpp merc.cpp
mob.cpp mob.cpp
MobAI.cpp MobAI.cpp

View File

@ -754,7 +754,7 @@ void Client::AI_Process()
{ {
bool WaypointChanged, NodeReached; bool WaypointChanged, NodeReached;
VERTEX Goal = UpdatePath(fear_walkto_x, fear_walkto_y, fear_walkto_z, Map::Vertex Goal = UpdatePath(fear_walkto_x, fear_walkto_y, fear_walkto_z,
GetFearSpeed(), WaypointChanged, NodeReached); GetFearSpeed(), WaypointChanged, NodeReached);
if(WaypointChanged) if(WaypointChanged)
@ -910,7 +910,7 @@ void Client::AI_Process()
else else
{ {
bool WaypointChanged, NodeReached; bool WaypointChanged, NodeReached;
VERTEX Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), Map::Vertex Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(),
GetRunspeed(), WaypointChanged, NodeReached); GetRunspeed(), WaypointChanged, NodeReached);
if(WaypointChanged) if(WaypointChanged)
@ -1022,7 +1022,7 @@ void Mob::AI_Process() {
{ {
bool WaypointChanged, NodeReached; bool WaypointChanged, NodeReached;
VERTEX Goal = UpdatePath(fear_walkto_x, fear_walkto_y, fear_walkto_z, Map::Vertex Goal = UpdatePath(fear_walkto_x, fear_walkto_y, fear_walkto_z,
GetFearSpeed(), WaypointChanged, NodeReached); GetFearSpeed(), WaypointChanged, NodeReached);
if(WaypointChanged) if(WaypointChanged)
@ -1360,7 +1360,7 @@ void Mob::AI_Process() {
{ {
bool WaypointChanged, NodeReached; bool WaypointChanged, NodeReached;
VERTEX Goal = UpdatePath(target->GetX(), target->GetY(), target->GetZ(), Map::Vertex Goal = UpdatePath(target->GetX(), target->GetY(), target->GetZ(),
GetRunspeed(), WaypointChanged, NodeReached); GetRunspeed(), WaypointChanged, NodeReached);
if(WaypointChanged) if(WaypointChanged)
@ -1683,7 +1683,7 @@ void NPC::AI_DoMovement() {
{ {
bool WaypointChanged; bool WaypointChanged;
bool NodeReached; bool NodeReached;
VERTEX Goal = UpdatePath(cur_wp_x, cur_wp_y, cur_wp_z, walksp, WaypointChanged, NodeReached); Map::Vertex Goal = UpdatePath(cur_wp_x, cur_wp_y, cur_wp_z, walksp, WaypointChanged, NodeReached);
if(WaypointChanged) if(WaypointChanged)
tar_ndx = 20; tar_ndx = 20;
@ -1722,7 +1722,7 @@ void NPC::AI_DoMovement() {
if(!((x_pos == guard_x) && (y_pos == guard_y) && (z_pos == guard_z))) if(!((x_pos == guard_x) && (y_pos == guard_y) && (z_pos == guard_z)))
{ {
bool WaypointChanged, NodeReached; bool WaypointChanged, NodeReached;
VERTEX Goal = UpdatePath(guard_x, guard_y, guard_z, walksp, WaypointChanged, NodeReached); Map::Vertex Goal = UpdatePath(guard_x, guard_y, guard_z, walksp, WaypointChanged, NodeReached);
if(WaypointChanged) if(WaypointChanged)
tar_ndx = 20; tar_ndx = 20;

View File

@ -872,133 +872,6 @@ bool Mob::CombatRange(Mob* other)
return false; return false;
} }
//Old LOS function, prolly not used anymore
//Not removed because I havent looked it over to see if anything
//useful is in here before we delete it.
bool Mob::CheckLos(Mob* other) {
if (zone->zonemap == 0)
{
return true;
}
float tmp_x = GetX();
float tmp_y = GetY();
float tmp_z = GetZ();
float trg_x = other->GetX();
float trg_y = other->GetY();
float trg_z = other->GetZ();
float perwalk_x = 0.5;
float perwalk_y = 0.5;
float perwalk_z = 0.5;
float dist_x = tmp_x - trg_x;
if (dist_x < 0)
dist_x *= -1;
float dist_y = tmp_y - trg_y;
if (dist_y < 0)
dist_y *= -1;
float dist_z = tmp_z - trg_z;
if (dist_z < 0)
dist_z *= -1;
if (dist_x < dist_y && dist_z < dist_y)
{
perwalk_x /= (dist_y/dist_x);
perwalk_z /= (dist_y/dist_z);
}
else if (dist_y < dist_x && dist_z < dist_x)
{
perwalk_y /= (dist_x/dist_y);
perwalk_z /= (dist_x/dist_z);
}
else if (dist_x < dist_z && dist_y < dist_z)
{
perwalk_x /= (dist_z/dist_x);
perwalk_y /= (dist_z/dist_y);
}
float steps = (dist_x/perwalk_x + dist_y/perwalk_y + dist_z/perwalk_z)*10; //Just a safety check to prevent endless loops.
while (steps > 0) {
steps--;
if (tmp_x < trg_x)
{
if (tmp_x + perwalk_x < trg_x)
tmp_x += perwalk_x;
else
tmp_x = trg_x;
}
if (tmp_y < trg_y)
{
if (tmp_y + perwalk_y < trg_y)
tmp_y += perwalk_y;
else
tmp_y = trg_y;
}
if (tmp_z < trg_z)
{
if (tmp_z + perwalk_z < trg_z)
tmp_z += perwalk_z;
else
tmp_z = trg_z;
}
if (tmp_x > trg_x)
{
if (tmp_x - perwalk_x > trg_x)
tmp_x -= perwalk_x;
else
tmp_x = trg_x;
}
if (tmp_y > trg_y)
{
if (tmp_y - perwalk_y > trg_y)
tmp_y -= perwalk_y;
else
tmp_y = trg_y;
}
if (tmp_z > trg_z)
{
if (tmp_z - perwalk_z > trg_z)
tmp_z -= perwalk_z;
else
tmp_z = trg_z;
}
if (tmp_y == trg_y && tmp_x == trg_x && tmp_z == trg_z)
{
return true;
}
//I believe this is contributing to breaking mob spawns when a map is loaded
// NodeRef pnode = zone->zonemap->SeekNode( zone->zonemap->GetRoot(), tmp_x, tmp_y );
NodeRef pnode = NODE_NONE;
if (pnode != NODE_NONE)
{
const int *iface = zone->zonemap->SeekFace( pnode, tmp_x, tmp_y );
if (*iface == -1) {
return false;
}
float temp_z = 0;
float best_z = 999999;
while(*iface != -1)
{
temp_z = zone->zonemap->GetFaceHeight( *iface, x_pos, y_pos );
//UMM.. OMG... sqrtf(pow(x, 2)) == x.... retards
float best_dist = sqrtf((float)(pow(best_z-tmp_z, 2)));
float tmp_dist = sqrtf((float)(pow(tmp_z-tmp_z, 2)));
if (tmp_dist < best_dist)
{
best_z = temp_z;
}
iface++;
}
/* solar: our aggro code isn't using this right now, just spells, so i'm
taking out the +-10 check for now to make it work right on hills
if (best_z - 10 > trg_z || best_z + 10 < trg_z)
{
return false;
}
*/
}
}
return true;
}
//Father Nitwit's LOS code //Father Nitwit's LOS code
bool Mob::CheckLosFN(Mob* other) { bool Mob::CheckLosFN(Mob* other) {
bool Result = false; bool Result = false;
@ -1020,8 +893,8 @@ bool Mob::CheckLosFN(float posX, float posY, float posZ, float mobSize) {
#endif #endif
} }
VERTEX myloc; Map::Vertex myloc;
VERTEX oloc; Map::Vertex oloc;
#define LOS_DEFAULT_HEIGHT 6.0f #define LOS_DEFAULT_HEIGHT 6.0f
@ -1036,72 +909,7 @@ bool Mob::CheckLosFN(float posX, float posY, float posZ, float mobSize) {
#if LOSDEBUG>=5 #if LOSDEBUG>=5
LogFile->write(EQEMuLog::Debug, "LOS from (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f) sizes: (%.2f, %.2f)", myloc.x, myloc.y, myloc.z, oloc.x, oloc.y, oloc.z, GetSize(), mobSize); LogFile->write(EQEMuLog::Debug, "LOS from (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f) sizes: (%.2f, %.2f)", myloc.x, myloc.y, myloc.z, oloc.x, oloc.y, oloc.z, GetSize(), mobSize);
#endif #endif
return zone->zonemap->CheckLoS(myloc, oloc);
FACE *onhit;
NodeRef mynode;
NodeRef onode;
VERTEX hit;
//see if anything in our node is in the way
mynode = zone->zonemap->SeekNode( zone->zonemap->GetRoot(), myloc.x, myloc.y);
if(mynode != NODE_NONE) {
if(zone->zonemap->LineIntersectsNode(mynode, myloc, oloc, &hit, &onhit)) {
#if LOSDEBUG>=5
LogFile->write(EQEMuLog::Debug, "Check LOS for %s target position, cannot see.", GetName());
LogFile->write(EQEMuLog::Debug, "\tPoly: (%.2f, %.2f, %.2f) (%.2f, %.2f, %.2f) (%.2f, %.2f, %.2f)\n",
onhit->a.x, onhit->a.y, onhit->a.z,
onhit->b.x, onhit->b.y, onhit->b.z,
onhit->c.x, onhit->c.y, onhit->c.z);
#endif
return(false);
}
}
#if LOSDEBUG>=5
else {
LogFile->write(EQEMuLog::Debug, "WTF, I have no node, what am I standing on??? (%.2f, %.2f).", myloc.x, myloc.y);
}
#endif
//see if they are in a different node.
//if so, see if anything in their node is blocking me.
if(! zone->zonemap->LocWithinNode(mynode, oloc.x, oloc.y)) {
onode = zone->zonemap->SeekNode( zone->zonemap->GetRoot(), oloc.x, oloc.y);
if(onode != NODE_NONE && onode != mynode) {
if(zone->zonemap->LineIntersectsNode(onode, myloc, oloc, &hit, &onhit)) {
#if LOSDEBUG>=5
LogFile->write(EQEMuLog::Debug, "Check LOS for %s target position, cannot see (2).", GetName());
LogFile->write(EQEMuLog::Debug, "\tPoly: (%.2f, %.2f, %.2f) (%.2f, %.2f, %.2f) (%.2f, %.2f, %.2f)\n",
onhit->a.x, onhit->a.y, onhit->a.z,
onhit->b.x, onhit->b.y, onhit->b.z,
onhit->c.x, onhit->c.y, onhit->c.z);
#endif
return(false);
}
}
#if LOSDEBUG>=5
else if(onode == NODE_NONE) {
LogFile->write(EQEMuLog::Debug, "WTF, They have no node, what are they standing on??? (%.2f, %.2f).", myloc.x, myloc.y);
}
#endif
}
/*
if(zone->zonemap->LineIntersectsZone(myloc, oloc, CHECK_LOS_STEP, &onhit)) {
#if LOSDEBUG>=5
LogFile->write(EQEMuLog::Debug, "Check LOS for %s target %s, cannot see.", GetName(), other->GetName() );
LogFile->write(EQEMuLog::Debug, "\tPoly: (%.2f, %.2f, %.2f) (%.2f, %.2f, %.2f) (%.2f, %.2f, %.2f)\n",
onhit->a.x, onhit->a.y, onhit->a.z,
onhit->b.x, onhit->b.y, onhit->b.z,
onhit->c.x, onhit->c.y, onhit->c.z);
#endif
return(false);
}*/
#if LOSDEBUG>=5
LogFile->write(EQEMuLog::Debug, "Check LOS for %s target position, CAN SEE.", GetName());
#endif
return(true);
} }
//offensive spell aggro //offensive spell aggro

View File

@ -1200,8 +1200,8 @@ protected:
Mob* bind_sight_target; Mob* bind_sight_target;
VERTEX aa_los_me; Map::Vertex aa_los_me;
VERTEX aa_los_them; Map::Vertex aa_los_them;
Mob *aa_los_them_mob; Mob *aa_los_them_mob;
bool los_status; bool los_status;
float aa_los_me_heading; float aa_los_me_heading;

View File

@ -8550,10 +8550,10 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
} }
else else
{ {
VERTEX Start(GetX(), GetY(), GetZ() + (GetSize() < 6.0 ? 6 : GetSize()) * HEAD_POSITION); Map::Vertex Start(GetX(), GetY(), GetZ() + (GetSize() < 6.0 ? 6 : GetSize()) * HEAD_POSITION);
VERTEX End(target->GetX(), target->GetY(), target->GetZ() + (target->GetSize() < 6.0 ? 6 : target->GetSize()) * HEAD_POSITION); Map::Vertex End(target->GetX(), target->GetY(), target->GetZ() + (target->GetSize() < 6.0 ? 6 : target->GetSize()) * HEAD_POSITION);
if(!zone->zonemap->LineIntersectsZone(Start, End, 1.0f, nullptr, nullptr) && zone->pathing->NoHazards(Start, End)) if(!zone->zonemap->LineIntersectsZone(Start, End, 1.0f, nullptr) && zone->pathing->NoHazards(Start, End))
{ {
points.resize(2); points.resize(2);
points[0].x = Start.x; points[0].x = Start.x;
@ -8594,7 +8594,7 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
bool LeadsToTeleporter = false; bool LeadsToTeleporter = false;
VERTEX v = zone->pathing->GetPathNodeCoordinates(pathlist.back()); Map::Vertex v = zone->pathing->GetPathNodeCoordinates(pathlist.back());
p.x = v.x; p.x = v.x;
p.y = v.y; p.y = v.y;
@ -8614,7 +8614,7 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
break; break;
} }
VERTEX v = zone->pathing->GetPathNodeCoordinates((*Iterator), false); Map::Vertex v = zone->pathing->GetPathNodeCoordinates((*Iterator), false);
p.x = v.x; p.x = v.x;
p.y = v.y; p.y = v.y;
p.z = v.z; p.z = v.z;
@ -8785,32 +8785,31 @@ bool Client::FinishConnState2(DBAsyncWork* dbaw) {
//if we zone in with invalid Z, fix it. //if we zone in with invalid Z, fix it.
if (zone->zonemap != nullptr) { if (zone->zonemap != nullptr) {
//for whatever reason, LineIntersectsNode is giving better results than FindBestZ Map::Vertex me;
NodeRef pnode;
VERTEX me;
me.x = GetX(); me.x = GetX();
me.y = GetY(); me.y = GetY();
me.z = GetZ() + (GetSize()==0.0?6:GetSize()); me.z = GetZ() + (GetSize() == 0.0 ? 6 : GetSize());
pnode = zone->zonemap->SeekNode( zone->zonemap->GetRoot(), me.x, me.y );
VERTEX hit; Map::Vertex hit;
VERTEX below_me(me);
below_me.z -= 500; if (zone->zonemap->FindBestZ(me, &hit) == BEST_Z_INVALID)
if(!zone->zonemap->LineIntersectsNode(pnode, me, below_me, &hit, nullptr) || hit.z < -5000) { {
#if EQDEBUG >= 5 #if EQDEBUG >= 5
LogFile->write(EQEMuLog::Debug, "Player %s started below the zone trying to fix! (%.3f, %.3f, %.3f)", GetName(), me.x, me.y, me.z); LogFile->write(EQEMuLog::Debug, "Player %s started below the zone trying to fix! (%.3f, %.3f, %.3f)", GetName(), me.x, me.y, me.z);
#endif #endif
//theres nothing below us... try to find something to stand on
me.z += 200; //arbitrary # me.z += 200; //arbitrary #
if(zone->zonemap->LineIntersectsNode(pnode, me, below_me, &hit, nullptr)) { if (zone->zonemap->FindBestZ(me, &hit) != BEST_Z_INVALID)
{
//+10 so they dont stick in the ground //+10 so they dont stick in the ground
SendTo(me.x, me.y, hit.z + 10); SendTo(me.x, me.y, hit.z + 10);
m_pp.z = hit.z + 10; m_pp.z = hit.z + 10;
} else { }
else
{
//one more, desperate try //one more, desperate try
me.z += 2000; me.z += 2000;
if(zone->zonemap->LineIntersectsNode(pnode, me, below_me, &hit, nullptr)) { if (zone->zonemap->FindBestZ(me, &hit) != BEST_Z_INVALID)
{
//+10 so they dont stick in the ground //+10 so they dont stick in the ground
SendTo(me.x, me.y, hit.z + 10); SendTo(me.x, me.y, hit.z + 10);
m_pp.z = hit.z + 10; m_pp.z = hit.z + 10;
@ -8819,14 +8818,6 @@ bool Client::FinishConnState2(DBAsyncWork* dbaw) {
} }
} }
//m_pp.hunger_level = 6000;
//m_pp.thirst_level = 6000;
//aa_title = m_pp.aa_title;
//m_pp.timeplayed=64;
//m_pp.birthday=1057434792;
//m_pp.lastlogin=1057464792;
if (m_pp.gm && admin < minStatusToBeGM) if (m_pp.gm && admin < minStatusToBeGM)
m_pp.gm = 0; m_pp.gm = 0;

View File

@ -7461,8 +7461,8 @@ void command_path(Client *c, const Seperator *sep)
if(zone->zonemap) if(zone->zonemap)
{ {
VERTEX loc(px, py, pz); Map::Vertex loc(px, py, pz);
best_z = zone->zonemap->FindBestZ(MAP_ROOT_NODE, loc, nullptr, nullptr); best_z = zone->zonemap->FindBestZ(loc, nullptr);
} }
else else
{ {
@ -7488,8 +7488,8 @@ void command_path(Client *c, const Seperator *sep)
if(zone->zonemap) if(zone->zonemap)
{ {
VERTEX loc(px, py, pz); Map::Vertex loc(px, py, pz);
best_z = zone->zonemap->FindBestZ(MAP_ROOT_NODE, loc, nullptr, nullptr); best_z = zone->zonemap->FindBestZ(loc, nullptr);
} }
else else
{ {
@ -7621,8 +7621,8 @@ void command_path(Client *c, const Seperator *sep)
{ {
if(c && c->GetTarget()) if(c && c->GetTarget())
{ {
if(zone->pathing->NoHazardsAccurate(VERTEX(c->GetX(),c->GetY(),c->GetZ()), if (zone->pathing->NoHazardsAccurate(Map::Vertex(c->GetX(), c->GetY(), c->GetZ()),
VERTEX(c->GetTarget()->GetX(),c->GetTarget()->GetY(),c->GetTarget()->GetZ()))) Map::Vertex(c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ())))
{ {
c->Message(0, "No hazards."); c->Message(0, "No hazards.");
} }
@ -7698,7 +7698,7 @@ void command_path(Client *c, const Seperator *sep)
{ {
Mob *m = c->GetTarget(); Mob *m = c->GetTarget();
VERTEX Position(m->GetX(), m->GetY(), m->GetZ()); Map::Vertex Position(m->GetX(), m->GetY(), m->GetZ());
int Node = zone->pathing->FindNearestPathNode(Position); int Node = zone->pathing->FindNearestPathNode(Position);
@ -7831,35 +7831,19 @@ void command_bestz(Client *c, const Seperator *sep) {
return; return;
} }
NodeRef pnode; Map::Vertex me;
if(c->GetTarget()) {
pnode = zone->zonemap->SeekNode( zone->zonemap->GetRoot(), c->GetTarget()->GetX(), c->GetTarget()->GetY() );
} else {
pnode = zone->zonemap->SeekNode( zone->zonemap->GetRoot(), c->GetX(), c->GetY() );
}
if (pnode == NODE_NONE) {
c->Message(0,"Unable to find your node.");
return;
}
VERTEX me;
me.x = c->GetX(); me.x = c->GetX();
me.y = c->GetY(); me.y = c->GetY();
me.z = c->GetZ() + (c->GetSize()==0.0?6:c->GetSize()) * HEAD_POSITION; me.z = c->GetZ() + (c->GetSize()==0.0?6:c->GetSize()) * HEAD_POSITION;
VERTEX hit; Map::Vertex hit;
VERTEX bme(me); Map::Vertex bme(me);
bme.z -= 500; bme.z -= 500;
float best_z = zone->zonemap->FindBestZ(pnode, me, &hit, nullptr); float best_z = zone->zonemap->FindBestZ(me, &hit);
float best_z2 = -999990;
if(zone->zonemap->LineIntersectsNode(pnode, me, bme, &hit, nullptr)) {
best_z2 = hit.z;
}
if (best_z != -999999) if (best_z != -999999)
{ {
c->Message(0,"Z is %.3f or %.3f at (%.3f, %.3f).", best_z, best_z2, me.x, me.y); c->Message(0,"Z is %.3f at (%.3f, %.3f).", best_z, me.x, me.y);
} }
else else
{ {

View File

@ -2554,8 +2554,8 @@ void EntityList::FindPathsToAllNPCs()
auto it = npc_list.begin(); auto it = npc_list.begin();
while (it != npc_list.end()) { while (it != npc_list.end()) {
VERTEX Node0 = zone->pathing->GetPathNodeCoordinates(0, false); Map::Vertex Node0 = zone->pathing->GetPathNodeCoordinates(0, false);
VERTEX Dest(it->second->GetX(), it->second->GetY(), it->second->GetZ()); Map::Vertex Dest(it->second->GetX(), it->second->GetY(), it->second->GetZ());
std::list<int> Route = zone->pathing->FindRoute(Node0, Dest); std::list<int> Route = zone->pathing->FindRoute(Node0, Dest);
if (Route.size() == 0) if (Route.size() == 0)
printf("Unable to find a route to %s\n", it->second->GetName()); printf("Unable to find a route to %s\n", it->second->GetName());
@ -3557,9 +3557,9 @@ bool Entity::CheckCoordLosNoZLeaps(float cur_x, float cur_y, float cur_z,
if (zone->zonemap == nullptr) if (zone->zonemap == nullptr)
return true; return true;
VERTEX myloc; Map::Vertex myloc;
VERTEX oloc; Map::Vertex oloc;
VERTEX hit; Map::Vertex hit;
myloc.x = cur_x; myloc.x = cur_x;
myloc.y = cur_y; myloc.y = cur_y;
@ -3572,9 +3572,7 @@ bool Entity::CheckCoordLosNoZLeaps(float cur_x, float cur_y, float cur_z,
if (myloc.x == oloc.x && myloc.y == oloc.y && myloc.z == oloc.z) if (myloc.x == oloc.x && myloc.y == oloc.y && myloc.z == oloc.z)
return true; return true;
FACE *onhit; if (!zone->zonemap->LineIntersectsZoneNoZLeaps(myloc,oloc,perwalk,&hit))
if (!zone->zonemap->LineIntersectsZoneNoZLeaps(myloc,oloc,perwalk,&hit,&onhit))
return true; return true;
return false; return false;
} }

View File

@ -152,11 +152,11 @@ void Mob::CalculateNewFearpoint()
{ {
int Node = zone->pathing->GetRandomPathNode(); int Node = zone->pathing->GetRandomPathNode();
VERTEX Loc = zone->pathing->GetPathNodeCoordinates(Node); Map::Vertex Loc = zone->pathing->GetPathNodeCoordinates(Node);
++Loc.z; ++Loc.z;
VERTEX CurrentPosition(GetX(), GetY(), GetZ()); Map::Vertex CurrentPosition(GetX(), GetY(), GetZ());
std::list<int> Route = zone->pathing->FindRoute(CurrentPosition, Loc); std::list<int> Route = zone->pathing->FindRoute(CurrentPosition, Loc);
@ -205,429 +205,6 @@ void Mob::CalculateNewFearpoint()
} }
} }
//we need to start acting scared...
//old fear function, kept for ref.
/*void Mob::SetFeared(Mob *caster, uint32 duration, bool flee) {
//special args to stop fear
if(caster == nullptr && duration == 0) {
fear_state = fearStateNotFeared;
#ifdef FLEE_HP_RATIO
flee_mode = false;
#endif
safe_delete(fear_path_state);
return;
}
flee_mode = flee;
//fear dosent work without at least maps
if(zone->zonemap == nullptr) {
fear_state = fearStateStuck;
return; //just stand there
}
//if we are allready feared, and we are on a fear grid..
//then just stay happy on the grid...
if(fear_path_state != nullptr) {
if(fear_state != fearStateGrid) {
LogFile->write(EQEMuLog::Debug, "Umm... %s has a fear path state, but is not in a grid state. Wtf?", GetName());
fear_state = fearStateGrid;
}
return;
}
//try to run straight away from the caster
VERTEX hit, fear_vector;
if(FearTryStraight(caster, duration, flee, hit, fear_vector)) {
return;
}
//OK, so if we just run, we are going to hit something...
//now we have to think a little more.
//first, try to find a fear node that we can see.
if(zone->pathing != nullptr) {
fear_path_state = new MobFearState();
if(zone->pathing->FindNearestFear(fear_path_state, GetX(), GetY(), GetZ())) {
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing Start: found path, moving from (%.2f, %.2f, %.2f) to path node (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), fear_path_state->x, fear_path_state->y, fear_path_state->z);
#endif
//we found a fear node... were on our way..
cur_wp_x = fear_path_state->x;
cur_wp_y = fear_path_state->y;
cur_wp_z = fear_path_state->z;
fear_state = fearStateGrid;
return;
}
//we have failed to find a path, so we dont need this..
safe_delete(fear_path_state);
}
//if we cannot just run, and we cannot see any paths, then
//we will give one last ditch effort to find a legit path. We
//will run as far as we can away from the player, and hope we
//can see a path from there if not, we will start breaking rules
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing Start: Hope run from (%.2f, %.2f, %.2f), hit at (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), hit.x, hit.y, hit.z);
#endif
//use the hit point - a little + a little Z as the first waypoint.
cur_wp_x = hit.x - fear_vector.x * 2;
cur_wp_y = hit.y - fear_vector.y * 2;
cur_wp_z = GetZ();
fear_state = fearStateRunning;
}
//old fear function, kept for ref.
bool Mob::FearTryStraight(Mob *caster, uint32 duration, bool flee, VERTEX &hit, VERTEX &fear_vector) {
//gotta have somebody to run from
if(caster == nullptr)
return(false);
//our goal is to run along this vector...
fear_vector.x = GetX() - caster->GetX();
fear_vector.y = GetY() - caster->GetY();
fear_vector.z = 0; //I dont see any reason to use Z
float mag = sqrtf(fear_vector.x*fear_vector.x + fear_vector.y*fear_vector.y);
fear_vector.x /= mag;
fear_vector.y /= mag;
//now see if we can just run without hitting anything...
VERTEX start, end;
start.x = GetX();
start.y = GetY();
start.z = GetZ() + 5.0; //raise up a little over small bumps
//distance moved per movement tic.
float distance = NPC_SPEED_MULTIPLIER * GetFearSpeed();
//times number of movement tics in the spell.
distance *= float(duration) / float(AImovement_duration);
end.x = start.x + fear_vector.x * distance;
end.y = start.y + fear_vector.y * distance;
end.z = start.z;
if(!zone->zonemap->LineIntersectsZone(start, end, 0.5, &hit, nullptr)) {
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing Start: can run entire vector from (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), end.x, end.y, end.z);
#endif
//no hit, we can run this whole vector.
cur_wp_x = end.x;
cur_wp_y = end.y;
cur_wp_z = GetZ();
fear_state = fearStateRunningForever;
return(true); //were done, nothing difficult needed.
}
return(false);
}
//old fear function, kept for ref.
void Mob::CalculateFearPosition() {
if(zone->zonemap == nullptr || fear_state == fearStateStuck) {
return; //just stand there
}
//This is the entire movement section, right here:
if (cur_wp_x != GetX() && cur_wp_y != GetY()) {
// not at waypoint yet, so keep moving
CalculateNewPosition2(cur_wp_x, cur_wp_y, cur_wp_z, GetFearSpeed(), true);
return;
}
//we have reached our waypoint, now what?
//figure out a new waypoint to run at...
if(fear_state == fearStateRunningForever) {
if(flee_mode) {
//a fleeing mob may run away again
VERTEX hit, fear_vector;
if(FearTryStraight(GetHateTop(), FLEE_RUN_DURATION, true, hit, fear_vector))
return; //we are running again
//else, we need to find a grid, so act like we were on a hope run
fear_state = fearStateRunning;
}
#ifndef FORCE_FEAR_TO_RUN
else {
//we were supposed to run forever, but we did not...
//should re-fear ourself or something??
fear_state = fearStateStuck;
return;
}
#endif
}
//first see if we are on a path. if so our life is easy
if(fear_state == fearStateGrid && fear_path_state) {
//assume that we have zone->pathing since we got to this state.
if(!zone->pathing->NextFearPath(fear_path_state)) {
//this is bad, we were on a path and now its giving us
//an error... we dont have a good way to deal with this
fear_state = fearStateStuck;
return;
}
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing: on path, moving from (%.2f, %.2f, %.2f) to path node (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), fear_path_state->x, fear_path_state->y, fear_path_state->z);
#endif
//we found a fear node... were on our way..
cur_wp_x = fear_path_state->x;
cur_wp_y = fear_path_state->y;
cur_wp_z = fear_path_state->z;
CalculateNewPosition2(cur_wp_x, cur_wp_y, cur_wp_z, GetFearSpeed(), true);
return;
}
//the only valid state left is fearStateRunning, where we try to
//find a grid once we reach our waypoint, which we have..
if(fear_state != fearStateRunning) {
//wtf... unknown state
LogFile->write(EQEMuLog::Debug, "Fear Pathing: Reached our fear waypoint, but we are in an unknown state %d... stopping.", fear_state);
fear_state = fearStateStuck;
return;
}
//we wanted to try to find a waypoint now, so lets try..
if(zone->pathing != nullptr) {
fear_path_state = new MobFearState();
if(zone->pathing->FindNearestFear(fear_path_state, GetX(), GetY(), GetZ())) {
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing: ran to find path, moving from (%.2f, %.2f, %.2f) to path node (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), fear_path_state->x, fear_path_state->y, fear_path_state->z);
#endif
//we found a fear node... were on our way..
cur_wp_x = fear_path_state->x;
cur_wp_y = fear_path_state->y;
cur_wp_z = fear_path_state->z;
fear_state = fearStateGrid;
CalculateNewPosition2(cur_wp_x, cur_wp_y, cur_wp_z, GetFearSpeed(), true);
return;
}
//if we get here... all valid methods have failed
#ifdef FORCE_FEAR_TO_RUN
//ok, now we start making shit up
//for now, we will limit our bullshitting to ignoring LOS
//when finding a pathing node, we SHOULD always get something..
//do not force a path if we are fleeing
if(!flee_mode && zone->pathing->FindNearestFear(fear_path_state, GetX(), GetY(), GetZ(), false)) {
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing: Bullshit Path from (%.2f, %.2f, %.2f) to path node (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), fear_path_state->x, fear_path_state->y, fear_path_state->z);
#endif
//we found a fear node... were on our way..
cur_wp_x = fear_path_state->x;
cur_wp_y = fear_path_state->y;
cur_wp_z = fear_path_state->z;
fear_state = fearStateGrid;
CalculateNewPosition2(cur_wp_x, cur_wp_y, cur_wp_z, GetFearSpeed(), true);
return;
}
#endif //FORCE_FEAR_TO_RUN
//we have failed to find a path once again, so we dont need this..
safe_delete(fear_path_state);
}
//if we get HERE... then NOTHING worked... just stick
fear_state = fearStateStuck;
//end of function, everything else is #ifdef'd out
//}
//I dont wanna get rid of this right now because it was a lot of hard
//work to write... but it dosent work reliably, so oh well..
#ifdef OLD_FEAR_PATHING
/*
The idea...
try to run along fear vector.
If we can see along it, run
otherwise, try to walk up a hill along the same vector
then try to move along a wall along largest component of FV
if cant move, change stae to stuck.
once we know a place to run, use the waypoint code to do it
then if combat ends, we will reach the waypoint and
*/
/*
//first try our original fear vector again...
VERTEX start, end, hit, normalhit;
start.x = GetX() - fear_vector.x * 0.4;
start.y = GetY() - fear_vector.y * 0.4;
start.z = GetZ() + 6.0; //raise up a little over small bumps
end.x = start.x + fear_vector.x * 10;
end.y = start.y + fear_vector.y * 10;
end.z = start.z;
if(!zone->zonemap->LineIntersectsZone(start, end, 0.5, &normalhit, nullptr)) {
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing: From (%.2f, %.2f, %.2f) normal run to (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), end.x, end.y, end.z);
#endif
//we can run along this vector without hitting anything...
cur_wp_x = end.x;
cur_wp_y = end.y;
cur_wp_z = end.z - 6.0;
CalculateNewPosition2(cur_wp_x, cur_wp_y, cur_wp_z, GetRunspeed(), true);
return;
}
//see if we can make ANY useful progress along that vector
//first, adjust normalhit to back up a little bit
//so we dont run through the wall
normalhit.x -= 0.4 * fear_vector.x;
normalhit.y -= 0.4 * fear_vector.y;
float xd = normalhit.x - start.x;
if(xd < 0)
xd = 0 - xd;
float yd = normalhit.y - start.y;
if(yd < 0)
yd = 0 - yd;
//this 2 is arbitrary
if((xd+yd) > 2.0) {
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing: From (%.2f, %.2f, %.2f) small run to (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), cur_wp_x, cur_wp_y, cur_wp_z);
#endif
cur_wp_x = normalhit.x;
cur_wp_y = normalhit.y;
cur_wp_z = GetZ();
//try and fix up the Z coord if possible
//not sure if this is worth it, since it prolly isnt up much
NodeRef c = zone->zonemap->SeekNode(zone->zonemap->GetRoot(), end.x, end.y);
if(c != NODE_NONE) {
cur_wp_z = zone->zonemap->FindBestZ(c, end, &hit, nullptr);
if(cur_wp_z < start.z)
cur_wp_z = end.z; //revert on error
}
CalculateNewPosition2(cur_wp_x, cur_wp_y, cur_wp_z, GetRunspeed(), true);
return;
}
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing: From (%.2f, %.2f, %.2f) normal hit at (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), normalhit.x, normalhit.y, normalhit.z);
#endif
//if we get here, we cannot run along our normal vector...
//try up hill first
/*
while this uphill stuff works great in outdoor zones,
it totally breaks dungeons...
float speed = GetRunspeed();
end.x = start.x + fear_vector.x * speed;
end.y = start.y + fear_vector.y * speed;
end.z = start.z + speed + speed;
if(!zone->zonemap->LineIntersectsZone(start, end, 0.5, &hit, nullptr)) {
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing: From (%.2f, %.2f, %.2f) up hill run to (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), end.x, end.y, end.z);
#endif
//we can run along this vector without hitting anything...
cur_wp_x = end.x - 0.4 * fear_vector.x;
cur_wp_y = end.y - 0.4 * fear_vector.y;
cur_wp_z = end.z;
//try and fix up the Z coord if possible
//not sure if this is worth it, since it prolly isnt up much
NodeRef c = zone->zonemap->SeekNode(zone->zonemap->GetRoot(), end.x, end.y);
if(c != NODE_NONE) {
cur_wp_z = zone->zonemap->FindBestZ(c, end, &hit, nullptr);
if(cur_wp_z < start.z)
cur_wp_z = end.z; //revert on error
}
CalculateNewPosition2(cur_wp_x, cur_wp_y, cur_wp_z, GetRunspeed(), true);
return;
}
*/
/*
//cant run along our vector at all....
//one last ditch effort... try to move to the side a little
//along the minor component of the fear vector.
//try it in one direction first...
if(fear_vector.x < fear_vector.y) {
end.x = start.x + fear_vector.x * 3;
end.y = start.y;
} else {
end.x = start.x;
end.y = start.y + fear_vector.y * 3;
}
end.z = start.z + 3; //a little lift as always
if(!zone->zonemap->LineIntersectsZone(start, end, 0.5, &hit, nullptr)) {
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing: From (%.2f, %.2f, %.2f) strafe 1 to (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), end.x, end.y, end.z);
#endif
//we can run along this vector without hitting anything...
cur_wp_x = end.x - 0.4 * fear_vector.x;
cur_wp_y = end.y - 0.4 * fear_vector.y;
cur_wp_z = end.z - 3;
CalculateNewPosition2(cur_wp_x, cur_wp_y, cur_wp_z, GetRunspeed(), true);
return;
}
//now the other...
if(fear_vector.x < fear_vector.y) {
end.x = start.x + fear_vector.x * 3;
end.y = start.y;
} else {
end.x = start.x;
end.y = start.y + fear_vector.y * 3;
}
end.z = start.z + 3; //a little lift as always
if(!zone->zonemap->LineIntersectsZone(start, end, 0.5, &hit, nullptr)) {
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing: From (%.2f, %.2f, %.2f) strafe 2 to (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), end.x, end.y, end.z);
#endif
//we can run along this vector without hitting anything...
cur_wp_x = end.x - 0.4 * fear_vector.x;
cur_wp_y = end.y - 0.4 * fear_vector.y;
cur_wp_z = end.z - 3;
CalculateNewPosition2(cur_wp_x, cur_wp_y, cur_wp_z, GetRunspeed(), true);
return;
}
//if we get here... we have wasted enough CPU cycles
//just call it quits on fear pathing...
//send them to normalhit and then stop
cur_wp_x = normalhit.x;
cur_wp_y = normalhit.y;
cur_wp_z = GetZ();
fear_state = fearStateRunningToStick;
#ifdef FEAR_PATHING_DEBUG
LogFile->write(EQEMuLog::Debug, "Fear Pathing: From (%.2f, %.2f, %.2f) final move to (%.2f, %.2f, %.2f)",
GetX(), GetY(), GetZ(), normalhit.x, normalhit.y, normalhit.z);
#endif
#endif //OLD_FEAR_PATHING
}*/

View File

@ -225,7 +225,7 @@ bool Client::CanFish() {
return false; return false;
} }
if(zone->zonemap!=nullptr && zone->watermap != nullptr && RuleB(Watermap, CheckForWaterWhenFishing)) { if(zone->zonemap != nullptr && zone->watermap != nullptr && RuleB(Watermap, CheckForWaterWhenFishing)) {
float RodX, RodY, RodZ; float RodX, RodY, RodZ;
// Tweak Rod and LineLength if required // Tweak Rod and LineLength if required
const float RodLength = RuleR(Watermap, FishingRodLength); const float RodLength = RuleR(Watermap, FishingRodLength);
@ -240,13 +240,12 @@ bool Client::CanFish() {
// Do BestZ to find where the line hanging from the rod intersects the water (if it is water). // Do BestZ to find where the line hanging from the rod intersects the water (if it is water).
// and go 1 unit into the water. // and go 1 unit into the water.
VERTEX dest; Map::Vertex dest;
dest.x = RodX; dest.x = RodX;
dest.y = RodY; dest.y = RodY;
dest.z = z_pos+10; dest.z = z_pos+10;
NodeRef n = zone->zonemap->SeekNode( zone->zonemap->GetRoot(), dest.x, dest.y);
if(n != NODE_NONE) { RodZ = zone->zonemap->FindBestZ(dest, nullptr) - 1;
RodZ = zone->zonemap->FindBestZ(n, dest, nullptr, nullptr) - 1;
bool in_lava = zone->watermap->InLava(RodX, RodY, RodZ); bool in_lava = zone->watermap->InLava(RodX, RodY, RodZ);
bool in_water = zone->watermap->InWater(RodX, RodY, RodZ) || zone->watermap->InVWater(RodX, RodY, RodZ); bool in_water = zone->watermap->InWater(RodX, RodY, RodZ) || zone->watermap->InVWater(RodX, RodY, RodZ);
//Message(0, "Rod is at %4.3f, %4.3f, %4.3f, InWater says %d, InLava says %d", RodX, RodY, RodZ, in_water, in_lava); //Message(0, "Rod is at %4.3f, %4.3f, %4.3f, InWater says %d, InLava says %d", RodX, RodY, RodZ, in_water, in_lava);
@ -259,7 +258,6 @@ bool Client::CanFish() {
return false; return false;
} }
} }
}
return true; return true;
} }

268
zone/map.cpp Normal file
View File

@ -0,0 +1,268 @@
#include "../common/debug.h"
#include "../common/MiscFunctions.h"
#include "map.h"
#include "RaycastMesh.h"
#include "zone.h"
#include <stdint.h>
#include <algorithm>
#include <locale>
#include <vector>
struct Map::impl
{
RaycastMesh *rm;
};
Map::Map() {
imp = nullptr;
}
Map::~Map() {
if(imp) {
imp->rm->release();
}
}
float Map::FindBestZ(Vertex &start, Vertex *result) const {
if (!imp)
return false;
Vertex tmp;
if(!result)
result = &tmp;
start.z += RuleI(Map, FindBestZHeightAdjust);
Vertex from = { start.x, start.y, start.z };
Vertex to = { start.x, start.y, BEST_Z_INVALID };
float hit_distance;
bool hit = false;
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
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;
}
bool Map::LineIntersectsZone(Vertex start, Vertex end, float step, Vertex *result) const {
if(!imp)
return false;
return imp->rm->raycast((const RmReal*)&start, (const RmReal*)&end, (RmReal*)result, nullptr, nullptr);
}
bool Map::LineIntersectsZoneNoZLeaps(Vertex start, Vertex end, float step_mag, Vertex *result) const {
if (!imp)
return false;
float z = BEST_Z_INVALID;
Vertex step;
Vertex cur;
cur.x = start.x;
cur.y = start.y;
cur.z = start.z;
step.x = end.x - start.x;
step.y = end.y - start.y;
step.z = end.z - start.z;
float factor = step_mag / sqrt(step.x*step.x + step.y*step.y + step.z*step.z);
step.x *= factor;
step.y *= factor;
step.z *= factor;
int steps = 0;
if (step.x > 0 && step.x < 0.001f)
step.x = 0.001f;
if (step.y > 0 && step.y < 0.001f)
step.y = 0.001f;
if (step.z > 0 && step.z < 0.001f)
step.z = 0.001f;
if (step.x < 0 && step.x > -0.001f)
step.x = -0.001f;
if (step.y < 0 && step.y > -0.001f)
step.y = -0.001f;
if (step.z < 0 && step.z > -0.001f)
step.z = -0.001f;
//while we are not past end
//always do this once, even if start == end.
while(cur.x != end.x || cur.y != end.y || cur.z != end.z)
{
steps++;
Vertex me;
me.x = cur.x;
me.y = cur.y;
me.z = cur.z;
Vertex hit;
float best_z = FindBestZ(me, &hit);
float diff = best_z - z;
diff = diff < 0 ? -diff : diff;
if (z == -999999 || best_z == -999999 || diff < 12.0)
z = best_z;
else
return true;
//look at current location
if(LineIntersectsZone(start, end, step_mag, result))
{
return true;
}
//move 1 step
if (cur.x != end.x)
cur.x += step.x;
if (cur.y != end.y)
cur.y += step.y;
if (cur.z != end.z)
cur.z += step.z;
//watch for end conditions
if ( (cur.x > end.x && end.x >= start.x) || (cur.x < end.x && end.x <= start.x) || (step.x == 0) ) {
cur.x = end.x;
}
if ( (cur.y > end.y && end.y >= start.y) || (cur.y < end.y && end.y <= start.y) || (step.y == 0) ) {
cur.y = end.y;
}
if ( (cur.z > end.z && end.z >= start.z) || (cur.z < end.z && end.z < start.z) || (step.z == 0) ) {
cur.z = end.z;
}
}
//walked entire line and didnt run into anything...
return false;
}
bool Map::CheckLoS(Vertex myloc, Vertex oloc) const {
if(!imp)
return false;
return !imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, nullptr, nullptr);
}
Map *Map::LoadMapFile(std::string file) {
std::string filename = MAP_DIR;
filename += "/";
std::transform(file.begin(), file.end(), file.begin(), ::tolower);
filename += file;
filename += ".map";
Map *m = new Map();
if (m->Load(filename)) {
return m;
}
delete m;
return nullptr;
}
bool Map::Load(std::string filename) {
FILE *f = fopen(filename.c_str(), "rb");
if(f) {
uint32_t version;
if(fread(&version, sizeof(version), 1, f) != 1) {
fclose(f);
return false;
}
if(version == 0x01000000) {
bool v = LoadV1(f);
fclose(f);
return v;
} else if(version == 0x02000000) {
bool v = LoadV2(f);
fclose(f);
return v;
} else {
fclose(f);
return false;
}
}
return false;
}
bool Map::LoadV1(FILE *f) {
uint32_t face_count;
uint16_t node_count;
uint32_t 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<Vertex> verts;
std::vector<uint32_t> indices;
for(uint32_t i = 0; i < face_count; ++i) {
Vertex a;
Vertex b;
Vertex c;
float normals[4];
if(fread(&a, sizeof(Vertex), 1, f) != 1) {
return false;
}
if(fread(&b, sizeof(Vertex), 1, f) != 1) {
return false;
}
if(fread(&c, sizeof(Vertex), 1, f) != 1) {
return false;
}
if(fread(normals, sizeof(normals), 1, f) != 1) {
return false;
}
size_t sz = verts.size();
verts.push_back(a);
indices.push_back((uint32_t)sz);
verts.push_back(b);
indices.push_back((uint32_t)sz + 1);
verts.push_back(c);
indices.push_back((uint32_t)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;
}
bool Map::LoadV2(FILE *f) {
return false;
}

67
zone/map.h Normal file
View File

@ -0,0 +1,67 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
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 ZONE_MAP_H
#define ZONE_MAP_H
#include <stdio.h>
#include <string>
#define BEST_Z_INVALID -99999
class Map
{
public:
#pragma pack(1)
struct Vertex
{
Vertex() : x(0.0f), y(0.0f), z(0.0f) { }
Vertex(float _x, float _y, float _z) : x(_x), y(_y), z(_z) { }
~Vertex() { }
bool operator==(const Vertex &v) const
{
return((v.x == x) && (v.y == y) && (v.z == z));
}
float x;
float y;
float z;
};
#pragma pack()
Map();
~Map();
float FindBestZ(Vertex &start, Vertex *result) const;
bool LineIntersectsZone(Vertex start, Vertex end, float step, Vertex *result) const;
bool LineIntersectsZoneNoZLeaps(Vertex start, Vertex end, float step_mag, Vertex *result) const;
bool CheckLoS(Vertex myloc, Vertex oloc) const;
bool Load(std::string filename);
static Map *LoadMapFile(std::string file);
private:
bool LoadV1(FILE *f);
bool LoadV2(FILE *f);
struct impl;
impl *imp;
};
#endif

View File

@ -2933,24 +2933,19 @@ void Mob::SetTarget(Mob* mob) {
float Mob::FindGroundZ(float new_x, float new_y, float z_offset) float Mob::FindGroundZ(float new_x, float new_y, float z_offset)
{ {
float ret = -999999; float ret = -999999;
if (zone->zonemap != 0) if (zone->zonemap != nullptr)
{ {
NodeRef pnode = zone->zonemap->SeekNode( zone->zonemap->GetRoot(), new_x, new_y ); Map::Vertex me;
if (pnode != NODE_NONE)
{
VERTEX me;
me.x = new_x; me.x = new_x;
me.y = new_y; me.y = new_y;
me.z = z_pos+z_offset; me.z = z_pos+z_offset;
VERTEX hit; Map::Vertex hit;
FACE *onhit; float best_z = zone->zonemap->FindBestZ(me, &hit);
float best_z = zone->zonemap->FindBestZ(pnode, me, &hit, &onhit);
if (best_z != -999999) if (best_z != -999999)
{ {
ret = best_z; ret = best_z;
} }
} }
}
return ret; return ret;
} }
@ -2960,22 +2955,17 @@ float Mob::GetGroundZ(float new_x, float new_y, float z_offset)
float ret = -999999; float ret = -999999;
if (zone->zonemap != 0) if (zone->zonemap != 0)
{ {
NodeRef pnode = zone->zonemap->SeekNode( zone->zonemap->GetRoot(), new_x, new_y ); Map::Vertex me;
if (pnode != NODE_NONE)
{
VERTEX me;
me.x = new_x; me.x = new_x;
me.y = new_y; me.y = new_y;
me.z = z_pos+z_offset; me.z = z_pos+z_offset;
VERTEX hit; Map::Vertex hit;
FACE *onhit; float best_z = zone->zonemap->FindBestZ(me, &hit);
float best_z = zone->zonemap->FindBestZ(pnode, me, &hit, &onhit);
if (best_z != -999999) if (best_z != -999999)
{ {
ret = best_z; ret = best_z;
} }
} }
}
return ret; return ret;
} }

View File

@ -417,7 +417,7 @@ public:
void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu); void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu);
void SendPosition(); void SendPosition();
void SetFlyMode(uint8 flymode); void SetFlyMode(uint8 flymode);
inline void Teleport(VERTEX NewPosition) { x_pos = NewPosition.x; y_pos = NewPosition.y; inline void Teleport(Map::Vertex NewPosition) { x_pos = NewPosition.x; y_pos = NewPosition.y;
z_pos = NewPosition.z; }; z_pos = NewPosition.z; };
//AI //AI
@ -447,7 +447,6 @@ public:
void ClearFeignMemory(); void ClearFeignMemory();
void PrintHateListToClient(Client *who) { hate_list.PrintToClient(who); } void PrintHateListToClient(Client *who) { hate_list.PrintToClient(who); }
std::list<tHateEntry*>& GetHateList() { return hate_list.GetHateList(); } std::list<tHateEntry*>& GetHateList() { return hate_list.GetHateList(); }
bool CheckLos(Mob* other);
bool CheckLosFN(Mob* other); bool CheckLosFN(Mob* other);
bool CheckLosFN(float posX, float posY, float posZ, float mobSize); bool CheckLosFN(float posX, float posY, float posZ, float mobSize);
inline void SetChanged() { pLastChange = Timer::GetCurrentTime(); } inline void SetChanged() { pLastChange = Timer::GetCurrentTime(); }
@ -981,7 +980,7 @@ protected:
bool HasDied(); bool HasDied();
void CalculateNewFearpoint(); void CalculateNewFearpoint();
float FindGroundZ(float new_x, float new_y, float z_offset=0.0); float FindGroundZ(float new_x, float new_y, float z_offset=0.0);
VERTEX UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange, bool &NodeReached); Map::Vertex UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange, bool &NodeReached);
void PrintRoute(); void PrintRoute();
void UpdateRuneFlags(); void UpdateRuneFlags();
@ -1146,8 +1145,8 @@ protected:
// Pathing // Pathing
// //
VERTEX PathingDestination; Map::Vertex PathingDestination;
VERTEX PathingLastPosition; Map::Vertex PathingLastPosition;
int PathingLoopCount; int PathingLoopCount;
int PathingLastNodeVisited; int PathingLastNodeVisited;
std::list<int> Route; std::list<int> Route;

View File

@ -21,7 +21,7 @@
extern Zone *zone; extern Zone *zone;
float VertexDistance(VERTEX a, VERTEX b) float VertexDistance(Map::Vertex a, Map::Vertex b)
{ {
float xdist = a.x - b.x; float xdist = a.x - b.x;
float ydist = a.y - b.y; float ydist = a.y - b.y;
@ -29,7 +29,7 @@ float VertexDistance(VERTEX a, VERTEX b)
return sqrtf(xdist * xdist + ydist * ydist + zdist * zdist); return sqrtf(xdist * xdist + ydist * ydist + zdist * zdist);
} }
float VertexDistanceNoRoot(VERTEX a, VERTEX b) float VertexDistanceNoRoot(Map::Vertex a, Map::Vertex b)
{ {
float xdist = a.x - b.x; float xdist = a.x - b.x;
float ydist = a.y - b.y; float ydist = a.y - b.y;
@ -187,9 +187,9 @@ void PathManager::PrintPathing()
} }
} }
VERTEX PathManager::GetPathNodeCoordinates(int NodeNumber, bool BestZ) Map::Vertex PathManager::GetPathNodeCoordinates(int NodeNumber, bool BestZ)
{ {
VERTEX Result; Map::Vertex Result;
if(NodeNumber < Head.PathNodeCount) if(NodeNumber < Head.PathNodeCount)
{ {
@ -335,12 +335,12 @@ std::list<int> PathManager::FindRoute(int startID, int endID)
} }
bool CheckLOSBetweenPoints(VERTEX start, VERTEX end) { bool CheckLOSBetweenPoints(Map::Vertex start, Map::Vertex end) {
VERTEX hit; Map::Vertex hit;
FACE *face;
if((zone->zonemap) && (zone->zonemap->LineIntersectsZone(start, end, 1, &hit, &face))) return false; if((zone->zonemap) && (zone->zonemap->LineIntersectsZone(start, end, 1, &hit)))
return false;
return true; return true;
} }
@ -350,7 +350,7 @@ bool SortPathNodesByDistance(PathNodeSortStruct n1, PathNodeSortStruct n2)
return n1.Distance < n2.Distance; return n1.Distance < n2.Distance;
} }
std::list<int> PathManager::FindRoute(VERTEX Start, VERTEX End) std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
{ {
_log(PATHING__DEBUG, "FindRoute(%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f)", Start.x, Start.y, Start.z, End.x, End.y, End.z); _log(PATHING__DEBUG, "FindRoute(%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f)", Start.x, Start.y, Start.z, End.x, End.y, End.z);
@ -388,7 +388,7 @@ std::list<int> PathManager::FindRoute(VERTEX Start, VERTEX End)
{ {
_log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id); _log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
if(!zone->zonemap->LineIntersectsZone(Start, PathNodes[(*Iterator).id].v, 1.0f, nullptr, nullptr)) if(!zone->zonemap->LineIntersectsZone(Start, PathNodes[(*Iterator).id].v, 1.0f, nullptr))
{ {
ClosestPathNodeToStart = (*Iterator).id; ClosestPathNodeToStart = (*Iterator).id;
break; break;
@ -429,7 +429,7 @@ std::list<int> PathManager::FindRoute(VERTEX Start, VERTEX End)
End.x, End.y, End.z, End.x, End.y, End.z,
PathNodes[(*Iterator).id].v.x, PathNodes[(*Iterator).id].v.y, PathNodes[(*Iterator).id].v.z); PathNodes[(*Iterator).id].v.x, PathNodes[(*Iterator).id].v.y, PathNodes[(*Iterator).id].v.z);
if(!zone->zonemap->LineIntersectsZone(End, PathNodes[(*Iterator).id].v, 1.0f, nullptr, nullptr)) if(!zone->zonemap->LineIntersectsZone(End, PathNodes[(*Iterator).id].v, 1.0f, nullptr))
{ {
ClosestPathNodeToEnd = (*Iterator).id; ClosestPathNodeToEnd = (*Iterator).id;
break; break;
@ -469,7 +469,7 @@ std::list<int> PathManager::FindRoute(VERTEX Start, VERTEX End)
if((*Second) < 0) if((*Second) < 0)
break; break;
if(!zone->zonemap->LineIntersectsZone(Start, PathNodes[(*Second)].v, 1.0f, nullptr, nullptr) if(!zone->zonemap->LineIntersectsZone(Start, PathNodes[(*Second)].v, 1.0f, nullptr)
&& zone->pathing->NoHazards(Start, PathNodes[(*Second)].v)) && zone->pathing->NoHazards(Start, PathNodes[(*Second)].v))
{ {
noderoute.erase(First); noderoute.erase(First);
@ -502,7 +502,7 @@ std::list<int> PathManager::FindRoute(VERTEX Start, VERTEX End)
if((*Second) < 0) if((*Second) < 0)
break; break;
if(!zone->zonemap->LineIntersectsZone(End, PathNodes[(*Second)].v, 1.0f, nullptr, nullptr) if(!zone->zonemap->LineIntersectsZone(End, PathNodes[(*Second)].v, 1.0f, nullptr)
&& zone->pathing->NoHazards(End, PathNodes[(*Second)].v)) && zone->pathing->NoHazards(End, PathNodes[(*Second)].v))
{ {
noderoute.erase(First); noderoute.erase(First);
@ -652,19 +652,19 @@ void PathManager::SimpleMeshTest()
fflush(stdout); fflush(stdout);
} }
VERTEX Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChanged, bool &NodeReached) Map::Vertex Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChanged, bool &NodeReached)
{ {
WaypointChanged = false; WaypointChanged = false;
NodeReached = false; NodeReached = false;
VERTEX NodeLoc; Map::Vertex NodeLoc;
VERTEX From(GetX(), GetY(), GetZ()); Map::Vertex From(GetX(), GetY(), GetZ());
VERTEX HeadPosition(From.x, From.y, From.z + (GetSize() < 6.0 ? 6 : GetSize()) * HEAD_POSITION); Map::Vertex HeadPosition(From.x, From.y, From.z + (GetSize() < 6.0 ? 6 : GetSize()) * HEAD_POSITION);
VERTEX To(ToX, ToY, ToZ); Map::Vertex To(ToX, ToY, ToZ);
bool SameDestination = (To == PathingDestination); bool SameDestination = (To == PathingDestination);
@ -761,7 +761,7 @@ VERTEX Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Waypo
if((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort)) if((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort))
&& (ABS(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold))) && (ABS(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold)))
{ {
if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr, nullptr)) if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr))
PathingLOSState = HaveLOS; PathingLOSState = HaveLOS;
else else
PathingLOSState = NoLOS; PathingLOSState = NoLOS;
@ -854,7 +854,7 @@ VERTEX Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Waypo
if((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort)) if((Distance <= RuleR(Pathing, MinDistanceForLOSCheckShort))
&& (ABS(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold))) && (ABS(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold)))
{ {
if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr, nullptr)) if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr))
PathingLOSState = HaveLOS; PathingLOSState = HaveLOS;
else else
PathingLOSState = NoLOS; PathingLOSState = NoLOS;
@ -893,7 +893,7 @@ VERTEX Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Waypo
&& (ABS(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold))) && (ABS(From.z - To.z) <= RuleR(Pathing, ZDiffThreshold)))
{ {
mlog(PATHING__DEBUG, " Checking for short LOS at distance %8.3f.", Distance); mlog(PATHING__DEBUG, " Checking for short LOS at distance %8.3f.", Distance);
if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr, nullptr)) if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr))
PathingLOSState = HaveLOS; PathingLOSState = HaveLOS;
else else
PathingLOSState = NoLOS; PathingLOSState = NoLOS;
@ -1046,7 +1046,7 @@ VERTEX Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Waypo
{ {
mlog(PATHING__DEBUG, " Checking for long LOS at distance %8.3f.", Distance); mlog(PATHING__DEBUG, " Checking for long LOS at distance %8.3f.", Distance);
if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr, nullptr)) if(!zone->zonemap->LineIntersectsZone(HeadPosition, To, 1.0f, nullptr))
PathingLOSState = HaveLOS; PathingLOSState = HaveLOS;
else else
PathingLOSState = NoLOS; PathingLOSState = NoLOS;
@ -1090,7 +1090,7 @@ VERTEX Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Waypo
} }
int PathManager::FindNearestPathNode(VERTEX Position) int PathManager::FindNearestPathNode(Map::Vertex Position)
{ {
// Find the nearest PathNode we have LOS to. // Find the nearest PathNode we have LOS to.
@ -1126,7 +1126,7 @@ int PathManager::FindNearestPathNode(VERTEX Position)
{ {
_log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id); _log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
if(!zone->zonemap->LineIntersectsZone(Position, PathNodes[(*Iterator).id].v, 1.0f, nullptr, nullptr)) if(!zone->zonemap->LineIntersectsZone(Position, PathNodes[(*Iterator).id].v, 1.0f, nullptr))
{ {
ClosestPathNodeToStart = (*Iterator).id; ClosestPathNodeToStart = (*Iterator).id;
break; break;
@ -1140,13 +1140,13 @@ int PathManager::FindNearestPathNode(VERTEX Position)
return ClosestPathNodeToStart; return ClosestPathNodeToStart;
} }
bool PathManager::NoHazards(VERTEX From, VERTEX To) bool PathManager::NoHazards(Map::Vertex From, Map::Vertex To)
{ {
// Test the Z coordinate at the mid point. // Test the Z coordinate at the mid point.
// //
VERTEX MidPoint((From.x + To.x) / 2, (From.y + To.y) / 2, From.z); Map::Vertex MidPoint((From.x + To.x) / 2, (From.y + To.y) / 2, From.z);
float NewZ = zone->zonemap->FindBestZ(MAP_ROOT_NODE, MidPoint, nullptr, nullptr); float NewZ = zone->zonemap->FindBestZ(MidPoint, nullptr);
if(ABS(NewZ - From.z) > RuleR(Pathing, ZDiffThreshold)) if(ABS(NewZ - From.z) > RuleR(Pathing, ZDiffThreshold))
{ {
@ -1164,10 +1164,10 @@ bool PathManager::NoHazards(VERTEX From, VERTEX To)
return true; return true;
} }
bool PathManager::NoHazardsAccurate(VERTEX From, VERTEX To) bool PathManager::NoHazardsAccurate(Map::Vertex From, Map::Vertex To)
{ {
float stepx, stepy, stepz, curx, cury, curz; float stepx, stepy, stepz, curx, cury, curz;
VERTEX cur = From; Map::Vertex cur = From;
float last_z = From.z; float last_z = From.z;
float step_size = 1.0; float step_size = 1.0;
@ -1181,13 +1181,13 @@ bool PathManager::NoHazardsAccurate(VERTEX From, VERTEX To)
stepy = (float)To.y - cury; stepy = (float)To.y - cury;
stepz = (float)To.z - curz; stepz = (float)To.z - curz;
float factor = sqrt(stepx*stepx + stepy*stepy + stepz*stepz); float factor = sqrt(stepx*stepx + stepy*stepy + stepz*stepz);
stepx = (stepx/factor)*step_size; stepx = (stepx / factor)*step_size;
stepy = (stepy/factor)*step_size; stepy = (stepy / factor)*step_size;
stepz = (stepz/factor)*step_size; stepz = (stepz / factor)*step_size;
VERTEX TestPoint(curx, cury, curz); Map::Vertex TestPoint = { curx, cury, curz };
float NewZ = zone->zonemap->FindBestZ(MAP_ROOT_NODE, TestPoint, nullptr, nullptr); float NewZ = zone->zonemap->FindBestZ(TestPoint, nullptr);
if(ABS(NewZ - last_z) > 5.0) if (ABS(NewZ - last_z) > 5.0f)
{ {
_log(PATHING__DEBUG, " HAZARD DETECTED moving from %8.3f, %8.3f, %8.3f to %8.3f, %8.3f, %8.3f. Best Z %8.3f, Z Change is %8.3f", _log(PATHING__DEBUG, " HAZARD DETECTED moving from %8.3f, %8.3f, %8.3f to %8.3f, %8.3f, %8.3f. Best Z %8.3f, Z Change is %8.3f",
From.x, From.y, From.z, TestPoint.x, TestPoint.y, TestPoint.z, NewZ, NewZ - From.z); From.x, From.y, From.z, TestPoint.x, TestPoint.y, TestPoint.z, NewZ, NewZ - From.z);
@ -1195,35 +1195,32 @@ bool PathManager::NoHazardsAccurate(VERTEX From, VERTEX To)
} }
last_z = NewZ; last_z = NewZ;
if(zone->watermap) if (zone->watermap)
{ {
NodeRef n = zone->zonemap->SeekNode( zone->zonemap->GetRoot(), TestPoint.x, TestPoint.y); if (zone->watermap->InLiquid(From.x, From.y, From.z) || zone->watermap->InLiquid(To.x, To.y, To.z))
if(n != NODE_NONE)
{
if(zone->watermap->InLiquid(From.x, From.y, From.z) || zone->watermap->InLiquid(To.x, To.y, To.z))
{ {
break; break;
} }
if(zone->watermap->InLiquid(TestPoint.x, TestPoint.y, NewZ)) if (zone->watermap->InLiquid(TestPoint.x, TestPoint.y, NewZ))
{ {
VERTEX TestPointWater(TestPoint.x, TestPoint.y, NewZ-0.5); Map::Vertex TestPointWater = { TestPoint.x, TestPoint.y, NewZ - 0.5f };
VERTEX TestPointWaterDest(TestPointWater); Map::Vertex TestPointWaterDest = TestPointWater;
VERTEX hit; Map::Vertex hit;
TestPointWaterDest.z -= 500; TestPointWaterDest.z -= 500;
float best_z2 = -999990; float best_z2 = -999990;
if(zone->zonemap->LineIntersectsNode(n, TestPointWater, TestPointWaterDest, &hit, nullptr)) if (zone->zonemap->LineIntersectsZone(TestPointWater, TestPointWaterDest, 1.0f, &hit))
{ {
best_z2 = hit.z; best_z2 = hit.z;
} }
if(best_z2 == -999990) if (best_z2 == -999990)
{ {
_log(PATHING__DEBUG, " HAZARD DETECTED, really deep water/lava!"); _log(PATHING__DEBUG, " HAZARD DETECTED, really deep water/lava!");
return false; return false;
} }
else else
{ {
if(ABS(NewZ - best_z2) > RuleR(Pathing, ZDiffThreshold)) if (ABS(NewZ - best_z2) > RuleR(Pathing, ZDiffThreshold))
{ {
_log(PATHING__DEBUG, " HAZARD DETECTED, water is fairly deep at %8.3f units deep", ABS(NewZ - best_z2)); _log(PATHING__DEBUG, " HAZARD DETECTED, water is fairly deep at %8.3f units deep", ABS(NewZ - best_z2));
return false; return false;
@ -1239,7 +1236,6 @@ bool PathManager::NoHazardsAccurate(VERTEX From, VERTEX To)
_log(PATHING__DEBUG, "Hazard point not in water or lava!"); _log(PATHING__DEBUG, "Hazard point not in water or lava!");
} }
} }
}
else else
{ {
_log(PATHING__DEBUG, "No water map loaded for hazards!"); _log(PATHING__DEBUG, "No water map loaded for hazards!");
@ -1253,12 +1249,11 @@ bool PathManager::NoHazardsAccurate(VERTEX From, VERTEX To)
cur.y = cury; cur.y = cury;
cur.z = curz; cur.z = curz;
if(ABS(curx - To.x) < step_size) cur.x = To.x; if (ABS(curx - To.x) < step_size) cur.x = To.x;
if(ABS(cury - To.y) < step_size) cur.y = To.y; if (ABS(cury - To.y) < step_size) cur.y = To.y;
if(ABS(curz - To.z) < step_size) cur.z = To.z; if (ABS(curz - To.z) < step_size) cur.z = To.z;
} } while (cur.x != To.x || cur.y != To.y || cur.z != To.z);
while(cur.x != To.x || cur.y != To.y || cur.z != To.z);
return true; return true;
} }
@ -2001,8 +1996,8 @@ void PathManager::MoveNode(Client *c)
if(zone->zonemap) if(zone->zonemap)
{ {
VERTEX loc(c->GetX(), c->GetY(), c->GetZ()); Map::Vertex loc(c->GetX(), c->GetY(), c->GetZ());
Node->bestz = zone->zonemap->FindBestZ(MAP_ROOT_NODE, loc, nullptr, nullptr); Node->bestz = zone->zonemap->FindBestZ(loc, nullptr);
} }
else else
{ {
@ -2072,14 +2067,14 @@ bool PathManager::NodesConnected(PathNode *a, PathNode *b)
return false; return false;
} }
bool PathManager::CheckLosFN(VERTEX a, VERTEX b) bool PathManager::CheckLosFN(Map::Vertex a, Map::Vertex b)
{ {
if(zone->zonemap) if(zone->zonemap)
{ {
VERTEX hit; Map::Vertex hit;
VERTEX myloc; Map::Vertex myloc;
VERTEX oloc; Map::Vertex oloc;
myloc.x = a.x; myloc.x = a.x;
myloc.y = a.y; myloc.y = a.y;
@ -2090,7 +2085,7 @@ bool PathManager::CheckLosFN(VERTEX a, VERTEX b)
oloc.z = b.z; oloc.z = b.z;
if(zone->zonemap->LineIntersectsZone(myloc, oloc, 1.0f, nullptr, nullptr)) if(zone->zonemap->LineIntersectsZone(myloc, oloc, 1.0f, nullptr))
{ {
return false; return false;
} }

View File

@ -31,7 +31,7 @@ struct NeighbourNode {
struct PathNode { struct PathNode {
uint16 id; uint16 id;
VERTEX v; Map::Vertex v;
float bestz; float bestz;
NeighbourNode Neighbours[PATHNODENEIGHBOURS]; NeighbourNode Neighbours[PATHNODENEIGHBOURS];
}; };
@ -61,17 +61,17 @@ public:
static PathManager *LoadPathFile(const char *ZoneName); static PathManager *LoadPathFile(const char *ZoneName);
bool loadPaths(FILE *fp); bool loadPaths(FILE *fp);
void PrintPathing(); void PrintPathing();
std::list<int> FindRoute(VERTEX Start, VERTEX End); std::list<int> FindRoute(Map::Vertex Start, Map::Vertex End);
std::list<int> FindRoute(int startID, int endID); std::list<int> FindRoute(int startID, int endID);
VERTEX GetPathNodeCoordinates(int NodeNumber, bool BestZ = true); Map::Vertex GetPathNodeCoordinates(int NodeNumber, bool BestZ = true);
bool CheckLosFN(VERTEX a, VERTEX b); bool CheckLosFN(Map::Vertex a, Map::Vertex b);
void SpawnPathNodes(); void SpawnPathNodes();
void MeshTest(); void MeshTest();
void SimpleMeshTest(); void SimpleMeshTest();
int FindNearestPathNode(VERTEX Position); int FindNearestPathNode(Map::Vertex Position);
bool NoHazards(VERTEX From, VERTEX To); bool NoHazards(Map::Vertex From, Map::Vertex To);
bool NoHazardsAccurate(VERTEX From, VERTEX To); bool NoHazardsAccurate(Map::Vertex From, Map::Vertex To);
void OpenDoors(int Node1, int Node2, Mob* ForWho); void OpenDoors(int Node1, int Node2, Mob* ForWho);
PathNode* FindPathNodeByCoordinates(float x, float y, float z); PathNode* FindPathNodeByCoordinates(float x, float y, float z);

View File

@ -234,9 +234,9 @@ void NPC::UpdateWaypoint(int wp_index)
if(!RuleB(Watermap, CheckForWaterAtWaypoints) || !zone->HasWaterMap() || if(!RuleB(Watermap, CheckForWaterAtWaypoints) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(cur_wp_x, cur_wp_y, cur_wp_z))) (zone->HasWaterMap() && !zone->watermap->InWater(cur_wp_x, cur_wp_y, cur_wp_z)))
{ {
VERTEX dest(cur_wp_x, cur_wp_y, cur_wp_z); Map::Vertex dest(cur_wp_x, cur_wp_y, cur_wp_z);
float newz = zone->zonemap->FindBestZ(MAP_ROOT_NODE, dest, nullptr, nullptr); float newz = zone->zonemap->FindBestZ(dest, nullptr);
if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaWaypoint)) if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaWaypoint))
cur_wp_z = newz + 1; cur_wp_z = newz + 1;
@ -564,9 +564,9 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
{ {
VERTEX dest(x_pos, y_pos, z_pos); Map::Vertex dest(x_pos, y_pos, z_pos);
float newz = zone->zonemap->FindBestZ(MAP_ROOT_NODE, dest, nullptr, nullptr); float newz = zone->zonemap->FindBestZ(dest, nullptr);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);
@ -693,9 +693,9 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
{ {
VERTEX dest(x_pos, y_pos, z_pos); Map::Vertex dest(x_pos, y_pos, z_pos);
float newz = zone->zonemap->FindBestZ(MAP_ROOT_NODE, dest, nullptr, nullptr); float newz = zone->zonemap->FindBestZ(dest, nullptr);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);
@ -818,9 +818,9 @@ bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool chec
if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
{ {
VERTEX dest(x_pos, y_pos, z_pos); Map::Vertex dest(x_pos, y_pos, z_pos);
float newz = zone->zonemap->FindBestZ(MAP_ROOT_NODE, dest, nullptr, nullptr); float newz = zone->zonemap->FindBestZ(dest, nullptr);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);
@ -926,9 +926,9 @@ void NPC::AssignWaypoints(int32 grid) {
if(!RuleB(Watermap, CheckWaypointsInWaterWhenLoading) || !zone->HasWaterMap() || if(!RuleB(Watermap, CheckWaypointsInWaterWhenLoading) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(newwp.x, newwp.y, newwp.z))) (zone->HasWaterMap() && !zone->watermap->InWater(newwp.x, newwp.y, newwp.z)))
{ {
VERTEX dest(newwp.x, newwp.y, newwp.z); Map::Vertex dest(newwp.x, newwp.y, newwp.z);
float newz = zone->zonemap->FindBestZ(MAP_ROOT_NODE, dest, nullptr, nullptr); float newz = zone->zonemap->FindBestZ(dest, nullptr);
if( (newz > -2000) && ABS(newz-dest.z) < RuleR(Map, FixPathingZMaxDeltaLoading)) if( (newz > -2000) && ABS(newz-dest.z) < RuleR(Map, FixPathingZMaxDeltaLoading))
newwp.z = newz + 1; newwp.z = newz + 1;
@ -981,9 +981,9 @@ void Mob::SendTo(float new_x, float new_y, float new_z) {
if(!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() || if(!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
{ {
VERTEX dest(x_pos, y_pos, z_pos); Map::Vertex dest(x_pos, y_pos, z_pos);
float newz = zone->zonemap->FindBestZ(MAP_ROOT_NODE, dest, nullptr, nullptr); float newz = zone->zonemap->FindBestZ(dest, nullptr);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);
@ -1012,9 +1012,9 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
if(!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() || if(!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
{ {
VERTEX dest(x_pos, y_pos, z_pos); Map::Vertex dest(x_pos, y_pos, z_pos);
float newz = zone->zonemap->FindBestZ(MAP_ROOT_NODE, dest, nullptr, nullptr); float newz = zone->zonemap->FindBestZ(dest, nullptr);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);

View File

@ -103,7 +103,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
worldserver.SetZone(0); worldserver.SetZone(0);
return false; return false;
} }
zone->zonemap = Map::LoadMapfile(zone->map_name); zone->zonemap = Map::LoadMapFile(zone->map_name);
zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name); zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name);
zone->pathing = PathManager::LoadPathFile(zone->map_name); zone->pathing = PathManager::LoadPathFile(zone->map_name);