Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/server/game/DataStores/DB2Structure.h
Original file line number Diff line number Diff line change
Expand Up @@ -2717,6 +2717,8 @@ struct SkillLineAbilityEntry
int16 UniqueBit;
int16 TradeSkillCategoryID;
int16 SkillupSkillLineID;

EnumFlag<SkillLineAbilityFlags> GetFlags() const { return EnumFlag<SkillLineAbilityFlags>(static_cast<SkillLineAbilityFlags>(Flags)); }
};

struct SkillRaceClassInfoEntry
Expand Down
8 changes: 8 additions & 0 deletions src/server/game/DataStores/DBCEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,14 @@ enum AbilytyLearnType
SKILL_LINE_ABILITY_REWARDED_FROM_QUEST = 4 // Learned as quest reward, also re-learned if missing
};

enum class SkillLineAbilityFlags
{
CanFallbackToLearnedOnSkillLearn = 0x80, // The skill is rewarded from a quest if player started on exile's reach

};

DEFINE_ENUM_FLAG(SkillLineAbilityFlags);

enum GlyphSlotType
{
GLYPH_SLOT_MAJOR = 0,
Expand Down
15 changes: 13 additions & 2 deletions src/server/game/Entities/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24801,8 +24801,19 @@ void Player::LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue)
if (!spellInfo)
continue;

if (ability->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE && ability->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
continue;
switch (ability->AcquireMethod)
{
case SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE:
case SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN:
break;
case SKILL_LINE_ABILITY_REWARDED_FROM_QUEST:
if (!ability->GetFlags().HasFlag(SkillLineAbilityFlags::CanFallbackToLearnedOnSkillLearn) ||
!spellInfo->MeetsFutureSpellPlayerCondition(this))
continue;
break;
default:
continue;
}

// AcquireMethod == 2 && NumSkillUps == 1 --> automatically learn riding skill spell, else we skip it (client shows riding in spellbook as trainable).
if (skillId == SKILL_RIDING && (ability->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN || ability->NumSkillUps != 1))
Expand Down
10 changes: 10 additions & 0 deletions src/server/game/Spells/SpellInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,7 @@ SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, S
IconFileDataId = _misc ? _misc->SpellIconFileDataID : 0;
ActiveIconFileDataId = _misc ? _misc->ActiveIconFileDataID : 0;
ContentTuningId = _misc ? _misc->ContentTuningID : 0;
ShowFutureSpellPlayerConditionID = _misc ? _misc->ShowFutureSpellPlayerConditionID : 0;

_visuals = std::move(visuals);

Expand Down Expand Up @@ -4532,3 +4533,12 @@ void SpellInfo::_UnloadImplicitTargetConditionLists()
}
}
}

bool SpellInfo::MeetsFutureSpellPlayerCondition(Player const* player) const
{
if (ShowFutureSpellPlayerConditionID == 0)
return false;

PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(ShowFutureSpellPlayerConditionID);
return !playerCondition || ConditionMgr::IsPlayerMeetingCondition(player, playerCondition);
}
4 changes: 4 additions & 0 deletions src/server/game/Spells/SpellInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ class TC_GAME_API SpellInfo
uint32 IconFileDataId;
uint32 ActiveIconFileDataId;
uint32 ContentTuningId;
uint32 ShowFutureSpellPlayerConditionID;
LocalizedString const* SpellName;
float ConeAngle;
float Width;
Expand Down Expand Up @@ -686,6 +687,9 @@ class TC_GAME_API SpellInfo

uint32 GetAllowedMechanicMask() const;

// Player Condition
bool MeetsFutureSpellPlayerCondition(Player const* player) const;

private:
// loading helpers
void _InitializeExplicitTargetMask();
Expand Down