***NOTE***: A fix has been found for the duplicate effect issue. This patch should still be considered still-in-test, as I can't be certain there aren't more bugs uncovered with the fix.
---
I've been itching to have another playthrough of FoT, with a high Charisma leader-type character, but it bothered me that Team Player was bugged. I had a go at fixing it yesterday, and I think I have it (and Loner as well) working correctly.
TL;DR: If you just want Team Player to activate, and behave like the current Loner (always enabled), the following hex locations can be changed (original values indicated first, so that you can validate the location is correct):
0x00171f9e: 28 00 8a -> 80 9a 89
0x0017cf61: 32 c0 -> 80 01
If you want both perks fixed to behave as described, there are seven locations to patch:
0x00171f9e: 28 00 8a -> 80 9a 89
0x0017cbb5 88 -> 89
0x0017ce4c 66 39 7c c8 06 -> e9 b0 02 00 00
0x0017ced8 39 9e d2 0e 00 00 74 79 32 c0 -> e9 54 0a 00 00 90 74 7b 90 90
0x0017cf59 39 9e d6 0e 00 00 74 79 32 c0 -> eb 7f 39 9e d6 0e 00 00 74 77
0x0017d101 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
-> c6 44 24 14 01 66 39 7c c8 06 e9 41 fd ff ff
0x0017d931 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
-> 8a 44 24 14 39 9e d2 0e 00 00 e9 9e f5 ff ff
Because of the way the fix is applied, a squad member with both "Team Player" and "Loner" perks (possible with Gain Charisma) would apply only the effect of Loner, and ignore Team Player entirely.
Note that I've done minimal testing so far (though effects appear to be applied and removed correctly), so please test and let me know if anything appears to break.
Details of the fix below:
The routine starting at 0017cb90 appears to apply a number of effects to an entity based on a provided list of "nearby" entities. This includes checks for Leader, Vat Skin, and likely others as well (I didn't check every path, but there's also reference to Glowing One in one pointer).
The problem with Loner and Team Player is that the routine *does* check for nearby teammates, but it doesn't save this information anywhere. As a result, when it checks both perks, it uses a default value of "0" (false) for determining if teammates are nearby. The code for applying the perk effects is in place, but never works correctly because of this (Loner always triggers, and Team Player never does).
The second change in the above patch initializes ESP+0x12 through ESP+0x15 to zero (previous code only initialized ESP+0x12 and ESP+0x13). Currently, ESP+0x12 is used to indicate "Leader nearby", and ESP+0x13 for "Vat Skin nearby". ESP+0x14 and ESP+0x15 are unused pad bytes, so I use ESP+0x14 for "squad member nearby".
The third change is made at the point in the routine where it has detected an entity belonging to the same team in the nearby list. I make a JMP out to an unused pad section between subroutines (sixth change), and set ESP+0x14 to 1, apply the original instruction the JMP replaced, and JMP back.
The fourth change is at the point where the Loner perk flag is checked. I modify this to JMP to a second unused pad section (seventh change), where I set AL to the saved value in ESP+0x14, perform the CMP that the JMP instruction replaced, and JMP back. I also modified the target location of the conditional jump if the Loner perk isn't set, to go straight into the Team Player check (this saves me from having to find yet another unused section to reload AL with the correct value, but this has a side effect described below).
The fifth change is handling for Team Player. If this section is entered after applying Loner perk (meaning it's selected), then it will reach the first instruction, which bypasses check for Team Player (this is because the code applying the Loner perk effects overwrites the value in AL, so this check would always break if the Loner perk was applied). Otherwise, if this section is entered from the conditional jump from the Loner flag being false, then the first JMP is skipped. The CMP and conditional jump for checking the Team Player flag are shifted two bytes, and the unneeded XOR AL,AL is removed. A cleaner fix for this would use a third unused pad section and do the same steps as above for Loner, but I skipped this since I figured having both Loner and Team Player was unlikely.
Now, back to the first change - with Team Player fixed, a new bug was uncovered, where the game would not properly save the fact that the effect had been applied. This would result in duplicate applications of the effect every time the game was saved/loaded, or on area transitions. The cause appears to be that the effect added to the saved entity for this effect was named "Team", while there was already a field in the entity named "Team" (for the entity's, well, team). This was fixed by adjusting the string pointer for the saved copy of the "Team Player" flag to a new string, in this case "team" (all lowercase). (It's not possible to change the string itself, as in the Sniper fix, since the EXE only has one copy of the uppercase "Team" string, and it's used in at least three places - assigning team to an entity, keeping track of Team Player effect, and for trigger rules.)
Finally - one other issue I noted is that Vat Skin appears to also be working incorrectly. The Perception penalty is actually -2, not -1, and it only applies to members of the same team, not opponents. This appears fixable (the Vat Skin check would need to be shifted to before the same-team check), but I don't know if anyone uses Vat Skin offensively, so not sure if this is worth the effort.
---
I've been itching to have another playthrough of FoT, with a high Charisma leader-type character, but it bothered me that Team Player was bugged. I had a go at fixing it yesterday, and I think I have it (and Loner as well) working correctly.
TL;DR: If you just want Team Player to activate, and behave like the current Loner (always enabled), the following hex locations can be changed (original values indicated first, so that you can validate the location is correct):
0x00171f9e: 28 00 8a -> 80 9a 89
0x0017cf61: 32 c0 -> 80 01
If you want both perks fixed to behave as described, there are seven locations to patch:
0x00171f9e: 28 00 8a -> 80 9a 89
0x0017cbb5 88 -> 89
0x0017ce4c 66 39 7c c8 06 -> e9 b0 02 00 00
0x0017ced8 39 9e d2 0e 00 00 74 79 32 c0 -> e9 54 0a 00 00 90 74 7b 90 90
0x0017cf59 39 9e d6 0e 00 00 74 79 32 c0 -> eb 7f 39 9e d6 0e 00 00 74 77
0x0017d101 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
-> c6 44 24 14 01 66 39 7c c8 06 e9 41 fd ff ff
0x0017d931 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
-> 8a 44 24 14 39 9e d2 0e 00 00 e9 9e f5 ff ff
Because of the way the fix is applied, a squad member with both "Team Player" and "Loner" perks (possible with Gain Charisma) would apply only the effect of Loner, and ignore Team Player entirely.
Note that I've done minimal testing so far (though effects appear to be applied and removed correctly), so please test and let me know if anything appears to break.
Details of the fix below:
The routine starting at 0017cb90 appears to apply a number of effects to an entity based on a provided list of "nearby" entities. This includes checks for Leader, Vat Skin, and likely others as well (I didn't check every path, but there's also reference to Glowing One in one pointer).
The problem with Loner and Team Player is that the routine *does* check for nearby teammates, but it doesn't save this information anywhere. As a result, when it checks both perks, it uses a default value of "0" (false) for determining if teammates are nearby. The code for applying the perk effects is in place, but never works correctly because of this (Loner always triggers, and Team Player never does).
The second change in the above patch initializes ESP+0x12 through ESP+0x15 to zero (previous code only initialized ESP+0x12 and ESP+0x13). Currently, ESP+0x12 is used to indicate "Leader nearby", and ESP+0x13 for "Vat Skin nearby". ESP+0x14 and ESP+0x15 are unused pad bytes, so I use ESP+0x14 for "squad member nearby".
The third change is made at the point in the routine where it has detected an entity belonging to the same team in the nearby list. I make a JMP out to an unused pad section between subroutines (sixth change), and set ESP+0x14 to 1, apply the original instruction the JMP replaced, and JMP back.
The fourth change is at the point where the Loner perk flag is checked. I modify this to JMP to a second unused pad section (seventh change), where I set AL to the saved value in ESP+0x14, perform the CMP that the JMP instruction replaced, and JMP back. I also modified the target location of the conditional jump if the Loner perk isn't set, to go straight into the Team Player check (this saves me from having to find yet another unused section to reload AL with the correct value, but this has a side effect described below).
The fifth change is handling for Team Player. If this section is entered after applying Loner perk (meaning it's selected), then it will reach the first instruction, which bypasses check for Team Player (this is because the code applying the Loner perk effects overwrites the value in AL, so this check would always break if the Loner perk was applied). Otherwise, if this section is entered from the conditional jump from the Loner flag being false, then the first JMP is skipped. The CMP and conditional jump for checking the Team Player flag are shifted two bytes, and the unneeded XOR AL,AL is removed. A cleaner fix for this would use a third unused pad section and do the same steps as above for Loner, but I skipped this since I figured having both Loner and Team Player was unlikely.
Now, back to the first change - with Team Player fixed, a new bug was uncovered, where the game would not properly save the fact that the effect had been applied. This would result in duplicate applications of the effect every time the game was saved/loaded, or on area transitions. The cause appears to be that the effect added to the saved entity for this effect was named "Team", while there was already a field in the entity named "Team" (for the entity's, well, team). This was fixed by adjusting the string pointer for the saved copy of the "Team Player" flag to a new string, in this case "team" (all lowercase). (It's not possible to change the string itself, as in the Sniper fix, since the EXE only has one copy of the uppercase "Team" string, and it's used in at least three places - assigning team to an entity, keeping track of Team Player effect, and for trigger rules.)
Finally - one other issue I noted is that Vat Skin appears to also be working incorrectly. The Perception penalty is actually -2, not -1, and it only applies to members of the same team, not opponents. This appears fixable (the Vat Skin check would need to be shifted to before the same-team check), but I don't know if anyone uses Vat Skin offensively, so not sure if this is worth the effort.
Last edited: