mirror of
https://github.com/EQEmu/Server.git
synced 2026-01-07 06:13:52 +00:00
Water work and work with grids (still not perfect but i think its the ai code)
This commit is contained in:
parent
f76fffe622
commit
973abef1b0
@ -2667,12 +2667,6 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
||||
if (!zone->watermap->InLiquid(glm::vec3(other->GetPosition()))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// first add self
|
||||
|
||||
// The damage on the hate list is used to award XP to the killer. This check is to prevent Killstealing.
|
||||
|
||||
@ -1061,6 +1061,7 @@ public:
|
||||
void SetCurrentWP(uint16 waypoint) { cur_wp = waypoint; }
|
||||
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther) { return FACTION_INDIFFERENT; }
|
||||
|
||||
virtual const bool IsUnderwaterOnly() const { return false; }
|
||||
inline bool IsTrackable() const { return(trackable); }
|
||||
Timer* GetAIThinkTimer() { return AI_think_timer.get(); }
|
||||
Timer* GetAIMovementTimer() { return AI_movement_timer.get(); }
|
||||
|
||||
@ -1710,7 +1710,7 @@ void NPC::AI_DoMovement() {
|
||||
|
||||
SetWaypointPause();
|
||||
SetAppearance(eaStanding, false);
|
||||
if (m_CurrentWayPoint.w >= 0.0) {
|
||||
if (cur_wp_pause > 0 && m_CurrentWayPoint.w >= 0.0) {
|
||||
RotateTo(m_CurrentWayPoint.w);
|
||||
}
|
||||
|
||||
@ -1756,7 +1756,7 @@ void NPC::AI_DoMovement() {
|
||||
|
||||
}
|
||||
else if (IsGuarding()) {
|
||||
bool at_gp = IsPositionEqualWithinCertainZ(m_Position, m_GuardPoint, 5.0f);
|
||||
bool at_gp = IsPositionEqualWithinCertainZ(m_Position, m_GuardPoint, 15.0f);
|
||||
|
||||
if (at_gp) {
|
||||
|
||||
|
||||
@ -46,28 +46,29 @@ public:
|
||||
|
||||
auto rotate_to_speed = m_rotate_to_mode == MovementRunning ? 50.0 : 16.0; //todo: get this from mob
|
||||
|
||||
auto from = FixHeading(m->GetHeading());
|
||||
auto to = FixHeading(m_rotate_to);
|
||||
auto diff = to - from;
|
||||
|
||||
while (diff < -256.0) {
|
||||
diff += 512.0;
|
||||
}
|
||||
|
||||
while (diff > 256) {
|
||||
diff -= 512.0;
|
||||
}
|
||||
|
||||
auto dist = std::abs(diff);
|
||||
|
||||
if (!m_started) {
|
||||
m_started = true;
|
||||
m->SetMoving(true);
|
||||
|
||||
if (rotate_to_speed > 0.0 && rotate_to_speed <= 25.0) { //send basic rotation
|
||||
if (dist > 15.0f && rotate_to_speed > 0.0 && rotate_to_speed <= 25.0) { //send basic rotation
|
||||
mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, m_rotate_to_dir * rotate_to_speed, 0, ClientRangeClose);
|
||||
}
|
||||
}
|
||||
|
||||
auto from = FixHeading(m->GetHeading());
|
||||
auto to = FixHeading(m_rotate_to);
|
||||
auto diff = to - from;
|
||||
|
||||
while (diff < -256.0) {
|
||||
diff += 512.0;
|
||||
}
|
||||
|
||||
while (diff > 256) {
|
||||
diff -= 512.0;
|
||||
}
|
||||
|
||||
auto dist = std::abs(diff);
|
||||
auto td = rotate_to_speed * 19.0 * frame_time;
|
||||
|
||||
if (td >= dist) {
|
||||
@ -604,51 +605,106 @@ void MobMovementManager::FillCommandStruct(PlayerPositionUpdateServer_Struct *sp
|
||||
|
||||
void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mode)
|
||||
{
|
||||
//If who is underwater & xyz is underwater & who can see xyz
|
||||
//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 &ent = (*iter);
|
||||
|
||||
PushMoveTo(ent.second, x, y, z, mode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool partial = false;
|
||||
bool stuck = false;
|
||||
auto route = zone->pathing->FindRoute(glm::vec3(who->GetX(), who->GetY(), who->GetZ()), glm::vec3(x, y, z), partial, stuck);
|
||||
|
||||
|
||||
//if route empty then return
|
||||
if (route.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto &first = route.front();
|
||||
auto &last = route.back();
|
||||
|
||||
//if who is already at the first node, then cull it
|
||||
if (IsPositionEqualWithinCertainZ(glm::vec3(who->GetX(), who->GetY(), who->GetZ()), first.pos, 5.0f)) {
|
||||
route.pop_front();
|
||||
}
|
||||
|
||||
if (route.empty()) {
|
||||
return;
|
||||
if (zone->HasWaterMap()) {
|
||||
//If who is underwater & who is not at the first node
|
||||
//Add node at who
|
||||
if (!IsPositionEqualWithinCertainZ(glm::vec3(who->GetX(), who->GetY(), who->GetZ()), first.pos, 5.0f)
|
||||
&& zone->watermap->InLiquid(who->GetPosition()))
|
||||
{
|
||||
IPathfinder::IPathNode node(who->GetPosition());
|
||||
route.push_front(node);
|
||||
}
|
||||
|
||||
//If xyz is underwater & xyz is not at the last node
|
||||
//Add node at xyz
|
||||
if (!IsPositionEqualWithinCertainZ(glm::vec3(x, y, z), last.pos, 5.0f)
|
||||
&& zone->watermap->InLiquid(glm::vec3(x, y, z)))
|
||||
{
|
||||
IPathfinder::IPathNode node(glm::vec3(x, y, z));
|
||||
route.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
//adjust route
|
||||
AdjustRoute(route, who->GetFlyMode(), who->GetZOffset());
|
||||
|
||||
auto iter = _impl->Entries.find(who);
|
||||
auto &ent = (*iter);
|
||||
|
||||
first = route.front();
|
||||
//If mode = walking then rotateto first node (if possible, live does this)
|
||||
if (mode == MovementWalking) {
|
||||
auto h = who->CalculateHeadingToTarget(first.pos.x, first.pos.y);
|
||||
PushRotateTo(ent.second, who, h, mode);
|
||||
}
|
||||
|
||||
//for each node create a moveto/teleport command
|
||||
auto eiter = _impl->Entries.find(who);
|
||||
auto &ent = (*eiter);
|
||||
auto iter = route.begin();
|
||||
glm::vec3 previous_pos(who->GetX(), who->GetY(), who->GetZ());
|
||||
for (auto &node : route) {
|
||||
if (node.teleport) {
|
||||
PushTeleportTo(ent.second, node.pos.x, node.pos.y, node.pos.z,
|
||||
CalculateHeadingAngleBetweenPositions(previous_pos.x, previous_pos.y, node.pos.x, node.pos.y));
|
||||
bool first_node = true;
|
||||
|
||||
//for each node
|
||||
while (iter != route.end()) {
|
||||
auto ¤t_node = (*iter);
|
||||
|
||||
iter++;
|
||||
|
||||
if (iter == route.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
previous_pos = current_node.pos;
|
||||
auto &next_node = (*iter);
|
||||
|
||||
if (first_node) {
|
||||
|
||||
if (mode == MovementWalking) {
|
||||
auto h = who->CalculateHeadingToTarget(next_node.pos.x, next_node.pos.y);
|
||||
PushRotateTo(ent.second, who, h, mode);
|
||||
}
|
||||
|
||||
first_node = false;
|
||||
}
|
||||
//yet rotate to node + 1
|
||||
//auto h = CalculateHeadingAngleBetweenPositions(current_node.pos.x, current_node.pos.y, next_node.pos.x, next_node.pos.z);
|
||||
//PushRotateTo(ent.second, who, h, mode);
|
||||
|
||||
//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
|
||||
if (next_node.teleport) {
|
||||
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));
|
||||
}
|
||||
else {
|
||||
PushMoveTo(ent.second, node.pos.x, node.pos.y, node.pos.z, mode);
|
||||
PushMoveTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z, mode);
|
||||
}
|
||||
|
||||
previous_pos = node.pos;
|
||||
}
|
||||
|
||||
//if stuck then handle stuck
|
||||
if (stuck) {
|
||||
PushTeleportTo(ent.second, x, y, z,
|
||||
CalculateHeadingAngleBetweenPositions(previous_pos.x, previous_pos.y, x, y));
|
||||
|
||||
@ -381,7 +381,7 @@ public:
|
||||
/* Only allows players that killed corpse to loot */
|
||||
const bool HasPrivateCorpse() const { return NPCTypedata->private_corpse; }
|
||||
|
||||
const bool IsUnderwaterOnly() const { return NPCTypedata->underwater; }
|
||||
virtual const bool IsUnderwaterOnly() const { return NPCTypedata->underwater; }
|
||||
const char* GetRawNPCTypeName() const { return NPCTypedata->name; }
|
||||
|
||||
void ChangeLastName(const char* in_lastname);
|
||||
|
||||
@ -392,7 +392,6 @@ void NPC::SetWaypointPause()
|
||||
|
||||
if (cur_wp_pause == 0) {
|
||||
AI_walking_timer->Start(100);
|
||||
AI_walking_timer->Trigger();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user