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:
Shauren
2014-06-25 20:34:10 +02:00
parent 2ae5036ad9
commit afd931550b
8 changed files with 86 additions and 14 deletions

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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";

View File

@@ -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);

View File

@@ -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);

View File

@@ -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*/)