Open kendallroth opened 3 months ago
"Scene Explorer" mod is useful in-game for selecting an entity and viewing its components. From investigations there are a couple of potential options:
Game.Creatures.Human
component, then check for m_Flags=Homeless
(bit comparison, likely?)Game.Citizens.HomelessHousehold
component, then get household members
Game.Citizens.HomelessHousehold
likely have a Game.Citizens.Household
component, as well as a Game.Citizens.HouseholdCitizen
buffer (length of people in homeless household?) 🎉HomelessHousehold
does return the same value/amount as searching for that component in-game (Scene Explorer)HomelessHousehold
apparently only exists for homeless currently living in a park!Game.Citizens.HouseholdMember
, which has m_Household
sub-entity, which in turn has Game.Citizens.HomelessHousehold
component. m_Household
sub-entity also has a prefab ref "component" (DynamicHousehold
) with a household data prefab containing the counts of children, students, adults, elders (not sure about teens?).[!Warning] Some information about
HomelessHousehold
has been adjusted!
Game.UI.InGame.CitizenUIUtils.cs
has an example (GetCitizenConditions()
) of indicating whether a citizen is homeless (for selected citizen info screen).
// From 'StatusSection', which inherits 'InfoSectionBase', which inherits 'UISystemBase'
Entity selectedEntity; // From 'InfoSectionBase' property
EntityManager entityManager = ((ComponentSystemBase)this).EntityManager;
Citizen componentData = ((EntityManager)(ref entityManager)).GetComponentData<Citizen>(selectedEntity);
entityManager = ((ComponentSystemBase)this).EntityManager;
HouseholdMember componentData2 = ((EntityManager)(ref entityManager)).GetComponentData<HouseholdMember>(selectedEntity);
conditions = CitizenUIUtils.GetCitizenConditions(((ComponentSystemBase)this).EntityManager, selectedEntity, componentData, componentData2, conditions);
public static NativeList<CitizenCondition> GetCitizenConditions(
EntityManager entityManager,
Entity entity,
Citizen citizen,
HouseholdMember householdMember,
NativeList<CitizenCondition> conditions
)
{
PropertyRenter propertyRenter = default(PropertyRenter);
if (
!((EntityManager)(ref entityManager)).HasComponent<CommuterHousehold>(householdMember.m_Household) &&
!((EntityManager)(ref entityManager)).HasComponent<TouristHousehold>(householdMember.m_Household) &&
(
!EntitiesExtensions.TryGetComponent<PropertyRenter>(entityManager, householdMember.m_Household, ref propertyRenter) ||
((EntityManager)(ref entityManager)).HasComponent<Game.Buildings.Park>(propertyRenter.m_Property))
)
{
CitizenCondition citizenCondition = new CitizenCondition(CitizenConditionKey.Homeless);
conditions.Add(ref citizenCondition);
}
}
Game.Creatures.CreatureUtils.cs
has an example (GetConditions
) of checking if a human is homeless. However, this does not necessarily correspond with whether the game considers them homeless, as even with this flag some citizens do not display the "Homeless" condition when selected (due to having PropertyRenter
component?).
public static ActivityCondition GetConditions(Human human)
{
if ((human.m_Flags & HumanFlags.Homeless) != 0)
{ ... }
}
Game.Debug.DebugSystem.cs
has an example (RemoveAllHomeless
) of querying for homeless households (and adding a Deleted
component).
private void RemoveAllHomeless()
{
EntityManager entityManager = ((ComponentSystemBase)this).EntityManager;
EntityQuery val = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly<HomelessHousehold>() });
entityManager = ((ComponentSystemBase)this).EntityManager;
((EntityManager)(ref entityManager)).AddComponent<Deleted>(val);
}
Game.Simulation.CountHouseholdDataSystem.cs
has an example (Accumulate
) of counting homeless households via iteration in job.
Game.UI.InGame.DeveloperInfoUISystem.cs
has an example appearing to reference a homeless count, but unfortunately it was only counting homeless within selected park (in debug mode) 🤷.
Ran some queries in Scene Explorer to compare with in-game (population 12,127
)
Component | Value |
---|---|
Citizen |
12,709 |
HouseholdMember |
12,709 |
Household |
5,837 |
HouseholdCitizen |
5,837 |
PropertyRenter |
5,613 |
Human |
3,112 |
HomelessHousehold |
52 |
TouristHousehold |
4 |
CommuterHousehold |
0 |
Renter |
897 |
Resident |
3,112 |
less useful stats
Component | Value |
---|---|
Temp |
0 |
Deleted |
0 |
Criminal |
10 ✔️ |
Creature |
4,107 |
HouseholdPet |
3,223 |
Pet |
981 |
Old code comments during experimentation
// Homeless Person
// Components:
// - Game.Creatures.Human [m_Flags=Homeless]
// - Game.Creatures.Resident [m_Flags=Arrive,Hangaround,IgnoreBenches]
// - m_Citizen: Entity(78485:1 - Citizen Male)
// - Components:
// - Game.Citizens.HouseholdMember (single household)
// - m_Household: Entity(95261:1 - Single Household)
// - Components:
// - Game.Prefabs.PrefabRef - DynamicHousehold
// - Game.Buildings.PropertyRenter
// - m_Rent: 0
// - Game.Citizens.HomelessHousehold
// - m_TempHome (park entity)
// - Game.Citizens.Household [m_Flags=MovedIn]
// - Game.Citizens.Citizen
// - m_UnemploymentCounter: 0 (not helpful?)
// - Game.Citizens.Arrived (tag)
// - Game.Prefabs.PrefabRef - Elderly_Male
// - Game.Prefabs.ResidentData
// - m_Age: Elderly
It turns out that HomelessHousehold
component is only for homeless households living in parks... Any homeless not living in parks (which could be even more, likely) will not be included in this query! Parks appear to have a maximum amount of homeless slots, which would explain why the homeless households count was remaining steady (even with Bye Bye Homeless active).
The most reliable option appears to be iterating over Human
flag and checking for m_Flags
indicating homelessness... However, this is assuming that all Human
component entities are always available in simulation 🤷♂️ (which might not be the case for performance (see above in have queries), although households do have a list of members...).
Should check whether HomelessHousehold
s are associated with renting process, even if living temporarily in park?
It does appear that HomelessHousehold
entities are associated with renting process (ie. have Game.Buildings.PropertyRenter
component) when living in a park (albeit with m_Rent=0
). This PropertyRenter
component is associated with the same entity as HomelessHousehold
(ie. HouseholdMember.m_Household.[HomelessHousehold | PropertyRenter | PropertySeeker]
).
With the current issues with homelessness, it could be nice to show a homeless count/percentage. However, this data is not currently exposed to the UI, and may not even be calculated behind the scenes? Once implemented, the displayed value will also need to be determined, as a percentage of entire population may not be super beneficial at massive populations (then again, it is a very similar idea to unemployment, and could benefit from #16).
This will require some additional ECS work, particularly with Queries, but may also require a Job (depending on approach).
Note that unemployment does not necessarily indicate homeless (due to temporary unemployment allowance), but might help pare down list of citizens?
There are several mods that are already calculating this, including ByeByeHomeless and CimCensus. However, both of these mods seem a little bit overkill for simply calculating the number of homeless in the city, but they may be the only viable options...