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__,...)
#define TC_LOG_INFO(filterType__,...)
bool roll_chance_f(float 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.
uint16 GetSkillValue(uint32 skill) const
bool HasSpell(uint32 spell) const override
bool IsExplicitDiscovery() const
SkillDiscoveryEntry(uint32 _spellId, uint32 req_skill_val, float _chance)