Skip to content

Game.WaterToolSystem

Assembly:
Assembly-CSharp (Cities: Skylines 2 runtime assembly / modding assembly)

Namespace:
Game.Tools

Type:
class

Base:
ToolBaseSystem

Summary:
WaterToolSystem implements the in-game "Water Tool" used to inspect and edit water sources. It manages the tool's input/state machine (Default, MouseDown, Dragging), performs raycasts against water source entities (and terrain while dragging), decides which attribute of a water source the user is manipulating (Location, Radius, Rate, Height), and produces temporary "definition" entities (WaterSourceDefinition + CreationDefinition) via a scheduled CreateDefinitionsJob so the rest of the simulation / UI can preview or apply changes. The system integrates with TerrainSystem, WaterSystem, CameraUpdateSystem and uses a ToolOutputBarrier to safely create/destroy preview entities on the main thread.


Fields

  • public enum Attribute { None, Location, Radius, Rate, Height }
    Describes which attribute of a water source the cursor is currently over (or being dragged): None, Location (move), Radius (size), Rate (amount / flow), Height (absolute depth/height for constant-depth sources).

  • private enum State { Default, MouseDown, Dragging }
    Tool internal state machine: Default (idle), MouseDown (user pressed apply on an entity), Dragging (user is dragging to alter attribute).

  • [BurstCompile] private struct CreateDefinitionsJob : IJob
    Job that reads the start and current control points and creates ephemeral definition entities (CreationDefinition + WaterSourceDefinition) via an EntityCommandBuffer. It reads the WaterSourceData component and uses the current Attribute/State to modify amounts/radius/position for previews while dragging.

  • private struct TypeHandle
    Compiler helper that stores a read-only ComponentLookup. It exposes __AssignHandles to populate the lookup from the SystemState.

  • public const string kToolID = "Water Tool"
    Constant identifier for the tool.

  • private TerrainSystem m_TerrainSystem
    Cached reference to the TerrainSystem used for sampling terrain heights and getting position offset.

  • private WaterSystem m_WaterSystem
    Cached reference to the WaterSystem (present for completeness / potential interactions).

  • private CameraUpdateSystem m_CameraUpdateSystem
    Cached reference to the camera/viewer system; used to compute raycast lines and viewer orientation for attribute detection.

  • private ToolOutputBarrier m_ToolOutputBarrier
    Barrier system used to create/destroy preview entities (EntityCommandBuffer producer barrier).

  • private EntityQuery m_DefinitionQuery
    EntityQuery used to find existing definition entities so they can be destroyed/updated when the raycast or state changes.

  • private ControlPoint m_RaycastPoint
    Current raycast result (ControlPoint) under the cursor this frame.

  • private ControlPoint m_StartPoint
    ControlPoint captured when the apply action was first pressed; used as the origin for dragging computations.

  • private State m_State
    Current tool state (Default, MouseDown, Dragging).

  • private TypeHandle __TypeHandle
    Instance of the compiler helper TypeHandle that contains the ComponentLookup used by jobs.

Properties

  • public override string toolID => "Water Tool"
    Unique tool identifier returned to the base Tool system. Used to distinguish this tool from others.

  • public Attribute attribute { get; private set; }
    Which Attribute is currently active/under-cursor. Public getter so other systems or UI can query the current attribute; setter is private and managed by the tool's logic.

Constructors

  • public WaterToolSystem()
    Default constructor. Marked with [Preserve] in source to avoid stripping; no custom initialization beyond what the ECS OnCreate/OnStartRunning methods perform.

Methods

  • [Preserve] protected override void OnCreate()
    Initializes the system: calls base.OnCreate(), caches references to TerrainSystem, WaterSystem, CameraUpdateSystem and ToolOutputBarrier from the World, and initializes the EntityQuery used for definition entities. This is where the system acquires other systems it depends on.

  • [Preserve] protected override void OnStartRunning()
    Resets transient state when the system starts running: clears raycast/start control points, sets state to Default and attribute to None.

  • private protected override void UpdateActions()
    Enables or disables tool actions (apply / secondary apply) based on actionsEnabled flag from base.

  • public override PrefabBase GetPrefab()
    Returns null. The WaterToolSystem does not use a prefab selection mechanic (it returns null to indicate no prefab).

  • public override bool TrySetPrefab(PrefabBase prefab)
    Always returns false. The WaterToolSystem does not accept setting a prefab.

  • public override void InitializeRaycast()
    Configures the ToolRaycastSystem for the current state and attribute. While dragging a Location attribute it raycasts against terrain and offsets the ray by the current source depth to allow intuitive dragging; otherwise it raycasts against water sources. This controls how GetRaycastResult will behave.

  • [Preserve] protected override JobHandle OnUpdate(JobHandle inputDeps)
    Main update loop executed each frame. It:

  • Updates infoview and snap masks.
  • Checks whether raycasts are enabled.
  • Handles input events (apply / secondary apply) and routes to Apply, Cancel, Clear or Update functions.
  • Returns a JobHandle representing any scheduled jobs (definition creation, barrier jobs, etc).

  • public override void GetAvailableSnapMask(out Snap onMask, out Snap offMask)
    Extends the available snapping options by enabling/disabling ContourLines snapping in addition to the base behaviour.

  • private JobHandle Clear(JobHandle inputDeps)
    Sets applyMode = ApplyMode.Clear and returns. Used when the tool should clear its apply state.

  • private JobHandle Cancel(JobHandle inputDeps, bool singleFrameOnly = false)
    Handles cancellation input (secondary apply). Depending on current state it may reset applyMode and state to Default or Clear.

  • private JobHandle Apply(JobHandle inputDeps, bool singleFrameOnly = false)
    Handles apply input (primary apply). Transitions between Default / MouseDown / Dragging states, captures the start point when beginning a drag, and sets applyMode to Apply/Clear depending on whether an actual apply should take place.

  • private JobHandle Update(JobHandle inputDeps)
    Core per-frame logic for updating the raycast result and state transitions:

  • Acquires current raycast result and compares to previous.
  • Updates attribute if in Default state.
  • Switches to Dragging when the mouse has moved beyond a small threshold from the start point.
  • Calls UpdateDefinitions to refresh preview entities.
  • Handles clearing attribute when no longer hitting an entity.

  • private Attribute GetAttribute(ControlPoint controlPoint)
    Determines which attribute of the hit water source the cursor is targeting:

  • If hit is near the center (within ~90% of radius): Location.
  • Otherwise decides between Radius vs (Rate or Height) based on camera orientation and the water source's constant-depth flag.
  • Returns None if no valid WaterSourceData is found.

  • protected override bool GetRaycastResult(out ControlPoint controlPoint)
    Overrides base raycast behavior to support special dragging interactions:

  • When dragging a non-Location attribute, it computes a raycast that intersects a circle (for Radius) or a horizontal plane / depth line (for Rate/Height) to produce intuitive drag hits relative to the start point.
  • Falls back to base.GetRaycastResult otherwise.

  • private JobHandle UpdateDefinitions(JobHandle inputDeps)
    Responsible for removing any previous temporary definition entities and scheduling a CreateDefinitionsJob when the raycast is over a water source entity. It:

  • Calls DestroyDefinitions with m_DefinitionQuery and m_ToolOutputBarrier.
  • If a valid m_RaycastPoint exists, schedules CreateDefinitionsJob supplying:
    • Start and raycast control points
    • state, attribute
    • ComponentLookup for WaterSourceData via __TypeHandle
    • position offset from TerrainSystem
    • a CommandBuffer from ToolOutputBarrier
  • Adds the job handle to the barrier and combines dependencies.

  • private void __AssignQueries(ref SystemState state)
    Compiler helper invoked from OnCreateForCompiler that should set up EntityQueryBuilder instances; in this implementation the method is present but only shows a temporary EntityQueryBuilder created and disposed. Used by the code generation/compilation path.

  • protected override void OnCreateForCompiler()
    Compiler-time initialization: calls base and assigns query handles and __TypeHandle using the SystemState passed from the ECS runtime. This method wires up the component lookups used by jobs.

  • private void __AssignHandles(ref SystemState state) (via TypeHandle)
    Populates the ComponentLookup used by the job. Called from OnCreateForCompiler.

  • public WaterToolSystem()
    Default constructor (preserved).

Nested job details (CreateDefinitionsJob.Execute): - Reads the appropriate entity and positions depending on State (Default uses raycast point, MouseDown uses start point, Dragging uses start-original entity but raycast position). - Attempts to read Game.Simulation.WaterSourceData on the entity; if missing, it returns early. - Creates a new entity and writes a CreationDefinition with Select flag (and Dragging flag when dragging), and a WaterSourceDefinition derived from the source data and current computed values (position, amount, radius, multiplier, polluted). - Adds an Updated tag/component so downstream systems react to the temporary definitions.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // Typical initialization the system performs:
    m_TerrainSystem = base.World.GetOrCreateSystemManaged<TerrainSystem>();
    m_WaterSystem = base.World.GetOrCreateSystemManaged<WaterSystem>();
    m_CameraUpdateSystem = base.World.GetOrCreateSystemManaged<CameraUpdateSystem>();
    m_ToolOutputBarrier = base.World.GetOrCreateSystemManaged<ToolOutputBarrier>();
    m_DefinitionQuery = GetDefinitionQuery();
}

Notes for modders: - The tool schedules a Burst-compiled job (CreateDefinitionsJob) to produce preview entities. Those entities are created via the ToolOutputBarrier (EntityCommandBuffer) — ensure any code consuming those ephemeral definitions is prepared to read them immediately on the main thread or via appropriate job dependencies. - When adding or modifying behavior here, be careful with the ComponentLookup and checked SystemState references: the system uses compiler-generated helpers to safely pass component lookups into jobs. - Attribute detection uses viewer orientation and source radius; camera changes can affect whether Radius or Rate/Height is chosen. If you need a different UX for selecting attributes, adjust GetAttribute and GetRaycastResult together.