mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-04 18:46:37 +00:00
[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:
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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!");
|
||||
|
||||
@@ -1177,6 +1177,8 @@ bool Zone::Init(bool is_static) {
|
||||
|
||||
LoadBaseData();
|
||||
|
||||
LoadSkillCaps();
|
||||
|
||||
//Load merchant data
|
||||
LoadMerchants();
|
||||
|
||||
|
||||
+11
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user