mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 01:11:29 +00:00
Prelim swimming support
This commit is contained in:
parent
cd59916e67
commit
c0ebe05d5d
@ -1264,7 +1264,7 @@ void command_movement(Client *c, const Seperator *sep)
|
|||||||
auto &mgr = MobMovementManager::Get();
|
auto &mgr = MobMovementManager::Get();
|
||||||
|
|
||||||
if (sep->arg[1][0] == 0) {
|
if (sep->arg[1][0] == 0) {
|
||||||
c->Message(0, "Usage: #movement stats/clearstats/walkto/runto/rotateto/stop");
|
c->Message(0, "Usage: #movement stats/clearstats/walkto/runto/rotateto/stop/packet");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1316,8 +1316,18 @@ void command_movement(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
target->StopNavigation();
|
target->StopNavigation();
|
||||||
}
|
}
|
||||||
|
else if (strcasecmp(sep->arg[1], "packet") == 0)
|
||||||
|
{
|
||||||
|
auto target = c->GetTarget();
|
||||||
|
if (target == nullptr) {
|
||||||
|
c->Message(0, "No target found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mgr.SendCommandToClients(target, atof(sep->arg[2]), atof(sep->arg[3]), atof(sep->arg[4]), atof(sep->arg[5]), atoi(sep->arg[6]), ClientRangeAny);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
c->Message(0, "Usage: #movement stats/clearstats/walkto/runto/rotateto/stop");
|
c->Message(0, "Usage: #movement stats/clearstats/walkto/runto/rotateto/stop/packet");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3438,6 +3438,22 @@ void EntityList::ProcessMove(NPC *n, float x, float y, float z) {
|
|||||||
args.push_back(&evt.area_type);
|
args.push_back(&evt.area_type);
|
||||||
parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0, &args);
|
parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zone->watermap) {
|
||||||
|
auto mode = n->GetFlyMode();
|
||||||
|
if (mode == GravityBehavior::Ground) {
|
||||||
|
if (zone->watermap->InLiquid(glm::vec3(x, y, z)))
|
||||||
|
{
|
||||||
|
n->SetFlyMode(GravityBehavior::Water);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mode == GravityBehavior::Water) {
|
||||||
|
if (!zone->watermap->InLiquid(glm::vec3(x, y, z)))
|
||||||
|
{
|
||||||
|
n->SetFlyMode(GravityBehavior::Ground);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityList::AddArea(int id, int type, float min_x, float max_x, float min_y,
|
void EntityList::AddArea(int id, int type, float min_x, float max_x, float min_y,
|
||||||
|
|||||||
@ -1367,15 +1367,7 @@ void Mob::AI_Process() {
|
|||||||
auto targetPosition = glm::vec3(target->GetX(), target->GetY(), target->GetZ());
|
auto targetPosition = glm::vec3(target->GetX(), target->GetY(), target->GetZ());
|
||||||
if (!zone->watermap->InLiquid(targetPosition)) {
|
if (!zone->watermap->InLiquid(targetPosition)) {
|
||||||
Mob *tar = hate_list.GetEntWithMostHateOnList(this);
|
Mob *tar = hate_list.GetEntWithMostHateOnList(this);
|
||||||
if (tar == target) {
|
if (tar != nullptr && tar != target) {
|
||||||
WipeHateList();
|
|
||||||
Heal();
|
|
||||||
BuffFadeAll();
|
|
||||||
AI_walking_timer->Start(100);
|
|
||||||
time_until_can_move = Timer::GetCurrentTime();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (tar != nullptr) {
|
|
||||||
SetTarget(tar);
|
SetTarget(tar);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -179,12 +179,12 @@ public:
|
|||||||
double distance_moved = frame_time * current_speed * 0.4f * 1.45f;
|
double distance_moved = frame_time * current_speed * 0.4f * 1.45f;
|
||||||
|
|
||||||
if (distance_moved > len) {
|
if (distance_moved > len) {
|
||||||
m->SetPosition(m_move_to_x, m_move_to_y, m_move_to_z);
|
|
||||||
|
|
||||||
if (m->IsNPC()) {
|
if (m->IsNPC()) {
|
||||||
entity_list.ProcessMove(m->CastToNPC(), m_move_to_x, m_move_to_y, m_move_to_z);
|
entity_list.ProcessMove(m->CastToNPC(), m_move_to_x, m_move_to_y, m_move_to_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m->SetPosition(m_move_to_x, m_move_to_y, m_move_to_z);
|
||||||
|
|
||||||
m->TryFixZ();
|
m->TryFixZ();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -196,11 +196,11 @@ public:
|
|||||||
double start_z = m_move_to_z - m_total_v_dist;
|
double start_z = m_move_to_z - m_total_v_dist;
|
||||||
double z_at_pos = start_z + (m_total_v_dist * (total_distance_traveled / m_total_h_dist));
|
double z_at_pos = start_z + (m_total_v_dist * (total_distance_traveled / m_total_h_dist));
|
||||||
|
|
||||||
m->SetPosition(npos.x, npos.y, z_at_pos);
|
|
||||||
|
|
||||||
if (m->IsNPC()) {
|
if (m->IsNPC()) {
|
||||||
entity_list.ProcessMove(m->CastToNPC(), npos.x, npos.y, z_at_pos);
|
entity_list.ProcessMove(m->CastToNPC(), npos.x, npos.y, z_at_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m->SetPosition(npos.x, npos.y, z_at_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -210,7 +210,7 @@ public:
|
|||||||
return m_started;
|
return m_started;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
|
||||||
double m_move_to_x;
|
double m_move_to_x;
|
||||||
double m_move_to_y;
|
double m_move_to_y;
|
||||||
@ -224,6 +224,101 @@ private:
|
|||||||
double m_total_v_dist;
|
double m_total_v_dist;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SwimToCommand : public MoveToCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SwimToCommand(float x, float y, float z, MobMovementMode mode) : MoveToCommand(x, y, z, mode) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Process(MobMovementManager *mgr, Mob *m)
|
||||||
|
{
|
||||||
|
if (!m->IsAIControlled()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Send a movement packet when you start moving
|
||||||
|
double current_time = static_cast<double>(Timer::GetCurrentTime()) / 1000.0;
|
||||||
|
int current_speed = 0;
|
||||||
|
|
||||||
|
if (m_move_to_mode == MovementRunning) {
|
||||||
|
current_speed = m->GetRunspeed();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
current_speed = m->GetWalkspeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_started) {
|
||||||
|
m_started = true;
|
||||||
|
//rotate to the point
|
||||||
|
m->SetMoving(true);
|
||||||
|
m->SetHeading(m->CalculateHeadingToTarget(m_move_to_x, m_move_to_y));
|
||||||
|
|
||||||
|
m_last_sent_speed = current_speed;
|
||||||
|
m_last_sent_time = current_time;
|
||||||
|
m_total_h_dist = DistanceNoZ(m->GetPosition(), glm::vec4(m_move_to_x, m_move_to_z, 0.0f, 0.0f));
|
||||||
|
m_total_v_dist = m_move_to_z - m->GetZ();
|
||||||
|
mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//When speed changes
|
||||||
|
if (current_speed != m_last_sent_speed) {
|
||||||
|
m_last_sent_speed = current_speed;
|
||||||
|
m_last_sent_time = current_time;
|
||||||
|
mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If x seconds have passed without sending an update.
|
||||||
|
if (current_time - m_last_sent_time >= 1.5) {
|
||||||
|
m_last_sent_speed = current_speed;
|
||||||
|
m_last_sent_time = current_time;
|
||||||
|
mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &p = m->GetPosition();
|
||||||
|
glm::vec2 tar(m_move_to_x, m_move_to_y);
|
||||||
|
glm::vec2 pos(p.x, p.y);
|
||||||
|
double len = glm::distance(pos, tar);
|
||||||
|
if (len == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m->SetMoved(true);
|
||||||
|
|
||||||
|
glm::vec2 dir = tar - pos;
|
||||||
|
glm::vec2 ndir = glm::normalize(dir);
|
||||||
|
double distance_moved = frame_time * current_speed * 0.4f * 1.45f;
|
||||||
|
|
||||||
|
if (distance_moved > len) {
|
||||||
|
if (m->IsNPC()) {
|
||||||
|
entity_list.ProcessMove(m->CastToNPC(), m_move_to_x, m_move_to_y, m_move_to_z);
|
||||||
|
}
|
||||||
|
|
||||||
|
m->SetPosition(m_move_to_x, m_move_to_y, m_move_to_z);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
glm::vec2 npos = pos + (ndir * static_cast<float>(distance_moved));
|
||||||
|
|
||||||
|
len -= distance_moved;
|
||||||
|
double total_distance_traveled = m_total_h_dist - len;
|
||||||
|
double start_z = m_move_to_z - m_total_v_dist;
|
||||||
|
double z_at_pos = start_z + (m_total_v_dist * (total_distance_traveled / m_total_h_dist));
|
||||||
|
|
||||||
|
if (m->IsNPC()) {
|
||||||
|
entity_list.ProcessMove(m->CastToNPC(), npos.x, npos.y, z_at_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
m->SetPosition(npos.x, npos.y, z_at_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class TeleportToCommand : public IMovementCommand
|
class TeleportToCommand : public IMovementCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -243,14 +338,14 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->SetPosition(m_teleport_to_x, m_teleport_to_y, m_teleport_to_z);
|
|
||||||
m->SetHeading(mgr->FixHeading(m_teleport_to_heading));
|
|
||||||
mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny);
|
|
||||||
|
|
||||||
if (m->IsNPC()) {
|
if (m->IsNPC()) {
|
||||||
entity_list.ProcessMove(m->CastToNPC(), m_teleport_to_x, m_teleport_to_y, m_teleport_to_z);
|
entity_list.ProcessMove(m->CastToNPC(), m_teleport_to_x, m_teleport_to_y, m_teleport_to_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m->SetPosition(m_teleport_to_x, m_teleport_to_y, m_teleport_to_z);
|
||||||
|
m->SetHeading(mgr->FixHeading(m_teleport_to_heading));
|
||||||
|
mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,24 +698,34 @@ void MobMovementManager::FillCommandStruct(PlayerPositionUpdateServer_Struct *sp
|
|||||||
|
|
||||||
void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mode)
|
void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mode)
|
||||||
{
|
{
|
||||||
//If who is underwater & xyz is underwater & who can see xyz
|
if (!zone->HasMap() || !zone->HasWaterMap()) {
|
||||||
//Create a route directly from who to xyz
|
|
||||||
//else
|
|
||||||
//Create Route
|
|
||||||
if (zone->HasMap() && zone->HasWaterMap()) {
|
|
||||||
if (zone->watermap->InLiquid(who->GetPosition()) && zone->watermap->InLiquid(glm::vec3(x, y, z)) && zone->zonemap->CheckLoS(who->GetPosition(), glm::vec3(x, y, z))) {
|
|
||||||
auto iter = _impl->Entries.find(who);
|
auto iter = _impl->Entries.find(who);
|
||||||
auto &ent = (*iter);
|
auto &ent = (*iter);
|
||||||
|
|
||||||
PushMoveTo(ent.second, x, y, z, mode);
|
PushMoveTo(ent.second, x, y, z, mode);
|
||||||
PushStopMoving(ent.second);
|
PushStopMoving(ent.second);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zone->watermap->InLiquid(who->GetPosition())
|
||||||
|
&& zone->watermap->InLiquid(glm::vec3(x, y, z))
|
||||||
|
&& zone->zonemap->CheckLoS(who->GetPosition(), glm::vec3(x, y, z))) {
|
||||||
|
auto iter = _impl->Entries.find(who);
|
||||||
|
auto &ent = (*iter);
|
||||||
|
|
||||||
|
PushSwimTo(ent.second, x, y, z, mode);
|
||||||
|
PushStopMoving(ent.second);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool partial = false;
|
bool partial = false;
|
||||||
bool stuck = false;
|
bool stuck = false;
|
||||||
auto route = zone->pathing->FindRoute(glm::vec3(who->GetX(), who->GetY(), who->GetZ()), glm::vec3(x, y, z), partial, stuck);
|
IPathfinder::IPath route;
|
||||||
|
if (who->IsUnderwaterOnly()) {
|
||||||
|
route = zone->pathing->FindRoute(glm::vec3(who->GetX(), who->GetY(), who->GetZ()), glm::vec3(x, y, z), partial, stuck, PathingWater | PathingLava | PathingVWater | PathingPortal | PathingPrefer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
route = zone->pathing->FindRoute(glm::vec3(who->GetX(), who->GetY(), who->GetZ()), glm::vec3(x, y, z), partial, stuck, PathingNotDisabled ^ PathingZoneLine);
|
||||||
|
}
|
||||||
|
|
||||||
//if route empty or only has two points, and we have los, then just force npc to move to location
|
//if route empty or only has two points, and we have los, then just force npc to move to location
|
||||||
if (route.size() < 3) {
|
if (route.size() < 3) {
|
||||||
@ -628,16 +733,28 @@ void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMove
|
|||||||
auto &ent = (*iter);
|
auto &ent = (*iter);
|
||||||
if (zone->zonemap->CheckLoS(who->GetPosition(), glm::vec3(x, y, z)) && route.size() > 0)
|
if (zone->zonemap->CheckLoS(who->GetPosition(), glm::vec3(x, y, z)) && route.size() > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto &first = route.front();
|
auto &first = route.front();
|
||||||
auto &last = route.back();
|
auto &last = route.back();
|
||||||
|
|
||||||
|
if (zone->watermap->InLiquid(who->GetPosition())) {
|
||||||
|
PushSwimTo(ent.second, x, y, z, mode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
PushMoveTo(ent.second, x, y, z, mode);
|
PushMoveTo(ent.second, x, y, z, mode);
|
||||||
|
}
|
||||||
|
|
||||||
PushStopMoving(ent.second);
|
PushStopMoving(ent.second);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(route.size() < 2)
|
else if(route.size() < 2)
|
||||||
{
|
{
|
||||||
|
if (zone->watermap->InLiquid(who->GetPosition())) {
|
||||||
|
PushSwimTo(ent.second, x, y, z, mode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PushMoveTo(ent.second, x, y, z, mode);
|
||||||
|
}
|
||||||
|
|
||||||
PushMoveTo(ent.second, x, y, z, mode);
|
PushMoveTo(ent.second, x, y, z, mode);
|
||||||
PushStopMoving(ent.second);
|
PushStopMoving(ent.second);
|
||||||
return;
|
return;
|
||||||
@ -699,22 +816,16 @@ void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMove
|
|||||||
first_node = false;
|
first_node = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if underwater only mob and node -> node + 1 is moving to land (terminate route, npc will go to the point where it would normally exit the water but no further)
|
|
||||||
if (who->IsUnderwaterOnly()) {
|
|
||||||
if (zone->HasWaterMap() && !zone->watermap->InLiquid(next_node.pos)) {
|
|
||||||
PushStopMoving(ent.second);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//move to / teleport to node + 1
|
//move to / teleport to node + 1
|
||||||
if (next_node.teleport && next_node.pos.x != 0.0f && next_node.pos.y != 0.0f) {
|
if (next_node.teleport && next_node.pos.x != 0.0f && next_node.pos.y != 0.0f) {
|
||||||
PushTeleportTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z,
|
PushTeleportTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z,
|
||||||
CalculateHeadingAngleBetweenPositions(current_node.pos.x, current_node.pos.y, next_node.pos.x, next_node.pos.y));
|
CalculateHeadingAngleBetweenPositions(current_node.pos.x, current_node.pos.y, next_node.pos.x, next_node.pos.y));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (next_node.pos.x != 0.0f && next_node.pos.y != 0.0f)
|
if (zone->watermap->InLiquid(previous_pos)) {
|
||||||
{
|
PushSwimTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z, mode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
PushMoveTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z, mode);
|
PushMoveTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -739,6 +850,11 @@ void MobMovementManager::PushMoveTo(MobMovementEntry &ent, float x, float y, flo
|
|||||||
ent.Commands.push_back(std::unique_ptr<IMovementCommand>(new MoveToCommand(x, y, z, mode)));
|
ent.Commands.push_back(std::unique_ptr<IMovementCommand>(new MoveToCommand(x, y, z, mode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MobMovementManager::PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode)
|
||||||
|
{
|
||||||
|
ent.Commands.push_back(std::unique_ptr<IMovementCommand>(new SwimToCommand(x, y, z, mode)));
|
||||||
|
}
|
||||||
|
|
||||||
void MobMovementManager::PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mode)
|
void MobMovementManager::PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mode)
|
||||||
{
|
{
|
||||||
auto from = FixHeading(who->GetHeading());
|
auto from = FixHeading(who->GetHeading());
|
||||||
|
|||||||
@ -60,6 +60,7 @@ private:
|
|||||||
void UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mode);
|
void UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mode);
|
||||||
void PushTeleportTo(MobMovementEntry &ent, float x, float y, float z, float heading);
|
void PushTeleportTo(MobMovementEntry &ent, float x, float y, float z, float heading);
|
||||||
void PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode);
|
void PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode);
|
||||||
|
void PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode);
|
||||||
void PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mode);
|
void PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mode);
|
||||||
void PushStopMoving(MobMovementEntry &ent);
|
void PushStopMoving(MobMovementEntry &ent);
|
||||||
|
|
||||||
|
|||||||
15
zone/npc.cpp
15
zone/npc.cpp
@ -39,6 +39,7 @@
|
|||||||
#include "spawn2.h"
|
#include "spawn2.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "water_map.h"
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -412,6 +413,20 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, Gravit
|
|||||||
AISpellVar.idle_no_sp_recast_min = RuleI(Spells, AI_IdleNoSpellMinRecast);
|
AISpellVar.idle_no_sp_recast_min = RuleI(Spells, AI_IdleNoSpellMinRecast);
|
||||||
AISpellVar.idle_no_sp_recast_max = RuleI(Spells, AI_IdleNoSpellMaxRecast);
|
AISpellVar.idle_no_sp_recast_max = RuleI(Spells, AI_IdleNoSpellMaxRecast);
|
||||||
AISpellVar.idle_beneficial_chance = RuleI(Spells, AI_IdleBeneficialChance);
|
AISpellVar.idle_beneficial_chance = RuleI(Spells, AI_IdleBeneficialChance);
|
||||||
|
|
||||||
|
if (zone->watermap) {
|
||||||
|
auto mode = GetFlyMode();
|
||||||
|
if (mode == GravityBehavior::Ground) {
|
||||||
|
if (zone->watermap->InLiquid(m_Position)) {
|
||||||
|
SetFlyMode(GravityBehavior::Water);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mode == GravityBehavior::Water) {
|
||||||
|
if (!zone->watermap->InLiquid(m_Position)) {
|
||||||
|
SetFlyMode(GravityBehavior::Ground);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NPC::~NPC()
|
NPC::~NPC()
|
||||||
|
|||||||
@ -6,6 +6,24 @@
|
|||||||
class Client;
|
class Client;
|
||||||
class Seperator;
|
class Seperator;
|
||||||
|
|
||||||
|
enum PathingPolyFlags
|
||||||
|
{
|
||||||
|
PathingNormal = 1,
|
||||||
|
PathingWater = 2,
|
||||||
|
PathingLava = 4,
|
||||||
|
PathingZoneLine = 8,
|
||||||
|
PathingPvP = 16,
|
||||||
|
PathingSlime = 32,
|
||||||
|
PathingIce = 64,
|
||||||
|
PathingVWater = 128,
|
||||||
|
PathingGeneralArea = 256,
|
||||||
|
PathingPortal = 512,
|
||||||
|
PathingPrefer = 1024,
|
||||||
|
PathingDisabled = 2048,
|
||||||
|
PathingAll = 65535,
|
||||||
|
PathingNotDisabled = PathingAll ^ PathingDisabled
|
||||||
|
};
|
||||||
|
|
||||||
class IPathfinder
|
class IPathfinder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -29,7 +47,7 @@ public:
|
|||||||
IPathfinder() { }
|
IPathfinder() { }
|
||||||
virtual ~IPathfinder() { }
|
virtual ~IPathfinder() { }
|
||||||
|
|
||||||
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck) = 0;
|
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck, int flags = PathingNotDisabled) = 0;
|
||||||
virtual glm::vec3 GetRandomLocation(const glm::vec3 &start) = 0;
|
virtual glm::vec3 GetRandomLocation(const glm::vec3 &start) = 0;
|
||||||
virtual void DebugCommand(Client *c, const Seperator *sep) = 0;
|
virtual void DebugCommand(Client *c, const Seperator *sep) = 0;
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@ PathfinderNavmesh::~PathfinderNavmesh()
|
|||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck)
|
IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck, int flags)
|
||||||
{
|
{
|
||||||
partial = false;
|
partial = false;
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const gl
|
|||||||
glm::vec3 dest_location(end.x, end.z, end.y);
|
glm::vec3 dest_location(end.x, end.z, end.y);
|
||||||
|
|
||||||
dtQueryFilter filter;
|
dtQueryFilter filter;
|
||||||
filter.setIncludeFlags(65535U ^ 2048);
|
filter.setIncludeFlags(flags);
|
||||||
filter.setAreaCost(0, 1.0f); //Normal
|
filter.setAreaCost(0, 1.0f); //Normal
|
||||||
filter.setAreaCost(1, 3.0f); //Water
|
filter.setAreaCost(1, 3.0f); //Water
|
||||||
filter.setAreaCost(2, 5.0f); //Lava
|
filter.setAreaCost(2, 5.0f); //Lava
|
||||||
|
|||||||
@ -9,7 +9,7 @@ public:
|
|||||||
PathfinderNavmesh(const std::string &path);
|
PathfinderNavmesh(const std::string &path);
|
||||||
virtual ~PathfinderNavmesh();
|
virtual ~PathfinderNavmesh();
|
||||||
|
|
||||||
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck);
|
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck, int flags = PathingNotDisabled);
|
||||||
virtual glm::vec3 GetRandomLocation(const glm::vec3 &start);
|
virtual glm::vec3 GetRandomLocation(const glm::vec3 &start);
|
||||||
virtual void DebugCommand(Client *c, const Seperator *sep);
|
virtual void DebugCommand(Client *c, const Seperator *sep);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#include "pathfinder_null.h"
|
#include "pathfinder_null.h"
|
||||||
|
|
||||||
IPathfinder::IPath PathfinderNull::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck)
|
IPathfinder::IPath PathfinderNull::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck, int flags)
|
||||||
{
|
{
|
||||||
partial = false;
|
partial = false;
|
||||||
stuck = false;
|
stuck = false;
|
||||||
|
|||||||
@ -8,7 +8,7 @@ public:
|
|||||||
PathfinderNull() { }
|
PathfinderNull() { }
|
||||||
virtual ~PathfinderNull() { }
|
virtual ~PathfinderNull() { }
|
||||||
|
|
||||||
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck);
|
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck, int flags = PathingNotDisabled);
|
||||||
virtual glm::vec3 GetRandomLocation(const glm::vec3 &start);
|
virtual glm::vec3 GetRandomLocation(const glm::vec3 &start);
|
||||||
virtual void DebugCommand(Client *c, const Seperator *sep) { }
|
virtual void DebugCommand(Client *c, const Seperator *sep) { }
|
||||||
};
|
};
|
||||||
|
|||||||
@ -114,7 +114,7 @@ PathfinderWaypoint::~PathfinderWaypoint()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
IPathfinder::IPath PathfinderWaypoint::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck)
|
IPathfinder::IPath PathfinderWaypoint::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck, int flags)
|
||||||
{
|
{
|
||||||
stuck = false;
|
stuck = false;
|
||||||
partial = false;
|
partial = false;
|
||||||
|
|||||||
@ -11,7 +11,7 @@ public:
|
|||||||
PathfinderWaypoint(const std::string &path);
|
PathfinderWaypoint(const std::string &path);
|
||||||
virtual ~PathfinderWaypoint();
|
virtual ~PathfinderWaypoint();
|
||||||
|
|
||||||
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck);
|
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &stuck, int flags = PathingNotDisabled);
|
||||||
virtual glm::vec3 GetRandomLocation(const glm::vec3 &start);
|
virtual glm::vec3 GetRandomLocation(const glm::vec3 &start);
|
||||||
virtual void DebugCommand(Client *c, const Seperator *sep);
|
virtual void DebugCommand(Client *c, const Seperator *sep);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user