From 8f0051db8dacc060c3ad48a395e15af155223d36 Mon Sep 17 00:00:00 2001 From: KimLS Date: Fri, 9 Nov 2018 00:54:51 -0800 Subject: [PATCH] Changes to various path finding behavior --- zone/aa.cpp | 6 +- zone/aggro.cpp | 2 +- zone/client.cpp | 2 +- zone/command.cpp | 2 +- zone/entity.cpp | 16 --- zone/forage.cpp | 2 +- zone/hate_list.cpp | 17 --- zone/horse.cpp | 2 +- zone/lua_general.cpp | 2 +- zone/merc.cpp | 2 +- zone/mob.cpp | 15 ++- zone/mob_ai.cpp | 24 +++-- zone/mob_movement_manager.cpp | 195 +++++++++++++++++++--------------- zone/mob_movement_manager.h | 3 + zone/npc.cpp | 16 +-- zone/pets.cpp | 2 +- zone/questmgr.cpp | 8 +- zone/spawn2.cpp | 2 +- zone/waypoints.cpp | 2 +- zone/zone.cpp | 2 +- 20 files changed, 157 insertions(+), 165 deletions(-) diff --git a/zone/aa.cpp b/zone/aa.cpp index 5a2b87bb5..4ea307a0d 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -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 0, GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f), - GravityBehavior::Ground); + GravityBehavior::Water); if (followme) 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 0, GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f), - GravityBehavior::Ground); + GravityBehavior::Water); if (followme) 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_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()){ auto nSI = new SwarmPet; diff --git a/zone/aggro.cpp b/zone/aggro.cpp index 0b61662fc..de83d12e8 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -954,7 +954,7 @@ bool Mob::CombatRange(Mob* other) if (_DistNoRoot <= size_mod) { //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; } diff --git a/zone/client.cpp b/zone/client.cpp index 45ce6791c..9fa8fbec7 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -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 0, GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f), - GravityBehavior::Ground); + GravityBehavior::Water); if(!swarm_pet_npc->GetSwarmInfo()){ auto nSI = new SwarmPet; diff --git a/zone/command.cpp b/zone/command.cpp index 3e9abd29f..5c07c4096 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -2611,7 +2611,7 @@ void command_npctypespawn(Client *c, const Seperator *sep) const NPCType* tmp = 0; if ((tmp = database.LoadNPCTypesData(atoi(sep->arg[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)) npc->SetNPCFactionID(atoi(sep->arg[2])); diff --git a/zone/entity.cpp b/zone/entity.cpp index 0ae9600d9..f7f5b4594 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -3438,22 +3438,6 @@ void EntityList::ProcessMove(NPC *n, float x, float y, float z) { args.push_back(&evt.area_type); 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, diff --git a/zone/forage.cpp b/zone/forage.cpp index ede05c59f..77361ce33 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -284,7 +284,7 @@ void Client::GoFish() if (tmp != nullptr) { auto positionNPC = GetPosition(); 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(); if (npc->DropsGlobalLoot()) npc->CheckGlobalLootTables(); diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index 3f1fbf892..242a4c8e3 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -335,15 +335,6 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip) 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 (hate == -1) { @@ -474,14 +465,6 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip) 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)) { top_hate = cur->entity_on_hatelist; diff --git a/zone/horse.cpp b/zone/horse.cpp index d7d242e83..9f5c9b4d3 100644 --- a/zone/horse.cpp +++ b/zone/horse.cpp @@ -30,7 +30,7 @@ std::map Horse::horse_types; LinkedList horses_auto_delete; 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. strn0cpy(name, _owner->GetCleanName(), 55); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 5979a3959..bcf597d3e 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -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(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); entity_list.AddNPC(npc); } diff --git a/zone/merc.cpp b/zone/merc.cpp index f8d4469de..f26531ccf 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -29,7 +29,7 @@ extern volatile bool is_zone_loaded; #endif 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_mana = d->Mana; diff --git a/zone/mob.cpp b/zone/mob.cpp index b34b667d7..a07eed7e3 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -24,6 +24,7 @@ #include "string_ids.h" #include "worldserver.h" #include "mob_movement_manager.h" +#include "water_map.h" #include #include @@ -427,7 +428,7 @@ Mob::Mob(const char* in_name, m_TargetRing = glm::vec3(); - flymode = GravityBehavior::Ground; + flymode = GravityBehavior::Water; DistractedFromGrid = false; hate_list.SetHateOwner(this); @@ -5995,8 +5996,16 @@ float Mob::GetDefaultRaceSize() const { void Mob::TryFixZ(int32 z_find_offset, bool fix_client_z) { - if (fix_z_timer.Check() && flymode == GravityBehavior::Ground) { - FixZ(); + if (fix_z_timer.Check() && flymode != GravityBehavior::Flying) { + auto watermap = zone->watermap; + if (watermap) { + if (!watermap->InLiquid(m_Position)) { + FixZ(); + } + } + else { + FixZ(); + } } } diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 6c740a397..e1a499e64 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1363,16 +1363,20 @@ void Mob::AI_Process() { else { //we cannot reach our target... //underwater stuff only works with water maps in the zone! - if (IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { - auto targetPosition = glm::vec3(target->GetX(), target->GetY(), target->GetZ()); - if (!zone->watermap->InLiquid(targetPosition)) { - Mob *tar = hate_list.GetEntWithMostHateOnList(this); - if (tar != nullptr && tar != target) { - SetTarget(tar); - return; - } - } - } + //if (IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { + // auto targetPosition = glm::vec3(target->GetX(), target->GetY(), target->GetZ()); + // if (!zone->watermap->InLiquid(targetPosition)) { + // Mob *tar = hate_list.GetEntWithMostHateOnList(this); + // if (tar != nullptr && tar != target) { + // SetTarget(tar); + // 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 if (!HateSummon()) { diff --git a/zone/mob_movement_manager.cpp b/zone/mob_movement_manager.cpp index c4fc822a8..603dc2234 100644 --- a/zone/mob_movement_manager.cpp +++ b/zone/mob_movement_manager.cpp @@ -428,18 +428,20 @@ struct MobMovementEntry NavigateTo NavTo; }; -void AdjustRoute(std::list &nodes, int flymode, float offset) { +void AdjustRoute(std::list &nodes, Mob *who) { if (!zone->HasMap() || !zone->HasWaterMap()) { return; } + auto offset = who->GetZOffset(); + 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); if (best_z != BEST_Z_INVALID) { 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()) { auto iter = _impl->Entries.find(who); auto &ent = (*iter); - + PushMoveTo(ent.second, x, y, z, mode); 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; } - bool partial = false; - bool stuck = false; - 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); + if (who->IsBoat()) { + UpdatePathBoat(who, x, y, z, mode); + } else if (who->IsUnderwaterOnly()) { + UpdatePathUnderwater(who, x, y, z, mode); } 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 - if (route.size() < 3) { - auto iter = _impl->Entries.find(who); - auto &ent = (*iter); - if (zone->zonemap->CheckLoS(who->GetPosition(), glm::vec3(x, y, z)) && route.size() > 0) - { - auto &first = route.front(); - 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); - } - - 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); - } +void MobMovementManager::UpdatePathGround(Mob * who, float x, float y, float z, MobMovementMode mode) +{ + //This is probably pointless since the nav mesh tool currently sets zonelines to disabled anyway + 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, + PathingNotDisabled ^ PathingZoneLine); - 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 &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; - - //for each node + while (iter != route.end()) { 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) { - 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) diff --git a/zone/mob_movement_manager.h b/zone/mob_movement_manager.h index 13b7b3b5b..57cbfe4e1 100644 --- a/zone/mob_movement_manager.h +++ b/zone/mob_movement_manager.h @@ -58,6 +58,9 @@ private: 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 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 PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode); void PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode); diff --git a/zone/npc.cpp b/zone/npc.cpp index 98d20bd72..dc96ff2ba 100644 --- a/zone/npc.cpp +++ b/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_max = RuleI(Spells, AI_IdleNoSpellMaxRecast); 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() @@ -1202,7 +1188,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* npc_type->prim_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); entity_list.AddNPC(npc); diff --git a/zone/pets.cpp b/zone/pets.cpp index bf2f0ad3a..ad88f7a60 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -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 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) -: 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); typeofpet = type; diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 0a86d9870..2b6c5d4a0 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -208,7 +208,7 @@ Mob* QuestManager::spawn2(int npc_type, int grid, int unused, const glm::vec4& p const NPCType* tmp = 0; 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(); if (npc->DropsGlobalLoot()) npc->CheckGlobalLootTables(); @@ -232,7 +232,7 @@ Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, const glm::v const NPCType* tmp = 0; 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(); if (npc->DropsGlobalLoot()) npc->CheckGlobalLootTables(); @@ -308,7 +308,7 @@ Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id) found_spawn->SetCurrentNPCID(npcid); 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); npc->AddLootTable(); @@ -1686,7 +1686,7 @@ void QuestManager::respawn(int npcTypeID, int grid) { const NPCType* npcType = nullptr; 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(); if (owner->CastToNPC()->DropsGlobalLoot()) owner->CastToNPC()->CheckGlobalLootTables(); diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index 05e7e7926..3a6142c42 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -255,7 +255,7 @@ bool Spawn2::Process() { } 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); diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index e39a40221..833a8132b 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -610,7 +610,7 @@ float Mob::GetFixedZ(const glm::vec3 &destination, int32 z_find_offset) { if (zone->HasMap() && RuleB(Map, FixZWhenMoving)) { - if (flymode != GravityBehavior::Ground) + if (flymode == GravityBehavior::Flying) return new_z; if (zone->HasWaterMap() && zone->watermap->InLiquid(glm::vec3(m_Position))) diff --git a/zone/zone.cpp b/zone/zone.cpp index 7e2c597e0..ebc08ef09 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -2257,7 +2257,7 @@ void Zone::DoAdventureActions() const NPCType* tmp = database.LoadNPCTypesData(ds->data_id); 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(); if (npc->DropsGlobalLoot()) npc->CheckGlobalLootTables();