Changes to various path finding behavior

This commit is contained in:
KimLS 2018-11-09 00:54:51 -08:00
parent fd7b6deafa
commit 8f0051db8d
20 changed files with 157 additions and 165 deletions

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;

View File

@ -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]));

View File

@ -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,

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -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);
} }

View File

@ -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;

View File

@ -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();
}
} }
} }

View File

@ -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()) {

View File

@ -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?
} }
} }
@ -704,96 +706,45 @@ void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMove
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 &current_node = (*iter); auto &current_node = (*iter);
@ -831,13 +782,85 @@ 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 &current_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)

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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);

View File

@ -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)))

View File

@ -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();