Skip to content

Instantly share code, notes, and snippets.

@Langerz82
Created January 25, 2019 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Langerz82/7fc5e50b2e46fdca1bd974c4662f622e to your computer and use it in GitHub Desktop.
Save Langerz82/7fc5e50b2e46fdca1bd974c4662f622e to your computer and use it in GitHub Desktop.
diff --git a/src/game/Object/SpellMgr.cpp b/src/game/Object/SpellMgr.cpp
index 48880cc..353ec8f 100644
--- a/src/game/Object/SpellMgr.cpp
+++ b/src/game/Object/SpellMgr.cpp
@@ -47,6 +47,9 @@ bool IsPrimaryProfessionSkill(uint32 skill)
SpellMgr::SpellMgr()
{
+ for (SkillRaceClassInfoEntry const* entry : sSkillRaceClassInfoStore)
+ if (sSkillLineStore.LookupEntry(entry->skillId))
+ SkillRaceClassInfoBySkill.emplace(entry->skillId, entry);
}
SpellMgr::~SpellMgr()
diff --git a/src/game/Object/SpellMgr.h b/src/game/Object/SpellMgr.h
index db35f76..d28698a 100644
--- a/src/game/Object/SpellMgr.h
+++ b/src/game/Object/SpellMgr.h
@@ -846,6 +846,7 @@ typedef std::pair<SkillLineAbilityMap::const_iterator, SkillLineAbilityMap::cons
typedef std::multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap;
typedef std::pair<SkillRaceClassInfoMap::const_iterator, SkillRaceClassInfoMap::const_iterator> SkillRaceClassInfoMapBounds;
+
bool IsPrimaryProfessionSkill(uint32 skill);
inline bool IsProfessionSkill(uint32 skill)
@@ -868,7 +869,7 @@ class SpellMgr
// Constructors
public:
- SpellMgr();
+ SpellMgr();
~SpellMgr();
// Accessors (const or static functions)
@@ -1103,6 +1104,22 @@ class SpellMgr
return mSkillRaceClassInfoMap.equal_range(skill_id);
}
+ SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_)
+ {
+ SkillRaceClassInfoMapBounds bounds = mSkillRaceClassInfoMap.equal_range(skill);
+ for (SkillRaceClassInfoMap::const_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 nullptr;
+ }
+
PetAura const* GetPetAura(uint32 spell_id)
{
SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find(spell_id);
@@ -1136,6 +1153,8 @@ class SpellMgr
SpellLinkedSet GetSpellLinked(uint32 spell_id, SpellLinkedType type) const;
+ SkillRaceClassInfoMap SkillRaceClassInfoBySkill;
+
// Modifiers
public:
static SpellMgr& Instance();
diff --git a/src/game/Server/DBCStores.cpp b/src/game/Server/DBCStores.cpp
index 63814ea..4637c06 100644
--- a/src/game/Server/DBCStores.cpp
+++ b/src/game/Server/DBCStores.cpp
@@ -103,6 +103,7 @@ DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);
DBCStorage <SkillLineEntry> sSkillLineStore(SkillLinefmt);
DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore(SkillLineAbilityfmt);
DBCStorage <SkillRaceClassInfoEntry> sSkillRaceClassInfoStore(SkillRaceClassInfofmt);
+DBCStorage <SkillTiersEntry> sSkillTiersStore(SkillTiersfmt);
DBCStorage <SoundEntriesEntry> sSoundEntriesStore(SoundEntriesfmt);
@@ -278,9 +279,12 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc");
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMapStore, dbcPath, "Map.dbc");
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc");
+
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc");
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc");
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillRaceClassInfoStore, dbcPath, "SkillRaceClassInfo.dbc");
+ LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillTiersStore, dbcPath, "SkillTiers.dbc");
+
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc");
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc");
for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i)
@@ -795,6 +799,8 @@ bool IsPointInAreaTriggerZone(AreaTriggerEntry const* atEntry, uint32 mapid, flo
return true;
}
+
+
uint32 GetCreatureModelRace(uint32 model_id)
{
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(model_id);
diff --git a/src/game/Server/DBCStores.h b/src/game/Server/DBCStores.h
index 1129a69..aa9a387 100644
--- a/src/game/Server/DBCStores.h
+++ b/src/game/Server/DBCStores.h
@@ -26,6 +26,7 @@
#define MANGOS_DBCSTORES_H
#include "Common.h"
+#include "DBCfmt.h"
#include "DBCStore.h"
#include "DBCStructure.h"
@@ -65,7 +66,7 @@ uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls);
bool IsPointInAreaTriggerZone(AreaTriggerEntry const* atEntry, uint32 mapid, float x, float y, float z, float delta = 0.0f);
- uint32 GetCreatureModelRace(uint32 model_id);
+uint32 GetCreatureModelRace(uint32 model_id);
extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions
extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore;
@@ -101,6 +102,9 @@ extern DBCStorage <QuestSortEntry> sQuestSortStore;
extern DBCStorage <SkillLineEntry> sSkillLineStore;
extern DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore;
extern DBCStorage <SkillRaceClassInfoEntry> sSkillRaceClassInfoStore;
+extern DBCStorage <SkillTiersEntry> sSkillTiersStore;
+
+
extern DBCStorage <SoundEntriesEntry> sSoundEntriesStore;
extern DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore;
extern DBCStorage <SpellDurationEntry> sSpellDurationStore;
diff --git a/src/game/Server/DBCStructure.h b/src/game/Server/DBCStructure.h
index 57eae02..fe70ea4 100644
--- a/src/game/Server/DBCStructure.h
+++ b/src/game/Server/DBCStructure.h
@@ -637,6 +637,15 @@ struct SkillLineAbilityEntry
uint32 reqtrainpoints; // 14
};
+#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
* \brief Entry representing sound for client, used for validation.
diff --git a/src/game/Server/DBCfmt.h b/src/game/Server/DBCfmt.h
index 05b8772..be0dbf7 100644
--- a/src/game/Server/DBCfmt.h
+++ b/src/game/Server/DBCfmt.h
@@ -58,6 +58,7 @@ const char QuestSortEntryfmt[] = "nxxxxxxxxx";
const char SkillLinefmt[] = "nixssssssssxxxxxxxxxxx";
const char SkillLineAbilityfmt[] = "niiiixxiiiiixxi";
const char SkillRaceClassInfofmt[] = "diiiiixx";
+const char SkillTiersfmt[] = "nxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiii";
const char SoundEntriesfmt[] = "nxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char SpellCastTimefmt[] = "nixx";
const char SpellDurationfmt[] = "niii";
diff --git a/src/game/WorldHandlers/SpellEffects.cpp b/src/game/WorldHandlers/SpellEffects.cpp
index 73b58bf..8629c28 100644
--- a/src/game/WorldHandlers/SpellEffects.cpp
+++ b/src/game/WorldHandlers/SpellEffects.cpp
@@ -2777,11 +2777,19 @@ void Spell::EffectLearnSkill(SpellEffectIndex eff_idx)
{ return; }
uint32 skillid = m_spellInfo->EffectMiscValue[eff_idx];
- uint16 skillval = ((Player*)unitTarget)->GetPureSkillValue(skillid);
- ((Player*)unitTarget)->SetSkill(skillid, skillval ? skillval : 1, damage * 75, damage);
+ SkillRaceClassInfoEntry const* rcEntry = sSpellMgr.GetSkillRaceClassInfo(skillid, unitTarget->getRace(), unitTarget->getClass());
+ if (!rcEntry)
+ return;
+
+ SkillTiersEntry const* tier = sSkillTiersStore.LookupEntry(rcEntry->skillId);
+ if (!tier)
+ return;
+
+ uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
+ unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effect[eff_idx], std::max<uint16>(skillval, 1), tier->MaxSkill[damage - 1]);
if (WorldObject const* caster = GetCastingObject())
- { DEBUG_LOG("Spell: %s has learned skill %u (to maxlevel %u) from %s", unitTarget->GetGuidStr().c_str(), skillid, damage * 75, caster->GetGuidStr().c_str()); }
+ { DEBUG_LOG("Spell: %s has learned skill %u (to maxlevel %u) from %s", unitTarget->GetGuidStr().c_str(), skillid, std::max<uint16>(skillval, 1), caster->GetGuidStr().c_str()); }
}
void Spell::EffectAddHonor(SpellEffectIndex /*eff_idx*/)
diff --git a/src/shared/DataStores/DBCStorageIterator.h b/src/shared/DataStores/DBCStorageIterator.h
new file mode 100644
index 0000000..695bf63
--- /dev/null
+++ b/src/shared/DataStores/DBCStorageIterator.h
@@ -0,0 +1,76 @@
+/**
+* MaNGOS is a full featured server for World of Warcraft, supporting
+* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
+*
+* Copyright (C) 2005-2019 MaNGOS project <https://getmangos.eu>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+* World of Warcraft, and all World of Warcraft or Warcraft art, images,
+* and lore are copyrighted by Blizzard Entertainment, Inc.
+*/
+
+#ifndef DBCStorageIterator_h__
+#define DBCStorageIterator_h__
+
+//#include "Define.h"
+#include <iterator>
+
+template <class T>
+class DBCStorageIterator : public std::iterator<std::forward_iterator_tag, T>
+{
+ public:
+ DBCStorageIterator() : _index(nullptr), _pos(0), _end(0) { }
+ DBCStorageIterator(T** index, uint32 size, uint32 pos = 0) : _index(index), _pos(pos), _end(size)
+ {
+ if (_pos < _end)
+ {
+ while (_pos < _end && !_index[_pos])
+ ++_pos;
+ }
+ }
+
+ T const* operator->() { return _index[_pos]; }
+ T const* operator*() { return _index[_pos]; }
+
+ bool operator==(DBCStorageIterator const& right) const { /*ASSERT(_index == right._index, "Iterator belongs to a different container")*/ return _pos == right._pos; }
+ bool operator!=(DBCStorageIterator const& right) const { return !(*this == right); }
+
+ DBCStorageIterator& operator++()
+ {
+ if (_pos < _end)
+ {
+ do
+ ++_pos;
+ while (_pos < _end && !_index[_pos]);
+ }
+
+ return *this;
+ }
+
+ DBCStorageIterator operator++(int)
+ {
+ DBCStorageIterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ private:
+ T** _index;
+ uint32 _pos;
+ uint32 _end;
+};
+
+#endif // DBCStorageIterator_h__
diff --git a/src/shared/DataStores/DBCStore.h b/src/shared/DataStores/DBCStore.h
index 3edb944..d82c7d9 100644
--- a/src/shared/DataStores/DBCStore.h
+++ b/src/shared/DataStores/DBCStore.h
@@ -26,6 +26,7 @@
#define DBCSTORE_H
#include "DBCFileLoader.h"
+#include "DBCStorageIterator.h"
template<class T>
/**
@@ -33,13 +34,11 @@ template<class T>
*
*/
class DBCStorage
-{
- /**
- * @brief
- *
- */
- typedef std::list<char*> StringPoolList;
+{
public:
+ typedef std::list<char*> StringPoolList;
+ typedef DBCStorageIterator<T> iterator;
+
/**
* @brief
*
@@ -194,7 +193,9 @@ class DBCStorage
* @param id
*/
void InsertEntry(T* entry, uint32 id) { assert(id < nCount && "Entry to be inserted must be in bounds!"); indexTable[id] = entry; }
-
+
+ iterator begin() { return iterator(indexTable, nCount); }
+ iterator end() { return iterator(indexTable, nCount, nCount); }
private:
uint32 nCount; /**< TODO */
uint32 fieldCount; /**< TODO */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment