Table of Contents

Class GridPositioner2D

Namespace
GridPlacement.GDScript
Assembly
MoonBark.GridPlacement.GDScript.dll

Controls the on-grid cursor used by building/interaction systems.\n\nResponsibilities: - Recenter according to GridTargetingSettings policy when input/mode is enabled - Follow mouse/keyboard input to update on-grid position - STRICTLY for tile center targeting - does NOT handle rotation or manipulation\n\nTargeting separation: Target acquisition/collision detection is handled by dedicated components (e.g., TargetingShapeCast2D). GridPositioner2D no longer depends on or manages any shapecast component.\n\nManipulation separation: Object rotation, flipping, and manipulation are handled by ManipulationParent. GridPositioner2D focuses solely on positioning the targeting cursor at tile centers.\n\nDependency Injection: resolve_placement_dependencies(container) is the standard method called by PlacementInjectorSystem to inject dependencies. This is the primary integration pattern for runtime use. set_dependencies(...) is an internal helper for testing and advanced use cases.

class GridPositioner2D extends Node2D
GridPositioner2D

Fields

LOG_PREFIX

const LOG_PREFIX: String = "[GridPositioner2D]"

Properties

cursor_source

Injected cursor-source callable. Returns a [Vector2] screen position. If the callable returns [code]null[/code], or if [member cursor_source] is not set, falls back to the real viewport mouse position. Tests inject a callable that returns a fixed Vector2 for deterministic positioning. Usage in tests: positioner.cursor_source = func(): return Vector2(100, 100)

var cursor_source: Callable

input_processing_enabled

Public flag & API for enabling/disabling input processing (used by tests)

var input_processing_enabled: bool = false

expected_vis

var expected_vis = should_be_visible()

mode_now

var mode_now: PlacementEnums.Mode = _mode_state.current if _mode_state else PlacementEnums.Mode.OFF

reconcile

var reconcile = _positioner_policy.visibility_reconcile(mode_now, visible, _last_mouse_input_status, _has_mouse_world)

tick_res

var tick_res: MouseEventVisibilityResult = _positioner_policy.visibility_on_process_tick(

was_enabled

var was_enabled = input_processing_enabled

motion

var motion: InputEventMouseMotion = event

current_mode

var current_mode: PlacementEnums.Mode = _mode_state.current if _mode_state else PlacementEnums.Mode.OFF

key_event

var key_event = event as InputEventKey

tile_change

var tile_change: Vector2i = PositionerPolicy.get_tile_delta_from_key_event(key_event, _actions)

input_allowed

var input_allowed: bool = _mouse_input_gate()

vis_result

var vis_result: MouseEventVisibilityResult = _positioner_policy.visibility_on_mouse_event(current_mode, input_allowed)

world_pos

var world_pos: Vector2 = _convert_screen_to_world(screen_pos)

target_tile

var target_tile: Vector2i = GBPositioning2DUtils.get_tile_from_global_position(world_position, _targeting_state.target_map)

viewport

var viewport: Viewport = _targeting_state.target_map.get_viewport()

map

var map: TileMapLayer = _targeting_state.target_map

cached_tile

var cached_tile: Vector2i = GBPositioning2DUtils.get_tile_from_global_position(_last_mouse_world, map)

vp

var vp = _get_active_viewport()

mouse_screen_pos

var mouse_screen_pos = _get_cursor_screen_position(vp)

vp_rect

var vp_rect = vp.get_visible_rect()

result

var result = cursor_source.call()

mouse_allowed

var mouse_allowed: bool = _targeting_settings.enable_mouse_input if _targeting_settings != null else false

disabled_in_off_mode

var disabled_in_off_mode = _is_disabled_in_off_mode()

viewport_available

var viewport_available = _get_active_viewport() != null

decision

var decision = _positioner_policy.recenter_on_enable_decision(

input_ready

var input_ready = is_input_ready()

mouse_global

var mouse_global: Vector2

vp

var vp = _get_active_viewport()

screen_pos

var screen_pos = _get_cursor_screen_position(vp)

target_tile

var target_tile: Vector2i = GBPositioning2DUtils.get_tile_from_global_position(world_position, _targeting_state.target_map)

map

var map: TileMapLayer = _targeting_state.target_map

current_tile

var current_tile: Vector2i = GBPositioning2DUtils.get_tile_from_global_position(global_position, map)

target_tile

var target_tile: Vector2i = GBPositioning2DUtils.get_tile_from_global_position(world_position, _targeting_state.target_map)

vp

var vp = _get_active_viewport()

result_tile

var result_tile: Vector2i = GBPositioning2DUtils.move_to_tile_center(self, target_tile, _targeting_state.target_map)

fallback_tile

var fallback_tile = Vector2i.ZERO

result_tile

var result_tile: Vector2i = GBPositioning2DUtils.move_to_tile_center(self, target_tile, _targeting_state.target_map)

world_position

var world_position: Vector2

vp

var vp = _get_active_viewport()

screen_pos

var screen_pos = _get_cursor_screen_position(vp)

target_tile

var target_tile: Vector2i = GBPositioning2DUtils.get_tile_from_global_position(world_position, _targeting_state.target_map)

result_tile

var result_tile: Vector2i = GBPositioning2DUtils.move_to_tile_center(self, target_tile, _targeting_state.target_map)

mode

var mode = _targeting_settings.manual_recenter_mode if _targeting_settings != null else PlacementEnums.CenteringMode.CENTER_ON_SCREEN

was_input_enabled

var was_input_enabled = input_processing_enabled

issues

var issues = get_runtime_issues()

issues

var issues = get_runtime_issues()

old_self

var old_self: bool = visible

visual

var visual = get_visual_node()

had_visual

var had_visual: bool = visual != null and visual is CanvasItem

old_visual_visible_str

var old_visual_visible_str: String = "n/a"

stack

var stack = get_stack()

stack_summary

var stack_summary = PlacementDiagnostics.format_stack_summary(stack, 6)

trace

var trace = _visibility_decision_trace()

last_mouse

var last_mouse = _last_mouse_input_status

mouse_info

var mouse_info = "<n/a>"

has_mouse

var has_mouse = str(_has_mouse_world)

ctx

var ctx = _visibility_context(visual if visual and visual is CanvasItem else null)

new_visual_visible_str

var new_visual_visible_str: String = "n/a"

visual

var visual = get_visual_node()

visual

var visual = get_visual_node()

ctx

var ctx = _visibility_context(visual if visual and visual is CanvasItem else null)

state

var state = "visible=%s" % str(visible)

vp

var vp = _get_active_viewport()

cam

var cam = _get_active_camera(vp)

map_ref

var map_ref: Variant = null

msg

var msg = PlacementDiagnostics.format_screen_state(cam, vp, global_position, _has_mouse_world, _last_mouse_world, map_ref)

vp

var vp = _get_active_viewport()

cam

var cam = _get_active_camera(vp)

dependencies_resolved

var dependencies_resolved = are_dependencies_resolved()

has_mode_state

var has_mode_state = _mode_state != null

has_targeting_settings

var has_targeting_settings = _targeting_settings != null

has_targeting_state

var has_targeting_state = _targeting_state != null

has_logger

var has_logger = _logger != null

input_ready

var input_ready = is_input_ready()

mode_label

var mode_label = "<no_mode_state>"

mouse_input_enabled

var mouse_input_enabled = false

keyboard_input_enabled

var keyboard_input_enabled = false

restrict_to_map_area

var restrict_to_map_area = false

limit_to_adjacent

var limit_to_adjacent = false

active_viewport

var active_viewport: Viewport = null

active_camera

var active_camera: Camera2D = null

target_map

var target_map = _targeting_state.target_map

is_camera_current

var is_camera_current = false

camera_zoom

var camera_zoom = Vector2.ONE

camera_position

var camera_position = Vector2.ZERO

visual_node

var visual_node = get_visual_node()

visual_label

var visual_label = "<none>"

visual_visible

var visual_visible = "<n/a>"

descriptor_parts

var descriptor_parts: Array[String] = []

descriptor_text

var descriptor_text = ", ".join(PackedStringArray(descriptor_parts))

formatted

var formatted = PlacementDiagnostics.format_debug("%s %s" % [LOG_PREFIX, p_message], "GridPositioner2D", get_script().resource_path)

world_pos

var world_pos: Vector2 = _convert_screen_to_world(screen_pos)

tile_coord

var tile_coord: Vector2i = GBPositioning2DUtils.get_tile_from_global_position(world_pos, _targeting_state.target_map)

map

var map: TileMapLayer = _targeting_state.target_map

tile_local

var tile_local: Vector2 = map.map_to_local(tile_coord)

tile_size

var tile_size: Vector2 = map.tile_set.tile_size

tile_center_local

var tile_center_local: Vector2 = tile_local + tile_size * 0.5

tile_center

var tile_center: Vector2 = map.to_global(tile_center_local)

Methods

set_targeting_state

func set_targeting_state(p_targeting_state: GridTargetingState) -> void:

Parameters

p_targeting_state

Returns

set_input_processing_enabled

func set_input_processing_enabled(p_enabled: bool) -> void:

Parameters

p_enabled

Returns

is_input_processing_enabled

func is_input_processing_enabled() -> bool:

Returns

is_input_ready

func is_input_ready() -> bool:

Returns

are_dependencies_ready

func are_dependencies_ready() -> bool:

Returns

resolve_placement_dependencies

func resolve_placement_dependencies(p_config : PlacementContainer) -> void:

Parameters

p_config

Returns

move_to_viewport_center_tile

func move_to_viewport_center_tile() -> Vector2i:

Returns

move_to_cursor_center_tile

func move_to_cursor_center_tile() -> Vector2i:

Returns

get_last_manual_recenter_mode

func get_last_manual_recenter_mode() -> int:

Returns

remove_self_as_positioner

func remove_self_as_positioner():

update_visibility

func update_visibility() -> void:

Returns

should_be_visible

func should_be_visible() -> bool:

Returns

set_dependencies

func set_dependencies(p_states : PlacementStates, p_config : PlacementConfig, p_logger: PlacementLogger = null, p_actions: PlacementActions = null, enable_input: bool = true) -> void:

Parameters

p_states
p_config
p_logger
p_actions
enable_input

Returns

get_runtime_issues

func get_runtime_issues() -> Array[String]:

Returns

validate_dependencies

func validate_dependencies() -> bool:

Returns

get_visual_node

func get_visual_node() -> Node:

Returns

is_visual_visible

func is_visual_visible() -> bool:

Returns

log_current_visual_state

func log_current_visual_state():

is_positioner_active

func is_positioner_active() -> bool:

Returns

should_hide_under_handled_ui

func should_hide_under_handled_ui() -> bool:

Returns

are_dependencies_resolved

func are_dependencies_resolved() -> bool:

Returns

to_diagnostic_string

func to_diagnostic_string() -> String:

Returns