mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-01 03:02:26 +00:00
Changes to various path finding behavior
This commit is contained in:
parent
fd7b6deafa
commit
8f0051db8d
@ -126,7 +126,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
|||||||
(npc_dup != nullptr) ? npc_dup : npc_type, //make sure we give the NPC the correct data pointer
|
(npc_dup != nullptr) ? npc_dup : npc_type, //make sure we give the NPC the correct data pointer
|
||||||
0,
|
0,
|
||||||
GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f),
|
GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f),
|
||||||
GravityBehavior::Ground);
|
GravityBehavior::Water);
|
||||||
|
|
||||||
if (followme)
|
if (followme)
|
||||||
swarm_pet_npc->SetFollowID(GetID());
|
swarm_pet_npc->SetFollowID(GetID());
|
||||||
@ -225,7 +225,7 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
|
|||||||
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
|
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
|
||||||
0,
|
0,
|
||||||
GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f),
|
GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f),
|
||||||
GravityBehavior::Ground);
|
GravityBehavior::Water);
|
||||||
|
|
||||||
if (followme)
|
if (followme)
|
||||||
swarm_pet_npc->SetFollowID(GetID());
|
swarm_pet_npc->SetFollowID(GetID());
|
||||||
@ -413,7 +413,7 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration)
|
|||||||
make_npc->d_melee_texture1 = 0;
|
make_npc->d_melee_texture1 = 0;
|
||||||
make_npc->d_melee_texture2 = 0;
|
make_npc->d_melee_texture2 = 0;
|
||||||
|
|
||||||
auto npca = new NPC(make_npc, 0, GetPosition(), GravityBehavior::Ground);
|
auto npca = new NPC(make_npc, 0, GetPosition(), GravityBehavior::Water);
|
||||||
|
|
||||||
if(!npca->GetSwarmInfo()){
|
if(!npca->GetSwarmInfo()){
|
||||||
auto nSI = new SwarmPet;
|
auto nSI = new SwarmPet;
|
||||||
|
|||||||
@ -954,7 +954,7 @@ bool Mob::CombatRange(Mob* other)
|
|||||||
if (_DistNoRoot <= size_mod)
|
if (_DistNoRoot <= size_mod)
|
||||||
{
|
{
|
||||||
//A hack to kill an exploit till we get something better.
|
//A hack to kill an exploit till we get something better.
|
||||||
if (flymode == GravityBehavior::Ground && _zDist > 500 && !CheckLastLosState()) {
|
if (flymode != GravityBehavior::Flying && _zDist > 500 && !CheckLastLosState()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6281,7 +6281,7 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
|
|||||||
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
|
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
|
||||||
0,
|
0,
|
||||||
GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f),
|
GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f),
|
||||||
GravityBehavior::Ground);
|
GravityBehavior::Water);
|
||||||
|
|
||||||
if(!swarm_pet_npc->GetSwarmInfo()){
|
if(!swarm_pet_npc->GetSwarmInfo()){
|
||||||
auto nSI = new SwarmPet;
|
auto nSI = new SwarmPet;
|
||||||
|
|||||||
@ -2611,7 +2611,7 @@ void command_npctypespawn(Client *c, const Seperator *sep)
|
|||||||
const NPCType* tmp = 0;
|
const NPCType* tmp = 0;
|
||||||
if ((tmp = database.LoadNPCTypesData(atoi(sep->arg[1])))) {
|
if ((tmp = database.LoadNPCTypesData(atoi(sep->arg[1])))) {
|
||||||
//tmp->fixedZ = 1;
|
//tmp->fixedZ = 1;
|
||||||
auto npc = new NPC(tmp, 0, c->GetPosition(), GravityBehavior::Ground);
|
auto npc = new NPC(tmp, 0, c->GetPosition(), GravityBehavior::Water);
|
||||||
if (npc && sep->IsNumber(2))
|
if (npc && sep->IsNumber(2))
|
||||||
npc->SetNPCFactionID(atoi(sep->arg[2]));
|
npc->SetNPCFactionID(atoi(sep->arg[2]));
|
||||||
|
|
||||||
|
|||||||
@ -3438,22 +3438,6 @@ 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,
|
||||||
|
|||||||
@ -284,7 +284,7 @@ void Client::GoFish()
|
|||||||
if (tmp != nullptr) {
|
if (tmp != nullptr) {
|
||||||
auto positionNPC = GetPosition();
|
auto positionNPC = GetPosition();
|
||||||
positionNPC.x = positionNPC.x + 3;
|
positionNPC.x = positionNPC.x + 3;
|
||||||
auto npc = new NPC(tmp, nullptr, positionNPC, GravityBehavior::Ground);
|
auto npc = new NPC(tmp, nullptr, positionNPC, GravityBehavior::Water);
|
||||||
npc->AddLootTable();
|
npc->AddLootTable();
|
||||||
if (npc->DropsGlobalLoot())
|
if (npc->DropsGlobalLoot())
|
||||||
npc->CheckGlobalLootTables();
|
npc->CheckGlobalLootTables();
|
||||||
|
|||||||
@ -335,15 +335,6 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto hateEntryPosition = glm::vec3(cur->entity_on_hatelist->GetX(), cur->entity_on_hatelist->GetY(), cur->entity_on_hatelist->GetZ());
|
|
||||||
if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
|
||||||
if (!zone->watermap->InLiquid(hateEntryPosition)) {
|
|
||||||
skipped_count++;
|
|
||||||
++iterator;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur->entity_on_hatelist->Sanctuary()) {
|
if (cur->entity_on_hatelist->Sanctuary()) {
|
||||||
if (hate == -1)
|
if (hate == -1)
|
||||||
{
|
{
|
||||||
@ -474,14 +465,6 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
|
||||||
if(!zone->watermap->InLiquid(glm::vec3(cur->entity_on_hatelist->GetPosition()))) {
|
|
||||||
skipped_count++;
|
|
||||||
++iterator;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur->entity_on_hatelist != nullptr && ((cur->stored_hate_amount > hate) || cur->is_entity_frenzy))
|
if (cur->entity_on_hatelist != nullptr && ((cur->stored_hate_amount > hate) || cur->is_entity_frenzy))
|
||||||
{
|
{
|
||||||
top_hate = cur->entity_on_hatelist;
|
top_hate = cur->entity_on_hatelist;
|
||||||
|
|||||||
@ -30,7 +30,7 @@ std::map<uint16, const NPCType *> Horse::horse_types;
|
|||||||
LinkedList<NPCType *> horses_auto_delete;
|
LinkedList<NPCType *> horses_auto_delete;
|
||||||
|
|
||||||
Horse::Horse(Client *_owner, uint16 spell_id, const glm::vec4& position)
|
Horse::Horse(Client *_owner, uint16 spell_id, const glm::vec4& position)
|
||||||
: NPC(GetHorseType(spell_id), nullptr, position, GravityBehavior::Ground)
|
: NPC(GetHorseType(spell_id), nullptr, position, GravityBehavior::Water)
|
||||||
{
|
{
|
||||||
//give the horse its proper name.
|
//give the horse its proper name.
|
||||||
strn0cpy(name, _owner->GetCleanName(), 55);
|
strn0cpy(name, _owner->GetCleanName(), 55);
|
||||||
|
|||||||
@ -1499,7 +1499,7 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
|
|||||||
LuaCreateNPCParse(no_target_hotkey, bool, false);
|
LuaCreateNPCParse(no_target_hotkey, bool, false);
|
||||||
LuaCreateNPCParse(raid_target, bool, false);
|
LuaCreateNPCParse(raid_target, bool, false);
|
||||||
|
|
||||||
NPC* npc = new NPC(npc_type, nullptr, glm::vec4(x, y, z, heading), GravityBehavior::Ground);
|
NPC* npc = new NPC(npc_type, nullptr, glm::vec4(x, y, z, heading), GravityBehavior::Water);
|
||||||
npc->GiveNPCTypeData(npc_type);
|
npc->GiveNPCTypeData(npc_type);
|
||||||
entity_list.AddNPC(npc);
|
entity_list.AddNPC(npc);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ extern volatile bool is_zone_loaded;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Merc::Merc(const NPCType* d, float x, float y, float z, float heading)
|
Merc::Merc(const NPCType* d, float x, float y, float z, float heading)
|
||||||
: NPC(d, nullptr, glm::vec4(x, y, z, heading), GravityBehavior::Ground, false), endupkeep_timer(1000), rest_timer(1), confidence_timer(6000), check_target_timer(2000)
|
: NPC(d, nullptr, glm::vec4(x, y, z, heading), GravityBehavior::Water, false), endupkeep_timer(1000), rest_timer(1), confidence_timer(6000), check_target_timer(2000)
|
||||||
{
|
{
|
||||||
base_hp = d->max_hp;
|
base_hp = d->max_hp;
|
||||||
base_mana = d->Mana;
|
base_mana = d->Mana;
|
||||||
|
|||||||
15
zone/mob.cpp
15
zone/mob.cpp
@ -24,6 +24,7 @@
|
|||||||
#include "string_ids.h"
|
#include "string_ids.h"
|
||||||
#include "worldserver.h"
|
#include "worldserver.h"
|
||||||
#include "mob_movement_manager.h"
|
#include "mob_movement_manager.h"
|
||||||
|
#include "water_map.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -427,7 +428,7 @@ Mob::Mob(const char* in_name,
|
|||||||
|
|
||||||
m_TargetRing = glm::vec3();
|
m_TargetRing = glm::vec3();
|
||||||
|
|
||||||
flymode = GravityBehavior::Ground;
|
flymode = GravityBehavior::Water;
|
||||||
DistractedFromGrid = false;
|
DistractedFromGrid = false;
|
||||||
hate_list.SetHateOwner(this);
|
hate_list.SetHateOwner(this);
|
||||||
|
|
||||||
@ -5995,8 +5996,16 @@ float Mob::GetDefaultRaceSize() const {
|
|||||||
|
|
||||||
void Mob::TryFixZ(int32 z_find_offset, bool fix_client_z)
|
void Mob::TryFixZ(int32 z_find_offset, bool fix_client_z)
|
||||||
{
|
{
|
||||||
if (fix_z_timer.Check() && flymode == GravityBehavior::Ground) {
|
if (fix_z_timer.Check() && flymode != GravityBehavior::Flying) {
|
||||||
FixZ();
|
auto watermap = zone->watermap;
|
||||||
|
if (watermap) {
|
||||||
|
if (!watermap->InLiquid(m_Position)) {
|
||||||
|
FixZ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FixZ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1363,16 +1363,20 @@ void Mob::AI_Process() {
|
|||||||
else {
|
else {
|
||||||
//we cannot reach our target...
|
//we cannot reach our target...
|
||||||
//underwater stuff only works with water maps in the zone!
|
//underwater stuff only works with water maps in the zone!
|
||||||
if (IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
//if (IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
|
||||||
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 != nullptr && tar != target) {
|
// if (tar != nullptr && tar != target) {
|
||||||
SetTarget(tar);
|
// SetTarget(tar);
|
||||||
return;
|
// RunTo(tar->GetX(), tar->GetY(), tar->GetZ());
|
||||||
}
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
// else {
|
||||||
|
// RunTo(target->GetX(), target->GetY(), target->GetZ());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
// See if we can summon the mob to us
|
// See if we can summon the mob to us
|
||||||
if (!HateSummon()) {
|
if (!HateSummon()) {
|
||||||
|
|||||||
@ -428,18 +428,20 @@ struct MobMovementEntry
|
|||||||
NavigateTo NavTo;
|
NavigateTo NavTo;
|
||||||
};
|
};
|
||||||
|
|
||||||
void AdjustRoute(std::list<IPathfinder::IPathNode> &nodes, int flymode, float offset) {
|
void AdjustRoute(std::list<IPathfinder::IPathNode> &nodes, Mob *who) {
|
||||||
if (!zone->HasMap() || !zone->HasWaterMap()) {
|
if (!zone->HasMap() || !zone->HasWaterMap()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto offset = who->GetZOffset();
|
||||||
|
|
||||||
for (auto &node : nodes) {
|
for (auto &node : nodes) {
|
||||||
if (flymode == GravityBehavior::Ground || !zone->watermap->InLiquid(node.pos)) {
|
if(!zone->watermap->InLiquid(node.pos)) {
|
||||||
auto best_z = zone->zonemap->FindBestZ(node.pos, nullptr);
|
auto best_z = zone->zonemap->FindBestZ(node.pos, nullptr);
|
||||||
if (best_z != BEST_Z_INVALID) {
|
if (best_z != BEST_Z_INVALID) {
|
||||||
node.pos.z = best_z + offset;
|
node.pos.z = best_z + offset;
|
||||||
}
|
}
|
||||||
}
|
} // todo: floating logic?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,99 +703,48 @@ void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMove
|
|||||||
if (!zone->HasMap() || !zone->HasWaterMap()) {
|
if (!zone->HasMap() || !zone->HasWaterMap()) {
|
||||||
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);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool partial = false;
|
if (who->IsBoat()) {
|
||||||
bool stuck = false;
|
UpdatePathBoat(who, x, y, z, mode);
|
||||||
IPathfinder::IPath route;
|
} else if (who->IsUnderwaterOnly()) {
|
||||||
if (who->IsUnderwaterOnly()) {
|
UpdatePathUnderwater(who, x, y, z, mode);
|
||||||
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 {
|
else {
|
||||||
route = zone->pathing->FindRoute(glm::vec3(who->GetX(), who->GetY(), who->GetZ()), glm::vec3(x, y, z), partial, stuck, PathingNotDisabled ^ PathingZoneLine);
|
UpdatePathGround(who, x, y, z, mode);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//if route empty or only has two points, and we have los, then just force npc to move to location
|
void MobMovementManager::UpdatePathGround(Mob * who, float x, float y, float z, MobMovementMode mode)
|
||||||
if (route.size() < 3) {
|
{
|
||||||
auto iter = _impl->Entries.find(who);
|
//This is probably pointless since the nav mesh tool currently sets zonelines to disabled anyway
|
||||||
auto &ent = (*iter);
|
auto partial = false;
|
||||||
if (zone->zonemap->CheckLoS(who->GetPosition(), glm::vec3(x, y, z)) && route.size() > 0)
|
auto stuck = false;
|
||||||
{
|
auto route = zone->pathing->FindRoute(
|
||||||
auto &first = route.front();
|
glm::vec3(who->GetX(), who->GetY(), who->GetZ()),
|
||||||
auto &last = route.back();
|
glm::vec3(x, y, z),
|
||||||
|
partial,
|
||||||
if (zone->watermap->InLiquid(who->GetPosition())) {
|
stuck,
|
||||||
PushSwimTo(ent.second, x, y, z, mode);
|
PathingNotDisabled ^ PathingZoneLine);
|
||||||
}
|
|
||||||
else {
|
|
||||||
PushMoveTo(ent.second, x, y, z, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
PushStopMoving(ent.second);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
PushStopMoving(ent.second);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto &first = route.front();
|
|
||||||
auto &last = route.back();
|
|
||||||
|
|
||||||
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 eiter = _impl->Entries.find(who);
|
auto eiter = _impl->Entries.find(who);
|
||||||
auto &ent = (*eiter);
|
auto &ent = (*eiter);
|
||||||
|
|
||||||
|
if (route.size() == 0) {
|
||||||
|
//handle stuck behavior
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdjustRoute(route, who);
|
||||||
|
|
||||||
auto iter = route.begin();
|
auto iter = route.begin();
|
||||||
glm::vec3 previous_pos(who->GetX(), who->GetY(), who->GetZ());
|
glm::vec3 previous_pos(who->GetX(), who->GetY(), who->GetZ());
|
||||||
bool first_node = true;
|
bool first_node = true;
|
||||||
|
|
||||||
//for each node
|
|
||||||
while (iter != route.end()) {
|
while (iter != route.end()) {
|
||||||
auto ¤t_node = (*iter);
|
auto ¤t_node = (*iter);
|
||||||
|
|
||||||
@ -830,14 +781,86 @@ void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMove
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//if stuck then handle stuck
|
|
||||||
if (stuck) {
|
if (stuck) {
|
||||||
PushMoveTo(ent.second, x, y, z, mode);
|
//handle stuck
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
PushStopMoving(ent.second);
|
|
||||||
|
void MobMovementManager::UpdatePathUnderwater(Mob * who, float x, float y, float z, MobMovementMode mode)
|
||||||
|
{
|
||||||
|
auto partial = false;
|
||||||
|
auto stuck = false;
|
||||||
|
auto route = zone->pathing->FindRoute(
|
||||||
|
glm::vec3(who->GetX(), who->GetY(), who->GetZ()),
|
||||||
|
glm::vec3(x, y, z),
|
||||||
|
partial,
|
||||||
|
stuck,
|
||||||
|
PathingWater | PathingLava | PathingVWater | PathingPortal | PathingPrefer);
|
||||||
|
|
||||||
|
auto eiter = _impl->Entries.find(who);
|
||||||
|
auto &ent = (*eiter);
|
||||||
|
|
||||||
|
if (route.size() == 0) {
|
||||||
|
//handle stuck behavior
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AdjustRoute(route, who);
|
||||||
|
|
||||||
|
auto iter = route.begin();
|
||||||
|
glm::vec3 previous_pos(who->GetX(), who->GetY(), who->GetZ());
|
||||||
|
bool first_node = true;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//move to / teleport to node + 1
|
||||||
|
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,
|
||||||
|
CalculateHeadingAngleBetweenPositions(current_node.pos.x, current_node.pos.y, next_node.pos.x, next_node.pos.y));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stuck) {
|
||||||
|
//handle stuck
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MobMovementManager::UpdatePathBoat(Mob *who, float x, float y, float z, MobMovementMode mode)
|
||||||
|
{
|
||||||
|
auto eiter = _impl->Entries.find(who);
|
||||||
|
auto &ent = (*eiter);
|
||||||
|
|
||||||
|
PushSwimTo(ent.second, x, y, z, mode);
|
||||||
|
PushStopMoving(ent.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MobMovementManager::PushTeleportTo(MobMovementEntry &ent, float x, float y, float z, float heading)
|
void MobMovementManager::PushTeleportTo(MobMovementEntry &ent, float x, float y, float z, float heading)
|
||||||
|
|||||||
@ -58,6 +58,9 @@ private:
|
|||||||
|
|
||||||
void FillCommandStruct(PlayerPositionUpdateServer_Struct *spu, Mob *m, float dx, float dy, float dz, float dh, int anim);
|
void FillCommandStruct(PlayerPositionUpdateServer_Struct *spu, Mob *m, float dx, float dy, float dz, float dh, int anim);
|
||||||
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 UpdatePathGround(Mob *who, float x, float y, float z, MobMovementMode mode);
|
||||||
|
void UpdatePathUnderwater(Mob *who, float x, float y, float z, MobMovementMode mode);
|
||||||
|
void UpdatePathBoat(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 PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode);
|
||||||
|
|||||||
16
zone/npc.cpp
16
zone/npc.cpp
@ -413,20 +413,6 @@ 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()
|
||||||
@ -1202,7 +1188,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client*
|
|||||||
npc_type->prim_melee_type = 28;
|
npc_type->prim_melee_type = 28;
|
||||||
npc_type->sec_melee_type = 28;
|
npc_type->sec_melee_type = 28;
|
||||||
|
|
||||||
auto npc = new NPC(npc_type, nullptr, position, GravityBehavior::Ground);
|
auto npc = new NPC(npc_type, nullptr, position, GravityBehavior::Water);
|
||||||
npc->GiveNPCTypeData(npc_type);
|
npc->GiveNPCTypeData(npc_type);
|
||||||
|
|
||||||
entity_list.AddNPC(npc);
|
entity_list.AddNPC(npc);
|
||||||
|
|||||||
@ -425,7 +425,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
|||||||
into walls or objects (+10), this sometimes creates the "ghost" effect. I changed to +2 (as close as I
|
into walls or objects (+10), this sometimes creates the "ghost" effect. I changed to +2 (as close as I
|
||||||
could get while it still looked good). I also noticed this can happen if an NPC is spawned on the same spot of another or in a related bad spot.*/
|
could get while it still looked good). I also noticed this can happen if an NPC is spawned on the same spot of another or in a related bad spot.*/
|
||||||
Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 power)
|
Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 power)
|
||||||
: NPC(type_data, 0, owner->GetPosition() + glm::vec4(2.0f, 2.0f, 0.0f, 0.0f), GravityBehavior::Ground)
|
: NPC(type_data, 0, owner->GetPosition() + glm::vec4(2.0f, 2.0f, 0.0f, 0.0f), GravityBehavior::Water)
|
||||||
{
|
{
|
||||||
GiveNPCTypeData(type_data);
|
GiveNPCTypeData(type_data);
|
||||||
typeofpet = type;
|
typeofpet = type;
|
||||||
|
|||||||
@ -208,7 +208,7 @@ Mob* QuestManager::spawn2(int npc_type, int grid, int unused, const glm::vec4& p
|
|||||||
const NPCType* tmp = 0;
|
const NPCType* tmp = 0;
|
||||||
if (tmp = database.LoadNPCTypesData(npc_type))
|
if (tmp = database.LoadNPCTypesData(npc_type))
|
||||||
{
|
{
|
||||||
auto npc = new NPC(tmp, nullptr, position, GravityBehavior::Ground);
|
auto npc = new NPC(tmp, nullptr, position, GravityBehavior::Water);
|
||||||
npc->AddLootTable();
|
npc->AddLootTable();
|
||||||
if (npc->DropsGlobalLoot())
|
if (npc->DropsGlobalLoot())
|
||||||
npc->CheckGlobalLootTables();
|
npc->CheckGlobalLootTables();
|
||||||
@ -232,7 +232,7 @@ Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, const glm::v
|
|||||||
const NPCType* tmp = 0;
|
const NPCType* tmp = 0;
|
||||||
if (tmp = database.LoadNPCTypesData(npc_type))
|
if (tmp = database.LoadNPCTypesData(npc_type))
|
||||||
{
|
{
|
||||||
auto npc = new NPC(tmp, nullptr, position, GravityBehavior::Ground);
|
auto npc = new NPC(tmp, nullptr, position, GravityBehavior::Water);
|
||||||
npc->AddLootTable();
|
npc->AddLootTable();
|
||||||
if (npc->DropsGlobalLoot())
|
if (npc->DropsGlobalLoot())
|
||||||
npc->CheckGlobalLootTables();
|
npc->CheckGlobalLootTables();
|
||||||
@ -308,7 +308,7 @@ Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id)
|
|||||||
found_spawn->SetCurrentNPCID(npcid);
|
found_spawn->SetCurrentNPCID(npcid);
|
||||||
|
|
||||||
auto position = glm::vec4(found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(), found_spawn->GetHeading());
|
auto position = glm::vec4(found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(), found_spawn->GetHeading());
|
||||||
auto npc = new NPC(tmp, found_spawn, position, GravityBehavior::Ground);
|
auto npc = new NPC(tmp, found_spawn, position, GravityBehavior::Water);
|
||||||
|
|
||||||
found_spawn->SetNPCPointer(npc);
|
found_spawn->SetNPCPointer(npc);
|
||||||
npc->AddLootTable();
|
npc->AddLootTable();
|
||||||
@ -1686,7 +1686,7 @@ void QuestManager::respawn(int npcTypeID, int grid) {
|
|||||||
const NPCType* npcType = nullptr;
|
const NPCType* npcType = nullptr;
|
||||||
if ((npcType = database.LoadNPCTypesData(npcTypeID)))
|
if ((npcType = database.LoadNPCTypesData(npcTypeID)))
|
||||||
{
|
{
|
||||||
owner = new NPC(npcType, nullptr, owner->GetPosition(), GravityBehavior::Ground);
|
owner = new NPC(npcType, nullptr, owner->GetPosition(), GravityBehavior::Water);
|
||||||
owner->CastToNPC()->AddLootTable();
|
owner->CastToNPC()->AddLootTable();
|
||||||
if (owner->CastToNPC()->DropsGlobalLoot())
|
if (owner->CastToNPC()->DropsGlobalLoot())
|
||||||
owner->CastToNPC()->CheckGlobalLootTables();
|
owner->CastToNPC()->CheckGlobalLootTables();
|
||||||
|
|||||||
@ -255,7 +255,7 @@ bool Spawn2::Process() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentnpcid = npcid;
|
currentnpcid = npcid;
|
||||||
NPC *npc = new NPC(tmp, this, glm::vec4(x, y, z, heading), GravityBehavior::Ground);
|
NPC *npc = new NPC(tmp, this, glm::vec4(x, y, z, heading), GravityBehavior::Water);
|
||||||
|
|
||||||
npc->mod_prespawn(this);
|
npc->mod_prespawn(this);
|
||||||
|
|
||||||
|
|||||||
@ -610,7 +610,7 @@ float Mob::GetFixedZ(const glm::vec3 &destination, int32 z_find_offset) {
|
|||||||
|
|
||||||
if (zone->HasMap() && RuleB(Map, FixZWhenMoving)) {
|
if (zone->HasMap() && RuleB(Map, FixZWhenMoving)) {
|
||||||
|
|
||||||
if (flymode != GravityBehavior::Ground)
|
if (flymode == GravityBehavior::Flying)
|
||||||
return new_z;
|
return new_z;
|
||||||
|
|
||||||
if (zone->HasWaterMap() && zone->watermap->InLiquid(glm::vec3(m_Position)))
|
if (zone->HasWaterMap() && zone->watermap->InLiquid(glm::vec3(m_Position)))
|
||||||
|
|||||||
@ -2257,7 +2257,7 @@ void Zone::DoAdventureActions()
|
|||||||
const NPCType* tmp = database.LoadNPCTypesData(ds->data_id);
|
const NPCType* tmp = database.LoadNPCTypesData(ds->data_id);
|
||||||
if(tmp)
|
if(tmp)
|
||||||
{
|
{
|
||||||
NPC* npc = new NPC(tmp, nullptr, glm::vec4(ds->assa_x, ds->assa_y, ds->assa_z, ds->assa_h), GravityBehavior::Ground);
|
NPC* npc = new NPC(tmp, nullptr, glm::vec4(ds->assa_x, ds->assa_y, ds->assa_z, ds->assa_h), GravityBehavior::Water);
|
||||||
npc->AddLootTable();
|
npc->AddLootTable();
|
||||||
if (npc->DropsGlobalLoot())
|
if (npc->DropsGlobalLoot())
|
||||||
npc->CheckGlobalLootTables();
|
npc->CheckGlobalLootTables();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user