Machiavelli24
Mod creator
- Joined
- May 9, 2012
- Messages
- 818
I have a while loop that is suppose to remove every specialists from a building (so it can safely be deleted) that is getting stuck in an infinite loop during an AI turn. TASK_REMOVE_SPECIALIST seems to fail to remove the specialist from the building.
The odd thing is that while I can consistently produce the infinite loop during the AI turn, if I use fireturner to execute the TASK_REMOVE_SPECIALIST for the AI during my turn it correctly removes the specialist. This implies 1) I have a syntax error in the code below or 2) TASK_REMOVE_SPECIALIST really is failing to remove the specialist but only during the AI's turn.
Looking through the C++ code I originally thought it could be an issue with the citizen being automatically reassigned as a specialist to the same building, since DoAddBestCitizenFromUnassigned gets called as part of TASK_REMOVE_SPECIALIST.
From CvCity.cpp
So I added lines to set city
oTask(TaskTypes.TASK_NO_AUTO_ASSIGN_SPECIALISTS, 0, 0, 1) (and change it back afterward) and tested it. It correctly turned off autoAssign (verified via city:IsNoAutoAssignSpecialists()) but the specialists count continued to remain stuck at 1 and the infinite loop persisted.
--------------
Another theory was that DoRemoveSpecialistFromBuilding was failing to remove the specialist. It will return out if pkBuildingInfo == NULL, but I don't see how that can happen during an AI turn but not during a human turn.
From CvCitizens.cpp
Has anyone else seen behavior like this before? Removing specialists to safely delete a building is such a common thing I expect this is a well trod area.
The odd thing is that while I can consistently produce the infinite loop during the AI turn, if I use fireturner to execute the TASK_REMOVE_SPECIALIST for the AI during my turn it correctly removes the specialist. This implies 1) I have a syntax error in the code below or 2) TASK_REMOVE_SPECIALIST really is failing to remove the specialist but only during the AI's turn.
Code:
while(cityToRemove:GetNumSpecialistsInBuilding(buildingID) > 0) do
cityToRemove:DoTask(TaskTypes.TASK_REMOVE_SPECIALIST, 0, buildingID, 0);
end
Looking through the C++ code I originally thought it could be an issue with the citizen being automatically reassigned as a specialist to the same building, since DoAddBestCitizenFromUnassigned gets called as part of TASK_REMOVE_SPECIALIST.
From CvCity.cpp
Code:
case TASK_REMOVE_SPECIALIST:
GetCityCitizens()->DoRemoveSpecialistFromBuilding(/*eBuilding*/ (BuildingTypes) iData2, true);
GetCityCitizens()->DoAddBestCitizenFromUnassigned();
break;

--------------
Another theory was that DoRemoveSpecialistFromBuilding was failing to remove the specialist. It will return out if pkBuildingInfo == NULL, but I don't see how that can happen during an AI turn but not during a human turn.
From CvCitizens.cpp
Code:
void CvCityCitizens::DoRemoveSpecialistFromBuilding(BuildingTypes eBuilding, bool bForced, bool bEliminatePopulation)
{
CvAssert(eBuilding > -1);
CvAssert(eBuilding < GC.getNumBuildingInfos());
CvBuildingEntry* pkBuildingInfo = GC.getBuildingInfo(eBuilding);
if(pkBuildingInfo == NULL)
{
return;
}
...
normal processing
...
Has anyone else seen behavior like this before? Removing specialists to safely delete a building is such a common thing I expect this is a well trod area.