diff --git a/zone/client.cpp b/zone/client.cpp index 739834acf..f79e9ecdf 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -11473,6 +11473,37 @@ void Client::SetLockSavePosition(bool lock_save_position) Client::m_lock_save_position = lock_save_position; } +void Client::SetAAPoints(uint32 points) +{ + const uint32 current_points = m_pp.aapoints; + + m_pp.aapoints = points; + + QuestEventID event_id = points > current_points ? EVENT_AA_GAIN : EVENT_AA_LOSS; + const uint32 change = event_id == EVENT_AA_GAIN ? points - current_points : current_points - points; + + if (parse->PlayerHasQuestSub(event_id)) { + parse->EventPlayer(event_id, this, std::to_string(change), 0); + } + + SendAlternateAdvancementStats(); +} + +bool Client::RemoveAAPoints(uint32 points) +{ + if (m_pp.aapoints < points) { + return false; + } + + m_pp.aapoints -= points; + + if (parse->PlayerHasQuestSub(EVENT_AA_LOSS)) { + parse->EventPlayer(EVENT_AA_LOSS, this, std::to_string(points), 0); + } + + SendAlternateAdvancementStats(); +} + void Client::AddAAPoints(uint32 points) { m_pp.aapoints += points; diff --git a/zone/client.h b/zone/client.h index 32c5f2d06..36d6b4750 100644 --- a/zone/client.h +++ b/zone/client.h @@ -933,8 +933,9 @@ public: void ResetAlternateAdvancementTimers(); void ResetOnDeathAlternateAdvancement(); - void SetAAPoints(uint32 points) { m_pp.aapoints = points; SendAlternateAdvancementStats(); } + void SetAAPoints(uint32 points); void AddAAPoints(uint32 points); + bool RemoveAAPoints(uint32 points); int GetAAPoints() { return m_pp.aapoints; } int GetSpentAA() { return m_pp.aapoints_spent; } uint32 GetRequiredAAExperience(); diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 7a0d22fc4..40395c85c 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -200,6 +200,7 @@ const char* QuestEventSubroutines[_LargestEventID] = { "EVENT_ENTITY_VARIABLE_DELETE", "EVENT_ENTITY_VARIABLE_SET", "EVENT_ENTITY_VARIABLE_UPDATE", + "EVENT_AA_LOSS", // Add new events before these or Lua crashes "EVENT_SPELL_EFFECT_BOT", @@ -2273,6 +2274,11 @@ void PerlembParser::ExportEventVariables( break; } + case EVENT_AA_LOSS: { + ExportVar(package_name.c_str(), "aa_lost", data); + break; + } + case EVENT_AA_EXP_GAIN: { ExportVar(package_name.c_str(), "aa_exp_gained", data); break; diff --git a/zone/event_codes.h b/zone/event_codes.h index 42754671a..5542f7fa7 100644 --- a/zone/event_codes.h +++ b/zone/event_codes.h @@ -142,6 +142,7 @@ typedef enum { EVENT_ENTITY_VARIABLE_DELETE, EVENT_ENTITY_VARIABLE_SET, EVENT_ENTITY_VARIABLE_UPDATE, + EVENT_AA_LOSS, // Add new events before these or Lua crashes EVENT_SPELL_EFFECT_BOT, diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 22612f1c7..0fa539e63 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -3296,6 +3296,12 @@ bool Lua_Client::IsInAGuild() return self->IsInAGuild(); } +bool Lua_Client::RemoveAAPoints(uint32 points) +{ + Lua_Safe_Call_Bool(); + return self->RemoveAAPoints(points); +} + luabind::scope lua_register_client() { return luabind::class_("Client") .def(luabind::constructor<>()) @@ -3669,6 +3675,7 @@ luabind::scope lua_register_client() { .def("ReadBookByName", (void(Lua_Client::*)(std::string,uint8))&Lua_Client::ReadBookByName) .def("RefundAA", (void(Lua_Client::*)(void))&Lua_Client::RefundAA) .def("ReloadDataBuckets", (bool(Lua_Client::*)(void))&Lua_Client::ReloadDataBuckets) + .def("RemoveAAPoints", (bool(Lua_Client::*)(uint32))&Lua_Client::RemoveAAPoints) .def("RemoveAllExpeditionLockouts", (void(Lua_Client::*)(std::string))&Lua_Client::RemoveAllExpeditionLockouts) .def("RemoveAllExpeditionLockouts", (void(Lua_Client::*)(void))&Lua_Client::RemoveAllExpeditionLockouts) .def("RemoveExpeditionLockout", (void(Lua_Client::*)(std::string, std::string))&Lua_Client::RemoveExpeditionLockout) diff --git a/zone/lua_client.h b/zone/lua_client.h index 70c6c70a6..6b7dc0992 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -566,6 +566,7 @@ public: void SetBotSpawnLimit(int new_spawn_limit, uint8 class_id); void CampAllBots(); void CampAllBots(uint8 class_id); + bool RemoveAAPoints(uint32 points); void DialogueWindow(std::string markdown); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 3ed23a411..4155cd7e7 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -6733,7 +6733,8 @@ luabind::scope lua_register_events() { luabind::value("timer_stop", static_cast(EVENT_TIMER_STOP)), luabind::value("entity_variable_delete", static_cast(EVENT_ENTITY_VARIABLE_DELETE)), luabind::value("entity_variable_set", static_cast(EVENT_ENTITY_VARIABLE_SET)), - luabind::value("entity_variable_update", static_cast(EVENT_ENTITY_VARIABLE_UPDATE)) + luabind::value("entity_variable_update", static_cast(EVENT_ENTITY_VARIABLE_UPDATE)), + luabind::value("aa_loss", static_cast(EVENT_AA_LOSS)) )]; } diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 72c767845..d2be1ec38 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -182,7 +182,8 @@ const char *LuaEvents[_LargestEventID] = { "event_timer_stop", "event_entity_variable_delete", "event_entity_variable_set", - "event_entity_variable_update" + "event_entity_variable_update", + "event_aa_loss" }; extern Zone *zone; @@ -343,6 +344,7 @@ LuaParser::LuaParser() { PlayerArgumentDispatch[EVENT_ENTITY_VARIABLE_DELETE] = handle_player_entity_variable; PlayerArgumentDispatch[EVENT_ENTITY_VARIABLE_SET] = handle_player_entity_variable; PlayerArgumentDispatch[EVENT_ENTITY_VARIABLE_UPDATE] = handle_player_entity_variable; + PlayerArgumentDispatch[EVENT_AA_LOSS] = handle_player_aa_loss; ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click; ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click; diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index cd9c9bdb6..4026581aa 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -1667,6 +1667,18 @@ void handle_player_entity_variable( } } +void handle_player_aa_loss( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + lua_pushinteger(L, Strings::ToInt(data)); + lua_setfield(L, -2, "aa_lost"); +} + // Item void handle_item_click( QuestInterface *parse, diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index 0c3309a65..9d4457ed6 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -827,6 +827,15 @@ void handle_player_entity_variable( std::vector *extra_pointers ); +void handle_player_aa_loss( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +); + // Item void handle_item_click( QuestInterface *parse, diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 2803314c6..752b29901 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -3103,6 +3103,11 @@ bool Perl_Client_IsInAGuild(Client* self) return self->IsInAGuild(); } +bool Perl_Client_RemoveAAPoints(Client* self, uint32 points) +{ + return self->RemoveAAPoints(points); +} + void perl_register_client() { perl::interpreter perl(PERL_GET_THX); @@ -3470,6 +3475,7 @@ void perl_register_client() package.add("ReadBookByName", &Perl_Client_ReadBookByName); package.add("RefundAA", &Perl_Client_RefundAA); package.add("ReloadDataBuckets", &Perl_Client_ReloadDataBuckets); + package.add("RemoveAAPoints", &Perl_Client_RemoveAAPoints); package.add("RemoveAllExpeditionLockouts", (void(*)(Client*))&Perl_Client_RemoveAllExpeditionLockouts); package.add("RemoveAllExpeditionLockouts", (void(*)(Client*, std::string))&Perl_Client_RemoveAllExpeditionLockouts); package.add("RemoveEbonCrystals", &Perl_Client_RemoveEbonCrystals);