diff --git a/zone/client.cpp b/zone/client.cpp index 28643efa8..e0ec723bd 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -6620,13 +6620,72 @@ void Client::SendAltCurrencies() { void Client::SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount) { + if (!zone->DoesAlternateCurrencyExist(currency_id)) { + return; + } + + const uint32 current_amount = alternate_currency[currency_id]; + + const bool is_gain = new_amount > current_amount; + + const uint32 change_amount = is_gain ? (new_amount - current_amount) : (current_amount - new_amount); + + if (!change_amount) { + return; + } + alternate_currency[currency_id] = new_amount; database.UpdateAltCurrencyValue(CharacterID(), currency_id, new_amount); SendAlternateCurrencyValue(currency_id); + + QuestEventID event_id = is_gain ? EVENT_ALT_CURRENCY_GAIN : EVENT_ALT_CURRENCY_LOSS; + if (parse->PlayerHasQuestSub(event_id)) { + const std::string &export_string = fmt::format( + "{} {} {}", + currency_id, + change_amount, + new_amount + ); + + parse->EventPlayer(event_id, this, export_string, 0); + } +} + +bool Client::RemoveAlternateCurrencyValue(uint32 currency_id, uint32 amount) +{ + if (!amount || !zone->DoesAlternateCurrencyExist(currency_id)) { + return false; + } + + const uint32 current_amount = alternate_currency[currency_id]; + if (current_amount < amount) { + return false; + } + + const uint32 new_amount = (current_amount - amount); + + alternate_currency[currency_id] = new_amount; + + if (parse->PlayerHasQuestSub(EVENT_ALT_CURRENCY_LOSS)) { + const std::string &export_string = fmt::format( + "{} {} {}", + currency_id, + amount, + new_amount + ); + + parse->EventPlayer(EVENT_ALT_CURRENCY_LOSS, this, export_string, 0); + } + + return true; } int Client::AddAlternateCurrencyValue(uint32 currency_id, int amount, bool is_scripted) { + if (!zone->DoesAlternateCurrencyExist(currency_id)) { + return 0; + } + /* Added via Quest, rest of the logging methods may be done inline due to information available in that area of the code */ if (is_scripted) { /* QS: PlayerLogAlternateCurrencyTransactions :: Cursor to Item Storage */ @@ -6665,7 +6724,6 @@ int Client::AddAlternateCurrencyValue(uint32 currency_id, int amount, bool is_sc SendAlternateCurrencyValue(currency_id); QuestEventID event_id = amount > 0 ? EVENT_ALT_CURRENCY_GAIN : EVENT_ALT_CURRENCY_LOSS; - if (parse->PlayerHasQuestSub(event_id)) { const std::string &export_string = fmt::format( "{} {} {}", @@ -6706,6 +6764,10 @@ void Client::SendAlternateCurrencyValue(uint32 currency_id, bool send_if_null) uint32 Client::GetAlternateCurrencyValue(uint32 currency_id) const { + if (!zone->DoesAlternateCurrencyExist(currency_id)) { + return 0; + } + auto iter = alternate_currency.find(currency_id); return iter == alternate_currency.end() ? 0 : (*iter).second; diff --git a/zone/client.h b/zone/client.h index 36d6b4750..af0bf64ff 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1540,6 +1540,7 @@ public: void SendAltCurrencies(); void SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount); int AddAlternateCurrencyValue(uint32 currency_id, int amount, bool is_scripted = false); + bool RemoveAlternateCurrencyValue(uint32 currency_id, uint32 amount); void SendAlternateCurrencyValues(); void SendAlternateCurrencyValue(uint32 currency_id, bool send_if_null = true); uint32 GetAlternateCurrencyValue(uint32 currency_id) const; diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 0fa539e63..6886a48fb 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -3302,6 +3302,12 @@ bool Lua_Client::RemoveAAPoints(uint32 points) return self->RemoveAAPoints(points); } +bool Lua_Client::RemoveAlternateCurrencyValue(uint32 currency_id, uint32 amount) +{ + Lua_Safe_Call_Bool(); + return self->RemoveAlternateCurrencyValue(currency_id, amount); +} + luabind::scope lua_register_client() { return luabind::class_("Client") .def(luabind::constructor<>()) @@ -3678,6 +3684,7 @@ luabind::scope lua_register_client() { .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("RemoveAlternateCurrencyValue", (bool(Lua_Client::*)(uint32,uint32))&Lua_Client::RemoveAlternateCurrencyValue) .def("RemoveExpeditionLockout", (void(Lua_Client::*)(std::string, std::string))&Lua_Client::RemoveExpeditionLockout) .def("RemoveItem", (void(Lua_Client::*)(uint32))&Lua_Client::RemoveItem) .def("RemoveItem", (void(Lua_Client::*)(uint32,uint32))&Lua_Client::RemoveItem) diff --git a/zone/lua_client.h b/zone/lua_client.h index 6b7dc0992..6a249924e 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -567,6 +567,7 @@ public: void CampAllBots(); void CampAllBots(uint8 class_id); bool RemoveAAPoints(uint32 points); + bool RemoveAlternateCurrencyValue(uint32 currency_id, uint32 amount); void DialogueWindow(std::string markdown); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 752b29901..708d89a03 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -3108,6 +3108,11 @@ bool Perl_Client_RemoveAAPoints(Client* self, uint32 points) return self->RemoveAAPoints(points); } +bool Perl_Client_RemoveAlternateCurrencyValue(Client* self, uint32 currency_id, uint32 amount) +{ + return self->RemoveAlternateCurrencyValue(currency_id, amount); +} + void perl_register_client() { perl::interpreter perl(PERL_GET_THX); @@ -3478,6 +3483,7 @@ void perl_register_client() 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("RemoveAlternateCurrencyValue", (bool(*)(Client*, uint32, uint32))&Perl_Client_RemoveAlternateCurrencyValue); package.add("RemoveEbonCrystals", &Perl_Client_RemoveEbonCrystals); package.add("RemoveExpeditionLockout", &Perl_Client_RemoveExpeditionLockout); package.add("RemoveFromInstance", &Perl_Client_RemoveFromInstance); diff --git a/zone/zone.cpp b/zone/zone.cpp index 883b29f02..826b33bf5 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -3318,4 +3318,15 @@ void Zone::SetSecondsBeforeIdle(uint32 seconds_before_idle) Zone::m_seconds_before_idle = seconds_before_idle; } +bool Zone::DoesAlternateCurrencyExist(uint32 currency_id) +{ + return std::any_of( + AlternateCurrencies.begin(), + AlternateCurrencies.end(), + [&](const auto& c) { + return c.id == currency_id; + } + ); +} + #include "zone_loot.cpp" diff --git a/zone/zone.h b/zone/zone.h index 946b14347..a6eceefba 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -152,6 +152,7 @@ public: bool IsSpecialBindLocation(const glm::vec4& location); bool Process(); bool SaveZoneCFG(); + bool DoesAlternateCurrencyExist(uint32 currency_id); int GetNpcPositionUpdateDistance() const; void SetNpcPositionUpdateDistance(int in_npc_position_update_distance);