aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells/Spell.cpp
diff options
context:
space:
mode:
authorQAston <none@none>2010-08-27 17:49:32 +0200
committerQAston <none@none>2010-08-27 17:49:32 +0200
commitf1d4933dcbcc343181c2402de9797f67fb710cd0 (patch)
tree324ec4aadc1d6eeeeaed090caf4a8e0dd4088f51 /src/server/game/Spells/Spell.cpp
parente2dc4c3a66a53109616bff726bb4f4e198af580b (diff)
*Fix combat logging of many spell effects - thanks to kiper, Ssp, Cyrax, and manuel for providing data and to Zor for inspecting opcodes.
--HG-- branch : trunk
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
-rw-r--r--src/server/game/Spells/Spell.cpp248
1 files changed, 139 insertions, 109 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index f9a39618207..69987f962fc 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -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>
@@ -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");