private static bool ProcessInBuilding(ref ResidentAI residentAI, uint citizenId, ref Citizen citizen) { if (citizen.ValidBuilding()) { var buildingInstance = citizen.GetBuildingInstance(); if (buildingInstance?.m_flags.IsFlagSet(Building.Flags.Evacuating) ?? false) { return(false); } if (citizen.AtHome()) { ProcessAtHome(ref residentAI, citizenId, ref citizen); } else if (citizen.AtWork()) { ProcessAtWork(ref residentAI, citizenId, ref citizen); } else if (citizen.IsVisiting()) { ProcessVisiting(ref residentAI, citizenId, ref citizen); } } return(true); }
public static bool FindAFunActivity(this ResidentAI residentAI, uint citizenId, ref Citizen citizen, ushort proximityBuilding) { var visitMonument = SimulationManager.instance.m_randomizer.Int32(10) < 3; var proximityBuildingInstance = BuildingManager.instance.m_buildings.m_buffer[proximityBuilding]; if (visitMonument && proximityBuilding != 0) { var monument = residentAI.FindSomewhere(citizenId, ref citizen, proximityBuildingInstance, new[] { ItemClass.Service.Monument }, new[] { ItemClass.SubService.None }); if (monument != 0) { residentAI.GoToBuilding(citizenId, ref citizen, monument); return(true); } } var foundBuilding = residentAI.FindSomewhere(citizenId, ref citizen, proximityBuildingInstance, new[] { ItemClass.Service.Beautification, ItemClass.Service.Commercial, ItemClass.Service.Natural, ItemClass.Service.Tourism }, new[] { ItemClass.SubService.None }); if (foundBuilding != 0) { residentAI.GoToBuilding(citizenId, ref citizen, foundBuilding); return(true); } return(false); }
private static bool ProcessAtHome(ref ResidentAI residentAI, uint citizenId, ref Citizen citizen) { CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.AtHome); if (citizen.ValidWorkBuilding() && citizen.ShouldGoToWork()) { residentAI.GoToWork(citizenId, ref citizen); return(true); } else if (citizen.Tired()) { residentAI.GoToSleep(citizenId); return(true); } else { var simulationManager = SimulationManager.instance; var happiness = Citizen.GetHappiness(citizen.m_health, citizen.m_wellbeing); var wealth = citizen.WealthLevel; var happinessLevel = Citizen.GetHappinessLevel(happiness); var dayOfWeek = simulationManager.m_currentGameTime.DayOfWeek; var weekend = !citizen.ValidWorkBuilding() || dayOfWeek == DayOfWeek.Saturday || dayOfWeek == DayOfWeek.Sunday; var goSomewhere = simulationManager.m_randomizer.Int32(16) < ((int)happinessLevel + (int)wealth) * (weekend ? 2 : 1); if (goSomewhere) { ProcessActivity(ref residentAI, citizenId, ref citizen); } return(true); } }
public static bool FindAFunActivity(this ResidentAI residentAI, uint citizenId, ref Citizen citizen, ushort proximityBuilding) { var visitMonument = SimulationManager.instance.m_randomizer.Int32(10) < 3; if (visitMonument && proximityBuilding != 0) { var proximityBuildingInstance = BuildingManager.instance.m_buildings.m_buffer[proximityBuilding]; var monument = residentAI.FindSomewhereClose(citizenId, ref citizen, BuildingManager.BUILDINGGRID_RESOLUTION * BuildingManager.BUILDINGGRID_CELL_SIZE, proximityBuildingInstance, new[] { ItemClass.Service.Monument }, new[] { ItemClass.SubService.None }); if (monument != 0) { residentAI.GoToBuilding(citizenId, ref citizen, monument); return(true); } } var entertainmentReason = new Traverse(residentAI).Method("GetEntertainmentReason").GetValue <TransferManager.TransferReason>(); if (entertainmentReason != TransferManager.TransferReason.None) { new Traverse(residentAI).Method("FindVisitPlace", citizenId, proximityBuilding, entertainmentReason); CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.AttemptingToGoForEntertainment); return(true); } return(false); }
public static bool UpdateLocationPrefix(ResidentAI __instance, uint citizenID, ref Citizen data) { if (UserModSettings.Settings.Enabled && UserModSettings.Settings.Citizens_Override) { return(!ResidentLocationHandler.Process(ref __instance, citizenID, ref data)); } return(true); }
private static void StartMoving(uint citizenId, ushort sourceBuildingId, ushort targetBuildingId) { CitizenInfo citizenInfo = CitizenManager.instance.m_citizens.m_buffer[citizenId].GetCitizenInfo(citizenId); Citizen citizen = CitizenManager.instance.m_citizens.m_buffer[citizenId]; ResidentAI resident = citizenInfo.m_citizenAI as ResidentAI; if (resident.StartMoving(citizenId, ref citizen, sourceBuildingId, targetBuildingId)) { Debug.Log("PfS: Citizen is moving..."); _citizens.Add(citizenId); } }
void OnTriggerEnter(Collider coll) { if (coll.gameObject.GetComponent <NavMeshAgent> () != null) { NavMeshAgent agent = coll.gameObject.GetComponent <NavMeshAgent> (); ResidentAI res = agent.gameObject.GetComponent <ResidentAI> (); if (gameObject.transform == res.destinationWayPoint) { res.ReachedDestination(); Debug.Log("Called reached destination"); } } }
private static bool ProcessMoving(ref ResidentAI residentAI, uint citizenId, ref Citizen citizen) { CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.Moving); if (citizen.ValidWorkBuilding() && citizen.ShouldGoToWork()) { residentAI.GoToWork(citizenId, ref citizen); return(true); } return(false); }
public static bool FindAShop(this ResidentAI residentAI, uint citizenId, ref Citizen citizen, ushort proximityBuilding) { var proximityBuildingInstance = BuildingManager.instance.m_buildings.m_buffer[proximityBuilding]; var foundBuilding = residentAI.FindSomewhere(citizenId, ref citizen, proximityBuildingInstance, new[] { ItemClass.Service.Commercial }, new[] { ItemClass.SubService.CommercialEco, ItemClass.SubService.CommercialHigh, ItemClass.SubService.CommercialLow }); if (foundBuilding != 0) { residentAI.GoToBuilding(citizenId, ref citizen, foundBuilding); return(true); } return(false); }
public static void UpdateLocation(ResidentAI resident, uint citizenID, ref Citizen data) { try { CitizenManager _citizenManager = Singleton<CitizenManager>.instance; if (data.m_homeBuilding == 0 && data.m_workBuilding == 0 && data.m_visitBuilding == 0 && data.m_instance == 0 && data.m_vehicle == 0) { _citizenManager.ReleaseCitizen(citizenID); } else { switch (data.CurrentLocation) { case Citizen.Location.Home: if (!ResidentLocationHandler.ProcessHome(ref resident, citizenID, ref data)) { return; } break; case Citizen.Location.Work: if (!ResidentLocationHandler.ProcessWork(ref resident, citizenID, ref data)) { return; } break; case Citizen.Location.Visit: if (!ResidentLocationHandler.ProcessVisit(ref resident, citizenID, ref data)) { return; } break; case Citizen.Location.Moving: if (!ResidentLocationHandler.ProcessMoving(ref resident, citizenID, ref data)) { return; } break; } data.m_flags &= ~Citizen.Flags.NeedGoods; } } catch (Exception ex) { Debug.LogWarning("Error on " + citizenID); Debug.LogException(ex); } }
public static bool FindAShop(this ResidentAI residentAI, uint citizenId, ushort proximityBuilding) { var shoppingReason = new Traverse(residentAI).Method("GetShoppingReason").GetValue <TransferManager.TransferReason>(); if (shoppingReason != TransferManager.TransferReason.None) { new Traverse(residentAI).Method("FindVisitPlace", citizenId, proximityBuilding, shoppingReason); CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.AttemptingToGoShopping); return(true); } return(false); }
private static bool ProcessVisiting(ref ResidentAI residentAI, uint citizenId, ref Citizen citizen) { CitizenActivityMonitor.LogActivity(citizenId, GetBuildingActivity(ref citizen)); if (citizen.ValidWorkBuilding() && citizen.ShouldGoToWork()) { residentAI.GoToWork(citizenId, ref citizen); return(true); } else if (citizen.ShouldGoHome()) { residentAI.GoHome(citizenId, ref citizen); return(true); } else { var simulationManager = SimulationManager.instance; var buildingInstance = citizen.GetBuildingInstance().Value; var shouldStay = GlobalLocationHandler.GoodBuildingToVisit(ref buildingInstance, ref citizen) && (citizen.AfraidOfGettingWet() || simulationManager.m_randomizer.UInt32(10) < 6); if (!shouldStay) { var ageGroup = Citizen.GetAgeGroup(citizen.Age); var happiness = Citizen.GetHappiness(citizen.m_health, citizen.m_wellbeing); var happinessLevel = Citizen.GetHappinessLevel(happiness); var visitSomewhereElse = simulationManager.m_randomizer.UInt32(100) < ((int)happinessLevel * 18) / ((int)ageGroup + 1); if (!visitSomewhereElse || !ProcessActivity(ref residentAI, citizenId, ref citizen)) { if (!residentAI.GoHome(citizenId, ref citizen)) { } } } else if (citizen.GettingWet()) { CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.GettingWet); residentAI.GoHome(citizenId, ref citizen); } return(true); } }
public static void UpdateLocation(ResidentAI resident, uint citizenID, ref Citizen data) { try { CitizenManager _citizenManager = Singleton <CitizenManager> .instance; if (data.m_homeBuilding == 0 && data.m_workBuilding == 0 && data.m_visitBuilding == 0 && data.m_instance == 0 && data.m_vehicle == 0) { _citizenManager.ReleaseCitizen(citizenID); } else { bool goodsSatisfied = false; switch (data.CurrentLocation) { case Citizen.Location.Home: goodsSatisfied = ResidentLocationHandler.ProcessHome(ref resident, citizenID, ref data); break; case Citizen.Location.Work: goodsSatisfied = ResidentLocationHandler.ProcessWork(ref resident, citizenID, ref data); break; case Citizen.Location.Visit: goodsSatisfied = ResidentLocationHandler.ProcessVisit(ref resident, citizenID, ref data); break; case Citizen.Location.Moving: goodsSatisfied = ResidentLocationHandler.ProcessMoving(ref resident, citizenID, ref data); break; } if (goodsSatisfied) { data.m_flags &= ~Citizen.Flags.NeedGoods; } } } catch (Exception ex) { Debug.LogWarning("Error on " + citizenID); Debug.LogException(ex); } }
internal static bool ProcessMoving(ref ResidentAI resident, uint citizenID, ref Citizen data) { if (data.Dead) { if (data.m_vehicle == 0) { Singleton <CitizenManager> .instance.ReleaseCitizen(citizenID); return(false); } if (data.m_homeBuilding != 0) { data.SetHome(citizenID, 0, 0U); } if (data.m_workBuilding != 0) { data.SetWorkplace(citizenID, 0, 0U); } if (data.m_visitBuilding != 0) { data.SetVisitplace(citizenID, 0, 0U); return(true); } return(true); } if (data.m_vehicle == 0 && data.m_instance == 0) //If they've stopped moving for whatever reason { if (data.m_visitBuilding != 0) { data.SetVisitplace(citizenID, 0, 0U); } data.CurrentLocation = Citizen.Location.Home; data.Arrested = false; return(true); } return(true); }
public static bool Process(ref ResidentAI residentAI, uint citizenId, ref Citizen citizen) { if (!citizen.Arrested && !citizen.Sick && !citizen.Collapsed && !citizen.Dead && citizen.Exists()) { CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.Unknown); if (citizen.IsAtABuilding()) { return(ProcessInBuilding(ref residentAI, citizenId, ref citizen)); } else if (citizen.IsMoving()) { return(ProcessMoving(ref residentAI, citizenId, ref citizen)); } return(true); } return(false); }
public void TryMoveFamily(uint citizenID) { uint temp = citizenID; int familySize = 0; CitizenUnit data = Singleton <CitizenManager> .instance.m_units.m_buffer[citizenID]; Citizen cit = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenID]; if ((int)data.m_citizen4 != 0 && !Singleton <CitizenManager> .instance.m_citizens.m_buffer[data.m_citizen4].Dead) { ++familySize; citizenID = data.m_citizen4; } if ((int)data.m_citizen3 != 0 && !Singleton <CitizenManager> .instance.m_citizens.m_buffer[data.m_citizen3].Dead) { ++familySize; citizenID = data.m_citizen3; } if ((int)data.m_citizen2 != 0 && !Singleton <CitizenManager> .instance.m_citizens.m_buffer[data.m_citizen2].Dead) { ++familySize; citizenID = data.m_citizen2; } if ((int)data.m_citizen1 != 0 && !Singleton <CitizenManager> .instance.m_citizens.m_buffer[data.m_citizen1].Dead) { ++familySize; citizenID = data.m_citizen1; } if ((int)data.m_citizen0 != 0 && !Singleton <CitizenManager> .instance.m_citizens.m_buffer[data.m_citizen0].Dead) { ++familySize; citizenID = data.m_citizen0; } if ((int)citizenID == 0) { return; } ResidentAI ai = cit.GetCitizenInfo(citizenID).GetAI() as ResidentAI; citizenID = temp; //TODO: Unsure if citizenID should be kept or changed below ai.TryMoveFamily(citizenID, ref cit, familySize); }
private static bool ProcessAtHome(ref ResidentAI residentAI, uint citizenId, ref Citizen citizen) { CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.AtHome); if (citizen.ValidWorkBuilding() && citizen.ShouldGoToWork()) { residentAI.GoToWork(citizenId, ref citizen); return(true); } else if (citizen.Tired()) { residentAI.GoToSleep(citizenId); return(true); } else if (citizen.NeedsGoods()) { var proximityBuilding = citizen.ValidHomeBuilding() ? citizen.HomeBuilding() : citizen.WorkBuilding(); //Prioritise something close to home, rather than work if (residentAI.GoToAShop(citizenId, ref citizen, proximityBuilding, BuildingManager.BUILDINGGRID_CELL_SIZE * 2)) { return(true); } } var simulationManager = SimulationManager.instance; var happiness = Citizen.GetHappiness(citizen.m_health, citizen.m_wellbeing); var wealth = citizen.WealthLevel; var happinessLevel = Citizen.GetHappinessLevel(happiness); var dayOfWeek = simulationManager.m_currentGameTime.DayOfWeek; var weekend = !citizen.ValidWorkBuilding() || dayOfWeek == DayOfWeek.Saturday || dayOfWeek == DayOfWeek.Sunday; var goSomewhere = simulationManager.m_randomizer.Int32(16) < ((int)happinessLevel + (int)wealth) * (weekend ? 2 : 1); if (goSomewhere) { ProcessActivity(ref residentAI, citizenId, ref citizen); } return(true); }
private static ushort FindCloseVisitPlace(ref ResidentAI thisAI, uint citizenID, ref Citizen person, ushort buildingID, float distance) { ushort foundBuilding = 0; if ((person.m_instance != 0 || NewResidentAI.DoRandomMove(thisAI))) { BuildingManager _buildingManager = Singleton <BuildingManager> .instance; Building _currentBuilding = _buildingManager.m_buildings.m_buffer[buildingID]; foundBuilding = _buildingManager.FindBuilding(_currentBuilding.m_position, distance, ItemClass.Service.Commercial, ItemClass.SubService.None, Building.Flags.Created | Building.Flags.Active, Building.Flags.Deleted); if (foundBuilding != 0) { LoggingWrapper.Log("Citizen " + citizenID + " going to a local commercial building."); thisAI.StartMoving(citizenID, ref person, buildingID, foundBuilding); person.SetVisitplace(citizenID, foundBuilding, 0U); person.m_visitBuilding = foundBuilding; } } return(foundBuilding); }
private static ushort FindLeisure(ref ResidentAI thisAI, uint citizenID, ref Citizen person, ushort buildingID) { ushort foundLeisure = 0; if ((person.m_instance != 0 || NewResidentAI.DoRandomMove(thisAI))) { BuildingManager _buildingManager = Singleton <BuildingManager> .instance; SimulationManager _simulationManager = Singleton <SimulationManager> .instance; Building _currentBuilding = _buildingManager.m_buildings.m_buffer[buildingID]; foundLeisure = _buildingManager.FindBuilding(_currentBuilding.m_position, 1000f, ItemClass.Service.Commercial, ItemClass.SubService.CommercialLeisure, Building.Flags.Created | Building.Flags.Active, Building.Flags.Deleted); if (foundLeisure != 0) { if (_simulationManager.m_randomizer.Int32(0, 10) > 2) { thisAI.StartMoving(citizenID, ref person, buildingID, foundLeisure); person.SetVisitplace(citizenID, foundLeisure, 0U); person.m_visitBuilding = foundLeisure; LoggingWrapper.Log("Citizen " + citizenID + " found leisure."); } else { LoggingWrapper.Log("Citizen " + citizenID + " found leisure, but chose not to bother."); NewResidentAI.FindVisitPlace(thisAI, citizenID, buildingID, NewResidentAI.GetEntertainmentReason(thisAI)); } } else { LoggingWrapper.Log("Citizen " + citizenID + " couldn't find leisure."); NewResidentAI.FindVisitPlace(thisAI, citizenID, buildingID, NewResidentAI.GetEntertainmentReason(thisAI)); } } return(foundLeisure); }
public static TransferManager.TransferReason GetEntertainmentReason(ResidentAI thisAI) { Debug.LogWarning("GetEntertainmentReason is not overridden!"); return 0; }
public static bool ProcessHome(ref ResidentAI thisAI, uint citizenID, ref Citizen person) { CitizenManager _citizenManager = Singleton <CitizenManager> .instance; SimulationManager _simulation = Singleton <SimulationManager> .instance; if ((person.m_flags & Citizen.Flags.MovingIn) != Citizen.Flags.None) { _citizenManager.ReleaseCitizen(citizenID); } else if (ProcessGenerics(ref thisAI, citizenID, ref person)) { if ((person.m_flags & Citizen.Flags.NeedGoods) != Citizen.Flags.None && (!Chances.WorkDay(ref person) || _simulation.m_currentDayTimeHour > Chances.m_startWorkHour)) //Wants to go shopping { if (person.m_homeBuilding != 0 && person.m_instance == 0 && person.m_vehicle == 0) //Person isn't already out and about { if (_simulation.m_isNightTime) { uint chance = _simulation.m_randomizer.UInt32(1000); if (chance < Chances.GoOutAtNight(person.Age) && NewResidentAI.DoRandomMove(thisAI)) { //Only go locally to find a shop at night FindCloseVisitPlace(ref thisAI, citizenID, ref person, person.m_homeBuilding, 1000f); return(true); } } else if (NewResidentAI.DoRandomMove(thisAI)) { uint chance = _simulation.m_randomizer.UInt32(100); if (chance < 10) { uint localChance = _simulation.m_randomizer.UInt32(100); ushort localVisitPlace = 0; if (ExperimentsToggle.AllowLocalBuildingSearch && localChance < ExperimentsToggle.LocalBuildingPercentage) { LoggingWrapper.Log("Citizen " + citizenID + " trying to find a local commercial building."); localVisitPlace = FindCloseVisitPlace(ref thisAI, citizenID, ref person, person.m_homeBuilding, 1000f); } if (localVisitPlace == 0) { LoggingWrapper.Log("Citizen " + citizenID + " going to a random commercial building."); NewResidentAI.FindVisitPlace(thisAI, citizenID, person.m_homeBuilding, NewResidentAI.GetShoppingReason(thisAI)); } return(true); } } } } else if (person.m_homeBuilding != 0 && person.m_instance != 0 && person.m_vehicle == 0 || NewResidentAI.DoRandomMove(thisAI)) //If the person is already out and about, or can move (based on entities already visible) { int eventId = CityEventManager.instance.EventStartsWithin(citizenID, ref person, StartMovingToEventTime); if (eventId != -1) { CityEvent _cityEvent = CityEventManager.instance.m_nextEvents[eventId]; if (_cityEvent.EventStartsWithin(StartMovingToEventTime) && !_cityEvent.EventStartsWithin(MaxMoveToEventTime)) { if ((person.m_instance != 0 || NewResidentAI.DoRandomMove(thisAI)) && _cityEvent.Register(citizenID, ref person)) { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_homeBuilding, _cityEvent.m_eventData.m_eventBuilding); person.SetVisitplace(citizenID, _cityEvent.m_eventData.m_eventBuilding, 0U); person.m_visitBuilding = _cityEvent.m_eventData.m_eventBuilding; return(true); } } } else { if (person.m_workBuilding != 0 && !_simulation.m_isNightTime && !Chances.ShouldReturnFromWork(ref person)) { if (Chances.ShouldGoToWork(ref person)) { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_homeBuilding, person.m_workBuilding); return(true); } } else { if (Chances.ShouldGoFindEntertainment(ref person)) { if (_simulation.m_isNightTime) { FindLeisure(ref thisAI, citizenID, ref person, person.m_homeBuilding); } else { NewResidentAI.FindVisitPlace(thisAI, citizenID, person.m_homeBuilding, NewResidentAI.GetEntertainmentReason(thisAI)); } return(true); } } } } } return(false); }
public static bool ProcessHome(ref ResidentAI thisAI, uint citizenID, ref Citizen person) { CitizenManager _citizenManager = Singleton<CitizenManager>.instance; SimulationManager _simulation = Singleton<SimulationManager>.instance; if ((person.m_flags & Citizen.Flags.MovingIn) != Citizen.Flags.None) { _citizenManager.ReleaseCitizen(citizenID); return false; } else if (person.Dead) { if (person.m_homeBuilding == 0) { _citizenManager.ReleaseCitizen(citizenID); return false; } if (person.m_workBuilding != 0) { person.SetWorkplace(citizenID, 0, 0U); } if (person.m_visitBuilding != 0) { person.SetVisitplace(citizenID, 0, 0U); } if (ExperimentsToggle.ExperimentDeathcare()) { if (person.m_vehicle == 0 && !NewResidentAI.FindHospital(thisAI, citizenID, person.m_homeBuilding, TransferManager.TransferReason.Sick)) { return false; } } else { if (person.m_vehicle == 0 && !NewResidentAI.FindHospital(thisAI, citizenID, person.m_homeBuilding, TransferManager.TransferReason.Dead)) { return false; } } } else if (person.Arrested) { person.Arrested = false; } else if (person.Sick) { if (person.m_homeBuilding != 0 && person.m_vehicle == 0 && !NewResidentAI.FindHospital(thisAI, citizenID, person.m_homeBuilding, TransferManager.TransferReason.Sick)) { return false; } } else if ((person.m_flags & Citizen.Flags.NeedGoods) != Citizen.Flags.None) //Wants to go shopping { if (person.m_homeBuilding != 0 && person.m_instance == 0 && person.m_vehicle == 0) //Person isn't already out and about { if (_simulation.m_isNightTime) { uint chance = _simulation.m_randomizer.UInt32(1000); if (chance < Chances.GoOutAtNight(person.Age)) { NewResidentAI.FindVisitPlace(thisAI, citizenID, person.m_homeBuilding, NewResidentAI.GetShoppingReason(thisAI)); } } else { NewResidentAI.FindVisitPlace(thisAI, citizenID, person.m_homeBuilding, NewResidentAI.GetShoppingReason(thisAI)); } } } else if (person.m_homeBuilding != 0 && person.m_instance != 0 && person.m_vehicle == 0 || NewResidentAI.DoRandomMove(thisAI)) //If the person is already out and about, or can move (based on entities already visible) { if (person.m_workBuilding != 0 && !_simulation.m_isNightTime && !Chances.ShouldReturnFromWork(ref person)) { if (Chances.ShouldGoToWork(ref person)) { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_homeBuilding, person.m_workBuilding); } } else { if(Chances.ShouldGoFindEntertainment(ref person)) { NewResidentAI.FindVisitPlace(thisAI, citizenID, person.m_homeBuilding, NewResidentAI.GetEntertainmentReason(thisAI)); } } } return true; }
public static bool ProcessWork(ref ResidentAI thisAI, uint citizenID, ref Citizen person) { CitizenManager _citizenManager = Singleton <CitizenManager> .instance; BuildingManager _buildingManager = Singleton <BuildingManager> .instance; SimulationManager _simulation = Singleton <SimulationManager> .instance; if (ProcessGenerics(ref thisAI, citizenID, ref person)) { if (person.m_instance != 0 || NewResidentAI.DoRandomMove(thisAI)) //If the person is already out and about, or can move (based on entities already visible) { if (Chances.ShouldReturnFromWork(ref person)) { int eventId = CityEventManager.instance.EventStartsWithin(citizenID, ref person, StartMovingToEventTime); if (eventId != -1) { CityEvent _cityEvent = CityEventManager.instance.m_nextEvents[eventId]; if (_cityEvent.EventStartsWithin(StartMovingToEventTime) && !_cityEvent.EventStartsWithin(MaxMoveToEventTime)) { if ((person.m_instance != 0 || NewResidentAI.DoRandomMove(thisAI)) && _cityEvent.Register(citizenID, ref person)) { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_workBuilding, _cityEvent.m_eventData.m_eventBuilding); person.SetVisitplace(citizenID, _cityEvent.m_eventData.m_eventBuilding, 0U); person.m_visitBuilding = _cityEvent.m_eventData.m_eventBuilding; } } } else { if (Chances.ShouldGoFindEntertainment(ref person)) { uint localChance = _simulation.m_randomizer.UInt32(100); ushort localVisitPlace = 0; if (ExperimentsToggle.AllowLocalBuildingSearch && localChance < ExperimentsToggle.LocalBuildingPercentage) { LoggingWrapper.Log("Citizen " + citizenID + " trying to find a local commercial building."); localVisitPlace = FindCloseVisitPlace(ref thisAI, citizenID, ref person, person.m_workBuilding, 1000f); } if (localVisitPlace == 0) { LoggingWrapper.Log("Citizen " + citizenID + " going to a random commercial building."); NewResidentAI.FindVisitPlace(thisAI, citizenID, person.m_workBuilding, NewResidentAI.GetEntertainmentReason(thisAI)); } return(true); } else { if ((person.m_flags & Citizen.Flags.NeedGoods) != Citizen.Flags.None) //Wants to go shopping { if (person.m_workBuilding != 0 && person.m_instance == 0 && person.m_vehicle == 0) //Person isn't already out and about { uint localChance = _simulation.m_randomizer.UInt32(100); ushort localVisitPlace = 0; if (ExperimentsToggle.AllowLocalBuildingSearch && localChance < ExperimentsToggle.LocalBuildingPercentage) { LoggingWrapper.Log("Citizen " + citizenID + " trying to find a local commercial building."); localVisitPlace = FindCloseVisitPlace(ref thisAI, citizenID, ref person, person.m_workBuilding, 1000f); } if (localVisitPlace == 0) { LoggingWrapper.Log("Citizen " + citizenID + " going to a random commercial building."); NewResidentAI.FindVisitPlace(thisAI, citizenID, person.m_workBuilding, NewResidentAI.GetShoppingReason(thisAI)); } } return(true); } else { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_workBuilding, person.m_homeBuilding); return(true); } } } } else if (Chances.ShouldGoToLunch(ref person) && person.m_workBuilding != 0) { //Try find somewhere close to eat ushort foundLunchPlace = FindCloseVisitPlace(ref thisAI, citizenID, ref person, person.m_workBuilding, 200f); if (foundLunchPlace != 0) { LoggingWrapper.Log("Citizen " + citizenID + " is heading out to eat for lunch at " + CityEventManager.CITY_TIME.ToShortTimeString() + "."); return(true); } else { LoggingWrapper.Log("Citizen " + citizenID + " wanted to head out for lunch, but there were no buildings close enough."); } } } } return(false); }
public static bool ProcessVisit(ref ResidentAI thisAI, uint citizenID, ref Citizen person) { if (ProcessGenerics(ref thisAI, citizenID, ref person)) { SimulationManager _simulation = Singleton <SimulationManager> .instance; WeatherManager _weatherManager = Singleton <WeatherManager> .instance; BuildingManager _buildingManager = Singleton <BuildingManager> .instance; ItemClass.Service service = ItemClass.Service.None; if (person.m_visitBuilding != 0) { service = _buildingManager.m_buildings.m_buffer[person.m_visitBuilding].Info.m_class.m_service; } if (service == ItemClass.Service.PoliceDepartment || service == ItemClass.Service.HealthCare) { if (person.m_homeBuilding != 0 && person.m_instance == 0 && person.m_vehicle == 0) { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_visitBuilding, person.m_homeBuilding); person.SetVisitplace(citizenID, 0, 0U); return(true); } } if (service == ItemClass.Service.Disaster) { if (_buildingManager.m_buildings.m_buffer[person.m_visitBuilding].m_flags.IsFlagSet(Building.Flags.Downgrading) && person.m_homeBuilding != 0 && person.m_vehicle == 0) { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_visitBuilding, person.m_homeBuilding); person.SetVisitplace(citizenID, 0, 0U); } } else if (!GameEventHelpers.EventTakingPlace(person.m_visitBuilding) && !CityEventManager.instance.EventTakingPlace(person.m_visitBuilding) && !CityEventManager.instance.EventStartsWithin(person.m_visitBuilding, 2D)) { int eventId = CityEventManager.instance.EventStartsWithin(citizenID, ref person, StartMovingToEventTime); bool eventOn = false; if (eventId != -1) { CityEvent _cityEvent = CityEventManager.instance.m_nextEvents[eventId]; if (_cityEvent.EventStartsWithin(StartMovingToEventTime) && !_cityEvent.EventStartsWithin(MaxMoveToEventTime)) { if ((person.m_instance != 0 || NewResidentAI.DoRandomMove(thisAI)) && _cityEvent.Register(citizenID, ref person)) { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_visitBuilding, _cityEvent.m_eventData.m_eventBuilding); person.SetVisitplace(citizenID, _cityEvent.m_eventData.m_eventBuilding, 0U); person.m_visitBuilding = _cityEvent.m_eventData.m_eventBuilding; eventOn = true; } } } if (!eventOn) { if (person.m_instance != 0 && _weatherManager.m_currentRain > 0 && _simulation.m_randomizer.Int32(0, 10) <= (_weatherManager.m_currentRain * 10)) { //It's raining, we're outside, and we need to go somewhere dry! if (person.m_workBuilding != 0 && !_simulation.m_isNightTime && !Chances.ShouldReturnFromWork(ref person)) { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_visitBuilding, person.m_workBuilding); LoggingWrapper.Log("Rain! Citizen " + citizenID + " is getting wet, and has decided to go back to work."); } else { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_visitBuilding, person.m_homeBuilding); LoggingWrapper.Log("Rain! Citizen " + citizenID + " is getting wet, and has decided to go home."); } person.SetVisitplace(citizenID, 0, 0U); } else if (person.m_workBuilding != 0 && (Chances.ShouldGoToWork(ref person) || ((Chances.LunchHour() || Chances.HoursSinceLunchHour(1.5f)) && Chances.ShouldGoToWork(ref person, true)))) { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_visitBuilding, person.m_workBuilding); person.SetVisitplace(citizenID, 0, 0U); LoggingWrapper.Log("Citizen " + citizenID + " was out and about but should've been at work. Going there now."); } else if ((person.m_flags & Citizen.Flags.NeedGoods) != Citizen.Flags.None) { if (person.m_visitBuilding == 0) { person.CurrentLocation = Citizen.Location.Home; } else { BuildingManager instance = Singleton <BuildingManager> .instance; BuildingInfo info = instance.m_buildings.m_buffer[person.m_visitBuilding].Info; int amountDelta = -100; info.m_buildingAI.ModifyMaterialBuffer(person.m_visitBuilding, ref instance.m_buildings.m_buffer[person.m_visitBuilding], TransferManager.TransferReason.Shopping, ref amountDelta); } return(true); } else if ((person.m_instance != 0 || NewResidentAI.DoRandomMove(thisAI)) && person.m_homeBuilding != 0 && person.m_vehicle == 0) { uint shouldStayPercent = 2; if (Chances.CanStayOut(ref person) && _simulation.m_randomizer.UInt32(100) < shouldStayPercent) { if (Chances.ShouldGoFindEntertainment(ref person)) { if (_simulation.m_isNightTime) { FindLeisure(ref thisAI, citizenID, ref person, person.m_visitBuilding); } else { NewResidentAI.FindVisitPlace(thisAI, citizenID, person.m_visitBuilding, NewResidentAI.GetEntertainmentReason(thisAI)); } return(true); } } else { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_visitBuilding, person.m_homeBuilding); person.SetVisitplace(citizenID, 0, 0U); return(true); } } } } } person.m_flags &= Citizen.Flags.Unemployed | Citizen.Flags.Wealth | Citizen.Flags.Location | Citizen.Flags.NoElectricity | Citizen.Flags.NoWater | Citizen.Flags.NoSewage | Citizen.Flags.BadHealth | Citizen.Flags.Created | Citizen.Flags.Tourist | Citizen.Flags.Sick | Citizen.Flags.Dead | Citizen.Flags.Student | Citizen.Flags.MovingIn | Citizen.Flags.DummyTraffic | Citizen.Flags.Criminal | Citizen.Flags.Arrested | Citizen.Flags.Evacuating | Citizen.Flags.Collapsed | Citizen.Flags.Education1 | Citizen.Flags.Education2 | Citizen.Flags.Education3 | Citizen.Flags.Original | Citizen.Flags.CustomName; return(false); }
private static bool StartMoving(ResidentAI instance, uint citizenId, ref Citizen citizen, ushort sourceBuilding, ushort targetBuilding) { throw new InvalidOperationException(RedirectNeededMessage); }
private static bool StartMoving(ResidentAI instance, uint citizenId, ref Citizen citizen, ushort sourceBuilding, TransferManager.TransferOffer offer) { throw new InvalidOperationException(RedirectNeededMessage); }
private static bool DoRandomMove(ResidentAI instance) { throw new InvalidOperationException(RedirectNeededMessage); }
private static TransferManager.TransferReason GetEntertainmentReason(ResidentAI instance) { throw new InvalidOperationException(RedirectNeededMessage); }
private static TransferManager.TransferReason GetEvacuationReason(ResidentAI instance, ushort sourceBuilding) { throw new InvalidOperationException(RedirectNeededMessage); }
private static void FindVisitPlace(ResidentAI instance, uint citizenId, ushort sourceBuilding, TransferManager.TransferReason reason) { throw new InvalidOperationException(RedirectNeededMessage); }
public static bool StartMoving(ResidentAI thisAI, uint citizenID, ref Citizen data, ushort sourceBuilding, ushort targetBuilding) { Debug.LogWarning("StartMoving is not overridden!"); return false; }
public static bool FindHospital(ResidentAI thisAI, uint citizenID, ushort sourceBuilding, TransferManager.TransferReason reason) { Debug.LogWarning("FindHospital is not overridden!"); return false; }
public static void FindVisitPlace(ResidentAI thisAI, uint citizenID, ushort sourceBuilding, TransferManager.TransferReason reason) { Debug.LogWarning("FindVisitPlace is not overridden!"); }
public static bool Prefix(ResidentAI __instance, ref VehicleInfo __result, ushort instanceID, ref CitizenInstance citizenData, bool forceProbability, out VehicleInfo trailer) { #if DEBUG bool citizenDebug = (DebugSettings.CitizenInstanceId == 0 || DebugSettings.CitizenInstanceId == instanceID) && (DebugSettings.CitizenId == 0 || DebugSettings.CitizenId == citizenData.m_citizen) && (DebugSettings.SourceBuildingId == 0 || DebugSettings.SourceBuildingId == citizenData.m_sourceBuilding) && (DebugSettings.TargetBuildingId == 0 || DebugSettings.TargetBuildingId == citizenData.m_targetBuilding); bool logParkingAi = DebugSwitch.BasicParkingAILog.Get() && citizenDebug; #else var logParkingAi = false; #endif trailer = null; if (citizenData.m_citizen == 0u) { __result = null; return(false); } // NON-STOCK CODE START bool forceTaxi = false; if (Options.parkingAI) { if (ExtCitizenInstanceManager.Instance.ExtInstances[instanceID] .pathMode == ExtPathMode.TaxiToTarget) { forceTaxi = true; } } // NON-STOCK CODE END Citizen.AgeGroup ageGroup = Constants.ManagerFactory.ExtCitizenManager.GetAgeGroup(citizenData.Info.m_agePhase); int carProb; int bikeProb; int taxiProb; // NON-STOCK CODE START if (forceTaxi) { carProb = 0; bikeProb = 0; taxiProb = 100; } else // NON-STOCK CODE END if (forceProbability || (citizenData.m_flags & CitizenInstance.Flags.BorrowCar) != CitizenInstance.Flags.None) { carProb = 100; bikeProb = 0; taxiProb = 0; } else { carProb = GetCarProbability(__instance, instanceID, ref citizenData, ageGroup); bikeProb = GetBikeProbability(__instance, instanceID, ref citizenData, ageGroup); taxiProb = GetTaxiProbability(__instance, instanceID, ref citizenData, ageGroup); } Randomizer randomizer = new Randomizer(citizenData.m_citizen); bool useCar = randomizer.Int32(100u) < carProb; bool useBike = !useCar && randomizer.Int32(100u) < bikeProb; bool useTaxi = !useCar && !useBike && randomizer.Int32(100u) < taxiProb; bool useElectricCar = false; if (useCar) { int electricProb = GetElectricCarProbability(__instance, instanceID, ref citizenData, __instance.m_info.m_agePhase); useElectricCar = randomizer.Int32(100u) < electricProb; } ItemClass.Service service = ItemClass.Service.Residential; ItemClass.SubService subService = useElectricCar ? ItemClass.SubService.ResidentialLowEco : ItemClass.SubService.ResidentialLow; if (useTaxi) { service = ItemClass.Service.PublicTransport; subService = ItemClass.SubService.PublicTransportTaxi; } // NON-STOCK CODE START VehicleInfo carInfo = null; if (Options.parkingAI && useCar) { ushort parkedVehicleId = citizenData.m_citizen.ToCitizen().m_parkedVehicle; if (parkedVehicleId != 0) { Log._DebugIf( logParkingAi, () => $"CustomResidentAI.CustomGetVehicleInfo({instanceID}): " + $"Citizen instance {instanceID} owns a parked vehicle {parkedVehicleId}. " + $"Reusing vehicle info."); carInfo = parkedVehicleId.ToParkedVehicle().Info; } } if (carInfo == null && (useCar || useTaxi)) { // NON-STOCK CODE END carInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo( ref randomizer, service, subService, ItemClass.Level.Level1); } if (useBike) { ItemClass.Level ageGroupLvl = ageGroup != Citizen.AgeGroup.Child ? ItemClass.Level.Level2 : ItemClass.Level.Level1; VehicleInfo bikeInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo( ref randomizer, ItemClass.Service.Residential, ItemClass.SubService.ResidentialHigh, ageGroupLvl); if (bikeInfo != null) { __result = bikeInfo; return(false); } } if ((useCar || useTaxi) && carInfo != null) { __result = carInfo; return(false); } __result = null; return(false); }
internal static bool ProcessMoving(ref ResidentAI resident, uint citizenID, ref Citizen data) { if (data.Dead) { if (data.m_vehicle == 0) { Singleton<CitizenManager>.instance.ReleaseCitizen(citizenID); return false; } if (data.m_homeBuilding != 0) { data.SetHome(citizenID, 0, 0U); } if (data.m_workBuilding != 0) { data.SetWorkplace(citizenID, 0, 0U); } if (data.m_visitBuilding != 0) { data.SetVisitplace(citizenID, 0, 0U); return true; } return true; } if (data.m_vehicle == 0 && data.m_instance == 0) //If they've stopped moving for whatever reason { if (data.m_visitBuilding != 0) { data.SetVisitplace(citizenID, 0, 0U); } data.CurrentLocation = Citizen.Location.Home; data.Arrested = false; return true; } return true; }
/// <summary> /// Generic stuff that can be taken care of as a group. /// </summary> /// <param name="thisAI"></param> /// <param name="citizenID"></param> /// <param name="person"></param> /// <returns>Whether to continue or whether this has taken care of the resident.</returns> private static bool ProcessGenerics(ref ResidentAI thisAI, uint citizenID, ref Citizen person) { bool everythingOk = false; ushort residingBuilding = 0; CitizenManager _citizenManager = Singleton <CitizenManager> .instance; Citizen.Location _currentLocation = person.CurrentLocation; switch (_currentLocation) { case Citizen.Location.Home: residingBuilding = person.m_homeBuilding; break; case Citizen.Location.Work: residingBuilding = person.m_workBuilding; break; case Citizen.Location.Visit: residingBuilding = person.m_visitBuilding; break; } Building visitBuilding = Singleton <BuildingManager> .instance.m_buildings.m_buffer[person.m_visitBuilding]; bool inHealthcare = _currentLocation == Citizen.Location.Visit && residingBuilding != 0 && (visitBuilding.Info.m_class.m_service == ItemClass.Service.HealthCare || visitBuilding.Info.m_class.m_service == ItemClass.Service.Disaster); if (person.Dead) { if (residingBuilding == 0) { _citizenManager.ReleaseCitizen(citizenID); } else { if ((_currentLocation == Citizen.Location.Work || _currentLocation == Citizen.Location.Visit) && person.m_homeBuilding != 0) { person.SetWorkplace(citizenID, 0, 0U); } if ((_currentLocation == Citizen.Location.Home || _currentLocation == Citizen.Location.Visit) && person.m_workBuilding != 0) { person.SetWorkplace(citizenID, 0, 0U); } if ((_currentLocation == Citizen.Location.Home || _currentLocation == Citizen.Location.Work) && person.m_visitBuilding != 0) { person.SetVisitplace(citizenID, 0, 0U); } if (ExperimentsToggle.ImprovedDeathcare) { if (person.m_vehicle == 0 && !inHealthcare) { NewResidentAI.FindHospital(thisAI, citizenID, residingBuilding, TransferManager.TransferReason.Sick); } } else { if (person.m_vehicle == 0 && !inHealthcare) { NewResidentAI.FindHospital(thisAI, citizenID, residingBuilding, TransferManager.TransferReason.Dead); } } } } else if (person.Arrested) { if (_currentLocation == Citizen.Location.Visit && residingBuilding == 0) { person.Arrested = false; } else { person.Arrested = false; } } else if (person.Sick) { if (residingBuilding != 0) { if (person.m_vehicle == 0 && !inHealthcare) { NewResidentAI.FindHospital(thisAI, citizenID, residingBuilding, TransferManager.TransferReason.Sick); } } else { person.CurrentLocation = Citizen.Location.Home; } } else if (residingBuilding == 0) { person.CurrentLocation = Citizen.Location.Home; } else if (ShouldEvacuate(residingBuilding)) { NewResidentAI.FindEvacuationPlace(thisAI, citizenID, residingBuilding, NewResidentAI.GetEvacuationReason(thisAI, residingBuilding)); } else if (!person.Collapsed) { everythingOk = true; } return(everythingOk); }
public static bool DoRandomMove(ResidentAI thisAI) { Debug.LogWarning("DoRandomMove is not overridden!"); return false; }
#pragma warning disable SA1313 // Parameter names must begin with lower-case letter private static bool Prefix(ResidentAI __instance, uint citizenID, ref Citizen data) { RealTimeAI?.UpdateLocation(__instance, citizenID, ref data); return(false); }
public static bool ProcessVisit(ref ResidentAI thisAI, uint citizenID, ref Citizen person) { if (person.Dead) { if (person.m_visitBuilding == 0) { Singleton<CitizenManager>.instance.ReleaseCitizen(citizenID); return false; } if (person.m_homeBuilding != 0) { person.SetHome(citizenID, (ushort)0, 0U); } if (person.m_workBuilding != 0) { person.SetWorkplace(citizenID, (ushort)0, 0U); } if (ExperimentsToggle.ExperimentDeathcare()) { if (person.m_vehicle == 0) { /*Attempt at making death more realistic. When people die they should now go to hospital, then get picked up from there by hearse.*/ if (Singleton<BuildingManager>.instance.m_buildings.m_buffer[person.m_visitBuilding].Info.m_class.m_service == ItemClass.Service.HealthCare) { if (!NewResidentAI.FindHospital(thisAI, citizenID, person.m_visitBuilding, TransferManager.TransferReason.Dead)) { return false; } } else if (!NewResidentAI.FindHospital(thisAI, citizenID, person.m_visitBuilding, TransferManager.TransferReason.Sick)) { return false; } } } else { if (person.m_vehicle == 0 && Singleton<BuildingManager>.instance.m_buildings.m_buffer[person.m_visitBuilding].Info.m_class.m_service != ItemClass.Service.HealthCare && !NewResidentAI.FindHospital(thisAI, citizenID, person.m_visitBuilding, TransferManager.TransferReason.Dead)) { return false; } } return true; } if (person.Arrested) { if (person.m_visitBuilding == 0) { person.Arrested = false; return true; } return true; } if (person.Sick) { if (person.m_visitBuilding == 0) { person.CurrentLocation = Citizen.Location.Home; return true; } if (person.m_vehicle == 0 && Singleton<BuildingManager>.instance.m_buildings.m_buffer[person.m_visitBuilding].Info.m_class.m_service != ItemClass.Service.HealthCare && !NewResidentAI.FindHospital(thisAI, citizenID, person.m_visitBuilding, TransferManager.TransferReason.Sick)) { return false; } return true; } ItemClass.Service service = ItemClass.Service.None; if (person.m_visitBuilding != 0) { service = Singleton<BuildingManager>.instance.m_buildings.m_buffer[(int)person.m_visitBuilding].Info.m_class.m_service; } if (service == ItemClass.Service.PoliceDepartment || service == ItemClass.Service.HealthCare) { if (person.m_homeBuilding != 0 && person.m_instance == 0 && person.m_vehicle == 0) { NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_visitBuilding, person.m_homeBuilding); person.SetVisitplace(citizenID, 0, 0U); return true; } return true; } if ((person.m_flags & Citizen.Flags.NeedGoods) != Citizen.Flags.None) { if (person.m_visitBuilding == 0) { person.CurrentLocation = Citizen.Location.Home; return true; } BuildingManager instance = Singleton<BuildingManager>.instance; BuildingInfo info = instance.m_buildings.m_buffer[person.m_visitBuilding].Info; int amountDelta = -100; info.m_buildingAI.ModifyMaterialBuffer(person.m_visitBuilding, ref instance.m_buildings.m_buffer[person.m_visitBuilding], TransferManager.TransferReason.Shopping, ref amountDelta); return true; } if (person.m_visitBuilding == 0) { person.CurrentLocation = Citizen.Location.Home; return true; } if ((person.m_instance != 0 || NewResidentAI.DoRandomMove(thisAI)) && person.m_homeBuilding != 0 && person.m_instance == 0 && person.m_vehicle == 0) { uint shouldStayPercent = 2; SimulationManager _simulation = Singleton<SimulationManager>.instance; if (Chances.CanStayOut(ref person) && _simulation.m_randomizer.UInt32(100) < shouldStayPercent) { if (Chances.ShouldGoFindEntertainment(ref person)) { NewResidentAI.FindVisitPlace(thisAI, citizenID, person.m_homeBuilding, NewResidentAI.GetEntertainmentReason(thisAI)); return true; } return true; } NewResidentAI.StartMoving(thisAI, citizenID, ref person, person.m_visitBuilding, person.m_homeBuilding); person.SetVisitplace(citizenID, 0, 0U); return true; } return true; }