mirror of
https://github.com/mangosfour/server.git
synced 2025-12-31 22:37:05 +00:00
Merge commit 'origin/master' into 320
This commit is contained in:
commit
6f2b9a7e80
48 changed files with 574 additions and 281 deletions
|
|
@ -20,7 +20,6 @@
|
|||
#define MANGOS_GRIDNOTIFIERS_H
|
||||
|
||||
#include "ObjectGridLoader.h"
|
||||
#include "ByteBuffer.h"
|
||||
#include "UpdateData.h"
|
||||
#include <iostream>
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ void WorldSession::HandleMoveWorldportAckOpcode()
|
|||
GetPlayer()->SetSemaphoreTeleportFar(false);
|
||||
|
||||
// relocate the player to the teleport destination
|
||||
GetPlayer()->SetMap(MapManager::Instance().CreateMap(loc.mapid, GetPlayer())); GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation);
|
||||
GetPlayer()->SetMap(MapManager::Instance().CreateMap(loc.mapid, GetPlayer()));
|
||||
GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation);
|
||||
|
||||
GetPlayer()->SendInitialPacketsBeforeAddToMap();
|
||||
|
|
|
|||
|
|
@ -85,7 +85,6 @@ enum PhaseMasks
|
|||
|
||||
class WorldPacket;
|
||||
class UpdateData;
|
||||
class ByteBuffer;
|
||||
class WorldSession;
|
||||
class Creature;
|
||||
class Player;
|
||||
|
|
|
|||
|
|
@ -451,12 +451,23 @@ ObjectAccessor::UpdateObjectVisibility(WorldObject *obj)
|
|||
|
||||
void ObjectAccessor::UpdateVisibilityForPlayer( Player* player )
|
||||
{
|
||||
CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
|
||||
Cell cell(p);
|
||||
WorldObject const* viewPoint = player->GetViewPoint();
|
||||
Map* m = player->GetMap();
|
||||
|
||||
CellPair p(MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY()));
|
||||
Cell cell(p);
|
||||
|
||||
m->UpdatePlayerVisibility(player, cell, p);
|
||||
m->UpdateObjectsVisibilityFor(player, cell, p);
|
||||
|
||||
if (player!=viewPoint)
|
||||
{
|
||||
CellPair pView(MaNGOS::ComputeCellPair(viewPoint->GetPositionX(), viewPoint->GetPositionY()));
|
||||
Cell cellView(pView);
|
||||
|
||||
m->UpdateObjectsVisibilityFor(player, cellView, pView);
|
||||
}
|
||||
else
|
||||
m->UpdateObjectsVisibilityFor(player, cell, p);
|
||||
}
|
||||
|
||||
/// Define the static member of HashMapHolder
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include "Utilities/UnorderedMap.h"
|
||||
#include "Policies/ThreadingModel.h"
|
||||
|
||||
#include "ByteBuffer.h"
|
||||
#include "UpdateData.h"
|
||||
|
||||
#include "GridDefines.h"
|
||||
|
|
|
|||
|
|
@ -3638,20 +3638,17 @@ void ObjectMgr::LoadQuests()
|
|||
qinfo->GetQuestId(),qinfo->RewSpell,qinfo->RewSpell);
|
||||
qinfo->RewSpell = 0; // no spell reward will display for this quest
|
||||
}
|
||||
|
||||
if(!SpellMgr::IsSpellValid(spellInfo))
|
||||
else if(!SpellMgr::IsSpellValid(spellInfo))
|
||||
{
|
||||
sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u is broken, quest will not have a spell reward.",
|
||||
qinfo->GetQuestId(),qinfo->RewSpell,qinfo->RewSpell);
|
||||
qinfo->RewSpell = 0; // no spell reward will display for this quest
|
||||
}
|
||||
|
||||
if(GetTalentSpellCost(qinfo->RewSpell))
|
||||
else if(GetTalentSpellCost(qinfo->RewSpell))
|
||||
{
|
||||
sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u is talent, quest will not have a spell reward.",
|
||||
qinfo->GetQuestId(),qinfo->RewSpell,qinfo->RewSpell);
|
||||
qinfo->RewSpell = 0; // no spell reward will display for this quest
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3665,20 +3662,17 @@ void ObjectMgr::LoadQuests()
|
|||
qinfo->GetQuestId(),qinfo->RewSpellCast,qinfo->RewSpellCast);
|
||||
qinfo->RewSpellCast = 0; // no spell will be casted on player
|
||||
}
|
||||
|
||||
if(!SpellMgr::IsSpellValid(spellInfo))
|
||||
else if(!SpellMgr::IsSpellValid(spellInfo))
|
||||
{
|
||||
sLog.outErrorDb("Quest %u has `RewSpellCast` = %u but spell %u is broken, quest will not have a spell reward.",
|
||||
qinfo->GetQuestId(),qinfo->RewSpellCast,qinfo->RewSpellCast);
|
||||
qinfo->RewSpellCast = 0; // no spell will be casted on player
|
||||
}
|
||||
|
||||
if(GetTalentSpellCost(qinfo->RewSpellCast))
|
||||
else if(GetTalentSpellCost(qinfo->RewSpellCast))
|
||||
{
|
||||
sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u is talent, quest will not have a spell reward.",
|
||||
qinfo->GetQuestId(),qinfo->RewSpellCast,qinfo->RewSpellCast);
|
||||
qinfo->RewSpellCast = 0; // no spell will be casted on player
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1008,13 +1008,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo);
|
||||
|
||||
caster->DealSpellDamage(&damageInfo, true);
|
||||
|
||||
// Judgement of Blood
|
||||
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000800000000)) && m_spellInfo->SpellIconID==153)
|
||||
{
|
||||
int32 damagePoint = damageInfo.damage * 33 / 100;
|
||||
m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true);
|
||||
}
|
||||
}
|
||||
// Passive spell hits/misses or active spells only misses (only triggers)
|
||||
else
|
||||
|
|
|
|||
|
|
@ -489,6 +489,9 @@ Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target,
|
|||
m_areaAuraType = AREA_AURA_RAID;
|
||||
if (target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())
|
||||
m_modifier.m_auraname = SPELL_AURA_NONE;
|
||||
// Light's Beacon not applied to caster itself (TODO: more generic check for another simialr spell if any?)
|
||||
else if (target == caster_ptr && m_spellProto->Id == 53651)
|
||||
m_modifier.m_auraname = SPELL_AURA_NONE;
|
||||
break;
|
||||
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
|
||||
m_areaAuraType = AREA_AURA_FRIEND;
|
||||
|
|
@ -782,7 +785,40 @@ void AreaAura::Update(uint32 diff)
|
|||
|
||||
for(std::list<Unit *>::iterator tIter = targets.begin(); tIter != targets.end(); tIter++)
|
||||
{
|
||||
if((*tIter)->HasAura(GetId(), m_effIndex))
|
||||
// flag for seelction is need apply aura to current iteration target
|
||||
bool apply = true;
|
||||
|
||||
// we need ignore present caster self applied are auras sometime
|
||||
// in cases if this only auras applied for spell effect
|
||||
Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), m_effIndex);
|
||||
for(Unit::AuraMap::const_iterator i = (*tIter)->GetAuras().lower_bound(spair); i != (*tIter)->GetAuras().upper_bound(spair); ++i)
|
||||
{
|
||||
if (i->second->IsDeleted())
|
||||
continue;
|
||||
|
||||
switch(m_areaAuraType)
|
||||
{
|
||||
case AREA_AURA_ENEMY:
|
||||
// non caster self-casted auras (non stacked)
|
||||
if(i->second->GetModifier()->m_auraname != SPELL_AURA_NONE)
|
||||
apply = false;
|
||||
break;
|
||||
case AREA_AURA_RAID:
|
||||
// non caster self-casted auras (stacked from diff. casters)
|
||||
if(i->second->GetModifier()->m_auraname != SPELL_AURA_NONE || i->second->GetCasterGUID() == GetCasterGUID())
|
||||
apply = false;
|
||||
break;
|
||||
default:
|
||||
// in generic case not allow stacking area auras
|
||||
apply = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!apply)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!apply)
|
||||
continue;
|
||||
|
||||
if(SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
|
||||
|
|
@ -815,7 +851,7 @@ void AreaAura::Update(uint32 diff)
|
|||
caster->IsFriendlyTo(m_target) != needFriendly
|
||||
)
|
||||
{
|
||||
m_target->RemoveAura(GetId(), GetEffIndex());
|
||||
m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(),GetCasterGUID());
|
||||
}
|
||||
else if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
|
||||
{
|
||||
|
|
@ -847,16 +883,16 @@ void AreaAura::Update(uint32 diff)
|
|||
{
|
||||
Player* checkTarget = m_target->GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||
if(!checkTarget)
|
||||
m_target->RemoveAura(GetId(), GetEffIndex());
|
||||
m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID());
|
||||
}
|
||||
else
|
||||
m_target->RemoveAura(GetId(), GetEffIndex());
|
||||
m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID());
|
||||
}
|
||||
}
|
||||
else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
|
||||
{
|
||||
if( m_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
|
||||
m_target->RemoveAura(GetId(), GetEffIndex());
|
||||
m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -897,6 +933,32 @@ void Aura::ApplyModifier(bool apply, bool Real)
|
|||
SetInUse(false);
|
||||
}
|
||||
|
||||
bool Aura::IsNeedVisibleSlot(Unit const* caster) const
|
||||
{
|
||||
bool totemAura = caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem();
|
||||
|
||||
// passive auras (except totem auras) do not get placed in the slots
|
||||
if (m_isPassive && !totemAura)
|
||||
return false;
|
||||
|
||||
// generic not caster case
|
||||
if (m_target != caster)
|
||||
return true;
|
||||
|
||||
// special area auras case at caster
|
||||
switch(m_spellProto->Effect[GetEffIndex()])
|
||||
{
|
||||
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
|
||||
return false;
|
||||
case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
|
||||
// not sure is totemAura need, just preserve old code results
|
||||
return totemAura || m_modifier.m_auraname != SPELL_AURA_NONE;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Aura::_AddAura()
|
||||
{
|
||||
if (!GetId())
|
||||
|
|
@ -954,10 +1016,7 @@ void Aura::_AddAura()
|
|||
}
|
||||
}
|
||||
|
||||
// passive auras (except totem auras) do not get placed in the slots
|
||||
// area auras with SPELL_AURA_NONE are not shown on target
|
||||
if((!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
|
||||
(m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster))
|
||||
if (IsNeedVisibleSlot(caster))
|
||||
{
|
||||
SetAuraSlot( slot );
|
||||
if(slot < MAX_AURAS) // slot found send data to client
|
||||
|
|
@ -2418,6 +2477,20 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
// Beacon of Light
|
||||
if (GetId() == 53563)
|
||||
{
|
||||
if(apply)
|
||||
// original caster must be target (beacon)
|
||||
m_target->CastSpell(m_target,53651,true,NULL,this,m_target->GetGUID());
|
||||
else
|
||||
m_target->RemoveAurasByCasterSpell(53651,m_target->GetGUID());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_DRUID:
|
||||
{
|
||||
switch(GetId())
|
||||
|
|
|
|||
|
|
@ -383,6 +383,7 @@ class MANGOS_DLL_SPEC Aura
|
|||
uint32 m_in_use; // > 0 while in Aura::ApplyModifier call/Aura::Update/etc
|
||||
private:
|
||||
void CleanupTriggeredSpells();
|
||||
bool IsNeedVisibleSlot(Unit const* caster) const; // helper for check req. visibility slot
|
||||
};
|
||||
|
||||
class MANGOS_DLL_SPEC AreaAura : public Aura
|
||||
|
|
|
|||
|
|
@ -610,9 +610,17 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
|||
}
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
// Judgement of Vengeance ${1+0.22*$SPH+0.14*$AP} + 10% for each application of Holy Vengeance on the target
|
||||
// Judgement of Vengeance/Corruption ${1+0.22*$SPH+0.14*$AP} + 10% for each application of Holy Vengeance/Blood Corruption on the target
|
||||
if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x800000000)) && m_spellInfo->SpellIconID==2292)
|
||||
{
|
||||
uint32 debuf_id;
|
||||
switch(m_spellInfo->Id)
|
||||
{
|
||||
case 53733: debuf_id = 53742; break;// Judgement of Corruption -> Blood Corruption
|
||||
case 31804: debuf_id = 31803; break;// Judgement of Vengeance -> Holy Vengeance
|
||||
default: return;
|
||||
}
|
||||
|
||||
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
|
||||
m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
|
||||
|
|
@ -621,11 +629,13 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
|||
uint32 stacks = 0;
|
||||
Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||
for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
|
||||
if((*itr)->GetId() == 31803 && (*itr)->GetCasterGUID()==m_caster->GetGUID())
|
||||
{
|
||||
if( ((*itr)->GetId() == debuf_id) && (*itr)->GetCasterGUID()==m_caster->GetGUID())
|
||||
{
|
||||
stacks = (*itr)->GetStackAmount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// + 10% for each application of Holy Vengeance on the target
|
||||
if(stacks)
|
||||
damage += damage * stacks * 10 /100;
|
||||
|
|
@ -1670,25 +1680,7 @@ void Spell::EffectDummy(uint32 i)
|
|||
if (!spell_proto)
|
||||
return;
|
||||
|
||||
if (!unitTarget->hasUnitState(UNIT_STAT_STUNNED) && m_caster->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
// decreased damage (/2) for non-stunned target.
|
||||
SpellModifier *mod = new SpellModifier;
|
||||
mod->op = SPELLMOD_DAMAGE;
|
||||
mod->value = -50;
|
||||
mod->type = SPELLMOD_PCT;
|
||||
mod->spellId = m_spellInfo->Id;
|
||||
mod->mask = UI64LIT(0x0000020000000000);
|
||||
mod->mask2= UI64LIT(0x0);
|
||||
|
||||
((Player*)m_caster)->AddSpellMod(mod, true);
|
||||
m_caster->CastSpell(unitTarget, spell_proto, true, NULL);
|
||||
// mod deleted
|
||||
((Player*)m_caster)->AddSpellMod(mod, false);
|
||||
}
|
||||
else
|
||||
m_caster->CastSpell(unitTarget, spell_proto, true, NULL);
|
||||
|
||||
m_caster->CastSpell(unitTarget, spell_proto, true, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -3508,6 +3500,11 @@ void Spell::EffectDispel(uint32 i)
|
|||
std::list < std::pair<uint32,uint64> > success_list;// (spell_id,casterGuid)
|
||||
std::list < uint32 > fail_list; // spell_id
|
||||
int32 list_size = dispel_list.size();
|
||||
|
||||
// some spells have effect value = 0 and all from its by meaning expect 1
|
||||
if(!damage)
|
||||
damage = 1;
|
||||
|
||||
// Dispell N = damage buffs (or while exist buffs for dispel)
|
||||
for (int32 count=0; count < damage && list_size > 0; ++count)
|
||||
{
|
||||
|
|
@ -4645,13 +4642,33 @@ void Spell::EffectWeaponDmg(uint32 i)
|
|||
if(m_caster->GetTypeId()==TYPEID_PLAYER)
|
||||
((Player*)m_caster)->AddComboPoints(unitTarget, 1);
|
||||
}
|
||||
|
||||
// Mangle (Cat): CP
|
||||
if (m_spellInfo->SpellFamilyName==SPELLFAMILY_DRUID && (m_spellInfo->SpellFamilyFlags==UI64LIT(0x0000040000000000)))
|
||||
else if (m_spellInfo->SpellFamilyName==SPELLFAMILY_DRUID && (m_spellInfo->SpellFamilyFlags==UI64LIT(0x0000040000000000)))
|
||||
{
|
||||
if(m_caster->GetTypeId()==TYPEID_PLAYER)
|
||||
((Player*)m_caster)->AddComboPoints(unitTarget, 1);
|
||||
}
|
||||
else if(m_spellInfo->SpellFamilyName==SPELLFAMILY_PALADIN)
|
||||
{
|
||||
// Judgement of Blood/of the Martyr backlash damage (33%)
|
||||
if(m_spellInfo->SpellFamilyFlags & 0x0000000800000000LL && m_spellInfo->SpellIconID==153)
|
||||
{
|
||||
int32 damagePoint = m_damage * 33 / 100;
|
||||
if(m_spellInfo->Id == 31898)
|
||||
m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true);
|
||||
else
|
||||
m_caster->CastCustomSpell(m_caster, 53725, &damagePoint, NULL, NULL, true);
|
||||
}
|
||||
// Seal of Blood/of the Martyr backlash damage (10%)
|
||||
else if(m_spellInfo->SpellIconID==2293)
|
||||
{
|
||||
int32 damagePoint = m_damage * 10 / 100;
|
||||
if(m_spellInfo->Id == 31893)
|
||||
m_caster->CastCustomSpell(m_caster, 32221, &damagePoint, NULL, NULL, true);
|
||||
else
|
||||
m_caster->CastCustomSpell(m_caster, 53718, &damagePoint, NULL, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
// take ammo
|
||||
if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
|
|
|
|||
|
|
@ -1571,6 +1571,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons
|
|||
if ((spellInfo_1->SpellFamilyFlags2 & 0x00000020) && (spellInfo_2->SpellIconID == 291 || spellInfo_2->SpellIconID == 3028) ||
|
||||
(spellInfo_2->SpellFamilyFlags2 & 0x00000020) && (spellInfo_1->SpellIconID == 291 || spellInfo_1->SpellIconID == 3028))
|
||||
return false;
|
||||
|
||||
// Beacon of Light and Light's Beacon
|
||||
if ((spellInfo_1->SpellIconID == 3032) && (spellInfo_2->SpellIconID == 3032))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Combustion and Fire Protection Aura (multi-family check)
|
||||
|
|
|
|||
|
|
@ -427,7 +427,7 @@ enum ProcFlags
|
|||
PROC_FLAG_KILLED = 0x00000001, // 00 Killed by agressor
|
||||
PROC_FLAG_KILL = 0x00000002, // 01 Kill target (in most cases need XP/Honor reward)
|
||||
|
||||
PROC_FLAG_SUCCESSFUL_MILEE_HIT = 0x00000004, // 02 Successful melee auto attack
|
||||
PROC_FLAG_SUCCESSFUL_MELEE_HIT = 0x00000004, // 02 Successful melee auto attack
|
||||
PROC_FLAG_TAKEN_MELEE_HIT = 0x00000008, // 03 Taken damage from melee auto attack hit
|
||||
|
||||
PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT = 0x00000010, // 04 Successful attack by Spell that use melee weapon
|
||||
|
|
@ -461,7 +461,7 @@ enum ProcFlags
|
|||
PROC_FLAG_SUCCESSFUL_OFFHAND_HIT = 0x00800000 // 23 Successful off-hand melee attacks
|
||||
};
|
||||
|
||||
#define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_SUCCESSFUL_MILEE_HIT | \
|
||||
#define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_SUCCESSFUL_MELEE_HIT | \
|
||||
PROC_FLAG_TAKEN_MELEE_HIT | \
|
||||
PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT | \
|
||||
PROC_FLAG_TAKEN_MELEE_SPELL_HIT | \
|
||||
|
|
|
|||
|
|
@ -1205,12 +1205,12 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
|
|||
switch (attackType)
|
||||
{
|
||||
case BASE_ATTACK:
|
||||
damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MILEE_HIT;
|
||||
damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MELEE_HIT;
|
||||
damageInfo->procVictim = PROC_FLAG_TAKEN_MELEE_HIT;
|
||||
damageInfo->HitInfo = HITINFO_NORMALSWING2;
|
||||
break;
|
||||
case OFF_ATTACK:
|
||||
damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MILEE_HIT | PROC_FLAG_SUCCESSFUL_OFFHAND_HIT;
|
||||
damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MELEE_HIT | PROC_FLAG_SUCCESSFUL_OFFHAND_HIT;
|
||||
damageInfo->procVictim = PROC_FLAG_TAKEN_MELEE_HIT;//|PROC_FLAG_TAKEN_OFFHAND_HIT // not used
|
||||
damageInfo->HitInfo = HITINFO_LEFTSWING;
|
||||
break;
|
||||
|
|
@ -3417,6 +3417,7 @@ bool Unit::AddAura(Aura *Aur)
|
|||
return false;
|
||||
}
|
||||
|
||||
// m_auraname can be modified to SPELL_AURA_NONE for area auras, this expected for this value
|
||||
AuraType aurName = Aur->GetModifier()->m_auraname;
|
||||
|
||||
spellEffectPair spair = spellEffectPair(Aur->GetId(), Aur->GetEffIndex());
|
||||
|
|
@ -3445,10 +3446,15 @@ bool Unit::AddAura(Aura *Aur)
|
|||
}
|
||||
|
||||
bool stop = false;
|
||||
switch(aurName)
|
||||
|
||||
// m_auraname can be modified to SPELL_AURA_NONE for area auras, use original
|
||||
AuraType aurNameReal = AuraType(aurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()]);
|
||||
|
||||
switch(aurNameReal)
|
||||
{
|
||||
// DoT/HoT/etc
|
||||
case SPELL_AURA_PERIODIC_DAMAGE: // allow stack
|
||||
case SPELL_AURA_DUMMY: // allow stack
|
||||
case SPELL_AURA_PERIODIC_DAMAGE:
|
||||
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
|
||||
case SPELL_AURA_PERIODIC_LEECH:
|
||||
case SPELL_AURA_PERIODIC_HEAL:
|
||||
|
|
@ -3752,6 +3758,22 @@ void Unit::RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID)
|
|||
}
|
||||
}
|
||||
|
||||
void Unit::RemoveAurasByCasterSpell(uint32 spellId, uint32 effindex, uint64 casterGUID)
|
||||
{
|
||||
spellEffectPair spair = spellEffectPair(spellId, effindex);
|
||||
for(AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair);)
|
||||
{
|
||||
Aura *aur = iter->second;
|
||||
if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID)
|
||||
{
|
||||
RemoveAura(iter);
|
||||
iter = m_Auras.lower_bound(spair);
|
||||
}
|
||||
else
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler)
|
||||
{
|
||||
for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); )
|
||||
|
|
@ -5110,7 +5132,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
|||
}
|
||||
|
||||
CastSpell(this, 28682, true, castItem, triggeredByAura);
|
||||
return (procEx & PROC_EX_CRITICAL_HIT);// charge update only at crit hits, no hidden cooldowns
|
||||
return (procEx & PROC_EX_CRITICAL_HIT); // charge update only at crit hits, no hidden cooldowns
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -5737,6 +5759,43 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
|||
return false;
|
||||
|
||||
triggered_spell_id = 31803;
|
||||
|
||||
// Add 5-stack effect
|
||||
int8 stacks = 0;
|
||||
AuraList const& auras = target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||
for(AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
|
||||
{
|
||||
if( ((*itr)->GetId() == 31803) && (*itr)->GetCasterGUID()==GetGUID())
|
||||
{
|
||||
stacks = (*itr)->GetStackAmount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(stacks >= 5)
|
||||
CastSpell(target,42463,true,NULL,triggeredByAura);
|
||||
break;
|
||||
}
|
||||
// Seal of Corruption (damage calc on apply aura)
|
||||
case 53736:
|
||||
{
|
||||
if(effIndex != 0) // effect 1,2 used by seal unleashing code
|
||||
return false;
|
||||
|
||||
triggered_spell_id = 53742;
|
||||
|
||||
// Add 5-stack effect
|
||||
int8 stacks = 0;
|
||||
AuraList const& auras = target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||
for(AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
|
||||
{
|
||||
if( ((*itr)->GetId() == 53742) && (*itr)->GetCasterGUID()==GetGUID())
|
||||
{
|
||||
stacks = (*itr)->GetStackAmount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(stacks >= 5)
|
||||
CastSpell(target,53739,true,NULL,triggeredByAura);
|
||||
break;
|
||||
}
|
||||
// Spiritual Attunement
|
||||
|
|
@ -5756,33 +5815,54 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
|||
// Seal of Blood do damage trigger
|
||||
case 31892:
|
||||
{
|
||||
if (effIndex == 0) // 0 effect - is proc on enemy
|
||||
// 0 effect - is proc on enemy
|
||||
if (effIndex == 0 && (procFlag & PROC_FLAG_SUCCESSFUL_MELEE_HIT))
|
||||
triggered_spell_id = 31893;
|
||||
else if (effIndex == 1) // 1 effect - is proc on self
|
||||
{
|
||||
// add spell damage from prev effect (27%)
|
||||
damage += CalculateDamage(BASE_ATTACK, false) * 27 / 100;
|
||||
basepoints0 = triggerAmount * damage / 100;
|
||||
target = this;
|
||||
triggered_spell_id = 32221;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
// Light's Beacon (heal target area aura)
|
||||
case 53651:
|
||||
{
|
||||
// not do bonus heal for explicit beacon focus healing
|
||||
if (GetGUID() == triggeredByAura->GetCasterGUID())
|
||||
return false;
|
||||
|
||||
// beacon
|
||||
Unit* beacon = triggeredByAura->GetCaster();
|
||||
if (!beacon)
|
||||
return false;
|
||||
|
||||
// find caster main aura at beacon
|
||||
Aura* dummy = NULL;
|
||||
Unit::AuraList const& baa = beacon->GetAurasByType(SPELL_AURA_DUMMY);
|
||||
for(Unit::AuraList::const_iterator i = baa.begin(); i != baa.end(); ++i)
|
||||
{
|
||||
if ((*i)->GetId() == 53563 && (*i)->GetCasterGUID() == pVictim->GetGUID())
|
||||
{
|
||||
dummy = (*i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// original heal must be form beacon caster
|
||||
if (!dummy)
|
||||
return false;
|
||||
|
||||
triggered_spell_id = 53652; // Beacon of Light
|
||||
basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
|
||||
|
||||
// cast with original caster set but beacon to beacon for apply caster mods and avoid LoS check
|
||||
beacon->CastCustomSpell(beacon,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura,pVictim->GetGUID());
|
||||
return true;
|
||||
}
|
||||
// Seal of the Martyr do damage trigger
|
||||
case 53720:
|
||||
{
|
||||
if (effIndex == 0) // 0 effect - is proc on enemy
|
||||
// 0 effect - is proc on enemy
|
||||
if (effIndex == 0 && (procFlag & PROC_FLAG_SUCCESSFUL_MELEE_HIT))
|
||||
triggered_spell_id = 53719;
|
||||
else if (effIndex == 1) // 1 effect - is proc on self
|
||||
{
|
||||
// add spell damage from prev effect (27%)
|
||||
damage += CalculateDamage(BASE_ATTACK, false) * 27 / 100;
|
||||
basepoints0 = triggerAmount * damage / 100;
|
||||
target = this;
|
||||
triggered_spell_id = 53718;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
break;
|
||||
|
|
@ -6590,6 +6670,13 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
break;
|
||||
}
|
||||
case SPELLFAMILY_HUNTER:
|
||||
// Piercing Shots
|
||||
if (auraSpellInfo->SpellIconID == 3247 && auraSpellInfo->SpellVisual[0] == 0)
|
||||
{
|
||||
basepoints[0] = damage * triggerAmount / 100 / 8;
|
||||
trigger_spell_id = 63468;
|
||||
target = pVictim;
|
||||
}
|
||||
break;
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
|
|
@ -8453,12 +8540,22 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
|
|||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELL_DAMAGE_CLASS_MELEE:
|
||||
{
|
||||
// Judgement of Command proc always crits on stunned target
|
||||
if(spellProto->SpellFamilyName == SPELLFAMILY_PALADIN)
|
||||
{
|
||||
if(spellProto->SpellFamilyFlags & 0x0000000000800000LL && spellProto->SpellIconID == 561)
|
||||
{
|
||||
if(pVictim->hasUnitState(UNIT_STAT_STUNNED))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
case SPELL_DAMAGE_CLASS_RANGED:
|
||||
{
|
||||
if (pVictim)
|
||||
|
|
|
|||
|
|
@ -1211,6 +1211,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
|||
void RemoveAurasDueToSpell(uint32 spellId, Aura* except = NULL);
|
||||
void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId);
|
||||
void RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID);
|
||||
void RemoveAurasByCasterSpell(uint32 spellId, uint32 effindex, uint64 casterGUID);
|
||||
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler);
|
||||
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
|
||||
void RemoveAurasDueToSpellByCancel(uint32 spellId);
|
||||
|
|
|
|||
|
|
@ -19,8 +19,11 @@
|
|||
#ifndef __UPDATEDATA_H
|
||||
#define __UPDATEDATA_H
|
||||
|
||||
#include "ByteBuffer.h"
|
||||
|
||||
class WorldPacket;
|
||||
|
||||
|
||||
enum OBJECT_UPDATE_TYPE
|
||||
{
|
||||
UPDATETYPE_VALUES = 0,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "ByteBuffer.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Auth/BigNumber.h"
|
||||
#include "Auth/Sha1.h"
|
||||
#include "WorldSession.h"
|
||||
#include "WorldSocketMgr.h"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue