diff --git a/addons/godot_gameplay_systems/interactables/nodes/interaction_manager.gd b/addons/godot_gameplay_systems/interactables/nodes/interaction_manager.gd index fa7714b..4ceea27 100644 --- a/addons/godot_gameplay_systems/interactables/nodes/interaction_manager.gd +++ b/addons/godot_gameplay_systems/interactables/nodes/interaction_manager.gd @@ -60,7 +60,10 @@ var can_interact: bool: if not tags.has(tag): return false - return focused_interactable != null + if focused_interactable != null: + return tags_blocking_interaction.size() == 0 and tags_required_to_interact.size() == 0 + + return false ## Is the interacting owner. Usually a [CharacterBody2D] or [CharacterBody3D]. var interacting_owner: Node: get: diff --git a/addons/godot_gameplay_systems/plugin.gd b/addons/godot_gameplay_systems/plugin.gd index 4657cdf..d421de3 100644 --- a/addons/godot_gameplay_systems/plugin.gd +++ b/addons/godot_gameplay_systems/plugin.gd @@ -7,6 +7,7 @@ const extended_character_nodes_script = preload("res://addons/godot_gameplay_sys const inventory_system_script = preload("res://addons/godot_gameplay_systems/inventory_system/plugin.gd") const interactables_script = preload("res://addons/godot_gameplay_systems/interactables/plugin.gd") const slideshow_script = preload("res://addons/godot_gameplay_systems/slideshow/plugin.gd") +const turn_based_script = preload("res://addons/godot_gameplay_systems/turn_based/plugin.gd") var attributes_and_abilities_plugin: EditorPlugin @@ -15,6 +16,7 @@ var extended_character_nodes: EditorPlugin var inventory_system: EditorPlugin var interactables: EditorPlugin var slideshow: EditorPlugin +var turn_based: EditorPlugin func _init() -> void: @@ -24,6 +26,7 @@ func _init() -> void: inventory_system = inventory_system_script.new() interactables = interactables_script.new() slideshow = slideshow_script.new() + turn_based = turn_based_script.new() func _enter_tree(): @@ -33,6 +36,7 @@ func _enter_tree(): inventory_system._enter_tree() interactables._enter_tree() slideshow._enter_tree() + turn_based._enter_tree() func _exit_tree(): @@ -42,3 +46,4 @@ func _exit_tree(): inventory_system._exit_tree() interactables._exit_tree() slideshow._exit_tree() + turn_based._exit_tree() diff --git a/addons/godot_gameplay_systems/turn_based/autoloads/turn_manager.gd b/addons/godot_gameplay_systems/turn_based/autoloads/turn_manager.gd new file mode 100644 index 0000000..87de003 --- /dev/null +++ b/addons/godot_gameplay_systems/turn_based/autoloads/turn_manager.gd @@ -0,0 +1,36 @@ +extends Node + + +## The [TurnBasedGame] node. +var turn_based_game: TurnBasedGame = null + + +## Called when the node enters the scene tree for the first time. +func _ready() -> void: + get_turn_based_game() + + +## Ends the current turn sequence. +func end_turn_sequence() -> void: + if get_turn_based_game(): + get_turn_based_game().end_turn_sequence() + + +## Gets the [TurnBasedGame] node. +func get_turn_based_game() -> TurnBasedGame: + if turn_based_game: + return turn_based_game + + for child in get_tree().get_nodes_in_group("ggs.turnbased"): + if child is TurnBasedGame: + turn_based_game = child + return turn_based_game + + return null + + +## Starts a new turn sequence (aka, starts the turn based mode). +func start_turn_sequence() -> void: + if get_turn_based_game(): + get_turn_based_game().start_turn_sequence() + diff --git a/addons/godot_gameplay_systems/turn_based/nodes/TurnBasedGame.gd b/addons/godot_gameplay_systems/turn_based/nodes/TurnBasedGame.gd new file mode 100644 index 0000000..c3da158 --- /dev/null +++ b/addons/godot_gameplay_systems/turn_based/nodes/TurnBasedGame.gd @@ -0,0 +1,124 @@ +class_name TurnBasedGame extends Node + + +## Emitted when a turn changes. +signal turn_changed(manager: TurnBasedGame) +## Emitted when the turn based game starts. +signal turn_game_started() +## Emitted when the turn based game stops. +signal turn_game_stopped() +## Emitted when a subscriber is added. +signal subscriber_added(subscriber: TurnSubscriber) +## Emitted when a subscriber is removed. +signal subscriber_removed(subscriber: TurnSubscriber) + + +## The current turn. +var current_turn: int = 0 +## The current turn subscriber. +var current_turn_subscriber: TurnSubscriber: + get: + if subscribers.size() == 0: + return null + + return subscribers[current_turn] +## The turn subscribers. +var subscribers: Array[TurnSubscriber] = [] + + +func _ready() -> void: + add_to_group("ggs.turnbased") + + +func _sort_subscribers() -> void: + subscribers.sort_custom(func (a, b): + return a.priority < b.priority + ) + + +## Called when a [TurnSubscriber] is subscribed. +## [br]This is a virtual method +func _subscriber_added(sub: TurnSubscriber) -> void: + pass + + +## Called when a [TurnSubscriber] is unsubscribed. +## [br]This is a virtual method +func _subscriber_removed(sub: TurnSubscriber) -> void: + pass + + +## Adds a [TurnSubscriber] +func add_subscriber(sub: TurnSubscriber) -> bool: + if subscribers.has(sub): + return false + + subscribers.append(sub) + subscriber_added.emit(sub) + + _sort_subscribers() + + return true + + +## Ends the current turn +func end_turn_sequence() -> void: + if subscribers.size() == 0: + return + + subscribers[current_turn].end_turn() + + current_turn += 1 + + if current_turn >= subscribers.size(): + current_turn = 0 + + subscribers[current_turn].turn_started.emit() + subscribers[current_turn]._turn_started() + + turn_game_stopped.emit() + + +## Calls next turn +func next_turn() -> void: + var subscribers_count := subscribers.size() + + if current_turn < subscribers_count: + subscribers[current_turn].turn_ended.emit() + subscribers[current_turn]._turn_ended() + + current_turn += 1 + + if current_turn >= subscribers_count: + current_turn = 0 + + subscribers[current_turn].turn_started.emit() + subscribers[current_turn]._turn_started() + + +## Removes a [TurnSubscriber] +func remove_subscriber(sub: TurnSubscriber) -> bool: + if not subscribers.has(sub): + return false + + var sub_turn_index = subscribers.find(func (x): return x == sub) + + subscribers.remove_at(sub_turn_index) + subscriber_removed.emit(sub) + + _sort_subscribers() + + return true + + +## Starts the turn based game. +func start_turn_sequence() -> void: + if subscribers.size() == 0: + return + + current_turn = 0 + + subscribers[current_turn]._turn_started() + subscribers[current_turn].turn_started.emit() + + turn_game_started.emit() diff --git a/addons/godot_gameplay_systems/turn_based/nodes/TurnSubscriber.gd b/addons/godot_gameplay_systems/turn_based/nodes/TurnSubscriber.gd new file mode 100644 index 0000000..72b31ab --- /dev/null +++ b/addons/godot_gameplay_systems/turn_based/nodes/TurnSubscriber.gd @@ -0,0 +1,54 @@ +class_name TurnSubscriber extends Node + +## A turn based participant +## +## It represents a scene which can partecipate to a turn based game + + +## Emitted when this subscriber turn ends +signal turn_ended() +## Emitted when this subscriber turn starts +signal turn_started() +## Emitter when the turn round ended, +signal turn_round_ended() + + +@export_group("Turn based game") +## Priority of this subscriber. The higher the priority, the sooner the turn starts. +@export var priority: int = 0 + + +func _enter_tree() -> void: + if TurnManager.get_turn_based_game() != null: + TurnManager.get_turn_based_game().add_subscriber(self) + + +func _exit_tree() -> void: + if TurnManager.get_turn_based_game() != null: + TurnManager.get_turn_based_game().remove_subscriber(self) + + +func _ready() -> void: + add_to_group("ggs.turnbased") + + if TurnManager.get_turn_based_game() != null: + TurnManager.get_turn_based_game().add_subscriber(self) + + +## Called when the turn round ended +## [br]It's a virtual method, it can be overrided +func _turn_ended() -> void: + pass + + +## Called when the turn round started +## [br]It's a virtual method, it can be overrided +func _turn_started() -> void: + pass + + +## Ends the turn of this subscriber +func end_turn() -> void: + if TurnManager.get_turn_based_game() != null: + TurnManager.get_turn_based_game().next_turn() + diff --git a/addons/godot_gameplay_systems/turn_based/plugin.gd b/addons/godot_gameplay_systems/turn_based/plugin.gd new file mode 100644 index 0000000..296ddb5 --- /dev/null +++ b/addons/godot_gameplay_systems/turn_based/plugin.gd @@ -0,0 +1,18 @@ +extends EditorPlugin + + +const TurnBasedGameScript = preload("res://addons/godot_gameplay_systems/turn_based/nodes/TurnBasedGame.gd") +const TurnSubscriberScript = preload("res://addons/godot_gameplay_systems/turn_based/nodes/TurnSubscriber.gd") + + +func _enter_tree() -> void: + add_autoload_singleton("TurnManager", "res://addons/godot_gameplay_systems/turn_based/autoloads/turn_manager.gd") + add_custom_type("TurnBasedGame", "Node", TurnBasedGameScript, null) + add_custom_type("TurnSubscriber", "Node", TurnSubscriberScript, null) + + +func _exit_tree() -> void: + remove_autoload_singleton("TurnManager") + remove_custom_type("TurnBasedGame") + remove_custom_type("TurnSubscriber") + diff --git a/docs/turn-based-nodes.md b/docs/turn-based-nodes.md new file mode 100644 index 0000000..aae7a8d --- /dev/null +++ b/docs/turn-based-nodes.md @@ -0,0 +1,30 @@ +Turn based nodes +================ + +Turn based nodes are nodes that can be used to create turn based games. + +To start adding functionalities to your game, you can add a `TurnBasedGame` node to your scene. This node should be at the highest level of your hierarchy. It will be used to manage the turns properly. + +Then you should add a `TurnSubscriber` to each node which should be notified when a turn starts or ends. + +This node has a priority property. The nodes with the highest priority will start their turns first. If two nodes have the same priority, the one that was added first will start its turn first. + +To get the `TurnBasedGame` node, you have to use the singleton `TurnManager`. + +This has a method which returns the `TurnBasedGame` node. You can use it like this: + +```gdscript +# To start a turn sequence +var turn_based_game = TurnManager.get_turn_based_game() +turn_based_game.start_turn_sequence(); + +# To end a turn sequence +turn_based_game.end_turn_sequence(); +``` + +Each `TurnSubscriber` can terminate it's own turn by calling their `end_turn` method. + +```gdscript +# To end a turn +self.end_turn(); +``` diff --git a/examples/examples_menu.tscn b/examples/examples_menu.tscn index 6aac93c..a783ad6 100644 --- a/examples/examples_menu.tscn +++ b/examples/examples_menu.tscn @@ -76,6 +76,12 @@ text = "SOT-like (sail management)" script = ExtResource("3_jxaps") scene_to_load = "res://examples/sot_like/sot_game.tscn" +[node name="TurnBasedTopDown" type="Button" parent="ExamplesMenu/ExampleButtons"] +layout_mode = 2 +text = "SOT-like (sail management)" +script = ExtResource("3_jxaps") +scene_to_load = "res://examples/turn_based_top_down/turn_based_top_down.tscn" + [node name="HSeparator" type="HSeparator" parent="ExamplesMenu"] custom_minimum_size = Vector2(2.08165e-12, 50) layout_mode = 2 diff --git a/examples/turn_based_top_down/turn_based_player.gd b/examples/turn_based_top_down/turn_based_player.gd new file mode 100644 index 0000000..7035224 --- /dev/null +++ b/examples/turn_based_top_down/turn_based_player.gd @@ -0,0 +1,30 @@ +extends CharacterBody3D + + +@export var turn_priority: int = 0 +@onready var point_and_click_3d: PointAndClick3D = $PointAndClick3D +@onready var turn_subscriber: TurnSubscriber = $TurnSubscriber +@onready var current_turn_indicator: MeshInstance3D = $CurrentTurnIndicator + + +func _ready() -> void: + turn_subscriber.priority = turn_priority + current_turn_indicator.visible = false + + set_process_input(false) + + turn_subscriber.turn_started.connect(func (): + set_process_input(true) + current_turn_indicator.visible = true + ) + + turn_subscriber.turn_ended.connect(func (): + set_process_input(false) + current_turn_indicator.visible = false + ) + + +func _input(event: InputEvent) -> void: + if event.is_action_pressed("diablo_like_move_to"): + point_and_click_3d.set_new_movement_position() + diff --git a/examples/turn_based_top_down/turn_based_player.tscn b/examples/turn_based_top_down/turn_based_player.tscn new file mode 100644 index 0000000..277dac1 --- /dev/null +++ b/examples/turn_based_top_down/turn_based_player.tscn @@ -0,0 +1,42 @@ +[gd_scene load_steps=8 format=3 uid="uid://cdnfhfmyr0s2r"] + +[ext_resource type="Script" path="res://addons/godot_gameplay_systems/extended_character_nodes/nodes/3d/point_and_click_3d.gd" id="1_303p0"] +[ext_resource type="Script" path="res://examples/turn_based_top_down/turn_based_player.gd" id="1_lu0be"] +[ext_resource type="Script" path="res://addons/godot_gameplay_systems/turn_based/nodes/TurnSubscriber.gd" id="3_kxm0n"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_8sggy"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_ueetf"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ltftp"] +albedo_color = Color(0.454902, 0.6, 0.423529, 1) +grow = true +grow_amount = -0.2 + +[sub_resource type="TorusMesh" id="TorusMesh_1p6n7"] +material = SubResource("StandardMaterial3D_ltftp") + +[node name="CharacterBody3D" type="CharacterBody3D"] +script = ExtResource("1_lu0be") + +[node name="PointAndClick3D" type="Node3D" parent="." node_paths=PackedStringArray("character_3d", "navigation_agent")] +script = ExtResource("1_303p0") +character_3d = NodePath("..") +navigation_agent = NodePath("../NavigationAgent3D") +clickable_layer = 31 + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +mesh = SubResource("CapsuleMesh_8sggy") +skeleton = NodePath("../PointAndClick3D") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("CapsuleShape3D_ueetf") + +[node name="NavigationAgent3D" type="NavigationAgent3D" parent="."] + +[node name="TurnSubscriber" type="Node" parent="."] +script = ExtResource("3_kxm0n") + +[node name="CurrentTurnIndicator" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.659721, 0) +mesh = SubResource("TorusMesh_1p6n7") diff --git a/examples/turn_based_top_down/turn_based_top_down.gd b/examples/turn_based_top_down/turn_based_top_down.gd new file mode 100644 index 0000000..b9b4638 --- /dev/null +++ b/examples/turn_based_top_down/turn_based_top_down.gd @@ -0,0 +1,22 @@ +extends Node + + +@onready var start: Button = $Control/Start +@onready var next_turn: Button = $Control/NextTurn + + +func _ready() -> void: + start.pressed.connect(handle_start, CONNECT_ONE_SHOT) + next_turn.pressed.connect(handle_next) + + next_turn.visible = false + + +func handle_next() -> void: + TurnManager.get_turn_based_game().next_turn() + + +func handle_start() -> void: + TurnManager.get_turn_based_game().start_turn_sequence() + start.queue_free() + next_turn.visible = true diff --git a/examples/turn_based_top_down/turn_based_top_down.tscn b/examples/turn_based_top_down/turn_based_top_down.tscn new file mode 100644 index 0000000..b1eb92b --- /dev/null +++ b/examples/turn_based_top_down/turn_based_top_down.tscn @@ -0,0 +1,36 @@ +[gd_scene load_steps=4 format=3 uid="uid://v4bu2a6tejyj"] + +[ext_resource type="Script" path="res://addons/godot_gameplay_systems/turn_based/nodes/TurnBasedGame.gd" id="1_cccuw"] +[ext_resource type="Script" path="res://examples/turn_based_top_down/turn_based_top_down.gd" id="1_tle0i"] +[ext_resource type="PackedScene" uid="uid://cc5awp7xp145c" path="res://examples/turn_based_top_down/turn_based_top_down_world.tscn" id="2_ea6y2"] + +[node name="turn_based_top_down" type="Node"] +script = ExtResource("1_tle0i") + +[node name="TurnBasedGame" type="Node" parent="."] +script = ExtResource("1_cccuw") + +[node name="TurnBasedTopDownWorld" parent="." instance=ExtResource("2_ea6y2")] + +[node name="Control" type="HBoxContainer" parent="."] +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -111.0 +offset_top = -31.0 +offset_right = 111.0 +grow_horizontal = 2 +grow_vertical = 0 +size_flags_horizontal = 3 + +[node name="Start" type="Button" parent="Control"] +layout_mode = 2 +text = "Start turn based movement" + +[node name="NextTurn" type="Button" parent="Control"] +layout_mode = 2 +mouse_default_cursor_shape = 2 +text = "Next turn +" diff --git a/examples/turn_based_top_down/turn_based_top_down_world.tscn b/examples/turn_based_top_down/turn_based_top_down_world.tscn new file mode 100644 index 0000000..603450f --- /dev/null +++ b/examples/turn_based_top_down/turn_based_top_down_world.tscn @@ -0,0 +1,101 @@ +[gd_scene load_steps=11 format=3 uid="uid://cc5awp7xp145c"] + +[ext_resource type="PackedScene" uid="uid://cdnfhfmyr0s2r" path="res://examples/turn_based_top_down/turn_based_player.tscn" id="1_8wet3"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_64ext"] + +[sub_resource type="Sky" id="Sky_rkfpt"] +sky_material = SubResource("ProceduralSkyMaterial_64ext") + +[sub_resource type="Environment" id="Environment_7rql6"] +sky = SubResource("Sky_rkfpt") +ambient_light_source = 3 +tonemap_mode = 2 + +[sub_resource type="NavigationMesh" id="NavigationMesh_q4c56"] +vertices = PackedVector3Array(0.75, 0.4, -7.25, 1.75, 0.4, -7.5, 1.75, 0.4, -12, -5.25, 0.4, -12, -2.75, 0.4, -1, -1.25, 0.4, -1, 0.75, 0.4, -5.75, -2.75, 0.4, -1, 0.75, 0.4, -5.75, 0.75, 0.4, -7.25, -5.25, 0.4, -12, -12, 0.4, -12, -12, 0.4, 0, -12, 0.4, 0, -3, 0.4, 0, -2.75, 0.4, -1, 3, 0.4, -7.25, 3, 0.4, -5.75, 3.25, 0.4, -5.75, 1.75, 0.4, -12, 1.75, 0.4, -7.5, 3, 0.4, -7.25, 12, 0.4, -5.75, 12, 0.4, -12, 3, 0.4, -7.25, 3.25, 0.4, -5.75, 12, 0.4, -5.75, 3.25, 0.4, -5.75, 3, 0.4, -5.75, 2.75, 0.4, -5.25, 3.25, 0.4, 0, 1, 0.4, -5.25, 0.75, 0.4, -5.75, -1.25, 0.4, -1, 1, 0.4, -5.25, -1.25, 0.4, -1, -0.75, 0.4, -0.75, 1.5, 0.4, 0.25, 3.25, 0.4, 0, 2.75, 0.4, -5.25, 2.75, 0.4, 12, 2.75, 0.4, 2.25, 1.5, 0.4, 2, 1.5, 0.4, 2, -0.75, 0.4, 1, -1.25, 0.4, 1.25, -1.5, 0.4, 12, 2.75, 0.4, 12, -0.75, 0.4, 1, 1.5, 0.4, 2, 1.5, 0.4, 0.25, -0.75, 0.4, -0.75, 3.25, 0.4, -5.75, 3.25, 0.4, 0, 3.75, 0.4, 0.25, 12, 0.4, 1.25, 12, 0.4, -5.75, 3.75, 0.4, 0.25, 3.75, 0.4, 1.25, 12, 0.4, 1.25, -2.75, 0.4, 1.25, -3, 0.4, 0, -12, 0.4, 0, -12, 0.4, 12, -1.5, 0.4, 12, -1.5, 0.4, 12, -1.25, 0.4, 1.25, -2.75, 0.4, 1.25, 12, 0.4, 1.25, 3.75, 0.4, 1.25, 3.5, 0.4, 2.25, 2.75, 0.4, 12, 12, 0.4, 12, 3.5, 0.4, 2.25, 2.75, 0.4, 2.25, 2.75, 0.4, 12) +polygons = [PackedInt32Array(1, 0, 2), PackedInt32Array(2, 0, 3), PackedInt32Array(6, 5, 4), PackedInt32Array(8, 7, 9), PackedInt32Array(9, 7, 10), PackedInt32Array(10, 7, 11), PackedInt32Array(11, 7, 12), PackedInt32Array(15, 14, 13), PackedInt32Array(18, 17, 16), PackedInt32Array(20, 19, 21), PackedInt32Array(21, 19, 23), PackedInt32Array(21, 23, 22), PackedInt32Array(26, 25, 24), PackedInt32Array(28, 27, 29), PackedInt32Array(29, 27, 30), PackedInt32Array(33, 32, 31), PackedInt32Array(36, 35, 37), PackedInt32Array(37, 35, 38), PackedInt32Array(38, 35, 34), PackedInt32Array(38, 34, 39), PackedInt32Array(42, 41, 40), PackedInt32Array(44, 43, 45), PackedInt32Array(45, 43, 46), PackedInt32Array(46, 43, 47), PackedInt32Array(51, 50, 48), PackedInt32Array(48, 50, 49), PackedInt32Array(53, 52, 54), PackedInt32Array(54, 52, 56), PackedInt32Array(54, 56, 55), PackedInt32Array(59, 58, 57), PackedInt32Array(61, 60, 62), PackedInt32Array(62, 60, 63), PackedInt32Array(63, 60, 64), PackedInt32Array(67, 66, 65), PackedInt32Array(69, 68, 70), PackedInt32Array(70, 68, 72), PackedInt32Array(70, 72, 71), PackedInt32Array(75, 74, 73)] +geometry_parsed_geometry_type = 2 +geometry_collision_mask = 4294967265 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_3j4sd"] +albedo_color = Color(0.658824, 0.423529, 0.258824, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_xkgc3"] +material = SubResource("StandardMaterial3D_3j4sd") +size = Vector3(25, 0.2, 25) + +[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_7vdh2"] +data = PackedVector3Array(-12.5, 0.1, 12.5, 12.5, 0.1, 12.5, -12.5, -0.1, 12.5, 12.5, 0.1, 12.5, 12.5, -0.1, 12.5, -12.5, -0.1, 12.5, 12.5, 0.1, -12.5, -12.5, 0.1, -12.5, 12.5, -0.1, -12.5, -12.5, 0.1, -12.5, -12.5, -0.1, -12.5, 12.5, -0.1, -12.5, 12.5, 0.1, 12.5, 12.5, 0.1, -12.5, 12.5, -0.1, 12.5, 12.5, 0.1, -12.5, 12.5, -0.1, -12.5, 12.5, -0.1, 12.5, -12.5, 0.1, -12.5, -12.5, 0.1, 12.5, -12.5, -0.1, -12.5, -12.5, 0.1, 12.5, -12.5, -0.1, 12.5, -12.5, -0.1, -12.5, 12.5, 0.1, 12.5, -12.5, 0.1, 12.5, 12.5, 0.1, -12.5, -12.5, 0.1, 12.5, -12.5, 0.1, -12.5, 12.5, 0.1, -12.5, -12.5, -0.1, 12.5, 12.5, -0.1, 12.5, -12.5, -0.1, -12.5, 12.5, -0.1, 12.5, 12.5, -0.1, -12.5, -12.5, -0.1, -12.5) + +[sub_resource type="BoxMesh" id="BoxMesh_6ab0p"] + +[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_1depw"] +data = PackedVector3Array(-0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5) + +[node name="TurnBasedTopDownWorld" type="Node3D"] + +[node name="characters" type="Node3D" parent="."] + +[node name="CharacterBody3D" parent="characters" instance=ExtResource("1_8wet3")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.46571, 1.01345, 1.52098) +turn_priority = 1 + +[node name="CharacterBody3D2" parent="characters" instance=ExtResource("1_8wet3")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.0281, 1.01345, -3.35444) +turn_priority = 3 + +[node name="CharacterBody3D3" parent="characters" instance=ExtResource("1_8wet3")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.99546, 1.01345, -3.35444) +turn_priority = 2 + +[node name="Camera3D" type="Camera3D" parent="."] +transform = Transform3D(1, -5.95416e-16, 2.4663e-16, 2.4663e-16, 0.707107, 0.707107, -5.95416e-16, -0.707107, 0.707107, 0, 9.26433, 6.89707) + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_7rql6") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="WorldEnvironment"] +transform = Transform3D(-0.99933, -0.025874, 0.025874, 0.0365913, -0.706633, 0.706633, 6.3073e-09, 0.707107, 0.707107, 0, 16.5322, 0) + +[node name="NavigationRegion3D" type="NavigationRegion3D" parent="."] +navigation_mesh = SubResource("NavigationMesh_q4c56") +navigation_layers = 255 + +[node name="floor" type="MeshInstance3D" parent="NavigationRegion3D"] +mesh = SubResource("BoxMesh_xkgc3") +skeleton = NodePath("../..") + +[node name="StaticBody3D" type="StaticBody3D" parent="NavigationRegion3D/floor"] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="NavigationRegion3D/floor/StaticBody3D"] +shape = SubResource("ConcavePolygonShape3D_7vdh2") + +[node name="obstacles" type="Node3D" parent="NavigationRegion3D"] + +[node name="MeshInstance3D" type="MeshInstance3D" parent="NavigationRegion3D/obstacles"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.83267, 0.469107, 0) +mesh = SubResource("BoxMesh_6ab0p") + +[node name="StaticBody3D" type="StaticBody3D" parent="NavigationRegion3D/obstacles/MeshInstance3D"] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="NavigationRegion3D/obstacles/MeshInstance3D/StaticBody3D"] +shape = SubResource("ConcavePolygonShape3D_1depw") + +[node name="MeshInstance3D2" type="MeshInstance3D" parent="NavigationRegion3D/obstacles"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.79587, 0.469107, -6.28681) +mesh = SubResource("BoxMesh_6ab0p") + +[node name="StaticBody3D" type="StaticBody3D" parent="NavigationRegion3D/obstacles/MeshInstance3D2"] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="NavigationRegion3D/obstacles/MeshInstance3D2/StaticBody3D"] +shape = SubResource("ConcavePolygonShape3D_1depw") + +[node name="MeshInstance3D3" type="MeshInstance3D" parent="NavigationRegion3D/obstacles"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.68826, 0.469107, 1.10325) +mesh = SubResource("BoxMesh_6ab0p") + +[node name="StaticBody3D" type="StaticBody3D" parent="NavigationRegion3D/obstacles/MeshInstance3D3"] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="NavigationRegion3D/obstacles/MeshInstance3D3/StaticBody3D"] +shape = SubResource("ConcavePolygonShape3D_1depw") diff --git a/project.godot b/project.godot index db2da45..512f9d2 100644 --- a/project.godot +++ b/project.godot @@ -15,6 +15,10 @@ run/main_scene="res://examples/examples.tscn" config/features=PackedStringArray("4.1", "Forward Plus") config/icon="res://icon.svg" +[autoload] + +TurnManager="*res://addons/godot_gameplay_systems/turn_based/autoloads/turn_manager.gd" + [display] window/stretch/aspect="keep_width"