Skill perfect item template (#1564)

* Core/Misc Created handler for character creation

* fix(Core/DB): Error message when the password is longer than 16 char when creating an account

* Update rev_1551539925032805900.sql

* Update AccountMgr.cpp

* Milestone (DB/Core): Create new table for perfect item craft, create new command for reload capability to this new table, implements the table into core (killExtraItems.cpp, SkillExtraItems.h, SpellEffects.cpp), change some magic number with enum. Tnx to Treestone

* clean old sql

* Remove perfect item in skill extra item template table, now the perfect are in skill_perfect_item_template, sync column name skill_extra_item_template same as TC

* Update rev_1552232377246845400.sql
This commit is contained in:
Ercules76
2019-03-21 19:38:40 +01:00
committed by Viste(Кирилл)
parent c4835d8099
commit c53437bc75
7 changed files with 361 additions and 62 deletions

View File

@@ -8,6 +8,7 @@
#include "DatabaseEnv.h"
#include "Log.h"
#include "Player.h"
#include "ObjectMgr.h"
#include <map>
// some type definitions
@@ -15,6 +16,91 @@
// struct to store information about extra item creation
// one entry for every spell that is able to create an extra item
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)
{
sLog->outErrorDb(">> Loaded 0 spell perfection definitions. DB table `skill_perfect_item_template` is empty.");
sLog->outString();
return;
}
uint32 count = 0;
do /* fetch data and run sanity checks */
{
Field* fields = result->Fetch();
uint32 spellId = fields[0].GetUInt32();
if (!sSpellMgr->GetSpellInfo(spellId))
{
sLog->outError("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))
{
sLog->outError("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)
{
sLog->outError("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))
{
sLog->outError("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());
sLog->outString(">> Loaded %u spell perfection definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
struct SkillExtraItemEntry
{
// the spell id of the specialization required to create extra items
@@ -44,7 +130,7 @@ void LoadSkillExtraItemTable()
SkillExtraItemStore.clear(); // need for reload
// 0 1 2 3
QueryResult result = WorldDatabase.Query("SELECT spellId, requiredSpecialization, additionalCreateChance, newMaxOrEntry FROM skill_extra_item_template");
QueryResult result = WorldDatabase.Query("SELECT spellId, requiredSpecialization, additionalCreateChance, additionalMaxNum FROM skill_extra_item_template");
if (!result)
{
@@ -102,6 +188,30 @@ void LoadSkillExtraItemTable()
sLog->outString();
}
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, int32 &newMaxOrEntry)
{
// get the info for the specified spell