|
1 | 1 | @tool |
2 | 2 | extends CharacterBody2D |
3 | 3 |
|
| 4 | +const OPEN_AREA_DEFAULT_WIDTH: float = 120.0 |
4 | 5 |
|
5 | | -@export var texture = preload("res://Graphics/Obstacles/Walls/shutter.png") |
6 | | -@export_enum("left","right","switch")var side = 0 |
7 | | -var open = false |
| 6 | +@export var texture: Texture2D = preload("res://Graphics/Obstacles/Walls/shutter.png"): |
| 7 | + set(value): |
| 8 | + texture = value |
| 9 | + if is_node_ready(): |
| 10 | + $Shutter.texture = texture |
| 11 | + _update_areas() |
8 | 12 |
|
9 | | -func _ready(): |
10 | | - if !Engine.is_editor_hint(): |
11 | | - # set areas |
12 | | - $Mask.shape.size = Vector2(texture.get_width(),texture.get_height()) |
13 | | - $OpenShutter/Mask.shape = $Mask.shape |
14 | | - $CloseShutter/Mask.shape = $Mask.shape |
15 | | - $CloseShutter2/Mask.shape = $Mask.shape |
16 | | - |
17 | | - $Shutter.texture = texture |
18 | | - $OpenShutter.position.x = abs($OpenShutter.position.x)*(-1+(min(1,side)*2)) |
19 | | - $CloseShutter.position.x = abs($CloseShutter.position.x)*(-1+(min(1,side)*2)) |
20 | | - $CloseShutter2.position.x = abs($CloseShutter2.position.x)*(1-(min(1,side)*2)) |
21 | | - |
22 | | - # disable areas if side is switch |
23 | | - if side == 2: |
24 | | - $OpenShutter.queue_free() |
25 | | - $CloseShutter.queue_free() |
26 | | - $CloseShutter2.queue_free() |
27 | | - |
| 13 | +enum SIDE { LEFT, RIGHT, SWITCH } |
| 14 | +@export var side: SIDE = SIDE.LEFT: |
| 15 | + set(value): |
| 16 | + side = value |
| 17 | + if is_node_ready(): |
| 18 | + _update_areas() |
28 | 19 |
|
29 | | -func _process(delta): |
30 | | - if !Engine.is_editor_hint(): |
31 | | - # move shutter |
32 | | - $Shutter.position = $Shutter.position.move_toward(Vector2(0,-texture.get_height()*int(open)),delta*512) |
33 | | - # disable mask if opened |
34 | | - $Mask.disabled = open |
35 | | - else: |
36 | | - $Mask.shape.size = Vector2(texture.get_width(),texture.get_height()) |
37 | | - $OpenShutter/Mask.shape = $Mask.shape |
38 | | - $CloseShutter/Mask.shape = $Mask.shape |
39 | | - $CloseShutter2/Mask.shape = $Mask.shape |
40 | | - |
| 20 | +@export var open: bool = false: |
| 21 | + set(value): |
| 22 | + open = value |
| 23 | + currently_open = value |
| 24 | +var currently_open: bool = open: |
| 25 | + set(value): |
| 26 | + var prev_value: bool = currently_open |
| 27 | + currently_open = value |
| 28 | + if is_node_ready(): |
| 29 | + if Engine.is_editor_hint(): |
| 30 | + # open/close the door |
| 31 | + $Shutter.position.y = -texture.get_height() if value else 0 |
| 32 | + elif value != prev_value: |
| 33 | + $ShutterSound.play() |
| 34 | + _update_areas() |
| 35 | + |
| 36 | +func _update_areas() -> void: |
| 37 | + if Engine.is_editor_hint(): |
41 | 38 | # hide masks if side is set to switch |
42 | | - $OpenShutter/Mask.visible = int(side < 2) |
43 | | - $CloseShutter/Mask.visible = int(side < 2) |
44 | | - $CloseShutter2/Mask.visible = int(side < 2) |
45 | | - |
46 | | - $Shutter.texture = texture |
47 | | - $OpenShutter.position.x = abs($OpenShutter.position.x)*(-1+(min(1,side)*2)) |
48 | | - $CloseShutter.position.x = abs($CloseShutter.position.x)*(-1+(min(1,side)*2)) |
49 | | - $CloseShutter2.position.x = abs($CloseShutter2.position.x)*(1-(min(1,side)*2)) |
| 39 | + # (also, hide CloseArea if the door is initially open) |
| 40 | + var not_switch: bool = (side != SIDE.SWITCH) |
| 41 | + $OpenArea/Mask.visible = not_switch |
| 42 | + $CloseArea/Mask.visible = not_switch and not open |
| 43 | + $CloseArea2/Mask.visible = not_switch |
| 44 | + $Mask.visible = not currently_open |
| 45 | + else: |
| 46 | + # disable the mask if the door is open |
| 47 | + $Mask.disabled = currently_open |
| 48 | + # disable detection areas if side is switch |
| 49 | + # (also, disable CloseArea if the door is initially open) |
| 50 | + var switch: bool = (side == SIDE.SWITCH) |
| 51 | + $OpenArea/Mask.disabled = switch |
| 52 | + $CloseArea/Mask.disabled = switch or open |
| 53 | + $CloseArea2/Mask.disabled = switch |
| 54 | + if side != SIDE.SWITCH: |
| 55 | + # sanity checks |
| 56 | + assert($Mask.shape is RectangleShape2D) |
| 57 | + assert($OpenArea/Mask.shape is RectangleShape2D) |
| 58 | + # set areas |
| 59 | + var door_shape: RectangleShape2D = $Mask.shape as RectangleShape2D |
| 60 | + door_shape.size = texture.get_size() |
| 61 | + $CloseArea/Mask.shape = door_shape |
| 62 | + $CloseArea2/Mask.shape = door_shape |
| 63 | + var side_sign: float = -1 if side == SIDE.LEFT else 1 |
| 64 | + var door_width: float = door_shape.size.x |
| 65 | + var open_area_width: float = OPEN_AREA_DEFAULT_WIDTH - door_width / 2.0 + (door_width if currently_open else 0.0) |
| 66 | + $OpenArea/Mask.shape.size = Vector2(open_area_width, door_shape.size.y) |
| 67 | + var open_area_pos_x = (open_area_width + door_width) / 2.0 - (door_width if currently_open else 0.0) |
| 68 | + $OpenArea.position.x = open_area_pos_x * side_sign |
| 69 | + var close_area_offset: float = (open_area_width + door_width) / 2.0 |
| 70 | + $CloseArea.position.x = (open_area_pos_x + close_area_offset) * side_sign |
| 71 | + $CloseArea2.position.x = (open_area_pos_x - close_area_offset - (0.0 if currently_open else door_width)) * side_sign |
50 | 72 |
|
51 | | -# open on body touch (and player 1) |
52 | | -func _on_OpenShutter_body_entered(body): |
53 | | - if body.playerControl == 1: |
54 | | - open = true |
| 73 | +func _ready() -> void: |
| 74 | + $Shutter.texture = texture |
| 75 | + $Shutter.position.y = -texture.get_height() if currently_open else 0 |
| 76 | + _update_areas() |
55 | 77 |
|
| 78 | +func _process(delta) -> void: |
| 79 | + if not Engine.is_editor_hint(): |
| 80 | + # move shutter |
| 81 | + $Shutter.position = $Shutter.position.move_toward(Vector2(0.0, -texture.get_height() if currently_open else 0), delta * 512.0) |
| 82 | + # disable mask if opened |
| 83 | + $Mask.disabled = currently_open |
56 | 84 |
|
57 | | -# close on body leave (and player 1) |
58 | | -func _on_CloseShutter_body_entered(body): |
59 | | - if body.playerControl == 1: |
60 | | - open = false |
| 85 | +func _physics_process(_delta: float) -> void: |
| 86 | + if $OpenArea.has_overlapping_bodies(): |
| 87 | + currently_open = true |
| 88 | + elif $CloseArea.has_overlapping_bodies() or $CloseArea2.has_overlapping_bodies(): |
| 89 | + currently_open = false |
61 | 90 |
|
62 | 91 | # force open and force close is used for switches |
63 | | -func force_open(): |
64 | | - open = true |
| 92 | +func force_open() -> void: |
| 93 | + currently_open = true |
65 | 94 |
|
66 | | -func force_close(): |
67 | | - open = false |
| 95 | +func force_close() -> void: |
| 96 | + currently_open = false |
0 commit comments