The next release of FTSE has taken me much longer than I expected (or would like), as I've been very limited on free time lately. However, in working on it, I came up with a fix for the crash when all special encounters are visited. With the fix, special encounters should properly revert to normal encounters once all have been visited.
As normal, fix below, followed by gory details.
Raw hex patch:
FTSE patch (include in the "patches" section of FTSE_config.json):
---
Fix details:
Inside a global campaign object, the game keeps a list of special encounters available in that campaign. When a special encounter is visited, that encounter is removed from the list. This has the following effects:
First, if the special encounter has a low index in the list, it will shift all other entries in the list down by 1. This appears to cause the locations of those later special encounters in the list to shift.
When future special encounter squares are reached, it is possible that the index assigned to that square may no longer exist (e.g. the square with special encounter #30 will always shift if it isn't the first found, and index 30 will be off the end of the list). If this happens, the game will choose the last special encounter on the list.
Finally, once the list becomes empty, the game may still try to spawn a special encounter, but will not check if the list is empty, resulting in a read from an incorrect memory location. In nearly all cases, this will cause a crash once it tries to use the value as a pointer. If it gets lucky and finds a pointer to a valid memory location, it will instead fail back to the main menu with a "Cannot load mission" error.
The fix adds an empty-list check to the routine that selects the special encounter. When that check finds the list empty, it jumps to the instruction that's normally used when the special encounter circle won't fit on the current world map location. This results in a fallback to normal encounters.
As normal, fix below, followed by gory details.
Raw hex patch:
Code:
2BB00E:
7D 04 8D 44 24 1C 8B 00 8B 74 24 18
-> 8B 74 24 18 7D 02 EB 25 8B 00 90 90
FTSE patch (include in the "patches" section of FTSE_config.json):
Code:
{
"name": "Special encounter crash fix",
"apply": "true",
"changes": [
{
"offset": "6bb00e",
"patch": "8b7424187d02eb258b009090"
}
]
},
---
Fix details:
Inside a global campaign object, the game keeps a list of special encounters available in that campaign. When a special encounter is visited, that encounter is removed from the list. This has the following effects:
First, if the special encounter has a low index in the list, it will shift all other entries in the list down by 1. This appears to cause the locations of those later special encounters in the list to shift.
When future special encounter squares are reached, it is possible that the index assigned to that square may no longer exist (e.g. the square with special encounter #30 will always shift if it isn't the first found, and index 30 will be off the end of the list). If this happens, the game will choose the last special encounter on the list.
Finally, once the list becomes empty, the game may still try to spawn a special encounter, but will not check if the list is empty, resulting in a read from an incorrect memory location. In nearly all cases, this will cause a crash once it tries to use the value as a pointer. If it gets lucky and finds a pointer to a valid memory location, it will instead fail back to the main menu with a "Cannot load mission" error.
The fix adds an empty-list check to the routine that selects the special encounter. When that check finds the list empty, it jumps to the instruction that's normally used when the special encounter circle won't fit on the current world map location. This results in a fallback to normal encounters.