aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/AchievementMgr.cpp63
-rw-r--r--src/game/ChatHandler.cpp78
-rw-r--r--src/game/Player.cpp16
-rw-r--r--src/game/Spell.cpp94
-rw-r--r--src/game/SpellAuras.cpp56
-rw-r--r--src/game/SpellEffects.cpp6
-rw-r--r--src/game/TargetedMovementGenerator.cpp2
-rw-r--r--src/game/Unit.cpp30
-rw-r--r--src/game/Unit.h2
-rw-r--r--src/game/WaypointMovementGenerator.cpp4
-rw-r--r--src/shared/Database/DBCStructure.h1
11 files changed, 225 insertions, 127 deletions
diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp
index 3acf2caa5a5..59e2c533462 100644
--- a/src/game/AchievementMgr.cpp
+++ b/src/game/AchievementMgr.cpp
@@ -689,12 +689,15 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
- if(GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID))
+ // spell always provide and at login spell learning.
+ if(miscvalue1 && miscvalue1!=achievementCriteria->learn_spell.spellID)
+ continue;
+ if(GetPlayer()->HasSpell(miscvalue1))
SetCriteriaProgress(achievementCriteria, 1);
break;
case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
// speedup for non-login case
- if(miscvalue1 && achievementCriteria->own_item.itemID!=miscvalue1)
+ if(miscvalue1 && achievementCriteria->own_item.itemID != miscvalue1)
continue;
SetCriteriaProgress(achievementCriteria, GetPlayer()->GetItemCount(achievementCriteria->own_item.itemID, true));
break;
@@ -736,6 +739,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
{
+ // skip faction check only at loading
+ if (miscvalue1 && miscvalue1 != achievementCriteria->gain_reputation.factionID)
+ continue;
+
int32 reputation = GetPlayer()->GetReputation(achievementCriteria->gain_reputation.factionID);
if (reputation > 0)
SetCriteriaProgress(achievementCriteria, reputation);
@@ -743,6 +750,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
}
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
{
+ // skip faction check only at loading
+ if (miscvalue1 && GetPlayer()->GetReputationRank(miscvalue1) < REP_EXALTED)
+ continue;
+
uint32 counter = 0;
const FactionStateList factionStateList = GetPlayer()->GetFactionStateList();
for (FactionStateList::const_iterator iter = factionStateList.begin(); iter!= factionStateList.end(); ++iter)
@@ -806,24 +817,43 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
break;
}
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
+ // miscvalue1 = item_id
+ if(!miscvalue1)
+ continue;
+ if(miscvalue1 != achievementCriteria->equip_item.itemID)
+ continue;
+
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
+ {
+ // spell always provide and at login spell learning.
+ if(!miscvalue1)
+ continue;
+ // rescan only when change possible
+ SkillLineAbilityMap::const_iterator skillIter0 = spellmgr.GetBeginSkillLineAbilityMap(miscvalue1);
+ if(skillIter0 == spellmgr.GetEndSkillLineAbilityMap(miscvalue1))
+ continue;
+ if(skillIter0->second->skillId != achievementCriteria->learn_skilline_spell.skillLine)
+ continue;
+
+ uint32 spellCount = 0;
+ for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin();
+ spellIter != GetPlayer()->GetSpellMap().end();
+ ++spellIter)
{
- uint32 spellCount = 0;
- for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin();
- spellIter != GetPlayer()->GetSpellMap().end();
- ++spellIter)
+ for(SkillLineAbilityMap::const_iterator skillIter = spellmgr.GetBeginSkillLineAbilityMap(spellIter->first);
+ skillIter != spellmgr.GetEndSkillLineAbilityMap(spellIter->first);
+ ++skillIter)
{
- for(SkillLineAbilityMap::const_iterator skillIter = spellmgr.GetBeginSkillLineAbilityMap(spellIter->first);
- skillIter != spellmgr.GetEndSkillLineAbilityMap(spellIter->first);
- ++skillIter)
- {
- if(skillIter->second->skillId == achievementCriteria->learn_skilline_spell.skillLine)
- spellCount++;
- }
+ if(skillIter->second->skillId == achievementCriteria->learn_skilline_spell.skillLine)
+ spellCount++;
}
- SetCriteriaProgress(achievementCriteria, spellCount);
- break;
}
+ SetCriteriaProgress(achievementCriteria, spellCount);
+ break;
+ }
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
{
if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID)
@@ -876,7 +906,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
- case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS:
case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS:
case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
@@ -1004,6 +1033,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
return progress->counter >= achievementCriteria->roll_greed_on_loot.count;
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
return progress->counter >= achievementCriteria->do_emote.count;
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
+ return progress->counter >= achievementCriteria->equip_item.count;
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD:
return progress->counter >= achievementCriteria->quest_reward_money.goldInCopper;
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp
index ba4be69e1b0..bf1c1add8a6 100644
--- a/src/game/ChatHandler.cpp
+++ b/src/game/ChatHandler.cpp
@@ -36,6 +36,8 @@
#include "SpellAuras.h"
#include "Language.h"
#include "Util.h"
+#include "GridNotifiersImpl.h"
+#include "CellImpl.h"
void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
{
@@ -498,6 +500,38 @@ void WorldSession::HandleEmoteOpcode( WorldPacket & recv_data )
GetPlayer()->HandleEmoteCommand(emote);
}
+namespace MaNGOS
+{
+ class EmoteChatBuilder
+ {
+ public:
+ EmoteChatBuilder(Player const& pl, uint32 text_emote, uint32 emote_num, Unit const* target)
+ : i_player(pl), i_text_emote(text_emote), i_emote_num(emote_num), i_target(target) {}
+
+ void operator()(WorldPacket& data, int32 loc_idx)
+ {
+ char const* nam = i_target ? i_target->GetNameForLocaleIdx(loc_idx) : NULL;
+ uint32 namlen = (nam ? strlen(nam) : 0) + 1;
+
+ data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
+ data << i_player.GetGUID();
+ data << (uint32)i_text_emote;
+ data << i_emote_num;
+ data << (uint32)namlen;
+ if( namlen > 1 )
+ data.append(nam, namlen);
+ else
+ data << (uint8)0x00;
+ }
+
+ private:
+ Player const& i_player;
+ uint32 i_text_emote;
+ uint32 i_emote_num;
+ Unit const* i_target;
+ };
+} // namespace MaNGOS
+
void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
{
if(!GetPlayer()->isAlive())
@@ -519,27 +553,12 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
recv_data >> emoteNum;
recv_data >> guid;
- const char *nam = 0;
- uint32 namlen = 1;
-
- Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
- Creature *pCreature = dynamic_cast<Creature *>(unit);
- if(unit)
- {
- nam = unit->GetName();
- namlen = (nam ? strlen(nam) : 0) + 1;
- }
-
EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote);
if (!em)
return;
- GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
-
uint32 emote_anim = em->textid;
- WorldPacket data;
-
switch(emote_anim)
{
case EMOTE_STATE_SLEEP:
@@ -552,21 +571,26 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
break;
}
- data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
- data << GetPlayer()->GetGUID();
- data << (uint32)text_emote;
- data << emoteNum;
- data << (uint32)namlen;
- if( namlen > 1 )
- data.append(nam, namlen);
- else
- data << (uint8)0x00;
+ Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
+
+ CellPair p = MaNGOS::ComputeCellPair(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
+
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
- GetPlayer()->SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true);
+ MaNGOS::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
+ MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > emote_do(emote_builder);
+ MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > > emote_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),emote_do);
+ TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > >, WorldTypeMapContainer > message(emote_worker);
+ CellLock<GridReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap());
+
+ GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
//Send scripted event call
- if (pCreature && Script)
- Script->ReceiveEmote(GetPlayer(),pCreature,text_emote);
+ if (unit && unit->GetTypeId()==TYPEID_UNIT && Script)
+ Script->ReceiveEmote(GetPlayer(),(Creature*)unit,text_emote);
}
void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data )
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 84aedc4c8e6..934c9920da5 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -3013,8 +3013,8 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
if(IsInWorld())
{
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL,spell_id);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS,spell_id);
}
// return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell
@@ -6042,8 +6042,8 @@ bool Player::ModifyOneFactionReputation(FactionEntry const* factionEntry, int32
}
}
}
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION,factionEntry->ID);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION,factionEntry->ID);
SendFactionState(&(itr->second));
return true;
@@ -6109,8 +6109,8 @@ bool Player::SetOneFactionReputation(FactionEntry const* factionEntry, int32 sta
SetFactionAtWar(&itr->second,true);
SendFactionState(&(itr->second));
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION);
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION,factionEntry->ID);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION,factionEntry->ID);
return true;
}
return false;
@@ -6576,7 +6576,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
pvpInfo.endTimer = time(0); // start toggle-off
}
- if(zone->flags & AREA_FLAG_SANCTUARY) // in sanctuary
+ if(zone->flags & (AREA_FLAG_SANCTUARY | AREA_FLAG_UNK7 & AREA_FLAG_UNK7)) // in sanctuary
{
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
if(sWorld.IsFFAPvPRealm())
@@ -10992,6 +10992,8 @@ Item* Player::EquipItem( uint16 pos, Item *pItem, bool update )
}
}
+ // only for full equip instead adding to stack
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry());
return pItem;
}
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 57bcebcef62..a44086b9407 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -3534,34 +3534,33 @@ SpellCastResult Spell::CheckCast(bool strict)
}
}
- bool reqAuraState=true;
+ bool reqCombat=true;
Unit::AuraList const& stateAuras = m_caster->GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
for(Unit::AuraList::const_iterator j = stateAuras.begin();j != stateAuras.end(); ++j)
{
if((*j)->isAffectedOnSpell(m_spellInfo))
{
- reqAuraState=false;
- break;
+ if ((*j)->GetModifier()->m_miscvalue==1)
+ {
+ reqCombat=false;
+ break;
+ }
}
}
- if (reqAuraState)
- {
- // caster state requirements
- if(m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState)))
- return SPELL_FAILED_CASTER_AURASTATE;
- if(m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot)))
- return SPELL_FAILED_CASTER_AURASTATE;
-
- if(m_spellInfo->casterAuraSpell && !m_caster->HasAura(m_spellInfo->casterAuraSpell))
- return SPELL_FAILED_CASTER_AURASTATE;
- if(m_spellInfo->excludeCasterAuraSpell && m_caster->HasAura(m_spellInfo->excludeCasterAuraSpell))
- return SPELL_FAILED_CASTER_AURASTATE;
+ // caster state requirements
+ if(m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState), m_spellInfo, m_caster))
+ return SPELL_FAILED_CASTER_AURASTATE;
+ if(m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot), m_spellInfo, m_caster))
+ return SPELL_FAILED_CASTER_AURASTATE;
- if(m_caster->isInCombat() && IsNonCombatSpell(m_spellInfo))
- return SPELL_FAILED_AFFECTING_COMBAT;
- }
+ if(m_spellInfo->casterAuraSpell && !m_caster->HasAura(m_spellInfo->casterAuraSpell))
+ return SPELL_FAILED_CASTER_AURASTATE;
+ if(m_spellInfo->excludeCasterAuraSpell && m_caster->HasAura(m_spellInfo->excludeCasterAuraSpell))
+ return SPELL_FAILED_CASTER_AURASTATE;
+ if(reqCombat && m_caster->isInCombat() && IsNonCombatSpell(m_spellInfo))
+ return SPELL_FAILED_AFFECTING_COMBAT;
// cancel autorepeat spells if cast start when moving
// (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
@@ -3575,23 +3574,21 @@ SpellCastResult Spell::CheckCast(bool strict)
if(Unit *target = m_targets.getUnitTarget())
{
- if (reqAuraState)
- {
- // target state requirements (not allowed state), apply to self also
- if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot)))
- return SPELL_FAILED_TARGET_AURASTATE;
- if(m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell))
- return SPELL_FAILED_TARGET_AURASTATE;
+ // target state requirements (not allowed state), apply to self also
+ if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot), m_spellInfo, m_caster))
+ return SPELL_FAILED_TARGET_AURASTATE;
- if(m_spellInfo->excludeTargetAuraSpell && target->HasAura(m_spellInfo->excludeTargetAuraSpell))
- return SPELL_FAILED_TARGET_AURASTATE;
- }
+ if(m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell))
+ return SPELL_FAILED_TARGET_AURASTATE;
+
+ if(m_spellInfo->excludeTargetAuraSpell && target->HasAura(m_spellInfo->excludeTargetAuraSpell))
+ return SPELL_FAILED_TARGET_AURASTATE;
if(target != m_caster)
{
// target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds
- if(reqAuraState && m_spellInfo->TargetAuraState && !target->HasAuraState(AuraState(m_spellInfo->TargetAuraState)))
+ if(m_spellInfo->TargetAuraState && !target->HasAuraState(AuraState(m_spellInfo->TargetAuraState), m_spellInfo, m_caster))
return SPELL_FAILED_TARGET_AURASTATE;
// Not allow casting on flying player
@@ -4217,25 +4214,38 @@ SpellCastResult Spell::CheckCast(bool strict)
{
case SPELL_AURA_DUMMY:
{
- if(m_spellInfo->Id == 1515)
+ //custom check
+ switch(m_spellInfo->Id)
{
- if (!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER)
- return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
+ case 61336:
+ if(m_caster->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_caster)->IsInFeralForm())
+ return SPELL_FAILED_ONLY_SHAPESHIFT;
+ break;
+ case 1515:
+ {
+ if (!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER)
+ return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
- if (m_targets.getUnitTarget()->getLevel() > m_caster->getLevel())
- return SPELL_FAILED_HIGHLEVEL;
+ if (m_targets.getUnitTarget()->getLevel() > m_caster->getLevel())
+ return SPELL_FAILED_HIGHLEVEL;
- // use SMSG_PET_TAME_FAILURE?
- if (!((Creature*)m_targets.getUnitTarget())->GetCreatureInfo()->isTameable ())
- return SPELL_FAILED_BAD_TARGETS;
+ // use SMSG_PET_TAME_FAILURE?
+ if (!((Creature*)m_targets.getUnitTarget())->GetCreatureInfo()->isTameable ())
+ return SPELL_FAILED_BAD_TARGETS;
- if(m_caster->GetPetGUID())
- return SPELL_FAILED_ALREADY_HAVE_SUMMON;
+ if(m_caster->GetPetGUID())
+ return SPELL_FAILED_ALREADY_HAVE_SUMMON;
- if(m_caster->GetCharmGUID())
- return SPELL_FAILED_ALREADY_HAVE_CHARM;
+ if(m_caster->GetCharmGUID())
+ return SPELL_FAILED_ALREADY_HAVE_CHARM;
+
+ break;
+ }
+ default:
+ break;
}
- }break;
+ break;
+ }
case SPELL_AURA_MOD_POSSESS:
case SPELL_AURA_MOD_CHARM:
{
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index ef31316b0ac..93d81d41aa5 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -2172,6 +2172,44 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
}
case SPELLFAMILY_DRUID:
{
+ switch(GetId())
+ {
+ case 34246: // Idol of the Emerald Queen
+ {
+ if (m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if(apply)
+ {
+ SpellModifier *mod = new SpellModifier;
+ mod->op = SPELLMOD_DOT;
+ mod->value = m_modifier.m_amount/7;
+ mod->type = SPELLMOD_FLAT;
+ mod->spellId = GetId();
+ mod->mask[1] = 0x0010;
+
+ m_spellmod = mod;
+ }
+
+ ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
+ return;
+ }
+ case 61336: // Survival Instincts
+ {
+ if(apply)
+ {
+ if (!m_target->IsInFeralForm())
+ return;
+
+ int32 bp0 = int32(m_target->GetMaxHealth() * m_modifier.m_amount / 100);
+ m_target->CastCustomSpell(m_target, 50322, &bp0, NULL, NULL, true);
+ }
+ else
+ m_target-> RemoveAurasDueToSpell(50322);
+ return;
+ }
+ }
+
// Lifebloom
if ( GetSpellProto()->SpellFamilyFlags[1] & 0x10 )
{
@@ -2215,24 +2253,6 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
((Player*)m_target)->UpdateAttackPowerAndDamage();
return;
}
- // Idol of the Emerald Queen
- if ( GetId() == 34246 && m_target->GetTypeId()==TYPEID_PLAYER )
- {
- if(apply)
- {
- SpellModifier *mod = new SpellModifier;
- mod->op = SPELLMOD_DOT;
- mod->value = m_modifier.m_amount/7;
- mod->type = SPELLMOD_FLAT;
- mod->spellId = GetId();
- mod->mask[1] = 0x0010;
-
- m_spellmod = mod;
- }
-
- ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
- return;
- }
break;
}
case SPELLFAMILY_HUNTER:
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 309cf6e5816..30861c2f451 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -437,7 +437,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
if((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID==2128)
{
// Incinerate does more dmg (dmg*0.25) if the target is Immolated.
- if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE))
+ if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE, m_spellInfo, m_caster))
damage += int32(damage*0.25f);
}
// Haunt
@@ -2606,7 +2606,7 @@ void Spell::SpellDamageHeal(uint32 /*i*/)
addhealth += damageAmount;
}
// Swiftmend - consumes Regrowth or Rejuvenation
- else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND))
+ else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND, m_spellInfo, m_caster))
{
Unit::AuraList const& RejorRegr = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
// find most short by duration
@@ -4411,7 +4411,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
{
bool found = false;
// fast check
- if(unitTarget->HasAuraState(AURA_STATE_DEADLY_POISON))
+ if(unitTarget->HasAuraState(AURA_STATE_DEADLY_POISON, m_spellInfo, m_caster))
found = true;
// full aura scan
else
diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp
index 31b4dcab101..6aa4be19765 100644
--- a/src/game/TargetedMovementGenerator.cpp
+++ b/src/game/TargetedMovementGenerator.cpp
@@ -94,8 +94,6 @@ template<class T>
void
TargetedMovementGenerator<T>::Initialize(T &owner)
{
- if(!&owner)
- return;
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index e8e8435ac1a..25370e0f02f 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -8145,6 +8145,18 @@ void Unit::ModifyAuraState(AuraState flag, bool apply)
ApplyModFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1), apply);
}
+bool Unit::HasAuraState(AuraState flag, SpellEntry const *spellProto, Unit * Caster) const
+{
+ if (Caster && spellProto)
+ {
+ AuraList const& stateAuras = Caster->GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
+ for(AuraList::const_iterator j = stateAuras.begin();j != stateAuras.end(); ++j)
+ if((*j)->isAffectedOnSpell(spellProto))
+ return true;
+ }
+ return HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1));
+}
+
Unit *Unit::GetOwner() const
{
uint64 ownerid = GetOwnerGUID();
@@ -8399,7 +8411,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
case 6926:
case 6928:
{
- if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
+ if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
DoneTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f;
break;
}
@@ -8432,7 +8444,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
case 6916: // Death's Embrace
case 6925:
case 6927:
- if (HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT))
+ if (HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, spellProto, this))
DoneTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f;
break;
case 5481: // Starfire Bonus
@@ -8459,7 +8471,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
// Merciless Combat
if ((*i)->GetSpellProto()->SpellIconID == 2656)
{
- if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
+ if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
DoneTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f;
}
else // Tundra Stalker
@@ -8694,7 +8706,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
// Ice Lance
if (spellProto->SpellFamilyName == SPELLFAMILY_MAGE && spellProto->SpellIconID == 186)
{
- if (pVictim->isFrozen())
+ if (pVictim->HasAuraState(AURA_STATE_FROZEN, spellProto, this))
DoneTotalMod *= 3.0f;
}
@@ -8954,11 +8966,11 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
continue;
switch((*i)->GetModifier()->m_miscvalue)
{
- case 849: if (pVictim->isFrozen()) crit_chance+= 17.0f; break; //Shatter Rank 1
- case 910: if (pVictim->isFrozen()) crit_chance+= 34.0f; break; //Shatter Rank 2
- case 911: if (pVictim->isFrozen()) crit_chance+= 50.0f; break; //Shatter Rank 3
+ case 849: if (pVictim->HasAuraState(AURA_STATE_FROZEN, spellProto, this)) crit_chance+= 17.0f; break; //Shatter Rank 1
+ case 910: if (pVictim->HasAuraState(AURA_STATE_FROZEN, spellProto, this)) crit_chance+= 34.0f; break; //Shatter Rank 2
+ case 911: if (pVictim->HasAuraState(AURA_STATE_FROZEN, spellProto, this)) crit_chance+= 50.0f; break; //Shatter Rank 3
case 7917: // Glyph of Shadowburn
- if (pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
+ if (pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
crit_chance+=(*i)->GetModifier()->m_amount;
break;
case 7997: // Renewed Hope
@@ -9666,7 +9678,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
switch((*i)->GetMiscValue())
{
case 6427: case 6428: // Dirty Deeds
- if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
+ if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
{
Aura* eff0 = GetAura((*i)->GetId(),0);
if(!eff0 || (*i)->GetEffIndex()!=1)
diff --git a/src/game/Unit.h b/src/game/Unit.h
index a54945241d6..14741562291 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1443,7 +1443,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
uint32 CalculateDamage(WeaponAttackType attType, bool normalized);
float GetAPMultiplier(WeaponAttackType attType, bool normalized);
void ModifyAuraState(AuraState flag, bool apply);
- bool HasAuraState(AuraState flag) const { return HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1)); }
+ bool HasAuraState(AuraState flag, SpellEntry const *spellProto = NULL, Unit * Caster = NULL) const ;
void UnsummonAllTotems();
int32 SpellBaseDamageBonus(SpellSchoolMask schoolMask);
int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask);
diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp
index 5aa7666db10..266fba73035 100644
--- a/src/game/WaypointMovementGenerator.cpp
+++ b/src/game/WaypointMovementGenerator.cpp
@@ -254,14 +254,14 @@ FlightPathMovementGenerator::Initialize(Player &player)
void FlightPathMovementGenerator::Finalize(Player & player)
{
+ // remove flag to prevent send object build movement packets for flight state and crash (movement generator already not at top of stack)
+ player.clearUnitState(UNIT_FLAG_DISABLE_MOVE | UNIT_STAT_IN_FLIGHT);
float x, y, z;
i_destinationHolder.GetLocationNow(player.GetMapId(), x, y, z);
player.SetPosition(x, y, z, player.GetOrientation());
- player.clearUnitState(UNIT_STAT_IN_FLIGHT);
player.Unmount();
- player.RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
if(player.m_taxi.empty())
{
diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h
index 12fa9f7d323..45718e82e19 100644
--- a/src/shared/Database/DBCStructure.h
+++ b/src/shared/Database/DBCStructure.h
@@ -377,6 +377,7 @@ struct AchievementCriteriaEntry
struct
{
uint32 itemID; // 3
+ uint32 count; // 4
} equip_item;
// ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD= 62