Merge branch 'master' into 310

This commit is contained in:
tomrus88 2009-04-14 15:54:43 +04:00
commit d6f6272f8c
41 changed files with 759 additions and 615 deletions

View file

@ -420,28 +420,22 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if (!spellProto || !(spellProto->Mechanic == MECHANIC_ROOT || IsAuraAddedBySpell(SPELL_AURA_MOD_ROOT, spellProto->Id)))
pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_ROOT, damage);
if(pVictim->GetTypeId() != TYPEID_PLAYER)
// no xp,health if type 8 /critters/
if(pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER)
{
// no xp,health if type 8 /critters/
if ( pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER)
{
pVictim->setDeathState(JUST_DIED);
pVictim->SetHealth(0);
pVictim->setDeathState(JUST_DIED);
pVictim->SetHealth(0);
// allow loot only if has loot_id in creature_template
CreatureInfo const* cInfo = ((Creature*)pVictim)->GetCreatureInfo();
if(cInfo && cInfo->lootid)
pVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
// allow loot only if has loot_id in creature_template
CreatureInfo const* cInfo = ((Creature*)pVictim)->GetCreatureInfo();
if(cInfo && cInfo->lootid)
pVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
// some critters required for quests
if(GetTypeId() == TYPEID_PLAYER)
((Player*)this)->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID());
// some critters required for quests
if(GetTypeId() == TYPEID_PLAYER)
((Player*)this)->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID());
return damage;
}
if(!pVictim->isInCombat() && ((Creature*)pVictim)->AI())
((Creature*)pVictim)->AI()->AttackStart(this);
return damage;
}
DEBUG_LOG("DealDamageStart");
@ -690,18 +684,16 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if(damagetype != DOT)
{
if(getVictim())
{
// if have target and damage pVictim just call AI reaction
if(pVictim != getVictim() && pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->AI())
((Creature*)pVictim)->AI()->AttackedBy(this);
}
else
if(!getVictim())
{
// if not have main target then attack state with target (including AI call)
//start melee attacks only after melee hit
Attack(pVictim,(damagetype == DIRECT_DAMAGE));
}
// if damage pVictim call AI reaction
if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->AI())
((Creature*)pVictim)->AI()->AttackedBy(this);
}
// polymorphed and other negative transformed cases
@ -1963,6 +1955,10 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
}
}
// if damage pVictim call AI reaction
if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->AI())
((Creature*)pVictim)->AI()->AttackedBy(this);
return;
}
@ -1990,6 +1986,10 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
--m_extraAttacks;
}
}
// if damage pVictim call AI reaction
if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->AI())
((Creature*)pVictim)->AI()->AttackedBy(this);
}
MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit *pVictim, WeaponAttackType attType) const
@ -2917,7 +2917,7 @@ void Unit::_UpdateSpells( uint32 time )
if(!m_gameObj.empty())
{
std::list<GameObject*>::iterator ite1, dnext1;
GameObjectList::iterator ite1, dnext1;
for (ite1 = m_gameObj.begin(); ite1 != m_gameObj.end(); ite1 = dnext1)
{
dnext1 = ite1;
@ -3044,7 +3044,7 @@ void Unit::InterruptSpell(uint32 spellType, bool withDelayed)
{
assert(spellType < CURRENT_MAX_SPELL);
if(m_currentSpells[spellType] && (withDelayed || m_currentSpells[spellType]->getState() != SPELL_STATE_DELAYED) )
if (m_currentSpells[spellType] && (withDelayed || m_currentSpells[spellType]->getState() != SPELL_STATE_DELAYED) )
{
// send autorepeat cancel message for autorepeat spells
if (spellType == CURRENT_AUTOREPEAT_SPELL)
@ -3055,8 +3055,13 @@ void Unit::InterruptSpell(uint32 spellType, bool withDelayed)
if (m_currentSpells[spellType]->getState() != SPELL_STATE_FINISHED)
m_currentSpells[spellType]->cancel();
m_currentSpells[spellType]->SetReferencedFromCurrent(false);
m_currentSpells[spellType] = NULL;
// cancel can interrupt spell already (caster cancel ->target aura remove -> caster iterrupt)
if (m_currentSpells[spellType])
{
m_currentSpells[spellType]->SetReferencedFromCurrent(false);
m_currentSpells[spellType] = NULL;
}
}
}
@ -3087,36 +3092,15 @@ void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id)
{
// generic spells are interrupted if they are not finished or delayed
if (m_currentSpells[CURRENT_GENERIC_SPELL] && (!spell_id || m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id==spell_id))
{
if ( (m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_FINISHED) &&
(withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED) )
m_currentSpells[CURRENT_GENERIC_SPELL]->cancel();
m_currentSpells[CURRENT_GENERIC_SPELL]->SetReferencedFromCurrent(false);
m_currentSpells[CURRENT_GENERIC_SPELL] = NULL;
}
InterruptSpell(CURRENT_GENERIC_SPELL,withDelayed);
// autorepeat spells are interrupted if they are not finished or delayed
if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL] && (!spell_id || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id==spell_id))
{
// send disable autorepeat packet in any case
if(GetTypeId()==TYPEID_PLAYER)
((Player*)this)->SendAutoRepeatCancel();
if ( (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() != SPELL_STATE_FINISHED) &&
(withDelayed || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() != SPELL_STATE_DELAYED) )
m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->cancel();
m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->SetReferencedFromCurrent(false);
m_currentSpells[CURRENT_AUTOREPEAT_SPELL] = NULL;
}
InterruptSpell(CURRENT_AUTOREPEAT_SPELL,withDelayed);
// channeled spells are interrupted if they are not finished, even if they are delayed
if (m_currentSpells[CURRENT_CHANNELED_SPELL] && (!spell_id || m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spell_id))
{
if (m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED)
m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel();
m_currentSpells[CURRENT_CHANNELED_SPELL]->SetReferencedFromCurrent(false);
m_currentSpells[CURRENT_CHANNELED_SPELL] = NULL;
}
InterruptSpell(CURRENT_CHANNELED_SPELL,true);
}
Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const
@ -4060,6 +4044,15 @@ DynamicObject * Unit::GetDynObject(uint32 spellId)
return NULL;
}
GameObject* Unit::GetGameObject(uint32 spellId) const
{
for (GameObjectList::const_iterator i = m_gameObj.begin(); i != m_gameObj.end();)
if ((*i)->GetSpellId() == spellId)
return *i;
return NULL;
}
void Unit::AddGameObject(GameObject* gameObj)
{
assert(gameObj && gameObj->GetOwnerGUID()==0);
@ -4110,7 +4103,7 @@ void Unit::RemoveGameObject(uint32 spellid, bool del)
{
if(m_gameObj.empty())
return;
std::list<GameObject*>::iterator i, next;
GameObjectList::iterator i, next;
for (i = m_gameObj.begin(); i != m_gameObj.end(); i = next)
{
next = i;
@ -4133,7 +4126,7 @@ void Unit::RemoveGameObject(uint32 spellid, bool del)
void Unit::RemoveAllGameObjects()
{
// remove references to unit
for(std::list<GameObject*>::iterator i = m_gameObj.begin(); i != m_gameObj.end();)
for(GameObjectList::iterator i = m_gameObj.begin(); i != m_gameObj.end();)
{
(*i)->SetOwnerGUID(0);
(*i)->SetRespawnTime(0);
@ -7173,9 +7166,6 @@ bool Unit::Attack(Unit *victim, bool meleeAttack)
m_attacking = victim;
m_attacking->_addAttacker(this);
if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->AI())
((Creature*)m_attacking)->AI()->AttackedBy(this);
if(GetTypeId()==TYPEID_UNIT)
{
WorldPacket data(SMSG_AI_REACTION, 12);
@ -7291,7 +7281,51 @@ void Unit::RemoveAllAttackers()
void Unit::ModifyAuraState(AuraState flag, bool apply)
{
ApplyModFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1), apply);
if (apply)
{
if (!HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1)))
{
SetFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1));
if(GetTypeId() == TYPEID_PLAYER)
{
const PlayerSpellMap& sp_list = ((Player*)this)->GetSpellMap();
for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
{
if(itr->second->state == PLAYERSPELL_REMOVED) continue;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
if (!spellInfo || !IsPassiveSpell(itr->first)) continue;
if (spellInfo->CasterAuraState == flag)
CastSpell(this, itr->first, true, NULL);
}
}
}
}
else
{
if (HasFlag(UNIT_FIELD_AURASTATE,1<<(flag-1)))
{
RemoveFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1));
Unit::AuraMap& tAuras = GetAuras();
for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
{
SpellEntry const* spellProto = (*itr).second->GetSpellProto();
if (spellProto->CasterAuraState == flag)
{
// exceptions (applied at state but not removed at state change)
// Rampage
if(spellProto->SpellIconID==2006 && spellProto->SpellFamilyName==SPELLFAMILY_WARRIOR && spellProto->SpellFamilyFlags==0x100000)
{
++itr;
continue;
}
RemoveAura(itr);
}
else
++itr;
}
}
}
}
Unit *Unit::GetOwner() const
@ -10746,8 +10780,8 @@ void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID)
// attack caster if can
Unit* caster = ObjectAccessor::GetObjectInWorld(casterGUID, (Unit*)NULL);
if(caster && caster != getVictim() && ((Creature*)this)->AI())
((Creature*)this)->AI()->AttackStart(caster);
if(caster && ((Creature*)this)->AI())
((Creature*)this)->AI()->AttackedBy(caster);
}
}