aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormegamage <none@none>2009-01-17 17:46:28 -0600
committermegamage <none@none>2009-01-17 17:46:28 -0600
commit9f1409c557c4ef6edc2bb9b54c6ad0463beb20db (patch)
treeaaa732818364d49fa07769b2c22e54ff37fb6f76
parentff3157eeb3802e06183edb23c2842d152bf79662 (diff)
*Fix a crash bug caused by motionmaster.
*Fix charge movement. --HG-- branch : trunk
-rw-r--r--src/bindings/scripts/include/sc_creature.cpp18
-rw-r--r--src/bindings/scripts/include/sc_creature.h2
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp15
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp61
-rw-r--r--src/game/DestinationHolderImp.h12
-rw-r--r--src/game/MotionMaster.cpp36
-rw-r--r--src/game/MotionMaster.h1
-rw-r--r--src/game/PointMovementGenerator.cpp10
-rw-r--r--src/game/PointMovementGenerator.h2
-rw-r--r--src/game/SpellEffects.cpp11
-rw-r--r--src/game/Unit.h3
12 files changed, 81 insertions, 106 deletions
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp
index 0caa102d56d..cbbb574d253 100644
--- a/src/bindings/scripts/include/sc_creature.cpp
+++ b/src/bindings/scripts/include/sc_creature.cpp
@@ -342,7 +342,7 @@ Unit* ScriptedAI::SelectUnit(SelectAggroTarget targetType, uint32 position, floa
Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
if(!target
|| playerOnly && target->GetTypeId() != TYPEID_PLAYER
- || dist && !m_creature->IsWithinDistInMap(target, dist))
+ || dist && !m_creature->IsWithinCombatRange(target, dist))
{
continue;
}
@@ -388,7 +388,7 @@ Unit* ScriptedAI::SelectUnit(SelectAggroTarget targetType, uint32 position, floa
target = Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
if(!target
|| playerOnly && target->GetTypeId() != TYPEID_PLAYER
- || dist && !m_creature->IsWithinDistInMap(target, dist))
+ || dist && !m_creature->IsWithinCombatRange(target, dist))
{
m_threatlist.erase(i);
}
@@ -414,7 +414,7 @@ void ScriptedAI::SelectUnitList(std::list<Unit*> &targetList, uint32 num, Select
Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
if(!target
|| playerOnly && target->GetTypeId() != TYPEID_PLAYER
- || dist && !m_creature->IsWithinDistInMap(target, dist))
+ || dist && !m_creature->IsWithinCombatRange(target, dist))
{
continue;
}
@@ -448,7 +448,7 @@ void ScriptedAI::SelectUnitList(std::list<Unit*> &targetList, uint32 num, Select
m_threatlist.erase(i);
if(!target
|| playerOnly && target->GetTypeId() != TYPEID_PLAYER
- || dist && !m_creature->IsWithinDistInMap(target, dist))
+ || dist && !m_creature->IsWithinCombatRange(target, dist))
{
continue;
}
@@ -575,6 +575,16 @@ bool ScriptedAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered)
return true;
}
+
+float GetSpellMaxRange(uint32 id)
+{
+ SpellEntry const *spellInfo = GetSpellStore()->LookupEntry(id);
+ if(!spellInfo) return 0;
+ SpellRangeEntry const *range = GetSpellRangeStore()->LookupEntry(spellInfo->rangeIndex);
+ if(!range) return 0;
+ return range->maxRange;
+}
+
void FillSpellSummary()
{
SpellSummary = new TSpellSummary[GetSpellStore()->GetNumRows()];
diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h
index 12ec3f0cbf5..cf991baa301 100644
--- a/src/bindings/scripts/include/sc_creature.h
+++ b/src/bindings/scripts/include/sc_creature.h
@@ -11,6 +11,8 @@
#include "CreatureAI.h"
#include "Creature.h"
+float GetSpellMaxRange(uint32 id);
+
class SummonList : std::list<uint64>
{
public:
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
index 04d548901d8..40d69bd2186 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
@@ -905,18 +905,11 @@ struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI
void ChargeCheck()
{
Unit* target = SelectUnit(SELECT_TARGET_FARTHEST, 0, 200, false);
- if(target && (!m_creature->IsWithinDistInMap(target, FLAME_CHARGE_DISTANCE)))
+ if(target && (!m_creature->IsWithinCombatRange(target, FLAME_CHARGE_DISTANCE)))
{
- m_creature->AttackStop();
- m_creature->GetMotionMaster()->Clear(false);
- float x, y, z; // is it possible to fix charge?
- target->GetContactPoint(m_creature, x, y, z);
- m_creature->Relocate(x,y,z);
- m_creature->SendMonsterMove(x, y, z, 0, MOVEMENTFLAG_WALK_MODE, 1);
- //m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
- m_creature->StopMoving();
- //DoCast(target, SPELL_CHARGE);
m_creature->AddThreat(target, 5000000.0f);
+ AttackStart(target);
+ DoCast(target, SPELL_CHARGE);
DoTextEmote("sets its gaze on $N!", target);
}
}
@@ -964,7 +957,7 @@ struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI
{
ChargeCheck();
EnrageCheck();
- CheckTimer = 5000;
+ CheckTimer = 1000;
}else CheckTimer -= diff;
DoMeleeAttackIfReady();
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp
index 433cb691f2e..81a35e6788b 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp
@@ -246,9 +246,6 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI
FlamePatch_Timer = 30000;
Phase1 = false;
break;
- case WE_CHARGE:
- m_creature->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate);
- break;
case WE_METEOR:
m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, false);
m_creature->CastSpell(m_creature, SPELL_DIVE_BOMB_VISUAL, false);
@@ -336,17 +333,8 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI
if(Charge_Timer < diff)
{
- if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 1))
- {
- m_creature->SetInFront(target);
- m_creature->GetMotionMaster()->Clear();
- m_creature->AttackStop();
- m_creature->SetSpeed(MOVE_RUN, 5.0f);
- DoCast(target, SPELL_CHARGE);
- WaitEvent = WE_CHARGE;
- WaitTimer = 1000;
- return;
- }
+ Unit *target= SelectUnit(SELECT_TARGET_RANDOM, 1, GetSpellMaxRange(SPELL_CHARGE), true);
+ DoCast(target, SPELL_CHARGE);
Charge_Timer = 30000;
}else Charge_Timer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp
index 844e4a6c0ce..54e27bbf7ce 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp
@@ -112,9 +112,6 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
uint32 ShapeShift_Timer;
uint32 Berserk_Timer;
- uint64 ChargeTargetGUID;
- uint64 TankGUID;
-
bool inBearForm;
bool MoveEvent;
bool inMove;
@@ -145,9 +142,6 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
ShapeShift_Timer = 45000 + rand()%5000;
Berserk_Timer = 600000;
- ChargeTargetGUID = 0;
- TankGUID = 0;
-
inBearForm = false;
m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 5122);
}
@@ -301,15 +295,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
void MovementInform(uint32 type, uint32 id)
{
- if(!MoveEvent)
- {
- if(ChargeTargetGUID)
- {
- if(Unit* target = Unit::GetUnit(*m_creature, ChargeTargetGUID))
- m_creature->CastSpell(target, SPELL_SURGE, true);
- ChargeTargetGUID = 0;
- }
- }else
+ if(MoveEvent)
{
if(type != POINT_MOTION_TYPE)
return;
@@ -360,19 +346,6 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
}else waitTimer -= diff;
}
- if(TankGUID)
- {
- if(!ChargeTargetGUID)
- {
- m_creature->SetSpeed(MOVE_RUN, 1.2f);
- m_creature->GetMotionMaster()->Clear();
- if(Unit* target = Unit::GetUnit(*m_creature, TankGUID))
- m_creature->GetMotionMaster()->MoveChase(target);
- TankGUID = 0;
- }
- return;
- }
-
if(!m_creature->SelectHostilTarget() && !m_creature->getVictim())
return;
@@ -434,37 +407,13 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
{
DoYell(YELL_SURGE, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_YELL_SURGE);
-
- Unit *target = NULL;
- std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
- std::vector<Unit *> target_list;
- for(std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
- {
- target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
- //50 yard radius maximum
- if(target && target->GetDistance2d(m_creature) < 50)
- target_list.push_back(target);
- target = NULL;
- }
- if(target_list.size())
- target = *(target_list.begin()+rand()%target_list.size());
-
- if(!target)
- target = m_creature->getVictim();
- TankGUID = m_creature->getVictim()->GetGUID();
- ChargeTargetGUID = target->GetGUID();
-
- float x, y, z;
- target->GetContactPoint(m_creature, x, y, z);
- m_creature->SetSpeed(MOVE_RUN, 5.0f);
- m_creature->GetMotionMaster()->Clear();
- m_creature->GetMotionMaster()->MovePoint(0, x, y, z);
-
+ Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 1, GetSpellMaxRange(SPELL_SURGE), true);
+ DoCast(target, SPELL_SURGE);
Surge_Timer = 15000 + rand()%5000;
- return;
}else Surge_Timer -= diff;
}
- else {
+ else
+ {
if(LaceratingSlash_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_LACERATINGSLASH);
diff --git a/src/game/DestinationHolderImp.h b/src/game/DestinationHolderImp.h
index 437123f110d..f799c8613e7 100644
--- a/src/game/DestinationHolderImp.h
+++ b/src/game/DestinationHolderImp.h
@@ -95,10 +95,16 @@ DestinationHolder<TRAVELLER>::StartTravel(TRAVELLER &traveller, bool sendMove)
dist = sqrt((dx*dx) + (dy*dy) + (dz*dz));
else //Walking on the ground
dist = sqrt((dx*dx) + (dy*dy));
- float speed = traveller.Speed();
- speed *= 0.001f; // speed is in seconds so convert from second to millisecond
- i_totalTravelTime = static_cast<uint32>(dist/speed);
+ if(traveller.GetTraveller().hasUnitState(UNIT_STAT_CHARGING))
+ i_totalTravelTime = 1000;
+ else
+ {
+ float speed = traveller.Speed();
+ speed *= 0.001f; // speed is in seconds so convert from second to millisecond
+ i_totalTravelTime = static_cast<uint32>(dist/speed);
+ }
+
i_timeElapsed = 0;
if(sendMove)
traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime);
diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp
index 5d9059b468d..afc1940f89b 100644
--- a/src/game/MotionMaster.cpp
+++ b/src/game/MotionMaster.cpp
@@ -46,8 +46,10 @@ MotionMaster::Initialize()
while(!empty())
{
MovementGenerator *curr = top();
- curr->Finalize(*i_owner);
pop();
+ if(!curr)
+ continue;
+ curr->Finalize(*i_owner);
if( !isStatic( curr ) )
delete curr;
}
@@ -69,8 +71,10 @@ MotionMaster::~MotionMaster()
while(!empty())
{
MovementGenerator *curr = top();
- curr->Finalize(*i_owner);
pop();
+ if(!curr)
+ continue;
+ curr->Finalize(*i_owner);
if( !isStatic( curr ) )
delete curr;
}
@@ -92,8 +96,10 @@ MotionMaster::Clear(bool reset)
while( !empty() && size() > 1 )
{
MovementGenerator *curr = top();
- curr->Finalize(*i_owner);
pop();
+ if(!curr)
+ continue;
+ curr->Finalize(*i_owner);
if( !isStatic( curr ) )
delete curr;
}
@@ -269,6 +275,26 @@ MotionMaster::MovePoint(uint32 id, float x, float y, float z)
}
void
+MotionMaster::MoveCharge(float x, float y, float z)
+{
+ if(Impl[MOTION_SLOT_CONTROLLED] && Impl[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE)
+ return;
+
+ i_owner->addUnitState(UNIT_STAT_CHARGING);
+ if(i_owner->GetTypeId()==TYPEID_PLAYER)
+ {
+ DEBUG_LOG("Player (GUID: %u) charge point (X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), x, y, z );
+ Mutate(new PointMovementGenerator<Player>(0,x,y,z), MOTION_SLOT_CONTROLLED);
+ }
+ else
+ {
+ DEBUG_LOG("Creature (Entry: %u GUID: %u) charge point (X: %f Y: %f Z: %f)",
+ i_owner->GetEntry(), i_owner->GetGUIDLow(), x, y, z );
+ Mutate(new PointMovementGenerator<Creature>(0,x,y,z), MOTION_SLOT_CONTROLLED);
+ }
+}
+
+void
MotionMaster::MoveFleeing(Unit* enemy)
{
if(!enemy)
@@ -366,14 +392,14 @@ void MotionMaster::MovePath(uint32 path_id, bool repeatable)
return;
//We set waypoint movement as new default movement generator
// clear ALL movement generators (including default)
- while(!empty())
+ /*while(!empty())
{
MovementGenerator *curr = top();
curr->Finalize(*i_owner);
pop();
if( !isStatic( curr ) )
delete curr;
- }
+ }*/
//i_owner->GetTypeId()==TYPEID_PLAYER ?
//Mutate(new WaypointMovementGenerator<Player>(path_id, repeatable)):
diff --git a/src/game/MotionMaster.h b/src/game/MotionMaster.h
index 4d9953c9d15..284c9631cd1 100644
--- a/src/game/MotionMaster.h
+++ b/src/game/MotionMaster.h
@@ -101,6 +101,7 @@ class TRINITY_DLL_SPEC MotionMaster //: private std::stack<MovementGenerator *>
void MoveConfused();
void MoveFleeing(Unit* enemy);
void MovePoint(uint32 id, float x,float y,float z);
+ void MoveCharge(float x, float y, float z);
void MoveTaxiFlight(uint32 path, uint32 pathnode);
void MoveDistract(uint32 time);
void MovePath(uint32 path_id, bool repeatable);
diff --git a/src/game/PointMovementGenerator.cpp b/src/game/PointMovementGenerator.cpp
index 54fcba4898e..31b696bcd3b 100644
--- a/src/game/PointMovementGenerator.cpp
+++ b/src/game/PointMovementGenerator.cpp
@@ -44,7 +44,12 @@ bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
return false;
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED))
- return true;
+ {
+ if(unit.hasUnitState(UNIT_STAT_CHARGING))
+ return false;
+ else
+ return true;
+ }
Traveller<T> traveller(unit);
@@ -53,7 +58,8 @@ bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
if(i_destinationHolder.HasArrived())
{
unit.StopMoving();
- MovementInform(unit);
+ if(!unit.hasUnitState(UNIT_STAT_CHARGING))
+ MovementInform(unit);
return false;
}
diff --git a/src/game/PointMovementGenerator.h b/src/game/PointMovementGenerator.h
index 6ef5ab019ed..8a3f0da675f 100644
--- a/src/game/PointMovementGenerator.h
+++ b/src/game/PointMovementGenerator.h
@@ -35,7 +35,7 @@ class TRINITY_DLL_SPEC PointMovementGenerator
i_x(_x), i_y(_y), i_z(_z), i_nextMoveTime(0) {}
void Initialize(T &);
- void Finalize(T &){}
+ void Finalize(T &unit){unit.clearUnitState(UNIT_STAT_CHARGING);}
void Reset(T &unit){unit.StopMoving();}
bool Update(T &, const uint32 &diff);
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index d1520fd97ea..ab35c5f3d76 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -5739,17 +5739,10 @@ void Spell::EffectCharge(uint32 /*i*/)
float x, y, z;
unitTarget->GetContactPoint(m_caster, x, y, z);
- if(unitTarget->GetTypeId() != TYPEID_PLAYER)
- ((Creature *)unitTarget)->StopMoving();
-
- // Only send MOVEMENTFLAG_WALK_MODE, client has strange issues with other move flags
- m_caster->SendMonsterMove(x, y, z, 0, MOVEMENTFLAG_WALK_MODE, 1);
-
- if(m_caster->GetTypeId() != TYPEID_PLAYER)
- m_caster->GetMap()->CreatureRelocation((Creature*)m_caster,x,y,z,m_caster->GetOrientation());
+ m_caster->GetMotionMaster()->MoveCharge(x, y, z);
// not all charge effects used in negative spells
- if ( !IsPositiveSpell(m_spellInfo->Id))
+ if ( !IsPositiveSpell(m_spellInfo->Id) && m_caster->GetTypeId() == TYPEID_PLAYER)
m_caster->Attack(unitTarget,true);
}
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 09c7130c92a..9b39254ee1e 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -367,8 +367,9 @@ enum UnitState
UNIT_STAT_ATTACK_PLAYER = 0x00004000,
UNIT_STAT_CASTING = 0x00008000,
UNIT_STAT_POSSESSED = 0x00010000,
+ UNIT_STAT_CHARGING = 0x00020000,
UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FOLLOW),
- UNIT_STAT_LOST_CONTROL = (UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING),
+ UNIT_STAT_LOST_CONTROL = (UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_CHARGING),
UNIT_STAT_SIGHTLESS = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CHASE | UNIT_STAT_SEARCHING),
UNIT_STAT_CANNOT_AUTOATTACK = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CASTING),
UNIT_STAT_ALL_STATE = 0xffffffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT)