mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 14:41:28 +00:00
[Fixes] AA System Fixes (#3572)
* -Always load AAs beyond our current expansion (Will need this for refunding invalid AAs). -AAs beyond our current expansion will no longer be buyable or sendable to clients. * #reload aa will now reload character aa data. * Base Implementation of auto grant AA * -Add DB manifest entry -Made has already purchased fn a bit better -Added auto grant to db entry * -Added grantaa command. -Reworked grantaa to not spam the client with packets, it still does spam messages because the feedback is important. * Port suggested changes for Finish AA purchase. --------- Co-authored-by: KimLS <KimLS@peqtgc.com>
This commit is contained in:
parent
e85a8db8c4
commit
d3a414a048
@ -4930,6 +4930,17 @@ CREATE TABLE `character_stats_record` (
|
|||||||
`updated_at` datetime DEFAULT NULL,
|
`updated_at` datetime DEFAULT NULL,
|
||||||
PRIMARY KEY (`character_id`)
|
PRIMARY KEY (`character_id`)
|
||||||
);
|
);
|
||||||
|
)"
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9236,
|
||||||
|
.description = "2023_08_24_aa_ability_auto_grant.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `aa_ability` LIKE 'auto_grant_enabled';",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `aa_ability` ADD COLUMN `auto_grant_enabled` TINYINT(4) NOT NULL DEFAULT '0' AFTER `reset_on_death`;
|
||||||
|
UPDATE `aa_ability` SET `auto_grant_enabled` = 1 WHERE `grant_only` = 0 AND `charges` = 0 AND `category` = -1;
|
||||||
)"
|
)"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -820,6 +820,7 @@ RULE_CATEGORY_END()
|
|||||||
RULE_CATEGORY(Expansion)
|
RULE_CATEGORY(Expansion)
|
||||||
RULE_INT(Expansion, CurrentExpansion, -1, "The current expansion enabled for the server [-1 = ALL, 0 = Classic, 1 = Kunark etc.]")
|
RULE_INT(Expansion, CurrentExpansion, -1, "The current expansion enabled for the server [-1 = ALL, 0 = Classic, 1 = Kunark etc.]")
|
||||||
RULE_BOOL(Expansion, UseCurrentExpansionAAOnly, false, "When true will only load AA ranks that match CurrentExpansion rule")
|
RULE_BOOL(Expansion, UseCurrentExpansionAAOnly, false, "When true will only load AA ranks that match CurrentExpansion rule")
|
||||||
|
RULE_INT(Expansion, AutoGrantAAExpansion, -1, "Expansion to auto grant AAs up to, [-1 = Disabled, 0 = Classic, 1 = Kunark etc.]")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Instances)
|
RULE_CATEGORY(Instances)
|
||||||
|
|||||||
167
zone/aa.cpp
167
zone/aa.cpp
@ -1111,7 +1111,7 @@ void Client::PurchaseAlternateAdvancementRank(int rank_id) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FinishAlternateAdvancementPurchase(rank, false);
|
FinishAlternateAdvancementPurchase(rank, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost) {
|
bool Client::GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost) {
|
||||||
@ -1134,13 +1134,13 @@ bool Client::GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
FinishAlternateAdvancementPurchase(rank, ignore_cost);
|
FinishAlternateAdvancementPurchase(rank, ignore_cost, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost) {
|
void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost, bool send_message_and_save) {
|
||||||
auto rank_id = rank->base_ability->first_rank_id;
|
auto rank_id = rank->base_ability->first_rank_id;
|
||||||
|
|
||||||
if (rank->base_ability->charges) {
|
if (rank->base_ability->charges) {
|
||||||
@ -1156,7 +1156,7 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost
|
|||||||
SetAA(rank_id, rank->current_value, 0);
|
SetAA(rank_id, rank->current_value, 0);
|
||||||
|
|
||||||
//if not max then send next aa
|
//if not max then send next aa
|
||||||
if (rank->next) {
|
if (rank->next && send_message_and_save) {
|
||||||
SendAlternateAdvancementRank(rank->base_ability->id, rank->next->current_value);
|
SendAlternateAdvancementRank(rank->base_ability->id, rank->next->current_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1164,10 +1164,12 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost
|
|||||||
auto cost = !ignore_cost ? rank->cost : 0;
|
auto cost = !ignore_cost ? rank->cost : 0;
|
||||||
|
|
||||||
m_pp.aapoints -= static_cast<uint32>(cost);
|
m_pp.aapoints -= static_cast<uint32>(cost);
|
||||||
SaveAA();
|
|
||||||
|
|
||||||
|
if (send_message_and_save) {
|
||||||
|
SaveAA();
|
||||||
SendAlternateAdvancementPoints();
|
SendAlternateAdvancementPoints();
|
||||||
SendAlternateAdvancementStats();
|
SendAlternateAdvancementStats();
|
||||||
|
}
|
||||||
|
|
||||||
if (player_event_logs.IsEventEnabled(PlayerEvent::AA_PURCHASE)) {
|
if (player_event_logs.IsEventEnabled(PlayerEvent::AA_PURCHASE)) {
|
||||||
auto e = PlayerEvent::AAPurchasedEvent{
|
auto e = PlayerEvent::AAPurchasedEvent{
|
||||||
@ -1181,6 +1183,7 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rank->prev) {
|
if (rank->prev) {
|
||||||
|
if (send_message_and_save) {
|
||||||
MessageString(
|
MessageString(
|
||||||
Chat::Yellow,
|
Chat::Yellow,
|
||||||
AA_IMPROVE,
|
AA_IMPROVE,
|
||||||
@ -1189,6 +1192,7 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost
|
|||||||
std::to_string(cost).c_str(),
|
std::to_string(cost).c_str(),
|
||||||
cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()
|
cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/* QS: Player_Log_AA_Purchases */
|
/* QS: Player_Log_AA_Purchases */
|
||||||
if (RuleB(QueryServ, PlayerLogAAPurchases)) {
|
if (RuleB(QueryServ, PlayerLogAAPurchases)) {
|
||||||
@ -1203,6 +1207,7 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost
|
|||||||
QServ->PlayerLogEvent(Player_Log_AA_Purchases, CharacterID(), event_desc);
|
QServ->PlayerLogEvent(Player_Log_AA_Purchases, CharacterID(), event_desc);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (send_message_and_save) {
|
||||||
MessageString(
|
MessageString(
|
||||||
Chat::Yellow,
|
Chat::Yellow,
|
||||||
AA_GAIN_ABILITY,
|
AA_GAIN_ABILITY,
|
||||||
@ -1210,6 +1215,7 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost
|
|||||||
std::to_string(cost).c_str(),
|
std::to_string(cost).c_str(),
|
||||||
cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()
|
cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/* QS: Player_Log_AA_Purchases */
|
/* QS: Player_Log_AA_Purchases */
|
||||||
if (RuleB(QueryServ, PlayerLogAAPurchases)) {
|
if (RuleB(QueryServ, PlayerLogAAPurchases)) {
|
||||||
@ -1594,6 +1600,15 @@ bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int expansion = RuleI(Expansion, CurrentExpansion);
|
||||||
|
bool use_expansion_aa = RuleB(Expansion, UseCurrentExpansionAAOnly);
|
||||||
|
if (use_expansion_aa && expansion >= 0) {
|
||||||
|
if (rank->expansion > expansion) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (IsClient()) {
|
if (IsClient()) {
|
||||||
if (rank->expansion && !(CastToClient()->GetPP().expansions & (1 << (rank->expansion - 1)))) {
|
if (rank->expansion && !(CastToClient()->GetPP().expansions & (1 << (rank->expansion - 1)))) {
|
||||||
return false;
|
return false;
|
||||||
@ -1645,6 +1660,10 @@ bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsClient() && CastToClient()->HasAlreadyPurchasedRank(rank)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//You can't purchase grant only AAs they can only be assigned
|
//You can't purchase grant only AAs they can only be assigned
|
||||||
if(check_grant && ability->grant_only) {
|
if(check_grant && ability->grant_only) {
|
||||||
return false;
|
return false;
|
||||||
@ -1764,7 +1783,7 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
|
|||||||
{
|
{
|
||||||
abilities.clear();
|
abilities.clear();
|
||||||
std::string query = "SELECT id, name, category, classes, races, deities, drakkin_heritage, status, type, charges, "
|
std::string query = "SELECT id, name, category, classes, races, deities, drakkin_heritage, status, type, charges, "
|
||||||
"grant_only, reset_on_death, first_rank_id FROM aa_ability WHERE enabled = 1";
|
"grant_only, reset_on_death, auto_grant_enabled, first_rank_id FROM aa_ability WHERE enabled = 1";
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if(results.Success()) {
|
if(results.Success()) {
|
||||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||||
@ -1782,7 +1801,8 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
|
|||||||
ability->charges = Strings::ToInt(row[9]);
|
ability->charges = Strings::ToInt(row[9]);
|
||||||
ability->grant_only = Strings::ToBool(row[10]);
|
ability->grant_only = Strings::ToBool(row[10]);
|
||||||
ability->reset_on_death = Strings::ToBool(row[11]);
|
ability->reset_on_death = Strings::ToBool(row[11]);
|
||||||
ability->first_rank_id = Strings::ToInt(row[12]);
|
ability->auto_grant_enabled = Strings::ToBool(row[12]);
|
||||||
|
ability->first_rank_id = Strings::ToInt(row[13]);
|
||||||
ability->first = nullptr;
|
ability->first = nullptr;
|
||||||
|
|
||||||
abilities[ability->id] = std::unique_ptr<AA::Ability>(ability);
|
abilities[ability->id] = std::unique_ptr<AA::Ability>(ability);
|
||||||
@ -1793,17 +1813,11 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("Loaded [{}] Alternate Advancement Abilities", Strings::Commify((int)abilities.size()));
|
LogInfo("Loaded [{}] Alternate Advancement Abilities", Strings::Commify((int)abilities.size()));
|
||||||
int expansion = RuleI(Expansion, CurrentExpansion);
|
|
||||||
bool use_expansion_aa = RuleB(Expansion, UseCurrentExpansionAAOnly);
|
|
||||||
|
|
||||||
ranks.clear();
|
ranks.clear();
|
||||||
if (use_expansion_aa && expansion >= 0) {
|
|
||||||
query = fmt::format("SELECT id, upper_hotkey_sid, lower_hotkey_sid, title_sid, desc_sid, cost, level_req, spell, spell_type, recast_time, "
|
|
||||||
"next_id, expansion FROM aa_ranks WHERE expansion <= {}", expansion);
|
|
||||||
} else {
|
|
||||||
query = "SELECT id, upper_hotkey_sid, lower_hotkey_sid, title_sid, desc_sid, cost, level_req, spell, spell_type, recast_time, "
|
query = "SELECT id, upper_hotkey_sid, lower_hotkey_sid, title_sid, desc_sid, cost, level_req, spell, spell_type, recast_time, "
|
||||||
"next_id, expansion FROM aa_ranks";
|
"next_id, expansion FROM aa_ranks";
|
||||||
}
|
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
if(results.Success()) {
|
if(results.Success()) {
|
||||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||||
@ -2068,3 +2082,126 @@ void Client::TogglePurchaseAlternativeAdvancementRank(int rank_id){
|
|||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::AutoGrantAAPoints() {
|
||||||
|
int auto_grant_expansion = RuleI(Expansion, AutoGrantAAExpansion);
|
||||||
|
|
||||||
|
if (auto_grant_expansion == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//iterate through every AA
|
||||||
|
for (auto& iter : zone->aa_abilities) {
|
||||||
|
auto ability = iter.second.get();
|
||||||
|
|
||||||
|
if (ability->grant_only) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ability->charges > 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ability->auto_grant_enabled) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto level = GetLevel();
|
||||||
|
auto p = 1;
|
||||||
|
auto rank = ability->first;
|
||||||
|
while (rank != nullptr) {
|
||||||
|
if (CanUseAlternateAdvancementRank(rank)) {
|
||||||
|
if (rank->expansion <= auto_grant_expansion && rank->level_req <= level && !HasAlreadyPurchasedRank(rank)) {
|
||||||
|
FinishAlternateAdvancementPurchase(rank, true, false);
|
||||||
|
|
||||||
|
if (rank->prev) {
|
||||||
|
MessageString(
|
||||||
|
Chat::Yellow,
|
||||||
|
AA_IMPROVE,
|
||||||
|
std::to_string(rank->title_sid).c_str(),
|
||||||
|
std::to_string(rank->prev->current_value).c_str(),
|
||||||
|
"0",
|
||||||
|
std::to_string(AA_POINTS).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MessageString(
|
||||||
|
Chat::Yellow,
|
||||||
|
AA_GAIN_ABILITY,
|
||||||
|
std::to_string(rank->title_sid).c_str(),
|
||||||
|
"0",
|
||||||
|
std::to_string(AA_POINTS).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
p++;
|
||||||
|
rank = rank->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SendClearAA();
|
||||||
|
SendAlternateAdvancementTable();
|
||||||
|
SendAlternateAdvancementPoints();
|
||||||
|
SendAlternateAdvancementStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::GrantAllAAPoints()
|
||||||
|
{
|
||||||
|
//iterate through every AA
|
||||||
|
for (auto& iter : zone->aa_abilities) {
|
||||||
|
auto ability = iter.second.get();
|
||||||
|
|
||||||
|
if (ability->charges > 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto level = GetLevel();
|
||||||
|
auto p = 1;
|
||||||
|
auto rank = ability->first;
|
||||||
|
while (rank != nullptr) {
|
||||||
|
if (CanUseAlternateAdvancementRank(rank)) {
|
||||||
|
if (rank->level_req <= level && !HasAlreadyPurchasedRank(rank)) {
|
||||||
|
FinishAlternateAdvancementPurchase(rank, true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
p++;
|
||||||
|
rank = rank->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveAA();
|
||||||
|
SendClearAA();
|
||||||
|
SendAlternateAdvancementTable();
|
||||||
|
SendAlternateAdvancementPoints();
|
||||||
|
SendAlternateAdvancementStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Client::HasAlreadyPurchasedRank(AA::Rank *rank) {
|
||||||
|
auto iter = aa_ranks.find(rank->base_ability->id);
|
||||||
|
|
||||||
|
if (iter == aa_ranks.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(iter->first, iter->second.first);
|
||||||
|
auto ability = ability_rank.first;
|
||||||
|
auto current = ability_rank.second;
|
||||||
|
|
||||||
|
while (current != nullptr) {
|
||||||
|
if (current == rank) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@ -50,6 +50,7 @@ public:
|
|||||||
int status;
|
int status;
|
||||||
bool grant_only;
|
bool grant_only;
|
||||||
bool reset_on_death;
|
bool reset_on_death;
|
||||||
|
bool auto_grant_enabled;
|
||||||
int type;
|
int type;
|
||||||
int charges;
|
int charges;
|
||||||
int first_rank_id;
|
int first_rank_id;
|
||||||
|
|||||||
@ -905,6 +905,9 @@ public:
|
|||||||
int GetAAPoints() { return m_pp.aapoints; }
|
int GetAAPoints() { return m_pp.aapoints; }
|
||||||
int GetSpentAA() { return m_pp.aapoints_spent; }
|
int GetSpentAA() { return m_pp.aapoints_spent; }
|
||||||
uint32 GetRequiredAAExperience();
|
uint32 GetRequiredAAExperience();
|
||||||
|
void AutoGrantAAPoints();
|
||||||
|
void GrantAllAAPoints();
|
||||||
|
bool HasAlreadyPurchasedRank(AA::Rank* rank);
|
||||||
|
|
||||||
bool SendGMCommand(std::string message, bool ignore_status = false);
|
bool SendGMCommand(std::string message, bool ignore_status = false);
|
||||||
|
|
||||||
@ -1662,7 +1665,7 @@ protected:
|
|||||||
bool client_data_loaded;
|
bool client_data_loaded;
|
||||||
|
|
||||||
|
|
||||||
void FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost);
|
void FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost, bool send_message_and_save);
|
||||||
|
|
||||||
Mob* bind_sight_target;
|
Mob* bind_sight_target;
|
||||||
|
|
||||||
|
|||||||
@ -918,6 +918,8 @@ void Client::CompleteConnect()
|
|||||||
|
|
||||||
RecordStats();
|
RecordStats();
|
||||||
|
|
||||||
|
AutoGrantAAPoints();
|
||||||
|
|
||||||
// enforce some rules..
|
// enforce some rules..
|
||||||
if (!CanEnterZone()) {
|
if (!CanEnterZone()) {
|
||||||
LogInfo("Kicking character [{}] from zone, not allowed here (missing requirements)", GetCleanName());
|
LogInfo("Kicking character [{}] from zone, not allowed here (missing requirements)", GetCleanName());
|
||||||
|
|||||||
@ -137,6 +137,7 @@ int command_init(void)
|
|||||||
command_add("givemoney", "[Platinum] [Gold] [Silver] [Copper] - Gives specified amount of money to you or your player target", AccountStatus::GMMgmt, command_givemoney) ||
|
command_add("givemoney", "[Platinum] [Gold] [Silver] [Copper] - Gives specified amount of money to you or your player target", AccountStatus::GMMgmt, command_givemoney) ||
|
||||||
command_add("gmzone", "[Zone ID|Zone Short Name] [Version] [Instance Identifier] - Zones to a private GM instance (Version defaults to 0 and Instance Identifier defaults to 'gmzone' if not used)", AccountStatus::GMAdmin, command_gmzone) ||
|
command_add("gmzone", "[Zone ID|Zone Short Name] [Version] [Instance Identifier] - Zones to a private GM instance (Version defaults to 0 and Instance Identifier defaults to 'gmzone' if not used)", AccountStatus::GMAdmin, command_gmzone) ||
|
||||||
command_add("goto", "[playername] or [x y z] [h] - Teleport to the provided coordinates or to your target", AccountStatus::Steward, command_goto) ||
|
command_add("goto", "[playername] or [x y z] [h] - Teleport to the provided coordinates or to your target", AccountStatus::Steward, command_goto) ||
|
||||||
|
command_add("grantaa", "Grants a player all available AA points for their level.", AccountStatus::GMMgmt, command_grantaa) ||
|
||||||
command_add("grid", "[add/delete] [grid_num] [wandertype] [pausetype] - Create/delete a wandering grid", AccountStatus::GMAreas, command_grid) ||
|
command_add("grid", "[add/delete] [grid_num] [wandertype] [pausetype] - Create/delete a wandering grid", AccountStatus::GMAreas, command_grid) ||
|
||||||
command_add("guild", "Guild manipulation commands. Use argument help for more info.", AccountStatus::Steward, command_guild) ||
|
command_add("guild", "Guild manipulation commands. Use argument help for more info.", AccountStatus::Steward, command_guild) ||
|
||||||
command_add("help", "[Search Criteria] - List available commands and their description, specify partial command as argument to search", AccountStatus::Player, command_help) ||
|
command_add("help", "[Search Criteria] - List available commands and their description, specify partial command as argument to search", AccountStatus::Player, command_help) ||
|
||||||
@ -826,6 +827,7 @@ void command_bot(Client *c, const Seperator *sep)
|
|||||||
#include "gm_commands/givemoney.cpp"
|
#include "gm_commands/givemoney.cpp"
|
||||||
#include "gm_commands/gmzone.cpp"
|
#include "gm_commands/gmzone.cpp"
|
||||||
#include "gm_commands/goto.cpp"
|
#include "gm_commands/goto.cpp"
|
||||||
|
#include "gm_commands/grantaa.cpp"
|
||||||
#include "gm_commands/grid.cpp"
|
#include "gm_commands/grid.cpp"
|
||||||
#include "gm_commands/guild.cpp"
|
#include "gm_commands/guild.cpp"
|
||||||
#include "gm_commands/hp.cpp"
|
#include "gm_commands/hp.cpp"
|
||||||
|
|||||||
@ -87,6 +87,7 @@ void command_giveitem(Client *c, const Seperator *sep);
|
|||||||
void command_givemoney(Client *c, const Seperator *sep);
|
void command_givemoney(Client *c, const Seperator *sep);
|
||||||
void command_gmzone(Client *c, const Seperator *sep);
|
void command_gmzone(Client *c, const Seperator *sep);
|
||||||
void command_goto(Client *c, const Seperator *sep);
|
void command_goto(Client *c, const Seperator *sep);
|
||||||
|
void command_grantaa(Client* c, const Seperator* sep);
|
||||||
void command_grid(Client *c, const Seperator *sep);
|
void command_grid(Client *c, const Seperator *sep);
|
||||||
void command_guild(Client *c, const Seperator *sep);
|
void command_guild(Client *c, const Seperator *sep);
|
||||||
void command_help(Client *c, const Seperator *sep);
|
void command_help(Client *c, const Seperator *sep);
|
||||||
|
|||||||
@ -5652,6 +5652,10 @@ void EntityList::SendAlternateAdvancementStats() {
|
|||||||
for (auto &c : client_list) {
|
for (auto &c : client_list) {
|
||||||
c.second->Message(Chat::White, "Reloading AA");
|
c.second->Message(Chat::White, "Reloading AA");
|
||||||
c.second->ReloadExpansionProfileSetting();
|
c.second->ReloadExpansionProfileSetting();
|
||||||
|
if (!database.LoadAlternateAdvancement(c.second)) {
|
||||||
|
c.second->Message(Chat::Red, "Error loading alternate advancement character data");
|
||||||
|
}
|
||||||
|
|
||||||
c.second->SendClearPlayerAA();
|
c.second->SendClearPlayerAA();
|
||||||
c.second->SendAlternateAdvancementTable();
|
c.second->SendAlternateAdvancementTable();
|
||||||
c.second->SendAlternateAdvancementStats();
|
c.second->SendAlternateAdvancementStats();
|
||||||
|
|||||||
@ -938,6 +938,8 @@ void Client::SetLevel(uint8 set_level, bool command)
|
|||||||
m_pp.exp = GetEXPForLevel(set_level);
|
m_pp.exp = GetEXPForLevel(set_level);
|
||||||
Message(Chat::Yellow, fmt::format("Welcome to level {}!", set_level).c_str());
|
Message(Chat::Yellow, fmt::format("Welcome to level {}!", set_level).c_str());
|
||||||
lu->exp = 0;
|
lu->exp = 0;
|
||||||
|
|
||||||
|
AutoGrantAAPoints();
|
||||||
} else {
|
} else {
|
||||||
const auto temporary_xp = (
|
const auto temporary_xp = (
|
||||||
static_cast<float>(m_pp.exp - GetEXPForLevel(GetLevel())) /
|
static_cast<float>(m_pp.exp - GetEXPForLevel(GetLevel())) /
|
||||||
|
|||||||
20
zone/gm_commands/grantaa.cpp
Normal file
20
zone/gm_commands/grantaa.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include "../client.h"
|
||||||
|
|
||||||
|
void command_grantaa(Client *c, const Seperator *sep)
|
||||||
|
{
|
||||||
|
if (!c->GetTarget() || !c->GetTarget()->IsClient()) {
|
||||||
|
c->Message(Chat::White, "You must target a player to use this command.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto t = c->GetTarget()->CastToClient();
|
||||||
|
t->GrantAllAAPoints();
|
||||||
|
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"Successfully granted all Alternate Advancements for {}.",
|
||||||
|
c->GetTargetDescription(t)
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user