mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-23 02:25:38 +01:00
Core/Quests: Implement new logic for selecting spell casters for accept/reward spells based on quest flags (#21316)
This commit is contained in:
@@ -26,6 +26,8 @@
|
||||
#include "Player.h"
|
||||
#include "QuestDef.h"
|
||||
#include "QuestPackets.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "World.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
@@ -447,8 +449,20 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU
|
||||
packet.QuestFlags[1] = quest->GetFlagsEx();
|
||||
packet.SuggestedPartyMembers = quest->GetSuggestedPlayers();
|
||||
|
||||
if (quest->GetSrcSpell())
|
||||
packet.LearnSpells.push_back(quest->GetSrcSpell());
|
||||
// RewardSpell can teach multiple spells in trigger spell effects. But not all effects must be SPELL_EFFECT_LEARN_SPELL. See example spell 33950
|
||||
if (quest->GetRewSpell())
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpell());
|
||||
if (spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL))
|
||||
{
|
||||
SpellEffectInfoVector effects = spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE);
|
||||
for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->IsEffect(SPELL_EFFECT_LEARN_SPELL))
|
||||
packet.LearnSpells.push_back((*itr)->TriggerSpell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
quest->BuildQuestRewards(packet.Rewards, _session->GetPlayer());
|
||||
|
||||
|
||||
@@ -15181,6 +15181,17 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
|
||||
UpdatePvPState();
|
||||
}
|
||||
|
||||
if (quest->GetSrcSpell() > 0)
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetSrcSpell());
|
||||
Unit* caster = this;
|
||||
if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ON_ACCEPT) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER) && !spellInfo->HasTargetType(TARGET_DEST_CASTER_SUMMON))
|
||||
if (Unit* unit = questGiver->ToUnit())
|
||||
unit->CastSpell(this, quest->GetSrcSpell(), true);
|
||||
|
||||
caster->CastSpell(this, quest->GetSrcSpell(), true);
|
||||
}
|
||||
|
||||
SetQuestSlot(log_slot, quest_id, qtime);
|
||||
|
||||
m_QuestStatusSave[quest_id] = QUEST_DEFAULT_SAVE_TYPE;
|
||||
@@ -15498,16 +15509,12 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
if (quest->GetRewSpell() > 0)
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpell());
|
||||
if (questGiver && questGiver->isType(TYPEMASK_UNIT) &&
|
||||
!spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_LEARN_SPELL) &&
|
||||
!spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_CREATE_ITEM) &&
|
||||
!spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_APPLY_AURA))
|
||||
{
|
||||
Unit* caster = this;
|
||||
if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ON_COMPLETE) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER))
|
||||
if (Unit* unit = questGiver->ToUnit())
|
||||
unit->CastSpell(this, quest->GetRewSpell(), true);
|
||||
}
|
||||
else
|
||||
CastSpell(this, quest->GetRewSpell(), true);
|
||||
caster = unit;
|
||||
|
||||
caster->CastSpell(this, quest->GetRewSpell(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -15516,15 +15523,12 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
if (quest->RewardDisplaySpell[i] > 0)
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->RewardDisplaySpell[i]);
|
||||
if (questGiver && questGiver->isType(TYPEMASK_UNIT) &&
|
||||
!spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_LEARN_SPELL) &&
|
||||
!spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_CREATE_ITEM))
|
||||
{
|
||||
if (Unit* unit = questGiver->ToUnit())
|
||||
unit->CastSpell(this, quest->RewardDisplaySpell[i], true);
|
||||
}
|
||||
else
|
||||
CastSpell(this, quest->RewardDisplaySpell[i], true);
|
||||
Unit* caster = this;
|
||||
if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ON_COMPLETE) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER))
|
||||
if (Unit * unit = questGiver->ToUnit())
|
||||
caster = unit;
|
||||
|
||||
caster->CastSpell(this, quest->RewardDisplaySpell[i], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,9 +201,6 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPackets::Quest::QuestG
|
||||
|
||||
_player->PlayerTalkClass->SendCloseGossip();
|
||||
|
||||
if (quest->GetSrcSpell() > 0)
|
||||
_player->CastSpell(_player, quest->GetSrcSpell(), true);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1319,6 +1319,30 @@ bool SpellInfo::HasOnlyDamageEffects() const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SpellInfo::HasTargetType(::Targets target) const
|
||||
{
|
||||
for (auto itr = _effects.begin(); itr != _effects.end(); ++itr)
|
||||
{
|
||||
for (SpellEffectInfo const* effect : itr->second)
|
||||
{
|
||||
if (effect && (effect->TargetA.GetTarget() == target || effect->TargetB.GetTarget() == target))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SpellInfo::HasTargetType(uint32 difficulty, ::Targets target) const
|
||||
{
|
||||
SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
|
||||
for (SpellEffectInfo const* effect : effects)
|
||||
{
|
||||
if (effect && (effect->TargetA.GetTarget() == target || effect->TargetB.GetTarget() == target))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SpellInfo::HasAnyAuraInterruptFlag() const
|
||||
{
|
||||
return std::find_if(AuraInterruptFlags.begin(), AuraInterruptFlags.end(), [](uint32 flag) { return flag != 0; }) != AuraInterruptFlags.end();
|
||||
|
||||
@@ -534,6 +534,8 @@ class TC_GAME_API SpellInfo
|
||||
bool HasAreaAuraEffect(uint32 difficulty) const;
|
||||
bool HasAreaAuraEffect() const;
|
||||
bool HasOnlyDamageEffects() const;
|
||||
bool HasTargetType(::Targets target) const;
|
||||
bool HasTargetType(uint32 difficulty, ::Targets target) const;
|
||||
|
||||
bool HasAttribute(SpellAttr0 attribute) const { return !!(Attributes & attribute); }
|
||||
bool HasAttribute(SpellAttr1 attribute) const { return !!(AttributesEx & attribute); }
|
||||
|
||||
Reference in New Issue
Block a user