Issue Data
|
Issue #29148: WorkshopParentScript.ResetWorkshop() can double-count population
So, WorkshopParentScript listens for OnLocationChange events on the player.
If a location that's switched to is a workshop, it will run ResetWorkshop on the workbench at that location (line 1050 in the vanilla version of the script). ResetWorkshop() (line 2998) loops over all the actors at the settlement (3137), calling AddActorToWorkshop on most of them (3143). Toward the end of AddActorToWorkshop(), we'll find this chunk of code (2008): if !workshopRef.RecalculateWorkshopResources() wsTrace(" RecalculateWorkshopResources returned false - add population manually") ; add population manually if couldn't recalc ModifyResourceData(WorkshopRatings[WorkshopRatingPopulation].resourceValue, workshopRef, 1) endif What this is doing is trying to run RecalculateWorkshopResources() on the local workshop to record the actor in the local WorkshopRatingPopulation AV. If this succeeds, which it will if the player is at the workshop (see also #23496), it will run the native RecalculateResources() function on the workshop, which uses some engine-level code to quickly record local resources and save the resulting actor values to the local workbench. If the player is not at the workshop, RecalculateWorkshopResources() will return false, and AddActorToWorkshop() will instead manually modify the WorkshopRatingPopulation on the workbench. The issue here is that, when RecalculateWorkshopResources() succeeds, it records the full population of the settlement—or, at least the ones that are loaded. But, AddActorToWorkshop() is a long function, and it takes a while to call it on every settler at the settlement. If the player leaves the settlement before ResetWorkshop() finishes its loop over every settler, usually because they've fast travelled away, RecalculateWorkshopResources() will begin failing, and any remaining population at the settlement will be counted twice—one by the native RecalculateResources() when it worked, and again by the manual addition of points to the workbench AV. I think the best fix for this is to just change this line (2821 in UFO4P v2.1.1) if !workshopRef.RecalculateWorkshopResources()to read if !bResetMode && !workshopRef.RecalculateWorkshopResources() The reason for this is that ResetWorkshop() will have already called this function (line 3071 UFO4P 2.1.1) just before starting the loop that calls AddActorToWorkshop() on each actor, so it's pointless to try counting them again, but the function will still be able to "remotely" increment the population value for the many other places where AddActorToWorkshop() is called with the intention of adding a new actor. |
This should never have run for bAlreadyAssigned = true. Only if false, an actor will actually have been added to the workshop (ResetWorkshop doesn't remove any actors from the workshop, not even temporarily).
Checking for bAlreadyAssigned == false now before running the resource recalculation. In that case, we also don't have to care about RecalculateWorkshopResources() returning 'false' because it doesn't include any actors whose workshopID doesn't match.
Checking for bAlreadyAssigned == false now before running the resource recalculation. In that case, we also don't have to care about RecalculateWorkshopResources() returning 'false' because it doesn't include any actors whose workshopID doesn't match.
Oh, fair enough. bResetMode and bAlreadyAssigned are usually equal in most cases anyway, but I suppose checking bAlreadyAssigned makes more sense. I checked the rest of the game code and it looks like there are a few rare cases where a new actor is added with the bResetMode flag set for some reason, so that should fix that if it ever comes up.
Just to confirm that it works, since it's been a while since I submitted this, I haven't noticed a single instance of settler under/overcounting ever since I implemented my version of the fix in ~200 hours or so. Prior to it I'd notice that at least one settlement would be badly over-counted nearly every time I checked the map/pip-boy numbers in a while, so even my slightly imperfect fix was a huge improvement.
Just to confirm that it works, since it's been a while since I submitted this, I haven't noticed a single instance of settler under/overcounting ever since I implemented my version of the fix in ~200 hours or so. Prior to it I'd notice that at least one settlement would be badly over-counted nearly every time I checked the map/pip-boy numbers in a while, so even my slightly imperfect fix was a huge improvement.
Showing Comments 1 - 2 of 2