mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Quest API] Add EVENT_AA_BUY and EVENT_AA_GAIN to Perl/Lua. (#2504)
# Perl - Add EVENT_AA_BUY to Perl. - Exports `$aa_cost`, `$aa_id`, `$aa_previous_id`, and `$aa_next_id` - Add EVENT_AA_GAIN to Perl. - Exports `$aa_gained` - Add quest::getaaname(aa_id) to Perl. # Lua - Add event_aa_buy to Lua. - Exports `e.aa_cost`, `e.aa_id`, `e.aa_previous_id`, and `e.aa_next_id` - Add event_aa_gain to Lua. - Exports `e.aa_gained` - Add eq.get_aa_name(aa_id) to Lua.
This commit is contained in:
parent
a3928ec504
commit
f6dbdf5db8
83
zone/aa.cpp
83
zone/aa.cpp
@ -29,6 +29,7 @@ Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
#include "groups.h"
|
||||
#include "mob.h"
|
||||
#include "queryserv.h"
|
||||
#include "quest_parser_collection.h"
|
||||
#include "raids.h"
|
||||
#include "string_ids.h"
|
||||
#include "titles.h"
|
||||
@ -1147,65 +1148,95 @@ bool Client::GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore
|
||||
}
|
||||
|
||||
void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost) {
|
||||
int rank_id = rank->base_ability->first_rank_id;
|
||||
auto rank_id = rank->base_ability->first_rank_id;
|
||||
|
||||
if(rank->base_ability->charges > 0) {
|
||||
if (rank->base_ability->charges) {
|
||||
uint32 charges = 0;
|
||||
GetAA(rank_id, &charges);
|
||||
|
||||
if(charges > 0) {
|
||||
if (charges) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetAA(rank_id, rank->current_value, rank->base_ability->charges);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SetAA(rank_id, rank->current_value, 0);
|
||||
|
||||
//if not max then send next aa
|
||||
if(rank->next) {
|
||||
if (rank->next) {
|
||||
SendAlternateAdvancementRank(rank->base_ability->id, rank->next->current_value);
|
||||
}
|
||||
}
|
||||
|
||||
int cost = !ignore_cost ? rank->cost : 0;
|
||||
auto cost = !ignore_cost ? rank->cost : 0;
|
||||
|
||||
m_pp.aapoints -= cost ;
|
||||
m_pp.aapoints -= static_cast<uint32>(cost);
|
||||
SaveAA();
|
||||
|
||||
SendAlternateAdvancementPoints();
|
||||
SendAlternateAdvancementStats();
|
||||
|
||||
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(),
|
||||
std::to_string(cost).c_str(),
|
||||
cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str());
|
||||
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(),
|
||||
std::to_string(cost).c_str(),
|
||||
cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()
|
||||
);
|
||||
|
||||
/* QS: Player_Log_AA_Purchases */
|
||||
if(RuleB(QueryServ, PlayerLogAAPurchases)) {
|
||||
std::string event_desc = StringFormat("Ranked AA Purchase :: aa_id:%i at cost:%i in zoneid:%i instid:%i", rank->id, cost, GetZoneID(), GetInstanceID());
|
||||
if (RuleB(QueryServ, PlayerLogAAPurchases)) {
|
||||
const auto event_desc = fmt::format(
|
||||
"Ranked AA Purchase :: aa_id:{} at cost:{} in zoneid:{} instid:{}",
|
||||
rank->id,
|
||||
cost,
|
||||
GetZoneID(),
|
||||
GetInstanceID()
|
||||
);
|
||||
|
||||
QServ->PlayerLogEvent(Player_Log_AA_Purchases, CharacterID(), event_desc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
MessageString(Chat::Yellow, AA_GAIN_ABILITY,
|
||||
std::to_string(rank->title_sid).c_str(),
|
||||
std::to_string(cost).c_str(),
|
||||
cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str());
|
||||
} else {
|
||||
MessageString(
|
||||
Chat::Yellow,
|
||||
AA_GAIN_ABILITY,
|
||||
std::to_string(rank->title_sid).c_str(),
|
||||
std::to_string(cost).c_str(),
|
||||
cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()
|
||||
);
|
||||
|
||||
/* QS: Player_Log_AA_Purchases */
|
||||
if(RuleB(QueryServ, PlayerLogAAPurchases)) {
|
||||
std::string event_desc = StringFormat("Initial AA Purchase :: aa_id:%i at cost:%i in zoneid:%i instid:%i", rank->id, cost, GetZoneID(), GetInstanceID());
|
||||
if (RuleB(QueryServ, PlayerLogAAPurchases)) {
|
||||
const auto event_desc = fmt::format(
|
||||
"Initial AA Purchase :: aa_id:{} at cost:{} in zoneid:{} instid:{}",
|
||||
rank->id,
|
||||
cost,
|
||||
GetZoneID(),
|
||||
GetInstanceID()
|
||||
);
|
||||
|
||||
QServ->PlayerLogEvent(Player_Log_AA_Purchases, CharacterID(), event_desc);
|
||||
}
|
||||
}
|
||||
|
||||
const auto export_string = fmt::format(
|
||||
"{} {} {} {}",
|
||||
cost,
|
||||
rank->id,
|
||||
rank->prev_id,
|
||||
rank->next_id
|
||||
);
|
||||
|
||||
parse->EventPlayer(EVENT_AA_BUY, this, export_string, 0);
|
||||
|
||||
CalcBonuses();
|
||||
|
||||
if(cost > 0) {
|
||||
if(title_manager.IsNewAATitleAvailable(m_pp.aapoints_spent, GetBaseClass()))
|
||||
if (cost) {
|
||||
if (title_manager.IsNewAATitleAvailable(m_pp.aapoints_spent, GetBaseClass())) {
|
||||
NotifyNewTitlesAvailable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -142,6 +142,7 @@ int command_init(void)
|
||||
command_add("faction", "[Find (criteria | all ) | Review (criteria | all) | Reset (id)] - Resets Player's Faction", AccountStatus::QuestTroupe, command_faction) ||
|
||||
command_add("factionassociation", "[factionid] [amount] - triggers a faction hits via association", AccountStatus::GMLeadAdmin, command_faction_association) ||
|
||||
command_add("feature", "Change your or your target's feature's temporarily", AccountStatus::QuestTroupe, command_feature) ||
|
||||
command_add("findaa", "[Search Criteria] - Search for an AA", AccountStatus::Guide, command_findaa) ||
|
||||
command_add("findaliases", "[Search Criteria]- Searches for available command aliases, by alias or command", AccountStatus::Player, command_findaliases) ||
|
||||
command_add("findclass", "[Search Criteria] - Search for a class", AccountStatus::Guide, command_findclass) ||
|
||||
command_add("findfaction", "[Search Criteria] - Search for a faction", AccountStatus::Guide, command_findfaction) ||
|
||||
@ -980,6 +981,7 @@ void command_bot(Client *c, const Seperator *sep)
|
||||
#include "gm_commands/equipitem.cpp"
|
||||
#include "gm_commands/faction.cpp"
|
||||
#include "gm_commands/feature.cpp"
|
||||
#include "gm_commands/findaa.cpp"
|
||||
#include "gm_commands/findclass.cpp"
|
||||
#include "gm_commands/findfaction.cpp"
|
||||
#include "gm_commands/findnpctype.cpp"
|
||||
|
||||
@ -82,6 +82,7 @@ void command_equipitem(Client *c, const Seperator *sep);
|
||||
void command_faction(Client *c, const Seperator *sep);
|
||||
void command_faction_association(Client *c, const Seperator *sep);
|
||||
void command_feature(Client *c, const Seperator *sep);
|
||||
void command_findaa(Client *c, const Seperator *sep);
|
||||
void command_findaliases(Client *c, const Seperator *sep);
|
||||
void command_findclass(Client *c, const Seperator *sep);
|
||||
void command_findfaction(Client *c, const Seperator *sep);
|
||||
|
||||
@ -161,6 +161,8 @@ const char *QuestEventSubroutines[_LargestEventID] = {
|
||||
"EVENT_MERCHANT_SELL",
|
||||
"EVENT_INSPECT",
|
||||
"EVENT_TASK_BEFORE_UPDATE",
|
||||
"EVENT_AA_BUY",
|
||||
"EVENT_AA_GAIN"
|
||||
};
|
||||
|
||||
PerlembParser::PerlembParser() : perl(nullptr)
|
||||
@ -1737,6 +1739,20 @@ void PerlembParser::ExportEventVariables(
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_AA_BUY: {
|
||||
Seperator sep(data);
|
||||
ExportVar(package_name.c_str(), "aa_cost", sep.arg[0]);
|
||||
ExportVar(package_name.c_str(), "aa_id", sep.arg[1]);
|
||||
ExportVar(package_name.c_str(), "aa_previous_id", sep.arg[2]);
|
||||
ExportVar(package_name.c_str(), "aa_next_id", sep.arg[3]);
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_AA_GAIN: {
|
||||
ExportVar(package_name.c_str(), "aa_gained", data);
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_INSPECT: {
|
||||
ExportVar(package_name.c_str(), "target_id", extradata);
|
||||
break;
|
||||
|
||||
@ -3724,6 +3724,15 @@ bool Perl__IsSnowing()
|
||||
return zone->IsSnowing();
|
||||
}
|
||||
|
||||
std::string Perl__getaaname(int aa_id)
|
||||
{
|
||||
if (!zone) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return zone->GetAAName(aa_id);
|
||||
}
|
||||
|
||||
void perl_register_quest()
|
||||
{
|
||||
perl::interpreter perl(PERL_GET_THX);
|
||||
@ -4083,6 +4092,7 @@ void perl_register_quest()
|
||||
package.add("forcedooropen", (void(*)(uint32, bool))&Perl__forcedooropen);
|
||||
package.add("getaaexpmodifierbycharid", (double(*)(uint32, uint32))&Perl__getaaexpmodifierbycharid);
|
||||
package.add("getaaexpmodifierbycharid", (double(*)(uint32, uint32, int16))&Perl__getaaexpmodifierbycharid);
|
||||
package.add("getaaname", (std::string(*)(int))&Perl__getaaname);
|
||||
package.add("getbodytypename", &Perl__getbodytypename);
|
||||
package.add("getcharidbyname", &Perl__getcharidbyname);
|
||||
package.add("getclassname", (std::string(*)(uint8))&Perl__getclassname);
|
||||
|
||||
@ -104,6 +104,8 @@ typedef enum {
|
||||
EVENT_MERCHANT_SELL,
|
||||
EVENT_INSPECT,
|
||||
EVENT_TASK_BEFORE_UPDATE,
|
||||
EVENT_AA_BUY,
|
||||
EVENT_AA_GAIN,
|
||||
_LargestEventID
|
||||
} QuestEventID;
|
||||
|
||||
|
||||
@ -715,6 +715,13 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
SendSound();
|
||||
}
|
||||
|
||||
const auto export_string = fmt::format(
|
||||
"{}",
|
||||
gained
|
||||
);
|
||||
|
||||
parse->EventPlayer(EVENT_AA_GAIN, this, export_string, 0);
|
||||
|
||||
/* QS: PlayerLogAARate */
|
||||
if (RuleB(QueryServ, PlayerLogAARate)){
|
||||
int add_points = (m_pp.aapoints - last_unspentAA);
|
||||
|
||||
100
zone/gm_commands/findaa.cpp
Executable file
100
zone/gm_commands/findaa.cpp
Executable file
@ -0,0 +1,100 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_findaa(Client *c, const Seperator *sep)
|
||||
{
|
||||
auto arguments = sep->argnum;
|
||||
if (!arguments) {
|
||||
c->Message(Chat::White, "Command Syntax: #findaa [Search Criteria]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
int aa_id = std::stoi(sep->arg[1]);
|
||||
auto aa_name = zone->GetAAName(aa_id);
|
||||
if (!aa_name.empty()) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"AA {}: {}",
|
||||
aa_id,
|
||||
aa_name
|
||||
).c_str()
|
||||
);
|
||||
} else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"AA ID {} was not found.",
|
||||
aa_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const auto search_criteria = Strings::ToLower(sep->argplus[1]);
|
||||
if (!search_criteria.empty()) {
|
||||
std::map<int, std::string> ordered_aas;
|
||||
|
||||
for (const auto& a : zone->aa_abilities) {
|
||||
ordered_aas[a.second.get()->id] = a.second.get()->name;
|
||||
}
|
||||
|
||||
int found_count = 0;
|
||||
for (const auto& a : ordered_aas) {
|
||||
auto aa_name = zone->GetAAName(a.first);
|
||||
if (!aa_name.empty()) {
|
||||
auto aa_name_lower = Strings::ToLower(aa_name);
|
||||
if (aa_name_lower.find(search_criteria) == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"AA {}: {}",
|
||||
a.first,
|
||||
aa_name
|
||||
).c_str()
|
||||
);
|
||||
found_count++;
|
||||
|
||||
if (found_count == 50) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_count) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"No AAs were found matching '{}'.",
|
||||
search_criteria
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (found_count == 50) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"50 AAs were found matching '{}', max reached.",
|
||||
search_criteria
|
||||
).c_str()
|
||||
);
|
||||
} else {
|
||||
auto skill_message = found_count == 1 ? "An AA was" : fmt::format("{} AAs were", found_count);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} found matching '{}'.",
|
||||
skill_message,
|
||||
search_criteria
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3444,6 +3444,14 @@ bool lua_is_snowing() {
|
||||
return zone->IsSnowing();
|
||||
}
|
||||
|
||||
std::string lua_get_aa_name(int aa_id) {
|
||||
if (!zone) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return zone->GetAAName(aa_id);
|
||||
}
|
||||
|
||||
#define LuaCreateNPCParse(name, c_type, default_value) do { \
|
||||
cur = table[#name]; \
|
||||
if(luabind::type(cur) != LUA_TNIL) { \
|
||||
@ -3910,6 +3918,7 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("has_recipe_learned", &lua_has_recipe_learned),
|
||||
luabind::def("is_raining", &lua_is_raining),
|
||||
luabind::def("is_snowing", &lua_is_snowing),
|
||||
luabind::def("get_aa_name", &lua_get_aa_name),
|
||||
|
||||
/*
|
||||
Cross Zone
|
||||
@ -4308,7 +4317,9 @@ luabind::scope lua_register_events() {
|
||||
luabind::value("merchant_buy", static_cast<int>(EVENT_MERCHANT_BUY)),
|
||||
luabind::value("merchant_sell", static_cast<int>(EVENT_MERCHANT_SELL)),
|
||||
luabind::value("inspect", static_cast<int>(EVENT_INSPECT)),
|
||||
luabind::value("task_before_update", static_cast<int>(EVENT_TASK_BEFORE_UPDATE))
|
||||
luabind::value("task_before_update", static_cast<int>(EVENT_TASK_BEFORE_UPDATE)),
|
||||
luabind::value("aa_buy", static_cast<int>(EVENT_AA_BUY)),
|
||||
luabind::value("aa_gain", static_cast<int>(EVENT_AA_GAIN))
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -148,6 +148,8 @@ const char *LuaEvents[_LargestEventID] = {
|
||||
"event_merchant_sell",
|
||||
"event_inspect",
|
||||
"event_task_before_update",
|
||||
"event_aa_buy",
|
||||
"event_aa_gain"
|
||||
};
|
||||
|
||||
extern Zone *zone;
|
||||
@ -249,6 +251,8 @@ LuaParser::LuaParser() {
|
||||
PlayerArgumentDispatch[EVENT_MERCHANT_BUY] = handle_player_merchant;
|
||||
PlayerArgumentDispatch[EVENT_MERCHANT_SELL] = handle_player_merchant;
|
||||
PlayerArgumentDispatch[EVENT_INSPECT] = handle_player_inspect;
|
||||
PlayerArgumentDispatch[EVENT_AA_BUY] = handle_player_aa_buy;
|
||||
PlayerArgumentDispatch[EVENT_AA_GAIN] = handle_player_aa_gain;
|
||||
|
||||
ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click;
|
||||
ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click;
|
||||
|
||||
@ -898,4 +898,24 @@ void handle_player_merchant(QuestInterface* parse, lua_State* L, Client* client,
|
||||
lua_setfield(L, -2, "item_cost");
|
||||
}
|
||||
|
||||
void handle_player_aa_buy(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector<std::any>* extra_pointers) {
|
||||
Seperator sep(data.c_str());
|
||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
||||
lua_setfield(L, -2, "aa_cost");
|
||||
|
||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
||||
lua_setfield(L, -2, "aa_id");
|
||||
|
||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
||||
lua_setfield(L, -2, "aa_previous_id");
|
||||
|
||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
||||
lua_setfield(L, -2, "aa_next_id");
|
||||
}
|
||||
|
||||
void handle_player_aa_gain(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector<std::any>* extra_pointers) {
|
||||
lua_pushinteger(L, std::stoi(data));
|
||||
lua_setfield(L, -2, "aa_gained");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -125,6 +125,10 @@ void handle_player_merchant(QuestInterface* parse, lua_State* L, Client* client,
|
||||
std::vector<std::any>* extra_pointers);
|
||||
void handle_player_inspect(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers);
|
||||
void handle_player_aa_buy(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers);
|
||||
void handle_player_aa_gain(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers);
|
||||
|
||||
//Item
|
||||
void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, EQ::ItemInstance* item, Mob *mob, std::string data, uint32 extra_data,
|
||||
|
||||
@ -2950,3 +2950,29 @@ void Zone::LoadDynamicZoneTemplates()
|
||||
dz_template_cache[dz_template.id] = dz_template;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Zone::GetAAName(int aa_id)
|
||||
{
|
||||
if (!aa_id) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
int current_aa_id = 0;
|
||||
|
||||
const auto& r = aa_ranks.find(aa_id);
|
||||
if (
|
||||
r != aa_ranks.end() &&
|
||||
r->second.get()->base_ability
|
||||
) {
|
||||
current_aa_id = r->second.get()->base_ability->id;
|
||||
}
|
||||
|
||||
if (current_aa_id) {
|
||||
const auto& a = aa_abilities.find(current_aa_id);
|
||||
if (a != aa_abilities.end()) {
|
||||
return a->second.get()->name;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
@ -249,6 +249,8 @@ public:
|
||||
uint32 GetCurrencyID(uint32 item_id);
|
||||
uint32 GetCurrencyItemID(uint32 currency_id);
|
||||
|
||||
std::string GetAAName(int aa_id);
|
||||
|
||||
inline bool IsRaining() { return zone_weather == EQ::constants::WeatherTypes::Raining; }
|
||||
inline bool IsSnowing() { return zone_weather == EQ::constants::WeatherTypes::Snowing; }
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user