mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 06:21:28 +00:00
[Character] Convert Delete/Load/Remove/Save of Character AA to Repositories (#3849)
* [Character] Convert Delete/Load/Remove/Save of Character AA to Repositories - Convert `DeleteCharacterAAs`, `LoadAlternateAdvancement`, `RemoveExpendedAA` and `SaveAA` to repositories. - Add `AACategory` namespace for AA Categories. - Cleanup some logic/formatting in modified methods. * Move namespace.
This commit is contained in:
parent
aa39ac8023
commit
fd787af53a
@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_ALTERNATE_ABILITIES_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_ALTERNATE_ABILITIES_REPOSITORY_H
|
||||||
@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterAlternateAbilitiesRepository {
|
class BaseCharacterAlternateAbilitiesRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterAlternateAbilities {
|
struct CharacterAlternateAbilities {
|
||||||
@ -116,8 +117,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_alternate_abilities_id
|
character_alternate_abilities_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -348,6 +350,68 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterAlternateAbilities &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.aa_id));
|
||||||
|
v.push_back(std::to_string(e.aa_value));
|
||||||
|
v.push_back(std::to_string(e.charges));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterAlternateAbilities> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.aa_id));
|
||||||
|
v.push_back(std::to_string(e.aa_value));
|
||||||
|
v.push_back(std::to_string(e.charges));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_ALTERNATE_ABILITIES_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_ALTERNATE_ABILITIES_REPOSITORY_H
|
||||||
|
|||||||
208
zone/aa.cpp
208
zone/aa.cpp
@ -39,6 +39,8 @@ Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
|||||||
|
|
||||||
#include "bot.h"
|
#include "bot.h"
|
||||||
|
|
||||||
|
#include "../common/repositories/character_alternate_abilities_repository.h"
|
||||||
|
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
extern QueryServ* QServ;
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
@ -510,35 +512,38 @@ void Mob::WakeTheDead(uint16 spell_id, Corpse *corpse_to_use, Mob *tar, uint32 d
|
|||||||
delete made_npc;
|
delete made_npc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::ResetAA() {
|
void Client::ResetAA()
|
||||||
|
{
|
||||||
SendClearAA();
|
SendClearAA();
|
||||||
RefundAA();
|
RefundAA();
|
||||||
|
|
||||||
memset(&m_pp.aa_array[0], 0, sizeof(AA_Array) * MAX_PP_AA_ARRAY);
|
memset(&m_pp.aa_array[0], 0, sizeof(AA_Array) * MAX_PP_AA_ARRAY);
|
||||||
|
|
||||||
int i = 0;
|
int slot_id = 0;
|
||||||
for(auto &rank_value : aa_ranks) {
|
|
||||||
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(rank_value.first, rank_value.second.first);
|
|
||||||
auto ability = ability_rank.first;
|
|
||||||
auto rank = ability_rank.second;
|
|
||||||
|
|
||||||
if(!rank) {
|
for (auto& rank_value: aa_ranks) {
|
||||||
|
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(rank_value.first, rank_value.second.first);
|
||||||
|
auto ability = ability_rank.first;
|
||||||
|
auto rank = ability_rank.second;
|
||||||
|
|
||||||
|
if (!rank) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pp.aa_array[i].AA = rank_value.first;
|
m_pp.aa_array[slot_id].AA = rank_value.first;
|
||||||
m_pp.aa_array[i].value = rank_value.second.first;
|
m_pp.aa_array[slot_id].value = rank_value.second.first;
|
||||||
m_pp.aa_array[i].charges = rank_value.second.second;
|
m_pp.aa_array[slot_id].charges = rank_value.second.second;
|
||||||
++i;
|
++slot_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < _maxLeaderAA; ++i)
|
for (int slot_id = 0; slot_id < _maxLeaderAA; ++slot_id) {
|
||||||
m_pp.leader_abilities.ranks[i] = 0;
|
m_pp.leader_abilities.ranks[slot_id] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
m_pp.group_leadership_points = 0;
|
m_pp.group_leadership_points = 0;
|
||||||
m_pp.raid_leadership_points = 0;
|
m_pp.raid_leadership_points = 0;
|
||||||
m_pp.group_leadership_exp = 0;
|
m_pp.group_leadership_exp = 0;
|
||||||
m_pp.raid_leadership_exp = 0;
|
m_pp.raid_leadership_exp = 0;
|
||||||
|
|
||||||
database.DeleteCharacterAAs(CharacterID());
|
database.DeleteCharacterAAs(CharacterID());
|
||||||
database.DeleteCharacterLeadershipAbilities(CharacterID());
|
database.DeleteCharacterLeadershipAbilities(CharacterID());
|
||||||
@ -833,31 +838,31 @@ void Client::RefundAA() {
|
|||||||
int refunded = 0;
|
int refunded = 0;
|
||||||
|
|
||||||
auto rank_value = aa_ranks.begin();
|
auto rank_value = aa_ranks.begin();
|
||||||
while(rank_value != aa_ranks.end()) {
|
while (rank_value != aa_ranks.end()) {
|
||||||
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(rank_value->first, rank_value->second.first);
|
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(rank_value->first, rank_value->second.first);
|
||||||
auto ability = ability_rank.first;
|
auto ability = ability_rank.first;
|
||||||
auto rank = ability_rank.second;
|
auto rank = ability_rank.second;
|
||||||
|
|
||||||
if(!ability) {
|
if (!ability) {
|
||||||
++rank_value;
|
++rank_value;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ability->charges > 0 && rank_value->second.second < 1) {
|
if (ability->charges > 0 && rank_value->second.second < 1) {
|
||||||
++rank_value;
|
++rank_value;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ability->grant_only) {
|
if (ability->grant_only) {
|
||||||
++rank_value;
|
++rank_value;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
refunded += rank->total_cost;
|
refunded += rank->total_cost;
|
||||||
rank_value = aa_ranks.erase(rank_value);
|
rank_value = aa_ranks.erase(rank_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(refunded > 0) {
|
if (refunded > 0) {
|
||||||
m_pp.aapoints += refunded;
|
m_pp.aapoints += refunded;
|
||||||
SaveAA();
|
SaveAA();
|
||||||
Save();
|
Save();
|
||||||
@ -1438,40 +1443,42 @@ void Mob::ExpendAlternateAdvancementCharge(uint32 aa_id) {
|
|||||||
|
|
||||||
bool ZoneDatabase::LoadAlternateAdvancement(Client *c) {
|
bool ZoneDatabase::LoadAlternateAdvancement(Client *c) {
|
||||||
c->ClearAAs();
|
c->ClearAAs();
|
||||||
std::string query = StringFormat(
|
|
||||||
"SELECT "
|
|
||||||
"aa_id, "
|
|
||||||
"aa_value, "
|
|
||||||
"charges "
|
|
||||||
"FROM "
|
|
||||||
"`character_alternate_abilities` "
|
|
||||||
"WHERE `id` = %u", c->CharacterID());
|
|
||||||
MySQLRequestResult results = database.QueryDatabase(query);
|
|
||||||
|
|
||||||
int i = 0;
|
const auto& l = CharacterAlternateAbilitiesRepository::GetWhere(
|
||||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
database,
|
||||||
uint32 aa = Strings::ToUnsignedInt(row[0]);
|
fmt::format(
|
||||||
uint32 value = Strings::ToUnsignedInt(row[1]);
|
"`id` = {}",
|
||||||
uint32 charges = Strings::ToUnsignedInt(row[2]);
|
c->CharacterID()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
auto rank = zone->GetAlternateAdvancementRank(aa);
|
uint32 slot_id = 0;
|
||||||
if(!rank) {
|
|
||||||
|
for (const auto& e : l) {
|
||||||
|
const uint16 aa_id = e.aa_id;
|
||||||
|
const uint16 aa_value = e.aa_value;
|
||||||
|
const uint16 charges = e.charges;
|
||||||
|
|
||||||
|
auto rank = zone->GetAlternateAdvancementRank(aa_id);
|
||||||
|
if (!rank) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ability = rank->base_ability;
|
auto ability = rank->base_ability;
|
||||||
if(!ability) {
|
if (!ability) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rank = ability->GetRankByPointsSpent(value);
|
rank = ability->GetRankByPointsSpent(aa_value);
|
||||||
|
|
||||||
if(c->CanUseAlternateAdvancementRank(rank)) {
|
if (c->CanUseAlternateAdvancementRank(rank)) {
|
||||||
c->GetPP().aa_array[i].AA = aa;
|
c->GetPP().aa_array[slot_id].AA = aa_id;
|
||||||
c->GetPP().aa_array[i].value = value;
|
c->GetPP().aa_array[slot_id].value = aa_value;
|
||||||
c->GetPP().aa_array[i].charges = charges;
|
c->GetPP().aa_array[slot_id].charges = charges;
|
||||||
c->SetAA(aa, value, charges);
|
|
||||||
i++;
|
c->SetAA(aa_id, aa_value, charges);
|
||||||
|
|
||||||
|
slot_id++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1556,56 +1563,61 @@ uint32 Mob::GetAAByAAID(uint32 aa_id, uint32 *charges) const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::SetAA(uint32 rank_id, uint32 new_value, uint32 charges) {
|
bool Mob::SetAA(uint32 rank_id, uint32 new_value, uint32 charges)
|
||||||
if(zone) {
|
{
|
||||||
AA::Ability *ability = zone->GetAlternateAdvancementAbilityByRank(rank_id);
|
if (zone) {
|
||||||
|
auto a = zone->GetAlternateAdvancementAbilityByRank(rank_id);
|
||||||
|
|
||||||
if(!ability) {
|
if (!a) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(new_value > ability->GetMaxLevel(this)) {
|
if(new_value > a->GetMaxLevel(this)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
aa_ranks[ability->id] = std::make_pair(new_value, charges);
|
aa_ranks[a->id] = std::make_pair(new_value, charges);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
|
bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank)
|
||||||
|
{
|
||||||
if (!rank) {
|
if (!rank) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AA::Ability *ability = rank->base_ability;
|
const auto a = rank->base_ability;
|
||||||
|
|
||||||
if(!ability)
|
if (!a) {
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!(ability->classes & (1 << GetClass()))) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Passive and Active Shroud AAs
|
if (!(a->classes & (1 << GetClass()))) {
|
||||||
// For now we skip them
|
return false;
|
||||||
if(ability->category == 3 || ability->category == 4) {
|
}
|
||||||
|
|
||||||
|
// Passive and Active Shroud AAs, skip for now
|
||||||
|
if (
|
||||||
|
a->category == AACategory::ShroudPassive ||
|
||||||
|
a->category == AACategory::ShroudActive
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//the one titanium hack i will allow
|
//the one titanium hack i will allow
|
||||||
//just to make sure we dont crash the client with newer aas
|
//just to make sure we dont crash the client with newer aas
|
||||||
//we'll exclude any expendable ones
|
//we'll exclude any expendable ones
|
||||||
if(IsClient() && CastToClient()->ClientVersionBit() & EQ::versions::maskTitaniumAndEarlier) {
|
if (IsClient() && CastToClient()->ClientVersionBit() & EQ::versions::maskTitaniumAndEarlier) {
|
||||||
if(ability->charges > 0) {
|
if (a->charges > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int expansion = RuleI(Expansion, CurrentExpansion);
|
const int expansion = RuleI(Expansion, CurrentExpansion);
|
||||||
bool use_expansion_aa = RuleB(Expansion, UseCurrentExpansionAAOnly);
|
const bool use_expansion_aa = RuleB(Expansion, UseCurrentExpansionAAOnly);
|
||||||
if (use_expansion_aa && expansion >= 0) {
|
if (use_expansion_aa && expansion >= 0) {
|
||||||
if (rank->expansion > expansion) {
|
if (rank->expansion > expansion) {
|
||||||
return false;
|
return false;
|
||||||
@ -1617,36 +1629,35 @@ bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
|
|||||||
if (rank->expansion && !(CastToClient()->GetPP().expansions & (1 << (rank->expansion - 1)))) {
|
if (rank->expansion && !(CastToClient()->GetPP().expansions & (1 << (rank->expansion - 1)))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (IsBot()) {
|
||||||
else if (IsBot()) {
|
|
||||||
if (rank->expansion && !(CastToBot()->GetExpansionBitmask() & (1 << (rank->expansion - 1)))) {
|
if (rank->expansion && !(CastToBot()->GetExpansionBitmask() & (1 << (rank->expansion - 1)))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (rank->expansion && !(RuleI(World, ExpansionSettings) & (1 << (rank->expansion - 1)))) {
|
if (rank->expansion && !(RuleI(World, ExpansionSettings) & (1 << (rank->expansion - 1)))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto race = GetPlayerRaceValue(GetBaseRace());
|
auto race = GetPlayerRaceValue(GetBaseRace());
|
||||||
race = race > 16 ? 1 : race;
|
|
||||||
if(!(ability->races & (1 << (race - 1)))) {
|
race = race > PLAYER_RACE_COUNT ? Race::Human : race;
|
||||||
|
|
||||||
|
if (!(a->races & (1 << (race - 1)))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto deity = GetDeityBit();
|
const auto deity = GetDeityBit();
|
||||||
if(!(ability->deities & deity)) {
|
if (!(a->deities & deity)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsClient() && CastToClient()->Admin() < ability->status) {
|
if (IsClient() && CastToClient()->Admin() < a->status) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetBaseRace() == 522) {
|
if (GetBaseRace() == Race::Drakkin) {
|
||||||
//drakkin_heritage
|
if (!(a->drakkin_heritage & (1 << GetDrakkinHeritage()))) {
|
||||||
if(!(ability->drakkin_heritage & (1 << GetDrakkinHeritage()))) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1654,13 +1665,15 @@ bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price, bool check_grant) {
|
bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price, bool check_grant)
|
||||||
AA::Ability *ability = rank->base_ability;
|
{
|
||||||
|
auto a = rank->base_ability;
|
||||||
|
|
||||||
if(!ability)
|
if (!a) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(!CanUseAlternateAdvancementRank(rank)) {
|
if (!CanUseAlternateAdvancementRank(rank)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1668,54 +1681,53 @@ bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//You can't purchase grant only AAs they can only be assigned
|
// You cannot purchase grant only AAs they can only be assigned
|
||||||
if(check_grant && ability->grant_only) {
|
if (check_grant && a->grant_only) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check level req
|
if (rank->level_req > GetLevel()) {
|
||||||
if(rank->level_req > GetLevel()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 current_charges = 0;
|
uint32 current_charges = 0;
|
||||||
auto points = GetAA(rank->id, ¤t_charges);
|
const uint32 points = GetAA(rank->id, ¤t_charges);
|
||||||
|
|
||||||
//check that we are on previous rank already (if exists)
|
//check that we are on previous rank already (if exists)
|
||||||
//grant ignores the req to own the previous rank.
|
//grant ignores the req to own the previous rank.
|
||||||
if(check_grant && rank->prev) {
|
if (check_grant && rank->prev) {
|
||||||
if(points != rank->prev->current_value) {
|
if (points != rank->prev->current_value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//check that we aren't already on this rank or one ahead of us
|
//check that we aren't already on this rank or one ahead of us
|
||||||
if(points >= rank->current_value) {
|
if (points >= rank->current_value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if expendable only let us purchase if we have no charges already
|
//if expendable only let us purchase if we have no charges already
|
||||||
//not quite sure on how this functions client side atm
|
//not quite sure on how this functions client side atm
|
||||||
//I intend to look into it later to make sure the behavior is right
|
//I intend to look into it later to make sure the behavior is right
|
||||||
if(ability->charges > 0 && current_charges > 0) {
|
if (a->charges > 0 && current_charges > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check prereqs
|
//check prereqs
|
||||||
for(auto &prereq : rank->prereqs) {
|
for (auto &prereq: rank->prereqs) {
|
||||||
AA::Ability *prereq_ability = zone->GetAlternateAdvancementAbility(prereq.first);
|
AA::Ability *prereq_ability = zone->GetAlternateAdvancementAbility(prereq.first);
|
||||||
|
|
||||||
if(prereq_ability) {
|
if (prereq_ability) {
|
||||||
auto ranks = GetAA(prereq_ability->first_rank_id);
|
auto ranks = GetAA(prereq_ability->first_rank_id);
|
||||||
if(ranks < prereq.second) {
|
if (ranks < prereq.second) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//check price, if client
|
//check price, if client
|
||||||
if(check_price && IsClient()) {
|
if (check_price && IsClient()) {
|
||||||
if(rank->cost > CastToClient()->GetAAPoints()) {
|
if (rank->cost > CastToClient()->GetAAPoints()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
zone/aa.h
13
zone/aa.h
@ -1525,6 +1525,19 @@ enum { //values of AA_Action.action
|
|||||||
aaActionBuy = 3
|
aaActionBuy = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace AACategory {
|
||||||
|
constexpr int None = -1;
|
||||||
|
constexpr int Passive = 1;
|
||||||
|
constexpr int Progression = 2;
|
||||||
|
constexpr int ShroudPassive = 3;
|
||||||
|
constexpr int ShroudActive = 4;
|
||||||
|
constexpr int VeteranReward = 5;
|
||||||
|
constexpr int Tradeskill = 6;
|
||||||
|
constexpr int Expendable = 7;
|
||||||
|
constexpr int RacialInnate = 8;
|
||||||
|
constexpr int EverQuest = 9;
|
||||||
|
}
|
||||||
|
|
||||||
class Timer;
|
class Timer;
|
||||||
class Mob;
|
class Mob;
|
||||||
class SwarmPet {
|
class SwarmPet {
|
||||||
|
|||||||
@ -58,6 +58,7 @@ extern volatile bool RunLoops;
|
|||||||
#include "mob_movement_manager.h"
|
#include "mob_movement_manager.h"
|
||||||
#include "cheat_manager.h"
|
#include "cheat_manager.h"
|
||||||
|
|
||||||
|
#include "../common/repositories/character_alternate_abilities_repository.h"
|
||||||
#include "../common/repositories/account_flags_repository.h"
|
#include "../common/repositories/account_flags_repository.h"
|
||||||
#include "../common/repositories/bug_reports_repository.h"
|
#include "../common/repositories/bug_reports_repository.h"
|
||||||
#include "../common/repositories/char_recipe_list_repository.h"
|
#include "../common/repositories/char_recipe_list_repository.h"
|
||||||
@ -586,45 +587,52 @@ void Client::ReportConnectingState() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::SaveAA() {
|
bool Client::SaveAA()
|
||||||
std::string iquery;
|
{
|
||||||
int spentpoints = 0;
|
std::vector<CharacterAlternateAbilitiesRepository::CharacterAlternateAbilities> v;
|
||||||
int i = 0;
|
|
||||||
for(auto &rank : aa_ranks) {
|
uint32 aa_points_spent = 0;
|
||||||
AA::Ability *ability = zone->GetAlternateAdvancementAbility(rank.first);
|
|
||||||
if(!ability)
|
auto e = CharacterAlternateAbilitiesRepository::NewEntity();
|
||||||
|
|
||||||
|
for (auto &rank : aa_ranks) {
|
||||||
|
auto a = zone->GetAlternateAdvancementAbility(rank.first);
|
||||||
|
if (!a) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(rank.second.first > 0) {
|
if (rank.second.first > 0) {
|
||||||
AA::Rank *r = ability->GetRankByPointsSpent(rank.second.first);
|
auto r = a->GetRankByPointsSpent(rank.second.first);
|
||||||
|
if (!r) {
|
||||||
if(!r)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
spentpoints += r->total_cost;
|
|
||||||
|
|
||||||
if(i == 0) {
|
|
||||||
iquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, aa_id, aa_value, charges)"
|
|
||||||
" VALUES (%u, %u, %u, %u)", character_id, ability->first_rank_id, rank.second.first, rank.second.second);
|
|
||||||
} else {
|
|
||||||
iquery += StringFormat(", (%u, %u, %u, %u)", character_id, ability->first_rank_id, rank.second.first, rank.second.second);
|
|
||||||
}
|
}
|
||||||
i++;
|
|
||||||
|
aa_points_spent += r->total_cost;
|
||||||
|
|
||||||
|
e.id = character_id;
|
||||||
|
e.aa_id = a->first_rank_id;
|
||||||
|
e.aa_value = rank.second.first;
|
||||||
|
e.charges = rank.second.second;
|
||||||
|
|
||||||
|
v.emplace_back(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pp.aapoints_spent = spentpoints + m_epp.expended_aa;
|
m_pp.aapoints_spent = aa_points_spent + m_epp.expended_aa;
|
||||||
|
|
||||||
if(iquery.length() > 0) {
|
return CharacterAlternateAbilitiesRepository::ReplaceMany(database, v);
|
||||||
database.QueryDatabase(iquery);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::RemoveExpendedAA(int aa_id)
|
void Client::RemoveExpendedAA(int aa_id)
|
||||||
{
|
{
|
||||||
database.QueryDatabase(StringFormat("DELETE from `character_alternate_abilities` WHERE `id` = %d and `aa_id` = %d", character_id, aa_id));
|
CharacterAlternateAbilitiesRepository::DeleteWhere(
|
||||||
|
database,
|
||||||
|
fmt::format(
|
||||||
|
"`id` = {} AND `aa_id` = {}",
|
||||||
|
CharacterID(),
|
||||||
|
aa_id
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::Save(uint8 iCommitNow) {
|
bool Client::Save(uint8 iCommitNow) {
|
||||||
|
|||||||
@ -32,6 +32,7 @@
|
|||||||
#include "../common/repositories/character_potionbelt_repository.h"
|
#include "../common/repositories/character_potionbelt_repository.h"
|
||||||
#include "../common/repositories/character_bandolier_repository.h"
|
#include "../common/repositories/character_bandolier_repository.h"
|
||||||
#include "../common/repositories/character_currency_repository.h"
|
#include "../common/repositories/character_currency_repository.h"
|
||||||
|
#include "../common/repositories/character_alternate_abilities_repository.h"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -1272,15 +1273,6 @@ bool ZoneDatabase::SaveCharacterCurrency(uint32 character_id, PlayerProfile_Stru
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level, uint32 charges){
|
|
||||||
std::string rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, aa_id, aa_value, charges)"
|
|
||||||
" VALUES (%u, %u, %u, %u)",
|
|
||||||
character_id, aa_id, current_level, charges);
|
|
||||||
auto results = QueryDatabase(rquery);
|
|
||||||
LogDebug("Saving AA for character ID: [{}], aa_id: [{}] current_level: [{}]", character_id, aa_id, current_level);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ZoneDatabase::SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id){
|
bool ZoneDatabase::SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id){
|
||||||
if (!IsValidSpell(spell_id)) {
|
if (!IsValidSpell(spell_id)) {
|
||||||
return false;
|
return false;
|
||||||
@ -1347,10 +1339,15 @@ bool ZoneDatabase::DeleteCharacterLeadershipAbilities(uint32 character_id)
|
|||||||
return CharacterLeadershipAbilitiesRepository::DeleteOne(*this, character_id);
|
return CharacterLeadershipAbilitiesRepository::DeleteOne(*this, character_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::DeleteCharacterAAs(uint32 character_id){
|
bool ZoneDatabase::DeleteCharacterAAs(uint32 character_id)
|
||||||
std::string query = StringFormat("DELETE FROM `character_alternate_abilities` WHERE `id` = %u AND `aa_id` NOT IN(SELECT a.first_rank_id FROM aa_ability a WHERE a.grant_only != 0)", character_id);
|
{
|
||||||
QueryDatabase(query);
|
return CharacterAlternateAbilitiesRepository::DeleteWhere(
|
||||||
return true;
|
*this,
|
||||||
|
fmt::format(
|
||||||
|
"`id` = {} AND `aa_id` NOT IN (SELECT a.first_rank_id FROM aa_ability a WHERE a.grant_only != 0)",
|
||||||
|
character_id
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::DeleteCharacterMaterialColor(uint32 character_id)
|
bool ZoneDatabase::DeleteCharacterMaterialColor(uint32 character_id)
|
||||||
|
|||||||
@ -444,7 +444,6 @@ public:
|
|||||||
bool LoadCharacterSkills(uint32 character_id, PlayerProfile_Struct* pp);
|
bool LoadCharacterSkills(uint32 character_id, PlayerProfile_Struct* pp);
|
||||||
bool LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Struct* pp);
|
bool LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Struct* pp);
|
||||||
|
|
||||||
bool SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level, uint32 charges);
|
|
||||||
bool SaveCharacterBandolier(uint32 character_id, uint8 bandolier_id, uint8 bandolier_slot, uint32 item_id, uint32 icon, const char* bandolier_name);
|
bool SaveCharacterBandolier(uint32 character_id, uint8 bandolier_id, uint8 bandolier_slot, uint32 item_id, uint32 icon, const char* bandolier_name);
|
||||||
bool SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp);
|
bool SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp);
|
||||||
bool SaveCharacterData(Client* c, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp);
|
bool SaveCharacterData(Client* c, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user