private void DoScheduledHome(ref CitizenSchedule schedule, TAI instance, uint citizenId, ref TCitizen citizen) { ushort homeBuilding = CitizenProxy.GetHomeBuilding(ref citizen); if (homeBuilding == 0) { Log.Debug(LogCategory.State, $"{GetCitizenDesc(citizenId, ref citizen)} is currently homeless. Cannot move home, waiting for the next opportunity"); return; } ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); CitizenProxy.RemoveFlags(ref citizen, Citizen.Flags.Evacuating); #if DEBUG string logEntry = $"{GetCitizenDesc(citizenId, ref citizen)} is going from {currentBuilding} back home"; #else const string logEntry = null; #endif if (residentAI.StartMoving(instance, citizenId, ref citizen, currentBuilding, homeBuilding)) { CitizenProxy.SetVisitPlace(ref citizen, citizenId, 0); schedule.Schedule(ResidentState.Unknown); Log.Debug(LogCategory.Movement, TimeInfo.Now, logEntry); } else { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanted to go home from {currentBuilding} but can't, waiting for the next opportunity"); } }
private bool ProcessCitizenSick(TAI instance, uint citizenId, ref TCitizen citizen) { Citizen.Location currentLocation = CitizenProxy.GetLocation(ref citizen); if (currentLocation == Citizen.Location.Moving) { return(false); } ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); if (currentLocation != Citizen.Location.Home && currentBuilding == 0) { Log.Debug(LogCategory.State, $"Teleporting {GetCitizenDesc(citizenId, ref citizen)} back home because they are sick but no building is specified"); CitizenProxy.SetLocation(ref citizen, Citizen.Location.Home); return(true); } if (currentLocation != Citizen.Location.Home && CitizenProxy.GetVehicle(ref citizen) != 0) { return(true); } if (currentLocation == Citizen.Location.Visit) { ItemClass.Service service = BuildingMgr.GetBuildingService(CitizenProxy.GetVisitBuilding(ref citizen)); if (service == ItemClass.Service.HealthCare || service == ItemClass.Service.Disaster) { return(true); } } Log.Debug(LogCategory.State, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} is sick, trying to get to a hospital"); residentAI.FindHospital(instance, citizenId, currentBuilding, TransferManager.TransferReason.Sick); return(true); }
private void DoScheduledHome(ref CitizenSchedule schedule, TAI instance, uint citizenId, ref TCitizen citizen) { ushort homeBuilding = CitizenProxy.GetHomeBuilding(ref citizen); if (homeBuilding == 0) { Log.Debug(LogCategory.State, $"WARNING: {GetCitizenDesc(citizenId, ref citizen)} is in corrupt state: want to go home with no home building. Releasing the poor citizen."); CitizenMgr.ReleaseCitizen(citizenId); schedule = default; return; } ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); CitizenProxy.RemoveFlags(ref citizen, Citizen.Flags.Evacuating); if (residentAI.StartMoving(instance, citizenId, ref citizen, currentBuilding, homeBuilding)) { CitizenProxy.SetVisitPlace(ref citizen, citizenId, 0); schedule.Schedule(ResidentState.Unknown); Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} is going from {currentBuilding} back home"); } else { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanted to go home from {currentBuilding} but can't, waiting for the next opportunity"); } }
private bool CitizenGoesRelaxing(TAI instance, uint citizenId, ref TCitizen citizen) { Citizen.AgeGroup citizenAge = CitizenProxy.GetAge(ref citizen); if (!IsChance(GetGoOutChance(citizenAge))) { return(false); } ushort buildingId = CitizenProxy.GetCurrentBuilding(ref citizen); if (buildingId == 0) { return(false); } if (TimeInfo.IsNightTime) { ushort leisure = MoveToLeisure(instance, citizenId, ref citizen, buildingId); Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanna relax at night, trying leisure area '{leisure}'"); return(leisure != 0); } if (CitizenProxy.GetWorkBuilding(ref citizen) != 0 && IsWorkDayMorning(citizenAge)) { return(false); } Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanna relax, heading to an entertainment place"); residentAI.FindVisitPlace(instance, citizenId, buildingId, residentAI.GetEntertainmentReason(instance)); return(true); }
private void DoScheduledShopping(ref CitizenSchedule schedule, TAI instance, uint citizenId, ref TCitizen citizen) { ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); if (schedule.Hint == ScheduleHint.LocalShoppingOnly) { schedule.Schedule(ResidentState.Unknown, default); ushort shop = MoveToCommercialBuilding(instance, citizenId, ref citizen, LocalSearchDistance); if (shop == 0) { Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanted go shopping, but didn't find a local shop"); } else { Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} goes shopping at a local shop {shop}"); } } else { uint moreShoppingChance = spareTimeBehavior.GetGoOutChance(CitizenProxy.GetAge(ref citizen)); ResidentState nextState = Random.ShouldOccur(moreShoppingChance) ? ResidentState.Unknown : ResidentState.Shopping; schedule.Schedule(nextState, default); if (schedule.CurrentState != ResidentState.Shopping) { Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} in state {schedule.CurrentState} wanna go shopping and schedules {nextState}, heading to a random shop"); residentAI.FindVisitPlace(instance, citizenId, currentBuilding, residentAI.GetShoppingReason(instance)); } } }
private bool StartMovingToVisitBuilding(TAI instance, uint citizenId, ref TCitizen citizen, ushort visitBuilding) { if (visitBuilding == 0) { return(false); } ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); if (currentBuilding == visitBuilding) { CitizenProxy.SetVisitPlace(ref citizen, citizenId, visitBuilding); CitizenProxy.SetLocation(ref citizen, Citizen.Location.Visit); return(true); } CitizenProxy.SetVisitPlace(ref citizen, citizenId, visitBuilding); if (CitizenProxy.GetVisitBuilding(ref citizen) == 0) { // Building is full and doesn't accept visitors anymore return(false); } if (!residentAI.StartMoving(instance, citizenId, ref citizen, currentBuilding, visitBuilding)) { CitizenProxy.SetVisitPlace(ref citizen, citizenId, 0); return(false); } return(true); }
private bool ScheduleRelaxing(ref CitizenSchedule schedule, uint citizenId, ref TCitizen citizen) { Citizen.AgeGroup citizenAge = CitizenProxy.GetAge(ref citizen); uint relaxChance = spareTimeBehavior.GetRelaxingChance(citizenAge, schedule.WorkShift, schedule.WorkStatus == WorkStatus.OnVacation); relaxChance = AdjustRelaxChance(relaxChance, ref citizen); if (!Random.ShouldOccur(relaxChance) || WeatherInfo.IsBadWeather) { return(false); } ICityEvent cityEvent = GetUpcomingEventToAttend(citizenId, ref citizen); if (cityEvent != null) { ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); DateTime departureTime = cityEvent.StartTime.AddHours(-travelBehavior.GetEstimatedTravelTime(currentBuilding, cityEvent.BuildingId)); schedule.Schedule(ResidentState.Relaxing, departureTime); schedule.EventBuilding = cityEvent.BuildingId; schedule.Hint = ScheduleHint.AttendingEvent; return(true); } schedule.Schedule(ResidentState.Relaxing); schedule.Hint = TimeInfo.IsNightTime && Random.ShouldOccur(NightLeisureChance) ? ScheduleHint.RelaxAtLeisureBuilding : ScheduleHint.None; return(true); }
private bool ScheduleRelaxing(ref CitizenSchedule schedule, uint citizenId, ref TCitizen citizen) { Citizen.AgeGroup citizenAge = CitizenProxy.GetAge(ref citizen); if (!Random.ShouldOccur(spareTimeBehavior.GetGoOutChance(citizenAge)) || IsBadWeather()) { return(false); } ICityEvent cityEvent = GetUpcomingEventToAttend(citizenId, ref citizen); if (cityEvent != null) { ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); DateTime departureTime = cityEvent.StartTime.AddHours(-GetEstimatedTravelTime(currentBuilding, cityEvent.BuildingId)); schedule.Schedule(ResidentState.Relaxing, departureTime); schedule.EventBuilding = cityEvent.BuildingId; schedule.Hint = ScheduleHint.AttendingEvent; return(true); } schedule.Schedule(ResidentState.Relaxing, default); schedule.Hint = TimeInfo.IsNightTime ? ScheduleHint.RelaxAtLeisureBuilding : ScheduleHint.None; return(true); }
private void ReturnFromVisit( TAI instance, uint citizenId, ref TCitizen citizen, ushort targetBuilding, Citizen.Location targetLocation, bool isVirtual) { if (targetBuilding == 0 || targetLocation == Citizen.Location.Visit || CitizenProxy.GetVehicle(ref citizen) != 0) { return; } ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); CitizenProxy.RemoveFlags(ref citizen, Citizen.Flags.Evacuating); CitizenProxy.SetVisitPlace(ref citizen, citizenId, 0); if (isVirtual || targetBuilding == currentBuilding) { CitizenProxy.SetLocation(ref citizen, targetLocation); } else { residentAI.StartMoving(instance, citizenId, ref citizen, currentBuilding, targetBuilding); } }
private ushort MoveToCommercialBuilding(TAI instance, uint citizenId, ref TCitizen citizen, float distance, bool isVirtual) { ushort buildingId = CitizenProxy.GetCurrentBuilding(ref citizen); if (buildingId == 0) { return(0); } ushort foundBuilding = BuildingMgr.FindActiveBuilding(buildingId, distance, ItemClass.Service.Commercial); if (IsBuildingNoiseRestricted(foundBuilding)) { Log.Debug($"Citizen {citizenId} won't go to the commercial building {foundBuilding}, it has a NIMBY policy"); return(0); } if (StartMovingToVisitBuilding(instance, citizenId, ref citizen, foundBuilding, isVirtual)) { ushort homeBuilding = CitizenProxy.GetHomeBuilding(ref citizen); uint homeUnit = BuildingMgr.GetCitizenUnit(homeBuilding); uint citizenUnit = CitizenProxy.GetContainingUnit(ref citizen, citizenId, homeUnit, CitizenUnit.Flags.Home); if (citizenUnit != 0) { CitizenMgr.ModifyUnitGoods(citizenUnit, ShoppingGoodsAmount); } } return(foundBuilding); }
private void DoScheduledWork(ref CitizenSchedule schedule, TAI instance, uint citizenId, ref TCitizen citizen) { ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); schedule.WorkStatus = WorkStatus.Working; schedule.DepartureToWorkTime = default; if (currentBuilding == schedule.WorkBuilding && schedule.CurrentState != ResidentState.AtSchoolOrWork) { CitizenProxy.SetVisitPlace(ref citizen, citizenId, 0); CitizenProxy.SetLocation(ref citizen, Citizen.Location.Work); } else if (residentAI.StartMoving(instance, citizenId, ref citizen, currentBuilding, schedule.WorkBuilding) && schedule.CurrentState == ResidentState.AtHome) { schedule.DepartureToWorkTime = TimeInfo.Now; } Citizen.AgeGroup citizenAge = CitizenProxy.GetAge(ref citizen); if (workBehavior.ScheduleLunch(ref schedule, citizenAge)) { Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} is going from {currentBuilding} to school/work {schedule.WorkBuilding} and will go to lunch at {schedule.ScheduledStateTime}"); } else { workBehavior.ScheduleReturnFromWork(ref schedule, citizenAge); Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} is going from {currentBuilding} to school/work {schedule.WorkBuilding} and will leave work at {schedule.ScheduledStateTime}"); } }
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; } if (vehicleId == 0 && CitizenMgr.IsAreaEvacuating(instanceId) && !CitizenProxy.HasFlags(ref citizen, Citizen.Flags.Evacuating)) { Log.Debug(TimeInfo.Now, $"Tourist {GetCitizenDesc(citizenId, ref citizen)} was on the way, but the area evacuates. Leaving the city."); touristAI.FindVisitPlace(instance, citizenId, CitizenProxy.GetCurrentBuilding(ref citizen), touristAI.GetLeavingReason(instance, citizenId, ref citizen)); return; } if (CitizenMgr.InstanceHasFlags(instanceId, CitizenInstance.Flags.TargetIsNode | CitizenInstance.Flags.OnTour, true)) { FindRandomVisitPlace(instance, citizenId, ref citizen, TouristDoNothingProbability, 0); } }
private bool StartMovingToVisitBuilding(TAI instance, uint citizenId, ref TCitizen citizen, ushort visitBuilding, bool isVirtual) { if (visitBuilding == 0) { return(false); } ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); if (isVirtual || currentBuilding == visitBuilding) { CitizenProxy.SetVisitPlace(ref citizen, citizenId, visitBuilding); CitizenProxy.SetVisitBuilding(ref citizen, visitBuilding); CitizenProxy.SetLocation(ref citizen, Citizen.Location.Visit); return(true); } else if (residentAI.StartMoving(instance, citizenId, ref citizen, currentBuilding, visitBuilding)) { CitizenProxy.SetVisitPlace(ref citizen, citizenId, visitBuilding); CitizenProxy.SetVisitBuilding(ref citizen, visitBuilding); return(true); } return(false); }
private void FindHotel(TAI instance, uint citizenId, ref TCitizen citizen) { ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); if (!Random.ShouldOccur(FindHotelChance)) { Log.Debug(TimeInfo.Now, $"Tourist {GetCitizenDesc(citizenId, ref citizen)} didn't want to stay in a hotel, leaving the city"); touristAI.FindVisitPlace(instance, citizenId, currentBuilding, touristAI.GetLeavingReason(instance, citizenId, ref citizen)); return; } ushort hotel = BuildingMgr.FindActiveBuilding( currentBuilding, FullSearchDistance, ItemClass.Service.Commercial, ItemClass.SubService.CommercialTourist); if (hotel == 0) { Log.Debug(TimeInfo.Now, $"Tourist {GetCitizenDesc(citizenId, ref citizen)} didn't find a hotel, leaving the city"); touristAI.FindVisitPlace(instance, citizenId, currentBuilding, touristAI.GetLeavingReason(instance, citizenId, ref citizen)); return; } StartMovingToVisitBuilding(instance, citizenId, ref citizen, currentBuilding, hotel); Log.Debug(TimeInfo.Now, $"Tourist {GetCitizenDesc(citizenId, ref citizen)} stays in a hotel {hotel}"); }
private void ProcessVisit(TAI instance, uint citizenId, ref TCitizen citizen) { ushort visitBuilding = CitizenProxy.GetVisitBuilding(ref citizen); if (visitBuilding == 0) { CitizenMgr.ReleaseCitizen(citizenId); return; } if (BuildingMgr.BuildingHasFlags(visitBuilding, Building.Flags.Evacuating)) { touristAI.FindEvacuationPlace(instance, citizenId, visitBuilding, touristAI.GetEvacuationReason(instance, visitBuilding)); return; } switch (BuildingMgr.GetBuildingService(visitBuilding)) { case ItemClass.Service.Disaster: if (BuildingMgr.BuildingHasFlags(visitBuilding, Building.Flags.Downgrading)) { CitizenProxy.RemoveFlags(ref citizen, Citizen.Flags.Evacuating); FindRandomVisitPlace(instance, citizenId, ref citizen, 0, visitBuilding); } return; // Tourist is sleeping in a hotel case ItemClass.Service.Commercial when BuildingMgr.GetBuildingSubService(visitBuilding) == ItemClass.SubService.CommercialTourist && !Random.ShouldOccur(GetHotelLeaveChance()): return; } ICityEvent currentEvent = EventMgr.GetCityEvent(visitBuilding); if (currentEvent != null && currentEvent.StartTime < TimeInfo.Now) { if (Random.ShouldOccur(TouristShoppingChance)) { BuildingMgr.ModifyMaterialBuffer(visitBuilding, TransferManager.TransferReason.Shopping, -ShoppingGoodsAmount); } return; } if (Random.ShouldOccur(TouristEventChance) && !WeatherInfo.IsBadWeather) { ICityEvent cityEvent = GetUpcomingEventToAttend(citizenId, ref citizen); if (cityEvent != null && StartMovingToVisitBuilding(instance, citizenId, ref citizen, CitizenProxy.GetCurrentBuilding(ref citizen), cityEvent.BuildingId)) { Log.Debug(LogCategory.Events, TimeInfo.Now, $"Tourist {GetCitizenDesc(citizenId, ref citizen)} attending an event at {cityEvent.BuildingId}"); return; } } FindRandomVisitPlace(instance, citizenId, ref citizen, 0, visitBuilding); }
private uint AdjustRelaxChance(uint relaxChance, ref TCitizen citizen) { ushort visitBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); return((BuildingMgr.GetBuildingSubService(visitBuilding) == ItemClass.SubService.BeautificationParks) ? relaxChance * 2 : relaxChance); }
private void ProcessCitizenEvacuation(TAI instance, uint citizenId, ref TCitizen citizen) { ushort building = CitizenProxy.GetCurrentBuilding(ref citizen); if (building != 0) { Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen, false)} is trying to find an evacuation place"); residentAI.FindEvacuationPlace(instance, citizenId, building, residentAI.GetEvacuationReason(instance, building)); } }
private bool DoScheduledShopping(ref CitizenSchedule schedule, TAI instance, uint citizenId, ref TCitizen citizen) { // Shopping 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.Shopping) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanted go shopping but is still at work or in shelter. No shopping activity found. Now going home."); return(false); } ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); if (schedule.Hint == ScheduleHint.LocalShoppingOnly) { schedule.Schedule(ResidentState.Unknown); ushort shop = MoveToCommercialBuilding(instance, citizenId, ref citizen, LocalSearchDistance); if (shop == 0) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanted go shopping, but didn't find a local shop"); return(false); } if (TimeInfo.IsNightTime) { schedule.Hint = ScheduleHint.NoShoppingAnyMore; } Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} goes shopping at a local shop {shop}"); return(true); } uint moreShoppingChance = spareTimeBehavior.GetShoppingChance(CitizenProxy.GetAge(ref citizen)); ResidentState nextState = schedule.Hint != ScheduleHint.NoShoppingAnyMore && Random.ShouldOccur(moreShoppingChance) ? ResidentState.Shopping : ResidentState.Unknown; schedule.Schedule(nextState); if (schedule.CurrentState != ResidentState.Shopping || Random.ShouldOccur(FindAnotherShopOrEntertainmentChance)) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} in state {schedule.CurrentState} wanna go shopping and schedules {nextState}, heading to a random shop, hint = {schedule.Hint}"); residentAI.FindVisitPlace(instance, citizenId, currentBuilding, residentAI.GetShoppingReason(instance)); } #if DEBUG else { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} continues shopping in the same building."); } #endif return(true); }
private void DoScheduledRelaxing(ref CitizenSchedule schedule, TAI instance, uint citizenId, ref TCitizen citizen) { ushort buildingId = CitizenProxy.GetCurrentBuilding(ref citizen); switch (schedule.Hint) { case ScheduleHint.RelaxAtLeisureBuilding: schedule.Schedule(ResidentState.Unknown, default); ushort leisure = MoveToLeisureBuilding(instance, citizenId, ref citizen, buildingId); if (leisure == 0) { Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanted relax but didn't found a leisure building"); } else { Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} heading to a leisure building {leisure}"); } return; case ScheduleHint.AttendingEvent: DateTime returnTime = default; ICityEvent cityEvent = EventMgr.GetCityEvent(schedule.EventBuilding); if (cityEvent == null) { Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanted attend an event at '{schedule.EventBuilding}', but there was no event there"); } else if (StartMovingToVisitBuilding(instance, citizenId, ref citizen, schedule.EventBuilding)) { returnTime = cityEvent.EndTime; Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanna attend an event at '{schedule.EventBuilding}', will return at {returnTime}"); } schedule.Schedule(ResidentState.Unknown, returnTime); schedule.EventBuilding = 0; return; } uint relaxChance = spareTimeBehavior.GetGoOutChance(CitizenProxy.GetAge(ref citizen)); ResidentState nextState = Random.ShouldOccur(relaxChance) ? ResidentState.Unknown : ResidentState.Relaxing; schedule.Schedule(nextState, default); if (schedule.CurrentState != ResidentState.Relaxing) { Log.Debug(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)); } }
private void ProcessCitizenAtSchoolOrWork(TAI instance, uint citizenId, ref TCitizen citizen, bool isVirtual) { ushort workBuilding = CitizenProxy.GetWorkBuilding(ref citizen); if (workBuilding == 0) { Log.Debug($"WARNING: {GetCitizenDesc(citizenId, ref citizen, isVirtual)} is in corrupt state: at school/work with no work building. Teleporting home."); CitizenProxy.SetLocation(ref citizen, Citizen.Location.Home); return; } ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); if (ShouldGoToLunch(CitizenProxy.GetAge(ref citizen), citizenId)) { ushort lunchPlace = MoveToCommercialBuilding(instance, citizenId, ref citizen, LocalSearchDistance, isVirtual); if (lunchPlace != 0) { Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen, isVirtual)} is going for lunch from {currentBuilding} to {lunchPlace}"); } else { Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen, isVirtual)} wanted to go for lunch from {currentBuilding}, but there were no buildings close enough"); } return; } if (!ShouldReturnFromSchoolOrWork(citizenId, currentBuilding, CitizenProxy.GetAge(ref citizen))) { return; } Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen, isVirtual)} leaves their workplace {workBuilding}"); if (CitizenGoesToEvent(instance, citizenId, ref citizen, isVirtual)) { return; } if (!CitizenGoesShopping(instance, citizenId, ref citizen, isVirtual) && !CitizenGoesRelaxing(instance, citizenId, ref citizen, isVirtual)) { if (isVirtual) { CitizenProxy.SetLocation(ref citizen, Citizen.Location.Home); } else { residentAI.StartMoving(instance, citizenId, ref citizen, workBuilding, CitizenProxy.GetHomeBuilding(ref citizen)); } } }
private bool StartMovingToVisitBuilding(TAI instance, uint citizenId, ref TCitizen citizen, ushort visitBuilding) { if (visitBuilding == 0) { return(false); } ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); residentAI.StartMoving(instance, citizenId, ref citizen, currentBuilding, visitBuilding); CitizenProxy.SetVisitPlace(ref citizen, citizenId, visitBuilding); CitizenProxy.SetVisitBuilding(ref citizen, visitBuilding); return(true); }
private bool CitizenGoesWorking(TAI instance, uint citizenId, ref TCitizen citizen) { ushort homeBuilding = CitizenProxy.GetHomeBuilding(ref citizen); ushort workBuilding = CitizenProxy.GetWorkBuilding(ref citizen); ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); if (!ShouldMoveToSchoolOrWork(workBuilding, currentBuilding, CitizenProxy.GetAge(ref citizen))) { return(false); } Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} is going from {currentBuilding} ({CitizenProxy.GetLocation(ref citizen)}) to school/work {workBuilding}"); residentAI.StartMoving(instance, citizenId, ref citizen, homeBuilding, workBuilding); return(true); }
private void DoScheduledEvacuation(ref CitizenSchedule schedule, TAI instance, uint citizenId, ref TCitizen citizen) { schedule.Schedule(ResidentState.Unknown); ushort building = CitizenProxy.GetCurrentBuilding(ref citizen); if (building == 0) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} is trying to find a shelter from current position"); TransferMgr.AddOutgoingOfferFromCurrentPosition(citizenId, residentAI.GetEvacuationReason(instance, 0)); } else { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} is trying to find a shelter from {building}"); residentAI.FindEvacuationPlace(instance, citizenId, building, residentAI.GetEvacuationReason(instance, building)); } }
private void DoScheduledEvacuation(ref CitizenSchedule schedule, TAI instance, uint citizenId, ref TCitizen citizen) { ushort building = CitizenProxy.GetCurrentBuilding(ref citizen); if (building == 0) { schedule.Schedule(ResidentState.AtHome); return; } schedule.Schedule(ResidentState.InShelter); if (schedule.CurrentState != ResidentState.InShelter) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} is trying to find an evacuation place"); residentAI.FindEvacuationPlace(instance, citizenId, building, residentAI.GetEvacuationReason(instance, building)); } }
private void ProcessCitizenDead(TAI instance, uint citizenId, ref TCitizen citizen) { ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); Citizen.Location currentLocation = CitizenProxy.GetLocation(ref citizen); switch (currentLocation) { case Citizen.Location.Home when currentBuilding != 0: CitizenProxy.SetWorkplace(ref citizen, citizenId, 0); CitizenProxy.SetVisitPlace(ref citizen, citizenId, 0); break; case Citizen.Location.Work when currentBuilding != 0: CitizenProxy.SetHome(ref citizen, citizenId, 0); CitizenProxy.SetVisitPlace(ref citizen, citizenId, 0); break; case Citizen.Location.Visit when currentBuilding != 0: CitizenProxy.SetHome(ref citizen, citizenId, 0); CitizenProxy.SetWorkplace(ref citizen, citizenId, 0); if (BuildingMgr.GetBuildingService(CitizenProxy.GetVisitBuilding(ref citizen)) == ItemClass.Service.HealthCare) { return; } break; case Citizen.Location.Moving when CitizenProxy.GetVehicle(ref citizen) != 0: CitizenProxy.SetHome(ref citizen, citizenId, 0); CitizenProxy.SetWorkplace(ref citizen, citizenId, 0); CitizenProxy.SetVisitPlace(ref citizen, citizenId, 0); return; default: Log.Debug(LogCategory.State, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} is released because of death"); residentSchedules[citizenId] = default; CitizenMgr.ReleaseCitizen(citizenId); return; } residentAI.FindHospital(instance, citizenId, currentBuilding, TransferManager.TransferReason.Dead); Log.Debug(LogCategory.State, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} is dead, body should get serviced"); }
private void DoScheduledWork(ref CitizenSchedule schedule, TAI instance, uint citizenId, ref TCitizen citizen) { ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); schedule.WorkStatus = WorkStatus.Working; if (currentBuilding == schedule.WorkBuilding && schedule.CurrentState != ResidentState.AtSchoolOrWork) { CitizenProxy.SetVisitPlace(ref citizen, citizenId, 0); CitizenProxy.SetLocation(ref citizen, Citizen.Location.Work); return; } #if DEBUG string citizenDesc = GetCitizenDesc(citizenId, ref citizen); #else const string citizenDesc = null; #endif if (residentAI.StartMoving(instance, citizenId, ref citizen, currentBuilding, schedule.WorkBuilding)) { if (schedule.CurrentState != ResidentState.AtHome) { // The start moving method will register a departure from any building to work, // but we are only interested in the 'home->work' route. schedule.DepartureTime = default; } Citizen.AgeGroup citizenAge = CitizenProxy.GetAge(ref citizen); if (workBehavior.ScheduleLunch(ref schedule, citizenAge)) { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{citizenDesc} is going from {currentBuilding} to school/work {schedule.WorkBuilding} and will go to lunch at {schedule.ScheduledStateTime}"); } else { workBehavior.ScheduleReturnFromWork(ref schedule, citizenAge); Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{citizenDesc} is going from {currentBuilding} to school/work {schedule.WorkBuilding} and will leave work at {schedule.ScheduledStateTime}"); } } else { Log.Debug(LogCategory.Movement, TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} wanted to go to work from {currentBuilding} but can't, will try once again next time"); schedule.Schedule(ResidentState.Unknown); } }
private uint AdjustRelaxChance(uint relaxChance, ref TCitizen citizen) { ushort visitBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); if (BuildingMgr.GetBuildingSubService(visitBuilding) == ItemClass.SubService.BeautificationParks) { return(relaxChance * 2); } else if (CitizenProxy.GetAge(ref citizen) == Citizen.AgeGroup.Senior && BuildingMgr.IsBuildingServiceLevel(visitBuilding, ItemClass.Service.HealthCare, ItemClass.Level.Level3)) { return(relaxChance * 4); } else { return(relaxChance); } }
private bool ScheduleWork(ref CitizenSchedule schedule, ref TCitizen citizen) { ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); if (!workBehavior.ScheduleGoToWork(ref schedule, currentBuilding, simulationCycle)) { return(false); } Log.Debug($" - Schedule work at {schedule.ScheduledStateTime}"); float timeLeft = (float)(schedule.ScheduledStateTime - TimeInfo.Now).TotalHours; if (timeLeft <= PrepareToWorkHours) { // Just sit at home if the work time will come soon Log.Debug($" - Work time in {timeLeft} hours, preparing for departure"); return(true); } if (timeLeft <= MaxTravelTime) { if (schedule.CurrentState != ResidentState.AtHome) { Log.Debug($" - Work time in {timeLeft} hours, returning home"); schedule.Schedule(ResidentState.AtHome, default); return(true); } // If we have some time, try to shop locally. if (ScheduleShopping(ref schedule, ref citizen, true)) { Log.Debug($" - Work time in {timeLeft} hours, trying local shop"); } else { Log.Debug($" - Work time in {timeLeft} hours, doing nothing"); } return(true); } return(false); }
private ushort MoveToCommercialBuilding(TAI instance, uint citizenId, ref TCitizen citizen, float distance) { ushort buildingId = CitizenProxy.GetCurrentBuilding(ref citizen); if (buildingId == 0) { return(0); } ushort foundBuilding = BuildingMgr.FindActiveBuilding(buildingId, distance, ItemClass.Service.Commercial); if (foundBuilding == CitizenProxy.GetWorkBuilding(ref citizen)) { return(0); } StartMovingToVisitBuilding(instance, citizenId, ref citizen, foundBuilding); return(foundBuilding); }
private void ProcessCitizenDead(TAI instance, uint citizenId, ref TCitizen citizen) { ushort currentBuilding = CitizenProxy.GetCurrentBuilding(ref citizen); Citizen.Location currentLocation = CitizenProxy.GetLocation(ref citizen); if (currentBuilding == 0 || (currentLocation == Citizen.Location.Moving && CitizenProxy.GetVehicle(ref citizen) == 0)) { Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} is released"); residentSchedules[citizenId] = default; CitizenMgr.ReleaseCitizen(citizenId); return; } if (currentLocation != Citizen.Location.Home && CitizenProxy.GetHomeBuilding(ref citizen) != 0) { CitizenProxy.SetHome(ref citizen, citizenId, 0); } if (currentLocation != Citizen.Location.Work && CitizenProxy.GetWorkBuilding(ref citizen) != 0) { CitizenProxy.SetWorkplace(ref citizen, citizenId, 0); } if (currentLocation != Citizen.Location.Visit && CitizenProxy.GetVisitBuilding(ref citizen) != 0) { CitizenProxy.SetVisitPlace(ref citizen, citizenId, 0); } if (currentLocation == Citizen.Location.Moving || CitizenProxy.GetVehicle(ref citizen) != 0) { return; } if (currentLocation == Citizen.Location.Visit && BuildingMgr.GetBuildingService(CitizenProxy.GetVisitBuilding(ref citizen)) == ItemClass.Service.HealthCare) { return; } residentAI.FindHospital(instance, citizenId, currentBuilding, TransferManager.TransferReason.Dead); Log.Debug(TimeInfo.Now, $"{GetCitizenDesc(citizenId, ref citizen)} is dead, body should get serviced"); }