Functional plugin
This commit is contained in:
@ -28,7 +28,7 @@ var save_button: Button
|
||||
var builder_scene_root: Node2D
|
||||
var builder_camera: Camera2D
|
||||
|
||||
# --- NEW: State Management Enum ---
|
||||
# --- State Management Enum ---
|
||||
enum BuilderState {
|
||||
IDLE,
|
||||
PLACING_STRUCTURAL,
|
||||
@ -45,6 +45,8 @@ var grid_size: float = 50.0
|
||||
|
||||
var undo_redo: EditorUndoRedoManager
|
||||
|
||||
# --- Most of the setup functions remain the same ---
|
||||
|
||||
func _enter_tree():
|
||||
main_screen = MAIN_EDITOR_SCENE.instantiate()
|
||||
EditorInterface.get_editor_main_screen().add_child(main_screen)
|
||||
@ -179,7 +181,6 @@ func _on_viewport_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseMotion:
|
||||
_update_preview_position()
|
||||
|
||||
# --- REFACTORED: Use match statement for state-based input handling ---
|
||||
match current_state:
|
||||
BuilderState.IDLE:
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT and event.is_pressed():
|
||||
@ -198,7 +199,6 @@ func _on_viewport_input(event: InputEvent) -> void:
|
||||
on_clear_preview()
|
||||
|
||||
BuilderState.WIRING:
|
||||
# Placeholder for future wiring logic
|
||||
pass
|
||||
|
||||
|
||||
@ -227,8 +227,6 @@ func _on_component_selected(component_scene: PackedScene):
|
||||
current_state = BuilderState.PLACING_COMPONENT
|
||||
active_scene = component_scene
|
||||
preview_node = component_scene.instantiate() as Component
|
||||
# You might want a specific material or modulation for component previews
|
||||
# preview_node.modulate = Color(0.5, 1.0, 0.5, 0.5)
|
||||
builder_scene_root.add_child(preview_node)
|
||||
|
||||
print("Now placing component: ", component_scene.resource_path)
|
||||
@ -256,20 +254,18 @@ func _update_preview_position():
|
||||
preview_node.global_position = snapped_pos
|
||||
preview_node.rotation = rotation_angle
|
||||
BuilderState.PLACING_COMPONENT:
|
||||
# For components, we snap to the closest attachment point
|
||||
var target_module = _find_first_module()
|
||||
if target_module:
|
||||
var closest_point = _find_closest_attachment_point(target_module, world_mouse_pos)
|
||||
if closest_point:
|
||||
preview_node.global_position = closest_point.position
|
||||
# You might want to handle rotation differently for components
|
||||
# preview_node.rotation = closest_point.rotation
|
||||
else:
|
||||
preview_node.global_position = world_mouse_pos # Or hide it
|
||||
preview_node.global_position = world_mouse_pos
|
||||
else:
|
||||
preview_node.global_position = world_mouse_pos # Or hide it
|
||||
preview_node.global_position = world_mouse_pos
|
||||
|
||||
|
||||
# --- REFACTORED: Piece Placement ---
|
||||
func _place_piece_from_preview():
|
||||
if not is_instance_valid(preview_node) or not is_instance_valid(active_scene):
|
||||
return
|
||||
@ -288,19 +284,22 @@ func _place_piece_from_preview():
|
||||
target_module.owner = builder_scene_root
|
||||
|
||||
var piece_to_place = active_scene.instantiate()
|
||||
target_module.structural_container.add_child(piece_to_place)
|
||||
|
||||
# --- The main change: Add as a direct child of the module ---
|
||||
target_module.add_child(piece_to_place)
|
||||
piece_to_place.owner = target_module
|
||||
piece_to_place.rotation = rotation_angle
|
||||
piece_to_place.global_position = snapped_pos
|
||||
|
||||
undo_redo.create_action("Place Structural Piece")
|
||||
undo_redo.add_do_method(target_module.structural_container, "add_child", piece_to_place)
|
||||
undo_redo.add_do_method(target_module, "add_child", piece_to_place)
|
||||
undo_redo.add_do_method(piece_to_place, "set_owner", target_module)
|
||||
undo_redo.add_do_method(target_module, "_recalculate_collision_shape")
|
||||
undo_redo.add_undo_method(target_module.structural_container, "remove_child", piece_to_place)
|
||||
undo_redo.add_undo_method(target_module, "remove_child", piece_to_place)
|
||||
undo_redo.add_undo_method(target_module, "_recalculate_collision_shape")
|
||||
undo_redo.commit_action()
|
||||
|
||||
# --- Component Placement remains the same ---
|
||||
func _place_component_from_preview():
|
||||
if not is_instance_valid(preview_node) or not is_instance_valid(active_scene):
|
||||
push_error("Cannot place component: Invalid preview or scene.")
|
||||
@ -334,6 +333,7 @@ func _place_component_from_preview():
|
||||
|
||||
preview_node.global_position = closest_point.position
|
||||
|
||||
# --- Find Nearby Modules remains the same ---
|
||||
func _find_nearby_modules(position: Vector2) -> Module:
|
||||
const OVERLAP_MARGIN = 20.0
|
||||
|
||||
@ -367,8 +367,9 @@ func _find_nearby_modules(position: Vector2) -> Module:
|
||||
if not result.is_empty():
|
||||
var collider = result[0].get("collider")
|
||||
if collider is StructuralPiece:
|
||||
if collider.get_parent() and collider.get_parent().get_parent() is Module:
|
||||
return collider.get_parent().get_parent()
|
||||
# --- REFACTORED: The module is now the direct parent/owner ---
|
||||
if is_instance_valid(collider.owner) and collider.owner is Module:
|
||||
return collider.owner
|
||||
|
||||
return null
|
||||
|
||||
@ -383,7 +384,6 @@ func _remove_piece_under_mouse():
|
||||
if not viewport: return
|
||||
var world_mouse_pos = viewport.get_canvas_transform().affine_inverse() * viewport.get_mouse_position()
|
||||
|
||||
# Point query to find what's under the mouse
|
||||
var space_state = builder_world.direct_space_state
|
||||
var query = PhysicsPointQueryParameters2D.new()
|
||||
query.position = world_mouse_pos
|
||||
@ -394,33 +394,35 @@ func _remove_piece_under_mouse():
|
||||
if collider is StructuralPiece:
|
||||
_remove_piece_with_undo_redo(collider)
|
||||
elif collider is Component:
|
||||
# Add logic to remove components here
|
||||
pass
|
||||
|
||||
|
||||
# --- REFACTORED: Piece Removal ---
|
||||
func _remove_piece_with_undo_redo(piece: StructuralPiece):
|
||||
var module = piece.owner as Module
|
||||
var parent = piece.get_parent()
|
||||
if not is_instance_valid(module) or not module is Module:
|
||||
return
|
||||
|
||||
undo_redo.create_action("Remove Structural Piece")
|
||||
|
||||
if module.structural_container.get_child_count(false) == 1 and module.get_child_count() > 2 : # Structural and HullVolume containers
|
||||
# If it's the last piece, remove the whole module
|
||||
# If this is the last structural piece of the module...
|
||||
if module.get_structural_pieces().size() == 1:
|
||||
# ...remove the entire module.
|
||||
undo_redo.add_do_method(builder_scene_root, "remove_child", module)
|
||||
undo_redo.add_undo_method(builder_scene_root, "add_child", module)
|
||||
undo_redo.add_undo_method(module, "set_owner", builder_scene_root)
|
||||
else:
|
||||
# Otherwise, just remove the piece
|
||||
undo_redo.add_do_method(parent, "remove_child", piece)
|
||||
# Otherwise, just remove the single piece from its parent (the module).
|
||||
undo_redo.add_do_method(module, "remove_child", piece)
|
||||
undo_redo.add_do_method(module, "_recalculate_collision_shape")
|
||||
|
||||
undo_redo.add_undo_method(parent, "add_child", piece)
|
||||
undo_redo.add_undo_method(module, "add_child", piece)
|
||||
undo_redo.add_undo_method(piece, "set_owner", module) # Re-assign owner on undo
|
||||
undo_redo.add_undo_method(module, "_recalculate_collision_shape")
|
||||
|
||||
undo_redo.commit_action()
|
||||
|
||||
# --- Toolbar Button Functions ---
|
||||
# --- Toolbar Button Functions (No changes needed) ---
|
||||
func _on_rotate_button_pressed():
|
||||
rotation_angle = wrapf(rotation_angle + PI / 2, 0, TAU)
|
||||
if is_instance_valid(preview_node):
|
||||
@ -480,7 +482,8 @@ func _perform_save(file_path: String, module_to_save: Module):
|
||||
|
||||
func _on_undo_redo_action_committed():
|
||||
_refresh_tree_display()
|
||||
|
||||
|
||||
# --- REFACTORED: Tree Display ---
|
||||
func _refresh_tree_display():
|
||||
if not is_instance_valid(tree_control):
|
||||
return
|
||||
@ -489,25 +492,23 @@ func _refresh_tree_display():
|
||||
var root_item = tree_control.create_item()
|
||||
root_item.set_text(0, builder_scene_root.name)
|
||||
|
||||
# Iterate through all modules and populate the tree.
|
||||
for module in builder_scene_root.get_children():
|
||||
if module is Module:
|
||||
print(module)
|
||||
var module_item = tree_control.create_item(root_item)
|
||||
module_item.set_text(0, module.name)
|
||||
module_item.set_meta("node", module)
|
||||
|
||||
for piece in module.structural_container.get_children():
|
||||
if piece is StructuralPiece:
|
||||
var piece_item = tree_control.create_item(module_item)
|
||||
piece_item.set_text(0, piece.name)
|
||||
piece_item.set_meta("node", piece)
|
||||
|
||||
# Also show components in the tree
|
||||
for component in module.get_children():
|
||||
if component is Component:
|
||||
var component_item = tree_control.create_item(module_item)
|
||||
component_item.set_text(0, component.name)
|
||||
component_item.set_meta("node", component)
|
||||
# Use the module's helper functions to find children
|
||||
for piece in module.get_structural_pieces():
|
||||
var piece_item = tree_control.create_item(module_item)
|
||||
piece_item.set_text(0, piece.name)
|
||||
piece_item.set_meta("node", piece)
|
||||
|
||||
for component in module.get_components():
|
||||
var component_item = tree_control.create_item(module_item)
|
||||
component_item.set_text(0, component.name)
|
||||
component_item.set_meta("node", component)
|
||||
|
||||
|
||||
func _find_closest_attachment_point(module: Module, world_pos: Vector2):
|
||||
|
||||
Reference in New Issue
Block a user