From adaa9eda9850f89f44b6caf7c53ca4c601650d0b Mon Sep 17 00:00:00 2001 From: "m.cirafisi" Date: Sat, 11 Apr 2026 18:40:28 +0200 Subject: [PATCH] add base system --- core/ai/ai_base/ai_base.gd | 48 +++++++++++ core/ai/ai_base/ai_base.gd.uid | 1 + core/ai/ai_base/ai_base.tscn | 41 ++++++++++ core/ai/ai_base/idle_state.gd | 24 ++++++ core/ai/ai_base/idle_state.gd.uid | 1 + core/ai/ai_base/patrol_state.gd | 10 +++ core/ai/ai_base/patrol_state.gd.uid | 1 + core/ai/ai_base/state.gd | 19 +++++ core/ai/ai_base/state.gd.uid | 1 + core/ai/ai_base/state_machine.gd | 48 +++++++++++ core/ai/ai_base/state_machine.gd.uid | 1 + core/photo_mode/collectible.gd | 6 ++ core/photo_mode/collectible.gd.uid | 1 + core/photo_mode/collectible.tscn | 11 +++ core/photo_mode/collectible_library.gd | 4 + core/photo_mode/collectible_library.gd.uid | 1 + core/photo_mode/collectible_library.tres | 31 +++++++ core/photo_mode/collectible_resource.gd | 6 ++ core/photo_mode/collectible_resource.gd.uid | 1 + core/photo_mode/collectible_ui.gd | 16 ++++ core/photo_mode/collectible_ui.gd.uid | 1 + core/photo_mode/collectible_ui.tscn | 47 +++++++++++ core/photo_mode/collection_compendium.gd | 28 +++++++ core/photo_mode/collection_compendium.gd.uid | 1 + core/photo_mode/collection_compendium.tscn | 47 +++++++++++ core/photo_mode/collection_manager.gd | 26 ++++++ core/photo_mode/collection_manager.gd.uid | 1 + core/photo_mode/photo_mode_controller.gd | 82 +++++++++++++++++++ core/photo_mode/photo_mode_controller.gd.uid | 1 + core/photo_mode/photo_mode_controller.tscn | 8 ++ docs/museums/ai/museum_ai.tscn | 54 ++++++++++++ docs/museums/photo_mode/museum_photo_mode.gd | 6 ++ .../photo_mode/museum_photo_mode.gd.uid | 1 + .../museums/photo_mode/museum_photo_mode.tscn | 80 ++++++++++++++++++ project.godot | 34 ++++++++ 35 files changed, 689 insertions(+) create mode 100644 core/ai/ai_base/ai_base.gd create mode 100644 core/ai/ai_base/ai_base.gd.uid create mode 100644 core/ai/ai_base/ai_base.tscn create mode 100644 core/ai/ai_base/idle_state.gd create mode 100644 core/ai/ai_base/idle_state.gd.uid create mode 100644 core/ai/ai_base/patrol_state.gd create mode 100644 core/ai/ai_base/patrol_state.gd.uid create mode 100644 core/ai/ai_base/state.gd create mode 100644 core/ai/ai_base/state.gd.uid create mode 100644 core/ai/ai_base/state_machine.gd create mode 100644 core/ai/ai_base/state_machine.gd.uid create mode 100644 core/photo_mode/collectible.gd create mode 100644 core/photo_mode/collectible.gd.uid create mode 100644 core/photo_mode/collectible.tscn create mode 100644 core/photo_mode/collectible_library.gd create mode 100644 core/photo_mode/collectible_library.gd.uid create mode 100644 core/photo_mode/collectible_library.tres create mode 100644 core/photo_mode/collectible_resource.gd create mode 100644 core/photo_mode/collectible_resource.gd.uid create mode 100644 core/photo_mode/collectible_ui.gd create mode 100644 core/photo_mode/collectible_ui.gd.uid create mode 100644 core/photo_mode/collectible_ui.tscn create mode 100644 core/photo_mode/collection_compendium.gd create mode 100644 core/photo_mode/collection_compendium.gd.uid create mode 100644 core/photo_mode/collection_compendium.tscn create mode 100644 core/photo_mode/collection_manager.gd create mode 100644 core/photo_mode/collection_manager.gd.uid create mode 100644 core/photo_mode/photo_mode_controller.gd create mode 100644 core/photo_mode/photo_mode_controller.gd.uid create mode 100644 core/photo_mode/photo_mode_controller.tscn create mode 100644 docs/museums/ai/museum_ai.tscn create mode 100644 docs/museums/photo_mode/museum_photo_mode.gd create mode 100644 docs/museums/photo_mode/museum_photo_mode.gd.uid create mode 100644 docs/museums/photo_mode/museum_photo_mode.tscn diff --git a/core/ai/ai_base/ai_base.gd b/core/ai/ai_base/ai_base.gd new file mode 100644 index 0000000..1d31c7a --- /dev/null +++ b/core/ai/ai_base/ai_base.gd @@ -0,0 +1,48 @@ +extends CharacterBody3D + +class_name AIBase + +@export var speed: float = 4.0 +@export var enable_state_machine: bool = true: + set(value): + enable_state_machine = value + toggle_enable_state_machine() + + +@onready var patrol_radius_shape: CollisionShape3D = $PatrolRadiusShape +@onready var nav_agent: NavigationAgent3D = $NavigationAgent3D +@onready var state_machine: StateMachine = $StateMachine + + +func _ready() -> void: + randomize() + toggle_enable_state_machine() + +func toggle_enable_state_machine() -> void: + $StateMachine.enable = enable_state_machine + +func _physics_process(delta: float) -> void: + if !enable_state_machine: + return + + state_machine.physics_process(delta) + + if nav_agent.is_navigation_finished(): + velocity = Vector3.ZERO + move_and_slide() + return + + var next_point = nav_agent.get_next_path_position() + var direction = global_position.direction_to(next_point) + + velocity.x = direction.x * speed + velocity.z = direction.z * speed + + move_and_slide() + +func navigate_to_random_point() -> void: + var nav_map_rid = get_world_3d().get_navigation_map() + var patrol_radius = patrol_radius_shape.shape.radius + var target_point_in_space = global_position + Vector3(randf_range(-1, 1), 0, randf_range(-1, 1)).normalized() * randf_range(0, patrol_radius) + var closest_valid_point = NavigationServer3D.map_get_closest_point(nav_map_rid, target_point_in_space) + nav_agent.target_position = closest_valid_point diff --git a/core/ai/ai_base/ai_base.gd.uid b/core/ai/ai_base/ai_base.gd.uid new file mode 100644 index 0000000..ea72f6d --- /dev/null +++ b/core/ai/ai_base/ai_base.gd.uid @@ -0,0 +1 @@ +uid://b30p1yqojbbbk diff --git a/core/ai/ai_base/ai_base.tscn b/core/ai/ai_base/ai_base.tscn new file mode 100644 index 0000000..74e83b1 --- /dev/null +++ b/core/ai/ai_base/ai_base.tscn @@ -0,0 +1,41 @@ +[gd_scene format=3 uid="uid://clx701xdwelgx"] + +[ext_resource type="Script" uid="uid://b30p1yqojbbbk" path="res://core/ai/ai_base/ai_base.gd" id="1_4d1nn"] +[ext_resource type="Script" uid="uid://ps3vlu2qvmop" path="res://core/ai/ai_base/state_machine.gd" id="2_q1hg3"] +[ext_resource type="Script" uid="uid://nga8qx56iwgu" path="res://core/ai/ai_base/idle_state.gd" id="3_26faq"] +[ext_resource type="Script" uid="uid://bngfthvt04ivv" path="res://core/ai/ai_base/patrol_state.gd" id="4_lim44"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_mh3lg"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_mh3lg"] + +[sub_resource type="SphereShape3D" id="SphereShape3D_lim44"] +radius = 20.0 + +[node name="AiBase" type="CharacterBody3D" unique_id=1228675528] +script = ExtResource("1_4d1nn") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=214482161] +mesh = SubResource("CapsuleMesh_mh3lg") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=92811823] +shape = SubResource("CapsuleShape3D_mh3lg") + +[node name="NavigationAgent3D" type="NavigationAgent3D" parent="." unique_id=1370024449] + +[node name="StateMachine" type="Node" parent="." unique_id=1286404264 node_paths=PackedStringArray("initial_state")] +script = ExtResource("2_q1hg3") +initial_state = NodePath("IdleState") + +[node name="IdleState" type="Node" parent="StateMachine" unique_id=763668255] +script = ExtResource("3_26faq") +state_id = "idle" + +[node name="PatrolState" type="Node" parent="StateMachine" unique_id=2054606629] +script = ExtResource("4_lim44") +state_id = "patrol" + +[node name="PatrolRadiusShape" type="CollisionShape3D" parent="." unique_id=1379515938] +shape = SubResource("SphereShape3D_lim44") +disabled = true +debug_color = Color(1, 1, 0, 1) diff --git a/core/ai/ai_base/idle_state.gd b/core/ai/ai_base/idle_state.gd new file mode 100644 index 0000000..fb9d45e --- /dev/null +++ b/core/ai/ai_base/idle_state.gd @@ -0,0 +1,24 @@ +extends State + +@export var wait_time: float = 3.0 + +var runtime_timer: Timer + +func enter() -> void: + runtime_timer = Timer.new() + runtime_timer.name = "IdleTimer" + add_child(runtime_timer) + runtime_timer.one_shot = true + runtime_timer.timeout.connect(_on_timer_timeout) + runtime_timer.start(wait_time) + +func exit() -> void: + if runtime_timer: + if runtime_timer.is_connected("timeout", _on_timer_timeout): + runtime_timer.timeout.disconnect(_on_timer_timeout) + + runtime_timer.queue_free() + runtime_timer = null + +func _on_timer_timeout() -> void: + transitioned.emit(self, "patrol") diff --git a/core/ai/ai_base/idle_state.gd.uid b/core/ai/ai_base/idle_state.gd.uid new file mode 100644 index 0000000..41fe475 --- /dev/null +++ b/core/ai/ai_base/idle_state.gd.uid @@ -0,0 +1 @@ +uid://nga8qx56iwgu diff --git a/core/ai/ai_base/patrol_state.gd b/core/ai/ai_base/patrol_state.gd new file mode 100644 index 0000000..9db0692 --- /dev/null +++ b/core/ai/ai_base/patrol_state.gd @@ -0,0 +1,10 @@ +extends State + +@onready var agent: AIBase = owner + +func enter() -> void: + agent.navigate_to_random_point() + +func update(_delta) -> void: + if agent.nav_agent.is_navigation_finished(): + transitioned.emit(self, "idle") diff --git a/core/ai/ai_base/patrol_state.gd.uid b/core/ai/ai_base/patrol_state.gd.uid new file mode 100644 index 0000000..4bdcccd --- /dev/null +++ b/core/ai/ai_base/patrol_state.gd.uid @@ -0,0 +1 @@ +uid://bngfthvt04ivv diff --git a/core/ai/ai_base/state.gd b/core/ai/ai_base/state.gd new file mode 100644 index 0000000..2e781f7 --- /dev/null +++ b/core/ai/ai_base/state.gd @@ -0,0 +1,19 @@ +extends Node + +class_name State + +@export var state_id: String = "" + +signal transitioned(state, new_state_name) + +func enter() -> void: + pass + +func exit() -> void: + pass + +func update(_delta) -> void: + pass + +func physics_update(_delta) -> void: + pass diff --git a/core/ai/ai_base/state.gd.uid b/core/ai/ai_base/state.gd.uid new file mode 100644 index 0000000..7f2faac --- /dev/null +++ b/core/ai/ai_base/state.gd.uid @@ -0,0 +1 @@ +uid://dpso7abi5ftyw diff --git a/core/ai/ai_base/state_machine.gd b/core/ai/ai_base/state_machine.gd new file mode 100644 index 0000000..f76456c --- /dev/null +++ b/core/ai/ai_base/state_machine.gd @@ -0,0 +1,48 @@ +extends Node + +class_name StateMachine + +@export var initial_state: State + +var current_state: State +var states: Dictionary = {} +var enable: bool = true: + set(value): + enable = value + toggle_enable() + +func toggle_enable() -> void: + if !enable: + return + + if !states.is_empty(): + return + + for state in get_children(): + if state is State: + states[state.state_id] = state + state.transitioned.connect(_on_state_transition) + + if initial_state: + current_state = initial_state + current_state.enter() + +func physics_process(delta) -> void: + if current_state and enable: + current_state.update(delta) + +func _on_state_transition(state: State, new_state_id: String) -> void: + if state != current_state: + return + + var new_state = states.get(new_state_id) + if not new_state: + return + + if current_state: + current_state.exit() + + current_state = new_state + current_state.enter() + + print("Transizione a: ", current_state.state_id) diff --git a/core/ai/ai_base/state_machine.gd.uid b/core/ai/ai_base/state_machine.gd.uid new file mode 100644 index 0000000..fc3d12e --- /dev/null +++ b/core/ai/ai_base/state_machine.gd.uid @@ -0,0 +1 @@ +uid://ps3vlu2qvmop diff --git a/core/photo_mode/collectible.gd b/core/photo_mode/collectible.gd new file mode 100644 index 0000000..08772f7 --- /dev/null +++ b/core/photo_mode/collectible.gd @@ -0,0 +1,6 @@ +extends Area3D + +@export var collectible_data: CollectibleResource + +func _ready() -> void: + add_to_group("collectible") diff --git a/core/photo_mode/collectible.gd.uid b/core/photo_mode/collectible.gd.uid new file mode 100644 index 0000000..3f51b53 --- /dev/null +++ b/core/photo_mode/collectible.gd.uid @@ -0,0 +1 @@ +uid://62d14boivr3g diff --git a/core/photo_mode/collectible.tscn b/core/photo_mode/collectible.tscn new file mode 100644 index 0000000..f3b8039 --- /dev/null +++ b/core/photo_mode/collectible.tscn @@ -0,0 +1,11 @@ +[gd_scene format=3 uid="uid://bmkxt6btcx8qr"] + +[ext_resource type="Script" uid="uid://62d14boivr3g" path="res://core/photo_mode/collectible.gd" id="1_xse8c"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_xse8c"] + +[node name="Collectible" type="Area3D" unique_id=1229019813] +script = ExtResource("1_xse8c") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1479480920] +shape = SubResource("BoxShape3D_xse8c") diff --git a/core/photo_mode/collectible_library.gd b/core/photo_mode/collectible_library.gd new file mode 100644 index 0000000..7aede1f --- /dev/null +++ b/core/photo_mode/collectible_library.gd @@ -0,0 +1,4 @@ +class_name CollectibleLibrary +extends Resource + +@export var collectibles: Array[CollectibleResource] diff --git a/core/photo_mode/collectible_library.gd.uid b/core/photo_mode/collectible_library.gd.uid new file mode 100644 index 0000000..4a5e341 --- /dev/null +++ b/core/photo_mode/collectible_library.gd.uid @@ -0,0 +1 @@ +uid://hhuufh87skq5 diff --git a/core/photo_mode/collectible_library.tres b/core/photo_mode/collectible_library.tres new file mode 100644 index 0000000..5a8c51c --- /dev/null +++ b/core/photo_mode/collectible_library.tres @@ -0,0 +1,31 @@ +[gd_resource type="Resource" script_class="CollectibleLibrary" format=3 uid="uid://c6pkpvsvimafb"] + +[ext_resource type="Script" uid="uid://bj34o0org55ei" path="res://core/photo_mode/collectible_resource.gd" id="1_3cgvf"] +[ext_resource type="Script" uid="uid://hhuufh87skq5" path="res://core/photo_mode/collectible_library.gd" id="2_ggu10"] +[ext_resource type="Texture2D" uid="uid://cx8d233y32kmu" path="res://icon.svg" id="2_pxmdy"] + +[sub_resource type="Resource" id="Resource_3cgvf"] +script = ExtResource("1_3cgvf") +id = "cane" +title = "Cane" +image = ExtResource("2_pxmdy") +metadata/_custom_type_script = "uid://bj34o0org55ei" + +[sub_resource type="Resource" id="Resource_ggu10"] +script = ExtResource("1_3cgvf") +id = "gatto" +title = "Gatto" +image = ExtResource("2_pxmdy") +metadata/_custom_type_script = "uid://bj34o0org55ei" + +[sub_resource type="Resource" id="Resource_pxmdy"] +script = ExtResource("1_3cgvf") +id = "farfalla" +title = "Farfalla" +image = ExtResource("2_pxmdy") +metadata/_custom_type_script = "uid://bj34o0org55ei" + +[resource] +script = ExtResource("2_ggu10") +collectibles = Array[ExtResource("1_3cgvf")]([SubResource("Resource_3cgvf"), SubResource("Resource_ggu10"), SubResource("Resource_pxmdy")]) +metadata/_custom_type_script = "uid://hhuufh87skq5" diff --git a/core/photo_mode/collectible_resource.gd b/core/photo_mode/collectible_resource.gd new file mode 100644 index 0000000..a25fe96 --- /dev/null +++ b/core/photo_mode/collectible_resource.gd @@ -0,0 +1,6 @@ +class_name CollectibleResource +extends Resource + +@export var id: String +@export var title: String +@export var image: Texture2D diff --git a/core/photo_mode/collectible_resource.gd.uid b/core/photo_mode/collectible_resource.gd.uid new file mode 100644 index 0000000..698ed09 --- /dev/null +++ b/core/photo_mode/collectible_resource.gd.uid @@ -0,0 +1 @@ +uid://bj34o0org55ei diff --git a/core/photo_mode/collectible_ui.gd b/core/photo_mode/collectible_ui.gd new file mode 100644 index 0000000..c6e1176 --- /dev/null +++ b/core/photo_mode/collectible_ui.gd @@ -0,0 +1,16 @@ +extends Control + +class_name CollectibleUI + +@onready var label: Label = $Panel/MarginContainer/VBoxContainer/Label +@onready var texture_rect: TextureRect = $Panel/MarginContainer/VBoxContainer/TextureRect +var collectible_resource: CollectibleResource + +func setup(collectible: CollectibleResource) -> void: + collectible_resource = collectible + $Panel/MarginContainer/VBoxContainer/Label.text = collectible_resource.title + if collectible.image: + $Panel/MarginContainer/VBoxContainer/TextureRect.texture = collectible_resource.image + +func unlock() -> void: + $Panel/MarginContainer/VBoxContainer/TextureRect.set_modulate(Color(1,1,1,1)) diff --git a/core/photo_mode/collectible_ui.gd.uid b/core/photo_mode/collectible_ui.gd.uid new file mode 100644 index 0000000..d9ba065 --- /dev/null +++ b/core/photo_mode/collectible_ui.gd.uid @@ -0,0 +1 @@ +uid://dxh8e1n16qjpp diff --git a/core/photo_mode/collectible_ui.tscn b/core/photo_mode/collectible_ui.tscn new file mode 100644 index 0000000..ed2c1db --- /dev/null +++ b/core/photo_mode/collectible_ui.tscn @@ -0,0 +1,47 @@ +[gd_scene format=3 uid="uid://dp7dvfauh5rpx"] + +[ext_resource type="Script" uid="uid://dxh8e1n16qjpp" path="res://core/photo_mode/collectible_ui.gd" id="1_tu5nx"] +[ext_resource type="Texture2D" uid="uid://cx8d233y32kmu" path="res://icon.svg" id="1_x3wje"] + +[node name="CollectibleUI" type="Control" unique_id=201865221] +custom_minimum_size = Vector2(200, 200) +layout_mode = 3 +anchors_preset = 0 +offset_right = 200.0 +offset_bottom = 200.0 +script = ExtResource("1_tu5nx") + +[node name="Panel" type="PanelContainer" parent="." unique_id=1372516531] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="MarginContainer" type="MarginContainer" parent="Panel" unique_id=1141643525] +layout_mode = 2 +theme_override_constants/margin_left = 12 +theme_override_constants/margin_top = 12 +theme_override_constants/margin_right = 12 +theme_override_constants/margin_bottom = 12 + +[node name="VBoxContainer" type="VBoxContainer" parent="Panel/MarginContainer" unique_id=1841409877] +layout_mode = 2 +alignment = 1 + +[node name="Label" type="Label" parent="Panel/MarginContainer/VBoxContainer" unique_id=117774359] +layout_mode = 2 +size_flags_vertical = 0 +text = "Collectible" +horizontal_alignment = 1 + +[node name="HSeparator" type="HSeparator" parent="Panel/MarginContainer/VBoxContainer" unique_id=1345822244] +layout_mode = 2 + +[node name="TextureRect" type="TextureRect" parent="Panel/MarginContainer/VBoxContainer" unique_id=506844785] +modulate = Color(0.16206557, 0.1620656, 0.16206557, 1) +layout_mode = 2 +size_flags_vertical = 3 +texture = ExtResource("1_x3wje") +stretch_mode = 3 diff --git a/core/photo_mode/collection_compendium.gd b/core/photo_mode/collection_compendium.gd new file mode 100644 index 0000000..1b80ba1 --- /dev/null +++ b/core/photo_mode/collection_compendium.gd @@ -0,0 +1,28 @@ +extends Control + +@onready var grid_container: GridContainer = $PanelContainer/MarginContainer/ScrollContainer/GridContainer +@onready var collectible_ui_scene = preload("res://core/photo_mode/collectible_ui.tscn") + + +func _ready() -> void: + CollectionManager.on_collectible_unlocked.connect(_unlock_collectible) + var unlocked_collectible_ids = CollectionManager.get_unlocked_collectible_ids() + var collectibles = CollectionManager.get_all_collectibles() + for collectible in collectibles: + _add_collectible(collectible) + if unlocked_collectible_ids.has(collectible.id): + _unlock_collectible(collectible.id) + +func on_collectible_unlocked(collectible_id: String) -> void: + _unlock_collectible(collectible_id) + +func _add_collectible(collectible: CollectibleResource) -> void: + var collectible_ui: CollectibleUI = collectible_ui_scene.instantiate() + collectible_ui.setup(collectible) + grid_container.add_child(collectible_ui) + + +func _unlock_collectible(collectible_id: String) -> void: + for collectible_ui in grid_container.get_children(): + if collectible_ui.collectible_resource.id == collectible_id: + collectible_ui.unlock() diff --git a/core/photo_mode/collection_compendium.gd.uid b/core/photo_mode/collection_compendium.gd.uid new file mode 100644 index 0000000..2ec65a4 --- /dev/null +++ b/core/photo_mode/collection_compendium.gd.uid @@ -0,0 +1 @@ +uid://dq3qtcrdnikl7 diff --git a/core/photo_mode/collection_compendium.tscn b/core/photo_mode/collection_compendium.tscn new file mode 100644 index 0000000..7daa1e5 --- /dev/null +++ b/core/photo_mode/collection_compendium.tscn @@ -0,0 +1,47 @@ +[gd_scene format=3 uid="uid://bvw086glfpcba"] + +[ext_resource type="Script" uid="uid://dq3qtcrdnikl7" path="res://core/photo_mode/collection_compendium.gd" id="1_67tug"] + +[node name="CollectionCompendium" type="Control" unique_id=354419843] +layout_mode = 3 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_67tug") + +[node name="PanelContainer" type="PanelContainer" parent="." unique_id=640179265] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -400.0 +offset_top = -400.0 +offset_right = 400.0 +offset_bottom = 400.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="MarginContainer" type="MarginContainer" parent="PanelContainer" unique_id=125147979] +layout_mode = 2 +theme_override_constants/margin_left = 12 +theme_override_constants/margin_top = 12 +theme_override_constants/margin_right = 12 +theme_override_constants/margin_bottom = 12 + +[node name="ScrollContainer" type="ScrollContainer" parent="PanelContainer/MarginContainer" unique_id=348576028] +layout_mode = 2 +draw_focus_border = true + +[node name="GridContainer" type="GridContainer" parent="PanelContainer/MarginContainer/ScrollContainer" unique_id=1187865988] +layout_mode = 2 +size_flags_horizontal = 6 +size_flags_vertical = 2 +theme_override_constants/h_separation = 12 +theme_override_constants/v_separation = 12 +columns = 3 diff --git a/core/photo_mode/collection_manager.gd b/core/photo_mode/collection_manager.gd new file mode 100644 index 0000000..8c310a8 --- /dev/null +++ b/core/photo_mode/collection_manager.gd @@ -0,0 +1,26 @@ +extends Node + +signal on_collectible_unlocked(collectible_id: String) + +#TODO -> assign library resource to game_state +var library: CollectibleLibrary = preload("res://core/photo_mode/collectible_library.tres") +var unlocked_ids: Array[String] = ['cane'] + +func unlock_photo(collectible_id: String) -> void: + if not collectible_id in unlocked_ids: + unlocked_ids.append(collectible_id) + var new_collectible = get_collectible_by_id(collectible_id) + if new_collectible: + on_collectible_unlocked.emit(collectible_id) + +func get_collectible_by_id(id: String) -> CollectibleResource: + for collectible in library.collectibles: + if collectible.id == id: + return collectible + return null + +func get_all_collectibles() -> Array[CollectibleResource]: + return library.collectibles + +func get_unlocked_collectible_ids() -> Array[String]: + return unlocked_ids diff --git a/core/photo_mode/collection_manager.gd.uid b/core/photo_mode/collection_manager.gd.uid new file mode 100644 index 0000000..39979fc --- /dev/null +++ b/core/photo_mode/collection_manager.gd.uid @@ -0,0 +1 @@ +uid://c3kq1qddpm8tf diff --git a/core/photo_mode/photo_mode_controller.gd b/core/photo_mode/photo_mode_controller.gd new file mode 100644 index 0000000..0bf7fef --- /dev/null +++ b/core/photo_mode/photo_mode_controller.gd @@ -0,0 +1,82 @@ +extends Node3D + +@export_group("Speed") +@export var pan_speed: float = 5.0 +@export var rotation_speed: float = 0.003 + +@export_group("Bounds") +@export var movement_bounds: AABB + +@export_group("Ref") +@export var rotation_target: Node3D + +@onready var camera: Camera3D = $Camera3D + +var total_yaw: float = 0.0 +var total_pitch: float = 0.0 +var orbit_distance: float = 0.0 +var current_pan: Vector2 = Vector2.ZERO + +func _ready() -> void: + total_yaw = global_rotation.y + total_pitch = global_rotation.x + + if rotation_target: + orbit_distance = global_position.distance_to(rotation_target.global_position) + +func _unhandled_input(event: InputEvent) -> void: + if event.is_action_pressed("toggle_photo_mode"): + if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) + else: + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + + if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: + total_yaw -= event.relative.x * rotation_speed + + if event.is_action_pressed("take_photo"): + take_photo() + +func _process(delta: float) -> void: + if not rotation_target: + return + + var pan_input = Input.get_vector("photo_pan_left", "photo_pan_right", "photo_pan_up", "photo_pan_down") + var rot_basis = Basis.from_euler(Vector3(total_pitch, total_yaw, 0)) + + if pan_input != Vector2.ZERO: + current_pan.x += pan_input.x * pan_speed * delta + current_pan.y += -pan_input.y * pan_speed * delta + + if movement_bounds.size != Vector3.ZERO: + current_pan.x = clampf(current_pan.x, movement_bounds.position.x, movement_bounds.position.x + movement_bounds.size.x) + current_pan.y = clampf(current_pan.y, movement_bounds.position.y, movement_bounds.position.y + movement_bounds.size.y) + + var right_dir = rot_basis.x.normalized() + var up_dir = rot_basis.y.normalized() + + var final_pan_offset = (right_dir * current_pan.x) + (up_dir * current_pan.y) + + var orbit_pos = rotation_target.global_position + (rot_basis * Vector3(0, 0, orbit_distance)) + + global_position = orbit_pos + final_pan_offset + global_basis = rot_basis + +func take_photo() -> void: + var targets = get_tree().get_nodes_in_group("collectible") + var space_state = get_world_3d().direct_space_state + + for target in targets: + if not target.collectible_data: + continue + + if camera.is_position_in_frustum(target.global_position): + var query = PhysicsRayQueryParameters3D.create(camera.global_position, target.global_position) + query.collide_with_areas = true + query.collide_with_bodies = true + + var result = space_state.intersect_ray(query) + + if result and result.collider == target: + CollectionManager.unlock_photo(target.collectible_data.id) + print("Foto scattata a: ", target.collectible_data.id) diff --git a/core/photo_mode/photo_mode_controller.gd.uid b/core/photo_mode/photo_mode_controller.gd.uid new file mode 100644 index 0000000..aba9819 --- /dev/null +++ b/core/photo_mode/photo_mode_controller.gd.uid @@ -0,0 +1 @@ +uid://d7ln6iru6mq6 diff --git a/core/photo_mode/photo_mode_controller.tscn b/core/photo_mode/photo_mode_controller.tscn new file mode 100644 index 0000000..cb447c6 --- /dev/null +++ b/core/photo_mode/photo_mode_controller.tscn @@ -0,0 +1,8 @@ +[gd_scene format=3 uid="uid://vni5kjalum6d"] + +[ext_resource type="Script" uid="uid://d7ln6iru6mq6" path="res://core/photo_mode/photo_mode_controller.gd" id="1_uhpya"] + +[node name="PhotoModeController" type="Node3D" unique_id=695158870] +script = ExtResource("1_uhpya") + +[node name="Camera3D" type="Camera3D" parent="." unique_id=1369039645] diff --git a/docs/museums/ai/museum_ai.tscn b/docs/museums/ai/museum_ai.tscn new file mode 100644 index 0000000..a22975e --- /dev/null +++ b/docs/museums/ai/museum_ai.tscn @@ -0,0 +1,54 @@ +[gd_scene format=3 uid="uid://dqvrhiqgkd3w1"] + +[ext_resource type="PackedScene" uid="uid://clx701xdwelgx" path="res://core/ai/ai_base/ai_base.tscn" id="1_tvd10"] + +[sub_resource type="NavigationMesh" id="NavigationMesh_optuv"] +vertices = PackedVector3Array(10.984741, 0.25012434, -1.0140381, 11.234741, 0.25012434, 0.23596191, 19.484741, 0.25012434, 0.23596191, 19.484741, 0.25012434, -19.514038, 9.234741, 0.25012434, -1.0140381, -19.515259, 0.25012434, -19.514038, -19.515259, 0.25012434, -0.014038086, 8.984741, 0.25012434, -0.014038086, 10.984741, 0.25012434, 1.2359619, 19.484741, 0.25012434, 19.235962, 9.234741, 0.25012434, 1.2359619, -19.515259, 0.25012434, 19.235962) +polygons = [PackedInt32Array(1, 0, 2), PackedInt32Array(2, 0, 3), PackedInt32Array(6, 5, 4), PackedInt32Array(4, 5, 3), PackedInt32Array(3, 0, 4), PackedInt32Array(4, 7, 6), PackedInt32Array(1, 2, 8), PackedInt32Array(8, 2, 9), PackedInt32Array(6, 10, 11), PackedInt32Array(11, 10, 9), PackedInt32Array(10, 8, 9), PackedInt32Array(6, 7, 10)] + +[sub_resource type="PlaneMesh" id="PlaneMesh_optuv"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_xtjak"] +size = Vector3(1.9942131, 0.09710693, 1.984024) + +[sub_resource type="BoxMesh" id="BoxMesh_lmjyn"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_lmjyn"] + +[sub_resource type="Environment" id="Environment_lmjyn"] + +[node name="MeuseumAI" type="Node3D" unique_id=868339787] + +[node name="NavigationRegion3D" type="NavigationRegion3D" parent="." unique_id=774907858] +navigation_mesh = SubResource("NavigationMesh_optuv") + +[node name="Floor" type="MeshInstance3D" parent="NavigationRegion3D" unique_id=1976415311] +transform = Transform3D(20, 0, 0, 0, 20, 0, 0, 0, 20, 0, -0.83473957, 0) +mesh = SubResource("PlaneMesh_optuv") + +[node name="StaticBody3D" type="StaticBody3D" parent="NavigationRegion3D/Floor" unique_id=2007477719] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="NavigationRegion3D/Floor/StaticBody3D" unique_id=1446628130] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0036563873, -0.009703338, -0.00868988) +shape = SubResource("BoxShape3D_xtjak") + +[node name="Obstacle" type="MeshInstance3D" parent="NavigationRegion3D" unique_id=710701082] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.148018, 0.06508446, 0) +mesh = SubResource("BoxMesh_lmjyn") + +[node name="StaticBody3D" type="StaticBody3D" parent="NavigationRegion3D/Obstacle" unique_id=67152580] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="NavigationRegion3D/Obstacle/StaticBody3D" unique_id=1663742898] +shape = SubResource("BoxShape3D_lmjyn") + +[node name="AIBase" parent="." unique_id=1228675528 instance=ExtResource("1_tvd10")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.48246834, 0.21202153, 0.11262059) + +[node name="Camera3D" type="Camera3D" parent="." unique_id=1148396057] +transform = Transform3D(-2.0613477e-08, 0.8818225, -0.47158146, 3.854569e-08, 0.47158146, 0.8818225, 1, -3.5527137e-15, -4.371139e-08, -18.21907, 28.71355, 0) + +[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1772424900] +environment = SubResource("Environment_lmjyn") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=269230449] +transform = Transform3D(1, 0, 0, 0, 0.17952333, 0.98375374, 0, -0.98375374, 0.17952333, 0, 18.920979, 0) diff --git a/docs/museums/photo_mode/museum_photo_mode.gd b/docs/museums/photo_mode/museum_photo_mode.gd new file mode 100644 index 0000000..5c6f30d --- /dev/null +++ b/docs/museums/photo_mode/museum_photo_mode.gd @@ -0,0 +1,6 @@ +extends Node3D + +@onready var collection_compendium: Control = $Control/CollectionCompendium + +func _on_button_pressed() -> void: + collection_compendium.visible = !collection_compendium.visible diff --git a/docs/museums/photo_mode/museum_photo_mode.gd.uid b/docs/museums/photo_mode/museum_photo_mode.gd.uid new file mode 100644 index 0000000..b17c53f --- /dev/null +++ b/docs/museums/photo_mode/museum_photo_mode.gd.uid @@ -0,0 +1 @@ +uid://7oglx4br38d5 diff --git a/docs/museums/photo_mode/museum_photo_mode.tscn b/docs/museums/photo_mode/museum_photo_mode.tscn new file mode 100644 index 0000000..a4d8ad3 --- /dev/null +++ b/docs/museums/photo_mode/museum_photo_mode.tscn @@ -0,0 +1,80 @@ +[gd_scene format=3 uid="uid://bwc8slnbu7dmn"] + +[ext_resource type="PackedScene" uid="uid://vni5kjalum6d" path="res://core/photo_mode/photo_mode_controller.tscn" id="1_css17"] +[ext_resource type="Script" uid="uid://7oglx4br38d5" path="res://docs/museums/photo_mode/museum_photo_mode.gd" id="1_ynvi2"] +[ext_resource type="PackedScene" uid="uid://bmkxt6btcx8qr" path="res://core/photo_mode/collectible.tscn" id="2_48mla"] +[ext_resource type="Script" uid="uid://bj34o0org55ei" path="res://core/photo_mode/collectible_resource.gd" id="3_hh1ka"] +[ext_resource type="Texture2D" uid="uid://c3grftlmap4q5" path="res://docs/museums/daynight/scenes/grain_test/leaf_test.png" id="4_fan5s"] +[ext_resource type="PackedScene" uid="uid://bvw086glfpcba" path="res://core/photo_mode/collection_compendium.tscn" id="5_ws0fy"] + +[sub_resource type="Environment" id="Environment_48mla"] + +[sub_resource type="PlaneMesh" id="PlaneMesh_hh1ka"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_ynvi2"] +size = Vector3(1.9942131, 0.09710693, 1.984024) + +[sub_resource type="Resource" id="Resource_ynvi2"] +script = ExtResource("3_hh1ka") +id = "gatto" +title = "Gatto" +image = ExtResource("4_fan5s") +metadata/_custom_type_script = "uid://bj34o0org55ei" + +[sub_resource type="BoxMesh" id="BoxMesh_hh1ka"] + +[node name="MuseumPhotoMode" type="Node3D" unique_id=1314600330] +script = ExtResource("1_ynvi2") + +[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=213183287] +environment = SubResource("Environment_48mla") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=1274975837] +transform = Transform3D(1, 0, 0, 0, 0.17952333, 0.98375374, 0, -0.98375374, 0.17952333, 0, 18.920979, 0) + +[node name="Floor" type="MeshInstance3D" parent="." unique_id=958865480] +transform = Transform3D(20, 0, 0, 0, 20, 0, 0, 0, 20, 0, -0.83473957, 0) +mesh = SubResource("PlaneMesh_hh1ka") + +[node name="StaticBody3D" type="StaticBody3D" parent="Floor" unique_id=2096983240] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Floor/StaticBody3D" unique_id=188185045] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0036563873, -0.009703338, -0.00868988) +shape = SubResource("BoxShape3D_ynvi2") + +[node name="PhotoModeController" parent="." unique_id=695158870 node_paths=PackedStringArray("rotation_target") instance=ExtResource("1_css17")] +transform = Transform3D(1, 0, 0, 0, 0.49999994, 0.8660254, 0, -0.8660254, 0.49999994, 0, 30, 20) +movement_bounds = AABB(-5, -5, -5, 10, 10, 10) +rotation_target = NodePath("../Node3D") + +[node name="Node3D" type="Node3D" parent="." unique_id=570786250] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10, 0) + +[node name="Node3D2" type="Node3D" parent="." unique_id=15037296] + +[node name="Collectible" parent="Node3D2" unique_id=1229019813 instance=ExtResource("2_48mla")] +collectible_data = SubResource("Resource_ynvi2") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Node3D2" unique_id=553040412] +mesh = SubResource("BoxMesh_hh1ka") + +[node name="Control" type="Control" parent="." unique_id=1802496396] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 + +[node name="Button" type="Button" parent="Control" unique_id=539195532] +layout_mode = 0 +offset_right = 8.0 +offset_bottom = 8.0 +text = "Compendium" + +[node name="CollectionCompendium" parent="Control" unique_id=354419843 instance=ExtResource("5_ws0fy")] +visible = false +layout_mode = 1 + +[connection signal="pressed" from="Control/Button" to="." method="_on_button_pressed"] diff --git a/project.godot b/project.godot index 1307a6b..6a5c15a 100644 --- a/project.godot +++ b/project.godot @@ -18,6 +18,7 @@ config/icon="res://icon.svg" [autoload] UIEvents="*uid://dehu28iq27mbn" +CollectionManager="*uid://c3kq1qddpm8tf" [display] @@ -32,6 +33,39 @@ weather_vegetables_node="" wind_node="Materials to apply wind" weather_node="" +[input] + +photo_pan_left={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":65,"location":0,"echo":false,"script":null) +] +} +photo_pan_right={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} +photo_pan_up={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +] +} +photo_pan_down={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +] +} +take_photo={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null) +] +} +toggle_photo_mode={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":80,"key_label":0,"unicode":112,"location":0,"echo":false,"script":null) +] +} + [physics] 3d/physics_engine="Jolt Physics"