immersive-home/app/content/system/house/room/states/edit.gd

281 lines
8.2 KiB
GDScript

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():
room.wall_corners.remove_child(child)
child.queue_free()
for child in room.wall_edges.get_children():
room.wall_edges.remove_child(child)
child.queue_free()
if floor_corner != null:
room.remove_child(floor_corner)
floor_corner.queue_free()
room.remove_child(height_edge)
height_edge.queue_free()
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
# Manually update the array
Store.house.state.rooms = Store.house.state.rooms
Store.house.save_local()