eqemu-server/common/skill_caps.cpp
Knightly 7ab909ee47 Standardize Licensing
- License was intended to be GPLv3 per earlier commit of GPLv3 LICENSE FILE
- This is confirmed by the inclusion of libraries that are incompatible with GPLv2
- This is also confirmed by KLS and the agreement of KLS's predecessors
- Added GPLv3 license headers to the compilable source files
- Removed Folly licensing in strings.h since the string functions do not match the Folly functions and are standard functions - this must have been left over from previous implementations
- Removed individual contributor license headers since the project has been under the "developer" mantle for many years
- Removed comments on files that were previously automatically generated since they've been manually modified multiple times and there are no automatic scripts referencing them (removed in 2023)
2026-04-01 17:09:57 -07:00

139 lines
3.7 KiB
C++

/* EQEmu: EQEmulator
Copyright (C) 2001-2026 EQEmu Development Team
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "skill_caps.h"
#include "common/timer.h"
// cache the skill cap max level in the database
std::map<uint8_t, int32_t> skill_max_level = {};
uint8 skill_cap_max_level = (
RuleI(Character, SkillCapMaxLevel) > 0 ?
RuleI(Character, SkillCapMaxLevel) :
RuleI(Character, MaxLevel)
);
SkillCaps *SkillCaps::SetContentDatabase(Database *db)
{
m_content_database = db;
return this;
}
int32_t SkillCaps::GetSkillCapMaxLevel(uint8 class_id, EQ::skills::SkillType skill_id)
{
// pull the max value defined in the database if it exists
auto it = skill_max_level.find((class_id * 1000000) + skill_id);
if (it != skill_max_level.end()) {
return it->second;
}
return skill_cap_max_level;
}
SkillCapsRepository::SkillCaps SkillCaps::GetSkillCap(uint8 class_id, EQ::skills::SkillType skill_id, uint8 level)
{
if (!IsPlayerClass(class_id) || static_cast<uint32>(skill_id) > EQ::skills::HIGHEST_SKILL + 1) {
return SkillCapsRepository::NewEntity();
}
const uint8 max_level = GetSkillCapMaxLevel(class_id, skill_id);
if (level > max_level) {
level = max_level;
}
const uint64_t key = (class_id * 1000000) + (level * 1000) + static_cast<uint32>(skill_id);
auto pos = m_skill_caps.find(key);
if (pos != m_skill_caps.end()) {
return pos->second;
}
return SkillCapsRepository::NewEntity();
}
uint8 SkillCaps::GetSkillTrainLevel(uint8 class_id, EQ::skills::SkillType skill_id, uint8 level)
{
if (
!IsPlayerClass(class_id) ||
class_id > Class::PLAYER_CLASS_COUNT ||
static_cast<uint32>(skill_id) > (EQ::skills::HIGHEST_SKILL + 1)
) {
return 0;
}
const uint8 max_level = level > skill_cap_max_level ? level : skill_cap_max_level;
const uint64_t key = (class_id * 1000000) + (level * 1000) + static_cast<uint32>(skill_id);
for (uint8 current_level = 1; current_level <= max_level; current_level++) {
auto pos = m_skill_caps.find(key);
if (pos != m_skill_caps.end()) {
return current_level;
}
}
return 0;
}
void SkillCaps::LoadSkillCaps()
{
const auto &l = SkillCapsRepository::All(*m_content_database);
m_skill_caps.clear();
for (const auto &e: l) {
if (
e.level < 1 ||
!IsPlayerClass(e.class_id) ||
static_cast<EQ::skills::SkillType>(e.skill_id) >= EQ::skills::SkillCount
) {
continue;
}
const uint64_t key = (e.class_id * 1000000) + (e.level * 1000) + e.skill_id;
m_skill_caps[key] = e;
const int max_level_key = (e.class_id * 1000000) + e.skill_id;
auto it = skill_max_level.find(max_level_key);
if (it != skill_max_level.end()) {
// Key found, update the value if the new level is higher
if (e.level > it->second) {
it->second = e.level;
}
// we never want to exceed the defined rule skill cap max level
if (it->second > skill_cap_max_level) {
it->second = skill_cap_max_level;
}
}
else {
// Key not found, insert the new key-value pair
skill_max_level[max_level_key] = e.level;
}
}
LogInfo(
"Loaded [{}] Skill Cap Entr{}",
l.size(),
l.size() != 1 ? "ies" : "y"
);
}
void SkillCaps::ReloadSkillCaps()
{
ClearSkillCaps();
LoadSkillCaps();
}