From ab6cdd65a361f7bc0cf340e708cc8b97ff4cfa95 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sun, 11 Nov 2018 01:04:25 -0800 Subject: [PATCH] Various stuck behavior --- zone/mob.h | 3 +- zone/mob_movement_manager.cpp | 76 ++++++++++++++++++++++++++++++++--- zone/mob_movement_manager.h | 10 +++++ zone/npc.h | 2 + zone/zonedb.cpp | 4 +- zone/zonedump.h | 1 + 6 files changed, 89 insertions(+), 7 deletions(-) diff --git a/zone/mob.h b/zone/mob.h index 967ab51f5..9e306c184 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -983,7 +983,8 @@ public: void TryFixZ(int32 z_find_offset = 5, bool fix_client_z = false); void FixZ(int32 z_find_offset = 5, bool fix_client_z = false); float GetFixedZ(const glm::vec3 &destination, int32 z_find_offset = 5); - + virtual int GetStuckBehavior() const { return 0; } + void NPCSpecialAttacks(const char* parse, int permtag, bool reset = true, bool remove = false); inline uint32 DontHealMeBefore() const { return pDontHealMeBefore; } inline uint32 DontBuffMeBefore() const { return pDontBuffMeBefore; } diff --git a/zone/mob_movement_manager.cpp b/zone/mob_movement_manager.cpp index bdf75704f..36f5aae5b 100644 --- a/zone/mob_movement_manager.cpp +++ b/zone/mob_movement_manager.cpp @@ -388,6 +388,38 @@ public: } }; +class EvadeCombatCommand : public IMovementCommand +{ +public: + EvadeCombatCommand() { + } + + virtual ~EvadeCombatCommand() { + + } + + virtual bool Process(MobMovementManager *mgr, Mob *m) { + if (!m->IsAIControlled()) { + return true; + } + + if (m->IsMoving()) { + m->SetMoving(false); + mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium); + } + + m->BuffFadeAll(); + m->WipeHateList(); + m->Heal(); + + return true; + } + + virtual bool Started() const { + return false; + } +}; + struct MovementStats { MovementStats() { @@ -782,11 +814,12 @@ void MobMovementManager::UpdatePathGround(Mob * who, float x, float y, float z, } } - PushStopMoving(ent.second); - if (stuck) { HandleStuckBehavior(who, x, y, z, mode); } + else { + PushStopMoving(ent.second); + } } void MobMovementManager::UpdatePathUnderwater(Mob *who, float x, float y, float z, MobMovementMode mode) @@ -875,11 +908,12 @@ void MobMovementManager::UpdatePathUnderwater(Mob *who, float x, float y, float } } - PushStopMoving(ent.second); - if (stuck) { HandleStuckBehavior(who, x, y, z, mode); } + else { + PushStopMoving(ent.second); + } } void MobMovementManager::UpdatePathBoat(Mob *who, float x, float y, float z, MobMovementMode mode) @@ -933,6 +967,38 @@ void MobMovementManager::PushStopMoving(MobMovementEntry &ent) ent.Commands.push_back(std::unique_ptr(new StopMovingCommand())); } -void MobMovementManager::HandleStuckBehavior(Mob * who, float x, float y, float z, MobMovementMode mode) +void MobMovementManager::PushEvadeCombat(MobMovementEntry &ent) { + ent.Commands.push_back(std::unique_ptr(new EvadeCombatCommand())); +} + +void MobMovementManager::HandleStuckBehavior(Mob *who, float x, float y, float z, MobMovementMode mode) +{ + auto sb = who->GetStuckBehavior(); + MobStuckBehavior behavior = RunToTarget; + + if (sb >= 0 && sb < MaxStuckBehavior) { + behavior = (MobStuckBehavior)sb; + } + + auto eiter = _impl->Entries.find(who); + auto &ent = (*eiter); + + switch (sb) { + case RunToTarget: + PushMoveTo(ent.second, x, y, z, mode); + PushStopMoving(ent.second); + break; + case WarpToTarget: + PushTeleportTo(ent.second, x, y, z, 0.0f); + PushStopMoving(ent.second); + break; + case TakeNoAction: + PushStopMoving(ent.second); + break; + case EvadeCombat: + //PushEvadeCombat(ent.second); + PushStopMoving(ent.second); + break; + } } diff --git a/zone/mob_movement_manager.h b/zone/mob_movement_manager.h index 8966aa24b..d9b2e7845 100644 --- a/zone/mob_movement_manager.h +++ b/zone/mob_movement_manager.h @@ -27,6 +27,15 @@ enum MobMovementMode : int MovementRunning = 1 }; +enum MobStuckBehavior : int +{ + RunToTarget, + WarpToTarget, + TakeNoAction, + EvadeCombat, + MaxStuckBehavior +}; + class MobMovementManager { public: @@ -66,6 +75,7 @@ private: void PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode); void PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mode); void PushStopMoving(MobMovementEntry &ent); + void PushEvadeCombat(MobMovementEntry &ent); void HandleStuckBehavior(Mob *who, float x, float y, float z, MobMovementMode mode); struct Implementation; diff --git a/zone/npc.h b/zone/npc.h index 5844c1a83..6917b0ec4 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -434,6 +434,8 @@ public: std::unique_ptr AIautocastspell_timer; + virtual int GetStuckBehavior() const { return NPCTypedata_ours ? NPCTypedata_ours->stuck_behavior : NPCTypedata->stuck_behavior; } + protected: const NPCType* NPCTypedata; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 027225243..db1da7868 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -2471,7 +2471,8 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load "npc_types.charm_avoidance_rating, " "npc_types.charm_atk, " "npc_types.skip_global_loot, " - "npc_types.rare_spawn " + "npc_types.rare_spawn, " + "npc_types.stuck_behavior " "FROM npc_types %s", where_condition.c_str() ); @@ -2660,6 +2661,7 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load temp_npctype_data->skip_global_loot = atoi(row[107]) != 0; temp_npctype_data->rare_spawn = atoi(row[108]) != 0; + temp_npctype_data->stuck_behavior = atoi(row[109]); // If NPC with duplicate NPC id already in table, // free item we attempted to add. diff --git a/zone/zonedump.h b/zone/zonedump.h index 66c7ec01d..6636bfa1e 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -143,6 +143,7 @@ struct NPCType bool untargetable; bool skip_global_loot; bool rare_spawn; + int8 stuck_behavior; }; namespace player_lootitem {