Skip to content

LineTool

namespace Griff.Scenes;
public sealed class LineTool : Component

Lets the player lay a line on the grid by dragging, as a factory game’s belt tool does: press on a cell, drag, let go. The line runs from the cell pressed on to the one under the mouse, along one axis and round a corner, each cell pointing the way the line runs; a see-through ghost shows where it goes, GhostColor where it fits and BlockedColor where it can’t. Letting go lays the cells that fit on a Conveyor as belts and on a Tiles map with its LineTiles, and raises Placed, so a script can lay something else (build orders, walls) or charge for it. R (the Rotate action) turns a single cell, or swaps the corner while dragging; a right-click (Command) or untick Controllable drops the line. With Joins, a line dragged from another’s end carries it on, and one dragged into or out of a line’s side merges or splits.

Put it on the camera (or anywhere) and untick Controllable while another tool is in hand: while it’s ticked, a SelectionControls leaves the mouse to it. Where a cell can’t go is up to StayOnMap, BlockedByWalls (solid tiles and colliders, as grid movers see them, but not the belts of its own conveyor, which a line laid over turns), BlockedByMovers, MaxCells (what the money covers, say) and a script’s CanLay. The drag is this machine’s own, and isn’t kept by a rewind; what it lays is the scene’s, like anything else a script changes. In a network game, have a client’s script send the host what Placed gives, as a command.

This is a component: its saved properties are on its component page.

public string? Action { get; set; }

The input action held to drag a line, e.g. “Select” (the left mouse button).

public ConveyorCellKind BeltKind { get; set; }

What it lays on the Conveyor: belts, crossings (walkers step over), splitters or unders (a line passes beneath).

public bool BlockedByMovers { get; set; }

True if a cell with a grid mover in it (a worker standing there), or heading into it, can’t take the line.

public bool BlockedByWalls { get; set; }

True if walls block it, as they do grid movers: solid tiles, solid colliders and other conveyors’ solid belts.

public Color BlockedColor { get; set; }

The ghost’s tint where the line can’t go.

public string? BlockingLayers { get; set; }

Collision layers whose solid colliders block it, e.g. “Machines, Walls”. Empty: any solid collider does.

public Func<LineCell, bool>? CanLay { get; set; }

A script’s say in where the line can go, besides walls and the map: return false for a cell that can’t take it (a storage zone, a machine’s footprint). Null lets every cell the other rules allow.

public string? CancelAction { get; set; }

The input action that drops a line being dragged without laying it, e.g. “Command” (the right mouse button).

public IReadOnlyList<LineCell> Cells { get; }

The ghost’s cells, each saying whether it Fits: the line being dragged, or the single cell under the mouse while it’s in hand. Empty with the mouse off the grid or on the HUD.

public bool Controllable { get; set; }

Untick it while another tool is in hand (or none): it leaves the mouse alone and drops a line being dragged. Its Focus action ticks it and unticks it on everything else the player plays.

public string? Conveyor { get; set; }

A conveyor to lay the line on as belts when it’s let go, turning belts already there. Empty lays no belts.

public bool Corners { get; set; }

True to turn a corner to reach the mouse; untick it for straight lines only, across or up and down, whichever way it’s dragged further (a wall tool).

public LineFirstLeg FirstLeg { get; set; }

Which leg of a line with a corner comes first: the way the drag started (the default), or the way it’s dragged further.

public Color GhostColor { get; set; }

The ghost’s tint where the line fits.

public GridCells Grid { get; }

The cells it lays on (see Map).

public ValueTuple<int, int>? Hover { get; }

The cell under the mouse while it’s in hand, or null.

public bool IsDragging { get; }

True while a line is being dragged.

public bool Joins { get; set; }

True to join a line onto those already laid (its Conveyor‘s belts, else its Tiles’ pieces): dragged from a line’s end it carries that line on (the old end turns to feed it, keeping its kind and speed, and its tile becomes a straight piece or a corner); dragged out of a line’s side it splits off it (that belt becomes a splitter); and ended on a line’s side it merges in (that belt stays as it is, the cell before it pointing in). The ghost shows the join. Unticked, each line is laid on its own, turning the belts it’s laid over.

public string? Map { get; set; }

The tilemap whose cells it lays on. Empty uses its Conveyor’s map, else its Tiles map, else the tilemap on its own entity or the one it’s inside, else the first in the scene; with none, cells are world units centered on whole numbers, as for a grid mover.

public int MaxCells { get; set; }

The most cells a line can have: those past it are blocked (what the money covers, set by a script). 0 for no limit.

public string? Message { get; set; }

A message sent with Game.Send when a line is laid, with how many cells as its data.

public string? RotateAction { get; set; }

The input action that turns a single cell a quarter clockwise, or swaps the corner while dragging, e.g. “Rotate” (R).

public bool StayOnMap { get; set; }

True if cells off the map’s grid can’t take the line.

public string? Tiles { get; set; }

A tilemap with LineTiles to lay the line’s tiles on when it’s let go, straight pieces and corners turned to follow it: a layer for belts, pipes or rails. Empty lays no tiles.

public LineWay Way { get; set; }

Which way a single cell points (a click without dragging). The Rotate action turns it a quarter clockwise.

public void Cancel()

Drops the line being dragged without laying it.

public IReadOnlyList<LineCell> Check(IReadOnlyList<LineCell> line)

line with each cell saying whether it can take the line: on the map, clear of walls and movers as this tool’s settings say, within MaxCells, and allowed by CanLay.

public Conveyor? FindConveyor()

The conveyor it lays belts on (see Conveyor), or null.

public Tilemap? FindMap()

The tilemap whose cells it lays on (see Map), or null for world units.

public LineTiles? FindTiles()

The line tiles it lays (see Tiles), or null.

public IReadOnlyList<LineCell> Join(IReadOnlyList<LineCell> line)

line joined onto the lines already laid, as Joins says (see Join): its Conveyor‘s belts, else its Tiles’ pieces. Without Joins, the line as it is.

public void Lay(IReadOnlyList<LineCell> line)

Lays the cells of line that fit, as letting go does: belts on its Conveyor and tiles on its Tiles map. It doesn’t raise Placed. A joined line (see Join) leaves a cell it merges into, turns one it splits off into a splitter and keeps the kind of the end it carries on.

public IReadOnlyList<LineCell> Line(ValueTuple<int, int> from, ValueTuple<int, int> to, bool acrossFirst = true)

The line from from to to as this tool would lay it (along the row first, or the column with acrossFirst false), each cell saying whether it Fits.

public void Rotate()

Turns the single cell’s Way a quarter clockwise, or while a line is dragged, swaps its corner: what the Rotate action does.

public event Action<LineTool, IReadOnlyList<LineCell>>? Dragging

Raised whenever the line being dragged changes, with its cells (each saying whether it fits).

public event Action<LineTool, IReadOnlyList<LineCell>>? Placed

Raised when a line is let go, after its belts and tiles are laid, with the cells that fit (the ones laid: with Joins, not a belt it merges into, which stays as it is). Not raised when none fit.