Various stuck behavior

This commit is contained in:
KimLS 2018-11-11 01:04:25 -08:00
parent 81b409a2e4
commit ab6cdd65a3
6 changed files with 89 additions and 7 deletions

View File

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

View File

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

View File

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

View File

@ -434,6 +434,8 @@ public:
std::unique_ptr<Timer> AIautocastspell_timer;
virtual int GetStuckBehavior() const { return NPCTypedata_ours ? NPCTypedata_ours->stuck_behavior : NPCTypedata->stuck_behavior; }
protected:
const NPCType* NPCTypedata;

View File

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

View File

@ -143,6 +143,7 @@ struct NPCType
bool untargetable;
bool skip_global_loot;
bool rare_spawn;
int8 stuck_behavior;
};
namespace player_lootitem {