refactor(Script/Command): learn spell (#24319)

Co-authored-by: Treeston <14020072+Treeston@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Kitzunu
2026-03-21 13:28:24 +01:00
committed by GitHub
parent b90c917b49
commit e6054ec7ea
6 changed files with 71 additions and 43 deletions
@@ -130,7 +130,7 @@ namespace Trainer
return nullptr;
}
bool Trainer::CanTeachSpell(Player const* player, Spell const* trainerSpell)
bool Trainer::CanTeachSpell(Player const* player, Spell const* trainerSpell) const
{
SpellState state = GetSpellState(player, trainerSpell);
if (state != SpellState::Available)
+1 -1
View File
@@ -70,7 +70,7 @@ namespace Trainer
[[nodiscard]] Spell const* GetSpell(uint32 spellId) const;
[[nodiscard]] std::vector<Spell> const& GetSpells() const { return _spells; }
void SendSpells(Creature* npc, Player* player, LocaleConstant locale) const;
bool CanTeachSpell(Player const* player, Spell const* trainerSpell);
bool CanTeachSpell(Player const* player, Spell const* trainerSpell) const;
void TeachSpell(Creature* npc, Player* player, uint32 spellId);
[[nodiscard]] Type GetTrainerType() const { return _type; }
+13 -1
View File
@@ -9719,6 +9719,7 @@ void ObjectMgr::LoadTrainers()
// For reload case
_trainers.clear();
_classTrainers.clear();
std::unordered_map<int32, std::vector<Trainer::Spell>> spellsByTrainer;
if (QueryResult trainerSpellsResult = WorldDatabase.Query("SELECT TrainerId, SpellId, MoneyCost, ReqSkillLine, ReqSkillRank, ReqAbility1, ReqAbility2, ReqAbility3, ReqLevel FROM trainer_spell"))
@@ -9795,7 +9796,18 @@ void ObjectMgr::LoadTrainers()
spellsByTrainer.erase(spellsItr);
}
_trainers.emplace(std::piecewise_construct, std::forward_as_tuple(trainerId), std::forward_as_tuple(trainerId, trainerType, requirement, std::move(greeting), std::move(spells)));
auto [it, isNew] = _trainers.emplace(std::piecewise_construct, std::forward_as_tuple(trainerId), std::forward_as_tuple(trainerId, trainerType, requirement, std::move(greeting), std::move(spells)));
ASSERT(isNew);
if (trainerType == Trainer::Type::Class)
{
if (!requirement || requirement >= MAX_CLASSES)
LOG_ERROR("sql.sql", "Table `trainer` has invalid class requirement for trainer {}, ignoring");
else
{
uint8 classId = static_cast<uint8>(requirement);
_classTrainers[classId].push_back(&it->second);
}
}
} while (trainersResult->NextRow());
}
+2
View File
@@ -1418,6 +1418,7 @@ public:
bool DeleteGameTele(std::string_view name);
Trainer::Trainer* GetTrainer(uint32 creatureId);
std::vector<Trainer::Trainer const*> const& GetClassTrainers(uint8 classId) const { return _classTrainers.at(classId); }
[[nodiscard]] VendorItemData const* GetNpcVendorItemList(uint32 entry) const
{
@@ -1666,6 +1667,7 @@ private:
CacheVendorItemContainer _cacheVendorItemStore;
std::unordered_map<uint32, Trainer::Trainer> _trainers;
std::unordered_map<uint8, std::vector<Trainer::Trainer const*>> _classTrainers;
std::unordered_map<uint32, uint32> _creatureDefaultTrainers;
std::set<uint32> _difficultyEntries[MAX_DIFFICULTY - 1]; // already loaded difficulty 1 value in creatures, used in CheckCreatureTemplate