diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index 0d68c1810..9482d4625 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -124,6 +124,12 @@ struct LDoNTrapTemplate uint8 locked; }; +enum CrystalReclaimTypes +{ + Ebon = 5, + Radiant = 4, +}; + /////////////////////////////////////////////////////////////////////////////// diff --git a/zone/client.cpp b/zone/client.cpp index 43c69a2b4..2e97f8c0d 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -5727,26 +5727,89 @@ void Client::AddPVPPoints(uint32 Points) SendPVPStats(); } -void Client::AddCrystals(uint32 radiant, uint32 ebon) -{ - m_pp.currentRadCrystals += radiant; - m_pp.careerRadCrystals += radiant; - m_pp.currentEbonCrystals += ebon; - m_pp.careerEbonCrystals += ebon; +void Client::AddEbonCrystals(uint32 amount, bool is_reclaim) { + m_pp.currentEbonCrystals += amount; + m_pp.careerEbonCrystals += amount; SaveCurrency(); - SendCrystalCounts(); - // newer clients handle message client side (older clients likely used eqstr 5967 and 5968, this matches live) - if (radiant > 0) - { - MessageString(Chat::Yellow, YOU_RECEIVE, fmt::format("{} Radiant Crystals", radiant).c_str()); - } + MessageString( + Chat::Yellow, + YOU_RECEIVE, + fmt::format( + "{} {}", + amount, + database.CreateItemLink(RuleI(Zone, EbonCrystalItemID)) + ).c_str() + ); - if (ebon > 0) - { - MessageString(Chat::Yellow, YOU_RECEIVE, fmt::format("{} Ebon Crystals", ebon).c_str()); + if (parse->PlayerHasQuestSub(EVENT_CRYSTAL_GAIN)) { + const std::string &export_string = fmt::format( + "{} 0 {}", + amount, + is_reclaim ? 1 : 0 + ); + parse->EventPlayer(EVENT_CRYSTAL_GAIN, this, export_string, 0); + } +} + +void Client::AddRadiantCrystals(uint32 amount, bool is_reclaim) { + m_pp.currentRadCrystals += amount; + m_pp.careerRadCrystals += amount; + + SaveCurrency(); + SendCrystalCounts(); + + MessageString( + Chat::Yellow, + YOU_RECEIVE, + fmt::format( + "{} {}", + amount, + database.CreateItemLink(RuleI(Zone, RadiantCrystalItemID)) + ).c_str() + ); + + if (parse->PlayerHasQuestSub(EVENT_CRYSTAL_GAIN)) { + const std::string &export_string = fmt::format( + "0 {} {}", + amount, + is_reclaim ? 1 : 0 + ); + parse->EventPlayer(EVENT_CRYSTAL_GAIN, this, export_string, 0); + } +} + +void Client::RemoveEbonCrystals(uint32 amount, bool is_reclaim) { + m_pp.currentEbonCrystals -= amount; + + SaveCurrency(); + SendCrystalCounts(); + + if (parse->PlayerHasQuestSub(EVENT_CRYSTAL_LOSS)) { + const std::string &export_string = fmt::format( + "{} 0 {}", + amount, + is_reclaim ? 1 : 0 + ); + parse->EventPlayer(EVENT_CRYSTAL_LOSS, this, export_string, 0); + } +} + +void Client::RemoveRadiantCrystals(uint32 amount, bool is_reclaim) { + m_pp.currentRadCrystals -= amount; + + SaveCurrency(); + SendCrystalCounts(); + + if (parse->PlayerHasQuestSub(EVENT_CRYSTAL_LOSS)) { + const std::string &export_string = fmt::format( + "0 {} {}", + amount, + is_reclaim ? 1 : 0 + ); + parse->EventPlayer(EVENT_CRYSTAL_LOSS, this, export_string, 0); } } diff --git a/zone/client.h b/zone/client.h index f58b69835..3ee7e75bc 100644 --- a/zone/client.h +++ b/zone/client.h @@ -611,11 +611,14 @@ public: void SetPVPPoints(uint32 Points) { m_pp.PVPCurrentPoints = Points; } uint32 GetPVPPoints() { return m_pp.PVPCurrentPoints; } void AddPVPPoints(uint32 Points); + void AddEbonCrystals(uint32 amount, bool is_reclaim = false); + void AddRadiantCrystals(uint32 amount, bool is_reclaim = false); + void RemoveEbonCrystals(uint32 amount, bool is_reclaim = false); + void RemoveRadiantCrystals(uint32 amount, bool is_reclaim = false); uint32 GetRadiantCrystals() { return m_pp.currentRadCrystals; } void SetRadiantCrystals(uint32 value); uint32 GetEbonCrystals() { return m_pp.currentEbonCrystals; } void SetEbonCrystals(uint32 value); - void AddCrystals(uint32 Radiant, uint32 Ebon); void SendCrystalCounts(); uint64 GetExperienceForKill(Mob *against); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index b4fa286b3..796660af1 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -5475,59 +5475,50 @@ void Client::Handle_OP_CreateObject(const EQApplicationPacket *app) void Client::Handle_OP_CrystalCreate(const EQApplicationPacket *app) { VERIFY_PACKET_LENGTH(OP_CrystalCreate, app, CrystalReclaim_Struct); - CrystalReclaim_Struct *cr = (CrystalReclaim_Struct*)app->pBuffer; + auto *cr = (CrystalReclaim_Struct *) app->pBuffer; - const uint32 requestQty = cr->amount; - const bool isRadiant = cr->type == 4; - const bool isEbon = cr->type == 5; + const uint32 quantity = cr->amount; + const bool is_radiant = cr->type == CrystalReclaimTypes::Radiant; + const bool is_ebon = cr->type == CrystalReclaimTypes::Ebon; - // Check: Valid type requested. - if (!isRadiant && !isEbon) { + if (!is_radiant && !is_ebon) { return; } - // Check: Valid quantity requested. - if (requestQty < 1) { + + if (quantity < 1) { return; } // Check: Valid client state to make request. // In this situation the client is either desynced or attempting an exploit. - const uint32 currentQty = isRadiant ? GetRadiantCrystals() : GetEbonCrystals(); - if (currentQty == 0) { + const uint32 current_quantity = is_radiant ? GetRadiantCrystals() : GetEbonCrystals(); + if (!current_quantity) { return; } // Prevent the client from creating more than they have. - const uint32 amount = EQ::ClampUpper(requestQty, currentQty); - const uint32 itemID = isRadiant ? RuleI(Zone, RadiantCrystalItemID) : RuleI(Zone, EbonCrystalItemID); - - // Summon crystals for player. - const bool success = SummonItem(itemID, amount); + const uint32 amount = EQ::ClampUpper(quantity, current_quantity); + const uint32 item_id = is_radiant ? RuleI(Zone, RadiantCrystalItemID) : RuleI(Zone, EbonCrystalItemID); + const bool success = SummonItem(item_id, amount); if (!success) { return; } - // Deduct crystals from client and update them. - if (isRadiant) { - m_pp.currentRadCrystals -= amount; - m_pp.careerRadCrystals -= amount; + if (is_ebon) { + RemoveEbonCrystals(amount, true); + } else if (is_radiant) { + RemoveRadiantCrystals(amount, true); } - else if (isEbon) { - m_pp.currentEbonCrystals -= amount; - m_pp.careerEbonCrystals -= amount; - } - - SaveCurrency(); - SendCrystalCounts(); } void Client::Handle_OP_CrystalReclaim(const EQApplicationPacket *app) { - uint32 ebon = NukeItem(RuleI(Zone, EbonCrystalItemID), invWhereWorn | invWherePersonal | invWhereCursor); - uint32 radiant = NukeItem(RuleI(Zone, RadiantCrystalItemID), invWhereWorn | invWherePersonal | invWhereCursor); + const uint32 ebon = NukeItem(RuleI(Zone, EbonCrystalItemID), invWhereWorn | invWherePersonal | invWhereCursor); + const uint32 radiant = NukeItem(RuleI(Zone, RadiantCrystalItemID), invWhereWorn | invWherePersonal | invWhereCursor); if ((ebon + radiant) > 0) { - AddCrystals(radiant, ebon); + AddEbonCrystals(ebon, true); + AddRadiantCrystals(radiant, true); } } diff --git a/zone/embparser.cpp b/zone/embparser.cpp index c9e722da8..bf8a16255 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -191,6 +191,9 @@ const char *QuestEventSubroutines[_LargestEventID] = { "EVENT_LDON_POINTS_LOSS", "EVENT_ALT_CURRENCY_GAIN", "EVENT_ALT_CURRENCY_LOSS", + "EVENT_CRYSTAL_GAIN", + "EVENT_CRYSTAL_LOSS", + // Add new events before these or Lua crashes "EVENT_SPELL_EFFECT_BOT", "EVENT_SPELL_EFFECT_BUFF_TIC_BOT" @@ -2281,6 +2284,15 @@ void PerlembParser::ExportEventVariables( break; } + case EVENT_CRYSTAL_GAIN: + case EVENT_CRYSTAL_LOSS: { + Seperator sep(data); + ExportVar(package_name.c_str(), "ebon_amount", sep.arg[0]); + ExportVar(package_name.c_str(), "radiant_amount", sep.arg[1]); + ExportVar(package_name.c_str(), "is_reclaim", sep.arg[2]); + break; + } + default: { break; } diff --git a/zone/event_codes.h b/zone/event_codes.h index 9d3f145c7..056a23ef1 100644 --- a/zone/event_codes.h +++ b/zone/event_codes.h @@ -133,6 +133,8 @@ typedef enum { EVENT_LDON_POINTS_LOSS, EVENT_ALT_CURRENCY_GAIN, EVENT_ALT_CURRENCY_LOSS, + EVENT_CRYSTAL_GAIN, + EVENT_CRYSTAL_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 888066248..69b6138d4 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -1211,7 +1211,24 @@ void Lua_Client::AddPVPPoints(uint32 points) { void Lua_Client::AddCrystals(uint32 radiant, uint32 ebon) { Lua_Safe_Call_Void(); - self->AddCrystals(radiant, ebon); + + if (ebon != 0) { + if (ebon > 0) { + self->AddEbonCrystals(ebon); + return; + } + + self->RemoveEbonCrystals(ebon); + } + + if (radiant != 0) { + if (radiant > 0) { + self->AddRadiantCrystals(radiant); + return; + } + + self->RemoveRadiantCrystals(radiant); + } } void Lua_Client::SetEbonCrystals(uint32 value) { @@ -3176,6 +3193,30 @@ void Lua_Client::GrantAllAAPoints(uint8 unlock_level) self->GrantAllAAPoints(unlock_level); } +void Lua_Client::AddEbonCrystals(uint32 amount) +{ + Lua_Safe_Call_Void(); + self->AddEbonCrystals(amount); +} + +void Lua_Client::AddRadiantCrystals(uint32 amount) +{ + Lua_Safe_Call_Void(); + self->AddRadiantCrystals(amount); +} + +void Lua_Client::RemoveEbonCrystals(uint32 amount) +{ + Lua_Safe_Call_Void(); + self->RemoveEbonCrystals(amount); +} + +void Lua_Client::RemoveRadiantCrystals(uint32 amount) +{ + Lua_Safe_Call_Void(); + self->RemoveRadiantCrystals(amount); +} + luabind::scope lua_register_client() { return luabind::class_("Client") .def(luabind::constructor<>()) @@ -3187,6 +3228,7 @@ luabind::scope lua_register_client() { .def("AddEXP", (void(Lua_Client::*)(uint32))&Lua_Client::AddEXP) .def("AddEXP", (void(Lua_Client::*)(uint32,int))&Lua_Client::AddEXP) .def("AddEXP", (void(Lua_Client::*)(uint32,int,bool))&Lua_Client::AddEXP) + .def("AddEbonCrystals", (void(Lua_Client::*)(uint32))&Lua_Client::AddEbonCrystals) .def("AddExpeditionLockout", (void(Lua_Client::*)(std::string, std::string, uint32))&Lua_Client::AddExpeditionLockout) .def("AddExpeditionLockout", (void(Lua_Client::*)(std::string, std::string, uint32, std::string))&Lua_Client::AddExpeditionLockout) .def("AddExpeditionLockoutDuration", (void(Lua_Client::*)(std::string, std::string, int))&Lua_Client::AddExpeditionLockoutDuration) @@ -3202,6 +3244,7 @@ luabind::scope lua_register_client() { .def("AddPlatinum", (void(Lua_Client::*)(uint32))&Lua_Client::AddPlatinum) .def("AddPlatinum", (void(Lua_Client::*)(uint32,bool))&Lua_Client::AddPlatinum) .def("AddPVPPoints", (void(Lua_Client::*)(uint32))&Lua_Client::AddPVPPoints) + .def("AddRadiantCrystals", (void(Lua_Client::*)(uint32))&Lua_Client::AddRadiantCrystals) .def("AddSkill", (void(Lua_Client::*)(int,int))&Lua_Client::AddSkill) .def("Admin", (int16(Lua_Client::*)(void))&Lua_Client::Admin) .def("ApplySpell", (void(Lua_Client::*)(int))&Lua_Client::ApplySpell) @@ -3554,7 +3597,9 @@ luabind::scope lua_register_client() { .def("ResetCastbarCooldownBySlot", (void(Lua_Client::*)(int))&Lua_Client::ResetCastbarCooldownBySlot) .def("ResetCastbarCooldownBySpellID", (void(Lua_Client::*)(uint32))&Lua_Client::ResetCastbarCooldownBySpellID) .def("ResetDisciplineTimer", (void(Lua_Client::*)(uint32))&Lua_Client::ResetDisciplineTimer) + .def("RemoveEbonCrystals", (void(Lua_Client::*)(uint32))&Lua_Client::RemoveEbonCrystals) .def("ResetItemCooldown", (void(Lua_Client::*)(uint32))&Lua_Client::ResetItemCooldown) + .def("RemoveRadiantCrystals", (void(Lua_Client::*)(uint32))&Lua_Client::RemoveRadiantCrystals) .def("ResetTrade", (void(Lua_Client::*)(void))&Lua_Client::ResetTrade) .def("RewardFaction", (void(Lua_Client::*)(int,int))&Lua_Client::RewardFaction) .def("Save", (void(Lua_Client::*)(int))&Lua_Client::Save) diff --git a/zone/lua_client.h b/zone/lua_client.h index 8017555e2..f298bacc0 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -482,6 +482,10 @@ public: void SetBucket(std::string bucket_name, std::string bucket_value, std::string expiration); void GrantAllAAPoints(); void GrantAllAAPoints(uint8 unlock_level); + void AddEbonCrystals(uint32 amount); + void AddRadiantCrystals(uint32 amount); + void RemoveEbonCrystals(uint32 amount); + void RemoveRadiantCrystals(uint32 amount); void ApplySpell(int spell_id); void ApplySpell(int spell_id, int duration); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 5e952a803..086e968ce 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -6614,7 +6614,9 @@ luabind::scope lua_register_events() { luabind::value("ldon_points_gain", static_cast(EVENT_LDON_POINTS_GAIN)), luabind::value("ldon_points_loss", static_cast(EVENT_LDON_POINTS_LOSS)), luabind::value("alt_currency_gain", static_cast(EVENT_ALT_CURRENCY_GAIN)), - luabind::value("alt_currency_loss", static_cast(EVENT_ALT_CURRENCY_LOSS)) + luabind::value("alt_currency_loss", static_cast(EVENT_ALT_CURRENCY_LOSS)), + luabind::value("crystal_gain", static_cast(EVENT_CRYSTAL_GAIN)), + luabind::value("crystal_loss", static_cast(EVENT_CRYSTAL_LOSS)) )]; } diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index bd5a58441..1a0a27a40 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -173,7 +173,9 @@ const char *LuaEvents[_LargestEventID] = { "event_ldon_points_gain", "event_ldon_points_loss", "event_alt_currency_gain", - "event_alt_currency_loss" + "event_alt_currency_loss", + "event_crystal_gain", + "event_crystal_loss" }; extern Zone *zone; @@ -310,6 +312,8 @@ LuaParser::LuaParser() { PlayerArgumentDispatch[EVENT_LDON_POINTS_LOSS] = handle_player_ldon_points_gain_loss; PlayerArgumentDispatch[EVENT_ALT_CURRENCY_GAIN] = handle_player_alt_currency_gain_loss; PlayerArgumentDispatch[EVENT_ALT_CURRENCY_LOSS] = handle_player_alt_currency_gain_loss; + PlayerArgumentDispatch[EVENT_CRYSTAL_GAIN] = handle_player_crystal_gain_loss; + PlayerArgumentDispatch[EVENT_CRYSTAL_LOSS] = handle_player_crystal_gain_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 ed4611fce..867912e2e 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -1518,6 +1518,26 @@ void handle_player_ldon_points_gain_loss( lua_setfield(L, -2, "points"); } +void handle_player_crystal_gain_loss( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + Seperator sep(data.c_str()); + + lua_pushnumber(L, Strings::ToUnsignedInt(sep.arg[0])); + lua_setfield(L, -2, "ebon_amount"); + + lua_pushnumber(L, Strings::ToUnsignedInt(sep.arg[1])); + lua_setfield(L, -2, "radiant_amount"); + + lua_pushboolean(L, Strings::ToBool(sep.arg[2])); + lua_setfield(L, -2, "is_reclaim"); +} + void handle_player_alt_currency_gain_loss( QuestInterface *parse, lua_State* L, diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index 89af5164b..218eaeef6 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -761,6 +761,15 @@ void handle_player_alt_currency_gain_loss( std::vector *extra_pointers ); +void handle_player_crystal_gain_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 d980b950a..a2495bedc 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -1159,7 +1159,23 @@ void Perl_Client_AddPVPPoints(Client* self, uint32 points) // @categories Curren void Perl_Client_AddCrystals(Client* self, uint32 radiant_count, uint32 ebon_count) // @categories Currency and Points { - self->AddCrystals(radiant_count, ebon_count); + if (ebon_count != 0) { + if (ebon_count > 0) { + self->AddEbonCrystals(ebon_count); + return; + } + + self->RemoveEbonCrystals(ebon_count); + } + + if (radiant_count != 0) { + if (radiant_count > 0) { + self->AddRadiantCrystals(radiant_count); + return; + } + + self->RemoveRadiantCrystals(radiant_count); + } } void Perl_Client_SetEbonCrystals(Client* self, uint32 value) @@ -2992,6 +3008,26 @@ void Perl_Client_GrantAllAAPoints(Client* self, uint8 unlock_level) self->GrantAllAAPoints(unlock_level); } +void Perl_Client_AddEbonCrystals(Client* self, uint32 amount) +{ + self->AddEbonCrystals(amount); +} + +void Perl_Client_AddRadiantCrystals(Client* self, uint32 amount) +{ + self->AddRadiantCrystals(amount); +} + +void Perl_Client_RemoveEbonCrystals(Client* self, uint32 amount) +{ + self->RemoveEbonCrystals(amount); +} + +void Perl_Client_RemoveRadiantCrystals(Client* self, uint32 amount) +{ + self->RemoveRadiantCrystals(amount); +} + void perl_register_client() { perl::interpreter perl(PERL_GET_THX); @@ -3006,6 +3042,7 @@ void perl_register_client() package.add("AddEXP", (void(*)(Client*, uint32))&Perl_Client_AddEXP); package.add("AddEXP", (void(*)(Client*, uint32, uint8))&Perl_Client_AddEXP); package.add("AddEXP", (void(*)(Client*, uint32, uint8, bool))&Perl_Client_AddEXP); + package.add("AddEbonCrystals", &Perl_Client_AddEbonCrystals); package.add("AddExpeditionLockout", (void(*)(Client*, std::string, std::string, uint32))&Perl_Client_AddExpeditionLockout); package.add("AddExpeditionLockout", (void(*)(Client*, std::string, std::string, uint32, std::string))&Perl_Client_AddExpeditionLockout); package.add("AddExpeditionLockoutDuration", (void(*)(Client*, std::string, std::string, int))&Perl_Client_AddExpeditionLockoutDuration); @@ -3021,6 +3058,7 @@ void perl_register_client() package.add("AddPlatinum", (void(*)(Client*, uint32))&Perl_Client_AddPlatinum); package.add("AddPlatinum", (void(*)(Client*, uint32, bool))&Perl_Client_AddPlatinum); package.add("AddPVPPoints", &Perl_Client_AddPVPPoints); + package.add("AddRadiantCrystals", &Perl_Client_AddRadiantCrystals); package.add("AddSkill", &Perl_Client_AddSkill); package.add("Admin", &Perl_Client_Admin); package.add("ApplySpell", (void(*)(Client*, int))&Perl_Client_ApplySpell); @@ -3352,6 +3390,7 @@ void perl_register_client() package.add("ReloadDataBuckets", &Perl_Client_ReloadDataBuckets); package.add("RemoveAllExpeditionLockouts", (void(*)(Client*))&Perl_Client_RemoveAllExpeditionLockouts); package.add("RemoveAllExpeditionLockouts", (void(*)(Client*, std::string))&Perl_Client_RemoveAllExpeditionLockouts); + package.add("RemoveEbonCrystals", &Perl_Client_RemoveEbonCrystals); package.add("RemoveExpeditionLockout", &Perl_Client_RemoveExpeditionLockout); package.add("RemoveFromInstance", &Perl_Client_RemoveFromInstance); package.add("RemoveItem", (void(*)(Client*, uint32))&Perl_Client_RemoveItem); @@ -3359,6 +3398,7 @@ void perl_register_client() package.add("RemoveLDoNLoss", &Perl_Client_RemoveLDoNLoss); package.add("RemoveLDoNWin", &Perl_Client_RemoveLDoNWin); package.add("RemoveNoRent", &Perl_Client_RemoveNoRent); + package.add("RemoveRadiantCrystals", &Perl_Client_RemoveRadiantCrystals); package.add("ResetAA", &Perl_Client_ResetAA); package.add("ResetAllDisciplineTimers", &Perl_Client_ResetAllDisciplineTimers); package.add("ResetAllCastbarCooldowns", &Perl_Client_ResetAllCastbarCooldowns); diff --git a/zone/task_client_state.cpp b/zone/task_client_state.cpp index 369aebec9..8485352fd 100644 --- a/zone/task_client_state.cpp +++ b/zone/task_client_state.cpp @@ -1101,9 +1101,9 @@ void ClientTaskState::RewardTask(Client *c, const TaskInformation *ti, ClientTas if (ti->reward_points > 0) { if (ti->reward_point_type == static_cast(zone->GetCurrencyID(RADIANT_CRYSTAL))) { - c->AddCrystals(ti->reward_points, 0); + c->AddRadiantCrystals(ti->reward_points); } else if (ti->reward_point_type == static_cast(zone->GetCurrencyID(EBON_CRYSTAL))) { - c->AddCrystals(0, ti->reward_points); + c->AddEbonCrystals(ti->reward_points); } else { for (const auto& ac : zone->AlternateCurrencies) { if (ti->reward_point_type == ac.id) {