diff options
author | megamage <none@none> | 2009-01-17 17:46:28 -0600 |
---|---|---|
committer | megamage <none@none> | 2009-01-17 17:46:28 -0600 |
commit | 9f1409c557c4ef6edc2bb9b54c6ad0463beb20db (patch) | |
tree | aaa732818364d49fa07769b2c22e54ff37fb6f76 | |
parent | ff3157eeb3802e06183edb23c2842d152bf79662 (diff) |
*Fix a crash bug caused by motionmaster.
*Fix charge movement.
--HG--
branch : trunk
-rw-r--r-- | src/bindings/scripts/include/sc_creature.cpp | 18 | ||||
-rw-r--r-- | src/bindings/scripts/include/sc_creature.h | 2 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp | 15 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp | 16 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp | 61 | ||||
-rw-r--r-- | src/game/DestinationHolderImp.h | 12 | ||||
-rw-r--r-- | src/game/MotionMaster.cpp | 36 | ||||
-rw-r--r-- | src/game/MotionMaster.h | 1 | ||||
-rw-r--r-- | src/game/PointMovementGenerator.cpp | 10 | ||||
-rw-r--r-- | src/game/PointMovementGenerator.h | 2 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 11 | ||||
-rw-r--r-- | src/game/Unit.h | 3 |
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) |