mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-21 01:37:37 +01:00
Core/Skills: Check if a skill can be unlearned with SkillRaceClassInfo.dbc data and use max skill level from SkillTiers.dbc
This commit is contained in:
@@ -349,23 +349,22 @@ enum ItemLimitCategoryMode
|
||||
ITEM_LIMIT_CATEGORY_MODE_EQUIP = 1 // limit applied to amount equipped items (including used gems)
|
||||
};
|
||||
|
||||
enum SkillRaceClassInfoFlags
|
||||
{
|
||||
SKILL_FLAG_NO_SKILLUP_MESSAGE = 0x2,
|
||||
SKILL_FLAG_ALWAYS_MAX_VALUE = 0x10,
|
||||
SKILL_FLAG_UNLEARNABLE = 0x20, // Skill can be unlearned
|
||||
SKILL_FLAG_INCLUDE_IN_SORT = 0x80, // Spells belonging to a skill with this flag will additionally compare skill ids when sorting spellbook in client
|
||||
SKILL_FLAG_NOT_TRAINABLE = 0x100,
|
||||
SKILL_FLAG_MONO_VALUE = 0x400 // Skill always has value 1
|
||||
};
|
||||
|
||||
enum SpellCategoryFlags
|
||||
{
|
||||
SPELL_CATEGORY_FLAG_COOLDOWN_SCALES_WITH_WEAPON_SPEED = 0x01, // unused
|
||||
SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT = 0x04
|
||||
};
|
||||
|
||||
enum TotemCategoryType
|
||||
{
|
||||
TOTEM_CATEGORY_TYPE_KNIFE = 1,
|
||||
TOTEM_CATEGORY_TYPE_TOTEM = 2,
|
||||
TOTEM_CATEGORY_TYPE_ROD = 3,
|
||||
TOTEM_CATEGORY_TYPE_PICK = 21,
|
||||
TOTEM_CATEGORY_TYPE_STONE = 22,
|
||||
TOTEM_CATEGORY_TYPE_HAMMER = 23,
|
||||
TOTEM_CATEGORY_TYPE_SPANNER = 24
|
||||
};
|
||||
|
||||
// SummonProperties.dbc, col 1
|
||||
enum SummonPropGroup
|
||||
{
|
||||
@@ -398,6 +397,17 @@ enum SummonPropFlags
|
||||
SUMMON_PROP_FLAG_UNK16 = 0x00008000 // Light/Dark Bullet, Soul/Fiery Consumption, Twisted Visage, Twilight Whelp. Phase related?
|
||||
};
|
||||
|
||||
enum TotemCategoryType
|
||||
{
|
||||
TOTEM_CATEGORY_TYPE_KNIFE = 1,
|
||||
TOTEM_CATEGORY_TYPE_TOTEM = 2,
|
||||
TOTEM_CATEGORY_TYPE_ROD = 3,
|
||||
TOTEM_CATEGORY_TYPE_PICK = 21,
|
||||
TOTEM_CATEGORY_TYPE_STONE = 22,
|
||||
TOTEM_CATEGORY_TYPE_HAMMER = 23,
|
||||
TOTEM_CATEGORY_TYPE_SPANNER = 24
|
||||
};
|
||||
|
||||
enum VehicleSeatFlags
|
||||
{
|
||||
VEHICLE_SEAT_FLAG_HAS_LOWER_ANIM_FOR_ENTER = 0x00000001,
|
||||
|
||||
@@ -151,6 +151,9 @@ DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore(ScalingStatValuesfmt
|
||||
|
||||
DBCStorage <SkillLineEntry> sSkillLineStore(SkillLinefmt);
|
||||
DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore(SkillLineAbilityfmt);
|
||||
DBCStorage <SkillRaceClassInfoEntry> sSkillRaceClassInfoStore(SkillRaceClassInfofmt);
|
||||
SkillRaceClassInfoMap SkillRaceClassInfoBySkill;
|
||||
DBCStorage <SkillTiersEntry> sSkillTiersStore(SkillTiersfmt);
|
||||
|
||||
DBCStorage <SoundEntriesEntry> sSoundEntriesStore(SoundEntriesfmt);
|
||||
|
||||
@@ -409,6 +412,13 @@ void LoadDBCStores(const std::string& dataPath)
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatValuesStore, dbcPath, "ScalingStatValues.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sSkillRaceClassInfoStore, dbcPath, "SkillRaceClassInfo.dbc");
|
||||
for (uint32 i = 0; i < sSkillRaceClassInfoStore.GetNumRows(); ++i)
|
||||
if (SkillRaceClassInfoEntry const* entry = sSkillRaceClassInfoStore.LookupEntry(i))
|
||||
if (sSkillLineStore.LookupEntry(entry->SkillId))
|
||||
SkillRaceClassInfoBySkill.emplace(entry->SkillId, entry);
|
||||
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sSkillTiersStore, dbcPath, "SkillTiers.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc", &CustomSpellEntryfmt, &CustomSpellEntryIndex);
|
||||
for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i)
|
||||
@@ -965,3 +975,19 @@ uint32 GetDefaultMapLight(uint32 mapId)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_)
|
||||
{
|
||||
SkillRaceClassInfoBounds bounds = SkillRaceClassInfoBySkill.equal_range(skill);
|
||||
for (SkillRaceClassInfoMap::iterator itr = bounds.first; itr != bounds.second; ++itr)
|
||||
{
|
||||
if (itr->second->RaceMask && !(itr->second->RaceMask & (1 << (race - 1))))
|
||||
continue;
|
||||
if (itr->second->ClassMask && !(itr->second->ClassMask & (1 << (class_ - 1))))
|
||||
continue;
|
||||
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -74,6 +74,10 @@ LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty);
|
||||
|
||||
uint32 GetDefaultMapLight(uint32 mapId);
|
||||
|
||||
typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap;
|
||||
typedef std::pair<SkillRaceClassInfoMap::iterator, SkillRaceClassInfoMap::iterator> SkillRaceClassInfoBounds;
|
||||
SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_);
|
||||
|
||||
extern DBCStorage <AchievementEntry> sAchievementStore;
|
||||
extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
|
||||
extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions
|
||||
@@ -150,6 +154,7 @@ extern DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore;
|
||||
extern DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore;
|
||||
extern DBCStorage <SkillLineEntry> sSkillLineStore;
|
||||
extern DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore;
|
||||
extern DBCStorage <SkillTiersEntry> sSkillTiersStore;
|
||||
extern DBCStorage <SoundEntriesEntry> sSoundEntriesStore;
|
||||
extern DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore;
|
||||
extern DBCStorage <SpellCategoryEntry> sSpellCategoryStore;
|
||||
|
||||
@@ -1584,6 +1584,27 @@ struct SkillLineAbilityEntry
|
||||
//uint32 characterPoints[2]; // 12-13 m_characterPoints[2]
|
||||
};
|
||||
|
||||
struct SkillRaceClassInfoEntry
|
||||
{
|
||||
//uint32 Id; // 0
|
||||
uint32 SkillId; // 1
|
||||
uint32 RaceMask; // 2
|
||||
uint32 ClassMask; // 3
|
||||
uint32 Flags; // 4
|
||||
//uint32 MinLevel; // 5
|
||||
uint32 SkillTier; // 6
|
||||
//uint32 SkillCostType; // 7
|
||||
};
|
||||
|
||||
#define MAX_SKILL_STEP 16
|
||||
|
||||
struct SkillTiersEntry
|
||||
{
|
||||
uint32 Id; // 0
|
||||
//uint32 StepCost[MAX_SKILL_STEP]; // 1-16
|
||||
uint32 MaxSkill[MAX_SKILL_STEP]; // 17-32
|
||||
};
|
||||
|
||||
struct SoundEntriesEntry
|
||||
{
|
||||
uint32 Id; // 0 m_ID
|
||||
|
||||
@@ -98,6 +98,8 @@ char const ScalingStatDistributionfmt[] = "niiiiiiiiiiiiiiiiiiiii";
|
||||
char const ScalingStatValuesfmt[] = "iniiiiiiiiiiiiiiiiiiiiii";
|
||||
char const SkillLinefmt[] = "nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi";
|
||||
char const SkillLineAbilityfmt[] = "niiiixxiiiiixx";
|
||||
char const SkillRaceClassInfofmt[] = "diiiixix";
|
||||
char const SkillTiersfmt[] = "nxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiii";
|
||||
char const SoundEntriesfmt[] = "nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
char const SpellCastTimefmt[] = "nixx";
|
||||
char const SpellCategoryfmt[] = "ni";
|
||||
|
||||
@@ -98,7 +98,8 @@ void WorldSession::HandleUnlearnSkillOpcode(WorldPacket& recvData)
|
||||
uint32 skillId;
|
||||
recvData >> skillId;
|
||||
|
||||
if (!IsPrimaryProfessionSkill(skillId))
|
||||
SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(skillId, GetPlayer()->getRace(), GetPlayer()->getClass());
|
||||
if (!rcEntry || !(rcEntry->Flags & SKILL_FLAG_UNLEARNABLE))
|
||||
return;
|
||||
|
||||
GetPlayer()->SetSkill(skillId, 0, 0, 0);
|
||||
|
||||
@@ -444,7 +444,6 @@ class WorldSession
|
||||
void HandleForceSpeedChangeAck(WorldPacket& recvData);
|
||||
|
||||
void HandlePingOpcode(WorldPacket& recvPacket);
|
||||
void HandleAuthSessionOpcode(WorldPacket& recvPacket);
|
||||
void HandleRepopRequestOpcode(WorldPacket& recvPacket);
|
||||
void HandleAutostoreLootItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleLootMoneyOpcode(WorldPacket& recvPacket);
|
||||
|
||||
@@ -2608,8 +2608,16 @@ void Spell::EffectLearnSkill(SpellEffIndex effIndex)
|
||||
return;
|
||||
|
||||
uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
|
||||
SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(skillid, unitTarget->getRace(), unitTarget->getClass());
|
||||
if (!rcEntry)
|
||||
return;
|
||||
|
||||
SkillTiersEntry const* tier = sSkillTiersStore.LookupEntry(rcEntry->SkillTier);
|
||||
if (!tier)
|
||||
return;
|
||||
|
||||
uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
|
||||
unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval?skillval:1, damage*75);
|
||||
unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), std::min<uint16>(skillval, 1), tier->MaxSkill[damage - 1]);
|
||||
}
|
||||
|
||||
void Spell::EffectAddHonor(SpellEffIndex /*effIndex*/)
|
||||
|
||||
Reference in New Issue
Block a user