private void ProcessMoving(TAI instance, uint citizenId, ref TCitizen citizen) { ushort instanceId = CitizenProxy.GetInstance(ref citizen); ushort vehicleId = CitizenProxy.GetVehicle(ref citizen); if (instanceId == 0) { if (vehicleId == 0) { CitizenMgr.ReleaseCitizen(citizenId); } return; } bool isEvacuating = CitizenProxy.HasFlags(ref citizen, Citizen.Flags.Evacuating); if (vehicleId == 0 && !isEvacuating && CitizenMgr.IsAreaEvacuating(instanceId)) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"Tourist {GetCitizenDesc(citizenId, ref citizen)} was on the way, but the area evacuates. Searching for a shelter."); TransferMgr.AddOutgoingOfferFromCurrentPosition(citizenId, touristAI.GetEvacuationReason(instance, 0)); return; } if (isEvacuating) { return; } if (CitizenMgr.InstanceHasFlags(instanceId, CitizenInstance.Flags.TargetIsNode | CitizenInstance.Flags.OnTour, all: true)) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"Tourist {GetCitizenDesc(citizenId, ref citizen)} exits the guided tour."); FindRandomVisitPlace(instance, citizenId, ref citizen, TouristDoNothingProbability, 0); return; } ushort targetBuildingId = CitizenProxy.GetVisitBuilding(ref citizen); TouristTarget target; if (CitizenMgr.InstanceHasFlags(instanceId, CitizenInstance.Flags.TargetIsNode)) { if (CitizenMgr.GetTargetNode(instanceId) != 0) { target = TouristTarget.Relaxing; } else { return; } } else { if (targetBuildingId == 0) { targetBuildingId = CitizenMgr.GetTargetBuilding(instanceId); } BuildingMgr.GetBuildingService(targetBuildingId, out ItemClass.Service targetService, out ItemClass.SubService targetSubService); switch (targetService) { // Heading to a hotel, no need to change anything case ItemClass.Service.Commercial when targetSubService == ItemClass.SubService.CommercialTourist: return; case ItemClass.Service.Commercial when targetSubService == ItemClass.SubService.CommercialLeisure: target = TouristTarget.Party; break; case ItemClass.Service.Tourism: case ItemClass.Service.Beautification: case ItemClass.Service.Monument: target = TouristTarget.Relaxing; break; case ItemClass.Service.Commercial: target = TouristTarget.Shopping; break; default: return; } } if (GetTouristGoingOutChance(ref citizen, target) > 0) { return; } ushort hotel = FindHotel(targetBuildingId); if (hotel != 0) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"Tourist {GetCitizenDesc(citizenId, ref citizen)} changes the target and moves to a hotel {hotel} because of time or weather"); StartMovingToVisitBuilding(instance, citizenId, ref citizen, 0, hotel); } else { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"Tourist {GetCitizenDesc(citizenId, ref citizen)} leaves the city because of time or weather"); touristAI.FindVisitPlace(instance, citizenId, 0, touristAI.GetLeavingReason(instance, citizenId, ref citizen)); } }