Skip to content
Merged
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

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extends Node2D
var is_interacting: bool:
get = _get_is_interacting

@onready var interact_zone: Area2D = %InteractZone
@onready var character_sight: CharacterSight = %CharacterSight
@onready var interact_marker: Marker2D = %InteractMarker
@onready var interact_label: FixedSizeLabel = %InteractLabel

Expand All @@ -26,7 +26,7 @@ func _set_character(new_character: CharacterBody2D) -> void:


func _get_is_interacting() -> bool:
return not interact_zone.monitoring
return not character_sight.monitoring


func _get_configuration_warnings() -> PackedStringArray:
Expand All @@ -36,39 +36,50 @@ func _get_configuration_warnings() -> PackedStringArray:
return warnings


func _ready() -> void:
character_sight.interact_area_changed.connect(_on_character_sight_interact_area_changed)
_on_character_sight_interact_area_changed()


func _process(_delta: float) -> void:
if is_interacting:
if not character_sight.interact_area:
return

var interact_area: InteractArea = interact_zone.get_interact_area()
if not interact_area:
interact_label.visible = false
else:
interact_label.visible = true
interact_label.label_text = interact_area.action
interact_marker.global_position = interact_area.get_global_interact_label_position()
interact_marker.global_position = (
character_sight.interact_area.get_global_interact_label_position()
)


func _unhandled_input(_event: InputEvent) -> void:
if is_interacting:
return

var interact_area: InteractArea = interact_zone.get_interact_area()
var interact_area := character_sight.interact_area
if interact_area and Input.is_action_just_pressed(&"interact"):
# While interacting, this class takes control over the player movement.
if character.has_method("take_control"):
character.take_control(self)
character.velocity = Vector2.ZERO

get_viewport().set_input_as_handled()
interact_zone.monitoring = false
character_sight.monitoring = false
interact_label.visible = false
interact_area.interaction_ended.connect(_on_interaction_ended, CONNECT_ONE_SHOT)
interact_area.start_interaction(player, interact_zone.is_looking_from_right)
interact_area.start_interaction(player, character_sight.is_looking_from_right)


func _on_interaction_ended() -> void:
interact_zone.monitoring = true
character_sight.monitoring = true
# After interacting, return control to the user.
if character.has_method("return_control"):
character.return_control(self)


func _on_character_sight_interact_area_changed() -> void:
if is_interacting:
return

if not character_sight.interact_area:
interact_label.visible = false
else:
interact_label.visible = true
interact_label.label_text = character_sight.interact_area.action
6 changes: 3 additions & 3 deletions scenes/game_elements/characters/player/player.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[ext_resource type="Script" uid="uid://bpu6jo4kvehlg" path="res://scenes/game_elements/characters/player/components/player_interaction.gd" id="3_dqkch"]
[ext_resource type="Script" uid="uid://ciw2w16c38ewq" path="res://scenes/game_elements/characters/player/components/player_dust_particles.gd" id="3_j0tly"]
[ext_resource type="Script" uid="uid://qro4uo83ba8f" path="res://scenes/game_elements/characters/player/components/player_sprite.gd" id="3_qlg0r"]
[ext_resource type="Script" uid="uid://necvar42rnih" path="res://scenes/game_elements/characters/player/components/interact_zone.gd" id="6_3in67"]
[ext_resource type="Script" uid="uid://necvar42rnih" path="res://scenes/game_elements/props/character_sight/character_sight.gd" id="6_3in67"]
[ext_resource type="PackedScene" uid="uid://yfpfno276rol" path="res://scenes/game_elements/props/fixed_size_label/fixed_size_label.tscn" id="6_h17s1"]
[ext_resource type="Script" uid="uid://e78f8iq448e1" path="res://scenes/game_elements/characters/player/components/animation_player.gd" id="7_0owmy"]
[ext_resource type="Script" uid="uid://kni2yl26matc" path="res://scenes/game_elements/characters/player/components/player_repel.gd" id="7_5gtgg"]
Expand Down Expand Up @@ -583,14 +583,14 @@ unique_name_in_owner = true
script = ExtResource("3_dqkch")
character = NodePath("..")

[node name="InteractZone" type="Area2D" parent="PlayerInteraction" unique_id=888605377 node_paths=PackedStringArray("character")]
[node name="CharacterSight" type="Area2D" parent="PlayerInteraction" unique_id=888605377 node_paths=PackedStringArray("character")]
unique_name_in_owner = true
collision_layer = 0
collision_mask = 32
script = ExtResource("6_3in67")
character = NodePath("../..")

[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerInteraction/InteractZone" unique_id=255765935]
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerInteraction/CharacterSight" unique_id=255765935]
position = Vector2(47, -30)
shape = SubResource("RectangleShape2D_blfj0")
debug_color = Color(0.600391, 0.54335, 0, 0.42)
Expand Down
76 changes: 76 additions & 0 deletions scenes/game_elements/props/character_sight/character_sight.gd
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a bit weird for this to live in props rather than player.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I did it to match interact_area. But also this can potentially be attached to a CharacterBody2D NPC.
Maybe I move it to scenes/game_logic/ ?

Copy link
Copy Markdown
Member

@wjt wjt Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could work. Honestly I think it's also quite strange that this script (not a scene) lives in scenes/, like many many others (e.g. area_filler.gd) but I can't bring myself to propose rearranging all the folders in the project again :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't feel the need to address this now, it's just a path, we can change it later. I was just observing that it seems a bit strange

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes the whole structure is strange to me as well!

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
class_name CharacterSight
extends Area2D
## The area of sight of the character.
##
## The character sees one [InteractArea] at a time to interact.
## This area also faces toward the character current direction.
## [br][br]
## This script automatically configures the correct [member collision_layer] and
## [member collision_mask] values to enable interaction with the player.

## Emitted when [member interact_area] changes.
signal interact_area_changed

## The character.
@export var character: CharacterBody2D

## The direction the character is facing.
## [br][br]
## TODO: Use east/west instead of right/left?
var is_looking_from_right: bool = false

## The area that the character is currently observing.
var interact_area: InteractArea


func _ready() -> void:
if not character and owner is CharacterBody2D:
character = owner
collision_layer = 0
collision_mask = 0
set_collision_mask_value(Enums.CollisionLayers.INTERACTABLE, true)
area_entered.connect(_on_area_entered)
area_exited.connect(_on_area_exited)


func _get_best_interact_area() -> InteractArea:
if not monitoring:
return null
var areas := get_overlapping_areas()
var best: InteractArea = null
var best_distance: float = INF

# TODO: This picks the closest area according to their global position,
# which could be misleading. An Area2D may have a collision shape
# that is far away from it's anchor.
for area in areas:
var distance := global_position.distance_to(area.global_position)
if not best or distance < best_distance:
best_distance = distance
best = area

return best


func _process(_delta: float) -> void:
if not character:
return
# Flip this area according to the character current direction:
if not is_zero_approx(character.velocity.x):
if character.velocity.x < 0:
scale.x = -1
else:
scale.x = 1
is_looking_from_right = scale.x < 0


func _on_area_entered(_area: Area2D) -> void:
interact_area = _get_best_interact_area()
interact_area_changed.emit()


func _on_area_exited(_area: Area2D) -> void:
interact_area = _get_best_interact_area()
interact_area_changed.emit()
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ extends Area2D
##
## To make an interactable object, add an [InteractArea] to it, and handle
## [signal interaction_started]. When the interaction is complete, call [method
## end_interaction]. This area is detected by the player scene's [InteractZone];
## end_interaction]. This area is detected by character's [CharacterSight];
## the player scene is typically responsible for calling [method
## start_interaction] in response to player input.
## [br][br]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[gd_scene format=4 uid="uid://g64l65moc1sx"]

[ext_resource type="TileSet" uid="uid://4ewcvb1sibsf" path="res://scenes/quests/story_quests/after_the_tremor/3_combat/2_cinematicacombate/tile/tilestaller.tres" id="1_8drhf"]
[ext_resource type="Script" uid="uid://pk3ucq7e2eah" path="res://scenes/game_logic/player_mode.gd" id="1_pm0tv"]
[ext_resource type="Shader" uid="uid://dmm7vum4u3k5e" path="res://scenes/quests/story_quests/after_the_tremor/0_intro/0_intro_part6/night.gdshader" id="2_ps5ij"]
[ext_resource type="Script" uid="uid://x1mxt6bmei2o" path="res://scenes/ui_elements/cinematic/cinematic.gd" id="3_a1j0i"]
[ext_resource type="Resource" uid="uid://x8dfau2t48gw" path="res://scenes/quests/story_quests/after_the_tremor/2_sequence_puzzle/2_tallerjuego/dialogojuego2.dialogue" id="4_ilpog"]
Expand All @@ -25,7 +26,6 @@
[ext_resource type="Script" uid="uid://cs3mackqqsjmr" path="res://scenes/quests/story_quests/after_the_tremor/2_sequence_puzzle/2_tallerjuego/reveal_tilemap.gd" id="23_ea4l7"]
[ext_resource type="AudioStream" uid="uid://buxupti22mp4y" path="res://scenes/quests/story_quests/after_the_tremor/music/minijuego2.ogg" id="24_8drhf"]
[ext_resource type="Script" uid="uid://d31cxd03praji" path="res://scenes/quests/story_quests/after_the_tremor/3_combat/scripts/MusicFix.gd" id="25_ls33p"]
[ext_resource type="Script" uid="uid://pk3ucq7e2eah" path="res://scenes/game_logic/player_mode.gd" id="1_pm0tv"]

[sub_resource type="ShaderMaterial" id="ShaderMaterial_famss"]
shader = ExtResource("2_ps5ij")
Expand Down Expand Up @@ -105,7 +105,7 @@ sprite_frames = ExtResource("9_cbqvq")
position = Vector2(-2.6667075, -73.333336)
sprite_frames = ExtResource("9_cbqvq")

[node name="CollisionShape2D" parent="Player/PlayerInteraction/InteractZone" parent_id_path=PackedInt32Array(894731746, 888605377) index="0" unique_id=255765935]
[node name="CollisionShape2D" parent="Player/PlayerInteraction/CharacterSight" parent_id_path=PackedInt32Array(894731746, 888605377) index="0" unique_id=255765935]
position = Vector2(53.333294, -73.333336)

[node name="Camera2D" type="Camera2D" parent="Player" unique_id=1018623546]
Expand Down
10 changes: 6 additions & 4 deletions scenes/quests/story_quests/champ/3_stealth/champ_stealth.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
[ext_resource type="Texture2D" uid="uid://c1vlj61hnl1dx" path="res://scenes/quests/story_quests/champ/tiles/assets/shore_and_lake_tiles.png" id="15_wbd51"]
[ext_resource type="Texture2D" uid="uid://cexg7otw5enpu" path="res://assets/third_party/tiny-swords/Terrain/Water/Foam/Foam.png" id="16_40h7x"]
[ext_resource type="Script" uid="uid://dwd8vjl5h6nxy" path="res://scenes/quests/story_quests/champ/3_stealth/champ_incomplete_character.gd" id="16_fw64s"]
[ext_resource type="Script" uid="uid://necvar42rnih" path="res://scenes/game_elements/characters/player/components/interact_zone.gd" id="16_g11k1"]
[ext_resource type="Script" uid="uid://necvar42rnih" path="res://scenes/game_elements/props/character_sight/character_sight.gd" id="16_g11k1"]
[ext_resource type="PackedScene" uid="uid://ipvcfv2g0oi1" path="res://scenes/game_elements/characters/npcs/talker/talker.tscn" id="16_ol5cv"]
[ext_resource type="Resource" uid="uid://c3yuq52k21sga" path="res://scenes/quests/story_quests/champ/3_stealth/stealth_components/champ_incomplete_stealth_guard_path_hint.dialogue" id="17_8qkne"]
[ext_resource type="Texture2D" uid="uid://cnmmh3uq7rkla" path="res://assets/third_party/tiny-swords/Terrain/Bridge/Bridge_All.png" id="17_g2bud"]
Expand Down Expand Up @@ -1825,17 +1825,19 @@ limit_bottom = 9999999
position_smoothing_enabled = true
editor_draw_limits = true

[node name="PlayerInteraction" type="Node2D" parent="Incomplete Character" unique_id=161308293]
[node name="PlayerInteraction" type="Node2D" parent="Incomplete Character" unique_id=161308293 node_paths=PackedStringArray("character")]
unique_name_in_owner = true
script = ExtResource("15_ecrvd")
character = NodePath("..")

[node name="InteractZone" type="Area2D" parent="Incomplete Character/PlayerInteraction" unique_id=826531250]
[node name="CharacterSight" type="Area2D" parent="Incomplete Character/PlayerInteraction" unique_id=826531250 node_paths=PackedStringArray("character")]
unique_name_in_owner = true
collision_layer = 0
collision_mask = 32
script = ExtResource("16_g11k1")
character = NodePath("../..")

[node name="CollisionShape2D" type="CollisionShape2D" parent="Incomplete Character/PlayerInteraction/InteractZone" unique_id=663814065]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Incomplete Character/PlayerInteraction/CharacterSight" unique_id=663814065]
position = Vector2(167, 5)
shape = SubResource("RectangleShape2D_680ig")
debug_color = Color(0.600391, 0.54335, 0, 0.42)
Expand Down
Loading