Merge branch 'master' into 308

This commit is contained in:
tomrus88 2009-01-21 10:59:27 +03:00
commit 8ffa79211b
129 changed files with 3156 additions and 1666 deletions

View file

@ -682,19 +682,23 @@ void Spell::prepareDataForTriggerSystem()
// Ñan spell trigger another or not ( m_canTrigger )
// Create base triggers flags for Attacker and Victim ( m_procAttacker and m_procVictim)
//==========================================================================================
// Fill flag can spell trigger or not
if (!m_IsTriggeredSpell)
// TODO: possible exist spell attribute for this
m_canTrigger = false;
if (m_CastItem)
m_canTrigger = false; // Do not trigger from item cast spell
else if (!m_IsTriggeredSpell)
m_canTrigger = true; // Normal cast - can trigger
else if (!m_triggeredByAuraSpell)
m_canTrigger = true; // Triggered from SPELL_EFFECT_TRIGGER_SPELL - can trigger
else // Exceptions (some periodic triggers)
if (!m_canTrigger) // Exceptions (some periodic triggers)
{
m_canTrigger = false; // Triggered spells can`t trigger another
switch (m_spellInfo->SpellFamilyName)
{
case SPELLFAMILY_MAGE: // Arcane Missles triggers need do it
if (m_spellInfo->SpellFamilyFlags & 0x0000000000200000LL) m_canTrigger = true;
case SPELLFAMILY_MAGE: // Arcane Missles / Blizzard triggers need do it
if (m_spellInfo->SpellFamilyFlags & 0x0000000000200080LL) m_canTrigger = true;
break;
case SPELLFAMILY_WARLOCK: // For Hellfire Effect / Rain of Fire / Seed of Corruption triggers need do it
if (m_spellInfo->SpellFamilyFlags & 0x0000800000000060LL) m_canTrigger = true;
@ -702,17 +706,17 @@ void Spell::prepareDataForTriggerSystem()
case SPELLFAMILY_PRIEST: // For Penance heal/damage triggers need do it
if (m_spellInfo->SpellFamilyFlags & 0x0001800000000000LL) m_canTrigger = true;
break;
case SPELLFAMILY_HUNTER: // Hunter Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect
if (m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL) m_canTrigger = true;
case SPELLFAMILY_ROGUE: // For poisons need do it
if (m_spellInfo->SpellFamilyFlags & 0x000000101001E000LL) m_canTrigger = true;
break;
case SPELLFAMILY_HUNTER: // Hunter Rapid Killing/Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect
if (m_spellInfo->SpellFamilyFlags & 0x0100200000000014LL) m_canTrigger = true;
break;
case SPELLFAMILY_PALADIN: // For Holy Shock triggers need do it
if (m_spellInfo->SpellFamilyFlags & 0x0001000000200000LL) m_canTrigger = true;
break;
}
}
// Do not trigger from item cast spell
if (m_CastItem)
m_canTrigger = false;
// Get data for type of attack and fill base info for trigger
switch (m_spellInfo->DmgClass)
@ -763,8 +767,6 @@ void Spell::CleanupTargetList()
m_UniqueTargetInfo.clear();
m_UniqueGOTargetInfo.clear();
m_UniqueItemInfo.clear();
m_countOfHit = 0;
m_countOfMiss = 0;
m_delayMoment = 0;
}
@ -773,6 +775,9 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
if( m_spellInfo->Effect[effIndex]==0 )
return;
// Check for effect immune skip if immuned
bool immuned = pVictim->IsImmunedToSpellEffect(m_spellInfo, effIndex);
uint64 targetGUID = pVictim->GetGUID();
// Lookup target in already in list
@ -780,7 +785,8 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
{
if (targetGUID == ihit->targetGUID) // Found in list
{
ihit->effectMask |= 1<<effIndex; // Add only effect mask
if (!immuned)
ihit->effectMask |= 1<<effIndex; // Add only effect mask if not immuned
return;
}
}
@ -790,15 +796,11 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
// Get spell hit result on target
TargetInfo target;
target.targetGUID = targetGUID; // Store target GUID
target.effectMask = 1<<effIndex; // Store index of effect
target.effectMask = immuned ? 0 : 1<<effIndex; // Store index of effect if not immuned
target.processed = false; // Effects not apply on target
// Calculate hit result
target.missCondition = m_caster->SpellHitResult(pVictim, m_spellInfo, m_canReflect);
if (target.missCondition == SPELL_MISS_NONE)
++m_countOfHit;
else
++m_countOfMiss;
// Spell have speed - need calculate incoming time
if (m_spellInfo->speed > 0.0f)
@ -878,8 +880,6 @@ void Spell::AddGOTarget(GameObject* pVictim, uint32 effIndex)
else
target.timeDelay = 0LL;
++m_countOfHit;
// Add target to list
m_UniqueGOTargetInfo.push_back(target);
}
@ -922,8 +922,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Get mask of effects for target
uint32 mask = target->effectMask;
if (mask == 0) // No effects
return;
Unit* unit = m_caster->GetGUID()==target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster,target->targetGUID);
if (!unit)
@ -1101,30 +1099,24 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
return;
}
// exclude Arcane Missiles Dummy Aura aura for now (attack on hit)
// TODO: find way to not need this?
if(!(m_spellInfo->SpellFamilyName == SPELLFAMILY_MAGE &&
m_spellInfo->SpellFamilyFlags & 0x800LL))
unit->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
if( !(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO) )
{
unit->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
if(!unit->IsStandState() && !unit->hasUnitState(UNIT_STAT_STUNNED))
unit->SetStandState(PLAYER_STATE_NONE);
if( !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) )
if(!unit->isInCombat() && unit->GetTypeId() != TYPEID_PLAYER && ((Creature*)unit)->AI())
((Creature*)unit)->AI()->AttackStart(m_caster);
unit->SetInCombatWith(m_caster);
m_caster->SetInCombatWith(unit);
if(Player *attackedPlayer = unit->GetCharmerOrOwnerPlayerOrPlayerItself())
{
if(!unit->IsStandState() && !unit->hasUnitState(UNIT_STAT_STUNNED))
unit->SetStandState(PLAYER_STATE_NONE);
if(!unit->isInCombat() && unit->GetTypeId() != TYPEID_PLAYER && ((Creature*)unit)->AI())
((Creature*)unit)->AI()->AttackStart(m_caster);
unit->SetInCombatWith(m_caster);
m_caster->SetInCombatWith(unit);
if(Player *attackedPlayer = unit->GetCharmerOrOwnerPlayerOrPlayerItself())
{
m_caster->SetContestedPvP(attackedPlayer);
}
unit->AddThreat(m_caster, 0.0f);
m_caster->SetContestedPvP(attackedPlayer);
}
unit->AddThreat(m_caster, 0.0f);
}
}
else
@ -1139,7 +1131,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
// assisting case, healing and resurrection
if(unit->hasUnitState(UNIT_STAT_ATTACK_PLAYER))
m_caster->SetContestedPvP();
if( unit->isInCombat() && !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) )
if( unit->isInCombat() && !(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO) )
{
m_caster->SetInCombatState(unit->GetCombatTimer() > 0);
unit->getHostilRefManager().threatAssist(m_caster, 0.0f);
@ -2046,7 +2038,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
}
}
void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura)
{
m_targets = *targets;
@ -2997,7 +2989,23 @@ void Spell::WriteAmmoToPacket( WorldPacket * data )
void Spell::WriteSpellGoTargets( WorldPacket * data )
{
*data << (uint8)m_countOfHit;
uint32 hit = m_UniqueGOTargetInfo.size(); // Always hits on GO
uint32 miss = 0;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
{
if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
{
// possibly SPELL_MISS_IMMUNE2 for this??
ihit->missCondition = SPELL_MISS_IMMUNE2;
miss++;
}
else if ((*ihit).missCondition == SPELL_MISS_NONE)
hit++;
else
miss++;
}
*data << (uint8)hit;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
*data << uint64(ihit->targetGUID);
@ -3005,7 +3013,7 @@ void Spell::WriteSpellGoTargets( WorldPacket * data )
for(std::list<GOTargetInfo>::iterator ighit= m_UniqueGOTargetInfo.begin();ighit != m_UniqueGOTargetInfo.end();++ighit)
*data << uint64(ighit->targetGUID); // Always hits
*data << (uint8)m_countOfMiss;
*data << (uint8)miss;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
{
if( ihit->missCondition != SPELL_MISS_NONE ) // Add only miss
@ -3080,7 +3088,7 @@ void Spell::SendLogExecute()
data << uint8(0);
break;
case SPELL_EFFECT_CREATE_ITEM:
case SPELL_EFFECT_157:
case SPELL_EFFECT_CREATE_ITEM_2:
data << uint32(m_spellInfo->EffectItemType[0]);
break;
case SPELL_EFFECT_SUMMON:
@ -3513,16 +3521,11 @@ void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTar
gameObjTarget = pGOTarget;
uint8 eff = m_spellInfo->Effect[i];
uint32 mechanic = m_spellInfo->EffectMechanic[i];
damage = int32(CalculateDamage((uint8)i,unitTarget)*DamageMultiplier);
sLog.outDebug( "Spell: Effect : %u", eff);
//Simply return. Do not display "immune" in red text on client
if(unitTarget && unitTarget->IsImmunedToSpellEffect(eff, mechanic))
return;
if(eff<TOTAL_SPELL_EFFECTS)
{
//sLog.outDebug( "WORLD: Spell FX %d < TOTAL_SPELL_EFFECTS ", eff);
@ -3655,6 +3658,20 @@ uint8 Spell::CanCast(bool strict)
}
}
}
else if (m_caster->GetTypeId()==TYPEID_PLAYER) // Target - is player caster
{
// Additional check for some spells
// If 0 spell effect empty - client not send target data (need use selection)
// TODO: check it on next client version
if (m_targets.m_targetMask == TARGET_FLAG_SELF &&
m_spellInfo->Effect[0] == 0 && m_spellInfo->EffectImplicitTargetA[1] != TARGET_SELF)
{
if (target = m_caster->GetUnit(*m_caster, ((Player *)m_caster)->GetSelection()))
m_targets.setUnitTarget(target);
else
return SPELL_FAILED_BAD_TARGETS;
}
}
// check pet presents
for(int j=0;j<3;j++)