diff options
-rw-r--r-- | src/game/AchievementMgr.cpp | 63 | ||||
-rw-r--r-- | src/game/ChatHandler.cpp | 78 | ||||
-rw-r--r-- | src/game/Player.cpp | 16 | ||||
-rw-r--r-- | src/game/Spell.cpp | 94 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 56 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 6 | ||||
-rw-r--r-- | src/game/TargetedMovementGenerator.cpp | 2 | ||||
-rw-r--r-- | src/game/Unit.cpp | 30 | ||||
-rw-r--r-- | src/game/Unit.h | 2 | ||||
-rw-r--r-- | src/game/WaypointMovementGenerator.cpp | 4 | ||||
-rw-r--r-- | src/shared/Database/DBCStructure.h | 1 |
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 |