[Feature] Cleanup Group Split Money Logic (#3583)

* addresses #2498

* fix some logic #2498

* fixes #2498

* derpy derp derp #2498

* leave default argument to appease build

* Formatting

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
Clayton Dunwell 2023-09-17 14:22:26 -04:00 committed by GitHub
parent f2f0228aa4
commit eb545a18a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 62 deletions

View File

@ -14423,7 +14423,7 @@ void Client::Handle_OP_Split(const EQApplicationPacket *app)
if (raid)
raid->SplitMoney(raid->GetGroup(this), split->copper, split->silver, split->gold, split->platinum);
else if (group)
group->SplitMoney(split->copper, split->silver, split->gold, split->platinum);
group->SplitMoney(split->copper, split->silver, split->gold, split->platinum, this);
return;

View File

@ -113,89 +113,91 @@ Group::~Group()
}
//Split money used in OP_Split (/split and /autosplit).
void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter) {
//avoid unneeded work
if (
!copper &&
!silver &&
!gold &&
!platinum
) {
void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter)
{
// Return early if no money to split.
if (!copper && !silver && !gold && !platinum) {
return;
}
// splitter can not be nullptr
if (!splitter) {
return;
}
// find number of clients in group and check if splitter is in group
uint8 member_count = 0;
bool splitter_in_group = false;
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) {
// Don't split with Mercs or Bots
if (members[i] && members[i]->IsClient()) {
member_count++;
if (members[i]->CastToClient() == splitter) {
splitter_in_group = true;
}
}
}
// Return if no group members found.
if (!member_count) {
return;
}
uint32 modifier;
if (member_count > 1) {
modifier = platinum % member_count;
if (modifier) {
platinum -= modifier;
gold += 10 * modifier;
// Splitter must be in group
if (!splitter_in_group) {
return;
}
modifier = gold % member_count;
// Calculate split and remainder for each coin type
uint32 copper_split = copper / member_count;
uint32 copper_remainder = copper % member_count;
uint32 silver_split = silver / member_count;
uint32 silver_remainder = silver % member_count;
uint32 gold_split = gold / member_count;
uint32 gold_remainder = gold % member_count;
uint32 platinum_split = platinum / member_count;
uint32 platinum_remainder = platinum % member_count;
if (modifier) {
gold -= modifier;
silver += 10 * modifier;
// Loop through the group members to split the coins.
for (const auto &m: members) {
if (m && m->IsClient()) {
Client *member_client = m->CastToClient();
uint32 receive_copper = copper_split;
uint32 receive_silver = silver_split;
uint32 receive_gold = gold_split;
uint32 receive_platinum = platinum_split;
// splitter gets the remainders of coin
if (member_client == splitter) {
receive_copper += copper_remainder;
receive_silver += silver_remainder;
receive_gold += gold_remainder;
receive_platinum += platinum_remainder;
}
modifier = silver % member_count;
if (modifier) {
silver -= modifier;
copper += 10 * modifier;
}
}
auto copper_split = copper / member_count;
auto silver_split = silver / member_count;
auto gold_split = gold / member_count;
auto platinum_split = platinum / member_count;
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (members[i] && members[i]->IsClient()) { // If Group Member is Client
members[i]->CastToClient()->AddMoneyToPP(
copper_split,
silver_split,
gold_split,
platinum_split,
true
);
// Add the coins to the player's purse.
member_client->AddMoneyToPP(receive_copper, receive_silver, receive_gold, receive_platinum, true);
// If logging of player money transactions is enabled, record the transaction.
if (player_event_logs.IsEventEnabled(PlayerEvent::SPLIT_MONEY)) {
auto e = PlayerEvent::SplitMoneyEvent{
.copper = copper_split,
.silver = silver_split,
.gold = gold_split,
.platinum = platinum_split,
.player_money_balance = members[i]->CastToClient()->GetCarriedMoney(),
.copper = receive_copper,
.silver = receive_silver,
.gold = receive_gold,
.platinum = receive_platinum,
.player_money_balance = member_client->GetCarriedMoney(),
};
RecordPlayerEventLogWithClient(members[i]->CastToClient(), PlayerEvent::SPLIT_MONEY, e);
RecordPlayerEventLogWithClient(member_client, PlayerEvent::SPLIT_MONEY, e);
}
members[i]->CastToClient()->MessageString(
// Notify the player of their received coins.
member_client->MessageString(
Chat::MoneySplit,
YOU_RECEIVE_AS_SPLIT,
Strings::Money(
platinum_split,
gold_split,
silver_split,
copper_split
).c_str()
Strings::Money(receive_platinum, receive_gold, receive_silver, receive_copper).c_str()
);
}
}