diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index ede731167..3f3b508b8 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -130,6 +130,11 @@ enum CrystalReclaimTypes Radiant = 4, }; +namespace ItemStackSizeConstraint { + constexpr int16 Minimum = 1; + constexpr int16 Maximum = 1000; +} + /////////////////////////////////////////////////////////////////////////////// diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index fd93983fc..0ecc5a597 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -5596,9 +5596,20 @@ void Client::Handle_OP_CrystalCreate(const EQApplicationPacket *app) } // Prevent the client from creating more than they have. - const uint32 amount = EQ::ClampUpper(quantity, current_quantity); + uint32 amount = EQ::ClampUpper(quantity, current_quantity); const uint32 item_id = is_radiant ? RuleI(Zone, RadiantCrystalItemID) : RuleI(Zone, EbonCrystalItemID); + const auto item = database.GetItem(item_id); + // Prevent pulling more than max stack size or 1,000 (if stackable), whichever is lesser + const uint32 max_reclaim_amount = EQ::Clamp( + item && item->Stackable ? item->StackSize : ItemStackSizeConstraint::Minimum, + ItemStackSizeConstraint::Minimum, + ItemStackSizeConstraint::Maximum + ); + if (amount > max_reclaim_amount) { + amount = max_reclaim_amount; + } + const bool success = SummonItem(item_id, amount); if (!success) { return;