private bool DoScheduledRelaxing(ref CitizenSchedule schedule, TAI instance, uint citizenId, ref TCitizen citizen) { // Relaxing was already scheduled last time, but the citizen is still at school/work or in shelter. // This can occur when the game's transfer manager can't find any activity for the citizen. // In that case, move back home. if ((schedule.CurrentState == ResidentState.AtSchoolOrWork || schedule.CurrentState == ResidentState.InShelter) && schedule.LastScheduledState == ResidentState.Relaxing) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanted relax but is still at work or in shelter. No relaxing activity found. Now going home."); return(false); } ushort buildingId = CitizenProxy.GetCurrentBuilding(ref citizen); switch (schedule.Hint) { case ScheduleHint.RelaxAtLeisureBuilding: schedule.Schedule(ResidentState.Unknown); ushort leisure = MoveToLeisureBuilding(instance, citizenId, ref citizen, buildingId); if (leisure == 0) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanted relax but didn't find a leisure building"); return(false); } Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} heading to a leisure building {leisure}"); return(true); case ScheduleHint.AttendingEvent: ushort eventBuilding = schedule.EventBuilding; schedule.EventBuilding = 0; ICityEvent cityEvent = EventMgr.GetCityEvent(eventBuilding); if (cityEvent == null) { Log.Debug(LogCategory.Events, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanted attend an event at '{eventBuilding}', but there was no event there"); } else if (StartMovingToVisitBuilding(instance, citizenId, ref citizen, eventBuilding)) { schedule.Schedule(ResidentState.Unknown, cityEvent.EndTime); Log.Debug(LogCategory.Events, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanna attend an event at '{eventBuilding}', will return at {cityEvent.EndTime}"); return(true); } schedule.Schedule(ResidentState.Unknown); return(false); case ScheduleHint.RelaxNearbyOnly: Vector3 currentPosition = CitizenMgr.GetCitizenPosition(CitizenProxy.GetInstance(ref citizen)); ushort parkBuildingId = BuildingMgr.FindActiveBuilding(currentPosition, LocalSearchDistance, ItemClass.Service.Beautification); if (StartMovingToVisitBuilding(instance, citizenId, ref citizen, parkBuildingId)) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} heading to a nearby entertainment building {parkBuildingId}"); schedule.Schedule(ResidentState.Unknown); return(true); } schedule.Schedule(ResidentState.Unknown); DoScheduledHome(ref schedule, instance, citizenId, ref citizen); return(true); } uint relaxChance = spareTimeBehavior.GetRelaxingChance( CitizenProxy.GetAge(ref citizen), schedule.WorkShift, schedule.WorkStatus == WorkStatus.OnVacation); relaxChance = AdjustRelaxChance(relaxChance, ref citizen); ResidentState nextState = Random.ShouldOccur(relaxChance) ? ResidentState.Relaxing : ResidentState.Unknown; schedule.Schedule(nextState); if (schedule.CurrentState != ResidentState.Relaxing || Random.ShouldOccur(FindAnotherShopOrEntertainmentChance)) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} in state {schedule.CurrentState} wanna relax and then schedules {nextState}, heading to an entertainment building."); residentAI.FindVisitPlace(instance, citizenId, buildingId, residentAI.GetEntertainmentReason(instance)); } #if DEBUG else { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} continues relaxing in the same entertainment building."); } #endif return(true); }