aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Skills/SkillExtraItems.cpp
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2015-10-11 11:40:05 +0200
committerCarbenium <carbenium@outlook.com>2015-11-07 01:15:21 +0100
commit88584a73981c218f83a685c308ad08f6cb0bcab3 (patch)
treea32136397a5b4563c812787907fde2a610c5dbdc /src/server/game/Skills/SkillExtraItems.cpp
parent74d76277784f483e1145513469d54e1cf3b35667 (diff)
Merge pull request #15495 from Treeston/3.3.5-gemperfection
Core/Spell: Implement "Gem Perfection" (and framework for similar spells in the future) (cherry picked from commit 15cafba8d522153c07e46b8aeb85fa8a4942afcf)
Diffstat (limited to 'src/server/game/Skills/SkillExtraItems.cpp')
-rw-r--r--src/server/game/Skills/SkillExtraItems.cpp111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/server/game/Skills/SkillExtraItems.cpp b/src/server/game/Skills/SkillExtraItems.cpp
index 8df9ce86f9a..2c9a2a7bcfd 100644
--- a/src/server/game/Skills/SkillExtraItems.cpp
+++ b/src/server/game/Skills/SkillExtraItems.cpp
@@ -20,11 +20,98 @@
#include "DatabaseEnv.h"
#include "Log.h"
#include "Player.h"
+#include "ObjectMgr.h"
#include <map>
// some type definitions
// no use putting them in the header file, they're only used in this .cpp
+// struct to store information about perfection procs
+// one entry per spell
+struct SkillPerfectItemEntry
+{
+ // the spell id of the spell required - it's named "specialization" to conform with SkillExtraItemEntry
+ uint32 requiredSpecialization;
+ // perfection proc chance
+ float perfectCreateChance;
+ // itemid of the resulting perfect item
+ uint32 perfectItemType;
+
+ SkillPerfectItemEntry()
+ : requiredSpecialization(0), perfectCreateChance(0.0f), perfectItemType(0) { }
+ SkillPerfectItemEntry(uint32 rS, float pCC, uint32 pIT)
+ : requiredSpecialization(rS), perfectCreateChance(pCC), perfectItemType(pIT) { }
+};
+
+// map to store perfection info. key = spellId of the creation spell, value is the perfectitementry as specified above
+typedef std::map<uint32, SkillPerfectItemEntry> SkillPerfectItemMap;
+
+SkillPerfectItemMap SkillPerfectItemStore;
+
+// loads the perfection proc info from DB
+void LoadSkillPerfectItemTable()
+{
+ uint32 oldMSTime = getMSTime();
+
+ SkillPerfectItemStore.clear(); // reload capability
+
+ // 0 1 2 3
+ QueryResult result = WorldDatabase.Query("SELECT spellId, requiredSpecialization, perfectCreateChance, perfectItemType FROM skill_perfect_item_template");
+
+ if (!result)
+ {
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 spell perfection definitions. DB table `skill_perfect_item_template` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+
+ do /* fetch data and run sanity checks */
+ {
+ Field* fields = result->Fetch();
+
+ uint32 spellId = fields[0].GetUInt32();
+
+ if (!sSpellMgr->GetSpellInfo(spellId))
+ {
+ TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u has non-existent spell id in `skill_perfect_item_template`!", spellId);
+ continue;
+ }
+
+ uint32 requiredSpecialization = fields[1].GetUInt32();
+ if (!sSpellMgr->GetSpellInfo(requiredSpecialization))
+ {
+ TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u has non-existent required specialization spell id %u in `skill_perfect_item_template`!", spellId, requiredSpecialization);
+ continue;
+ }
+
+ float perfectCreateChance = fields[2].GetFloat();
+ if (perfectCreateChance <= 0.0f)
+ {
+ TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u has impossibly low proc chance in `skill_perfect_item_template`!", spellId);
+ continue;
+ }
+
+ uint32 perfectItemType = fields[3].GetUInt32();
+ if (!sObjectMgr->GetItemTemplate(perfectItemType))
+ {
+ TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u references non-existent perfect item id %u in `skill_perfect_item_template`!", spellId, perfectItemType);
+ continue;
+ }
+
+ SkillPerfectItemEntry& skillPerfectItemEntry = SkillPerfectItemStore[spellId];
+
+ skillPerfectItemEntry.requiredSpecialization = requiredSpecialization;
+ skillPerfectItemEntry.perfectCreateChance = perfectCreateChance;
+ skillPerfectItemEntry.perfectItemType = perfectItemType;
+
+ ++count;
+ }
+ while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u spell perfection definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
// struct to store information about extra item creation
// one entry for every spell that is able to create an extra item
struct SkillExtraItemEntry
@@ -112,6 +199,30 @@ void LoadSkillExtraItemTable()
TC_LOG_INFO("server.loading", ">> Loaded %u spell specialization definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
+bool CanCreatePerfectItem(Player* player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
+{
+ SkillPerfectItemMap::const_iterator ret = SkillPerfectItemStore.find(spellId);
+ // no entry in DB means no perfection proc possible
+ if (ret == SkillPerfectItemStore.end())
+ return false;
+
+ SkillPerfectItemEntry const* thisEntry = &ret->second;
+ // lack of entry means no perfection proc possible
+ if (!thisEntry)
+ return false;
+
+ // if you don't have the spell needed, then no procs for you
+ if (!player->HasSpell(thisEntry->requiredSpecialization))
+ return false;
+
+ // set values as appropriate
+ perfectCreateChance = thisEntry->perfectCreateChance;
+ perfectItemType = thisEntry->perfectItemType;
+
+ // and tell the caller to start rolling the dice
+ return true;
+}
+
bool CanCreateExtraItems(Player* player, uint32 spellId, float &additionalChance, uint8 &additionalMax)
{
// get the info for the specified spell