mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
Merge branch 'master' into 310
This commit is contained in:
commit
d6f6272f8c
41 changed files with 759 additions and 615 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue