aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2014-06-25 20:34:10 +0200
committerShauren <shauren.trinity@gmail.com>2014-06-25 20:34:10 +0200
commitafd931550b942007d57eb1a8cf3f6b60c8b2903e (patch)
treef67fdc7c77d070b6d5ac7507ef012c596332481d
parent2ae5036ad98f6e7efed993e5ebebbf266da304bd (diff)
Core/Skills: Check if a skill can be unlearned with SkillRaceClassInfo.dbc data and use max skill level from SkillTiers.dbc
-rw-r--r--src/server/game/DataStores/DBCEnums.h32
-rw-r--r--src/server/game/DataStores/DBCStores.cpp26
-rw-r--r--src/server/game/DataStores/DBCStores.h5
-rw-r--r--src/server/game/DataStores/DBCStructure.h21
-rw-r--r--src/server/game/DataStores/DBCfmt.h2
-rw-r--r--src/server/game/Handlers/SkillHandler.cpp3
-rw-r--r--src/server/game/Server/WorldSession.h1
-rw-r--r--src/server/game/Spells/SpellEffects.cpp10
8 files changed, 86 insertions, 14 deletions
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 8e186e9d094..10b7c25bb1f 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -349,21 +349,20 @@ enum ItemLimitCategoryMode
ITEM_LIMIT_CATEGORY_MODE_EQUIP = 1 // limit applied to amount equipped items (including used gems)
};
-enum SpellCategoryFlags
+enum SkillRaceClassInfoFlags
{
- SPELL_CATEGORY_FLAG_COOLDOWN_SCALES_WITH_WEAPON_SPEED = 0x01, // unused
- SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT = 0x04
+ 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 TotemCategoryType
+enum SpellCategoryFlags
{
- 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
+ SPELL_CATEGORY_FLAG_COOLDOWN_SCALES_WITH_WEAPON_SPEED = 0x01, // unused
+ SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT = 0x04
};
// SummonProperties.dbc, col 1
@@ -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,
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 44f03b6978d..92d00b20645 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -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;
+}
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index fe775dfda19..8b89a86fafe 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -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;
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 5d6c8c7aa89..2da166fb049 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -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
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index 222353467f4..a90cc48c5af 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -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";
diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp
index f90dfef2684..8a94753b692 100644
--- a/src/server/game/Handlers/SkillHandler.cpp
+++ b/src/server/game/Handlers/SkillHandler.cpp
@@ -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);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 3422934fcd9..c8c81a415e1 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -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);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 0a43c5a2c45..1240d8af7ac 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -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*/)