Game.Simulation.MapTilePurchaseSystem
Assembly: Assembly-CSharp
Namespace: Game.Simulation
Type: class
Base: GameSystemBase, IMapTilePurchaseSystem
Summary:
Manages selection and purchase/unlock logic for map tiles in Cities: Skylines 2. Calculates purchase cost and upkeep based on map features and owned tiles, enforces permit/finance constraints, toggles the map-tile selection tool, and performs tile unlocking and achievement progress when tiles are bought. The system caches feature totals, exposes status flags, and queries various game systems (city, resources, map tiles, economy parameters, milestones).
Fields
-
private struct TypeHandle
Internal container used to cache ComponentLookup handles for PrefabRef, TilePurchaseCostFactor, Native and MapTile so the system can access component data efficiently during update. -
private static readonly double kMapTileSizeModifier
Baseline modifier applied to certain map features for cost calculation (derived from a hardcoded constant). -
private static readonly double kResourceModifier
Baseline modifier used for resource-type features. -
private static readonly int kAutoUnlockedTiles
Number of tiles auto-unlocked for a new city (9). -
private static readonly double[] kMapFeatureBaselineModifiers
Array of baseline multipliers used when calculating feature cost impact. Length covers map features expected by the game. -
private SelectionToolSystem m_SelectionToolSystem
Reference to the SelectionToolSystem (used to toggle/select map tiles). -
private DefaultToolSystem m_DefaultToolSystem
Reference to the default tool system (to restore default tool when exiting selection). -
private ToolSystem m_ToolSystem
Reference to the global ToolSystem (used to set active tool). -
private CitySystem m_CitySystem
Reference to the CitySystem (used for player money and city entity lookups). -
private NaturalResourceSystem m_NaturalResourceSystem
Reference to the NaturalResourceSystem (used to convert fertile land amounts to area). -
private MapTileSystem m_MapTileSystem
Reference to the MapTileSystem (used to get start tiles and other map tile helpers). -
private CityConfigurationSystem m_CityConfigurationSystem
Reference to CityConfigurationSystem (used to check city config like unlockMapTiles). -
private EntityQuery m_SelectionQuery
Query to retrieve selection buffer entity (SelectionElement) used when selecting tiles. -
private EntityQuery m_OwnedTileQuery
Query for owned MapTile entities (MapTile & without Native). -
private EntityQuery m_LockedMapTilesQuery
Query for locked map tiles (MapTile + Native + Area). -
private EntityQuery m_UnlockedMilestoneQuery
Query to fetch milestones that are unlocked (MilestoneData & not Locked). -
private EntityQuery m_LockedMilestoneQuery
Query to fetch milestones that are still locked (MilestoneData + Locked). -
private EntityQuery m_EconomyParameterQuery
Query to access EconomyParameterData singleton. -
private NativeArray<float> m_FeatureAmounts
Persistent native array caching totals for each map feature (size 9). Used to report feature amounts and aggregated calculations. Allocated in OnCreate and disposed in OnDestroy. -
private float m_Cost
Transient calculated purchase cost for the current selection. -
private float m_Upkeep
Transient calculated upkeep delta for the current selection. -
private TypeHandle __TypeHandle
Instance of the TypeHandle struct used to store ComponentLookup handles for fast access.
Properties
-
public TilePurchaseErrorFlags status { get; private set }
Current status flags describing whether a purchase is possible and, if not, why (e.g., None, NoSelection, InsufficientFunds, InsufficientPermits, NoAvailable, NoCurrentlyAvailable). Updated each frame in UpdateStatus. -
public bool selecting { get; set; }
Get: returns true when the active tool is the selection tool and its selectionType is MapTiles.
Set: toggles the selection tool for map tiles. Setting true will switch to the SelectionToolSystem with selectionType = MapTiles and selectionOwner = Entity.Null. Setting false will restore the DefaultToolSystem if selection tool was active. -
public int cost { get }
Rounded integer purchase cost for current selection (Mathf.RoundToInt(m_Cost)). -
public int upkeep { get }
Rounded integer upkeep change for the current selection (Mathf.RoundToInt(m_Upkeep)). -
public float GetMapTileUpkeepCostMultiplier(int tileCount)
Returns the upkeep multiplier for map tiles using the EconomyParameterData curve. Tiles up to kAutoUnlockedTiles (9) have 0 upkeep. For larger tile counts the economy parameter curve is evaluated. -
public bool GetMapTileUpkeepEnabled()
Checks whether upkeep is enabled for map tiles in the current configuration / economy parameters. Returns false if city configuration forces no map tile unlocks; otherwise inspects the economy curve to determine whether upkeep ever becomes non-zero.
Constructors
public MapTilePurchaseSystem()
Default constructor. (Most initialization happens in OnCreate.)
Methods
-
protected override void OnCreate()
: System.Void
Initializes references to other systems, builds entity queries, allocates m_FeatureAmounts and registers requirements for update (RequireForUpdate on economy parameters). Called when the system is created. -
protected override void OnDestroy()
: System.Void
Disposes persistent native memory (m_FeatureAmounts) and calls base cleanup. -
protected override void OnUpdate()
: System.Void
Called each frame; invokes UpdateStatus() to refresh selection cost/upkeep/status. -
private void UpdateStatus()
: System.Void
Core logic that: - Resets feature totals and costs.
- Calculates owned and available tiles, owned tile base cost/upkeep.
- Reads current selection buffer (if any) and computes a per-tile value based on map feature amounts, prefab factors, baseline modifiers and map feature costs.
- Sorts tile values and applies increasing multiplier for successive purchased tiles.
- Computes final m_Cost and m_Upkeep and updates status flags (insufficient permits, insufficient funds, no selection, etc.).
-
Uses multiple ComponentLookup handles and temporary NativeList for computation.
-
public int GetAvailableTiles()
: System.Int32
Returns how many additional tiles the player may purchase: auto-unlocked + unlocked milestones map-tiles minus currently owned tiles, clamped to >= 0. -
public bool IsMilestonesLeft()
: System.Boolean
Returns true if there are still locked milestones (i.e., more milestone rewards are available that could unlock map tiles). -
private double GetBaselineModifier(int mapFeature)
: System.Double
Returns a baseline modifier for the given map feature index using the kMapFeatureBaselineModifiers array; returns 1.0 for out-of-range indices. -
public void UnlockMapTiles()
: System.Void
Unlocks all currently locked map tiles matching the m_LockedMapTilesQuery by removing the Native component and adding an Updated component to notify the ECS. -
public void PurchaseSelection()
: System.Void
Attempts to purchase the current selection: - Calls UpdateStatus() and aborts if status != None.
- Subtracts cost from the PlayerMoney on the city entity.
- Retrieves the selection buffer (writable) and unlocks each selected tile via UnlockTile.
- Clears the selection, and indicates achievement progress for relevant achievements (TheExplorer, EverythingTheLightTouches).
-
Uses persistent EntityManager component changes for unlocking.
-
public static void UnlockTile(EntityManager entityManager, Entity area)
: System.Void
Static helper that removes the Native component from an area/entity (if present) and adds Updated component to mark the entity changed. -
private bool TryGetSelections(bool isReadOnly, out DynamicBuffer<SelectionElement> selections)
: System.Boolean
Attempts to get the SelectionElement buffer from the singleton selection entity when selecting is true; returns true and the buffer if successful, otherwise returns false and sets selections to default. -
public int GetSelectedTileCount()
: System.Int32
Returns the number of currently selected tiles (0 if none or not selecting). -
private int CalculateOwnedTiles()
: System.Int32
Counts owned tile entities by executing m_OwnedTileQuery.CalculateEntityCountWithoutFiltering(). -
private float CalculateOwnedTilesCost()
: System.Single
Calculates the aggregated cost baseline for currently owned tiles (or currently selected tiles if selection exists). Uses PrefabRef and TilePurchaseCostFactor, iterates features, applies baseline modifiers and prefab factors. Adds to m_FeatureAmounts while calculating. -
public int CalculateOwnedTilesUpkeep()
: System.Int32
Returns the upkeep for owned tiles by multiplying result of CalculateOwnedTilesCost() by GetMapTileUpkeepCostMultiplier(CalculateOwnedTiles()) and rounding. -
public float GetFeatureAmount(MapFeature feature)
: System.Single
Returns the cached feature amount from m_FeatureAmounts for the requested MapFeature. For FertileLand it converts resource amount to area using NaturalResourceSystem. -
private void __AssignQueries(ref SystemState state)
: System.Void
Compiler helper to initialize queries (internal; aggressive inlining present). No external use. -
protected override void OnCreateForCompiler()
: System.Void
Compiler helper: assigns queries and component lookup handles for the CheckedStateRef. Called by generated code path.
Usage Example
// Get the managed system from the world (typical in mod code)
var mapTileSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<Game.Simulation.MapTilePurchaseSystem>();
// Enter map-tile selection mode
mapTileSystem.selecting = true;
// ... player selects tiles via UI/tool ...
// Check computed status & costs (UpdateStatus runs on system update; you can call methods after an update)
if (mapTileSystem.status == TilePurchaseErrorFlags.None)
{
Debug.Log($"Cost: {mapTileSystem.cost}, Upkeep delta: {mapTileSystem.upkeep}");
// Attempt purchase
mapTileSystem.PurchaseSelection();
}
else
{
Debug.Log($"Cannot purchase tiles: {mapTileSystem.status}");
}
// Exit selection mode
mapTileSystem.selecting = false;
// Unlock all locked map tiles (administrative / cheat action)
mapTileSystem.UnlockMapTiles();
Notes:
- The system allocates a persistent NativeArray