From 15403f0a8fb9c4980c7d5b29412c5427eda59482 Mon Sep 17 00:00:00 2001 From: QAston Date: Tue, 20 Jan 2009 20:32:23 +0100 Subject: *Fix bug with mindcontrol when aura interrupted on target is still on caster *Fix bug with "stucked succubus" --HG-- branch : trunk --- src/game/Unit.cpp | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'src/game/Unit.cpp') diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 607e33d6219..813d7783243 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4644,7 +4644,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) // Statue unsummoned at aura remove Totem* statue = NULL; - bool caster_channeled = false; + bool channeled = false; if(IsChanneledSpell(AurSpellInfo)) { if(!caster) // can be already located for IsSingleTargetSpell case @@ -4654,8 +4654,15 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) { if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE) statue = ((Totem*)caster); - else - caster_channeled = caster==this; + + // stop caster chanelling state + else if(caster->m_currentSpells[CURRENT_CHANNELED_SPELL] + //prevent recurential call + && caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED) + { + caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel(false); + channeled = true; + } } } @@ -4683,8 +4690,13 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) delete Aur; - if(caster_channeled) - RemoveAurasAtChanneledTarget (AurSpellInfo); + if(channeled) + { + //if target is not caster remove auras also on caster + if (caster!=this) + caster->RemoveAurasAtChanneledTarget (AurSpellInfo, caster); + RemoveAurasAtChanneledTarget (AurSpellInfo, caster); + } if(statue) statue->UnSummon(); @@ -12553,23 +12565,23 @@ bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura ) return true; } -void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo) +void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo, Unit * caster) { - uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT); +/* uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT); if(target_guid == GetGUID()) return; if(!IS_UNIT_GUID(target_guid)) return; - Unit* target = ObjectAccessor::GetUnit(*this, target_guid); - if(!target) + Unit* target = ObjectAccessor::GetUnit(*this, target_guid);*/ + if(!caster) return; - for (AuraMap::iterator iter = target->GetAuras().begin(); iter != target->GetAuras().end(); ) + for (AuraMap::iterator iter = GetAuras().begin(); iter != GetAuras().end(); ) { - if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID()==GetGUID()) - target->RemoveAura(iter); + if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID() == caster->GetGUID()) + RemoveAura(iter); else ++iter; } -- cgit v1.2.3 From e0b527be8ac4723a14b2cd5623aa511681f11775 Mon Sep 17 00:00:00 2001 From: QAston Date: Wed, 21 Jan 2009 20:24:21 +0100 Subject: *Fix rain of fire. --HG-- branch : trunk --- src/game/Unit.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/game/Unit.cpp') diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 813d7783243..d46d77f8703 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4660,8 +4660,13 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) //prevent recurential call && caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED) { - caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel(false); - channeled = true; + if (caster==this || !IsAreaOfEffectSpell(AurSpellInfo)) + { + // remove auras only for non-aoe spells or when chanelled aura is removed + // because aoe spells don't require aura on target to continue + caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel(false); + channeled = true; + } } } } -- cgit v1.2.3 From d81d81b211977093c8481a591a96bcc69d66bfe8 Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 21 Jan 2009 14:17:29 -0600 Subject: *Move SelectHostilTarget() to class Creature and return getVictim() directly. *Fix the crash caused by mandokir script. --HG-- branch : trunk --- .../scripts/scripts/zone/karazhan/boss_moroes.cpp | 6 +-- .../scripts/zone/zulgurub/boss_mandokir.cpp | 7 ++-- src/game/Creature.h | 1 + src/game/Unit.cpp | 46 +++++++++++++--------- src/game/Unit.h | 5 ++- 5 files changed, 38 insertions(+), 27 deletions(-) (limited to 'src/game/Unit.cpp') diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp index 3f0d6dd7a27..99283ca7097 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp @@ -276,13 +276,13 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI { for (uint8 i = 0; i < 4; ++i) { - Unit* Temp = NULL; + Creature* Temp = NULL; if (AddGUID[i]) { - Temp = Unit::GetUnit((*m_creature),AddGUID[i]); + Temp = (Creature*)Unit::GetUnit((*m_creature),AddGUID[i]); if (Temp && Temp->isAlive()) if (!Temp->SelectHostilTarget() || !Temp->getVictim() ) - ((Creature*)Temp)->AI()->AttackStart(m_creature->getVictim()); + Temp->AI()->AttackStart(m_creature->getVictim()); } } CheckAdds_Timer = 5000; diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp index 14f3702354d..a440ba4a575 100644 --- a/src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp +++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp @@ -131,7 +131,8 @@ struct TRINITY_DLL_DECL boss_mandokirAI : public ScriptedAI void UpdateAI(const uint32 diff) { - if (!m_creature->SelectHostilTarget() || !m_creature->getVictim()) + Unit *victim = m_creature->SelectHostilTarget(); + if(!victim) return; if( m_creature->getVictim() && m_creature->isAlive()) @@ -234,11 +235,11 @@ struct TRINITY_DLL_DECL boss_mandokirAI : public ScriptedAI }else Fear_Timer -=diff; //Mortal Strike if target below 50% hp - if (m_creature->getVictim()->GetHealth() < m_creature->getVictim()->GetMaxHealth()*0.5) + if (victim && victim->GetHealth() < victim->GetMaxHealth()*0.5) { if (MortalStrike_Timer < diff) { - DoCast(m_creature->getVictim(),SPELL_MORTAL_STRIKE); + DoCast(victim,SPELL_MORTAL_STRIKE); MortalStrike_Timer = 15000; }else MortalStrike_Timer -= diff; } diff --git a/src/game/Creature.h b/src/game/Creature.h index 1ae41b86776..563a9ddb80c 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -630,6 +630,7 @@ class TRINITY_DLL_SPEC Creature : public Unit bool IsFormationLeader() {return (GetDBTableGUIDLow() && GetDBTableGUIDLow() == m_formationID);} uint32 GetFormationID(){return m_formationID;} + Unit *SelectHostilTarget(); protected: bool CreateFromProto(uint32 guidlow,uint32 Entry,uint32 team, const CreatureData *data = NULL); bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index d46d77f8703..35b45c2750e 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -261,8 +261,17 @@ Unit::~Unit() if(m_uint32Values) { sLog.outDetail("Deconstruct Unit Entry = %u", GetEntry()); - if(m_scAuras.size()) + /*for(int i = 0; i < TOTAL_AURAS; ++i) + { + if(m_modAuras[i].begin() != m_modAuras[i].end()) + sLog.outError("Unit %u has mod auras during deconstruction", GetEntry()); + } + if(m_scAuras.begin() != m_scAuras.end()) sLog.outError("Unit %u has sc auras during deconstruction", GetEntry()); + if(m_interruptableAuras.begin() != m_interruptableAuras.end()) + sLog.outError("Unit %u has interruptable auras during deconstruction", GetEntry()); + if(m_ccAuras.begin() != m_ccAuras.end()) + sLog.outError("Unit %u has cc auras during deconstruction", GetEntry());*/ } } @@ -10390,18 +10399,17 @@ void Unit::TauntFadeOut(Unit *taunter) //====================================================================== -bool Unit::SelectHostilTarget() +Unit* Creature::SelectHostilTarget() { //function provides main threat functionality //next-victim-selection algorithm and evade mode are called //threat list sorting etc. - assert(GetTypeId()== TYPEID_UNIT); Unit* target = NULL; //This function only useful once AI has been initialized - if (!((Creature*)this)->AI()) - return false; + if (!AI()) + return NULL; if(!m_ThreatManager.isThreatListEmpty()) { @@ -10417,36 +10425,36 @@ bool Unit::SelectHostilTarget() { if(!hasUnitState(UNIT_STAT_STUNNED)) SetInFront(target); - ((Creature*)this)->AI()->AttackStart(target); - return true; + AI()->AttackStart(target); + return getVictim(); } // no target but something prevent go to evade mode if( !isInCombat() /*|| HasAuraType(SPELL_AURA_MOD_TAUNT)*/ ) - return false; + return NULL; // last case when creature don't must go to evade mode: // it in combat but attacker not make any damage and not enter to aggro radius to have record in threat list // for example at owner command to pet attack some far away creature // Note: creature not have targeted movement generator but have attacker in this case - if( GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE ) + /*if( GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE ) { for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr) { if( (*itr)->IsInMap(this) && canAttack(*itr) && (*itr)->isInAccessiblePlaceFor((Creature*)this) ) return false; } - } + }*/ // search nearby enemy before enter evade mode - if(((Creature*)this)->HasReactState(REACT_AGGRESSIVE)) + if(HasReactState(REACT_AGGRESSIVE)) { - if(Unit *target = ((Creature*)this)->SelectNearestTarget()) + if(target = SelectNearestTarget()) { - if(!((Creature*)this)->IsOutOfThreatArea(target)) + if(!IsOutOfThreatArea(target)) { - ((Creature*)this)->AI()->AttackStart(target); - return true; + AI()->AttackStart(target); + return getVictim(); } } } @@ -10457,16 +10465,16 @@ bool Unit::SelectHostilTarget() for(Unit::AuraList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr) if((*itr)->IsPermanent()) { - ((Creature*)this)->AI()->EnterEvadeMode(); + AI()->EnterEvadeMode(); break; } - return false; + return NULL; } // enter in evade mode in other case - ((Creature*)this)->AI()->EnterEvadeMode(); + AI()->EnterEvadeMode(); - return false; + return NULL; } //====================================================================== diff --git a/src/game/Unit.h b/src/game/Unit.h index 077e82a2143..83cb1900506 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1238,7 +1238,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL); float ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL); void DeleteThreatList(); - bool SelectHostilTarget(); + //bool SelectHostilTarget(); void TauntApply(Unit* pVictim); void TauntFadeOut(Unit *taunter); ThreatManager& getThreatManager() { return m_ThreatManager; } @@ -1450,6 +1450,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject uint32 m_reactiveTimer[MAX_REACTIVE]; + ThreatManager m_ThreatManager; private: void SendAttackStop(Unit* victim); // only from AttackStop(Unit*) //void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*) @@ -1469,7 +1470,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject Diminishing m_Diminishing; // Manage all Units threatening us - ThreatManager m_ThreatManager; +// ThreatManager m_ThreatManager; // Manage all Units that are threatened by us HostilRefManager m_HostilRefManager; -- cgit v1.2.3 From 18cc905c4270cad9fa6df5cdb472061c2a80889e Mon Sep 17 00:00:00 2001 From: QAston Date: Thu, 22 Jan 2009 20:48:08 +0100 Subject: *Fix fishing and Eagle eye. --HG-- branch : trunk --- src/game/Unit.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/game/Unit.cpp') diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 35b45c2750e..2e966eb53cc 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4673,8 +4673,13 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) { // remove auras only for non-aoe spells or when chanelled aura is removed // because aoe spells don't require aura on target to continue - caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel(false); - channeled = true; + if (AurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()]!=SPELL_AURA_PERIODIC_DUMMY + && AurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()]!= SPELL_AURA_DUMMY) + //don't stop channeling of scripted spells (this is actually a hack) + { + caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel(false); + channeled = true; + } } } } -- cgit v1.2.3