Merge
--HG-- branch : trunk
This commit is contained in:
@@ -2320,7 +2320,7 @@ void Unit::CalcHealAbsorb(Unit *pVictim, const SpellEntry *healSpell, uint32 &he
|
||||
healAmount = RemainingHeal;
|
||||
}
|
||||
|
||||
void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool /*extra*/)
|
||||
void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool extra)
|
||||
{
|
||||
if (hasUnitState(UNIT_STAT_CANNOT_AUTOATTACK) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
|
||||
return;
|
||||
@@ -2339,36 +2339,46 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool /*
|
||||
else
|
||||
return; // ignore ranged case
|
||||
|
||||
// melee attack spell casted at main hand attack only
|
||||
// melee attack spell casted at main hand attack only - no normal melee dmg dealt
|
||||
if (attType == BASE_ATTACK && m_currentSpells[CURRENT_MELEE_SPELL])
|
||||
{
|
||||
m_currentSpells[CURRENT_MELEE_SPELL]->cast();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// attack can be redirected to another target
|
||||
pVictim = SelectMagnetTarget(pVictim);
|
||||
|
||||
CalcDamageInfo damageInfo;
|
||||
CalculateMeleeDamage(pVictim, 0, &damageInfo, attType);
|
||||
// Send log damage message to client
|
||||
DealDamageMods(pVictim, damageInfo.damage, &damageInfo.absorb);
|
||||
SendAttackStateUpdate(&damageInfo);
|
||||
|
||||
ProcDamageAndSpell(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, damageInfo.damage, damageInfo.attackType);
|
||||
DealMeleeDamage(&damageInfo,true);
|
||||
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
sLog.outStaticDebug("AttackerStateUpdate: (Player) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.",
|
||||
GetGUIDLow(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist);
|
||||
else
|
||||
sLog.outStaticDebug("AttackerStateUpdate: (NPC) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.",
|
||||
GetGUIDLow(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist);
|
||||
|
||||
// if damage pVictim call AI reaction
|
||||
//if (pVictim->GetTypeId() == TYPEID_UNIT && pVictim->ToCreature()->AI())
|
||||
// pVictim->ToCreature()->AI()->AttackedBy(this);
|
||||
}
|
||||
|
||||
// attack can be redirected to another target
|
||||
pVictim = SelectMagnetTarget(pVictim);
|
||||
|
||||
CalcDamageInfo damageInfo;
|
||||
CalculateMeleeDamage(pVictim, 0, &damageInfo, attType);
|
||||
// Send log damage message to client
|
||||
DealDamageMods(pVictim, damageInfo.damage, &damageInfo.absorb);
|
||||
SendAttackStateUpdate(&damageInfo);
|
||||
|
||||
ProcDamageAndSpell(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, damageInfo.damage, damageInfo.attackType);
|
||||
DealMeleeDamage(&damageInfo,true);
|
||||
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
sLog.outStaticDebug("AttackerStateUpdate: (Player) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.",
|
||||
GetGUIDLow(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist);
|
||||
else
|
||||
sLog.outStaticDebug("AttackerStateUpdate: (NPC) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.",
|
||||
GetGUIDLow(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist);
|
||||
|
||||
// if damage pVictim call AI reaction
|
||||
//if (pVictim->GetTypeId() == TYPEID_UNIT && pVictim->ToCreature()->AI())
|
||||
// pVictim->ToCreature()->AI()->AttackedBy(this);
|
||||
|
||||
if(!extra && m_extraAttacks)
|
||||
{
|
||||
while(m_extraAttacks)
|
||||
{
|
||||
AttackerStateUpdate(pVictim, BASE_ATTACK, true);
|
||||
if(m_extraAttacks > 0)
|
||||
--m_extraAttacks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit *pVictim, WeaponAttackType attType) const
|
||||
|
||||
+141
-111
@@ -532,6 +532,7 @@ m_caster(Caster), m_spellValue(new SpellValue(m_spellInfo))
|
||||
}
|
||||
|
||||
CleanupTargetList();
|
||||
CleanupEffectExecuteData();
|
||||
}
|
||||
|
||||
Spell::~Spell()
|
||||
@@ -555,6 +556,8 @@ Spell::~Spell()
|
||||
if (m_caster && m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
ASSERT(m_caster->ToPlayer()->m_spellModTakingSpell != this);
|
||||
delete m_spellValue;
|
||||
|
||||
CheckEffectExecuteData();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -2218,7 +2221,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
|
||||
Unit *target = m_targets.getUnitTarget();
|
||||
if (!target)
|
||||
{
|
||||
sLog.outError("SPELL: no unit target for spell ID %u\n", m_spellInfo->Id);
|
||||
sLog.outError("SPELL: no unit target for spell ID %u", m_spellInfo->Id);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2261,7 +2264,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
|
||||
{
|
||||
if (!m_targets.HasDst())
|
||||
{
|
||||
sLog.outError("SPELL: no destination for spell ID %u\n", m_spellInfo->Id);
|
||||
sLog.outError("SPELL: no destination for spell ID %u", m_spellInfo->Id);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3360,6 +3363,8 @@ void Spell::handle_immediate()
|
||||
}
|
||||
}
|
||||
|
||||
PrepareTargetProcessing();
|
||||
|
||||
// process immediate effects (items, ground, etc.) also initialize some variables
|
||||
_handle_immediate_phase();
|
||||
|
||||
@@ -3369,6 +3374,8 @@ void Spell::handle_immediate()
|
||||
for (std::list<GOTargetInfo>::iterator ihit= m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
|
||||
DoAllEffectOnTarget(&(*ihit));
|
||||
|
||||
FinishTargetProcessing();
|
||||
|
||||
// spell is finished, perform some last features of the spell here
|
||||
_handle_finish_phase();
|
||||
|
||||
@@ -3388,6 +3395,8 @@ uint64 Spell::handle_delayed(uint64 t_offset)
|
||||
|
||||
uint64 next_time = 0;
|
||||
|
||||
PrepareTargetProcessing();
|
||||
|
||||
if (!m_immediateHandled)
|
||||
{
|
||||
_handle_immediate_phase();
|
||||
@@ -3420,6 +3429,8 @@ uint64 Spell::handle_delayed(uint64 t_offset)
|
||||
}
|
||||
}
|
||||
|
||||
FinishTargetProcessing();
|
||||
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
|
||||
|
||||
@@ -3449,7 +3460,6 @@ void Spell::_handle_immediate_phase()
|
||||
|
||||
PrepareScriptHitHandlers();
|
||||
|
||||
m_needSpellLog = IsNeedSendToClient();
|
||||
for (uint32 j = 0; j < 3; ++j)
|
||||
{
|
||||
if (m_spellInfo->Effect[j] == 0)
|
||||
@@ -3461,10 +3471,6 @@ void Spell::_handle_immediate_phase()
|
||||
HandleEffects(NULL, NULL, NULL, j);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't do spell log, if is school damage spell
|
||||
if (m_spellInfo->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE || m_spellInfo->Effect[j] == 0)
|
||||
m_needSpellLog = false;
|
||||
}
|
||||
|
||||
// initialize Diminishing Returns Data
|
||||
@@ -3543,10 +3549,6 @@ void Spell::_handle_finish_phase()
|
||||
if (m_comboPointGain)
|
||||
m_caster->m_movedPlayer->GainSpellComboPoints(m_comboPointGain);
|
||||
}
|
||||
|
||||
// spell log
|
||||
if (m_needSpellLog)
|
||||
SendLogExecute();
|
||||
}
|
||||
|
||||
void Spell::SendSpellCooldown()
|
||||
@@ -3713,10 +3715,6 @@ void Spell::finish(bool ok)
|
||||
}
|
||||
}
|
||||
|
||||
// Okay to remove extra attacks
|
||||
if (IsSpellHaveEffect(m_spellInfo, SPELL_EFFECT_ADD_EXTRA_ATTACKS))
|
||||
m_caster->m_extraAttacks = 0;
|
||||
|
||||
if (IsMeleeAttackResetSpell())
|
||||
{
|
||||
bool found = false;
|
||||
@@ -4119,112 +4117,105 @@ void Spell::WriteSpellGoTargets(WorldPacket * data)
|
||||
|
||||
void Spell::SendLogExecute()
|
||||
{
|
||||
Unit *target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster;
|
||||
|
||||
WorldPacket data(SMSG_SPELLLOGEXECUTE, (8+4+4+4+4+8));
|
||||
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
data.append(m_caster->GetPackGUID());
|
||||
else
|
||||
data.append(target->GetPackGUID());
|
||||
data.append(m_caster->GetPackGUID());
|
||||
|
||||
data << uint32(m_spellInfo->Id);
|
||||
uint32 count1 = 1;
|
||||
data << uint32(count1); // count1 (effect count?)
|
||||
for (uint32 i = 0; i < count1; ++i)
|
||||
|
||||
uint8 effCount = 0;
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
data << uint32(m_spellInfo->Effect[0]); // spell effect
|
||||
uint32 count2 = 1;
|
||||
data << uint32(count2); // count2 (target count?)
|
||||
for (uint32 j = 0; j < count2; ++j)
|
||||
{
|
||||
switch(m_spellInfo->Effect[0])
|
||||
{
|
||||
case SPELL_EFFECT_POWER_DRAIN:
|
||||
if (Unit *unit = m_targets.getUnitTarget())
|
||||
data.append(unit->GetPackGUID());
|
||||
else
|
||||
data << uint8(0);
|
||||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
data << float(0);
|
||||
break;
|
||||
case SPELL_EFFECT_ADD_EXTRA_ATTACKS:
|
||||
if (Unit *unit = m_targets.getUnitTarget())
|
||||
data.append(unit->GetPackGUID());
|
||||
else
|
||||
data << uint8(0);
|
||||
data << uint32(m_caster->m_extraAttacks);
|
||||
break;
|
||||
case SPELL_EFFECT_INTERRUPT_CAST:
|
||||
if (Unit *unit = m_targets.getUnitTarget())
|
||||
data.append(unit->GetPackGUID());
|
||||
else
|
||||
data << uint8(0);
|
||||
data << uint32(0); // spellid
|
||||
break;
|
||||
case SPELL_EFFECT_DURABILITY_DAMAGE:
|
||||
if (Unit *unit = m_targets.getUnitTarget())
|
||||
data.append(unit->GetPackGUID());
|
||||
else
|
||||
data << uint8(0);
|
||||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
break;
|
||||
case SPELL_EFFECT_OPEN_LOCK:
|
||||
if (Item *item = m_targets.getItemTarget())
|
||||
data.append(item->GetPackGUID());
|
||||
else
|
||||
data << uint8(0);
|
||||
break;
|
||||
case SPELL_EFFECT_CREATE_ITEM:
|
||||
case SPELL_EFFECT_CREATE_ITEM_2:
|
||||
data << uint32(m_spellInfo->EffectItemType[0]);
|
||||
break;
|
||||
case SPELL_EFFECT_SUMMON:
|
||||
case SPELL_EFFECT_TRANS_DOOR:
|
||||
case SPELL_EFFECT_SUMMON_PET:
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_WILD:
|
||||
case SPELL_EFFECT_CREATE_HOUSE:
|
||||
case SPELL_EFFECT_DUEL:
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_SLOT1:
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_SLOT2:
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_SLOT3:
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_SLOT4:
|
||||
if (Unit *unit = m_targets.getUnitTarget())
|
||||
data.append(unit->GetPackGUID());
|
||||
else if (m_targets.getItemTargetGUID())
|
||||
data.appendPackGUID(m_targets.getItemTargetGUID());
|
||||
else if (GameObject *go = m_targets.getGOTarget())
|
||||
data.append(go->GetPackGUID());
|
||||
else
|
||||
data << uint8(0); // guid
|
||||
break;
|
||||
case SPELL_EFFECT_FEED_PET:
|
||||
data << uint32(m_targets.getItemTargetEntry());
|
||||
break;
|
||||
case SPELL_EFFECT_DISMISS_PET:
|
||||
if (Unit *unit = m_targets.getUnitTarget())
|
||||
data.append(unit->GetPackGUID());
|
||||
else
|
||||
data << uint8(0);
|
||||
break;
|
||||
case SPELL_EFFECT_RESURRECT:
|
||||
case SPELL_EFFECT_RESURRECT_NEW:
|
||||
if (Unit *unit = m_targets.getUnitTarget())
|
||||
data.append(unit->GetPackGUID());
|
||||
else
|
||||
data << uint8(0);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (m_effectExecuteData[i])
|
||||
++effCount;
|
||||
}
|
||||
|
||||
if (!effCount)
|
||||
return;
|
||||
|
||||
data << uint32(effCount);
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
if (!m_effectExecuteData[i])
|
||||
continue;
|
||||
|
||||
data << uint32(m_spellInfo->Effect[i]); // spell effect
|
||||
|
||||
data.append(*m_effectExecuteData[i]);
|
||||
|
||||
delete m_effectExecuteData[i];
|
||||
m_effectExecuteData[i] = NULL;
|
||||
}
|
||||
m_caster->SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
void Spell::ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit * target, uint32 powerType, uint32 powerTaken, float gainMultiplier)
|
||||
{
|
||||
InitEffectExecuteData(effIndex);
|
||||
m_effectExecuteData[effIndex]->append(target->GetPackGUID());
|
||||
*m_effectExecuteData[effIndex] << uint32(powerType);
|
||||
*m_effectExecuteData[effIndex] << uint32(powerTaken);
|
||||
*m_effectExecuteData[effIndex] << float(gainMultiplier);
|
||||
}
|
||||
|
||||
void Spell::ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit * victim, uint32 attCount)
|
||||
{
|
||||
InitEffectExecuteData(effIndex);
|
||||
m_effectExecuteData[effIndex]->append(victim->GetPackGUID());
|
||||
*m_effectExecuteData[effIndex] << uint32(attCount);
|
||||
}
|
||||
|
||||
void Spell::ExecuteLogEffectInterruptCast(uint8 effIndex, Unit * victim, uint32 spellId)
|
||||
{
|
||||
InitEffectExecuteData(effIndex);
|
||||
m_effectExecuteData[effIndex]->append(victim->GetPackGUID());
|
||||
*m_effectExecuteData[effIndex] << uint32(spellId);
|
||||
}
|
||||
|
||||
void Spell::ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit * victim, uint32 itemslot, uint32 damage)
|
||||
{
|
||||
InitEffectExecuteData(effIndex);
|
||||
m_effectExecuteData[effIndex]->append(victim->GetPackGUID());
|
||||
*m_effectExecuteData[effIndex] << uint32(itemslot);
|
||||
*m_effectExecuteData[effIndex] << uint32(damage);
|
||||
}
|
||||
|
||||
void Spell::ExecuteLogEffectOpenLock(uint8 effIndex, Object * obj)
|
||||
{
|
||||
InitEffectExecuteData(effIndex);
|
||||
m_effectExecuteData[effIndex]->append(obj->GetPackGUID());
|
||||
}
|
||||
|
||||
void Spell::ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
|
||||
{
|
||||
InitEffectExecuteData(effIndex);
|
||||
*m_effectExecuteData[effIndex] << uint32(entry);
|
||||
}
|
||||
|
||||
void Spell::ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
|
||||
{
|
||||
InitEffectExecuteData(effIndex);
|
||||
*m_effectExecuteData[effIndex] << uint32(entry);
|
||||
}
|
||||
|
||||
void Spell::ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject * obj)
|
||||
{
|
||||
InitEffectExecuteData(effIndex);
|
||||
m_effectExecuteData[effIndex]->append(obj->GetPackGUID());
|
||||
}
|
||||
|
||||
void Spell::ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject * obj)
|
||||
{
|
||||
InitEffectExecuteData(effIndex);
|
||||
m_effectExecuteData[effIndex]->append(obj->GetPackGUID());
|
||||
}
|
||||
|
||||
void Spell::ExecuteLogEffectResurrect(uint8 effIndex, Unit * target)
|
||||
{
|
||||
InitEffectExecuteData(effIndex);
|
||||
m_effectExecuteData[effIndex]->append(target->GetPackGUID());
|
||||
}
|
||||
|
||||
void Spell::SendInterrupted(uint8 result)
|
||||
{
|
||||
WorldPacket data(SMSG_SPELL_FAILURE, (8+4+1));
|
||||
@@ -7263,6 +7254,45 @@ void Spell::SelectTrajTargets()
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::PrepareTargetProcessing()
|
||||
{
|
||||
CheckEffectExecuteData();
|
||||
}
|
||||
|
||||
void Spell::FinishTargetProcessing()
|
||||
{
|
||||
SendLogExecute();
|
||||
}
|
||||
|
||||
void Spell::InitEffectExecuteData(uint8 effIndex)
|
||||
{
|
||||
ASSERT(effIndex < MAX_SPELL_EFFECTS);
|
||||
if (!m_effectExecuteData[effIndex])
|
||||
{
|
||||
m_effectExecuteData[effIndex] = new ByteBuffer();
|
||||
// first dword - target counter
|
||||
*m_effectExecuteData[effIndex] << uint32(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// increase target counter by one
|
||||
uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
|
||||
(*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::CleanupEffectExecuteData()
|
||||
{
|
||||
for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
m_effectExecuteData[i] = NULL;
|
||||
}
|
||||
|
||||
void Spell::CheckEffectExecuteData()
|
||||
{
|
||||
for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
ASSERT(!m_effectExecuteData[i]);
|
||||
}
|
||||
|
||||
void Spell::LoadScripts()
|
||||
{
|
||||
sLog.outDebug("Spell::LoadScripts");
|
||||
|
||||
@@ -32,6 +32,7 @@ class DynamicObject;
|
||||
class WorldObject;
|
||||
class Aura;
|
||||
class SpellScript;
|
||||
class ByteBuffer;
|
||||
|
||||
struct SpellEntry;
|
||||
|
||||
@@ -475,6 +476,16 @@ class Spell
|
||||
void SendSpellGo();
|
||||
void SendSpellCooldown();
|
||||
void SendLogExecute();
|
||||
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit * target, uint32 powerType, uint32 powerTaken, float gainMultiplier);
|
||||
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit * victim, uint32 attCount);
|
||||
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit * victim, uint32 spellId);
|
||||
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit * victim, uint32 itemslot, uint32 damage);
|
||||
void ExecuteLogEffectOpenLock(uint8 effIndex, Object * obj);
|
||||
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry);
|
||||
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry);
|
||||
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject * obj);
|
||||
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject * obj);
|
||||
void ExecuteLogEffectResurrect(uint8 effIndex, Unit * target);
|
||||
void SendInterrupted(uint8 result);
|
||||
void SendChannelUpdate(uint32 time);
|
||||
void SendChannelStart(uint32 duration);
|
||||
@@ -573,7 +584,6 @@ class Spell
|
||||
// These vars are used in both delayed spell system and modified immediate spell system
|
||||
bool m_referencedFromCurrentSpell; // mark as references to prevent deleted and access by dead pointers
|
||||
bool m_executedCurrently; // mark as executed to prevent deleted and access by dead pointers
|
||||
bool m_needSpellLog; // need to send spell log?
|
||||
bool m_needComboPoints;
|
||||
|
||||
// Current targets, to be used in SpellEffects (MUST BE USED ONLY IN SPELL EFFECTS)
|
||||
@@ -662,6 +672,14 @@ class Spell
|
||||
void SpellDamageWeaponDmg(uint32 i);
|
||||
void SpellDamageHeal(uint32 i);
|
||||
|
||||
void PrepareTargetProcessing();
|
||||
void FinishTargetProcessing();
|
||||
|
||||
// spell execution log
|
||||
void InitEffectExecuteData(uint8 effIndex);
|
||||
void CleanupEffectExecuteData();
|
||||
void CheckEffectExecuteData();
|
||||
|
||||
// Scripting system
|
||||
void LoadScripts();
|
||||
void PrepareScriptHitHandlers();
|
||||
@@ -698,6 +716,8 @@ class Spell
|
||||
uint32 m_effectMask;
|
||||
uint8 m_auraScaleMask;
|
||||
|
||||
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS];
|
||||
|
||||
#ifdef MAP_BASED_RAND_GEN
|
||||
int32 irand(int32 min, int32 max) { return int32 (m_caster->GetMap()->mtRand.randInt(max - min)) + min; }
|
||||
uint32 urand(uint32 min, uint32 max) { return m_caster->GetMap()->mtRand.randInt(max - min) + min; }
|
||||
|
||||
@@ -260,6 +260,7 @@ void Spell::EffectResurrectNew(uint32 i)
|
||||
|
||||
uint32 health = damage;
|
||||
uint32 mana = m_spellInfo->EffectMiscValue[i];
|
||||
ExecuteLogEffectResurrect(i, pTarget);
|
||||
pTarget->setResurrectRequestData(m_caster->GetGUID(), m_caster->GetMapId(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), health, mana);
|
||||
SendResurrectRequest(pTarget);
|
||||
}
|
||||
@@ -2352,15 +2353,18 @@ void Spell::EffectPowerDrain(uint32 i)
|
||||
|
||||
int32 newDamage = unitTarget->ModifyPower(powerType, -int32(power));
|
||||
|
||||
float gainMultiplier = 0.0f;
|
||||
|
||||
// Don`t restore from self drain
|
||||
if (m_caster != unitTarget)
|
||||
{
|
||||
float gainMultiplier = SpellMgr::CalculateSpellEffectValueMultiplier(m_spellInfo, i, m_originalCaster, this);
|
||||
gainMultiplier = SpellMgr::CalculateSpellEffectValueMultiplier(m_spellInfo, i, m_originalCaster, this);
|
||||
|
||||
int32 gain = int32(newDamage * gainMultiplier);
|
||||
|
||||
m_caster->EnergizeBySpell(m_caster, m_spellInfo->Id, gain, powerType);
|
||||
}
|
||||
ExecuteLogEffectTakeTargetPower(i, unitTarget, powerType, newDamage, gainMultiplier);
|
||||
}
|
||||
|
||||
void Spell::EffectSendEvent(uint32 EffectIndex)
|
||||
@@ -2413,7 +2417,8 @@ void Spell::EffectPowerBurn(uint32 i)
|
||||
|
||||
newDamage = int32(newDamage * dmgMultiplier);
|
||||
|
||||
//TODO: no log
|
||||
ExecuteLogEffectTakeTargetPower(i,unitTarget, powerType, newDamage, dmgMultiplier);
|
||||
|
||||
if (m_originalCaster)
|
||||
m_originalCaster->DealDamage(unitTarget, newDamage);
|
||||
}
|
||||
@@ -2714,6 +2719,7 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype)
|
||||
void Spell::EffectCreateItem(uint32 i)
|
||||
{
|
||||
DoCreateItem(i,m_spellInfo->EffectItemType[i]);
|
||||
ExecuteLogEffectCreateItem(i, m_spellInfo->EffectItemType[i]);
|
||||
}
|
||||
|
||||
void Spell::EffectCreateItem2(uint32 i)
|
||||
@@ -2745,6 +2751,7 @@ void Spell::EffectCreateItem2(uint32 i)
|
||||
else
|
||||
player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
|
||||
}
|
||||
// TODO: ExecuteLogEffectCreateItem(i, m_spellInfo->EffectItemType[i]);
|
||||
}
|
||||
|
||||
void Spell::EffectCreateRandomItem(uint32 /*i*/)
|
||||
@@ -2755,6 +2762,7 @@ void Spell::EffectCreateRandomItem(uint32 /*i*/)
|
||||
|
||||
// create some random items
|
||||
player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell);
|
||||
// TODO: ExecuteLogEffectCreateItem(i, m_spellInfo->EffectItemType[i]);
|
||||
}
|
||||
|
||||
void Spell::EffectPersistentAA(uint32 i)
|
||||
@@ -3069,6 +3077,7 @@ void Spell::EffectOpenLock(uint32 effIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
ExecuteLogEffectOpenLock(effIndex, gameObjTarget ? (Object*)gameObjTarget : (Object*)itemTarget);
|
||||
}
|
||||
|
||||
void Spell::EffectSummonChangeItem(uint32 i)
|
||||
@@ -3328,8 +3337,9 @@ void Spell::EffectSummonType(uint32 i)
|
||||
summon->setFaction(m_originalCaster->getFaction());
|
||||
summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
||||
}
|
||||
ExecuteLogEffectSummonObject(i, summon);
|
||||
}
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}//switch
|
||||
break;
|
||||
@@ -3363,6 +3373,7 @@ void Spell::EffectSummonType(uint32 i)
|
||||
{
|
||||
summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
||||
summon->SetCreatorGUID(m_originalCaster->GetGUID());
|
||||
ExecuteLogEffectSummonObject(i, summon);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4032,6 +4043,8 @@ void Spell::EffectSummonPet(uint32 i)
|
||||
std::string new_name=sObjectMgr.GeneratePetName(petentry);
|
||||
if (!new_name.empty())
|
||||
pet->SetName(new_name);
|
||||
|
||||
ExecuteLogEffectSummonObject(i, pet);
|
||||
}
|
||||
|
||||
void Spell::EffectLearnPetSpell(uint32 i)
|
||||
@@ -4438,7 +4451,7 @@ void Spell::EffectHealMaxHealth(uint32 /*i*/)
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::EffectInterruptCast(uint32 /*i*/)
|
||||
void Spell::EffectInterruptCast(uint32 effIndex)
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
@@ -4462,6 +4475,7 @@ void Spell::EffectInterruptCast(uint32 /*i*/)
|
||||
int32 duration = m_originalCaster->ModSpellDuration(m_spellInfo, unitTarget, m_originalCaster->CalcSpellDuration(m_spellInfo), false);
|
||||
unitTarget->ProhibitSpellScholl(GetSpellSchoolMask(curSpellInfo), duration/*GetSpellDuration(m_spellInfo)*/);
|
||||
}
|
||||
ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
|
||||
unitTarget->InterruptSpell(CurrentSpellTypes(i), false);
|
||||
}
|
||||
}
|
||||
@@ -4498,6 +4512,8 @@ void Spell::EffectSummonObjectWild(uint32 i)
|
||||
pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
|
||||
pGameObj->SetSpellId(m_spellInfo->Id);
|
||||
|
||||
ExecuteLogEffectSummonObject(i, pGameObj);
|
||||
|
||||
// Wild object not have owner and check clickable by players
|
||||
map->Add(pGameObj);
|
||||
|
||||
@@ -4541,6 +4557,8 @@ void Spell::EffectSummonObjectWild(uint32 i)
|
||||
linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
|
||||
linkedGO->SetSpellId(m_spellInfo->Id);
|
||||
|
||||
ExecuteLogEffectSummonObject(i, linkedGO);
|
||||
|
||||
// Wild object not have owner and check clickable by players
|
||||
map->Add(linkedGO);
|
||||
}
|
||||
@@ -5705,6 +5723,8 @@ void Spell::EffectDuel(uint32 i)
|
||||
pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
|
||||
pGameObj->SetSpellId(m_spellInfo->Id);
|
||||
|
||||
ExecuteLogEffectSummonObject(i, pGameObj);
|
||||
|
||||
m_caster->AddGameObject(pGameObj);
|
||||
map->Add(pGameObj);
|
||||
//END
|
||||
@@ -5940,10 +5960,12 @@ void Spell::EffectFeedPet(uint32 i)
|
||||
_player->DestroyItemCount(foodItem,count,true);
|
||||
// TODO: fix crash when a spell has two effects, both pointed at the same item target
|
||||
|
||||
ExecuteLogEffectDestroyItem(i, foodItem->GetEntry());
|
||||
|
||||
m_caster->CastCustomSpell(pet, m_spellInfo->EffectTriggerSpell[i], &benefit, NULL, NULL, true);
|
||||
}
|
||||
|
||||
void Spell::EffectDismissPet(uint32 /*i*/)
|
||||
void Spell::EffectDismissPet(uint32 i)
|
||||
{
|
||||
if (m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
@@ -5954,6 +5976,7 @@ void Spell::EffectDismissPet(uint32 /*i*/)
|
||||
if (!pet||!pet->isAlive())
|
||||
return;
|
||||
|
||||
ExecuteLogEffectUnsummonObject(i, pet);
|
||||
m_caster->ToPlayer()->RemovePet(pet, PET_SAVE_NOT_IN_SLOT);
|
||||
}
|
||||
|
||||
@@ -6012,12 +6035,14 @@ void Spell::EffectSummonObject(uint32 i)
|
||||
pGameObj->SetSpellId(m_spellInfo->Id);
|
||||
m_caster->AddGameObject(pGameObj);
|
||||
|
||||
ExecuteLogEffectSummonObject(i, pGameObj);
|
||||
|
||||
map->Add(pGameObj);
|
||||
|
||||
m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
|
||||
}
|
||||
|
||||
void Spell::EffectResurrect(uint32 /*effIndex*/)
|
||||
void Spell::EffectResurrect(uint32 effIndex)
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
@@ -6066,32 +6091,23 @@ void Spell::EffectResurrect(uint32 /*effIndex*/)
|
||||
uint32 health = pTarget->CountPctFromMaxHealth(damage);
|
||||
uint32 mana = pTarget->GetMaxPower(POWER_MANA) * damage / 100;
|
||||
|
||||
ExecuteLogEffectResurrect(effIndex, pTarget);
|
||||
|
||||
pTarget->setResurrectRequestData(m_caster->GetGUID(), m_caster->GetMapId(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), health, mana);
|
||||
SendResurrectRequest(pTarget);
|
||||
}
|
||||
|
||||
void Spell::EffectAddExtraAttacks(uint32 /*i*/)
|
||||
void Spell::EffectAddExtraAttacks(uint32 i)
|
||||
{
|
||||
if (!unitTarget || !unitTarget->isAlive())
|
||||
if (!unitTarget || !unitTarget->isAlive() || !unitTarget->getVictim())
|
||||
return;
|
||||
|
||||
if (unitTarget->m_extraAttacks)
|
||||
return;
|
||||
|
||||
Unit *victim = unitTarget->getVictim();
|
||||
|
||||
// attack prevented
|
||||
// fixme, some attacks may not target current victim, this is right now not handled
|
||||
if (!victim || !unitTarget->IsWithinMeleeRange(victim) || !unitTarget->HasInArc(static_cast<float>(2*M_PI/3), victim))
|
||||
return;
|
||||
|
||||
// Only for proc/log informations
|
||||
unitTarget->m_extraAttacks = damage;
|
||||
// Need to send log before attack is made
|
||||
SendLogExecute();
|
||||
m_needSpellLog = false;
|
||||
|
||||
unitTarget->AttackerStateUpdate(victim, BASE_ATTACK, true);
|
||||
ExecuteLogEffectExtraAttacks(i, unitTarget->getVictim(), damage);
|
||||
}
|
||||
|
||||
void Spell::EffectParry(uint32 /*i*/)
|
||||
@@ -6500,6 +6516,8 @@ void Spell::EffectDurabilityDamage(uint32 i)
|
||||
|
||||
if (Item* item = unitTarget->ToPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
|
||||
unitTarget->ToPlayer()->DurabilityPointsLoss(item, damage);
|
||||
|
||||
ExecuteLogEffectDurabilityDamage(i, unitTarget, slot, damage);
|
||||
}
|
||||
|
||||
void Spell::EffectDurabilityDamagePCT(uint32 i)
|
||||
@@ -6646,6 +6664,8 @@ void Spell::EffectTransmitted(uint32 effIndex)
|
||||
//pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
|
||||
pGameObj->SetSpellId(m_spellInfo->Id);
|
||||
|
||||
ExecuteLogEffectSummonObject(effIndex, pGameObj);
|
||||
|
||||
sLog.outStaticDebug("AddObject at SpellEfects.cpp EffectTransmitted");
|
||||
//m_caster->AddGameObject(pGameObj);
|
||||
//m_ObjToDel.push_back(pGameObj);
|
||||
@@ -6663,6 +6683,8 @@ void Spell::EffectTransmitted(uint32 effIndex)
|
||||
linkedGO->SetSpellId(m_spellInfo->Id);
|
||||
linkedGO->SetOwnerGUID(m_caster->GetGUID());
|
||||
|
||||
ExecuteLogEffectSummonObject(effIndex, linkedGO);
|
||||
|
||||
linkedGO->GetMap()->Add(linkedGO);
|
||||
}
|
||||
else
|
||||
@@ -7086,6 +7108,8 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *
|
||||
summon->SetDisplayId(1126);
|
||||
|
||||
summon->AI()->EnterEvadeMode();
|
||||
|
||||
ExecuteLogEffectSummonObject(i, summon);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3862,6 +3862,19 @@ void SpellMgr::LoadSpellCustomAttr()
|
||||
mSpellCustomAttr[i] |= SPELL_ATTR_CU_IGNORE_ARMOR;
|
||||
count++;
|
||||
break;
|
||||
// THESE SPELLS ARE WORKING CORRECTLY EVEN WITHOUT THIS HACK
|
||||
// THE ONLY REASON ITS HERE IS THAT CURRENT GRID SYSTEM
|
||||
// DOES NOT ALLOW FAR OBJECT SELECTION (dist > 333)
|
||||
case 70781: // Light's Hammer Teleport
|
||||
case 70856: // Oratory of the Damned Teleport
|
||||
case 70857: // Rampart of Skulls Teleport
|
||||
case 70858: // Deathbringer's Rise Teleport
|
||||
case 70859: // Upper Spire Teleport
|
||||
case 70860: // Frozen Throne Teleport
|
||||
case 70861: // Sindragosa's Lair Teleport
|
||||
spellInfo->EffectImplicitTargetA[0] = TARGET_DST_DB;
|
||||
count++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1449,15 +1449,15 @@ void World::SetInitialWorldSettings()
|
||||
sLog.outString("Loading Graveyard-zone links...");
|
||||
sObjectMgr.LoadGraveyardZones();
|
||||
|
||||
sLog.outString("Loading Spell target coordinates...");
|
||||
sSpellMgr.LoadSpellTargetPositions();
|
||||
|
||||
sLog.outString("Loading spell pet auras...");
|
||||
sSpellMgr.LoadSpellPetAuras();
|
||||
|
||||
sLog.outString("Loading spell extra attributes...");
|
||||
sSpellMgr.LoadSpellCustomAttr();
|
||||
|
||||
sLog.outString("Loading Spell target coordinates...");
|
||||
sSpellMgr.LoadSpellTargetPositions();
|
||||
|
||||
sLog.outString("Loading enchant custom attributes...");
|
||||
sSpellMgr.LoadEnchantCustomAttr();
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ class icecrown_citadel_teleport : public GameObjectScript
|
||||
|
||||
bool OnGossipSelect(Player* player, GameObject* go, uint32 sender, uint32 action)
|
||||
{
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
SpellEntry const* spell = sSpellStore.LookupEntry(action);
|
||||
if (!spell)
|
||||
return false;
|
||||
|
||||
@@ -207,8 +207,8 @@ class instance_icecrown_citadel : public InstanceMapScript
|
||||
switch (data)
|
||||
{
|
||||
case DONE:
|
||||
// TEMPORARY, UNCOMMMENT IF YOU WANT TO DO SAURFANG AND SKIP GUNSHIP
|
||||
//uiEncounterState[DATA_GUNSHIP_EVENT] = DONE;
|
||||
// TEMPORARY, SKIP GUNSHIP
|
||||
uiEncounterState[DATA_GUNSHIP_EVENT] = DONE;
|
||||
HandleGameObject(uiOratoryDoor, true);
|
||||
if (GameObject* elevator = instance->GetGameObject(uiLadyDeathwisperElevator))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user