Merge branch 'master' of https://git.ghostguild.org/henry/tojam20-elevator
This commit is contained in:
commit
4abb622f71
24 changed files with 398 additions and 110 deletions
BIN
audio/RoboZacSpeaker.wav
Normal file
BIN
audio/RoboZacSpeaker.wav
Normal file
Binary file not shown.
24
audio/RoboZacSpeaker.wav.import
Normal file
24
audio/RoboZacSpeaker.wav.import
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="wav"
|
||||||
|
type="AudioStreamWAV"
|
||||||
|
uid="uid://cnfmytsyo8biq"
|
||||||
|
path="res://.godot/imported/RoboZacSpeaker.wav-f05e9451bbf465ad55d22d78b38e2297.sample"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://audio/RoboZacSpeaker.wav"
|
||||||
|
dest_files=["res://.godot/imported/RoboZacSpeaker.wav-f05e9451bbf465ad55d22d78b38e2297.sample"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
force/8_bit=false
|
||||||
|
force/mono=false
|
||||||
|
force/max_rate=false
|
||||||
|
force/max_rate_hz=44100
|
||||||
|
edit/trim=false
|
||||||
|
edit/normalize=false
|
||||||
|
edit/loop_mode=1
|
||||||
|
edit/loop_begin=0
|
||||||
|
edit/loop_end=-1
|
||||||
|
compress/mode=2
|
||||||
BIN
images/virtua_hand_left.png
Normal file
BIN
images/virtua_hand_left.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 575 B |
41
images/virtua_hand_left.png.import
Normal file
41
images/virtua_hand_left.png.import
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://hjn06y02ragw"
|
||||||
|
path.s3tc="res://.godot/imported/virtua_hand_left.png-efef97087be89c63cfe333c552ecb2f0.s3tc.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://images/virtua_hand_left.png"
|
||||||
|
dest_files=["res://.godot/imported/virtua_hand_left.png-efef97087be89c63cfe333c552ecb2f0.s3tc.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
||||||
18
scenes/button_panel.gd
Normal file
18
scenes/button_panel.gd
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
extends Node3D
|
||||||
|
|
||||||
|
const BUTTON_SCENE = preload("res://scenes/floor_button.tscn")
|
||||||
|
const BUTTON_COUNT := 10
|
||||||
|
const Y_TOP := 8.49
|
||||||
|
const Y_BOTTOM := -4.36
|
||||||
|
|
||||||
|
@onready var _container: Node3D = $FloorButtons
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
var spacing = (Y_TOP - Y_BOTTOM) / float(BUTTON_COUNT - 1)
|
||||||
|
for i in range(BUTTON_COUNT):
|
||||||
|
var btn = BUTTON_SCENE.instantiate()
|
||||||
|
btn.name = "%02d" % i
|
||||||
|
btn.position = Vector3(0, Y_BOTTOM + i * spacing, 0)
|
||||||
|
_container.add_child(btn)
|
||||||
|
var sprite: Sprite3D = btn.get_node("ButtonSprite")
|
||||||
|
sprite.frame = i
|
||||||
1
scenes/button_panel.gd.uid
Normal file
1
scenes/button_panel.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cp2n258uuuou3
|
||||||
|
|
@ -1,75 +1,9 @@
|
||||||
[gd_scene format=3 uid="uid://cnjn0vhg1phav"]
|
[gd_scene format=3 uid="uid://cnjn0vhg1phav"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://bw1kbbl3n83e8" path="res://scenes/floor_button.tscn" id="1_lff67"]
|
[ext_resource type="PackedScene" uid="uid://bw1kbbl3n83e8" path="res://scenes/floor_button.tscn" id="1_lff67"]
|
||||||
|
[ext_resource type="Script" path="res://scenes/button_panel.gd" id="2_bpscr"]
|
||||||
|
|
||||||
[node name="ButtonPanel" type="Node3D" unique_id=1270714626]
|
[node name="ButtonPanel" type="Node3D" unique_id=1270714626]
|
||||||
|
script = ExtResource("2_bpscr")
|
||||||
|
|
||||||
[node name="FloorButtons" type="Node3D" parent="." unique_id=1608506954]
|
[node name="FloorButtons" type="Node3D" parent="." unique_id=1608506954]
|
||||||
|
|
||||||
[node name="00" parent="." unique_id=1628684586 instance=ExtResource("1_lff67")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -4.360477, 0)
|
|
||||||
|
|
||||||
[node name="01" parent="." unique_id=1324476691 instance=ExtResource("1_lff67")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2.8598118, 0)
|
|
||||||
|
|
||||||
[node name="ButtonSprite" parent="01" index="0" unique_id=1628684586]
|
|
||||||
frame = 1
|
|
||||||
|
|
||||||
[node name="02" parent="." unique_id=1143590285 instance=ExtResource("1_lff67")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.3875825, 0)
|
|
||||||
|
|
||||||
[node name="ButtonSprite" parent="02" index="0" unique_id=1628684586]
|
|
||||||
frame = 2
|
|
||||||
|
|
||||||
[node name="03" parent="." unique_id=1467372561 instance=ExtResource("1_lff67")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.03961301, 0)
|
|
||||||
|
|
||||||
[node name="ButtonSprite" parent="03" index="0" unique_id=1628684586]
|
|
||||||
frame = 3
|
|
||||||
|
|
||||||
[node name="04" parent="." unique_id=652433944 instance=ExtResource("1_lff67")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3832786, 0)
|
|
||||||
|
|
||||||
[node name="ButtonSprite" parent="04" index="0" unique_id=1628684586]
|
|
||||||
frame = 4
|
|
||||||
|
|
||||||
[node name="05" parent="." unique_id=470439905 instance=ExtResource("1_lff67")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.842876, 0)
|
|
||||||
|
|
||||||
[node name="ButtonSprite" parent="05" index="0" unique_id=1628684586]
|
|
||||||
frame = 5
|
|
||||||
|
|
||||||
[node name="06" parent="." unique_id=1293107230 instance=ExtResource("1_lff67")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4.1931896, 0)
|
|
||||||
|
|
||||||
[node name="ButtonSprite" parent="06" index="0" unique_id=1628684586]
|
|
||||||
frame = 6
|
|
||||||
|
|
||||||
[node name="07" parent="." unique_id=1309697731 instance=ExtResource("1_lff67")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5.632162, 0)
|
|
||||||
|
|
||||||
[node name="ButtonSprite" parent="07" index="0" unique_id=1628684586]
|
|
||||||
frame = 7
|
|
||||||
|
|
||||||
[node name="08" parent="." unique_id=447931949 instance=ExtResource("1_lff67")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7.0681796, 0)
|
|
||||||
|
|
||||||
[node name="ButtonSprite" parent="08" index="0" unique_id=1628684586]
|
|
||||||
frame = 8
|
|
||||||
|
|
||||||
[node name="09" parent="." unique_id=1200513083 instance=ExtResource("1_lff67")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 8.490524, 0)
|
|
||||||
|
|
||||||
[node name="ButtonSprite" parent="09" index="0" unique_id=1628684586]
|
|
||||||
frame = 9
|
|
||||||
|
|
||||||
[editable path="00"]
|
|
||||||
[editable path="01"]
|
|
||||||
[editable path="02"]
|
|
||||||
[editable path="03"]
|
|
||||||
[editable path="04"]
|
|
||||||
[editable path="05"]
|
|
||||||
[editable path="06"]
|
|
||||||
[editable path="07"]
|
|
||||||
[editable path="08"]
|
|
||||||
[editable path="09"]
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,14 @@ const DOOR_CLOSED_X := 0.7
|
||||||
const DOOR_DEFAULT_TIME := 3.0
|
const DOOR_DEFAULT_TIME := 3.0
|
||||||
const DOOR_FAST_CLOSE_TIME := 1.0
|
const DOOR_FAST_CLOSE_TIME := 1.0
|
||||||
const DOOR_REOPEN_TIME := 0.4
|
const DOOR_REOPEN_TIME := 0.4
|
||||||
|
const PULSE_CLOSE_LAG_TOP := 1.0
|
||||||
|
const PULSE_CLOSE_LAG_PER_FLOOR := 0.09
|
||||||
|
const PULSE_CLOSE_LAG_MIN := 0.2
|
||||||
|
const DOORS_NEARLY_OPEN_LEAD := 0.4
|
||||||
|
|
||||||
var _tween: Tween = null
|
var _tween: Tween = null
|
||||||
|
var _pulse_close_pending: bool = false
|
||||||
|
var _current_floor: int = EventBus.STARTING_FLOOR
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
$ElevatorDoorRight.position = Vector3(DOOR_CLOSED_X, 0, 0)
|
$ElevatorDoorRight.position = Vector3(DOOR_CLOSED_X, 0, 0)
|
||||||
|
|
@ -16,21 +22,39 @@ func _ready():
|
||||||
EventBus.doors_closed.connect(_on_doors_closed)
|
EventBus.doors_closed.connect(_on_doors_closed)
|
||||||
EventBus.pulse_started.connect(_on_pulse_started)
|
EventBus.pulse_started.connect(_on_pulse_started)
|
||||||
EventBus.pulse_blocked.connect(_on_pulse_blocked)
|
EventBus.pulse_blocked.connect(_on_pulse_blocked)
|
||||||
|
EventBus.floor_changed.connect(func(f): _current_floor = f)
|
||||||
|
|
||||||
func _on_doors_opened():
|
func _on_doors_opened():
|
||||||
|
_pulse_close_pending = false
|
||||||
_set_door_collision(false)
|
_set_door_collision(false)
|
||||||
_tween_doors(DOOR_OPEN_X, DOOR_DEFAULT_TIME)
|
_tween_doors(DOOR_OPEN_X, DOOR_DEFAULT_TIME)
|
||||||
|
_tween.chain().tween_callback(func(): EventBus.doors_fully_opened.emit())
|
||||||
|
get_tree().create_timer(DOOR_DEFAULT_TIME - DOORS_NEARLY_OPEN_LEAD, false).timeout.connect(
|
||||||
|
func(): EventBus.doors_nearly_opened.emit(),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
func _on_doors_closed(fast: bool):
|
func _on_doors_closed(fast: bool):
|
||||||
|
_pulse_close_pending = false
|
||||||
_set_door_collision(true)
|
_set_door_collision(true)
|
||||||
_tween_doors(DOOR_CLOSED_X, DOOR_FAST_CLOSE_TIME if fast else DOOR_DEFAULT_TIME)
|
_tween_doors(DOOR_CLOSED_X, DOOR_FAST_CLOSE_TIME if fast else DOOR_DEFAULT_TIME)
|
||||||
_tween.chain().tween_callback(func(): EventBus.doors_fully_closed.emit())
|
_tween.chain().tween_callback(func(): EventBus.doors_fully_closed.emit())
|
||||||
|
|
||||||
func _on_pulse_started(duration: float):
|
func _on_pulse_started(duration: float):
|
||||||
_set_door_collision(true)
|
_set_door_collision(true)
|
||||||
_tween_doors(DOOR_CLOSED_X, duration)
|
_pulse_close_pending = true
|
||||||
|
var floors_descended = EventBus.STARTING_FLOOR - _current_floor
|
||||||
|
var lag = max(PULSE_CLOSE_LAG_MIN, PULSE_CLOSE_LAG_TOP - floors_descended * PULSE_CLOSE_LAG_PER_FLOOR)
|
||||||
|
get_tree().create_timer(lag, false).timeout.connect(
|
||||||
|
func():
|
||||||
|
if _pulse_close_pending:
|
||||||
|
_pulse_close_pending = false
|
||||||
|
_tween_doors(DOOR_CLOSED_X, duration),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
func _on_pulse_blocked():
|
func _on_pulse_blocked():
|
||||||
|
_pulse_close_pending = false
|
||||||
_set_door_collision(false)
|
_set_door_collision(false)
|
||||||
_tween_doors(DOOR_OPEN_X, DOOR_REOPEN_TIME)
|
_tween_doors(DOOR_OPEN_X, DOOR_REOPEN_TIME)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ const ROBOT_DELAY_MIN := 1.0
|
||||||
var people_in_elevator := 0
|
var people_in_elevator := 0
|
||||||
|
|
||||||
const PERFECT_STUN_DURATION := 1.5
|
const PERFECT_STUN_DURATION := 1.5
|
||||||
const PRE_PULSE_DELAY := 3.5
|
const DING_TO_DOORS_DELAY := 2.0
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
_close_button.text = "CLOSE"
|
_close_button.text = "CLOSE"
|
||||||
|
|
@ -41,7 +41,7 @@ func _ready():
|
||||||
_screen.pulse_blocked_perfect.connect(_on_pulse_blocked_perfect)
|
_screen.pulse_blocked_perfect.connect(_on_pulse_blocked_perfect)
|
||||||
_screen.doors_closing.connect(func(): _on_doors_closing(true))
|
_screen.doors_closing.connect(func(): _on_doors_closing(true))
|
||||||
|
|
||||||
EventBus.game_started.connect(_start_floor)
|
EventBus.game_started.connect(_on_game_started)
|
||||||
EventBus.game_lost.connect(func(_reason): $SfxRobotIUnderstand.play())
|
EventBus.game_lost.connect(func(_reason): $SfxRobotIUnderstand.play())
|
||||||
EventBus.survivor_squeaked_in.connect(_on_survivor_squeaked_in)
|
EventBus.survivor_squeaked_in.connect(_on_survivor_squeaked_in)
|
||||||
EventBus.robot_close_warning.connect(_on_robot_close_warning)
|
EventBus.robot_close_warning.connect(_on_robot_close_warning)
|
||||||
|
|
@ -59,6 +59,10 @@ func _unhandled_input(event):
|
||||||
EventBus.debug_starting_floor = EventBus.STARTING_FLOOR
|
EventBus.debug_starting_floor = EventBus.STARTING_FLOOR
|
||||||
get_tree().reload_current_scene()
|
get_tree().reload_current_scene()
|
||||||
|
|
||||||
|
func _on_game_started():
|
||||||
|
await EventBus.intro_finished
|
||||||
|
_start_floor()
|
||||||
|
|
||||||
func _reset_floor_state():
|
func _reset_floor_state():
|
||||||
doors_closing_flag = false
|
doors_closing_flag = false
|
||||||
people_in_elevator = 0
|
people_in_elevator = 0
|
||||||
|
|
@ -72,12 +76,18 @@ func _start_floor():
|
||||||
_onboarded = true
|
_onboarded = true
|
||||||
EventBus.debug_starting_floor = 0
|
EventBus.debug_starting_floor = 0
|
||||||
|
|
||||||
$SfxOpen.play()
|
|
||||||
$SfxBell.play()
|
$SfxBell.play()
|
||||||
if _onboarded and randf() < 0.4:
|
if _onboarded and randf() < 0.4:
|
||||||
$SfxRobotDeepBreath.play()
|
$SfxRobotDeepBreath.play()
|
||||||
_reset_floor_state()
|
_reset_floor_state()
|
||||||
EventBus.doors_opened.emit()
|
get_tree().create_timer(DING_TO_DOORS_DELAY, false).timeout.connect(
|
||||||
|
func():
|
||||||
|
if not is_instance_valid(self) or doors_closing_flag:
|
||||||
|
return
|
||||||
|
$SfxOpen.play()
|
||||||
|
EventBus.doors_opened.emit(),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
EventBus.people_changed.emit(people_in_elevator, THRESHOLD)
|
EventBus.people_changed.emit(people_in_elevator, THRESHOLD)
|
||||||
EventBus.floor_changed.emit(current_floor)
|
EventBus.floor_changed.emit(current_floor)
|
||||||
|
|
@ -97,17 +107,7 @@ func _start_floor():
|
||||||
|
|
||||||
if not _onboarded:
|
if not _onboarded:
|
||||||
_onboarded = true
|
_onboarded = true
|
||||||
_screen.show_onboarding("BLOCK\nIN GREEN ZONE")
|
EventBus.doors_nearly_opened.connect(
|
||||||
get_tree().create_timer(3.0, false).timeout.connect(
|
|
||||||
func():
|
|
||||||
if not is_instance_valid(_screen):
|
|
||||||
return
|
|
||||||
_screen.end_onboarding()
|
|
||||||
_screen.launch_pulse(),
|
|
||||||
CONNECT_ONE_SHOT
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
get_tree().create_timer(PRE_PULSE_DELAY, false).timeout.connect(
|
|
||||||
func():
|
func():
|
||||||
if not is_instance_valid(self) or doors_closing_flag:
|
if not is_instance_valid(self) or doors_closing_flag:
|
||||||
return
|
return
|
||||||
|
|
@ -126,6 +126,7 @@ func _on_robot_close_warning():
|
||||||
func _on_block_pressed():
|
func _on_block_pressed():
|
||||||
if doors_closing_flag:
|
if doors_closing_flag:
|
||||||
return
|
return
|
||||||
|
EventBus.block_pressed.emit()
|
||||||
if _screen.pulse_active:
|
if _screen.pulse_active:
|
||||||
_screen.attempt_block()
|
_screen.attempt_block()
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@ extends Node3D
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
$ComponentSpawn.survivor_spawn = $World/SurvivorSpawn
|
$ComponentSpawn.survivor_spawn = $World/SurvivorSpawn
|
||||||
|
$Ambience.finished.connect($Ambience.play)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
[ext_resource type="PackedScene" uid="uid://sgakdvtoblmd" path="res://scenes/title_screen.tscn" id="11_title"]
|
[ext_resource type="PackedScene" uid="uid://sgakdvtoblmd" path="res://scenes/title_screen.tscn" id="11_title"]
|
||||||
[ext_resource type="AudioStream" uid="uid://b3d6rntbosvc6" path="res://audio/Ambience.wav" id="12_amb"]
|
[ext_resource type="AudioStream" uid="uid://b3d6rntbosvc6" path="res://audio/Ambience.wav" id="12_amb"]
|
||||||
[ext_resource type="PackedScene" path="res://scenes/pause_menu.tscn" id="12_pause"]
|
[ext_resource type="PackedScene" path="res://scenes/pause_menu.tscn" id="12_pause"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://cnfmytsyo8biq" path="res://audio/RoboZacSpeaker.wav" id="13_muzak"]
|
||||||
|
[ext_resource type="Script" uid="uid://deyjxii7yykjv" path="res://scenes/muzak.gd" id="14_muzak_s"]
|
||||||
|
|
||||||
[node name="Game" type="Node3D" unique_id=1456297160]
|
[node name="Game" type="Node3D" unique_id=1456297160]
|
||||||
script = ExtResource("1_lbhrr")
|
script = ExtResource("1_lbhrr")
|
||||||
|
|
@ -66,6 +68,11 @@ stream = ExtResource("12_amb")
|
||||||
volume_db = -6.0
|
volume_db = -6.0
|
||||||
autoplay = true
|
autoplay = true
|
||||||
|
|
||||||
|
[node name="Muzak" type="AudioStreamPlayer" parent="." unique_id=1100000006]
|
||||||
|
stream = ExtResource("13_muzak")
|
||||||
|
volume_db = -10.0
|
||||||
|
script = ExtResource("14_muzak_s")
|
||||||
|
|
||||||
[node name="ComponentSpawn" parent="." unique_id=649225939 instance=ExtResource("9_0tnpc")]
|
[node name="ComponentSpawn" parent="." unique_id=649225939 instance=ExtResource("9_0tnpc")]
|
||||||
|
|
||||||
[node name="EndScreen" parent="." unique_id=993175156 instance=ExtResource("10_endsc")]
|
[node name="EndScreen" parent="." unique_id=993175156 instance=ExtResource("10_endsc")]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
[gd_scene load_steps=3 format=3 uid="uid://cbvi51vvpt7mu"]
|
[gd_scene load_steps=2 format=3 uid="uid://cbvi51vvpt7mu"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://fpaw3u5yjtbk" path="res://scenes/hud.gd" id="1_64ctp"]
|
[ext_resource type="Script" uid="uid://fpaw3u5yjtbk" path="res://scenes/hud.gd" id="1_64ctp"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dshaftstrip01" path="res://scenes/shaft_strip.tscn" id="2_shaft"]
|
|
||||||
|
|
||||||
[node name="HUD" type="MarginContainer" unique_id=769131693]
|
[node name="HUD" type="MarginContainer" unique_id=769131693]
|
||||||
offset_right = 40.0
|
offset_right = 40.0
|
||||||
|
|
@ -31,13 +30,3 @@ text = "FLOOR: 0"
|
||||||
[node name="ScoreLabel" type="Label" parent="StatsColumn" unique_id=1595653166]
|
[node name="ScoreLabel" type="Label" parent="StatsColumn" unique_id=1595653166]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme_override_font_sizes/font_size = 24
|
theme_override_font_sizes/font_size = 24
|
||||||
|
|
||||||
[node name="ShaftStrip" parent="." instance=ExtResource("2_shaft")]
|
|
||||||
top_level = true
|
|
||||||
anchors_preset = 9
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = 12.0
|
|
||||||
offset_top = 12.0
|
|
||||||
offset_right = 60.0
|
|
||||||
offset_bottom = -12.0
|
|
||||||
grow_vertical = 2
|
|
||||||
|
|
|
||||||
114
scenes/left_hand.gd
Normal file
114
scenes/left_hand.gd
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
extends Sprite3D
|
||||||
|
|
||||||
|
const INTRO_DURATION := 1.5
|
||||||
|
const ENTRY_OFFSET := 0.5
|
||||||
|
const EXIT_OFFSET := 0.5
|
||||||
|
const FORWARD_OFFSET := 0.05
|
||||||
|
const FINGER_OFFSET_X := 0.0
|
||||||
|
|
||||||
|
@onready var _button_panel: Node3D = get_parent().get_node("ButtonPanel")
|
||||||
|
|
||||||
|
var _buttons: Array = []
|
||||||
|
var _intro_playing := false
|
||||||
|
var _sprite_half_h := 0.0
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
visible = false
|
||||||
|
_sprite_half_h = texture.get_height() * pixel_size * global_transform.basis.get_scale().y * 0.5
|
||||||
|
|
||||||
|
EventBus.game_started.connect(_play_intro)
|
||||||
|
EventBus.floor_changed.connect(_on_floor_changed)
|
||||||
|
|
||||||
|
func _ensure_buttons() -> void:
|
||||||
|
if not _buttons.is_empty():
|
||||||
|
return
|
||||||
|
_buttons = _collect_buttons()
|
||||||
|
if not _buttons.is_empty():
|
||||||
|
_set_all_lit(false)
|
||||||
|
|
||||||
|
func _collect_buttons() -> Array:
|
||||||
|
var arr: Array = []
|
||||||
|
var container = _button_panel.get_node_or_null("FloorButtons")
|
||||||
|
if container == null or container.get_child_count() == 0:
|
||||||
|
container = _button_panel
|
||||||
|
for i in range(10):
|
||||||
|
var button_name := "%02d" % i
|
||||||
|
var btn = container.get_node_or_null(button_name)
|
||||||
|
if btn != null:
|
||||||
|
arr.append(btn)
|
||||||
|
return arr
|
||||||
|
|
||||||
|
func _play_intro() -> void:
|
||||||
|
if _intro_playing:
|
||||||
|
return
|
||||||
|
_intro_playing = true
|
||||||
|
|
||||||
|
_ensure_buttons()
|
||||||
|
if _buttons.size() < 10:
|
||||||
|
_intro_playing = false
|
||||||
|
EventBus.intro_finished.emit()
|
||||||
|
return
|
||||||
|
|
||||||
|
_set_all_lit(false)
|
||||||
|
|
||||||
|
# animate the hand's global_position.y from start to end over a set duration
|
||||||
|
# each button gets a sibling callback scheduled in *parallel*!
|
||||||
|
# what fraction of the way from start to end is this button's Y?
|
||||||
|
# to figure out when to fire callback on set_delay() to stagge.3.r
|
||||||
|
# this way it is easy to change the duration if we want
|
||||||
|
|
||||||
|
var top_button: Node3D = _buttons[9]
|
||||||
|
var bottom_button: Node3D = _buttons[0]
|
||||||
|
var camera = get_viewport().get_camera_3d()
|
||||||
|
var camera_pos = camera.global_position if camera else Vector3.ZERO
|
||||||
|
var button_z = top_button.global_position.z
|
||||||
|
var hand_z = button_z - FORWARD_OFFSET
|
||||||
|
var z_ratio = (hand_z - camera_pos.z) / (button_z - camera_pos.z)
|
||||||
|
|
||||||
|
var hand_x = camera_pos.x + (top_button.global_position.x - camera_pos.x) * z_ratio + FINGER_OFFSET_X
|
||||||
|
|
||||||
|
var finger_start_y_world = top_button.global_position.y + ENTRY_OFFSET
|
||||||
|
var finger_end_y_world = bottom_button.global_position.y - EXIT_OFFSET
|
||||||
|
var finger_start_y = camera_pos.y + (finger_start_y_world - camera_pos.y) * z_ratio
|
||||||
|
var finger_end_y = camera_pos.y + (finger_end_y_world - camera_pos.y) * z_ratio
|
||||||
|
|
||||||
|
var sprite_start_y = finger_start_y - _sprite_half_h
|
||||||
|
var sprite_end_y = finger_end_y - _sprite_half_h
|
||||||
|
|
||||||
|
global_position = Vector3(hand_x, sprite_start_y, hand_z)
|
||||||
|
visible = true
|
||||||
|
|
||||||
|
var tween := create_tween().set_parallel(true)
|
||||||
|
tween.tween_property(self, "global_position:y", sprite_end_y, INTRO_DURATION)
|
||||||
|
|
||||||
|
for i in range(_buttons.size()):
|
||||||
|
var button_y_world = _buttons[i].global_position.y
|
||||||
|
# weird thing: button_y is projected onto the hand's Z-plane to account for perspective
|
||||||
|
# to keep the fingertip visually aligned with each button at the exact right moment
|
||||||
|
var button_y_proj = camera_pos.y + (button_y_world - camera_pos.y) * z_ratio
|
||||||
|
var t_fraction = (finger_start_y - button_y_proj) / (finger_start_y - finger_end_y)
|
||||||
|
t_fraction = clamp(t_fraction, 0.0, 1.0)
|
||||||
|
tween.tween_callback(_light_button.bind(i)).set_delay(t_fraction * INTRO_DURATION)
|
||||||
|
|
||||||
|
await tween.finished
|
||||||
|
visible = false
|
||||||
|
_intro_playing = false
|
||||||
|
EventBus.intro_finished.emit()
|
||||||
|
|
||||||
|
func _light_button(index: int) -> void:
|
||||||
|
var sprite: Sprite3D = _buttons[index].get_node("ButtonSprite")
|
||||||
|
sprite.frame = index + 10
|
||||||
|
|
||||||
|
func _set_all_lit(lit: bool) -> void:
|
||||||
|
for i in range(_buttons.size()):
|
||||||
|
var sprite: Sprite3D = _buttons[i].get_node("ButtonSprite")
|
||||||
|
sprite.frame = i + (10 if lit else 0)
|
||||||
|
|
||||||
|
func _on_floor_changed(floor_num: int) -> void:
|
||||||
|
if floor_num >= EventBus.STARTING_FLOOR:
|
||||||
|
return
|
||||||
|
_ensure_buttons()
|
||||||
|
if floor_num < 0 or floor_num >= _buttons.size():
|
||||||
|
return
|
||||||
|
var sprite: Sprite3D = _buttons[floor_num].get_node("ButtonSprite")
|
||||||
|
sprite.frame = floor_num
|
||||||
1
scenes/left_hand.gd.uid
Normal file
1
scenes/left_hand.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cqi3wsvqno12v
|
||||||
11
scenes/left_hand.tscn
Normal file
11
scenes/left_hand.tscn
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
[gd_scene format=3 uid="uid://cl3hb1nm4xy8t"]
|
||||||
|
|
||||||
|
[ext_resource type="Texture2D" path="res://images/virtua_hand_left.png" id="1_lhand"]
|
||||||
|
[ext_resource type="Script" path="res://scenes/left_hand.gd" id="2_lhscr"]
|
||||||
|
|
||||||
|
[node name="LeftHand" type="Sprite3D"]
|
||||||
|
billboard = 1
|
||||||
|
texture_filter = 0
|
||||||
|
alpha_cut = 1
|
||||||
|
texture = ExtResource("1_lhand")
|
||||||
|
script = ExtResource("2_lhscr")
|
||||||
64
scenes/muzak.gd
Normal file
64
scenes/muzak.gd
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
extends AudioStreamPlayer
|
||||||
|
|
||||||
|
const NORMAL_DB := -10.0
|
||||||
|
const DUCKED_DB := -24.0
|
||||||
|
const DUCK_IN := 0.15
|
||||||
|
const DUCK_OUT := 0.4
|
||||||
|
# these paths wwould need to be updated if renamed or moved
|
||||||
|
const BARK_PATHS := [
|
||||||
|
"../CanvasPanel/ElevatorPanel/SfxRobotDeepBreath",
|
||||||
|
"../CanvasPanel/ElevatorPanel/SfxRobotSoundsDifficult",
|
||||||
|
"../CanvasPanel/ElevatorPanel/SfxRobotIUnderstand",
|
||||||
|
"../CanvasPanel/ElevatorPanel/SfxRobotThankYou",
|
||||||
|
]
|
||||||
|
|
||||||
|
var _barks: Array = []
|
||||||
|
var _ducked: bool = false
|
||||||
|
var _tween: Tween
|
||||||
|
var _started: bool = false
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
volume_db = NORMAL_DB
|
||||||
|
finished.connect(play)
|
||||||
|
for p in BARK_PATHS:
|
||||||
|
var n := get_node_or_null(p)
|
||||||
|
if n:
|
||||||
|
_barks.append(n)
|
||||||
|
EventBus.game_started.connect(_on_game_started)
|
||||||
|
EventBus.game_won.connect(_on_game_ended)
|
||||||
|
EventBus.game_lost.connect(_on_game_lost)
|
||||||
|
|
||||||
|
func _process(_delta: float) -> void:
|
||||||
|
if not playing:
|
||||||
|
return
|
||||||
|
var any := false
|
||||||
|
for b in _barks:
|
||||||
|
if b.playing:
|
||||||
|
any = true
|
||||||
|
break
|
||||||
|
if any and not _ducked:
|
||||||
|
_ducked = true
|
||||||
|
_to_db(DUCKED_DB, DUCK_IN)
|
||||||
|
elif not any and _ducked:
|
||||||
|
_ducked = false
|
||||||
|
_to_db(NORMAL_DB, DUCK_OUT)
|
||||||
|
|
||||||
|
func _to_db(target: float, time: float) -> void:
|
||||||
|
if _tween:
|
||||||
|
_tween.kill()
|
||||||
|
_tween = create_tween()
|
||||||
|
_tween.tween_property(self, "volume_db", target, time)
|
||||||
|
|
||||||
|
func _on_game_started() -> void:
|
||||||
|
if _started:
|
||||||
|
return
|
||||||
|
_started = true
|
||||||
|
_ducked = false
|
||||||
|
volume_db = NORMAL_DB
|
||||||
|
play()
|
||||||
|
|
||||||
|
func _on_game_ended() -> void:
|
||||||
|
stop()
|
||||||
|
|
||||||
|
func _on_game_lost(_reason) -> void:
|
||||||
|
stop()
|
||||||
1
scenes/muzak.gd.uid
Normal file
1
scenes/muzak.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://deyjxii7yykjv
|
||||||
|
|
@ -6,7 +6,7 @@ const STALK_ILLUMINATE_DISTANCE := 15.0
|
||||||
var robot_ready: bool = false
|
var robot_ready: bool = false
|
||||||
var robot_win: bool = false
|
var robot_win: bool = false
|
||||||
var speed: float = 1.0
|
var speed: float = 1.0
|
||||||
var doors_open: bool = false
|
var doors_open: bool = true
|
||||||
var stun_remaining: float = 0.0
|
var stun_remaining: float = 0.0
|
||||||
var _stalking_close: bool = false
|
var _stalking_close: bool = false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,16 @@ const CHASE_LONG := preload("res://audio/Chase1.wav")
|
||||||
const CHASE_TRACKS := [CHASE_SHORT_1, CHASE_SHORT_2, CHASE_MID, CHASE_LONG]
|
const CHASE_TRACKS := [CHASE_SHORT_1, CHASE_SHORT_2, CHASE_MID, CHASE_LONG]
|
||||||
static var _last_chase: AudioStream = null
|
static var _last_chase: AudioStream = null
|
||||||
|
|
||||||
|
const SCREAM_OPEN_DB := 0.0
|
||||||
|
const SCREAM_CLOSED_DB := -20.0
|
||||||
|
|
||||||
var speed: int = 3
|
var speed: int = 3
|
||||||
var clumsiness: int = 0
|
var clumsiness: int = 0
|
||||||
var _saved: bool = false
|
var _saved: bool = false
|
||||||
|
var _in_safety_zone: bool = false
|
||||||
|
|
||||||
@onready var safety_zone: Node = get_node_or_null("/root/Game/World/ElevatorSafeZone")
|
@onready var safety_zone: Node = get_node_or_null("/root/Game/World/ElevatorSafeZone")
|
||||||
|
@onready var _elevator: Node = safety_zone.get_node_or_null("Elevator") if safety_zone else null
|
||||||
|
|
||||||
|
|
||||||
#func start(xform):
|
#func start(xform):
|
||||||
|
|
@ -30,16 +35,31 @@ func _ready():
|
||||||
)
|
)
|
||||||
|
|
||||||
func _physics_process(_delta):
|
func _physics_process(_delta):
|
||||||
|
var p: float = _elevator.get_door_close_progress() if _elevator else 0.0
|
||||||
|
if _in_safety_zone and not _saved and p > 0.49:
|
||||||
|
velocity.z = 0
|
||||||
|
else:
|
||||||
velocity.z = -speed
|
velocity.z = -speed
|
||||||
move_and_slide()
|
move_and_slide()
|
||||||
|
if _elevator:
|
||||||
|
$ScreamPlayer.volume_db = lerp(SCREAM_OPEN_DB, SCREAM_CLOSED_DB, p)
|
||||||
|
|
||||||
func _on_area_3d_area_entered(area: Area3D) -> void:
|
func _on_area_3d_area_entered(area: Area3D) -> void:
|
||||||
if area == safety_zone and not _saved:
|
if area == safety_zone and not _in_safety_zone:
|
||||||
_saved = true
|
_in_safety_zone = true
|
||||||
var elevator = safety_zone.get_node_or_null("Elevator")
|
var elevator = safety_zone.get_node_or_null("Elevator")
|
||||||
if elevator and elevator.get_door_close_progress() > 0.7:
|
var close_progress: float = elevator.get_door_close_progress() if elevator else 0.0
|
||||||
EventBus.survivor_squeaked_in.emit()
|
if close_progress > 0.49:
|
||||||
|
return
|
||||||
get_tree().create_timer(0.5, false).timeout.connect(
|
get_tree().create_timer(0.5, false).timeout.connect(
|
||||||
func(): queue_free(),
|
func():
|
||||||
|
if not is_instance_valid(self):
|
||||||
|
return
|
||||||
|
var elev = safety_zone.get_node_or_null("Elevator")
|
||||||
|
var final_progress: float = elev.get_door_close_progress() if elev else 0.0
|
||||||
|
if final_progress > 0.49:
|
||||||
|
return
|
||||||
|
_saved = true
|
||||||
|
queue_free(),
|
||||||
CONNECT_ONE_SHOT
|
CONNECT_ONE_SHOT
|
||||||
)
|
)
|
||||||
|
|
|
||||||
25
scenes/virtua_hand.gd
Normal file
25
scenes/virtua_hand.gd
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
extends Sprite3D
|
||||||
|
|
||||||
|
const UP_DURATION := 0.1
|
||||||
|
const HOLD_DURATION := 0.05
|
||||||
|
const DOWN_DURATION := 0.18
|
||||||
|
|
||||||
|
var _rest_position: Vector3
|
||||||
|
var _tween: Tween
|
||||||
|
|
||||||
|
@onready var _button: Node3D = get_parent().get_node("ElevatorButton")
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
_rest_position = position
|
||||||
|
EventBus.block_pressed.connect(_animate_press)
|
||||||
|
|
||||||
|
func _animate_press() -> void:
|
||||||
|
if not is_instance_valid(_button):
|
||||||
|
return
|
||||||
|
if _tween and _tween.is_valid():
|
||||||
|
_tween.kill()
|
||||||
|
var press_pos := Vector3(_rest_position.x, _button.position.y, _rest_position.z)
|
||||||
|
_tween = create_tween()
|
||||||
|
_tween.tween_property(self, "position", press_pos, UP_DURATION).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_OUT)
|
||||||
|
_tween.tween_interval(HOLD_DURATION)
|
||||||
|
_tween.tween_property(self, "position", _rest_position, DOWN_DURATION).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN)
|
||||||
1
scenes/virtua_hand.gd.uid
Normal file
1
scenes/virtua_hand.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://by5qr8pax54b1
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
[gd_scene format=3 uid="uid://bkqwi2yqa0nvg"]
|
[gd_scene format=3 uid="uid://bkqwi2yqa0nvg"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://51p1gbyn5l02" path="res://images/virtua_hand.png" id="1_ikq7c"]
|
[ext_resource type="Texture2D" uid="uid://51p1gbyn5l02" path="res://images/virtua_hand.png" id="1_ikq7c"]
|
||||||
|
[ext_resource type="Script" path="res://scenes/virtua_hand.gd" id="2_hand_s"]
|
||||||
|
|
||||||
[node name="VirtuaHand" type="Sprite3D" unique_id=1811028460]
|
[node name="VirtuaHand" type="Sprite3D" unique_id=1811028460]
|
||||||
billboard = 1
|
billboard = 1
|
||||||
texture_filter = 0
|
texture_filter = 0
|
||||||
texture = ExtResource("1_ikq7c")
|
texture = ExtResource("1_ikq7c")
|
||||||
|
script = ExtResource("2_hand_s")
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
[ext_resource type="PackedScene" uid="uid://cwwexawpj46hk" path="res://scenes/elevator_button.tscn" id="5_qfnet"]
|
[ext_resource type="PackedScene" uid="uid://cwwexawpj46hk" path="res://scenes/elevator_button.tscn" id="5_qfnet"]
|
||||||
[ext_resource type="Script" uid="uid://c6v2lhrkeup5i" path="res://scenes/world.gd" id="5_world"]
|
[ext_resource type="Script" uid="uid://c6v2lhrkeup5i" path="res://scenes/world.gd" id="5_world"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cnjn0vhg1phav" path="res://scenes/button_panel.tscn" id="7_i7141"]
|
[ext_resource type="PackedScene" uid="uid://cnjn0vhg1phav" path="res://scenes/button_panel.tscn" id="7_i7141"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cl3hb1nm4xy8t" path="res://scenes/left_hand.tscn" id="8_lefth"]
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_k0juu"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_k0juu"]
|
||||||
size = Vector3(3.8, 6.6328125, 0.8612671)
|
size = Vector3(3.8, 6.6328125, 0.8612671)
|
||||||
|
|
@ -63,12 +64,16 @@ unit_size = 4.0
|
||||||
max_distance = 30.0
|
max_distance = 30.0
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="ElevatorSafeZone" unique_id=264489586]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="ElevatorSafeZone" unique_id=264489586]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.24584353, 2.8164063, -0.56969166)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.24584353, 2.8164063, -0.49238968)
|
||||||
shape = SubResource("BoxShape3D_k0juu")
|
shape = SubResource("BoxShape3D_k0juu")
|
||||||
|
|
||||||
[node name="ButtonPanel" parent="ElevatorSafeZone" unique_id=1270714626 instance=ExtResource("7_i7141")]
|
[node name="ButtonPanel" parent="ElevatorSafeZone" unique_id=1270714626 instance=ExtResource("7_i7141")]
|
||||||
transform = Transform3D(0.3, 0, 0, 0, 0.3, 0, 0, 0, 0.3, 3.4193654, 2.2598982, -0.39259052)
|
transform = Transform3D(0.3, 0, 0, 0, 0.3, 0, 0, 0, 0.3, 3.4193654, 2.2598982, -0.39259052)
|
||||||
|
|
||||||
|
[node name="LeftHand" parent="ElevatorSafeZone" instance=ExtResource("8_lefth")]
|
||||||
|
transform = Transform3D(3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0)
|
||||||
|
visible = false
|
||||||
|
|
||||||
[node name="SurvivorSpawn" type="Marker3D" parent="." unique_id=1095768768]
|
[node name="SurvivorSpawn" type="Marker3D" parent="." unique_id=1095768768]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.9181392, 13.711893)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.9181392, 13.711893)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ signal game_won
|
||||||
signal game_lost(reason: String)
|
signal game_lost(reason: String)
|
||||||
signal floor_started(survivor_count: int)
|
signal floor_started(survivor_count: int)
|
||||||
signal doors_opened
|
signal doors_opened
|
||||||
|
signal doors_nearly_opened
|
||||||
|
signal doors_fully_opened
|
||||||
signal doors_closed(fast: bool)
|
signal doors_closed(fast: bool)
|
||||||
signal doors_fully_closed
|
signal doors_fully_closed
|
||||||
signal pulse_started(duration: float)
|
signal pulse_started(duration: float)
|
||||||
|
|
@ -23,5 +25,7 @@ signal robot_stun_requested(duration: float)
|
||||||
signal robot_floor_started(delay: float, robot_speed: float)
|
signal robot_floor_started(delay: float, robot_speed: float)
|
||||||
signal robot_close_warning
|
signal robot_close_warning
|
||||||
signal survivor_squeaked_in
|
signal survivor_squeaked_in
|
||||||
|
signal block_pressed
|
||||||
|
signal intro_finished
|
||||||
|
|
||||||
@warning_ignore_restore("unused_signal")
|
@warning_ignore_restore("unused_signal")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue