[Skill Caps] Remove from shared memory and simplify (#4069)

* [Skill Caps] Remove from shared memory and simplify

- Removes Skill Caps loading from shared memory and puts it into zone.
- Adds `id` column to `skill_caps`.
- Remove primary keys and use `id` as primary key.
- Add unique index using `skill_id`, `class_id`, `level`, and `cap`.
- Renames `class` to `class_id` in `skill_caps` table.
- Renames `skillID` to `skill_id` in `skill_caps` table.
- Regenerates Skill Caps repository.
- Adds `#reload skill_caps` to reload skill caps in real time.

* Update groups.cpp

* Update groups.cpp
This commit is contained in:
Alex King
2024-03-23 19:52:40 -04:00
committed by GitHub
parent 036309ebec
commit d7ea290b6b
25 changed files with 306 additions and 414 deletions
+1
View File
@@ -166,6 +166,7 @@ SET(zone_sources
zone_event_scheduler.cpp
zone_npc_factions.cpp
zone_reload.cpp
zone_skill_caps.cpp
zoning.cpp
)
+51 -23
View File
@@ -2756,31 +2756,48 @@ void Client::CheckLanguageSkillIncrease(uint8 language_id, uint8 teacher_skill)
}
}
bool Client::HasSkill(EQ::skills::SkillType skill_id) const {
return((GetSkill(skill_id) > 0) && CanHaveSkill(skill_id));
}
bool Client::CanHaveSkill(EQ::skills::SkillType skill_id) const {
if (ClientVersion() < EQ::versions::ClientVersion::RoF2 && class_ == Class::Berserker && skill_id == EQ::skills::Skill1HPiercing)
skill_id = EQ::skills::Skill2HPiercing;
return(content_db.GetSkillCap(GetClass(), skill_id, RuleI(Character, MaxLevel)) > 0);
//if you don't have it by max level, then odds are you never will?
}
uint16 Client::MaxSkill(EQ::skills::SkillType skillid, uint16 class_, uint16 level) const {
if (ClientVersion() < EQ::versions::ClientVersion::RoF2 && class_ == Class::Berserker && skillid == EQ::skills::Skill1HPiercing)
skillid = EQ::skills::Skill2HPiercing;
return(content_db.GetSkillCap(class_, skillid, level));
}
uint8 Client::SkillTrainLevel(EQ::skills::SkillType skillid, uint16 class_)
bool Client::HasSkill(EQ::skills::SkillType skill_id) const
{
if (ClientVersion() < EQ::versions::ClientVersion::RoF2 && class_ == Class::Berserker && skillid == EQ::skills::Skill1HPiercing)
skillid = EQ::skills::Skill2HPiercing;
return GetSkill(skill_id) > 0 && CanHaveSkill(skill_id);
}
return(content_db.GetTrainLevel(class_, skillid, RuleI(Character, MaxLevel)));
bool Client::CanHaveSkill(EQ::skills::SkillType skill_id) const
{
if (
ClientVersion() < EQ::versions::ClientVersion::RoF2 &&
class_ == Class::Berserker &&
skill_id == EQ::skills::Skill1HPiercing
) {
skill_id = EQ::skills::Skill2HPiercing;
}
return zone->GetSkillCap(GetClass(), skill_id, RuleI(Character, MaxLevel)).cap > 0;
}
uint16 Client::MaxSkill(EQ::skills::SkillType skill_id, uint8 class_id, uint8 level) const
{
if (
ClientVersion() < EQ::versions::ClientVersion::RoF2 &&
class_id == Class::Berserker &&
skill_id == EQ::skills::Skill1HPiercing
) {
skill_id = EQ::skills::Skill2HPiercing;
}
return(content_db.GetSkillCap(class_id, skill_id, level));
}
uint8 Client::SkillTrainLevel(EQ::skills::SkillType skill_id, uint8 class_id)
{
if (
ClientVersion() < EQ::versions::ClientVersion::RoF2 &&
class_id == Class::Berserker &&
skill_id == EQ::skills::Skill1HPiercing
) {
skill_id = EQ::skills::Skill2HPiercing;
}
return zone->GetTrainLevel(class_id, skill_id, RuleI(Character, MaxLevel));
}
uint16 Client::GetMaxSkillAfterSpecializationRules(EQ::skills::SkillType skillid, uint16 maxSkill)
@@ -9226,6 +9243,7 @@ void Client::ShowDevToolsMenu()
menu_reload_six += " | " + Saylink::Silent("#reload quest", "Quests");
menu_reload_seven += Saylink::Silent("#reload rules", "Rules");
menu_reload_seven += " | " + Saylink::Silent("#reload skill_caps", "Skill Caps");
menu_reload_seven += " | " + Saylink::Silent("#reload static", "Static Zone Data");
menu_reload_seven += " | " + Saylink::Silent("#reload tasks", "Tasks");
@@ -11353,6 +11371,16 @@ void Client::SendReloadCommandMessages() {
).c_str()
);
auto skill_caps_link = Saylink::Silent("#reload skill_caps");
Message(
Chat::White,
fmt::format(
"Usage: {} - Reloads Skill Caps globally",
skill_caps_link
).c_str()
);
auto static_link = Saylink::Silent("#reload static");
Message(
+3 -3
View File
@@ -815,9 +815,9 @@ public:
void SetHoTT(uint32 mobid);
void ShowSkillsWindow();
uint16 MaxSkill(EQ::skills::SkillType skillid, uint16 class_, uint16 level) const;
inline uint16 MaxSkill(EQ::skills::SkillType skillid) const { return MaxSkill(skillid, GetClass(), GetLevel()); }
uint8 SkillTrainLevel(EQ::skills::SkillType skillid, uint16 class_);
uint16 MaxSkill(EQ::skills::SkillType skill_id, uint8 class_id, uint8 level) const;
inline uint16 MaxSkill(EQ::skills::SkillType skill_id) const { return MaxSkill(skill_id, GetClass(), GetLevel()); }
uint8 SkillTrainLevel(EQ::skills::SkillType skill_id, uint8 class_id);
void MaxSkills();
void SendTradeskillSearchResults(const std::string &query, unsigned long objtype, unsigned long someid);
+5
View File
@@ -34,6 +34,7 @@ void command_reload(Client *c, const Seperator *sep)
bool is_perl_export = !strcasecmp(sep->arg[1], "perl_export");
bool is_quest = !strcasecmp(sep->arg[1], "quest") || (is_rq_alias);
bool is_rules = !strcasecmp(sep->arg[1], "rules");
bool is_skill_caps = !strcasecmp(sep->arg[1], "skill_caps");
bool is_static = !strcasecmp(sep->arg[1], "static");
bool is_tasks = !strcasecmp(sep->arg[1], "tasks");
bool is_titles = !strcasecmp(sep->arg[1], "titles");
@@ -66,6 +67,7 @@ void command_reload(Client *c, const Seperator *sep)
!is_perl_export &&
!is_quest &&
!is_rules &&
!is_skill_caps &&
!is_static &&
!is_tasks &&
!is_titles &&
@@ -161,6 +163,9 @@ void command_reload(Client *c, const Seperator *sep)
} else if (is_rules) {
c->Message(Chat::White, "Attempting to reload Rules globally.");
pack = new ServerPacket(ServerOP_ReloadRules, 0);
} else if (is_skill_caps) {
c->Message(Chat::White, "Attempting to reload Skill Caps globally.");
pack = new ServerPacket(ServerOP_ReloadSkillCaps, 0);
} else if (is_static) {
c->Message(Chat::White, "Attempting to reload Static Zone Data globally.");
pack = new ServerPacket(ServerOP_ReloadStaticZoneData, 0);
-4
View File
@@ -372,10 +372,6 @@ int main(int argc, char **argv)
LogError("Failed. But ignoring error and going on..");
}
if (!content_db.LoadSkillCaps(std::string(hotfix_name))) {
LogError("Loading skill caps failed!");
return 1;
}
if (!database.LoadSpells(hotfix_name, &SPDAT_RECORDS, &spells)) {
LogError("Loading spells failed!");
return 1;
+9 -5
View File
@@ -2097,6 +2097,15 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset(), true);
break;
}
case ServerOP_ReloadSkillCaps:
{
if (zone && zone->IsLoaded()) {
zone->SendReloadMessage("Skill Caps");
zone->ReloadSkillCaps();
}
break;
}
case ServerOP_ReloadDataBucketsCache:
{
zone->SendReloadMessage("Data buckets cache");
@@ -3563,11 +3572,6 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
LogError("Loading items failed!");
}
LogInfo("Loading skill caps");
if (!content_db.LoadSkillCaps(std::string(hotfix_name))) {
LogError("Loading skill caps failed!");
}
LogInfo("Loading spells");
if (!content_db.LoadSpells(hotfix_name, &SPDAT_RECORDS, &spells)) {
LogError("Loading spells failed!");
+2
View File
@@ -1177,6 +1177,8 @@ bool Zone::Init(bool is_static) {
LoadBaseData();
LoadSkillCaps();
//Load merchant data
LoadMerchants();
+11
View File
@@ -46,6 +46,7 @@
#include "../common/repositories/lootdrop_repository.h"
#include "../common/repositories/lootdrop_entries_repository.h"
#include "../common/repositories/base_data_repository.h"
#include "../common/repositories/skill_caps_repository.h"
struct EXPModifier
{
@@ -452,6 +453,13 @@ public:
void LoadBaseData();
void ReloadBaseData();
// Skill Caps
inline void ClearSkillCaps() { m_skill_caps.clear(); }
SkillCapsRepository::SkillCaps GetSkillCap(uint8 class_id, EQ::skills::SkillType skill_id, uint8 level);
uint8 GetTrainLevel(uint8 class_id, EQ::skills::SkillType skill_id, uint8 level);
void LoadSkillCaps();
void ReloadSkillCaps();
private:
bool allow_mercs;
bool can_bind;
@@ -515,6 +523,9 @@ private:
// Base Data
std::vector<BaseDataRepository::BaseData> m_base_data = { };
// Skill Caps
std::vector<SkillCapsRepository::SkillCaps> m_skill_caps = { };
};
#endif
+84
View File
@@ -0,0 +1,84 @@
#include "zone.h"
SkillCapsRepository::SkillCaps Zone::GetSkillCap(uint8 class_id, EQ::skills::SkillType skill_id, uint8 level)
{
if (!IsPlayerClass(class_id)) {
return SkillCapsRepository::NewEntity();
}
for (const auto& e : m_skill_caps) {
if (
e.class_id == class_id &&
e.level == level &&
static_cast<EQ::skills::SkillType>(e.skill_id) == skill_id
) {
return e;
}
}
return SkillCapsRepository::NewEntity();
}
uint8 Zone::GetTrainLevel(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 skill_cap_max_level = (
RuleI(Character, SkillCapMaxLevel) > 0 ?
RuleI(Character, SkillCapMaxLevel) :
RuleI(Character, MaxLevel)
);
const uint8 max_level = level > skill_cap_max_level ? level : skill_cap_max_level;
for (const auto& e : m_skill_caps) {
for (uint8 current_level = 1; current_level <= max_level; current_level++) {
if (
e.class_id == class_id &&
static_cast<EQ::skills::SkillType>(e.skill_id) == skill_id &&
e.level == current_level
) {
return current_level;
}
}
}
return 0;
}
void Zone::LoadSkillCaps()
{
const auto& l = SkillCapsRepository::All(content_db);
m_skill_caps.reserve(l.size());
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;
}
m_skill_caps.emplace_back(e);
}
LogInfo(
"Loaded [{}] Skill Cap Entr{}",
l.size(),
l.size() != 1 ? "ies" : "y"
);
}
void Zone::ReloadSkillCaps()
{
ClearSkillCaps();
LoadSkillCaps();
}