Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[ext_resource type="TileSet" uid="uid://dfp36ffpanjq2" path="res://tiles/elevation.tres" id="8_y728v"]
[ext_resource type="PackedScene" uid="uid://crqjcicx0vdu" path="res://scenes/game_elements/props/decoration/bush/bush.tscn" id="9_gwpnv"]
[ext_resource type="PackedScene" uid="uid://lgu7aeqa7o3r" path="res://scenes/game_elements/props/door/door.tscn" id="10_f63i0"]
[ext_resource type="Script" uid="uid://hqdquinbimce" path="res://scenes/game_elements/props/teleporter/teleporter.gd" id="11_3hf7k"]
[ext_resource type="PackedScene" uid="uid://0ull24fvmhwk" path="res://scenes/game_elements/props/teleporter/teleporter.tscn" id="11_2s6si"]
[ext_resource type="PackedScene" uid="uid://iu2q66clupc6" path="res://scenes/game_elements/characters/player/player.tscn" id="12_7utab"]
[ext_resource type="SpriteFrames" uid="uid://dtoylirwywk0j" path="res://scenes/game_elements/characters/components/sprite_frames/storyweaver_blue.tres" id="13_om8go"]
[ext_resource type="PackedScene" uid="uid://dy8ohrl7j24qy" path="res://scenes/game_elements/characters/enemies/mothsache/Mothsache.tscn" id="19_bigvs"]
Expand Down Expand Up @@ -120,14 +120,11 @@ position = Vector2(608, -93)
position = Vector2(0, 72)
play_victory_fanfare_on_open = true

[node name="Teleporter" type="Area2D" parent="OnTheGround/LevelExit" unique_id=175216420]
[node name="Teleporter" parent="OnTheGround/LevelExit" unique_id=1779636661 instance=ExtResource("11_2s6si")]
position = Vector2(0, -25)
collision_layer = 4
script = ExtResource("11_3hf7k")
next_scene = "uid://biwvr6vxj6ykk"
enter_transition = 4
enter_transition = 5
exit_transition = 5
metadata/_custom_type_script = "uid://hqdquinbimce"

[node name="CollisionShape2D" type="CollisionShape2D" parent="OnTheGround/LevelExit/Teleporter" unique_id=1246369757]
position = Vector2(-1.5, -9.5)
Expand Down
4 changes: 2 additions & 2 deletions scenes/game_elements/characters/player/components/player.gd
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ func defeat(falling: bool = false) -> void:
# Check if player has lives remaining
if GameState.current_lives > 0:
# Still have lives - reload current scene/checkpoint
SceneSwitcher.reload_with_transition(Transition.Effect.FADE, Transition.Effect.FADE)
SceneSwitcher.reload_with_transition()
else:
# Game over - restart from challenge start
_handle_game_over()
Expand Down Expand Up @@ -250,7 +250,7 @@ func _handle_game_over() -> void:
# Fallback: reload current scene if no challenge start is defined
# Clear spawn point to start from the beginning of the current scene
GameState.set_current_spawn_point(^"")
SceneSwitcher.reload_with_transition(Transition.Effect.FADE, Transition.Effect.FADE)
SceneSwitcher.reload_with_transition()
else:
# Restart from the challenge start scene
SceneSwitcher.change_to_file_with_transition(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
[ext_resource type="Texture2D" uid="uid://b5ooaiyxdrp6a" path="res://scenes/game_elements/components/light_texture_256x256.tres" id="12_g3km8"]
[ext_resource type="Script" uid="uid://bk52qjv58locq" path="res://scenes/game_logic/light2d_behaviors/artificial_light_behavior.gd" id="13_e4f0h"]
[ext_resource type="PackedScene" uid="uid://d0c4l7ev6ca3c" path="res://scenes/game_elements/props/spawn_point/spawn_point.tscn" id="14_s7qaw"]
[ext_resource type="Script" uid="uid://hqdquinbimce" path="res://scenes/game_elements/props/teleporter/teleporter.gd" id="16_d01n5"]
[ext_resource type="PackedScene" uid="uid://0ull24fvmhwk" path="res://scenes/game_elements/props/teleporter/teleporter.tscn" id="16_d01n5"]
[ext_resource type="PackedScene" uid="uid://daqd67aro1o1m" path="res://scenes/game_elements/fx/time_and_weather/time_and_weather.tscn" id="16_qvyuv"]

[sub_resource type="RectangleShape2D" id="RectangleShape2D_stvbe"]
Expand Down Expand Up @@ -121,11 +121,11 @@ metadata/_custom_type_script = "uid://bk52qjv58locq"
position = Vector2(1348, 253)
look_at_side_on_spawn = -1

[node name="Teleporter" type="Area2D" parent="." unique_id=812046722]
[node name="Teleporter" parent="." unique_id=1779636661 instance=ExtResource("16_d01n5")]
position = Vector2(1401, 201)
collision_layer = 4
script = ExtResource("16_d01n5")
next_scene = "uid://co2wxwlojq08k"
enter_transition = 1
exit_transition = 1

[node name="CollisionShape2D" type="CollisionShape2D" parent="Teleporter" unique_id=1238931458]
position = Vector2(45, 51.5)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
[ext_resource type="Script" uid="uid://du8wfijr35r35" path="res://scenes/game_elements/props/interact_area/interact_area.gd" id="15_o3luo"]
[ext_resource type="PackedScene" uid="uid://d0c4l7ev6ca3c" path="res://scenes/game_elements/props/spawn_point/spawn_point.tscn" id="15_pr1ca"]
[ext_resource type="PackedScene" uid="uid://daqd67aro1o1m" path="res://scenes/game_elements/fx/time_and_weather/time_and_weather.tscn" id="17_3d8kk"]
[ext_resource type="Script" uid="uid://hqdquinbimce" path="res://scenes/game_elements/props/teleporter/teleporter.gd" id="17_o3luo"]
[ext_resource type="PackedScene" uid="uid://0ull24fvmhwk" path="res://scenes/game_elements/props/teleporter/teleporter.tscn" id="17_o3luo"]

[sub_resource type="CircleShape2D" id="CircleShape2D_h3871"]
radius = 87.43
Expand Down Expand Up @@ -139,14 +139,12 @@ shape = SubResource("CircleShape2D_h3871")
position = Vector2(525, 166)
look_at_side_on_spawn = -1

[node name="Teleporter" type="Area2D" parent="." unique_id=812046722]
[node name="Teleporter" parent="." unique_id=1779636661 instance=ExtResource("17_o3luo")]
position = Vector2(-89, 336)
collision_layer = 4
script = ExtResource("17_o3luo")
next_scene = "uid://dep64htv6c4na"
spawn_point_path = NodePath("SpawnPoint")
enter_transition = 2
exit_transition = 1
exit_transition = 2

[node name="CollisionShape2D" type="CollisionShape2D" parent="Teleporter" unique_id=1238931458]
position = Vector2(45, 51.5)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ height = 28.0

[node name="CollectibleItem" type="Node2D" unique_id=327991066]
script = ExtResource("1_7ff3m")
enter_transition = 0
exit_transition = 0

[node name="InteractArea" type="Area2D" parent="." unique_id=1327503985 node_paths=PackedStringArray("marker")]
collision_layer = 32
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
@tool
class_name CollectibleItem extends Node2D
class_name CollectibleItem
extends SceneLink

## Overworld collectible that can be interacted with. When a player interacts
## with it, an [InventoryItem] is added to the [Inventory]
Expand All @@ -14,9 +15,6 @@ class_name CollectibleItem extends Node2D
revealed = new_value
_update_based_on_revealed()

## If provided, switch to this scene after collecting and possibly displaying a dialogue.
@export_file("*.tscn") var next_scene: String

## [InventoryItem] provided by this collectible when interacted with.
@export var item: InventoryItem:
set = _set_item
Expand All @@ -40,16 +38,18 @@ class_name CollectibleItem extends Node2D


func _validate_property(property: Dictionary) -> void:
super._validate_property(property)
match property.name:
"dialogue_title":
if not collected_dialogue:
property.usage |= PROPERTY_USAGE_READ_ONLY


func _get_configuration_warnings() -> PackedStringArray:
var warnings := super._get_configuration_warnings()
if not item:
return ["item property must be set"]
return []
warnings.append("item property must be set")
return warnings


func _set_item(new_value: InventoryItem) -> void:
Expand All @@ -65,6 +65,8 @@ func _set_item(new_value: InventoryItem) -> void:


func _ready() -> void:
super._ready()

_set_item(item)
_update_based_on_revealed()
sprite_2d.modulate = Color.WHITE if revealed else Color.TRANSPARENT
Expand Down Expand Up @@ -102,7 +104,7 @@ func _on_interacted(player: Player, _from_right: bool) -> void:

if next_scene:
GameState.set_challenge_start_scene(next_scene)
SceneSwitcher.change_to_file_with_transition(next_scene)
switch()


func _update_based_on_revealed() -> void:
Expand Down
1 change: 0 additions & 1 deletion scenes/game_elements/props/teleporter/teleporter.gd.uid

This file was deleted.

16 changes: 16 additions & 0 deletions scenes/game_elements/props/teleporter/teleporter.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[gd_scene format=3 uid="uid://0ull24fvmhwk"]

[ext_resource type="Script" uid="uid://d2vp62mjrf6gn" path="res://scenes/globals/scene_switcher/scene_link.gd" id="1_2wkov"]
[ext_resource type="Script" uid="uid://0gr6vi3gxhcp" path="res://scenes/game_elements/props/teleporter/teleporter_logic.gd" id="2_2wkov"]

[node name="Teleporter" type="Area2D" unique_id=1779636661]
editor_description = "The player entering this area triggers either a scene switch to \"Next Scene\", or teleports the player within the current scene.

Add a collision shape, and set the destination."
collision_layer = 4
script = ExtResource("1_2wkov")

[node name="TeleporterLogic" type="Node" parent="." unique_id=713140263 node_paths=PackedStringArray("teleport_area", "scene_link")]
script = ExtResource("2_2wkov")
teleport_area = NodePath("..")
scene_link = NodePath("..")
36 changes: 36 additions & 0 deletions scenes/game_elements/props/teleporter/teleporter_logic.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
extends Node
# The Teleporter component needs to be an Area2D so that collision shapes can be
# added as children in each scene using it. But it also needs to be a SceneLink,
# which does not extend Area2D.
#
# In GDScript, if you have a node of type U (e.g. Area2D) which extends T (e.g.
# Node2D), you can attach a script which extends T (in this case SceneLink) to
# it. So then the only missing piece is to connect the Area2D's signals to the
# SceneLink.switch() method, and that's where this script comes in.
#
# If Godot supported traits, or re-exported properties of child nodes, we
# wouldn't need this weird workaround.

@export var teleport_area: Area2D
@export var scene_link: SceneLink


func _connect() -> void:
# ONE_SHOT to avoid triggering the same teleporter while the transition is running.
# DEFERRED because otherwise if use_transition is false, switching scene
# would delete Area2D during a physics callback - bad!
var flags := CONNECT_ONE_SHOT | CONNECT_DEFERRED
teleport_area.body_entered.connect(_on_teleport_area_body_entered, flags)


func _on_teleport_area_body_entered(_body: Node2D) -> void:
await scene_link.switch()
if not scene_link.next_scene:
# We didn't change scene - re-enable the teleporter
_connect()


func _ready() -> void:
_connect()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://0gr6vi3gxhcp
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
@tool
class_name Teleporter
extends Area2D
class_name SceneLink
extends Node2D
## Represents a potential transition to another scene.
##
## This can be used directly, but acts primarily a base class for other
## components: [Cinematic], [CollectibleItem], and the Teleporter scene.

const SPAWN_POINT_GROUP_NAME: String = "spawn_point"

Expand All @@ -13,7 +17,6 @@ const SPAWN_POINT_GROUP_NAME: String = "spawn_point"
set(new_value):
next_scene = new_value
_update_available_spawn_points()
notify_property_list_changed()

## Which SpawnPoint in [member next_scene] the player character should start at;
## or blank/NONE to start at the default position in the scene.
Expand All @@ -23,46 +26,38 @@ const SPAWN_POINT_GROUP_NAME: String = "spawn_point"
spawn_point_path = ^""
else:
spawn_point_path = new_val
update_configuration_warnings()

@export_group("Transition")

## Whether to use a visual transition effect when the player enters the teleporter.
## Whether to use a visual transition effect when switching to the target scene.
@export var use_transition: bool = true:
set(new_val):
use_transition = new_val
notify_property_list_changed()

## Transition to use when the player enters this teleport.
@export var enter_transition: Transition.Effect = Transition.Effect.LEFT_TO_RIGHT_WIPE
## Transition to use at the start of the switch to [member next_scene].
@export var enter_transition: Transition.Effect = Transition.Effect.FADE

## Transition to use when the player leaves this teleport.
@export var exit_transition: Transition.Effect = Transition.Effect.RIGHT_TO_LEFT_WIPE
## Transition to use at the end of the switch to [member next_scene].
@export var exit_transition: Transition.Effect = Transition.Effect.FADE

var _available_spawn_points: Array[NodePath] = []


func _ready() -> void:
collision_layer = 0
collision_mask = 0
set_collision_layer_value(3, true)
set_collision_mask_value(1, true)

if Engine.is_editor_hint():
_update_available_spawn_points()
notify_property_list_changed()
return

self.body_entered.connect(_on_body_entered, CONNECT_ONE_SHOT)


func _on_body_entered(_body: PhysicsBody2D) -> void:
## Trigger the scene-switch or teleport described by [member next_scene] and
## [member spawn_point_path], with the configured transition.
func switch() -> void:
var next_scene_path := _get_next_scene_path()
if next_scene_path and next_scene_path != get_tree().current_scene.scene_file_path:
# We are using call_deferred here because removing nodes with
# collisions during a callback caused by a collision might cause
# undesired behavior.
if use_transition:
SceneSwitcher.change_to_file_with_transition.call_deferred(
SceneSwitcher.change_to_file_with_transition(
next_scene, spawn_point_path, enter_transition, exit_transition
)
else:
Expand All @@ -72,7 +67,7 @@ func _on_body_entered(_body: PhysicsBody2D) -> void:

if is_instance_valid(spawn_point):
if use_transition:
Transitions.do_transition(
await Transitions.do_transition(
self._teleport_to_spawn_point.bind(spawn_point),
enter_transition,
exit_transition
Expand All @@ -83,7 +78,6 @@ func _on_body_entered(_body: PhysicsBody2D) -> void:

func _teleport_to_spawn_point(spawn_point: SpawnPoint) -> void:
spawn_point.move_player_to_self_position(true)
self.body_entered.connect(_on_body_entered, CONNECT_ONE_SHOT)


func _get_next_scene_path() -> String:
Expand Down Expand Up @@ -119,6 +113,9 @@ func _update_available_spawn_points() -> void:

_available_spawn_points = paths

notify_property_list_changed()
update_configuration_warnings()


func _validate_property(property: Dictionary) -> void:
match property.name:
Expand All @@ -132,3 +129,10 @@ func _validate_property(property: Dictionary) -> void:
"exit_transition":
if not use_transition:
property.usage |= PROPERTY_USAGE_READ_ONLY


func _get_configuration_warnings() -> PackedStringArray:
var warnings: PackedStringArray
if spawn_point_path and spawn_point_path not in _available_spawn_points:
warnings.append("Spawn point '%s' does not exist" % [spawn_point_path])
return warnings
1 change: 1 addition & 0 deletions scenes/globals/scene_switcher/scene_link.gd.uid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://d2vp62mjrf6gn
8 changes: 4 additions & 4 deletions scenes/globals/scene_switcher/scene_switcher.gd
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func _on_hash_changed(args: Array) -> void:
func change_to_file_with_transition(
scene_path: String,
spawn_point: NodePath = ^"",
enter_transition: Transition.Effect = Transition.Effect.RIGHT_TO_LEFT_WIPE,
enter_transition: Transition.Effect = Transition.Effect.LEFT_TO_RIGHT_WIPE,
exit_transition: Transition.Effect = Transition.Effect.LEFT_TO_RIGHT_WIPE
) -> void:
assert(scene_path != "")
Expand All @@ -124,7 +124,7 @@ func change_to_file_with_transition(
func change_to_packed_with_transition(
scene: PackedScene,
spawn_point: NodePath = ^"",
enter_transition: Transition.Effect = Transition.Effect.RIGHT_TO_LEFT_WIPE,
enter_transition: Transition.Effect = Transition.Effect.LEFT_TO_RIGHT_WIPE,
exit_transition: Transition.Effect = Transition.Effect.LEFT_TO_RIGHT_WIPE
) -> void:
assert(scene != null)
Expand All @@ -135,8 +135,8 @@ func change_to_packed_with_transition(


func reload_with_transition(
enter_transition: Transition.Effect = Transition.Effect.RIGHT_TO_LEFT_WIPE,
exit_transition: Transition.Effect = Transition.Effect.LEFT_TO_RIGHT_WIPE
enter_transition: Transition.Effect = Transition.Effect.FADE,
exit_transition: Transition.Effect = Transition.Effect.FADE,
) -> void:
Transitions.do_transition(get_tree().reload_current_scene, enter_transition, exit_transition)

Expand Down
Loading
Loading