Skip to content

Game.UpgradeToolSystem

Assembly:
Namespace: Game.Tools

Type: class

Base: ObjectToolBaseSystem

Summary:
UpgradeToolSystem implements the in-game "Upgrade Tool" used to apply building/object upgrades (ServiceUpgrade prefabs) to existing placeable objects. It integrates with the ECS prefab/system infrastructure, handles user input actions (Place Upgrade / Rebuild), manages temporary visual definitions for preview, audio feedback, and telemetry for placement. The system also respects editor vs game modes and validates whether the selected object can accept upgrades before allowing placement.


Fields

  • public const string kToolID = "Upgrade Tool"
    Identifier constant for the tool.

  • private CityConfigurationSystem m_CityConfigurationSystem
    Reference to the CityConfigurationSystem used for theme, traffic handedness and other city-level configuration used when creating visual definitions.

  • private AudioManager m_AudioManager
    Reference to the AudioManager, used to play UI sounds for successful/failing placement.

  • private EntityQuery m_DefinitionQuery
    ECS EntityQuery used to find existing temporary/preview definitions that this tool creates and should destroy/recreate.

  • private EntityQuery m_SoundQuery
    ECS EntityQuery used to fetch tool UX sound settings (ToolUXSoundSettingsData) for UI sounds played by the tool.

  • private EntityQuery m_ContainerQuery
    EntityQuery used when in editor mode to obtain container entities (lane containers etc.) that may be needed when computing definitions.

  • private Entity m_UpgradingObject
    Entity currently selected for upgrade (the object being upgraded). Null if no valid selected object.

  • private NativeList<ControlPoint> m_ControlPoints
    NativeList (persistent allocator) holding one or more control points used by CreateDefinitions to compute preview geometry/placement. The list is created on OnCreate and disposed on OnDestroy.

  • private RandomSeed m_RandomSeed
    RandomSeed used to add deterministic variation to created definitions/previews.

  • private bool m_AlreadyCreated
    Flag tracking whether the temporary preview definitions have already been created for the current selection/state (avoids recreating each frame).

  • private ObjectPrefab m_Prefab
    Currently selected upgrade prefab (ObjectPrefab). When set this is used to create temporary preview definitions and to perform the actual upgrade placement.

  • private IProxyAction m_PlaceUpgrade
    Proxy action bound to the "Place Upgrade" input action (obtained from InputManager). Used as the primary apply action when an upgrade prefab is selected.

  • private IProxyAction m_Rebuild
    Proxy action bound to the "Rebuild" input action. Used as the apply action when no upgrade prefab is selected (rebuild mode).

  • private TypeHandle __TypeHandle
    Compiler-generated struct that holds ComponentLookup handles (currently PlaceableObjectData read-only). Used by TrySetPrefab to check for certain components on prefab entities.

Properties

  • public override string toolID => "Upgrade Tool"
    Tool identifier exposed by the system. Matches kToolID constant.

  • public ObjectPrefab prefab { get; set; }
    Getter/Setter for the selected upgrade prefab. Setting a different prefab sets m_ForceUpdate = true to force recreation of previews. The setter stores the ObjectPrefab in m_Prefab.

  • private protected override IEnumerable<IProxyAction> toolActions
    Enumerates the actions exposed by this tool: yields m_PlaceUpgrade first then m_Rebuild. These actions are used by the base tool UI and input handling.

Constructors

  • public UpgradeToolSystem()
    Default constructor (compiler generated). Primary initialization occurs in OnCreate.

Methods

  • [Preserve] protected override void OnCreate()
    Initializes system references (CityConfigurationSystem, AudioManager), queries (definition/container/sound), obtains input actions from InputManager, and creates the native list (m_ControlPoints) with Allocator.Persistent. Called once when the system is created.

  • [Preserve] protected override void OnDestroy()
    Disposes m_ControlPoints and calls base.OnDestroy. Ensures native memory is released.

  • [Preserve] protected override void OnStartRunning()
    Called when the system starts running: clears m_ControlPoints, seeds m_RandomSeed, clears m_AlreadyCreated flag, and sets requirements (requireZones, requireAreas) used by the base tool behavior. Prepares tool for use.

  • private protected override void UpdateActions()
    Updates the tool's current apply/cancel action bindings depending on whether an upgrade prefab is selected. If prefab != null, applyAction override is set to PlaceUpgrade; otherwise to Rebuild. Also enables/disables actions based on GetAllowApply and base.actionsEnabled. Uses ProxyAction.DeferStateUpdating() to batch state changes.

  • public override PrefabBase GetPrefab()
    Returns the currently set prefab (m_Prefab) as PrefabBase.

  • public override bool TrySetPrefab(PrefabBase prefab)
    Attempts to set the tool's prefab. Only succeeds if:

  • The tool is not in the editor-restricted path (checks m_ToolSystem.actionMode.IsEditor()),
  • The provided PrefabBase is an ObjectPrefab and has a ServiceUpgrade component,
  • The target prefab entity does not contain PlaceableObjectData after dependency completion (checked via InternalCompilerInterface and __TypeHandle). On success sets this.prefab and returns true; otherwise returns false.

  • public override void InitializeRaycast()
    Overrides raycast initialization; currently calls base.InitializeRaycast (kept for potential future customization).

  • [Preserve] protected override JobHandle OnUpdate(JobHandle inputDeps)
    Main per-frame update. Key responsibilities:

  • Tracks the selected entity (m_UpgradingObject) and validates it (has InstalledUpgrade buffer when prefab != null; not destroyed when prefab == null).
  • If selected prefab has BuildingExtensionData with underground elements it requires additional net layer (Layer.Road).
  • Updates infoview depending on prefab presence.
  • Computes snap masks via GetAvailableSnapMask and updates actions.
  • If a valid m_UpgradingObject exists and no full update is required, responds to input:
    • cancelAction -> Cancel()
    • applyAction -> Apply()
    • otherwise -> Update() to create/update preview
  • If not valid, calls Clear().

  • private JobHandle Cancel(JobHandle inputDeps)
    Cancels the tool action: switches the active tool back to default, sets applyMode to Clear, clears m_AlreadyCreated. Returns the inputDeps unchanged (no job scheduling).

  • private JobHandle Apply(JobHandle inputDeps)
    Handles applying the upgrade or rebuild:

  • If GetAllowApply() true: sets active tool to default, applyMode = Apply, reseeds m_RandomSeed, clears m_AlreadyCreated, plays place-upgrade sound, and if in game mode records telemetry (Telemtry.PlaceBuilding) with prefab and target position. Returns inputDeps.
  • If not allowed: plays place-fail sound and falls back to Update() to keep previews.

  • private JobHandle Update(JobHandle inputDeps)
    Creates or updates temporary preview definitions for the currently selected object:

  • If there is no selected object, sets applyMode.Clear and clears m_AlreadyCreated.
  • If previews already created and no force update requested, does nothing (applyMode.None).
  • Otherwise sets applyMode.Clear, marks m_AlreadyCreated true, and calls CreateTempObject to build control points and schedule definition creation.

  • private JobHandle Clear(JobHandle inputDeps)
    Clears preview state (applyMode.Clear and m_AlreadyCreated = false). Returns inputDeps.

  • private JobHandle CreateTempObject(JobHandle inputDeps)
    Builds a ControlPoint from the selected object's Game.Objects.Transform (position + rotation). If the chosen prefab has BuildingExtensionData with a placement offset it transforms the local offset into world space and uses that as the control point position. Clears and populates m_ControlPoints and calls UpdateDefinitions to schedule create/destroy definition jobs.

  • private JobHandle UpdateDefinitions(JobHandle inputDeps)
    Schedules destruction of existing temporary definitions (DestroyDefinitions) and, if m_UpgradingObject != Entity.Null, schedules CreateDefinitions with the appropriate parameters:

  • objectPrefab: entity of selected upgrade prefab (or Entity.Null)
  • lane container determined only in editor mode
  • uses city theme from m_CityConfigurationSystem and other tool state (brushSize, brushAngle, brushStrength, stamping, removing)
  • passes m_ControlPoints, m_RandomSeed, snap settings and AgeMask.Sapling Returns a combined JobHandle representing scheduled work.

  • [MethodImpl(MethodImplOptions.AggressiveInlining)] private void __AssignQueries(ref SystemState state)
    Compiler-generated helper; here it creates and disposes a temporary EntityQueryBuilder. Used by OnCreateForCompiler; no runtime behavior beyond query assignment scaffolding.

  • protected override void OnCreateForCompiler()
    Compiler helper called when the system is created by generated code. Calls __AssignQueries and __TypeHandle.__AssignHandles to ensure required lookups are assigned.

  • [Preserve] public UpgradeToolSystem()
    Public constructor (kept for clarity, actual initialization via OnCreate).

Usage Example

// Example: Setting an upgrade prefab for the tool and forcing an update
[Preserve]
protected override void OnCreate()
{
    base.OnCreate();

    // Obtain a prefab (example: by name, via the prefab system)
    var prefabBase = m_PrefabSystem.GetPrefab("MyServiceUpgradePrefab");
    if (prefabBase is ObjectPrefab objectPrefab && TrySetPrefab(objectPrefab))
    {
        // Prefab is valid and accepted by the tool.
        // The tool will now show preview definitions over the selected object
        // and allow applying the upgrade with the configured input action.
    }
}

Notes and tips for modders: - TrySetPrefab enforces that prefabs are ServiceUpgrade object prefabs and performs internal checks (e.g., for PlaceableObjectData). Use TrySetPrefab rather than directly assigning prefab when integrating with existing tool logic. - The system creates temporary preview definitions via CreateDefinitions/DestroyDefinitions. Those are scheduled as jobs—be mindful of job dependencies when integrating additional logic. - Remember to call base.OnCreate/base.OnDestroy if overriding those lifecycle methods to preserve proper resource creation/disposal (m_ControlPoints is allocated with Allocator.Persistent). - Audio cues are played from ToolUXSoundSettingsData (queried via m_SoundQuery) — you can customize sounds by modifying that singleton data.