Core/Movement:

- Lower movement radius and speed when confused/disoriented.
- Force attackstop when confused or feared. Should fix issue with creatures "teleporting" after fear.

Close #2689
Close #466
Close #3743
This commit is contained in:
kaelima
2011-11-13 02:36:51 +01:00
parent 79903f31ce
commit 9b7e9a1ee3
3 changed files with 28 additions and 26 deletions
+14 -7
View File
@@ -2220,22 +2220,23 @@ void Unit::SendMeleeAttackStart(Unit* victim)
WorldPacket data(SMSG_ATTACKSTART, 8 + 8); WorldPacket data(SMSG_ATTACKSTART, 8 + 8);
data << uint64(GetGUID()); data << uint64(GetGUID());
data << uint64(victim->GetGUID()); data << uint64(victim->GetGUID());
SendMessageToSet(&data, true); SendMessageToSet(&data, true);
sLog->outStaticDebug("WORLD: Sent SMSG_ATTACKSTART"); sLog->outStaticDebug("WORLD: Sent SMSG_ATTACKSTART");
} }
void Unit::SendMeleeAttackStop(Unit* victim) void Unit::SendMeleeAttackStop(Unit* victim)
{ {
if (!victim)
return;
WorldPacket data(SMSG_ATTACKSTOP, (8+8+4)); // we guess size WorldPacket data(SMSG_ATTACKSTOP, (8+8+4)); // we guess size
data.append(GetPackGUID()); data.append(GetPackGUID());
data.append(victim->GetPackGUID()); // can be 0x00... data.append(victim ? victim->GetPackGUID() : 0); // can be 0x00...
data << uint32(0); // can be 0x1 data << uint32(0); // can be 0x1
SendMessageToSet(&data, true); SendMessageToSet(&data, true);
sLog->outDetail("%s %u stopped attacking %s %u", (GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), GetGUIDLow(), (victim->GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), victim->GetGUIDLow()); sLog->outStaticDebug("WORLD: Sent SMSG_ATTACKSTART");
if (victim)
sLog->outDetail("%s %u stopped attacking %s %u", (GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), GetGUIDLow(), (victim->GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), victim->GetGUIDLow());
else
sLog->outDetail("%s %u stopped attacking", (GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), GetGUIDLow());
} }
bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType) bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType)
@@ -15635,6 +15636,9 @@ void Unit::SetControlled(bool apply, UnitState state)
case UNIT_STAT_CONFUSED: case UNIT_STAT_CONFUSED:
if (!HasUnitState(UNIT_STAT_STUNNED)) if (!HasUnitState(UNIT_STAT_STUNNED))
{ {
ClearUnitState(UNIT_STAT_MELEE_ATTACKING);
SendMeleeAttackStop();
// SendAutoRepeatCancel ?
SetConfused(true); SetConfused(true);
CastStop(); CastStop();
} }
@@ -15642,6 +15646,9 @@ void Unit::SetControlled(bool apply, UnitState state)
case UNIT_STAT_FLEEING: case UNIT_STAT_FLEEING:
if (!HasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED)) if (!HasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED))
{ {
ClearUnitState(UNIT_STAT_MELEE_ATTACKING);
SendMeleeAttackStop();
// SendAutoRepeatCancel ?
SetFeared(true); SetFeared(true);
CastStop(); CastStop();
} }
+1 -1
View File
@@ -1310,7 +1310,7 @@ class Unit : public WorldObject
void CombatStopWithPets(bool includingCast = false); void CombatStopWithPets(bool includingCast = false);
void StopAttackFaction(uint32 faction_id); void StopAttackFaction(uint32 faction_id);
Unit* SelectNearbyTarget(float dist = NOMINAL_MELEE_RANGE) const; Unit* SelectNearbyTarget(float dist = NOMINAL_MELEE_RANGE) const;
void SendMeleeAttackStop(Unit* victim); void SendMeleeAttackStop(Unit* victim = NULL);
void SendMeleeAttackStart(Unit* pVictim); void SendMeleeAttackStart(Unit* pVictim);
void AddUnitState(uint32 f) { m_state |= f; } void AddUnitState(uint32 f) { m_state |= f; }
@@ -29,10 +29,9 @@
#endif #endif
template<class T> template<class T>
void void ConfusedMovementGenerator<T>::Initialize(T &unit)
ConfusedMovementGenerator<T>::Initialize(T &unit)
{ {
const float wander_distance = 11; float const wanderDistance = 4;
float x, y, z; float x, y, z;
x = unit.GetPositionX(); x = unit.GetPositionX();
y = unit.GetPositionY(); y = unit.GetPositionY();
@@ -47,8 +46,8 @@ ConfusedMovementGenerator<T>::Initialize(T &unit)
for (uint8 idx = 0; idx <= MAX_CONF_WAYPOINTS; ++idx) for (uint8 idx = 0; idx <= MAX_CONF_WAYPOINTS; ++idx)
{ {
float wanderX = x + wander_distance*(float)rand_norm() - wander_distance/2; float wanderX = x + wanderDistance * (float)rand_norm() - wanderDistance/2;
float wanderY = y + wander_distance*(float)rand_norm() - wander_distance/2; float wanderY = y + wanderDistance * (float)rand_norm() - wanderDistance/2;
Trinity::NormalizeMapCoord(wanderX); Trinity::NormalizeMapCoord(wanderX);
Trinity::NormalizeMapCoord(wanderY); Trinity::NormalizeMapCoord(wanderY);
@@ -68,7 +67,7 @@ ConfusedMovementGenerator<T>::Initialize(T &unit)
} }
// Taken from FleeingMovementGenerator // Taken from FleeingMovementGenerator
if (!(new_z - z) || wander_distance / fabs(new_z - z) > 1.0f) if (!(new_z - z) || wanderDistance / fabs(new_z - z) > 1.0f)
{ {
i_waypoints[idx][0] = wanderX; i_waypoints[idx][0] = wanderX;
i_waypoints[idx][1] = wanderY; i_waypoints[idx][1] = wanderY;
@@ -89,29 +88,26 @@ ConfusedMovementGenerator<T>::Initialize(T &unit)
unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
unit.CastStop(); unit.CastStop();
unit.StopMoving(); unit.StopMoving();
unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); unit.AddUnitMovementFlag(MOVEMENTFLAG_WALKING); // Should actually be splineflag
unit.AddUnitState(UNIT_STAT_CONFUSED); unit.AddUnitState(UNIT_STAT_CONFUSED);
} }
template<> template<>
void void ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok)
ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok)
{ {
is_water_ok = creature.canSwim(); is_water_ok = creature.canSwim();
is_land_ok = creature.canWalk(); is_land_ok = creature.canWalk();
} }
template<> template<>
void void ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok)
ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok)
{ {
is_water_ok = true; is_water_ok = true;
is_land_ok = true; is_land_ok = true;
} }
template<class T> template<class T>
void void ConfusedMovementGenerator<T>::Reset(T &unit)
ConfusedMovementGenerator<T>::Reset(T &unit)
{ {
i_nextMove = 1; i_nextMove = 1;
i_nextMoveTime.Reset(0); i_nextMoveTime.Reset(0);
@@ -120,8 +116,7 @@ ConfusedMovementGenerator<T>::Reset(T &unit)
} }
template<class T> template<class T>
bool bool ConfusedMovementGenerator<T>::Update(T &unit, const uint32 diff)
ConfusedMovementGenerator<T>::Update(T &unit, const uint32 diff)
{ {
if (!&unit) if (!&unit)
return true; return true;
@@ -141,7 +136,7 @@ ConfusedMovementGenerator<T>::Update(T &unit, const uint32 diff)
unit.ClearUnitState(UNIT_STAT_MOVE); unit.ClearUnitState(UNIT_STAT_MOVE);
i_nextMove = urand(1, MAX_CONF_WAYPOINTS); i_nextMove = urand(1, MAX_CONF_WAYPOINTS);
i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher i_nextMoveTime.Reset(urand(100, 1000));
} }
} }
} }
@@ -164,11 +159,11 @@ ConfusedMovementGenerator<T>::Update(T &unit, const uint32 diff)
} }
template<class T> template<class T>
void void ConfusedMovementGenerator<T>::Finalize(T &unit)
ConfusedMovementGenerator<T>::Finalize(T &unit)
{ {
unit.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); unit.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
unit.ClearUnitState(UNIT_STAT_CONFUSED); unit.ClearUnitState(UNIT_STAT_CONFUSED);
if (unit.GetTypeId() == TYPEID_UNIT && unit.getVictim()) if (unit.GetTypeId() == TYPEID_UNIT && unit.getVictim())
unit.SetTarget(unit.getVictim()->GetGUID()); unit.SetTarget(unit.getVictim()->GetGUID());
} }