extends RoomState const wall_corner_scene = preload("../wall_corner.tscn") const wall_edge_scene = preload("../wall_edge.tscn") const RoomState = preload("./room_state.gd") var moving = null var deleting: bool = false var floor_corner: StaticBody3D = null var height_corner: StaticBody3D = null var height_edge: StaticBody3D = null func _on_enter(): var room_store = Store.house.get_room(room.name) if room_store == null: return var corners = room_store.corners if corners.size() > 0: add_floor_corner(room.to_local(Vector3(corners[0].x, 0, corners[0].y))) add_height_corner(room.to_local(Vector3(corners[0].x, 0, corners[0].y))) room.room_ceiling.position.y = room_store.height height_edge.align_to_corners(floor_corner.position, floor_corner.position + Vector3.UP * room.room_ceiling.position.y) for i in range(1, corners.size()): add_corner(room.to_local(Vector3(corners[i].x, 0, corners[i].y))) room.room_ceiling.get_node("CollisionShape3D").disabled = (floor_corner == null && height_corner == null) room.room_floor.get_node("CollisionShape3D").disabled = false var ceiling_shape = WorldBoundaryShape3D.new() ceiling_shape.plane = Plane(Vector3.DOWN, 0) room.room_ceiling.get_node("CollisionShape3D").shape = ceiling_shape room.room_floor.get_node("CollisionShape3D").shape = WorldBoundaryShape3D.new() room.room_ceiling.get_node("Clickable").on_click.connect(_on_click_ceiling) room.room_floor.get_node("Clickable").on_click.connect(_on_click_floor) func _on_leave(): update_store() for child in room.wall_corners.get_children(): child.queue_free() await child.tree_exited for child in room.wall_edges.get_children(): child.queue_free() await child.tree_exited if floor_corner != null: floor_corner.queue_free() await floor_corner.tree_exited height_edge.queue_free() await height_edge.tree_exited room.room_ceiling.get_node("CollisionShape3D").disabled = true room.room_floor.get_node("CollisionShape3D").disabled = true room.room_ceiling.get_node("Clickable").on_click.disconnect(_on_click_ceiling) room.room_floor.get_node("Clickable").on_click.disconnect(_on_click_floor) func get_corner(index: int) -> MeshInstance3D: return room.wall_corners.get_child(index % room.wall_corners.get_child_count()) func get_edge(index: int) -> MeshInstance3D: return room.wall_edges.get_child(index % room.wall_edges.get_child_count()) func remove_corner(index: int): get_corner(index).queue_free() get_edge(index).queue_free() func _on_click_floor(event): if floor_corner != null && height_corner != null: return add_floor_corner(event.ray.get_collision_point()) add_height_corner(event.ray.get_collision_point()) room.room_ceiling.get_node("CollisionShape3D").disabled = false func _on_click_ceiling(event): if floor_corner == null || height_corner == null || event.target != room.room_ceiling: return var pos = event.ray.get_collision_point() pos.y = 0 add_corner(pos) func add_floor_corner(position: Vector3): floor_corner = wall_corner_scene.instantiate() floor_corner.position = position height_edge = wall_edge_scene.instantiate() height_edge.align_to_corners(position, position + Vector3.UP * room.room_ceiling.position.y) floor_corner.get_node("Clickable").on_grab_down.connect(func(event): if !is_active() || moving != null: return moving = event.target ) floor_corner.get_node("Clickable").on_grab_move.connect(func(event): if moving == null: return var moving_index = height_corner.get_index() var direction = -event.ray.global_transform.basis.z var new_position = room.room_floor.get_node("CollisionShape3D").shape.plane.intersects_ray(event.ray.global_position, direction) if new_position == null: return moving.position = new_position height_edge.align_to_corners(new_position, new_position + Vector3.UP * room.room_ceiling.global_position.y) get_corner(moving_index).position.x = new_position.x get_corner(moving_index).position.z = new_position.z if room.wall_edges.get_child_count() == 0: return get_edge(moving_index).align_to_corners(new_position, get_corner(moving_index + 1).position) get_edge(moving_index - 1).align_to_corners(get_corner(moving_index - 1).position, new_position) ) floor_corner.get_node("Clickable").on_grab_up.connect(func(_event): moving = null ) room.add_child(floor_corner) room.add_child(height_edge) func add_height_corner(position: Vector3): height_corner = wall_corner_scene.instantiate() height_corner.position.x = position.x height_corner.position.z = position.z height_corner.get_node("Clickable").on_grab_down.connect(func(event): if !is_active() || moving != null: return moving = event.target ) height_corner.get_node("Clickable").on_grab_move.connect(func(event): if moving == null: return var direction = -event.ray.global_transform.basis.z var plane_direction = direction plane_direction.y = 0 plane_direction = plane_direction.normalized() * -1 var plane = Plane(plane_direction, moving.position) var new_position = plane.intersects_ray(event.ray.global_position, direction) if new_position == null: return room.room_ceiling.position.y = new_position.y height_edge.align_to_corners(floor_corner.position, floor_corner.position + Vector3.UP * room.room_ceiling.position.y) ) height_corner.get_node("Clickable").on_grab_up.connect(func(_event): moving = null ) room.wall_corners.add_child(height_corner) func add_corner(position: Vector3, index: int = -1): var corner = wall_corner_scene.instantiate() corner.position.x = position.x corner.position.z = position.z corner.get_node("Clickable").on_grab_down.connect(func(event): if !is_active() || moving != null: return moving = event.target ) corner.get_node("Clickable").on_grab_move.connect(func(event): if moving == null: return var moving_index = moving.get_index() var direction = -event.ray.global_transform.basis.z var ceiling_plane = Plane(Vector3.DOWN, room.room_ceiling.global_position) var new_position = ceiling_plane.intersects_ray(event.ray.global_position, direction) if new_position == null: deleting = true new_position = event.ray.global_position + direction get_corner(moving_index).global_position = new_position if room.wall_edges.get_child_count() == 0: return get_edge(moving_index).align_to_corners(get_corner(moving_index - 1).position, get_corner(moving_index + 1).position) get_edge(moving_index - 1).transform = get_edge(moving_index).transform return deleting = false new_position.y = 0 moving.position = new_position if room.wall_edges.get_child_count() == 0: return get_edge(moving_index).align_to_corners(new_position, get_corner(moving_index + 1).position) get_edge(moving_index - 1).align_to_corners(get_corner(moving_index - 1).position, new_position) ) corner.get_node("Clickable").on_grab_up.connect(func(_event): if deleting: var moving_index = moving.get_index() remove_corner(moving_index) moving = null deleting = false ) room.wall_corners.add_child(corner) room.wall_corners.move_child(corner, index) var num_corners = room.wall_corners.get_child_count() if num_corners > 1: add_edge(position, get_corner(index + 1).position, index) if num_corners > 2: if num_corners != room.wall_edges.get_child_count(): add_edge(get_corner(-2).position, get_corner(-1).position, -2) else: get_edge(index - 1).align_to_corners(get_corner(index - 1).position, position) func add_edge(from_pos: Vector3, to_pos: Vector3, index: int = -1): var edge: StaticBody3D = wall_edge_scene.instantiate() edge.align_to_corners(from_pos, to_pos) edge.get_node("Clickable").on_press_down.connect(func(event): var point = event.ray.get_collision_point() point.y = 0 add_corner(point, edge.get_index() + 1) ) room.wall_edges.add_child(edge) room.wall_edges.move_child(edge, index) return edge func update_store(): var store_room = Store.house.get_room(room.name) if store_room == null: return var corners = [] for corner in room.wall_corners.get_children(): corners.append(Vector2(corner.global_position.x, corner.global_position.z)) store_room.corners = corners store_room.height = room.room_ceiling.position.y Store.house.save_local()