Honorable Member Owsap 8246 Posted April 17 Honorable Member Share Posted April 17 I recently came across this issue when updating some things on the party (group) system and I realized that this problem was present on all the branches of the source. Although I've seen certain topics with some solutions, they don't provide much information and, in my opinion, a good solution. So, I'll share mine with you and you can use it if you're happy with the results. The Bug When you set a role to a member as a leader, it will give the member a certain bonus according to the role, this bonus is given if the leadership skill is high. Now, if you decide to remove the members role, in theory the bonus should be removed. However, when this happens, it will only compute the battle points of the player which will make some bonuses of certain roles the same until the character computes all his points again. For example, if you set a member with the tanker role, which grants a bonus of additional health points and then remove the role from the member, the bonus will not be removed until the character computes his points again. It doesn't remove the bonus because the function by default only computes the battle points, this relates to roles like, attacker and defender. Realization So far, we realized a possible solution, which is replacing the ComputeBattlePoints with ComputePoints, well sure, and I've seen this solution on this forum in some help request topics but this comes to a major cost in performance since the role computation function CParty::ComputeRolePoint is frequently called. The Solution What we really want to do is check if the member has any bonus assigned to a role, remove the bonus and finally compute the character's points appropriately, avoiding constant updates to the ComputePoints function. If the member doesn't have any bonus given from a role, there will be no need to calculate the points. Spoiler /// @ server/game/src/party.cpp // Search @ void CParty::ComputeRolePoint if (!bAdd) { ch->PointChange(POINT_PARTY_ATTACKER_BONUS, -ch->GetPoint(POINT_PARTY_ATTACKER_BONUS)); ch->PointChange(POINT_PARTY_TANKER_BONUS, -ch->GetPoint(POINT_PARTY_TANKER_BONUS)); ch->PointChange(POINT_PARTY_BUFFER_BONUS, -ch->GetPoint(POINT_PARTY_BUFFER_BONUS)); ch->PointChange(POINT_PARTY_SKILL_MASTER_BONUS, -ch->GetPoint(POINT_PARTY_SKILL_MASTER_BONUS)); ch->PointChange(POINT_PARTY_DEFENDER_BONUS, -ch->GetPoint(POINT_PARTY_DEFENDER_BONUS)); ch->PointChange(POINT_PARTY_HASTE_BONUS, -ch->GetPoint(POINT_PARTY_HASTE_BONUS)); ch->ComputeBattlePoints(); return; } // Replace with (you might need to include <array> in your file) if (!bAdd) { const BYTE bMaxRoleNum = PARTY_ROLE_MAX_NUM - PARTY_ROLE_ATTACKER; std::array<long, bMaxRoleNum> alPartyPoints = { ch->GetPoint(POINT_PARTY_ATTACKER_BONUS), ch->GetPoint(POINT_PARTY_TANKER_BONUS), ch->GetPoint(POINT_PARTY_BUFFER_BONUS), ch->GetPoint(POINT_PARTY_SKILL_MASTER_BONUS), ch->GetPoint(POINT_PARTY_HASTE_BONUS), ch->GetPoint(POINT_PARTY_DEFENDER_BONUS) }; bool bComputePoints = false; for (BYTE bIndex = 0; bIndex < bMaxRoleNum; ++bIndex) { if (alPartyPoints[bIndex] != 0) { BYTE bRole = PARTY_ROLE_ATTACKER + bIndex; WORD wPointType = POINT_NONE; switch (bRole) { case PARTY_ROLE_ATTACKER: wPointType = POINT_PARTY_ATTACKER_BONUS; break; case PARTY_ROLE_TANKER: wPointType = POINT_PARTY_TANKER_BONUS; break; case PARTY_ROLE_BUFFER: wPointType = POINT_PARTY_BUFFER_BONUS; break; case PARTY_ROLE_SKILL_MASTER: wPointType = POINT_PARTY_SKILL_MASTER_BONUS; break; case PARTY_ROLE_HASTE: wPointType = POINT_PARTY_HASTE_BONUS; break; case PARTY_ROLE_DEFENDER: wPointType = POINT_PARTY_DEFENDER_BONUS; break; default: continue; } ch->PointChange(wPointType, -alPartyPoints[bIndex]); bComputePoints = true; } } if (bComputePoints) ch->ComputePoints(); return; } // If flexibility and readability are more important for you, than you can use a map. // However, it may have a slight performance overhead compared to array access. if (!bAdd) { std::map<WORD, long> mPartyPoints; mPartyPoints[POINT_PARTY_ATTACKER_BONUS] = ch->GetPoint(POINT_PARTY_ATTACKER_BONUS); mPartyPoints[POINT_PARTY_TANKER_BONUS] = ch->GetPoint(POINT_PARTY_TANKER_BONUS); mPartyPoints[POINT_PARTY_BUFFER_BONUS] = ch->GetPoint(POINT_PARTY_BUFFER_BONUS); mPartyPoints[POINT_PARTY_SKILL_MASTER_BONUS] = ch->GetPoint(POINT_PARTY_SKILL_MASTER_BONUS); mPartyPoints[POINT_PARTY_HASTE_BONUS] = ch->GetPoint(POINT_PARTY_HASTE_BONUS); mPartyPoints[POINT_PARTY_DEFENDER_BONUS] = ch->GetPoint(POINT_PARTY_DEFENDER_BONUS); bool bComputePoints = false; for (const auto& it : mPartyPoints) { if (it.second != 0) { ch->PointChange(it.first, -it.second); bComputePoints = true; } } if (bComputePoints) ch->ComputePoints(); return; } 5 1 7 https://owsap.dev/ / https://osf.owsap.dev/ Link to comment Share on other sites More sharing options...
Active Member ReFresh 2349 Posted April 18 Active Member Share Posted April 18 (edited) Along with this problem, there're some little visual problems too, probably not only visual. When the party leader (or someone else from the group) goes offline the EXP bonus icon should dissapear from their UI. (I don't really know, if the EXP bonus value is still counting to the group, but looks like it's counting). I'm talking about this little icon: Also, if the party leader goes offline and the player have assigned a party role, the little icon showing the bonus of the party role should dissapear too (here is the bonus value removed, so it looks like, it's only visual problem): Edited April 18 by ReFresh Core X - External 2 Internal I'll be always helpful! Link to comment Share on other sites More sharing options...
Mafuyu 51 Posted April 21 Share Posted April 21 (edited) after over and over granting and revoking the same bonus, it destorys your character. first of all, it stacks over time more and more, by also bringing other stats to negativ. pretty lit please post your full function void CParty::ComputeRolePoint(LPCHARACTER ch, BYTE bRole, bool bAdd) edit: your second option works perfectly fine. Your first option is bugged af, dunno. duping every attribute while bringing others to negativ, dunno whats broken there Edited April 21 by Mafuyu Core X - External 2 Internal Link to comment Share on other sites More sharing options...
Recommended Posts