From 92f220e20895b596a854761bc93eb824f7559165 Mon Sep 17 00:00:00 2001 From: Jonas Reith Date: Wed, 26 Aug 2026 21:05:38 +0200 Subject: [PATCH] Populate the first region: 6 placeholder POIs + gated center portal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit poi.tscn now uses the checkerboard debug texture instead of the ruins sprite, and poi.gd gained a marker_color export (multiplied into the existing visited/undiscovered dimming) so each POI marker can be tinted a distinct color. Six instances placed inside region k=0's wedge (angle ~12-48°, radius ~18-38, clear of the border walls), tagged with the "region1_pois" group, in red/orange/yellow/green/ blue/purple. Simplified InteractionManager's "Erkunden" content to a plain placeholder ("Das wurde besucht.") instead of the old random animal-track flavor text, and removed the now-dead handle_explore() submenu it drove. Added InteractionManager.open_message() for POIs that need an info popup without the explore/rest/close menu. New poi_gate.gd/.tscn: a portal placed near region k=0's table-edge border. Checks whether every POI in "region1_pois" has been visited; if not, shows a "not yet" message, otherwise teleports the player to target_position (the center) — a one-way shortcut past the border wall rather than an opening in it, matching the "explore everything, then unlock the way onward" progression the user described (this pattern will repeat per outer region later). Verified headless: all 6 POIs register in the group with correct names/colors, gate refuses the transition at 0/6 and 5/6 visited and allows it at 6/6, and the teleport lands the player exactly on target_position. --- interaction_manager.gd | 35 +++++++------------------ interaction_ui.gd | 6 +---- main.tscn | 36 ++++++++++++++++++++++++++ poi.gd | 8 +++--- poi.tscn | 8 ++---- poi_gate.gd | 59 ++++++++++++++++++++++++++++++++++++++++++ poi_gate.gd.uid | 1 + poi_gate.tscn | 51 ++++++++++++++++++++++++++++++++++++ 8 files changed, 163 insertions(+), 41 deletions(-) create mode 100644 poi_gate.gd create mode 100644 poi_gate.gd.uid create mode 100644 poi_gate.tscn diff --git a/interaction_manager.gd b/interaction_manager.gd index ff7a495..29153ef 100755 --- a/interaction_manager.gd +++ b/interaction_manager.gd @@ -21,37 +21,20 @@ func _get_main_options() -> Array: func handle_selection(action: String) -> void: match action: "explore": - InteractionUI.show_menu("Erkunden", _get_explore_options()) + # Platzhalter, bis echte Erkunden-Events pro POI existieren + InteractionUI.show_text("Das wurde besucht.") "rest": InteractionUI.show_text("Du rastest eine Weile...\nDu fühlst dich erholt.") "close": close() -func handle_explore(action: String) -> void: - match action: - "track_follow": - var success = randf() > 0.5 - if success: - InteractionUI.show_text("Du folgst den Spuren...\nEine seltene Tierbeobachtung!") - else: - InteractionUI.show_text("Du folgst den Spuren...\nDas Tier ist verschwunden.") - "track_leave": - close() - -func _get_explore_options() -> Array: - # Zufälliges Ereignis beim Erkunden - var roll = randf() - if roll < 0.5: - InteractionUI.show_text("Du findest Tierspuren!") - return [ - { "label": "Tier verfolgen", "action": "track_follow" }, - { "label": "In Ruhe lassen", "action": "track_leave" }, - ] - else: - InteractionUI.show_text("Nichts Besonderes zu finden.") - return [ - { "label": "Zurück", "action": "close" }, - ] +# Für POIs außerhalb des generischen Menüs (z.B. Portale): Panel mit reinem +# Info-Text öffnen, ohne die Erkunden/Ausruhen/Beenden-Optionen. +func open_message(poi: Node, title: String, text: String) -> void: + active = true + current_poi = poi + InteractionUI.show_menu(title, []) + InteractionUI.show_text(text) func close() -> void: active = false diff --git a/interaction_ui.gd b/interaction_ui.gd index 535a8a9..9b763b6 100755 --- a/interaction_ui.gd +++ b/interaction_ui.gd @@ -51,11 +51,7 @@ func _clear_options() -> void: child.queue_free() func _on_option_pressed(action: String) -> void: - # Unterscheiden ob wir im Erkunden-Submenu sind - if action in ["track_follow", "track_leave"]: - InteractionManager.handle_explore(action) - else: - InteractionManager.handle_selection(action) + InteractionManager.handle_selection(action) func _input(event: InputEvent) -> void: if not panel.visible: diff --git a/main.tscn b/main.tscn index a4b2d5a..92c8131 100755 --- a/main.tscn +++ b/main.tscn @@ -5,6 +5,7 @@ [ext_resource type="Texture2D" uid="uid://epcqli428yem" path="res://assets/sprites/player/debug_player.png" id="2_h2yge"] [ext_resource type="Script" uid="uid://b0y06y7c0bihj" path="res://camera_rig.gd" id="3_h2yge"] [ext_resource type="PackedScene" uid="uid://be6ufrc3dsjge" path="res://poi.tscn" id="5_lquwl"] +[ext_resource type="PackedScene" path="res://poi_gate.tscn" id="5_gate"] [ext_resource type="PackedScene" uid="uid://dmhs1oy1kh6hi" path="res://assets/models/mountain.glb" id="6_7mycd"] [ext_resource type="PackedScene" uid="uid://gl4qpk4wto1e" path="res://assets/models/mountain2v5.glb" id="7_272bh"] [ext_resource type="PackedScene" uid="uid://be2uq7ixlbv6b" path="res://assets/models/forest.glb" id="8_5vw27"] @@ -205,6 +206,41 @@ far = 500.0 [node name="POI" parent="." unique_id=1770000468 instance=ExtResource("5_lquwl")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0.5, 2) +[node name="Ort1" parent="." instance=ExtResource("5_lquwl") groups=["region1_pois"]] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 24.15, -1.214, 6.47) +poi_name = "Ort 1" +marker_color = Color(1, 0.2, 0.2, 1) + +[node name="Ort2" parent="." instance=ExtResource("5_lquwl") groups=["region1_pois"]] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 17.68, -1.214, 17.68) +poi_name = "Ort 2" +marker_color = Color(1, 0.6, 0.1, 1) + +[node name="Ort3" parent="." instance=ExtResource("5_lquwl") groups=["region1_pois"]] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 37.17, -3.443, 7.9) +poi_name = "Ort 3" +marker_color = Color(1, 0.95, 0.2, 1) + +[node name="Ort4" parent="." instance=ExtResource("5_lquwl") groups=["region1_pois"]] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 25.43, -3.443, 28.24) +poi_name = "Ort 4" +marker_color = Color(0.2, 0.9, 0.3, 1) + +[node name="Ort5" parent="." instance=ExtResource("5_lquwl") groups=["region1_pois"]] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 19.05, -0.7, 11.0) +poi_name = "Ort 5" +marker_color = Color(0.2, 0.5, 1, 1) + +[node name="Ort6" parent="." instance=ExtResource("5_lquwl") groups=["region1_pois"]] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 38.1, -4.471, 22.0) +poi_name = "Ort 6" +marker_color = Color(0.7, 0.3, 0.9, 1) + +[node name="GateToCenter" parent="." instance=ExtResource("5_gate")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.72, 0.157, 8.5) +poi_name = "Tor zur Mitte" +target_position = Vector3(0, 0.5, 0) + [node name="Node3D" type="Node3D" parent="." unique_id=597556846] transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 3.6214647, -0.23645921, 0.47627413) diff --git a/poi.gd b/poi.gd index 33879ca..26896af 100755 --- a/poi.gd +++ b/poi.gd @@ -1,6 +1,7 @@ extends Area3D @export var poi_name: String = "Ruinen" +@export var marker_color: Color = Color.WHITE @onready var sprite: AnimatedSprite3D = $AnimatedSprite3D @onready var name_label: Label3D = $Billboard/NameLabel @@ -19,13 +20,12 @@ func _ready() -> void: func _update_visuals() -> void: if visited: name_label.text = poi_name - # Normale Farbe - sprite.modulate = Color(1.0, 1.0, 1.0, 1.0) + sprite.modulate = marker_color name_label.modulate = Color(1.0, 1.0, 1.0, 1.0) else: name_label.text = "???" - # Ausgegraut - sprite.modulate = Color(0.4, 0.4, 0.4, 1.0) + # Ausgegraut, behält aber die Kennfarbe + sprite.modulate = marker_color * Color(0.4, 0.4, 0.4, 1.0) name_label.modulate = Color(0.6, 0.6, 0.6, 1.0) func _on_body_entered(body: Node3D) -> void: diff --git a/poi.tscn b/poi.tscn index c325cc7..4dfd58e 100755 --- a/poi.tscn +++ b/poi.tscn @@ -1,20 +1,16 @@ [gd_scene format=3 uid="uid://be6ufrc3dsjge"] [ext_resource type="Script" uid="uid://c12tpdqhr2l5" path="res://poi.gd" id="1_gwpk6"] -[ext_resource type="Texture2D" uid="uid://c0u8xjymrfw2x" path="res://assets/sprites/enviroment/Brown-gray_ruins2.png" id="2_yof6k"] +[ext_resource type="Texture2D" uid="uid://c3ajv7vb8c4fb" path="res://assets/debug/checkerboard.png" id="2_yof6k"] [sub_resource type="SphereShape3D" id="SphereShape3D_gwpk6"] radius = 0.8699188 -[sub_resource type="AtlasTexture" id="AtlasTexture_mekjb"] -atlas = ExtResource("2_yof6k") -region = Rect2(0, 0, 80, 80) - [sub_resource type="SpriteFrames" id="SpriteFrames_0surh"] animations = [{ "frames": [{ "duration": 1.0, -"texture": SubResource("AtlasTexture_mekjb") +"texture": ExtResource("2_yof6k") }], "loop": true, "name": &"default", diff --git a/poi_gate.gd b/poi_gate.gd new file mode 100644 index 0000000..8e10aaa --- /dev/null +++ b/poi_gate.gd @@ -0,0 +1,59 @@ +extends Area3D + +@export var poi_name: String = "Tor zur Mitte" +@export var marker_color: Color = Color(1.0, 0.9, 0.4) +@export var required_group: String = "region1_pois" +@export var target_position: Vector3 = Vector3.ZERO + +@onready var sprite: AnimatedSprite3D = $AnimatedSprite3D +@onready var name_label: Label3D = $Billboard/NameLabel +@onready var prompt: Label3D = $Billboard/InteractionPrompt + +var player_nearby: bool = false + +func _ready() -> void: + prompt.visible = false + prompt.text = "[F] Interact" + name_label.text = poi_name + _update_visuals() + body_entered.connect(_on_body_entered) + body_exited.connect(_on_body_exited) + +func _all_required_visited() -> bool: + var pois := get_tree().get_nodes_in_group(required_group) + if pois.is_empty(): + return false + for poi in pois: + if not poi.visited: + return false + return true + +func _update_visuals() -> void: + if _all_required_visited(): + sprite.modulate = marker_color + else: + sprite.modulate = marker_color * Color(0.4, 0.4, 0.4, 1.0) + +func _on_body_entered(body: Node3D) -> void: + if body.is_in_group("player"): + player_nearby = true + prompt.visible = true + _update_visuals() + +func _on_body_exited(body: Node3D) -> void: + if body.is_in_group("player"): + player_nearby = false + prompt.visible = false + +func _input(event: InputEvent) -> void: + if player_nearby and Input.is_action_just_pressed("interact"): + _try_transition() + +func _try_transition() -> void: + if _all_required_visited(): + InteractionManager.open_message(self, poi_name, "Du betrittst die Mitte der Insel.") + var player := get_tree().get_first_node_in_group("player") + if player: + player.global_position = target_position + else: + InteractionManager.open_message(self, poi_name, "Hier geht es noch nicht weiter.\nErst müssen alle sechs Orte dieser Region erkundet sein.") diff --git a/poi_gate.gd.uid b/poi_gate.gd.uid new file mode 100644 index 0000000..f5635b7 --- /dev/null +++ b/poi_gate.gd.uid @@ -0,0 +1 @@ +uid://d34t6agm5pxgt diff --git a/poi_gate.tscn b/poi_gate.tscn new file mode 100644 index 0000000..b927b7f --- /dev/null +++ b/poi_gate.tscn @@ -0,0 +1,51 @@ +[gd_scene format=3] + +[ext_resource type="Script" path="res://poi_gate.gd" id="1_gate"] +[ext_resource type="Texture2D" uid="uid://c3ajv7vb8c4fb" path="res://assets/debug/checkerboard.png" id="2_gate"] + +[sub_resource type="SphereShape3D" id="SphereShape3D_gate"] +radius = 0.8699188 + +[sub_resource type="SpriteFrames" id="SpriteFrames_gate"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": ExtResource("2_gate") +}], +"loop": true, +"name": &"default", +"speed": 5.0 +}] + +[sub_resource type="BoxShape3D" id="BoxShape3D_gate"] +size = Vector3(0.8, 2.132, 2.333828) + +[node name="POIGate" type="Area3D"] +script = ExtResource("1_gate") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.6096671) +shape = SubResource("SphereShape3D_gate") + +[node name="AnimatedSprite3D" type="AnimatedSprite3D" parent="."] +sprite_frames = SubResource("SpriteFrames_gate") + +[node name="StaticBody3D" type="StaticBody3D" parent="."] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D"] +transform = Transform3D(0.6, 0, 0, 0, 0.6, 0, 0, 0, 0.6, 0, 0, -0.69380605) +shape = SubResource("BoxShape3D_gate") + +[node name="Billboard" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) + +[node name="NameLabel" type="Label3D" parent="Billboard"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0) +billboard = 1 +text = "Tor zur Mitte" +font_size = 16 + +[node name="InteractionPrompt" type="Label3D" parent="Billboard"] +visible = false +billboard = 1 +font_size = 12