55 QueryResult result =
WorldDatabase.Query(
"SELECT spellId, reqSpell, reqSkillValue, chance FROM skill_discovery_template");
59 TC_LOG_INFO(
"server.loading",
">> Loaded 0 skill discovery definitions. DB table `skill_discovery_template` is empty.");
65 std::ostringstream ssNonDiscoverableEntries;
66 std::set<uint32> reportedReqSpells;
70 Field* fields = result->Fetch();
79 ssNonDiscoverableEntries <<
"spellId = " << spellId <<
" reqSkillOrSpell = " << reqSkillOrSpell
80 <<
" reqSkillValue = " << reqSkillValue <<
" chance = " << chance <<
"(chance problem)\n";
84 if (reqSkillOrSpell > 0)
90 if (reportedReqSpells.find(absReqSkillOrSpell) == reportedReqSpells.end())
92 TC_LOG_ERROR(
"sql.sql",
"Spell (ID: {}) has a non-existing spell (ID: {}) in `reqSpell` field in the `skill_discovery_template` table.", spellId, reqSkillOrSpell);
93 reportedReqSpells.insert(absReqSkillOrSpell);
103 if (reportedReqSpells.find(absReqSkillOrSpell) == reportedReqSpells.end())
105 TC_LOG_ERROR(
"sql.sql",
"Spell (ID: {}) does not have any MECHANIC_DISCOVERY (28) value in the Mechanic field in spell.dbc"
106 " nor 100% chance random discovery ability, but is listed for spellId {} (and maybe more) in the `skill_discovery_template` table.",
107 absReqSkillOrSpell, spellId);
108 reportedReqSpells.insert(absReqSkillOrSpell);
115 else if (reqSkillOrSpell == 0)
119 if (bounds.first == bounds.second)
121 TC_LOG_ERROR(
"sql.sql",
"Spell (ID: {}) is not listed in `SkillLineAbility.dbc`, but listed with `reqSpell`= 0 in the `skill_discovery_template` table.", spellId);
125 for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx)
130 TC_LOG_ERROR(
"sql.sql",
"Spell (ID: {}) has a negative value in `reqSpell` field in the `skill_discovery_template` table.", spellId);
136 while (result->NextRow());
138 if (!ssNonDiscoverableEntries.str().empty())
139 TC_LOG_ERROR(
"sql.sql",
"Some items can't be successfully discovered, their chance field value is < 0.000001 in the `skill_discovery_template` DB table. List:\n{}", ssNonDiscoverableEntries.str());
153 TC_LOG_ERROR(
"sql.sql",
"Spell (ID: {}) has got 100% chance random discovery ability, but does not have data in the `skill_discovery_template` table.", spellEntry->
Id);
170 float full_chance = 0;
171 for (SkillDiscoveryList::const_iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
172 if (item_iter->reqSkillValue <= skillvalue)
173 if (!player->
HasSpell(item_iter->spellId))
174 full_chance += item_iter->chance;
176 float rate = full_chance / 100.0f;
179 for (SkillDiscoveryList::const_iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
181 if (item_iter->reqSkillValue > skillvalue)
184 if (player->
HasSpell(item_iter->spellId))
187 if (item_iter->chance > roll)
188 return item_iter->spellId;
190 roll -= item_iter->chance;
202 for (SkillDiscoveryList::const_iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
203 if (!player->
HasSpell(item_iter->spellId))
215 for (SkillDiscoveryList::const_iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
216 if (player->
HasSpell(item_iter->spellId))
231 for (SkillDiscoveryList::const_iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
234 item_iter->reqSkillValue <= skillvalue &&
235 !player->
HasSpell(item_iter->spellId))
236 return item_iter->spellId;
249 for (SkillDiscoveryList::const_iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
252 item_iter->reqSkillValue <= skillvalue &&
253 !player->
HasSpell(item_iter->spellId))
254 return item_iter->spellId;
DB2Storage< SpellNameEntry > sSpellNameStore("SpellName.db2", &SpellNameLoadInfo::Instance)
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
#define TC_LOG_ERROR(filterType__, message__,...)
#define TC_LOG_INFO(filterType__, message__,...)
bool roll_chance(T chance)
std::list< SkillDiscoveryEntry > SkillDiscoveryList
static SkillDiscoveryMap SkillDiscoveryStore
uint32 GetExplicitDiscoverySpell(uint32 spellId, Player *player)
uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player *player)
std::unordered_map< int32, SkillDiscoveryList > SkillDiscoveryMap
bool HasDiscoveredAllSpells(uint32 spellId, Player *player)
bool HasDiscoveredAnySpell(uint32 spellId, Player *player)
void LoadSkillDiscoveryTable()
std::pair< SkillLineAbilityMap::const_iterator, SkillLineAbilityMap::const_iterator > SkillLineAbilityMapBounds
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Class used to access individual fields of database query result.
float GetFloat() const noexcept
uint32 GetUInt32() const noexcept
uint16 GetUInt16() const noexcept
int32 GetInt32() const noexcept
uint16 GetSkillValue(uint32 skill) const
bool HasSpell(uint32 spell) const override
bool IsExplicitDiscovery() const
SkillDiscoveryEntry(uint32 _spellId, uint32 req_skill_val, float _chance)