aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormegamage <none@none>2009-05-08 19:20:28 -0500
committermegamage <none@none>2009-05-08 19:20:28 -0500
commitbd33ebf6d37705547d8db9446918ce502bc8b737 (patch)
treee3d444c7547b5880bf22cd467d388b520fd6dc6d /src
parentb7b7262c7c13c8a7c809543f86459a352153e1d1 (diff)
[7801] Apply damage mods from scripts or target state not in DealDamage but in new function before send data to client. Author: VladimirMangos
* Fixed bug with health decrease (client side visual bug) at spell damage by target with AI::DamageTaken damage set to 0 * Fixed bug with ignore .die command and instant kill damage in some cases. --HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/game/Level3.cpp22
-rw-r--r--src/game/Player.cpp2
-rw-r--r--src/game/Spell.cpp1
-rw-r--r--src/game/SpellAuras.cpp12
-rw-r--r--src/game/SpellEffects.cpp3
-rw-r--r--src/game/Unit.cpp60
-rw-r--r--src/game/Unit.h1
7 files changed, 77 insertions, 24 deletions
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index 1130bcec070..f4ec15bcfb0 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -4028,31 +4028,34 @@ bool ChatHandler::HandleDamageCommand(const char * args)
Unit* target = getSelectedUnit();
- if(!target || !m_session->GetPlayer()->GetSelection())
+ if (!target || !m_session->GetPlayer()->GetSelection())
{
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
SetSentErrorMessage(true);
return false;
}
- if( !target->isAlive() )
+ if (!target->isAlive())
return true;
char* damageStr = strtok((char*)args, " ");
- if(!damageStr)
+ if (!damageStr)
return false;
- int32 damage = atoi((char*)damageStr);
- if(damage <=0)
+ int32 damage_int = atoi((char*)damageStr);
+ if(damage_int <=0)
return true;
+ uint32 damage = damage_int;
+
char* schoolStr = strtok((char*)NULL, " ");
// flat melee damage without resistence/etc reduction
- if(!schoolStr)
+ if (!schoolStr)
{
m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
+ if (target != m_session->GetPlayer())
+ m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
return true;
}
@@ -4068,7 +4071,7 @@ bool ChatHandler::HandleDamageCommand(const char * args)
char* spellStr = strtok((char*)NULL, " ");
// melee damage by specific school
- if(!spellStr)
+ if (!spellStr)
{
uint32 absorb = 0;
uint32 resist = 0;
@@ -4080,6 +4083,7 @@ bool ChatHandler::HandleDamageCommand(const char * args)
damage -= absorb + resist;
+ m_session->GetPlayer()->DealDamageMods(target,damage,&absorb);
m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
return true;
@@ -4089,7 +4093,7 @@ bool ChatHandler::HandleDamageCommand(const char * args)
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
uint32 spellid = extractSpellIdFromLink((char*)args);
- if(!spellid || !sSpellStore.LookupEntry(spellid))
+ if (!spellid || !sSpellStore.LookupEntry(spellid))
return false;
m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage);
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 4e58fa5b885..23bfea068d8 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -897,6 +897,8 @@ void Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
damage-=absorb+resist;
+ DealDamageMods(this,damage,&absorb);
+
WorldPacket data(SMSG_ENVIRONMENTALDAMAGELOG, (21));
data << uint64(GetGUID());
data << uint8(type!=DAMAGE_FALL_TO_VOID ? type : DAMAGE_FALL);
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 168e6ddd16f..d4e2207964b 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1028,6 +1028,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Add bonuses and fill damageInfo struct
caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo);
+ caster->DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb);
// Send log damage message to client
caster->SendSpellNonMeleeDamageLog(&damageInfo);
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 01fc612018d..5b941a0440f 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -5800,6 +5800,8 @@ void AuraEffect::PeriodicTick()
sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
+ pCaster->DealDamageMods(m_target,pdamage,&absorb);
+
WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
data.append(m_target->GetPackGUID());
data.appendPackGUID(GetCasterGUID());
@@ -5983,10 +5985,13 @@ void AuraEffect::PeriodicTick()
}
else
{
- pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), gain, GetSpellSchoolMask(GetSpellProto()), 0, 0, false, 0, false);
+ uint32 damage = gain;
+ uint32 absorb = 0;
+ pCaster->DealDamageMods(pCaster,damage,&absorb);
+ pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), damage, GetSpellSchoolMask(GetSpellProto()), absorb, 0, false, 0, false);
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
- pCaster->DealDamage(pCaster, gain, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
+ pCaster->DealDamage(pCaster, damage, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
}
}
@@ -6202,6 +6207,9 @@ void AuraEffect::PeriodicTick()
SpellNonMeleeDamage damageInfo(pCaster, m_target, spellProto->Id, spellProto->SchoolMask);
//no SpellDamageBonus for burn mana
pCaster->CalculateSpellDamageTaken(&damageInfo, gain, spellProto);
+
+ pCaster->DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb);
+
pCaster->SendSpellNonMeleeDamageLog(&damageInfo);
// Set trigger flag
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 3226ccdbec0..c7119c993ec 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -286,8 +286,7 @@ void Spell::EffectInstaKill(uint32 /*i*/)
if(m_caster==unitTarget) // prevent interrupt message
finish();
- uint32 health = unitTarget->GetHealth();
- m_caster->DealDamage(unitTarget, health, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ m_caster->DealDamage(unitTarget, unitTarget->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
void Spell::EffectEnvirinmentalDMG(uint32 i)
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index c9461d4b218..39e23db5fb9 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -535,10 +535,15 @@ void Unit::RemoveSpellbyDamageTaken(uint32 damage, uint32 spell)
}
}
-uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss)
+void Unit::DealDamageMods(Unit *pVictim, uint32 &damage, uint32* absorb)
{
if (!pVictim->isAlive() || pVictim->hasUnitState(UNIT_STAT_UNATTACKABLE) || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
- return 0;
+ {
+ if(absorb)
+ absorb += damage;
+ damage = 0;
+ return;
+ }
//You don't lose health from damage taken from another player while in a sanctuary
//You still see it in the combat log though
@@ -546,14 +551,30 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
{
const AreaTableEntry *area = GetAreaEntryByAreaID(pVictim->GetAreaId());
if(area && area->flags & AREA_FLAG_SANCTUARY) //sanctuary
- return 0;
+ {
+ if(absorb)
+ absorb += damage;
+ damage = 0;
+ }
}
+ uint32 originalDamage = damage;
+
+ //Script Event damage Deal
+ //if( GetTypeId()== TYPEID_UNIT && ((Creature *)this)->AI())
+ // ((Creature *)this)->AI()->DamageDeal(pVictim, damage);
//Script Event damage taken
if( pVictim->GetTypeId()== TYPEID_UNIT && ((Creature *)pVictim)->IsAIEnabled )
- {
((Creature *)pVictim)->AI()->DamageTaken(this, damage);
+ if(absorb && originalDamage > damage)
+ absorb += (originalDamage - damage);
+}
+
+uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss)
+{
+ if( pVictim->GetTypeId()== TYPEID_UNIT)
+ {
// Set tagging
if(!pVictim->HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_OTHER_TAGGER) && !((Creature*)pVictim)->isPet())
{
@@ -1203,6 +1224,7 @@ uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage
SpellNonMeleeDamage damageInfo(this, pVictim, spellInfo->Id, spellInfo->SchoolMask);
damage = SpellDamageBonus(pVictim, spellInfo, damage, SPELL_DIRECT_DAMAGE);
CalculateSpellDamageTaken(&damageInfo, damage, spellInfo);
+ DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb);
SendSpellNonMeleeDamageLog(&damageInfo);
DealSpellDamage(&damageInfo, true);
return damageInfo.damage;
@@ -1706,6 +1728,8 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
//CalcAbsorbResist(pVictim, SpellSchools(spellProto->School), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
//damage-=absorb + resist;
+ pVictim->DealDamageMods(this,damage,NULL);
+
WorldPacket data(SMSG_SPELLDAMAGESHIELD,(8+8+4+4+4+4));
data << uint64(pVictim->GetGUID());
data << uint64(GetGUID());
@@ -2082,8 +2106,12 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
int32 canabsorb = caster->GetHealth();
if (canabsorb < absorbed)
absorbed = canabsorb;
- DealDamage(caster, absorbed, NULL, damagetype, schoolMask, 0, false);
+
RemainingDamage -= absorbed;
+
+ uint32 ab_damage = absorbed;
+ DealDamageMods(caster,ab_damage,NULL);
+ DealDamage(caster, ab_damage, NULL, damagetype, schoolMask, 0, false);
continue;
}
break;
@@ -2192,10 +2220,15 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
RemainingDamage -= currentAbsorb;
- SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, currentAbsorb, schoolMask, 0, 0, false, 0, false);
- CleanDamage cleanDamage = CleanDamage(currentAbsorb, BASE_ATTACK, MELEE_HIT_NORMAL);
- DealDamage(caster, currentAbsorb, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false);
+ uint32 splitted = currentAbsorb;
+ uint32 splitted_absorb = 0;
+ DealDamageMods(caster,splitted,&splitted_absorb);
+
+ SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, splitted, schoolMask, splitted_absorb, 0, false, 0, false);
+
+ CleanDamage cleanDamage = CleanDamage(splitted, BASE_ATTACK, MELEE_HIT_NORMAL);
+ DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false);
}
AuraEffectList const& vSplitDamagePct = pVictim->GetAurasByType(SPELL_AURA_SPLIT_DAMAGE_PCT);
@@ -2212,11 +2245,14 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
if(!caster || caster == pVictim || !caster->IsInWorld() || !caster->isAlive())
continue;
- int32 splitted = int32(RemainingDamage * (*i)->GetAmount() / 100.0f);
+ uint32 splitted = uint32(RemainingDamage * (*i)->GetAmount() / 100.0f);
+
+ RemainingDamage -= int32(splitted);
- RemainingDamage -= splitted;
+ uint32 split_absorb = 0;
+ DealDamageMods(caster,splitted,&split_absorb);
- SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, splitted, schoolMask, 0, 0, false, 0, false);
+ SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, splitted, schoolMask, split_absorb, 0, false, 0, false);
CleanDamage cleanDamage = CleanDamage(splitted, BASE_ATTACK, MELEE_HIT_NORMAL);
DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false);
@@ -2351,6 +2387,7 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
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);
@@ -11916,6 +11953,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
SpellNonMeleeDamage damageInfo(this, pTarget, spellInfo->Id, spellInfo->SchoolMask);
uint32 damage = SpellDamageBonus(pTarget, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE);
CalculateSpellDamageTaken(&damageInfo, damage, spellInfo);
+ DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb);
SendSpellNonMeleeDamageLog(&damageInfo);
DealSpellDamage(&damageInfo, true);
break;
diff --git a/src/game/Unit.h b/src/game/Unit.h
index d0173315c7b..49e8264b277 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1073,6 +1073,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
void RemoveSpellbyDamageTaken(uint32 damage, uint32 spell);
+ void DealDamageMods(Unit *pVictim, uint32 &damage, uint32* absorb);
uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *spellProto = NULL, bool durabilityLoss = true);
void Kill(Unit *pVictim, bool durabilityLoss = true);
int32 DealHeal(Unit *pVictim, uint32 addhealth, SpellEntry const *spellProto, bool critical = false);