Issue #25237: Problems with settler transfer
Settler transfer means to send settlers from one workshop to another with the 'Move' command in workshop mode
This operation was addressed in an official fix (tagged with no. 89671):
; 89671: no need to remove actor from workshop completely when assigning to different workshop ;UnassignActor_Private (assignedActor, false, bResetMode = bResetMode)
Unfortunately though, this "fix" creates another problem, because the bool passed in to UnassignActor_Private determines only whether an actor is completely removed from the workshop (if true) or not at all (false). An intermediate process that performs most (but not all) of the steps required to remove an actor from a workshop does not exist. Thus, if a settler is transferred to another workshop, he's currently not removed from its old workshop at all:
It's basically a good idea to skip the removal process because the function that handles the transfer subsequently overwrites all of his flags, links and properties with the values of the new workshop, so it doesn't matter whether the data from the old workshop are previously cleared or not. However, at least his bed needs to be unassigned. With the current settings, a settler who is moved to another workshop keeps his bed at the old workshop, and this leads to short term trouble with bed assignement because that faulty assignment does not get sorted out until the next reset runs on the affected workshops.
Likewise, we also have to make sure that the population rating values are properly updated. If an actor is not removed from a workshop, the script increments the unassigned population rating; if he is removed, it decrements the total population rating instead. Thus, when we transfer a settler and don't run the removal process at all, we end up with wrong values for both ratings.
Thus, unless there are good reasons to skip specific operations on transferred settlers, it's better to fix this by resetting the bool to 'true' and run the full romoval process anyway instead of adding checks to individual operations as they only would make the removal process slower for all actors on which it is called. A close inspection of the individual operations revealed two things:
(1) It turned out that the removal process never clears the home marker link. This doesn't matter for transferred settlers because the function that handles the transfer updates the link for their new workshop subsequently. Though, it matters for settlers that are entirely removed from a workshop because they remain linked to a reference. That's in fact another vanilla bug, but I will fix it for this ticket too.
(2) There is in fact one operation that should not run on transferred settlers: they should not be removed from their workshop alias. Even though the transfer process would fill them back into this alias subsequently, it's probably not a good idea to not keep them in any alias even for a short period of time. This doesn't matter for settlers that are completely removed (e.g.. dead actors), but we do not want an actor we actually want to keep to get lost for obscure reasons
Thus, to fix this, we have to tell UnassignActor_Private that there is a third option in addition to full removal and no removal. To get this done, I had to add another bool argument (to the private function only, so no API issue)