About this mod
Fixes a bug in which inactive party members receive unequal experience even when they are the same level. Now Eder won't hog all the bench experience!
- Permissions and credits
- Changelogs
This mod changes/replaces the Assembly-CSharp.dll library, and is thus not compatible with other mods that do the same (even if they don't touch the AssignXPToInactiveParty method).
Installation:
- Backup Assembly-CSharp.dll. It should be in your POE2 game folder, under PillarsOfEternityII_Data\Managed. I suggest adding ".backup" to the extension, but that's just me.
- Download the Assembly-CSharp.zip file from this site.
- Unzip it and replace the Assembly-CSharp.dll in your POE2 game folder.
Patching Compatibility with Other Assembly-CSharp.dll mods:
I don't use any mods which replace Assembly-CSharp.dll, but in case there are others, I'm listing out the steps to incorporate this mod into another. I'm going to assume no/little coding knowledge.
- Back up Assembly-CSharp.dll. It should be in the POE2 game directory, under PillarsOfEternityII_Data\Managed.
- Open Assembly-CSharp.dll in dnSpy. Website: here, or go directly to the releases page.
- Find the AssignXPToInactiveParty method. Use the lower search box (see the highlighted text in the image below). It should be in Game.PartyManager.
- Double click the orange text below the search box.
- Right click in the upper right/main window and select "Edit Method (C#)..."
- Change the code to what you want. I would suggest the following.
private void AssignXPToInactiveParty(int xp)
{
int newxp = xp;
if (GameState.PlayerCharacter == null || GameState.PlayerCharacter.Stats == null || DataObject.IsNullOrEmpty(ExperienceTable.GameData))
{
return;
}
IList<PartyMemberData> partyMembersOfInactiveStatus = this.GetPartyMembersOfInactiveStatus();
if (partyMembersOfInactiveStatus != null && partyMembersOfInactiveStatus.Count > 0)
{
foreach (PartyMemberData partyMemberData in partyMembersOfInactiveStatus)
{
if (partyMemberData != null && partyMemberData.MemberType == PartyMemberType.Primary)
{
if (partyMemberData.Level <= GameState.PlayerCharacter.Stats.Level)
{
newxp = xp * ExperienceTable.GameData.StoredExperiencePercent / 100;
}
else
{
newxp = xp * ExperienceTable.GameData.StoredExperienceHigherLevelPercent / 100;
}
partyMemberData.Experience += newxp;
}
}
}
} - Save.
If you want to make other changes (such as applying no inactive experience penalty at all), you can take the above and change newxp such that it always matches xp.
For the purposes of seeing if you've already changed the code, the original code (as of patch 5.0.0.0040) is as follows. If (by some miracle) another patch comes out and the code for this method changes, different changes may be necessary (or hopefully this won't be needed at all).
private void AssignXPToInactiveParty(int xp)
{
if (GameState.PlayerCharacter == null || GameState.PlayerCharacter.Stats == null || DataObject.IsNullOrEmpty(ExperienceTable.GameData))
{
return;
}
IList<PartyMemberData> partyMembersOfInactiveStatus = this.GetPartyMembersOfInactiveStatus();
if (partyMembersOfInactiveStatus != null && partyMembersOfInactiveStatus.Count > 0)
{
foreach (PartyMemberData partyMemberData in partyMembersOfInactiveStatus)
{
if (partyMemberData != null && partyMemberData.MemberType == PartyMemberType.Primary)
{
if (partyMemberData.Level <= GameState.PlayerCharacter.Stats.Level)
{
xp = xp * ExperienceTable.GameData.StoredExperiencePercent / 100;
}
else
{
xp = xp * ExperienceTable.GameData.StoredExperienceHigherLevelPercent / 100;
}
partyMemberData.Experience += xp;
}
}
}
}
Credit: I would not have done this without Fhav6X's tutorial on the Obsidian forums.