[Feature] Add Rule for dealing with augments when an item evolves (#4758)

This commit is contained in:
Mitch Freeman 2025-03-08 01:00:11 -04:00 committed by GitHub
parent 9f10c12874
commit 53610c2f0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 64 additions and 4 deletions

View File

@ -1163,6 +1163,7 @@ RULE_REAL(EvolvingItems, PercentOfSoloExperience, 0.1, "Percentage of solo exper
RULE_REAL(EvolvingItems, PercentOfGroupExperience, 0.1, "Percentage of group experience allocated to evolving items that require experience.")
RULE_REAL(EvolvingItems, PercentOfRaidExperience, 0.1, "Percentage of raid experience allocated to evolving items that require experience.")
RULE_INT(EvolvingItems, DelayUponEquipping, 30000, "Delay in ms before an evolving item will earn rewards after equipping. Default is 30000ms or 30s.")
RULE_BOOL(EvolvingItems, DestroyAugmentsOnEvolve, false, "If this is enabled, any augments in an item will be destroyed when the item evolves. Otherwise, send augments to the player via the parcel system (requires that the Parcel System be enabled).")
RULE_CATEGORY_END()
#undef RULE_CATEGORY

View File

@ -404,6 +404,7 @@ public:
void LoadParcels();
std::map<uint32, CharacterParcelsRepository::CharacterParcels> GetParcels() { return m_parcels; }
int32 FindNextFreeParcelSlot(uint32 char_id);
int32 FindNextFreeParcelSlotUsingMemory();
void SendParcelIconStatus();
void SendBecomeTraderToWorld(Client *trader, BazaarTraderBarterActions action);
@ -1900,7 +1901,7 @@ public:
void SendEvolvingPacket(int8 action, const CharacterEvolvingItemsRepository::CharacterEvolvingItems &item);
void DoEvolveItemToggle(const EQApplicationPacket* app);
void DoEvolveItemDisplayFinalResult(const EQApplicationPacket* app);
bool DoEvolveCheckProgression(const EQ::ItemInstance &inst);
bool DoEvolveCheckProgression(EQ::ItemInstance &inst);
void SendEvolveXPWindowDetails(const EQApplicationPacket* app);
void DoEvolveTransferXP(const EQApplicationPacket* app);
void SendEvolveXPTransferWindow();

View File

@ -71,7 +71,7 @@ void Client::SendEvolvingPacket(const int8 action, const CharacterEvolvingItemsR
void Client::ProcessEvolvingItem(const uint64 exp, const Mob *mob)
{
std::vector<const EQ::ItemInstance *> queue{};
std::vector<EQ::ItemInstance *> queue{};
for (auto &[key, inst]: GetInv().GetWorn()) {
LogEvolveItemDetail(
@ -298,7 +298,7 @@ void Client::DoEvolveItemDisplayFinalResult(const EQApplicationPacket *app)
}
}
bool Client::DoEvolveCheckProgression(const EQ::ItemInstance &inst)
bool Client::DoEvolveCheckProgression(EQ::ItemInstance &inst)
{
if (inst.GetEvolveProgression() < 100 || inst.GetEvolveLvl() == inst.GetMaxEvolveLvl()) {
return false;
@ -315,6 +315,48 @@ bool Client::DoEvolveCheckProgression(const EQ::ItemInstance &inst)
return false;
}
if (RuleB(EvolvingItems, EnableParcelMerchants) &&
!RuleB(EvolvingItems, DestroyAugmentsOnEvolve) &&
inst.IsAugmented()
) {
auto const augs = inst.GetAugmentIDs();
std::vector<CharacterParcelsRepository::CharacterParcels> parcels;
for (auto const &item_id: augs) {
if (!item_id) {
continue;
}
CharacterParcelsRepository::CharacterParcels p{};
p.char_id = CharacterID();
p.from_name = "Evolving Item Sub-System";
p.note = fmt::format(
"System automatically removed from {} which recently evolved.",
inst.GetItem()->Name
);
p.slot_id = FindNextFreeParcelSlotUsingMemory();
p.sent_date = time(nullptr);
p.item_id = item_id;
p.quantity = 1;
if (player_event_logs.IsEventEnabled(PlayerEvent::PARCEL_SEND)) {
PlayerEvent::ParcelSend e{};
e.from_player_name = p.from_name;
e.to_player_name = GetCleanName();
e.item_id = p.item_id;
e.quantity = 1;
e.sent_date = p.sent_date;
RecordPlayerEventLog(PlayerEvent::PARCEL_SEND, e);
}
parcels.push_back(p);
}
CharacterParcelsRepository::InsertMany(database, parcels);
SendParcelStatus();
SendParcelIconStatus();
}
CheckItemDiscoverability(new_inst->GetID());
PlayerEvent::EvolveItem e{};

View File

@ -888,6 +888,22 @@ void Client::AddParcel(CharacterParcelsRepository::CharacterParcels &parcel)
"Unable to send parcel at this time. Please try again later."
);
SendParcelAck();
return;
}
}
int32 Client::FindNextFreeParcelSlotUsingMemory()
{
auto const results = GetParcels();
if (results.empty()) {
return PARCEL_BEGIN_SLOT;
}
for (uint32 i = PARCEL_BEGIN_SLOT; i <= RuleI(Parcel, ParcelMaxItems); i++) {
if (!results.contains(i)) {
return i;
}
}
return INVALID_INDEX;
}