Merge commit 'origin/master' into 330

This commit is contained in:
tomrus88 2009-10-19 15:08:16 +04:00
commit aa161f802b
35 changed files with 548 additions and 341 deletions

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0',
`required_8618_01_mangos_spell_proc_event` bit(1) default NULL
`required_8676_01_mangos_creature_template` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--

View file

@ -0,0 +1,5 @@
ALTER TABLE db_version CHANGE COLUMN required_8618_01_mangos_spell_proc_event required_8676_01_mangos_creature_template bit;
-- set all spirithealer and spiritguides to be visible only for dead people
UPDATE creature_template SET flags_extra = flags_extra | 0x200
WHERE npcflag & (16384 | 32768);

View file

@ -135,6 +135,7 @@ pkgdata_DATA = \
8608_01_mangos_mangos_string.sql \
8608_02_mangos_battleground_events.sql \
8618_01_mangos_spell_proc_event.sql \
8676_01_mangos_creature_template.sql \
README
## Additional files to include when running 'make dist'
@ -250,4 +251,5 @@ EXTRA_DIST = \
8608_01_mangos_mangos_string.sql \
8608_02_mangos_battleground_events.sql \
8618_01_mangos_spell_proc_event.sql \
8676_01_mangos_creature_template.sql \
README

View file

@ -46,7 +46,7 @@ AggressorAI::MoveInLineOfSight(Unit *u)
if( !m_creature->canFly() && m_creature->GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
return;
if( !m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && u->isTargetableForAttack() &&
if( !(m_creature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GHOST) && !m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && u->isTargetableForAttack() &&
( m_creature->IsHostileTo( u ) /*|| u->getVictim() && m_creature->IsFriendlyTo( u->getVictim() )*/ ) &&
u->isInAccessablePlaceFor(m_creature) )
{
@ -60,7 +60,7 @@ AggressorAI::MoveInLineOfSight(Unit *u)
}
else if(sMapStore.LookupEntry(m_creature->GetMapId())->IsDungeon())
{
m_creature->AddThreat(u, 0.0f);
m_creature->AddThreat(u);
u->SetInCombatWith(m_creature);
}
}
@ -155,7 +155,7 @@ AggressorAI::AttackStart(Unit *u)
// DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", m_creature->GetName(), u->GetGUIDLow());
i_victimGuid = u->GetGUID();
m_creature->AddThreat(u, 0.0f);
m_creature->AddThreat(u);
m_creature->SetInCombatWith(u);
u->SetInCombatWith(m_creature);

View file

@ -336,15 +336,6 @@ void Creature::Update(uint32 diff)
break;
case DEAD:
{
if (isSpiritService())
{
Unit::Update( diff );
// do not allow the AI to be changed during update
m_AI_locked = true;
i_AI->UpdateAI(diff);
m_AI_locked = false;
break; // they don't should respawn
}
if( m_respawnTime <= time(NULL) )
{
DEBUG_LOG("Respawning...");
@ -1563,10 +1554,7 @@ void Creature::setDeathState(DeathState s)
RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
AddMonsterMoveFlag(MONSTER_MOVE_WALK);
SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag);
if (!isSpiritService())
Unit::setDeathState(ALIVE);
else
Unit::setDeathState(DEAD);
Unit::setDeathState(ALIVE);
clearUnitState(UNIT_STAT_ALL_STATE);
i_motionMaster.Clear();
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));
@ -1761,7 +1749,7 @@ bool Creature::IsVisibleInGridForPlayer(Player* pl) const
// Live player (or with not release body see live creatures or death creatures with corpse disappearing time > 0
if(pl->isAlive() || pl->GetDeathTimer() > 0)
{
if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_INVISIBLE)
if(GetCreatureInfo()->flags_extra & (CREATURE_FLAG_EXTRA_INVISIBLE | CREATURE_FLAG_EXTRA_GHOST))
return false;
return (isAlive() || m_deathTimer > 0 || (m_isDeadByDefault && m_deathState == CORPSE));
}
@ -1778,8 +1766,8 @@ bool Creature::IsVisibleInGridForPlayer(Player* pl) const
}
}
// Dead player see Spirit Healer or Spirit Guide
if(isSpiritService())
// Dead player see ghosts
if (GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GHOST)
return true;
// and not see any other
@ -2057,7 +2045,7 @@ void Creature::SetInCombatWithZone()
if (pPlayer->isAlive())
{
pPlayer->SetInCombatWith(this);
AddThreat(pPlayer, 0.0f);
AddThreat(pPlayer);
}
}
}

View file

@ -143,6 +143,7 @@ enum CreatureFlagsExtra
CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP
CREATURE_FLAG_EXTRA_INVISIBLE = 0x00000080, // creature is always invisible for player (mostly trigger creatures)
CREATURE_FLAG_EXTRA_NOT_TAUNTABLE = 0x00000100, // creature is immune to taunt auras and effect attack me
CREATURE_FLAG_EXTRA_GHOST = 0x00000200, // creature is only visible for dead players
};
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
@ -238,13 +239,18 @@ struct CreatureInfo
return SKILL_SKINNING; // normal case
}
bool IsExotic() const
{
return (type_flags & CREATURE_TYPEFLAGS_EXOTIC);
}
bool isTameable(bool exotic) const
{
if(type != CREATURE_TYPE_BEAST || family == 0 || (type_flags & CREATURE_TYPEFLAGS_TAMEABLE)==0)
if(type != CREATURE_TYPE_BEAST || family == 0 || (type_flags & CREATURE_TYPEFLAGS_TAMEABLE) == 0)
return false;
// if can tame exotic then can tame any temable
return exotic || (type_flags & CREATURE_TYPEFLAGS_EXOTIC)==0;
return exotic || !IsExotic();
}
};

View file

@ -948,7 +948,7 @@ void CreatureEventAI::AttackStart(Unit *who)
if (m_creature->Attack(who, MeleeEnabled))
{
m_creature->AddThreat(who, 0.0f);
m_creature->AddThreat(who);
m_creature->SetInCombatWith(who);
who->SetInCombatWith(m_creature);
@ -1010,7 +1010,7 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
}
else if (m_creature->GetMap()->IsDungeon())
{
m_creature->AddThreat(who, 0.0f);
m_creature->AddThreat(who);
who->SetInCombatWith(m_creature);
}
}

View file

@ -138,7 +138,7 @@ void GuardAI::AttackStart(Unit *u)
if(m_creature->Attack(u,true))
{
i_victimGuid = u->GetGUID();
m_creature->AddThreat(u, 0.0f);
m_creature->AddThreat(u);
m_creature->SetInCombatWith(u);
u->SetInCombatWith(m_creature);

View file

@ -40,7 +40,7 @@ void HostileRefManager::threatAssist(Unit *pVictim, float pThreat, SpellEntry co
ref = getFirst();
while(ref != NULL)
{
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, (pThreatSpell ? GetSpellSchoolMask(pThreatSpell) : SPELL_SCHOOL_MASK_NORMAL), pThreatSpell);
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, false, (pThreatSpell ? GetSpellSchoolMask(pThreatSpell) : SPELL_SCHOOL_MASK_NORMAL), pThreatSpell);
if(pVictim == getOwner())
ref->addThreat(float (threat) / size); // It is faster to modify the threat durectly if possible
else

View file

@ -996,6 +996,14 @@ bool Item::IsBindedNotWith( Player const* player ) const
}
}
void Item::BuildUpdateData(UpdateDataMapType& update_players)
{
if (Player* pl = GetOwner())
BuildUpdateDataForPlayer(pl, update_players);
ClearUpdateMask(false);
}
bool ItemRequiredTarget::IsFitToRequirements( Unit* pUnitTarget ) const
{
if(pUnitTarget->GetTypeId() != TYPEID_UNIT)

View file

@ -313,6 +313,7 @@ class MANGOS_DLL_SPEC Item : public Object
bool IsPotion() const { return GetProto()->IsPotion(); }
bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }
void BuildUpdateData(UpdateDataMapType& update_players);
private:
uint8 m_slot;
Bag *m_container;

View file

@ -128,7 +128,7 @@ void Object::BuildMovementUpdateBlock(UpdateData * data, uint32 flags ) const
buf << uint8( UPDATETYPE_MOVEMENT );
buf.append(GetPackGUID());
_BuildMovementUpdate(&buf, flags, 0x00000000);
BuildMovementUpdate(&buf, flags, 0x00000000);
data->AddUpdateBlock(buf);
}
@ -189,12 +189,12 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
buf.append(GetPackGUID());
buf << (uint8)m_objectTypeId;
_BuildMovementUpdate(&buf, flags, flags2);
BuildMovementUpdate(&buf, flags, flags2);
UpdateMask updateMask;
updateMask.SetCount( m_valuesCount );
_SetCreateBits( &updateMask, target );
_BuildValuesUpdate(updatetype, &buf, &updateMask, target);
BuildValuesUpdate(updatetype, &buf, &updateMask, target);
data->AddUpdateBlock(buf);
}
@ -220,7 +220,7 @@ void Object::BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) c
updateMask.SetCount( m_valuesCount );
_SetUpdateBits( &updateMask, target );
_BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target);
BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target);
data->AddUpdateBlock(buf);
}
@ -240,7 +240,7 @@ void Object::DestroyForPlayer( Player *target, bool anim ) const
target->GetSession()->SendPacket( &data );
}
void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2) const
void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2) const
{
uint16 unk_flags = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.unk1 : 0);
@ -567,7 +567,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2
}
}
void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const
void Object::BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const
{
if(!target)
return;
@ -1065,6 +1065,20 @@ bool Object::PrintIndexError(uint32 index, bool set) const
return false;
}
void Object::BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players)
{
UpdateDataMapType::iterator iter = update_players.find(pl);
if (iter == update_players.end())
{
std::pair<UpdateDataMapType::iterator, bool> p = update_players.insert( UpdateDataMapType::value_type(pl, UpdateData()) );
assert(p.second);
iter = p.first;
}
BuildValuesUpdateBlockForPlayer(&iter->second, iter->first);
}
WorldObject::WorldObject()
: m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL),
m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), m_currMap(NULL)
@ -1857,3 +1871,33 @@ void WorldObject::UpdateObjectVisibility()
GetMap()->UpdateObjectVisibility(this, cell, p);
}
struct WorldObjectChangeAccumulator
{
UpdateDataMapType &i_updateDatas;
WorldObject &i_object;
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {}
void Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
if(iter->getSource()->HaveAtClient(&i_object))
i_object.BuildUpdateDataForPlayer(iter->getSource(), i_updateDatas);
}
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
};
void WorldObject::BuildUpdateData( UpdateDataMapType & update_players)
{
CellPair p = MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY());
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
WorldObjectChangeAccumulator notifier(*this, update_players);
TypeContainerVisitor<WorldObjectChangeAccumulator, WorldTypeMapContainer > player_notifier(notifier);
CellLock<GridReadGuard> cell_lock(cell, p);
Map* aMap = GetMap();
//we must build packets for all visible players
cell_lock->Visit(cell_lock, player_notifier, *aMap, *this, aMap->GetVisibilityDistance());
ClearUpdateMask(false);
}

View file

@ -148,6 +148,7 @@ class MANGOS_DLL_SPEC Object
virtual void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
void SendCreateUpdateToPlayer(Player* player);
virtual void BuildUpdateData(UpdateDataMapType& update_players) =0;
void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
void BuildOutOfRangeUpdateBlock( UpdateData *data ) const;
void BuildMovementUpdateBlock( UpdateData * data, uint32 flags = 0 ) const;
@ -307,8 +308,9 @@ class MANGOS_DLL_SPEC Object
virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;
virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
void _BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 ) const;
void _BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const;
void BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 ) const;
void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const;
void BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players);
uint16 m_objectType;
@ -339,8 +341,12 @@ class MANGOS_DLL_SPEC Object
Object& operator=(Object const&); // prevent generation assigment operator
};
struct WorldObjectChangeAccumulator;
class MANGOS_DLL_SPEC WorldObject : public Object
{
friend struct WorldObjectChangeAccumulator;
public:
virtual ~WorldObject ( ) {}
@ -488,11 +494,11 @@ class MANGOS_DLL_SPEC WorldObject : public Object
//this function should be removed in nearest time...
Map const* GetBaseMap() const;
Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
void BuildUpdateData(UpdateDataMapType &);
Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
protected:
explicit WorldObject();
std::string m_name;
//these functions are used mostly for Relocate() and Corpse/Player specific stuff...
//use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
@ -500,6 +506,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object
void SetLocationMapId(uint32 _mapId) { m_mapId = _mapId; }
void SetLocationInstanceId(uint32 _instanceId) { m_InstanceId = _instanceId; }
std::string m_name;
private:
Map * m_currMap; //current object's Map location

View file

@ -182,49 +182,6 @@ ObjectAccessor::SaveAllPlayers()
itr->second->SaveToDB();
}
void
ObjectAccessor::_buildUpdateObject(Object *obj, UpdateDataMapType &update_players)
{
if(obj->isType(TYPEMASK_ITEM))
{
Item *item = static_cast<Item *>(obj);
if (Player* pl = item->GetOwner())
_buildPacket(pl, obj, update_players);
}
else
_buildChangeObjectForPlayer(static_cast<WorldObject*>(obj), update_players);
}
void
ObjectAccessor::_buildPacket(Player *pl, Object *obj, UpdateDataMapType &update_players)
{
UpdateDataMapType::iterator iter = update_players.find(pl);
if( iter == update_players.end() )
{
std::pair<UpdateDataMapType::iterator, bool> p = update_players.insert( UpdateDataValueType(pl, UpdateData()) );
assert(p.second);
iter = p.first;
}
obj->BuildValuesUpdateBlockForPlayer(&iter->second, iter->first);
}
void
ObjectAccessor::_buildChangeObjectForPlayer(WorldObject *obj, UpdateDataMapType &update_players)
{
CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
WorldObjectChangeAccumulator notifier(*obj, update_players);
TypeContainerVisitor<WorldObjectChangeAccumulator, WorldTypeMapContainer > player_notifier(notifier);
CellLock<GridReadGuard> cell_lock(cell, p);
Map& map = *obj->GetMap();
//we must build packets for all visible players
cell_lock->Visit(cell_lock, player_notifier, map, *obj, map.GetVisibilityDistance());
}
Pet*
ObjectAccessor::GetPet(uint64 guid)
{
@ -386,8 +343,7 @@ ObjectAccessor::Update(uint32 diff)
i_objects.erase(i_objects.begin());
if (!obj)
continue;
_buildUpdateObject(obj, update_players);
obj->ClearUpdateMask(false);
obj->BuildUpdateData(update_players);
}
}
@ -400,14 +356,6 @@ ObjectAccessor::Update(uint32 diff)
}
}
void
ObjectAccessor::WorldObjectChangeAccumulator::Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
if(iter->getSource()->HaveAtClient(&i_object))
ObjectAccessor::_buildPacket(iter->getSource(), &i_object, i_updateDatas);
}
/// Define the static member of HashMapHolder
template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap;

View file

@ -89,7 +89,6 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
public:
typedef UNORDERED_MAP<uint64, Corpse* > Player2CorpsesMapType;
typedef UNORDERED_MAP<Player*, UpdateData>::value_type UpdateDataValueType;
template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/)
{
@ -180,21 +179,10 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
Corpse* ConvertCorpseForPlayer(uint64 player_guid, bool insignia = false);
static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
// TODO: This methods will need lock in MT environment
static void LinkMap(Map* map) { i_mapList.push_back(map); }
static void DelinkMap(Map* map) { i_mapList.remove(map); }
private:
struct WorldObjectChangeAccumulator
{
UpdateDataMapType &i_updateDatas;
WorldObject &i_object;
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {}
void Visit(PlayerMapType &);
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
};
// TODO: This methods will need lock in MT environment
// Theoreticaly multiple threads can enter and search in this method but
// in that case linking/delinking other map should be guarded
@ -213,14 +201,11 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
static std::list<Map*> i_mapList;
friend struct WorldObjectChangeAccumulator;
Player2CorpsesMapType i_player2corpse;
typedef ACE_Thread_Mutex LockType;
typedef MaNGOS::GeneralLock<LockType > Guard;
static void _buildChangeObjectForPlayer(WorldObject *, UpdateDataMapType &);
static void _buildPacket(Player *, Object *, UpdateDataMapType &);
std::set<Object *> i_objects;
LockType i_playerGuard;
LockType i_updateGuard;

View file

@ -102,8 +102,6 @@ template<> void addUnitState(Creature *obj, CellPair const& cell_pair)
Cell cell(cell_pair);
obj->SetCurrentCell(cell);
if(obj->isSpiritService())
obj->setDeathState(DEAD);
}
template <class T>

View file

@ -172,7 +172,7 @@ void PetAI::UpdateAI(const uint32 diff)
return;
//if pet misses its target, it will also be the first in threat list
m_creature->getVictim()->AddThreat(m_creature,0.0f);
m_creature->getVictim()->AddThreat(m_creature);
if( _needToStop() )
_stopAttack();

View file

@ -2098,15 +2098,14 @@ Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
return NULL;
// player check
if(!CanInteractWithNPCs(!unit->isSpiritService()))
if(!CanInteractWithNPCs(!(unit->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GHOST)))
return NULL;
// appropriate npc type
if(npcflagmask && !unit->HasFlag( UNIT_NPC_FLAGS, npcflagmask ))
return NULL;
// alive or spirit healer
if(!unit->isAlive() && (!unit->isSpiritService() || isAlive() ))
if (isAlive() && !unit->isAlive())
return NULL;
// not allow interaction under control, but allow with own pets
@ -2357,10 +2356,21 @@ void Player::GiveXP(uint32 xp, Unit* victim)
if(level >= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
return;
// handle SPELL_AURA_MOD_XP_PCT auras
Unit::AuraList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_XP_PCT);
for(Unit::AuraList::const_iterator i = ModXPPctAuras.begin();i != ModXPPctAuras.end(); ++i)
xp = uint32(xp*(1.0f + (*i)->GetModifier()->m_amount / 100.0f));
if(victim)
{
// handle SPELL_AURA_MOD_KILL_XP_PCT auras
Unit::AuraList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_KILL_XP_PCT);
for(Unit::AuraList::const_iterator i = ModXPPctAuras.begin();i != ModXPPctAuras.end(); ++i)
xp = uint32(xp*(1.0f + (*i)->GetModifier()->m_amount / 100.0f));
}
else
{
// handle SPELL_AURA_MOD_QUEST_XP_PCT auras
Unit::AuraList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_QUEST_XP_PCT);
for(Unit::AuraList::const_iterator i = ModXPPctAuras.begin();i != ModXPPctAuras.end(); ++i)
xp = uint32(xp*(1.0f + (*i)->GetModifier()->m_amount / 100.0f));
}
// XP resting bonus for kill
uint32 rested_bonus_xp = victim ? GetXPRestBonus(xp) : 0;
@ -12561,6 +12571,13 @@ bool Player::CanRewardQuest( Quest const *pQuest, uint32 reward, bool msg )
return true;
}
void Player::SendPetTameFailure(PetTameFailureReason reason)
{
WorldPacket data(SMSG_PET_TAME_FAILURE, 1);
data << uint8(reason);
GetSession()->SendPacket(&data);
}
void Player::AddQuest( Quest const *pQuest, Object *questGiver )
{
uint16 log_slot = FindQuestSlot( 0 );

View file

@ -1418,6 +1418,8 @@ class MANGOS_DLL_SPEC Player : public Unit
bool m_mailsLoaded;
bool m_mailsUpdated;
void SendPetTameFailure(PetTameFailureReason reason);
void SetBindPoint(uint64 guid);
void SendTalentWipeConfirm(uint64 guid);
void RewardRage( uint32 damage, uint32 weaponSpeedHitFactor, bool attacker );

View file

@ -185,11 +185,15 @@ void PoolGroup<T>::SpawnObject(uint32 limit, bool cache)
if (limit == 1) // This is the only case where explicit chance is used
{
uint32 roll = RollOne();
if (cache && m_LastDespawnedNode != roll)
Despawn1Object(m_LastDespawnedNode);
if (!cache || (cache && m_LastDespawnedNode != roll))
{
if (cache)
Despawn1Object(m_LastDespawnedNode);
Spawn1Object(roll);
}
else
ReSpawn1Object(roll);
m_LastDespawnedNode = 0;
Spawn1Object(roll);
}
else if (limit < EqualChanced.size() && m_SpawnedPoolAmount < limit)
{

View file

@ -49,7 +49,7 @@ ReactorAI::AttackStart(Unit *p)
{
DEBUG_LOG("Tag unit GUID: %u (TypeId: %u) as a victim", p->GetGUIDLow(), p->GetTypeId());
i_victimGuid = p->GetGUID();
m_creature->AddThreat(p, 0.0f);
m_creature->AddThreat(p);
m_creature->SetInCombatWith(p);
p->SetInCombatWith(m_creature);

View file

@ -2640,4 +2640,23 @@ enum MailResponseResult
MAIL_ERR_ITEM_HAS_EXPIRED = 21,
};
// reasons for why pet tame may fail
// in fact, these are also used elsewhere
enum PetTameFailureReason
{
PETTAME_INVALIDCREATURE = 0,
PETTAME_TOOMANY = 1,
PETTAME_CREATUREALREADYOWNED = 2,
PETTAME_NOTTAMEABLE = 3,
PETTAME_ANOTHERSUMMONACTIVE = 4,
PETTAME_UNITSCANTTAME = 5,
PETTAME_NOPETAVAILABLE = 6, // not used in taming
PETTAME_INTERNALERROR = 7,
PETTAME_TOOHIGHLEVEL = 8,
PETTAME_DEAD = 9, // not used in taming
PETTAME_NOTDEAD = 10, // not used in taming
PETTAME_CANTCONTROLEXOTIC = 11, // 3.x
PETTAME_UNKNOWNERROR = 12
};
#endif

View file

@ -1092,7 +1092,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
if (!unit->isInCombat() && unit->GetTypeId() != TYPEID_PLAYER && ((Creature*)unit)->AI())
((Creature*)unit)->AI()->AttackedBy(realCaster);
unit->AddThreat(realCaster, 0.0f);
unit->AddThreat(realCaster);
unit->SetInCombatWith(realCaster);
realCaster->SetInCombatWith(unit);
@ -1116,7 +1116,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
if (unit->isInCombat() && !(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO))
{
realCaster->SetInCombatState(unit->GetCombatTimer() > 0);
unit->getHostileRefManager().threatAssist(realCaster, 0.0f);
unit->getHostileRefManager().threatAssist(realCaster, 0.0f, m_spellInfo);
}
}
}
@ -3770,7 +3770,7 @@ void Spell::HandleThreatSpells(uint32 spellId)
if(!threat)
return;
m_targets.getUnitTarget()->AddThreat(m_caster, float(threat));
m_targets.getUnitTarget()->AddThreat(m_caster, float(threat), false, GetSpellSchoolMask(m_spellInfo), m_spellInfo);
DEBUG_LOG("Spell %u, rank %u, added an additional %i threat", spellId, spellmgr.GetSpellRank(spellId), threat);
}
@ -3860,9 +3860,6 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_NOT_READY;
}
if (IsDeathOnlySpell(m_spellInfo) && m_caster->isAlive())
return SPELL_FAILED_TARGET_NOT_DEAD;
// only allow triggered spells if at an ended battleground
if( !m_IsTriggeredSpell && m_caster->GetTypeId() == TYPEID_PLAYER)
if(BattleGround * bg = ((Player*)m_caster)->GetBattleGround())
@ -3933,6 +3930,9 @@ SpellCastResult Spell::CheckCast(bool strict)
if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot)))
return SPELL_FAILED_TARGET_AURASTATE;
if (IsDeathOnlySpell(m_spellInfo) && target->isAlive())
return SPELL_FAILED_TARGET_NOT_DEAD;
// Target aura req check if need
if(m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell))
return SPELL_FAILED_CASTER_AURASTATE;
@ -4313,26 +4313,50 @@ SpellCastResult Spell::CheckCast(bool strict)
}
case SPELL_EFFECT_TAMECREATURE:
{
if (m_caster->GetTypeId() != TYPEID_PLAYER)
if (m_caster->GetTypeId() != TYPEID_PLAYER ||
!m_targets.getUnitTarget() ||
m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER)
return SPELL_FAILED_BAD_TARGETS;
if (!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER)
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
Player* plrCaster = (Player*)m_caster;
if(plrCaster->getClass() != CLASS_HUNTER)
{
plrCaster->SendPetTameFailure(PETTAME_UNITSCANTTAME);
return SPELL_FAILED_DONT_REPORT;
}
Creature* target = (Creature*)m_targets.getUnitTarget();
if (target->getLevel() > m_caster->getLevel())
return SPELL_FAILED_HIGHLEVEL;
if(target->isPet() || target->isCharmed())
{
plrCaster->SendPetTameFailure(PETTAME_CREATUREALREADYOWNED);
return SPELL_FAILED_DONT_REPORT;
}
// use SMSG_PET_TAME_FAILURE?
if (!target->GetCreatureInfo()->isTameable (((Player*)m_caster)->CanTameExoticPets()))
return SPELL_FAILED_BAD_TARGETS;
if (target->getLevel() > plrCaster->getLevel())
{
plrCaster->SendPetTameFailure(PETTAME_TOOHIGHLEVEL);
return SPELL_FAILED_DONT_REPORT;
}
if(m_caster->GetPetGUID())
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
if (target->GetCreatureInfo()->IsExotic() && !plrCaster->CanTameExoticPets())
{
plrCaster->SendPetTameFailure(PETTAME_CANTCONTROLEXOTIC);
return SPELL_FAILED_DONT_REPORT;
}
if(m_caster->GetCharmGUID())
return SPELL_FAILED_ALREADY_HAVE_CHARM;
if (!target->GetCreatureInfo()->isTameable(plrCaster->CanTameExoticPets()))
{
plrCaster->SendPetTameFailure(PETTAME_NOTTAMEABLE);
return SPELL_FAILED_DONT_REPORT;
}
if(plrCaster->GetPetGUID() || plrCaster->GetCharmGUID())
{
plrCaster->SendPetTameFailure(PETTAME_ANOTHERSUMMONACTIVE);
return SPELL_FAILED_DONT_REPORT;
}
break;
}

View file

@ -59,7 +59,7 @@ enum AuraType
SPELL_AURA_MOD_DAMAGE_TAKEN = 14,
SPELL_AURA_DAMAGE_SHIELD = 15,
SPELL_AURA_MOD_STEALTH = 16,
SPELL_AURA_MOD_DETECT = 17,
SPELL_AURA_MOD_STEALTH_DETECT = 17,
SPELL_AURA_MOD_INVISIBILITY = 18,
SPELL_AURA_MOD_INVISIBILITY_DETECTION = 19,
SPELL_AURA_OBS_MOD_HEALTH = 20, //20,21 unofficial
@ -242,12 +242,12 @@ enum AuraType
SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197,
SPELL_AURA_198 = 198, // old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT = 199,
SPELL_AURA_MOD_XP_PCT = 200,
SPELL_AURA_MOD_KILL_XP_PCT = 200,
SPELL_AURA_FLY = 201,
SPELL_AURA_IGNORE_COMBAT_RESULT = 202,
SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE = 203,
SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE = 204,
SPELL_AURA_205 = 205, // unused
SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_DAMAGE = 205,
SPELL_AURA_MOD_SPEED_MOUNTED = 206, // ? used in strange spells
SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED = 207,
SPELL_AURA_MOD_SPEED_FLIGHT = 208,
@ -311,11 +311,11 @@ enum AuraType
SPELL_AURA_266 = 266,
SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL = 267,
SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268,
SPELL_AURA_269 = 269,
SPELL_AURA_MOD_IGNORE_DAMAGE_REDUCTION_SCHOOL = 269,
SPELL_AURA_MOD_IGNORE_TARGET_RESIST = 270, // Possibly need swap vs 195 aura used only in 1 spell Chaos Bolt Passive
SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271,
SPELL_AURA_272 = 272,
SPELL_AURA_273 = 273,
SPELL_AURA_X_RAY = 273,
SPELL_AURA_274 = 274,
SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275,
SPELL_AURA_276 = 276, // Only "Test Mod Damage % Mechanic" spell, possible mod damage done
@ -329,26 +329,26 @@ enum AuraType
SPELL_AURA_284,
SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR = 285,
SPELL_AURA_ABILITY_PERIODIC_CRIT = 286,
SPELL_AURA_DEFLECT_SPELLS,
SPELL_AURA_288,
SPELL_AURA_289,
SPELL_AURA_MOD_ALL_CRIT_CHANCE,
SPELL_AURA_291,
SPELL_AURA_292,
SPELL_AURA_293,
SPELL_AURA_294,
SPELL_AURA_295,
SPELL_AURA_296,
SPELL_AURA_297,
SPELL_AURA_298,
SPELL_AURA_299,
SPELL_AURA_300,
SPELL_AURA_301,
SPELL_AURA_302,
SPELL_AURA_303,
SPELL_AURA_304,
SPELL_AURA_305,
SPELL_AURA_306,
SPELL_AURA_DEFLECT_SPELLS = 287,
SPELL_AURA_288 = 288,
SPELL_AURA_289 = 289,
SPELL_AURA_MOD_ALL_CRIT_CHANCE = 290,
SPELL_AURA_MOD_QUEST_XP_PCT = 291,
SPELL_AURA_292 = 292,
SPELL_AURA_293 = 293,
SPELL_AURA_294 = 294,
SPELL_AURA_295 = 295,
SPELL_AURA_296 = 296,
SPELL_AURA_297 = 297,
SPELL_AURA_298 = 298,
SPELL_AURA_299 = 299,
SPELL_AURA_300 = 300,
SPELL_AURA_301 = 301,
SPELL_AURA_302 = 302,
SPELL_AURA_303 = 303,
SPELL_AURA_304 = 304,
SPELL_AURA_305 = 305,
SPELL_AURA_306 = 306,
TOTAL_AURAS = 307
};

View file

@ -64,10 +64,10 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleModTaunt, // 11 SPELL_AURA_MOD_TAUNT
&Aura::HandleAuraModStun, // 12 SPELL_AURA_MOD_STUN
&Aura::HandleModDamageDone, // 13 SPELL_AURA_MOD_DAMAGE_DONE
&Aura::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
&Aura::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DoAttackDamage
&Aura::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellBaseDamageBonusForVictim
&Aura::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DealMeleeDamage
&Aura::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH
&Aura::HandleNoImmediateEffect, // 17 SPELL_AURA_MOD_STEALTH_DETECT
&Aura::HandleNoImmediateEffect, // 17 SPELL_AURA_MOD_STEALTH_DETECT implemented in Unit::isVisibleForOrDetect
&Aura::HandleInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY
&Aura::HandleInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
&Aura::HandleAuraModTotalHealthPercentRegen, // 20 SPELL_AURA_OBS_MOD_HEALTH
@ -96,7 +96,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
&Aura::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
&Aura::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
&Aura::HandleUnused, // 46 SPELL_AURA_46 (used in test spells 54054 and 54058, and spell 48050) (3.0.8a)
&Aura::HandleUnused, // 46 SPELL_AURA_46 (used in test spells 54054 and 54058, and spell 48050) (3.0.8a-3.2.2a)
&Aura::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT
&Aura::HandleNULL, // 48 SPELL_AURA_48 spell Napalm (area damage spell with additional delayed damage effect)
&Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT
@ -113,34 +113,34 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
&Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
&Aura::HandlePeriodicHealthFunnel, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
&Aura::HandleUnused, // 63 unused (3.0.8a) old SPELL_AURA_PERIODIC_MANA_FUNNEL
&Aura::HandleUnused, // 63 unused (3.0.8a-3.2.2a) old SPELL_AURA_PERIODIC_MANA_FUNNEL
&Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH
&Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK
&Aura::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
&Aura::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM
&Aura::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
&Aura::HandleSchoolAbsorb, // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
&Aura::HandleUnused, // 70 SPELL_AURA_EXTRA_ATTACKS Useless, used by only one spell that has only visual effect
&Aura::HandleUnused, // 70 SPELL_AURA_EXTRA_ATTACKS Useless, used by only one spell 41560 that has only visual effect (3.2.2a)
&Aura::HandleModSpellCritChanceShool, // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
&Aura::HandleModPowerCostPCT, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
&Aura::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
&Aura::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
&Aura::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE
&Aura::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE implemented in WorldSession::HandleMessagechatOpcode
&Aura::HandleFarSight, // 76 SPELL_AURA_FAR_SIGHT
&Aura::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY
&Aura::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED
&Aura::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
&Aura::HandleModPercentStat, // 80 SPELL_AURA_MOD_PERCENT_STAT
&Aura::HandleNoImmediateEffect, // 81 SPELL_AURA_SPLIT_DAMAGE_PCT
&Aura::HandleNoImmediateEffect, // 81 SPELL_AURA_SPLIT_DAMAGE_PCT implemented in Unit::CalcAbsorbResist
&Aura::HandleWaterBreathing, // 82 SPELL_AURA_WATER_BREATHING
&Aura::HandleModBaseResistance, // 83 SPELL_AURA_MOD_BASE_RESISTANCE
&Aura::HandleModRegen, // 84 SPELL_AURA_MOD_REGEN
&Aura::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN
&Aura::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
&Aura::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
&Aura::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
&Aura::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT implemented in Player::RegenerateHealth
&Aura::HandlePeriodicDamagePCT, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
&Aura::HandleUnused, // 90 unused (3.0.8a) old SPELL_AURA_MOD_RESIST_CHANCE
&Aura::HandleUnused, // 90 unused (3.0.8a-3.2.2a) old SPELL_AURA_MOD_RESIST_CHANCE
&Aura::HandleNoImmediateEffect, // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance
&Aura::HandlePreventFleeing, // 92 SPELL_AURA_PREVENTS_FLEEING
&Aura::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE
@ -150,7 +150,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleManaShield, // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist
&Aura::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT
&Aura::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER
&Aura::HandleUnused, //100 SPELL_AURA_AURAS_VISIBLE obsolete? all player can see all auras now, but still have spells including GM-spell
&Aura::HandleUnused, //100 SPELL_AURA_AURAS_VISIBLE obsolete 3.x? all player can see all auras now, but still have 2 spells including GM-spell (1852,2855)
&Aura::HandleModResistancePercent, //101 SPELL_AURA_MOD_RESISTANCE_PCT
&Aura::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
&Aura::HandleAuraModTotalThreat, //103 SPELL_AURA_MOD_TOTAL_THREAT
@ -162,14 +162,14 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleAddTargetTrigger, //109 SPELL_AURA_ADD_TARGET_TRIGGER
&Aura::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
&Aura::HandleNoImmediateEffect, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER implemented in Unit::SelectMagnetTarget
&Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
&Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS implemented in diff functions.
&Aura::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
&Aura::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
&Aura::HandleNoImmediateEffect, //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusForVictim
&Aura::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
&Aura::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT imppemented in Player::RegenerateAll and Player::RegenerateHealth
&Aura::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult
&Aura::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus
&Aura::HandleUnused, //119 unused (3.0.8a) old SPELL_AURA_SHARE_PET_TRACKING
&Aura::HandleUnused, //119 unused (3.0.8a-3.2.2a) old SPELL_AURA_SHARE_PET_TRACKING
&Aura::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE
&Aura::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY
&Aura::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
@ -194,27 +194,27 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
&Aura::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
&Aura::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
&Aura::HandleAuraSafeFall, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
&Aura::HandleAuraSafeFall, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
&Aura::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS
&Aura::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE
&Aura::HandleModMechanicImmunityMask, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY implemented in Unit::IsImmunedToSpell and Unit::IsImmunedToSpellEffect (check part)
&Aura::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE implemented in Player::CanTameExoticPets
&Aura::HandleModMechanicImmunityMask, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK implemented in Unit::IsImmunedToSpell and Unit::IsImmunedToSpellEffect (check part)
&Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
&Aura::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK
&Aura::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK implemented in Spell::Delayed and Spell::DelayedChannel
&Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
&Aura::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
&Aura::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
&Aura::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
&Aura::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL
&Aura::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
&Aura::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
&Aura::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
&Aura::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
&Aura::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT implemented in Unit::CalcAbsorbResist
&Aura::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL implemented in Unit::isVisibleForOrDetect
&Aura::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING implemented in Player::getMaxTimer
&Aura::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN implemented in Player::CalculateReputationGain
&Aura::HandleUnused, //157 SPELL_AURA_PET_DAMAGE_MULTI (single test like spell 20782, also single for 214 aura)
&Aura::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
&Aura::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
&Aura::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
&Aura::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
&Aura::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT implemented in Player::RewardHonor
&Aura::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
&Aura::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT implemented in Player::RegenerateAll and Player::RegenerateHealth
&Aura::HandleAuraPowerBurn, //162 SPELL_AURA_POWER_BURN_MANA
&Aura::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
&Aura::HandleUnused, //164 unused (3.0.8a), only one test spell
&Aura::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE implememnted in Unit::CalculateMeleeDamage and Unit::SpellCriticalDamageBonus
&Aura::HandleUnused, //164 unused (3.0.8a-3.2.2a), only one test spell 10654
&Aura::HandleNoImmediateEffect, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
&Aura::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
&Aura::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
@ -223,17 +223,17 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNULL, //170 SPELL_AURA_DETECT_AMORE different spells that ignore transformation effects
&Aura::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK
&Aura::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
&Aura::HandleUnused, //173 unused (3.0.8a) no spells, old SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
&Aura::HandleUnused, //173 unused (3.0.8a-3.2.2a) no spells, old SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
&Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus
&Aura::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
&Aura::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end
&Aura::HandleNULL, //177 SPELL_AURA_AOE_CHARM
&Aura::HandleNULL, //177 SPELL_AURA_AOE_CHARM (22 spells)
&Aura::HandleNoImmediateEffect, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult
&Aura::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
&Aura::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus
&Aura::HandleUnused, //181 unused (3.0.8a) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS
&Aura::HandleUnused, //181 unused (3.0.8a-3.2.2a) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS
&Aura::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
&Aura::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT only used in 28746
&Aura::HandleNoImmediateEffect, //183 SPELL_AURA_MOD_CRITICAL_THREAT only used in 28746, implemented in ThreatCalcHelper::calcThreat
&Aura::HandleNoImmediateEffect, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
&Aura::HandleNoImmediateEffect, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
&Aura::HandleNoImmediateEffect, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE implemented in Unit::MagicSpellHitResult
@ -244,41 +244,41 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
&Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
&Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
&Aura::HandleNULL, //194 SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL
&Aura::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL implement in Unit::CalculateSpellDamage
&Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN
&Aura::HandleNoImmediateEffect, //194 SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL implement in Unit::CalcNotIgnoreAbsorbDamage
&Aura::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL implement in Unit::CalcNotIgnoreAbsorbDamage
&Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN (single spell 24818 in 3.2.2a)
&Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
&Aura::HandleUnused, //198 unused (3.0.8a) old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
&Aura::HandleUnused, //198 unused (3.0.8a-3.2.2a) old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
&Aura::HandleNoImmediateEffect, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT implemented in Unit::MagicSpellHitResult
&Aura::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::GiveXP
&Aura::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_KILL_XP_PCT implemented in Player::GiveXP
&Aura::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode...
&Aura::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
&Aura::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
&Aura::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
&Aura::HandleNULL, //205 vulnerable to school dmg?
&Aura::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::SpellCriticalDamageBonus
&Aura::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::SpellCriticalDamageBonus
&Aura::HandleNoImmediateEffect, //205 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_DAMAGE implemented in Unit::SpellCriticalDamageBonus
&Aura::HandleNULL, //206 SPELL_AURA_MOD_SPEED_MOUNTED
&Aura::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
&Aura::HandleAuraModIncreaseFlightSpeed, //208 SPELL_AURA_MOD_SPEED_FLIGHT, used only in spell: Flight Form (Passive)
&Aura::HandleAuraModIncreaseFlightSpeed, //209 SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS
&Aura::HandleNULL, //210 Commentator's Command
&Aura::HandleNULL, //210 "Increase flight speed by"
&Aura::HandleAuraModIncreaseFlightSpeed, //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
&Aura::HandleAuraModRangedAttackPowerOfStatPercent, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
&Aura::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
&Aura::HandleNULL, //214 Tamed Pet Passive
&Aura::HandleUnused, //214 Tamed Pet Passive (single test like spell 20782, also single for 157 aura)
&Aura::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION
&Aura::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS
&Aura::HandleUnused, //217 unused (3.0.8a)
&Aura::HandleUnused, //217 unused (3.0.8a-3.2.2a)
&Aura::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED
&Aura::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
&Aura::HandleModRatingFromStat, //220 SPELL_AURA_MOD_RATING_FROM_STAT
&Aura::HandleNULL, //221 ignored
&Aura::HandleUnused, //222 unused (3.0.8a) only for spell 44586 that not used in real spell cast
&Aura::HandleNULL, //223 Cold Stare
&Aura::HandleUnused, //224 unused (3.0.8a)
&Aura::HandleUnused, //222 unused (3.0.8a-3.2.2a) only for spell 44586 that not used in real spell cast
&Aura::HandleNULL, //223 dummy code (cast damage spell to attacker) and another dymmy (jump to another nearby raid member)
&Aura::HandleUnused, //224 unused (3.0.8a-3.2.2a)
&Aura::HandleNoImmediateEffect, //225 SPELL_AURA_PRAYER_OF_MENDING
&Aura::HandleAuraPeriodicDummy, //226 SPELL_AURA_PERIODIC_DUMMY
&Aura::HandlePeriodicTriggerSpellWithValue, //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
&Aura::HandleNoImmediateEffect, //228 stealth detection
&Aura::HandleNoImmediateEffect, //228 SPELL_AURA_DETECT_STEALTH
&Aura::HandleNoImmediateEffect, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE implemented in Unit::SpellDamageBonus
&Aura::HandleAuraModIncreaseMaxHealth, //230 Commanding Shout
&Aura::HandleNoImmediateEffect, //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
@ -292,11 +292,11 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
&Aura::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE
&Aura::HandleForceMoveForward, //241 Forces the player to move forward
&Aura::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING
&Aura::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING (only 2 test spels in 3.2.2a)
&Aura::HandleNULL, //243 faction reaction override spells
&Aura::HandleComprehendLanguage, //244 Comprehend language
&Aura::HandleComprehendLanguage, //244 SPELL_AURA_COMPREHEND_LANGUAGE
&Aura::HandleNULL, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS
&Aura::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL
&Aura::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL implemented in Unit::CalculateSpellDuration
&Aura::HandleNULL, //247 target to become a clone of the caster
&Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
&Aura::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE
@ -314,16 +314,16 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandlePhase, //261 SPELL_AURA_PHASE undetectable invisibility? implemented in Unit::isVisibleForOrDetect
&Aura::HandleNULL, //262 ignore combat/aura state?
&Aura::HandleNULL, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask
&Aura::HandleUnused, //264 unused (3.0.8a)
&Aura::HandleUnused, //265 unused (3.0.8a)
&Aura::HandleUnused, //266 unused (3.0.8a)
&Aura::HandleUnused, //264 unused (3.0.8a-3.2.2a)
&Aura::HandleUnused, //265 unused (3.0.8a-3.2.2a)
&Aura::HandleUnused, //266 unused (3.0.8a-3.2.2a)
&Aura::HandleNoImmediateEffect, //267 SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL implemented in Unit::IsImmunedToSpellEffect
&Aura::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT
&Aura::HandleNULL, //269 ignore DR effects?
&Aura::HandleNULL, //270 SPELL_AURA_MOD_IGNORE_TARGET_RESIST
&Aura::HandleNoImmediateEffect, //269 SPELL_AURA_MOD_IGNORE_DAMAGE_REDUCTION_SCHOOL implemented in Unit::CalcNotIgnoreDamageRedunction
&Aura::HandleUnused, //270 SPELL_AURA_MOD_IGNORE_TARGET_RESIST (unused in 3.2.2a)
&Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus
&Aura::HandleNULL, //272 reduce spell cast time?
&Aura::HandleNULL, //273 x-ray effect
&Aura::HandleNoImmediateEffect, //273 SPELL_AURA_X_RAY (client side implementation)
&Aura::HandleNULL, //274 proc free shot?
&Aura::HandleNoImmediateEffect, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select
&Aura::HandleNULL, //276 mod damage % mechanic?
@ -334,25 +334,25 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNoImmediateEffect, //281 SPELL_AURA_MOD_HONOR_GAIN implemented in Player::RewardHonor
&Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
&Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus
&Aura::HandleUnused, //284 51 spells
&Aura::HandleNULL, //284 51 spells
&Aura::HandleAuraModAttackPowerOfArmor, //285 SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR implemented in Player::UpdateAttackPowerAndDamage
&Aura::HandleNoImmediateEffect, //286 SPELL_AURA_ABILITY_PERIODIC_CRIT implemented in Aura::IsCritFromAbilityAura called from Aura::PeriodicTick
&Aura::HandleNoImmediateEffect, //287 SPELL_AURA_DEFLECT_SPELLS implemented in Unit::MagicSpellHitResult and Unit::MeleeSpellHitResult
&Aura::HandleUnused, //288 increase parry/deflect, prevent attack
&Aura::HandleUnused, //289 unused
&Aura::HandleNULL, //288 increase parry/deflect, prevent attack (single spell used 67801)
&Aura::HandleUnused, //289 unused (3.2.2a)
&Aura::HandleAuraModAllCritChance, //290 SPELL_AURA_MOD_ALL_CRIT_CHANCE
&Aura::HandleUnused, //291 1 spell (+pct experience bonus)
&Aura::HandleNoImmediateEffect, //291 SPELL_AURA_MOD_QUEST_XP_PCT implemented in Player::GiveXP
&Aura::HandleNULL, //292 call stabled pet
&Aura::HandleNULL, //293 3 spells
&Aura::HandleNULL, //294 2 spells, possible prevent mana regen
&Aura::HandleNULL, //295 unused
&Aura::HandleUnused, //295 unused (3.2.2a)
&Aura::HandleNULL, //296 2 spells
&Aura::HandleNULL, //297 1 spell (counter spell school?)
&Aura::HandleNULL, //298 unused
&Aura::HandleNULL, //299 unused
&Aura::HandleUnused, //298 unused (3.2.2a)
&Aura::HandleUnused, //299 unused (3.2.2a)
&Aura::HandleNULL, //300 3 spells (share damage?)
&Aura::HandleNULL, //301 5 spells
&Aura::HandleNULL, //302 unused
&Aura::HandleUnused, //302 unused (3.2.2a)
&Aura::HandleNULL, //303 17 spells
&Aura::HandleNULL, //304 2 spells (alcohol effect?)
&Aura::HandleNULL, //305 2 spells
@ -1575,8 +1575,13 @@ void Aura::TriggerSpell()
// case 25041: break;
// // Agro Drones
// case 25152: break;
// // Consume
// case 25371: break;
// Consume
case 25371:
{
int32 bpDamage = target->GetMaxHealth()*10/100;
caster->CastCustomSpell(target, 25373, &bpDamage, NULL, NULL, true, NULL, this);
return;
}
// // Pain Spike
// case 25572: break;
// // Rotate 360
@ -2195,7 +2200,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
case 1515: // Tame beast
// FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness
if( caster && m_target->CanHaveThreatList())
m_target->AddThreat(caster, 10.0f);
m_target->AddThreat(caster, 10.0f, false, GetSpellSchoolMask(GetSpellProto()), GetSpellProto());
return;
case 13139: // net-o-matic
// root to self part of (root_target->charge->root_self sequence
@ -4039,7 +4044,7 @@ void Aura::HandleAuraModTotalThreat(bool apply, bool Real)
float threatMod = apply ? float(m_modifier.m_amount) : float(-m_modifier.m_amount);
m_target->getHostileRefManager().threatAssist(caster, threatMod);
m_target->getHostileRefManager().threatAssist(caster, threatMod, GetSpellProto());
}
void Aura::HandleModTaunt(bool apply, bool Real)
@ -5759,6 +5764,37 @@ void Aura::HandleSpellSpecificBoosts(bool apply)
}
case SPELLFAMILY_PALADIN:
{
if (m_spellProto->Id == 31884) // Avenging Wrath
{
if(!apply)
spellId1 = 57318; // Sanctified Wrath (triggered)
else
{
int32 percent = 0;
Unit::AuraList const& dummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
{
if ((*itr)->GetSpellProto()->SpellIconID == 3029)
{
percent = (*itr)->GetModifier()->m_amount;
break;
}
}
// apply in special way
if(percent)
{
spellId1 = 57318; // Sanctified Wrath (triggered)
// prevent aura deletion, specially in multi-boost case
SetInUse(true);
m_target->CastCustomSpell(m_target, spellId1, &percent, &percent, NULL, true, NULL, this);
SetInUse(false);
}
return;
}
break;
}
// Only process on player casting paladin aura
// all aura bonuses applied also in aura area effect way to caster
if (GetCasterGUID() != m_target->GetGUID() || !IS_PLAYER_GUID(GetCasterGUID()))
@ -6311,6 +6347,10 @@ void Aura::PeriodicTick()
// This method can modify pdamage
bool isCrit = IsCritFromAbilityAura(pCaster, pdamage);
// send critical in hit info for threat calculation
if (isCrit)
cleanDamage.hitOutCome = MELEE_HIT_CRIT;
pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
@ -6556,7 +6596,7 @@ void Aura::PeriodicTick()
if(gain_amount)
{
int32 gain = pCaster->ModifyPower(power, gain_amount);
m_target->AddThreat(pCaster, float(gain) * 0.5f, GetSpellSchoolMask(GetSpellProto()), GetSpellProto());
m_target->AddThreat(pCaster, float(gain) * 0.5f, pInfo.critical, GetSpellSchoolMask(GetSpellProto()), GetSpellProto());
}
break;
}

View file

@ -1043,6 +1043,31 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastSpell(m_caster, spell_id, true, NULL);
return;
}
case 34665: //Administer Antidote
{
if (!unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER )
return;
// Spell has scriptable target but for sure.
if (unitTarget->GetTypeId() != TYPEID_UNIT)
return;
uint32 health = unitTarget->GetHealth();
float x, y, z, o;
unitTarget->GetPosition(x, y, z);
o = unitTarget->GetOrientation();
((Creature*)unitTarget)->ForcedDespawn();
if (Creature* summon = m_caster->SummonCreature(16992, x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,180000))
{
summon->SetHealth(health);
((Player*)m_caster)->RewardPlayerAndGroupAtEvent(16992, summon);
if (summon->AI())
summon->AI()->AttackStart(m_caster);
}
return;
}
case 35745: // Socrethar's Stone
{
uint32 spell_id;
@ -1122,31 +1147,6 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastSpell(m_caster, 42337, true, NULL);
return;
}
case 34665: //Administer Antidote
{
if (!unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER )
return;
// Spell has scriptable target but for sure.
if (unitTarget->GetTypeId() != TYPEID_UNIT)
return;
uint32 health = unitTarget->GetHealth();
float x, y, z, o;
unitTarget->GetPosition(x, y, z);
o = unitTarget->GetOrientation();
((Creature*)unitTarget)->ForcedDespawn();
if (Creature* summon = m_caster->SummonCreature(16992, x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,180000))
{
summon->SetHealth(health);
((Player*)m_caster)->RewardPlayerAndGroupAtEvent(16992, summon);
if (summon->AI())
summon->AI()->AttackStart(m_caster);
}
return;
}
case 44997: // Converting Sentry
{
//Converted Sentry Credit
@ -1159,13 +1159,34 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastSpell(m_caster, 45088, true);
return;
}
case 55004: // Nitro Boosts
if (!m_CastItem)
case 49357: // Brewfest Mount Transformation
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
if (roll_chance_i(95)) // Nitro Boosts - success
m_caster->CastSpell(m_caster, 54861, true, m_CastItem);
else // Knocked Up - backfire 5%
m_caster->CastSpell(m_caster, 46014, true, m_CastItem);
if (!m_caster->HasAuraType(SPELL_AURA_MOUNTED))
return;
m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
// Ram for Alliance, Kodo for Horde
if (((Player *)m_caster)->GetTeam() == ALLIANCE)
{
if (m_caster->GetSpeedRate(MOVE_RUN) >= 2.0f)
// 100% Ram
m_caster->CastSpell(m_caster, 43900, true);
else
// 60% Ram
m_caster->CastSpell(m_caster, 43899, true);
}
else
{
if (((Player *)m_caster)->GetSpeedRate(MOVE_RUN) >= 2.0f)
// 100% Kodo
m_caster->CastSpell(m_caster, 49379, true);
else
// 60% Kodo
m_caster->CastSpell(m_caster, 49378, true);
}
return;
case 50243: // Teach Language
{
@ -1233,6 +1254,35 @@ void Spell::EffectDummy(uint32 i)
return;
m_caster->CastCustomSpell(unitTarget, 52752, &damage, NULL, NULL, true);
return;
case 52845: // Brewfest Mount Transformation (Faction Swap)
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
if (!m_caster->HasAuraType(SPELL_AURA_MOUNTED))
return;
m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
// Ram for Horde, Kodo for Alliance
if (((Player *)m_caster)->GetTeam() == HORDE)
{
if (m_caster->GetSpeedRate(MOVE_RUN) >= 2.0f)
// 100% Ram
m_caster->CastSpell(m_caster, 43900, true);
else
// 60% Ram
m_caster->CastSpell(m_caster, 43899, true);
}
else
{
if (((Player *)m_caster)->GetSpeedRate(MOVE_RUN) >= 2.0f)
// 100% Kodo
m_caster->CastSpell(m_caster, 49379, true);
else
// 60% Kodo
m_caster->CastSpell(m_caster, 49378, true);
}
return;
case 53341: // Rune of Cinderglacier
case 53343: // Rune of Razorice
{
@ -1240,6 +1290,14 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastSpell(m_caster, 54586, true);
return;
}
case 55004: // Nitro Boosts
if (!m_CastItem)
return;
if (roll_chance_i(95)) // Nitro Boosts - success
m_caster->CastSpell(m_caster, 54861, true, m_CastItem);
else // Knocked Up - backfire 5%
m_caster->CastSpell(m_caster, 46014, true, m_CastItem);
return;
case 58418: // Portal to Orgrimmar
case 58420: // Portal to Stormwind
return; // implemented in EffectScript[0]
@ -3840,7 +3898,7 @@ void Spell::EffectAddHonor(uint32 /*i*/)
if (m_CastItem)
{
((Player*)unitTarget)->RewardHonor(NULL, 1, damage / 10);
sLog.outError("SpellEffect::AddHonor (spell_id %u) rewards %d honor points (item %u) for player: %u", m_spellInfo->Id, damage/10, m_CastItem->GetEntry(),((Player*)unitTarget)->GetGUIDLow());
sLog.outDebug("SpellEffect::AddHonor (spell_id %u) rewards %d honor points (item %u) for player: %u", m_spellInfo->Id, damage/10, m_CastItem->GetEntry(),((Player*)unitTarget)->GetGUIDLow());
return;
}
@ -4097,35 +4155,23 @@ void Spell::EffectEnchantItemTmp(uint32 i)
void Spell::EffectTameCreature(uint32 /*i*/)
{
if(m_caster->GetPetGUID())
return;
if(!unitTarget)
return;
if(unitTarget->GetTypeId() == TYPEID_PLAYER)
return;
// Caster must be player, checked in Spell::CheckCast
Player* plr = (Player*)m_caster;
Creature* creatureTarget = (Creature*)unitTarget;
if(creatureTarget->isPet())
return;
if(m_caster->getClass() != CLASS_HUNTER)
return;
// cast finish successfully
//SendChannelUpdate(0);
finish();
Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget,m_spellInfo->Id);
Pet* pet = plr->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
if(!pet) // in versy specific state like near world end/etc.
return;
// "kill" original creature
creatureTarget->ForcedDespawn();
uint32 level = (creatureTarget->getLevel() < (m_caster->getLevel() - 5)) ? (m_caster->getLevel() - 5) : creatureTarget->getLevel();
uint32 level = (creatureTarget->getLevel() < (plr->getLevel() - 5)) ? (plr->getLevel() - 5) : creatureTarget->getLevel();
// prepare visual effect for levelup
pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
@ -4137,13 +4183,10 @@ void Spell::EffectTameCreature(uint32 /*i*/)
pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
// caster have pet now
m_caster->SetPet(pet);
plr->SetPet(pet);
if(m_caster->GetTypeId() == TYPEID_PLAYER)
{
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
((Player*)m_caster)->PetSpellInitialize();
}
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
plr->PetSpellInitialize();
}
void Spell::EffectSummonPet(uint32 i)
@ -4681,7 +4724,7 @@ void Spell::EffectThreat(uint32 /*i*/)
if(!unitTarget->CanHaveThreatList())
return;
unitTarget->AddThreat(m_caster, float(damage));
unitTarget->AddThreat(m_caster, float(damage), false, GetSpellSchoolMask(m_spellInfo), m_spellInfo);
}
void Spell::EffectHealMaxHealth(uint32 /*i*/)

View file

@ -438,7 +438,8 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
// some explicitly required dummy effect sets
switch(spellId)
{
case 28441: return false; // AB Effect 000
case 28441: // AB Effect 000
return false;
default:
break;
}
@ -469,6 +470,7 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
case 38638: // Nether Exhaustion (green)
case 38639: // Nether Exhaustion (blue)
case 11196: // Recently Bandaged
case 44689: // Relay Race Accept Hidden Debuff - DND
return false;
// some spells have unclear target modes for selection, so just make effect positive
case 27184:

View file

@ -203,8 +203,7 @@ inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
inline bool IsDeathOnlySpell(SpellEntry const *spellInfo)
{
return spellInfo->AttributesEx3 & SPELL_ATTR_EX3_CAST_ON_DEAD
|| spellInfo->Id == 2584
|| spellInfo->Id == 22011;
|| spellInfo->Id == 2584;
}
inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo)

View file

@ -840,8 +840,8 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE);
float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE);
float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct * dmg_multiplier;
float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct * dmg_multiplier;
float mindamage = ((base_value + weapon_mindamage) * dmg_multiplier * base_pct + total_value) * total_pct;
float maxdamage = ((base_value + weapon_maxdamage) * dmg_multiplier * base_pct + total_value) * total_pct;
SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage);
SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage);

View file

@ -30,12 +30,21 @@
//==============================================================
// The pHatingUnit is not used yet
float ThreatCalcHelper::calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float pThreat, SpellSchoolMask schoolMask, SpellEntry const *pThreatSpell)
float ThreatCalcHelper::calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float pThreat, bool crit, SpellSchoolMask schoolMask, SpellEntry const *pThreatSpell)
{
// all flat mods applied early
if(!pThreat)
return 0.0f;
if (pThreatSpell)
{
if (Player* modOwner = pHatedUnit->GetSpellModOwner())
modOwner->ApplySpellMod(pThreatSpell->Id, SPELLMOD_THREAT, pThreat);
if(crit)
pThreat *= pHatedUnit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRITICAL_THREAT,schoolMask);
}
float threat = pHatedUnit->ApplyTotalThreatModifier(pThreat, schoolMask);
return threat;
}
@ -357,7 +366,7 @@ void ThreatManager::clearReferences()
//============================================================
void ThreatManager::addThreat(Unit* pVictim, float pThreat, SpellSchoolMask schoolMask, SpellEntry const *pThreatSpell)
void ThreatManager::addThreat(Unit* pVictim, float pThreat, bool crit, SpellSchoolMask schoolMask, SpellEntry const *pThreatSpell)
{
//function deals with adding threat and adding players and pets into ThreatList
//mobs, NPCs, guards have ThreatList and HateOfflineList
@ -378,7 +387,7 @@ void ThreatManager::addThreat(Unit* pVictim, float pThreat, SpellSchoolMask scho
assert(getOwner()->GetTypeId()== TYPEID_UNIT);
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, schoolMask, pThreatSpell);
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, crit, schoolMask, pThreatSpell);
HostileReference* ref = iThreatContainer.addThreat(pVictim, threat);
// Ref is not in the online refs, search the offline refs next

View file

@ -39,7 +39,7 @@ struct SpellEntry;
class ThreatCalcHelper
{
public:
static float calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL);
static float calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float threat, bool crit, SpellSchoolMask schoolMask, SpellEntry const *threatSpell);
};
//==============================================================
@ -176,7 +176,8 @@ class MANGOS_DLL_SPEC ThreatManager
void clearReferences();
void addThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL);
void addThreat(Unit* pVictim, float threat, bool crit, SpellSchoolMask schoolMask, SpellEntry const *threatSpell);
void addThreat(Unit* pVictim, float threat) { addThreat(pVictim,threat,false,SPELL_SCHOOL_MASK_NONE,NULL); }
void modifyThreatPercent(Unit *pVictim, int32 pPercent);
float getThreat(Unit *pVictim, bool pAlsoSearchOfflineList = false);

View file

@ -761,9 +761,9 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if (pVictim->GetTypeId() != TYPEID_PLAYER)
{
if(spellProto && IsDamageToThreatSpell(spellProto))
pVictim->AddThreat(this, damage*2, damageSchoolMask, spellProto);
pVictim->AddThreat(this, damage*2, (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto);
else
pVictim->AddThreat(this, damage, damageSchoolMask, spellProto);
pVictim->AddThreat(this, damage, (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto);
}
else // victim is a player
{
@ -1060,7 +1060,10 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S
damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim);
// Resilience - reduce crit damage
if (pVictim->GetTypeId()==TYPEID_PLAYER)
damage -= ((Player*)pVictim)->GetMeleeCritDamageReduction(damage);
{
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask);
damage -= ((Player*)pVictim)->GetMeleeCritDamageReduction(redunction_affected_damage);
}
}
}
break;
@ -1077,21 +1080,30 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S
damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim);
// Resilience - reduce crit damage
if (pVictim->GetTypeId()==TYPEID_PLAYER)
damage -= ((Player*)pVictim)->GetSpellCritDamageReduction(damage);
{
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask);
damage -= ((Player*)pVictim)->GetSpellCritDamageReduction(redunction_affected_damage);
}
}
}
break;
}
if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
damage -= ((Player*)pVictim)->GetSpellDamageReduction(damage);
{
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask);
damage -= ((Player*)pVictim)->GetSpellDamageReduction(redunction_affected_damage);
}
// damage mitigation
if(damage > 0)
if (damage > 0)
{
// physical damage => armor
if ( damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL )
damage = CalcArmorReducedDamage(pVictim, damage);
if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL)
{
uint32 armor_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask);
damage = damage - armor_affected_damage + CalcArmorReducedDamage(pVictim, armor_affected_damage);
}
// block (only for damage class ranged and -melee, also non-physical damage possible)
if (blocked)
@ -1102,21 +1114,9 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S
damage-=damageInfo->blocked;
}
// absorb/resist: lookup ignore auras on caster for spell
bool ignore = false;
Unit::AuraList const& ignoreAbsorb = GetAurasByType(SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL);
for(Unit::AuraList::const_iterator i = ignoreAbsorb.begin(); i != ignoreAbsorb.end(); ++i)
if ((*i)->isAffectedOnSpell(spellInfo))
{
ignore = true;
break;
}
if (!ignore)
{
CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist);
damage-= damageInfo->absorb + damageInfo->resist;
}
uint32 absorb_affected_damage = CalcNotIgnoreAbsorbDamage(damage,damageSchoolMask,spellInfo);
CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, absorb_affected_damage, &damageInfo->absorb, &damageInfo->resist);
damage-= damageInfo->absorb + damageInfo->resist;
}
else
damage = 0;
@ -1125,7 +1125,7 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S
void Unit::DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss)
{
if (damageInfo==0)
if (!damageInfo)
return;
Unit *pVictim = damageInfo->target;
@ -1152,8 +1152,8 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss)
return;
}
// Call default DealDamage
CleanDamage cleanDamage(damageInfo->cleanDamage, BASE_ATTACK, MELEE_HIT_NORMAL);
// Call default DealDamage (send critical in hit info for threat calculation)
CleanDamage cleanDamage(damageInfo->cleanDamage, BASE_ATTACK, damageInfo->HitInfo & SPELL_HIT_TYPE_CRIT ? MELEE_HIT_CRIT : MELEE_HIT_NORMAL);
DealDamage(pVictim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), spellProto, durabilityLoss);
}
@ -1205,7 +1205,7 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
}
// Physical Immune check
if(damageInfo->target->IsImmunedToDamage(SpellSchoolMask(damageInfo->damageSchoolMask)))
if (damageInfo->target->IsImmunedToDamage(damageInfo->damageSchoolMask))
{
damageInfo->HitInfo |= HITINFO_NORMALSWING;
damageInfo->TargetState = VICTIMSTATE_IS_IMMUNE;
@ -1219,13 +1219,15 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
// Add melee damage bonus
damage = MeleeDamageBonus(damageInfo->target, damage, damageInfo->attackType);
// Calculate armor reduction
damageInfo->damage = CalcArmorReducedDamage(damageInfo->target, damage);
uint32 armor_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageInfo->damageSchoolMask);
damageInfo->damage = damage - armor_affected_damage + CalcArmorReducedDamage(damageInfo->target, armor_affected_damage);
damageInfo->cleanDamage += damage - damageInfo->damage;
damageInfo->hitOutCome = RollMeleeOutcomeAgainst(damageInfo->target, damageInfo->attackType);
// Disable parry or dodge for ranged attack
if(damageInfo->attackType == RANGED_ATTACK)
if (damageInfo->attackType == RANGED_ATTACK)
{
if (damageInfo->hitOutCome == MELEE_HIT_PARRY) damageInfo->hitOutCome = MELEE_HIT_NORMAL;
if (damageInfo->hitOutCome == MELEE_HIT_DODGE) damageInfo->hitOutCome = MELEE_HIT_MISS;
@ -1285,7 +1287,8 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
// Resilience - reduce crit damage
if (pVictim->GetTypeId()==TYPEID_PLAYER)
{
uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(damageInfo->damage);
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damageInfo->damage,damageInfo->damageSchoolMask);
uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(redunction_affected_damage);
damageInfo->damage -= resilienceReduction;
damageInfo->cleanDamage += resilienceReduction;
}
@ -1389,18 +1392,21 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
{
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageInfo->damageSchoolMask);
if (attackType != RANGED_ATTACK)
damage-=((Player*)pVictim)->GetMeleeDamageReduction(damage);
damage-=((Player*)pVictim)->GetMeleeDamageReduction(redunction_affected_damage);
else
damage-=((Player*)pVictim)->GetRangedDamageReduction(damage);
damage-=((Player*)pVictim)->GetRangedDamageReduction(redunction_affected_damage);
}
// Calculate absorb resist
if(int32(damageInfo->damage) > 0)
{
damageInfo->procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE;
// Calculate absorb & resists
CalcAbsorbResist(damageInfo->target, SpellSchoolMask(damageInfo->damageSchoolMask), DIRECT_DAMAGE, damageInfo->damage, &damageInfo->absorb, &damageInfo->resist);
uint32 absorb_affected_damage = CalcNotIgnoreAbsorbDamage(damageInfo->damage,damageInfo->damageSchoolMask);
CalcAbsorbResist(damageInfo->target, damageInfo->damageSchoolMask, DIRECT_DAMAGE, absorb_affected_damage, &damageInfo->absorb, &damageInfo->resist);
damageInfo->damage-=damageInfo->absorb + damageInfo->resist;
if (damageInfo->absorb)
{
@ -1479,7 +1485,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
// Call default DealDamage
CleanDamage cleanDamage(damageInfo->cleanDamage,damageInfo->attackType,damageInfo->hitOutCome);
DealDamage(pVictim, damageInfo->damage, &cleanDamage, DIRECT_DAMAGE, SpellSchoolMask(damageInfo->damageSchoolMask), NULL, durabilityLoss);
DealDamage(pVictim, damageInfo->damage, &cleanDamage, DIRECT_DAMAGE, damageInfo->damageSchoolMask, NULL, durabilityLoss);
// If this is a creature and it attacks from behind it has a probability to daze it's victim
if( (damageInfo->hitOutCome==MELEE_HIT_CRIT || damageInfo->hitOutCome==MELEE_HIT_CRUSHING || damageInfo->hitOutCome==MELEE_HIT_NORMAL || damageInfo->hitOutCome==MELEE_HIT_GLANCING) &&
@ -1558,6 +1564,36 @@ void Unit::HandleEmoteCommand(uint32 anim_id)
SendMessageToSet(&data, true);
}
uint32 Unit::CalcNotIgnoreAbsorbDamage( uint32 damage, SpellSchoolMask damageSchoolMask, SpellEntry const* spellInfo /*= NULL*/)
{
float absorb_affected_rate = 1.0f;
Unit::AuraList const& ignoreAbsorb = GetAurasByType(SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL);
for(Unit::AuraList::const_iterator i = ignoreAbsorb.begin(); i != ignoreAbsorb.end(); ++i)
if ((*i)->GetMiscValue() & damageSchoolMask)
absorb_affected_rate *= (100.0f - (*i)->GetModifier()->m_amount)/100.0f;
if(spellInfo)
{
Unit::AuraList const& ignoreAbsorb = GetAurasByType(SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL);
for(Unit::AuraList::const_iterator i = ignoreAbsorb.begin(); i != ignoreAbsorb.end(); ++i)
if ((*i)->isAffectedOnSpell(spellInfo))
absorb_affected_rate *= (100.0f - (*i)->GetModifier()->m_amount)/100.0f;
}
return absorb_affected_rate <= 0.0f ? 0 : (absorb_affected_rate < 1.0f ? uint32(damage * absorb_affected_rate) : damage);
}
uint32 Unit::CalcNotIgnoreDamageRedunction( uint32 damage, SpellSchoolMask damageSchoolMask)
{
float absorb_affected_rate = 1.0f;
Unit::AuraList const& ignoreAbsorb = GetAurasByType(SPELL_AURA_MOD_IGNORE_DAMAGE_REDUCTION_SCHOOL);
for(Unit::AuraList::const_iterator i = ignoreAbsorb.begin(); i != ignoreAbsorb.end(); ++i)
if ((*i)->GetMiscValue() & damageSchoolMask)
absorb_affected_rate *= (100.0f - (*i)->GetModifier()->m_amount)/100.0f;
return absorb_affected_rate <= 0.0f ? 0 : (absorb_affected_rate < 1.0f ? uint32(damage * absorb_affected_rate) : damage);
}
uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage)
{
uint32 newdamage = 0;
@ -2157,6 +2193,8 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
// Reduce dodge chance by attacker expertise rating
if (GetTypeId() == TYPEID_PLAYER)
dodge_chance -= int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType)*100);
else
dodge_chance -= GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE)*25;
// Modify dodge chance by attacker SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
dodge_chance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE);
@ -2183,6 +2221,8 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
// Reduce parry chance by attacker expertise rating
if (GetTypeId() == TYPEID_PLAYER)
parry_chance-= int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType)*100);
else
parry_chance -= GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE)*25;
if(pVictim->GetTypeId()==TYPEID_PLAYER || !(((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_PARRY) )
{
@ -2527,6 +2567,8 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell)
// Reduce dodge chance by attacker expertise rating
if (GetTypeId() == TYPEID_PLAYER)
dodgeChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
else
dodgeChance -= GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE)*25;
if (dodgeChance < 0)
dodgeChance = 0;
@ -2542,6 +2584,8 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell)
// Reduce parry chance by attacker expertise rating
if (GetTypeId() == TYPEID_PLAYER)
parryChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
else
parryChance -= GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE)*25;
if (parryChance < 0)
parryChance = 0;
@ -8707,6 +8751,9 @@ uint32 Unit::SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damag
critPctDamageMod += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE);
}
}
else
critPctDamageMod += pVictim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_DAMAGE,GetSpellSchoolMask(spellProto));
uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
critPctDamageMod += GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, creatureTypeMask);
@ -9556,7 +9603,8 @@ bool Unit::isTargetableForAttack(bool inverseAlive /*=false*/) const
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
return false;
if (!(isAlive() != inverseAlive))
// target is dead or has ghost-flag
if ((!isAlive() || (GetTypeId() == TYPEID_UNIT && ((Creature *)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GHOST)) != inverseAlive)
return false;
return IsInWorld() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/;
@ -9845,7 +9893,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo
//-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia)
//based on wowwiki every 5 mod we have 1 more level diff in calculation
visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_DETECT)) - stealthMod)/5.0f;
visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_DETECT)) - stealthMod)/5.0f;
visibleDistance = visibleDistance > MAX_PLAYER_STEALTH_DETECT_RANGE ? MAX_PLAYER_STEALTH_DETECT_RANGE : visibleDistance;
// recheck new distance
@ -10196,7 +10244,10 @@ bool Unit::CanHaveThreatList() const
float Unit::ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask)
{
if(!HasAuraType(SPELL_AURA_MOD_THREAT))
if (!HasAuraType(SPELL_AURA_MOD_THREAT))
return threat;
if (schoolMask == SPELL_SCHOOL_MASK_NONE)
return threat;
SpellSchools school = GetFirstSchoolInMask(schoolMask);
@ -10206,11 +10257,11 @@ float Unit::ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask)
//======================================================================
void Unit::AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask, SpellEntry const *threatSpell)
void Unit::AddThreat(Unit* pVictim, float threat /*= 0.0f*/, bool crit /*= false*/, SpellSchoolMask schoolMask /*= SPELL_SCHOOL_MASK_NONE*/, SpellEntry const *threatSpell /*= NULL*/)
{
// Only mobs can manage threat lists
if(CanHaveThreatList())
m_ThreatManager.addThreat(pVictim, threat, schoolMask, threatSpell);
m_ThreatManager.addThreat(pVictim, threat, crit, schoolMask, threatSpell);
}
//======================================================================

View file

@ -637,7 +637,7 @@ struct CalcDamageInfo
{
Unit *attacker; // Attacker
Unit *target; // Target for damage
uint32 damageSchoolMask;
SpellSchoolMask damageSchoolMask;
uint32 damage;
uint32 absorb;
uint32 resist;
@ -1336,7 +1336,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
// Threat related methods
bool CanHaveThreatList() const;
void AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL);
void AddThreat(Unit* pVictim, float threat = 0.0f, bool crit = false, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NONE, SpellEntry const *threatSpell = NULL);
float ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL);
void DeleteThreatList();
bool SelectHostileTarget();
@ -1468,6 +1468,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void _ApplyAllAuraMods();
int32 CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_index, int32 basePoints, Unit const* target);
uint32 CalcNotIgnoreAbsorbDamage( uint32 damage, SpellSchoolMask damageSchoolMask, SpellEntry const* spellInfo = NULL);
uint32 CalcNotIgnoreDamageRedunction( uint32 damage, SpellSchoolMask damageSchoolMask);
int32 CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_index, Unit const* target);
float CalculateLevelPenalty(SpellEntry const* spellProto) const;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8656"
#define REVISION_NR "8677"
#endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_8596_01_characters_bugreport"
#define REVISION_DB_MANGOS "required_8618_01_mangos_spell_proc_event"
#define REVISION_DB_MANGOS "required_8676_01_mangos_creature_template"
#define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters"
#endif // __REVISION_SQL_H__