Class ManipulationSystem
- Namespace
- GridPlacement.GDScript
- Assembly
- MoonBark.GridPlacement.GDScript.dll
System for manipulating (move, rotate, flip, demolish, build preview integration) grid building objects.\n\nResponsibilities: - Creates and manages a temporary manipulation copy ("move copy") when entering MOVE workflows. - Delegates spatial translation to the external targeting/positioner system. (No per-frame movement logic here.) - Sets up and tears down placement validation rules for move and build actions. - Manages physics layer disabling/enabling during active manipulation. - Emits structured status transitions via ManipulationData.status (STARTED, FAILED, FINISHED, CANCELED).\n\nNon‑Responsibilities (by design): - Calculating or enforcing cursor/keyboard driven position updates (handled by GridTargetingSystem & its positioner node). - Determining selection/target acquisition (handled by targeting state & systems). - Rendering or UI feedback (delegated to name displayer / external UI nodes).\n\nDesign Notes: - The move copy is parented under the active positioner when available so that any positioner movement (mouse, keyboard, gamepad) naturally repositions the copy without duplicate logic or tight coupling. - If no positioner exists (edge/test fallback), the copy is parented under the manipulation parent as a legacy behavior. - Rotation / flip actions operate directly on the target Node2D passed in, typically the move copy's root while an action is active.
class ManipulationSystem extends GBSystem
Properties
system
var system = ManipulationSystem.new()
issues
var issues = setup_report.indicators_report.issues
logger
var logger = container.get_logger()
issues
var issues = setup_report.indicators_report.issues
required_props
var required_props: Array[String] = ["_states", "_manipulation_settings", "_actions", "_indicator_context"]
issues
var issues = setup_report.indicators_report.issues
failed_reason
var failed_reason: String
source
var source: Manipulatable = GBSearchUtils.find_first(p_root, Manipulatable)
move_data
var move_data = _states.manipulation.data
started
Validate all possible reasons for failing
var started: bool = _start_move(move_data)
root
var root: Node = target.root
kept_script_types
var kept_script_types: Array[String] = ["Manipulatable"]
source_rotation
var source_rotation: float = p_data.source.root.rotation
source_scale
var source_scale: Vector2 = p_data.source.root.scale
move_rules
var move_rules: Array[PlacementRule] = []
ignore_base_rules
var ignore_base_rules = p_data.source.settings != null and p_data.source.settings.ignore_base_rules == true
report
var report = _indicator_context.get_manager().try_setup(move_rules, _states.targeting, ignore_base_rules)
indicators
var indicators: Array[RuleCheckIndicator] = _indicator_context.get_manager().get_indicators()
bad_move_results
var bad_move_results = ValidationResults.new(false, "[p_move] is not valid. Cannot move object.", {})
target_root
var target_root = p_move.target.root
move_rules
var move_rules: Array[PlacementRule] = []
ignore_base
var ignore_base: bool = false
validation_results
var validation_results: ValidationResults
setup_report
var setup_report: PlacementReport = _indicator_context.get_manager().try_setup(
issues
var issues = setup_report.indicators_report.issues
vr
var vr = ValidationResults.new(
old_transform
var old_transform: Transform2D = p_move.source.root.global_transform
manipulation_parent
var manipulation_parent: ManipulationParent = _states.manipulation.parent
final_position
var final_position: Vector2 = target_root.global_position
accumulated_rotation
var accumulated_rotation: float = manipulation_parent.rotation
accumulated_scale
var accumulated_scale: Vector2 = manipulation_parent.scale
root_node
var root_node: Node = p_move.source.root
body
var body = root_node as RigidBody2D
node2d
var node2d = root_node as Node2D
applied_position
var applied_position: Vector2 = (root_node as Node2D).global_position if root_node is Node2D else final_position
passing
var passing = true
data
var data: ManipulationData = _states.manipulation.data
target
var target: Manipulatable = p_manipulatable if p_manipulatable != null else _states.manipulation.active_manipulatable
demolish_data
var demolish_data = try_demolish(p_manipulatable)
root
var root: Node = target.root
display_name
var display_name: String = _get_demolish_display_name(target)
demolish_data
var demolish_data = try_demolish(p_manipulatable)
tree
var tree = get_tree()
tree
var tree = get_tree()
manipulation_parent
var manipulation_parent: ManipulationParent = _states.manipulation.parent
manipulation_parent
var manipulation_parent: ManipulationParent = _states.manipulation.parent
manipulation_parent
var manipulation_parent: ManipulationParent = _states.manipulation.parent
active_data
var active_data = _states.manipulation.data
move_data
var move_data = _states.manipulation.data
manipulatable
var manipulatable = GBSearchUtils.find_first(p_preview, Manipulatable)
area2d
var area2d = p_new if p_new is Area2D else null
has_targetable
var has_targetable: bool = area2d.get_collision_layer_value(12)
manipulatable
var manipulatable = GBSearchUtils.find_first(p_preview, Manipulatable)
failed
var failed = ManipulationData.new(_states.manipulation.get_manipulator(), _states.manipulation.data.source, p_manipulated, p_action)
physics_objects
var physics_objects = GBSearchUtils.get_collision_object_2ds(p_container)
node
var node: Node = p_manipulatable.root if p_manipulatable.root != null else p_manipulatable
bits
var bits: Array[int] = []
Methods
create_with_injection
static func create_with_injection(p_parent: Node, container: PlacementContainer) -> ManipulationSystem:
Parameters
p_parentcontainer
Returns
get_runtime_issues
func get_runtime_issues() -> Array[String]:
Returns
resolve_gb_dependencies
func resolve_gb_dependencies(p_container: PlacementContainer) -> void:
Parameters
p_container
Returns
try_move
func try_move(p_root: Node) -> ManipulationData:
Parameters
p_root
Returns
try_placement
func try_placement(p_move: ManipulationData) -> ValidationResults:
Parameters
p_move
Returns
is_ready
func is_ready() -> bool:
Returns
cancel
func cancel() -> void:
Returns
try_demolish
func try_demolish(p_manipulatable: Manipulatable) -> ManipulationData:
Parameters
p_manipulatable
Returns
demolish
func demolish(p_manipulatable: Manipulatable) -> bool:
Parameters
p_manipulatable
Returns
rotate
func rotate(p_target: Node, degrees: float) -> bool:
Parameters
p_targetdegrees
Returns
flip_horizontal
func flip_horizontal(p_target: Node) -> bool:
Parameters
p_target
Returns
flip_vertical
func flip_vertical(p_target: Node) -> bool:
Parameters
p_target
Returns
get_targeted
func get_targeted() -> Node:
Returns
set_targeted
func set_targeted(p_obj_root: Node) -> void:
Parameters
p_obj_root
Returns
Events
move_indicators_ready
Emitted when move indicators have been fully set up after physics frame Passes the array of created indicators for debugging and validation
signal move_indicators_ready(indicators: Array[RuleCheckIndicator])