Refactored node structure for TurnActors
parent
a7776b3c86
commit
3f75d5a616
|
|
@ -2,15 +2,9 @@
|
|||
class_name ActionDecider
|
||||
extends Node
|
||||
|
||||
var actor: TurnActor
|
||||
var current_action: Action
|
||||
@export var actor: TurnActor
|
||||
|
||||
func get_actor():
|
||||
var parent = get_parent()
|
||||
if parent is TurnActor:
|
||||
return parent
|
||||
else:
|
||||
return null
|
||||
var current_action: Action
|
||||
|
||||
func connect_to_actor():
|
||||
actor.connect("turn_started", handle_turn_start)
|
||||
|
|
@ -71,11 +65,7 @@ func inner_action_cleanup():
|
|||
actor.end_turn()
|
||||
|
||||
func _ready():
|
||||
actor = get_actor()
|
||||
if not actor is TurnActor:
|
||||
push_error("Couldn't get TurnActor from TurnAction")
|
||||
else:
|
||||
connect_to_actor()
|
||||
connect_to_actor()
|
||||
|
||||
func _process(delta: float):
|
||||
if current_action:
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
class_name MoveAction
|
||||
extends Action
|
||||
|
||||
var mover: GridPosition
|
||||
var mover: Mover
|
||||
var dir: Vector2i
|
||||
|
||||
func _init(new_mover: GridPosition, new_dir: Vector2i) -> void:
|
||||
func _init(new_mover: Mover, new_dir: Vector2i) -> void:
|
||||
mover = new_mover
|
||||
dir = new_dir
|
||||
|
||||
|
|
|
|||
|
|
@ -3,23 +3,31 @@
|
|||
[ext_resource type="Texture2D" uid="uid://doscvutq8uqmd" path="res://sprites/sheet.png" id="1_72ieh"]
|
||||
[ext_resource type="Script" uid="uid://sxo578w2yds2" path="res://prefabs/player/player_input.gd" id="2_rdx4y"]
|
||||
|
||||
[node name="Player" type="TurnActor"]
|
||||
[node name="Player" type="GridPosition"]
|
||||
|
||||
[node name="Input" type="Node2D" parent="."]
|
||||
script = ExtResource("2_rdx4y")
|
||||
metadata/_custom_type_script = "uid://okxdlbfuvb1b"
|
||||
|
||||
[node name="GridPosition" type="GridPosition" parent="."]
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="GridPosition"]
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
texture = ExtResource("1_72ieh")
|
||||
centered = false
|
||||
hframes = 8
|
||||
vframes = 8
|
||||
frame = 1
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="GridPosition"]
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
position = Vector2(16, 16)
|
||||
zoom = Vector2(2, 2)
|
||||
|
||||
[node name="Gatherer" type="Gatherer" parent="GridPosition"]
|
||||
[node name="Gatherer" type="Gatherer" parent="." node_paths=PackedStringArray("grid", "actor")]
|
||||
grid = NodePath("..")
|
||||
actor = NodePath("../TurnActor")
|
||||
|
||||
[node name="Mover" type="Mover" parent="."]
|
||||
|
||||
[node name="TurnActor" type="TurnActor" parent="."]
|
||||
position = Vector2(-1, 0)
|
||||
|
||||
[node name="ActionDecider" type="Node2D" parent="." node_paths=PackedStringArray("grid", "mover", "actor")]
|
||||
script = ExtResource("2_rdx4y")
|
||||
grid = NodePath("..")
|
||||
mover = NodePath("../Mover")
|
||||
actor = NodePath("../TurnActor")
|
||||
metadata/_custom_type_script = "uid://okxdlbfuvb1b"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
@icon("res://icons/turn_action.svg")
|
||||
extends ActionDecider
|
||||
|
||||
@onready var grid_position: GridPosition = $"../GridPosition"
|
||||
@export var grid: GridPosition
|
||||
@export var mover: Mover
|
||||
|
||||
func poll_movement_dir():
|
||||
var movement_dir = Vector2i.ZERO
|
||||
|
|
@ -25,23 +26,11 @@ func _input(event: InputEvent) -> void:
|
|||
print("skip turn!")
|
||||
if try_perform(SkipAction.new()):
|
||||
return
|
||||
#KEY_UP:
|
||||
#if try_perform(MoveAction.new(grid_position, Vector2i.UP)):
|
||||
#return
|
||||
#KEY_DOWN:
|
||||
#if try_perform(MoveAction.new(grid_position, Vector2i.DOWN)):
|
||||
#return
|
||||
#KEY_LEFT:
|
||||
#if try_perform(MoveAction.new(grid_position, Vector2i.LEFT)):
|
||||
#return
|
||||
#KEY_RIGHT:
|
||||
#if try_perform(MoveAction.new(grid_position, Vector2i.RIGHT)):
|
||||
#return
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if not is_deciding():
|
||||
return
|
||||
var movement_dir = poll_movement_dir()
|
||||
if movement_dir != Vector2i.ZERO:
|
||||
if try_perform(MoveAction.new(grid_position, movement_dir)):
|
||||
if try_perform(MoveAction.new(mover, movement_dir)):
|
||||
return
|
||||
|
|
|
|||
|
|
@ -4,18 +4,20 @@
|
|||
[ext_resource type="TileSet" uid="uid://bxwohuw2p43k1" path="res://tilesets/foreground_tileset.tres" id="2_u2ss0"]
|
||||
[ext_resource type="PackedScene" uid="uid://drs6h7ks4r2ta" path="res://prefabs/player/player.tscn" id="3_u2ss0"]
|
||||
|
||||
[node name="Root" type="Level" node_paths=PackedStringArray("background", "foreground")]
|
||||
[node name="TurnManager" type="TurnManager"]
|
||||
|
||||
[node name="Root" type="Level" parent="." node_paths=PackedStringArray("background", "foreground")]
|
||||
background = NodePath("Background")
|
||||
foreground = NodePath("Foreground")
|
||||
|
||||
[node name="Background" type="TileMapLayer" parent="."]
|
||||
[node name="Background" type="TileMapLayer" parent="Root"]
|
||||
tile_map_data = PackedByteArray("AAD8//z/AQAAAAQAAAD8//3/AQAAAAQAAAD8//7/AQAAAAQAAAD8////AQAAAAQAAAD9//z/AQAAAAQAAAD9//3/AQAAAAQAAAD9//7/AQAAAAQAAAD9////AQAAAAQAAAD+//z/AQAAAAQAAAD+//3/AQAAAAQAAAD+//7/AQAAAAQAAAD+////AQAAAAQAAAD///z/AQAAAAQAAAD///3/AQAAAAQAAAD///7/AQAAAAQAAAD/////AQAAAAQAAAD8/wAAAQAAAAQAAAD8/wEAAQAAAAQAAAD8/wIAAQAAAAQAAAD8/wMAAQAAAAQAAAD9/wAAAQAAAAQAAAD9/wEAAQAAAAQAAAD9/wIAAQAAAAQAAAD9/wMAAQAAAAQAAAD+/wAAAQAAAAQAAAD+/wEAAQAAAAQAAAD+/wIAAQAAAAQAAAD+/wMAAQAAAAQAAAD//wAAAQAAAAQAAAD//wEAAQAAAAQAAAD//wIAAQAAAAQAAAD//wMAAQAAAAQAAAAAAPz/AQAAAAQAAAAAAP3/AQAAAAQAAAAAAP7/AQAAAAQAAAAAAP//AQAAAAQAAAAAAAAAAQAAAAQAAAAAAAEAAQAAAAQAAAAAAAIAAQAAAAQAAAAAAAMAAQAAAAQAAAABAPz/AQAAAAQAAAABAP3/AQAAAAQAAAABAP7/AQAAAAQAAAABAP//AQAAAAQAAAABAAAAAQAAAAQAAAABAAEAAQAAAAQAAAABAAIAAQAAAAQAAAABAAMAAQAAAAQAAAACAPz/AQAAAAQAAAACAP3/AQAAAAQAAAACAP7/AQAAAAQAAAACAP//AQAAAAQAAAACAAAAAQAAAAQAAAACAAEAAQAAAAQAAAACAAIAAQAAAAQAAAACAAMAAQAAAAQAAAADAPz/AQAAAAQAAAADAP3/AQAAAAQAAAADAP7/AQAAAAQAAAADAP//AQAAAAQAAAADAAAAAQAAAAQAAAADAAEAAQAAAAQAAAADAAIAAQAAAAQAAAADAAMAAQAAAAQAAAD6//v/AQAAAAQAAAD6//z/AQAAAAQAAAD6//3/AQAAAAQAAAD6//7/AQAAAAQAAAD6////AQAAAAQAAAD6/wAAAQAAAAQAAAD6/wEAAQAAAAQAAAD6/wIAAQAAAAQAAAD6/wMAAQAAAAQAAAD6/wQAAQAAAAQAAAD6/wUAAQAAAAQAAAD7//v/AQAAAAQAAAD7//z/AQAAAAQAAAD7//3/AQAAAAQAAAD7//7/AQAAAAQAAAD7////AQAAAAQAAAD7/wAAAQAAAAQAAAD7/wEAAQAAAAQAAAD7/wIAAQAAAAQAAAD7/wMAAQAAAAQAAAD7/wQAAQAAAAQAAAD7/wUAAQAAAAQAAAD8//v/AQAAAAQAAAD8/wQAAQAAAAQAAAD8/wUAAQAAAAQAAAD9//v/AQAAAAQAAAD9/wQAAQAAAAQAAAD9/wUAAQAAAAQAAAD+//v/AQAAAAQAAAD+/wQAAQAAAAQAAAD+/wUAAQAAAAQAAAD///v/AQAAAAQAAAD//wQAAQAAAAQAAAD//wUAAQAAAAQAAAAAAPv/AQAAAAQAAAAAAAQAAQAAAAQAAAAAAAUAAQAAAAQAAAABAPv/AQAAAAQAAAABAAQAAQAAAAQAAAABAAUAAQAAAAQAAAACAPv/AQAAAAQAAAACAAQAAQAAAAQAAAACAAUAAQAAAAQAAAADAPr/AQABAAQAAAADAPv/AQAAAAQAAAADAAQAAQAAAAQAAAADAAUAAQAAAAQAAAAEAPr/AQABAAQAAAAEAPv/AQABAAQAAAAEAPz/AQABAAQAAAAEAP3/AQABAAQAAAAEAP7/AQAAAAQAAAAEAP//AQAAAAQAAAAEAAAAAQAAAAQAAAAEAAEAAQAAAAQAAAAEAAIAAQAAAAQAAAAEAAMAAQAAAAQAAAAEAAQAAQAAAAQAAAAEAAUAAQAAAAQAAAAFAPr/AQABAAQAAAAFAPv/AQABAAQAAAAFAPz/AQABAAQAAAAFAP3/AQABAAQAAAAFAP7/AQAAAAQAAAAFAP//AQAAAAQAAAAFAAAAAQAAAAQAAAAFAAEAAQAAAAQAAAAFAAIAAQAAAAQAAAAFAAMAAQAAAAQAAAAFAAQAAQAAAAQAAAAFAAUAAQAAAAQAAAAGAPj/AQABAAQAAAAGAPn/AQABAAQAAAAGAPr/AQABAAQAAAAGAPv/AQABAAQAAAAGAPz/AQABAAQAAAAHAPj/AQABAAQAAAAHAPn/AQABAAQAAAAHAPr/AQABAAQAAAAHAPv/AQABAAQAAAAHAPz/AQABAAQAAAAIAPj/AQABAAQAAAAIAPn/AQABAAQAAAAIAPr/AQABAAQAAAAIAPv/AQABAAQAAAAIAPz/AQABAAQAAAAJAPj/AQABAAQAAAAJAPn/AQABAAQAAAAJAPr/AQABAAQAAAAJAPv/AQABAAQAAAAJAPz/AQABAAQAAAAKAPj/AQABAAQAAAAKAPn/AQABAAQAAAAKAPr/AQABAAQAAAAKAPv/AQABAAQAAAAKAPz/AQABAAQAAAAEAPn/AQABAAQAAAAGAP3/AQABAAQAAAAHAP3/AQABAAQAAAAIAP3/AQABAAQAAAAIAP7/AQABAAQAAAAHAP7/AQABAAQAAAAEAPj/AQABAAQAAAAEAPf/AQABAAQAAAAFAPf/AQABAAQAAAAFAPj/AQABAAQAAAAFAPn/AQABAAQAAAAHAPf/AQABAAQAAAAGAPf/AQABAAQAAAAIAPf/AQABAAQAAAAJAPf/AQABAAQAAAAKAPf/AQABAAQAAAALAPn/AQABAAQAAAALAPr/AQABAAQAAAALAPv/AQABAAQAAAAKAP3/AQABAAQAAAAJAP3/AQABAAQAAAD3//v/AQAAAAQAAAD3//z/AQAAAAQAAAD3//3/AQAAAAQAAAD3//7/AQAAAAQAAAD3////AQAAAAQAAAD3/wAAAQAAAAQAAAD3/wEAAQAAAAQAAAD3/wIAAQAAAAQAAAD3/wMAAQAAAAQAAAD3/wQAAQAAAAQAAAD3/wUAAQAAAAQAAAD4//v/AQAAAAQAAAD4//z/AQAAAAQAAAD4//3/AQAAAAQAAAD4//7/AQAAAAQAAAD4////AQAAAAQAAAD4/wAAAQAAAAQAAAD4/wEAAQAAAAQAAAD4/wIAAQAAAAQAAAD4/wMAAQAAAAQAAAD4/wQAAQAAAAQAAAD4/wUAAQAAAAQAAAD5//v/AQAAAAQAAAD5//z/AQAAAAQAAAD5//3/AQAAAAQAAAD5//7/AQAAAAQAAAD5////AQAAAAQAAAD5/wAAAQAAAAQAAAD5/wEAAQAAAAQAAAD5/wIAAQAAAAQAAAD5/wMAAQAAAAQAAAD5/wQAAQAAAAQAAAD5/wUAAQAAAAQAAAAGAP//AQAAAAQAAAAGAAAAAQAAAAQAAAAGAAEAAQAAAAQAAAAGAAIAAQAAAAQAAAAGAAMAAQAAAAQAAAAGAAQAAQAAAAQAAAAGAAUAAQAAAAQAAAAHAP//AQAAAAQAAAAHAAAAAQAAAAQAAAAHAAEAAQAAAAQAAAAHAAIAAQAAAAQAAAAHAAMAAQAAAAQAAAAHAAQAAQAAAAQAAAAHAAUAAQAAAAQAAAAIAP//AQAAAAQAAAAIAAAAAQAAAAQAAAAIAAEAAQAAAAQAAAAIAAIAAQAAAAQAAAAIAAMAAQAAAAQAAAAIAAQAAQAAAAQAAAAIAAUAAQAAAAQAAAAJAP//AQAAAAQAAAAJAAAAAQAAAAQAAAAJAAEAAQAAAAQAAAAJAAIAAQAAAAQAAAAJAAMAAQAAAAQAAAAJAAQAAQAAAAQAAAAJAAUAAQAAAAQAAAAJAP7/AQABAAQAAAAGAP7/AQABAAQAAAA=")
|
||||
tile_set = ExtResource("1_m1b5j")
|
||||
|
||||
[node name="Foreground" type="TileMapLayer" parent="."]
|
||||
[node name="Foreground" type="TileMapLayer" parent="Root"]
|
||||
tile_map_data = PackedByteArray("AAD/////AQAAAAMAAAAEAAEAAQAAAAIAAAADAAEAAQAAAAIAAAADAAIAAQAAAAIAAAADAAMAAQAAAAIAAAACAAMAAQAAAAIAAAAFAAMAAQABAAIAAAAGAAMAAQABAAIAAAD8//3/AQABAAMAAAD9//3/AQABAAMAAAD9//7/AQABAAMAAAD9/wAAAQABAAMAAAD9/wEAAQABAAMAAAD8/wEAAQABAAMAAAAEAPv/AQACAAMAAAAGAP3/AQACAAMAAAAHAP7/AQACAAMAAAAIAP7/AQACAAMAAAAJAP7/AQACAAMAAAAGAPn/AQACAAMAAAAGAPr/AQACAAMAAAAGAPv/AQACAAMAAAAHAPv/AQACAAMAAAAIAPv/AQACAAMAAAAIAPz/AQACAAMAAAAJAPz/AQACAAMAAAAKAPz/AQACAAMAAAAKAPv/AQACAAMAAAAJAPv/AQACAAMAAAAIAPr/AQACAAMAAAAHAPr/AQACAAMAAAAHAPn/AQACAAMAAAD3//v/AQABAAMAAAD3//z/AQABAAMAAAD3//3/AQABAAMAAAD3//7/AQABAAMAAAD3////AQABAAMAAAD3/wAAAQABAAMAAAD3/wEAAQABAAMAAAD3/wIAAQABAAMAAAD4//v/AQABAAMAAAD4//z/AQABAAMAAAD4//3/AQABAAMAAAD4//7/AQABAAMAAAD4////AQABAAMAAAD4/wAAAQABAAMAAAD4/wEAAQABAAMAAAD4/wIAAQABAAMAAAD3/wMAAQABAAMAAAD3/wQAAQABAAMAAAD3/wUAAQABAAMAAAD4/wMAAQABAAMAAAD4/wQAAQABAAMAAAD4/wUAAQABAAMAAAD5/wUAAQABAAMAAAD6/wUAAQABAAMAAAD7/wUAAQABAAMAAAD8/wUAAQABAAMAAAD9/wUAAQABAAMAAAD+/wUAAQABAAMAAAD//wUAAQABAAMAAAAAAAUAAQABAAMAAAABAAUAAQABAAMAAAACAAUAAQABAAMAAAADAAUAAQABAAMAAAAEAAUAAQABAAMAAAAFAAUAAQABAAMAAAAGAAUAAQABAAMAAAAHAAUAAQABAAMAAAAIAAUAAQABAAMAAAAJAAUAAQABAAMAAAD5//v/AQABAAMAAAD6//v/AQABAAMAAAD7//v/AQABAAMAAAD8//v/AQABAAMAAAD9//v/AQABAAMAAAD+//v/AQABAAMAAAD///v/AQABAAMAAAAAAPv/AQABAAMAAAABAPv/AQABAAMAAAACAPv/AQABAAMAAAADAPv/AQABAAMAAAAJAP//AQABAAMAAAAJAAAAAQABAAMAAAAJAAEAAQABAAMAAAAJAAIAAQABAAMAAAAJAAMAAQABAAMAAAAJAAQAAQABAAMAAAD7/wEAAQABAAMAAAD7//3/AQABAAMAAAD6//3/AQABAAMAAAD6/wEAAQABAAMAAAD6//7/AQABAAMAAAD6/wAAAQABAAMAAAA=")
|
||||
tile_set = ExtResource("2_u2ss0")
|
||||
|
||||
[node name="Player" parent="." instance=ExtResource("3_u2ss0")]
|
||||
[node name="Player" parent="Root" instance=ExtResource("3_u2ss0")]
|
||||
|
||||
[node name="TurnManager" type="TurnManager" parent="."]
|
||||
[node name="Camera2D" type="Camera2D" parent="Root"]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use godot::{classes::*, obj::WithBaseField, prelude::*};
|
||||
use godot::{classes::*, prelude::*};
|
||||
|
||||
use crate::{turn::TurnActor, utils};
|
||||
use crate::{turn::*, utils::find_in_parents};
|
||||
|
||||
#[derive(Debug, GodotClass)]
|
||||
#[class(init, base=Node)]
|
||||
|
|
@ -78,70 +78,11 @@ pub struct GridPosition {
|
|||
#[init(val = Vector2::splat(32.0))]
|
||||
grid_size: Vector2,
|
||||
|
||||
#[export]
|
||||
#[init(val = 30.0)]
|
||||
movement_speed: f32,
|
||||
|
||||
#[export_group(name = "Flags")]
|
||||
#[export]
|
||||
#[init(val = false)]
|
||||
ignore_collisions: bool,
|
||||
|
||||
is_moving: bool,
|
||||
target_coords: Vector2i,
|
||||
|
||||
base: Base<Node2D>,
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl INode2D for GridPosition {
|
||||
fn ready(&mut self) {
|
||||
self.target_coords = self.get_coords();
|
||||
}
|
||||
|
||||
fn process(&mut self, delta: f64) {
|
||||
if self.is_moving {
|
||||
let start = self.base().get_global_position();
|
||||
let target_coords = self.target_coords;
|
||||
let movement_speed = self.movement_speed;
|
||||
let end = self.get_target_pos();
|
||||
if start.distance_squared_to(end) <= Self::TILE_SNAP_DIST_SQR {
|
||||
self.base_mut().set_global_position(end);
|
||||
self.is_moving = false;
|
||||
self.signals().finished_moving().emit(target_coords);
|
||||
} else {
|
||||
self.base_mut()
|
||||
.set_global_position(start.lerp(end, movement_speed * delta as f32));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl GridPosition {
|
||||
const TILE_SNAP_DIST_SQR: f32 = 1.0;
|
||||
|
||||
pub fn level(&self) -> Option<Gd<Level>> {
|
||||
Level::find_from_node(self.to_gd().upcast::<Node>())
|
||||
}
|
||||
|
||||
// #[func]
|
||||
// pub fn find_from_node(node: Gd<Node>) -> Option<Gd<Self>> {
|
||||
// let mut current = node.clone();
|
||||
// while let Some(parent) = current.get_parent() {
|
||||
// match parent.try_cast::<Self>() {
|
||||
// Ok(level) => return Some(level),
|
||||
// Err(other) => current = other,
|
||||
// }
|
||||
// }
|
||||
// None
|
||||
// }
|
||||
|
||||
#[func]
|
||||
pub fn get_target_pos(&self) -> Vector2 {
|
||||
self.target_coords.cast_float() * self.grid_size
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn get_coords(&self) -> Vector2i {
|
||||
(self.base().get_global_position() / self.grid_size)
|
||||
|
|
@ -155,41 +96,6 @@ impl GridPosition {
|
|||
self.base_mut()
|
||||
.set_global_position(pos.cast_float() * grid_size);
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn can_move(&self, dir: Vector2i) -> bool {
|
||||
if self.is_moving {
|
||||
return false;
|
||||
}
|
||||
if self.ignore_collisions {
|
||||
return true;
|
||||
}
|
||||
match self.level() {
|
||||
Some(level) => !level.bind().tile_has_collision(self.get_coords() + dir),
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn try_move(&mut self, dir: Vector2i) -> bool {
|
||||
let start_coords = self.target_coords;
|
||||
let target_coords = start_coords + dir;
|
||||
|
||||
if !self.can_move(dir) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.is_moving = true;
|
||||
self.target_coords = target_coords;
|
||||
self.signals().started_moving().emit(start_coords, dir);
|
||||
true
|
||||
}
|
||||
|
||||
#[signal]
|
||||
fn started_moving(from_coords: Vector2i, dir: Vector2i);
|
||||
|
||||
#[signal]
|
||||
fn finished_moving(coords: Vector2i);
|
||||
}
|
||||
|
||||
#[derive(GodotConvert, Var, Export, Clone, Copy, Default, Debug, PartialEq, Eq)]
|
||||
|
|
@ -202,12 +108,16 @@ pub enum ItemKind {
|
|||
#[derive(Debug, GodotClass)]
|
||||
#[class(init, base=Node)]
|
||||
pub struct Gatherer {
|
||||
#[export]
|
||||
grid: Option<Gd<GridPosition>>,
|
||||
#[export]
|
||||
actor: Option<Gd<TurnActor>>,
|
||||
|
||||
#[export]
|
||||
#[init(val = 0)]
|
||||
radius: i32,
|
||||
|
||||
level: Option<Gd<Level>>,
|
||||
grid_position: Option<Gd<GridPosition>>,
|
||||
|
||||
base: Base<Node>,
|
||||
}
|
||||
|
|
@ -215,11 +125,10 @@ pub struct Gatherer {
|
|||
#[godot_api]
|
||||
impl INode for Gatherer {
|
||||
fn ready(&mut self) {
|
||||
self.level = utils::find_in_parents(self.to_gd());
|
||||
self.grid_position = utils::find_in_parents(self.to_gd());
|
||||
let actor = TurnActor::find_from_node(self.to_gd().upcast::<Node>())
|
||||
.expect("Getting Actor in some parent");
|
||||
actor
|
||||
self.level = find_in_parents(self.to_gd());
|
||||
self.actor
|
||||
.as_ref()
|
||||
.expect("getting Actor")
|
||||
.signals()
|
||||
.turn_ended()
|
||||
.connect_other(self, |this, action| this.on_turn_end(action));
|
||||
|
|
@ -228,8 +137,8 @@ impl INode for Gatherer {
|
|||
|
||||
#[godot_api]
|
||||
impl Gatherer {
|
||||
fn on_turn_end(&self, action: GString) -> Option<()> {
|
||||
let coords = self.grid_position.clone()?.bind().get_coords();
|
||||
fn on_turn_end(&self, _action: GString) -> Option<()> {
|
||||
let coords = self.grid.clone()?.bind().get_coords();
|
||||
if let Some((item, count)) = self.try_gather_tile(coords) {
|
||||
godot_print!("Gathered {count} x {:?}", item);
|
||||
}
|
||||
|
|
@ -256,3 +165,97 @@ impl Gatherer {
|
|||
#[signal]
|
||||
fn gathered(item: ItemKind, count: i32);
|
||||
}
|
||||
|
||||
#[derive(Debug, GodotClass)]
|
||||
#[class(init, base=Node)]
|
||||
pub struct Mover {
|
||||
#[export]
|
||||
#[init(val = 30.0)]
|
||||
movement_speed: f32,
|
||||
|
||||
#[export_group(name = "Flags")]
|
||||
#[export]
|
||||
#[init(val = false)]
|
||||
ignore_collisions: bool,
|
||||
|
||||
is_moving: bool,
|
||||
target_coords: Vector2i,
|
||||
grid: Option<Gd<GridPosition>>,
|
||||
|
||||
base: Base<Node>,
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl INode for Mover {
|
||||
fn ready(&mut self) {
|
||||
self.grid = find_in_parents(self.to_gd());
|
||||
self.target_coords = self.get_grid().bind().get_coords();
|
||||
}
|
||||
|
||||
fn process(&mut self, delta: f64) {
|
||||
if self.is_moving {
|
||||
let start = self.get_grid().get_global_position();
|
||||
let target_coords = self.target_coords;
|
||||
let movement_speed = self.movement_speed;
|
||||
let end = self.get_target_pos();
|
||||
if start.distance_squared_to(end) <= Self::TILE_SNAP_DIST_SQR {
|
||||
self.get_grid().set_global_position(end);
|
||||
self.is_moving = false;
|
||||
self.signals().finished_moving().emit(target_coords);
|
||||
} else {
|
||||
self.get_grid()
|
||||
.set_global_position(start.lerp(end, movement_speed * delta as f32));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl Mover {
|
||||
const TILE_SNAP_DIST_SQR: f32 = 1.0;
|
||||
|
||||
#[func]
|
||||
pub fn get_grid(&self) -> Gd<GridPosition> {
|
||||
self.grid.clone().unwrap()
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn get_target_pos(&self) -> Vector2 {
|
||||
self.target_coords.cast_float() * self.get_grid().bind().grid_size
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn can_move(&self, dir: Vector2i) -> bool {
|
||||
if self.is_moving {
|
||||
return false;
|
||||
}
|
||||
if self.ignore_collisions {
|
||||
return true;
|
||||
}
|
||||
let level: Gd<Level> = find_in_parents(self.to_gd()).unwrap();
|
||||
!level
|
||||
.bind()
|
||||
.tile_has_collision(self.get_grid().bind().get_coords() + dir)
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn try_move(&mut self, dir: Vector2i) -> bool {
|
||||
let start_coords = self.target_coords;
|
||||
let target_coords = start_coords + dir;
|
||||
|
||||
if !self.can_move(dir) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.is_moving = true;
|
||||
self.target_coords = target_coords;
|
||||
self.signals().started_moving().emit(start_coords, dir);
|
||||
true
|
||||
}
|
||||
|
||||
#[signal]
|
||||
fn started_moving(from_coords: Vector2i, dir: Vector2i);
|
||||
|
||||
#[signal]
|
||||
fn finished_moving(coords: Vector2i);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use godot::{
|
||||
classes::{object::ConnectFlags, *},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use crate::utils::find_in_parents;
|
||||
|
||||
#[derive(Debug, GodotClass)]
|
||||
#[class(init, base=Node)]
|
||||
pub struct TurnManager {
|
||||
registered_actors: HashSet<Gd<TurnActor>>,
|
||||
round_queue: Array<Gd<TurnActor>>,
|
||||
current_actor: Option<Gd<TurnActor>>,
|
||||
|
||||
|
|
@ -15,6 +20,11 @@ pub struct TurnManager {
|
|||
#[godot_api]
|
||||
impl INode for TurnManager {
|
||||
fn process(&mut self, _delta: f64) {
|
||||
if let Some(current) = self.current_actor.as_ref() {
|
||||
if !current.is_instance_valid() {
|
||||
self.start_next_turn();
|
||||
}
|
||||
}
|
||||
if self.current_actor.is_none() && self.round_queue.is_empty() {
|
||||
self.start_round();
|
||||
}
|
||||
|
|
@ -23,35 +33,52 @@ impl INode for TurnManager {
|
|||
|
||||
#[godot_api]
|
||||
impl TurnManager {
|
||||
pub fn register(&mut self, actor: Gd<TurnActor>) {
|
||||
self.registered_actors.insert(actor);
|
||||
}
|
||||
|
||||
fn unregister(&mut self, actor: &Gd<TurnActor>) {
|
||||
self.registered_actors.remove(actor);
|
||||
}
|
||||
|
||||
fn unregister_deleted(&mut self) {
|
||||
self.registered_actors
|
||||
.retain(|actor| actor.is_instance_valid() && !actor.is_queued_for_deletion());
|
||||
}
|
||||
|
||||
fn new_round(&self) -> Array<Gd<TurnActor>> {
|
||||
let mut actors: Array<Gd<TurnActor>> = self.registered_actors.iter().cloned().collect();
|
||||
actors.sort_unstable_by(|a, b| a.instance_id().cmp(&b.instance_id()));
|
||||
actors
|
||||
}
|
||||
|
||||
fn start_round(&mut self) {
|
||||
self.round_queue = self.find_sibling_actors();
|
||||
godot_print!("New round: {:?}", self.round_queue);
|
||||
self.unregister_deleted();
|
||||
self.round_queue = self.new_round();
|
||||
self.start_next_turn();
|
||||
}
|
||||
|
||||
fn start_next_turn(&mut self) {
|
||||
self.current_actor = self.round_queue.pop();
|
||||
if let Some(mut actor) = self.current_actor.clone() {
|
||||
actor
|
||||
.signals()
|
||||
.turn_ended()
|
||||
.builder()
|
||||
.flags(ConnectFlags::ONE_SHOT)
|
||||
.connect_other_mut(self, |this, _action| this.start_next_turn());
|
||||
actor.bind_mut().start_turn();
|
||||
if actor.is_instance_valid() && !actor.is_queued_for_deletion() {
|
||||
godot_print!("Next up: \"{}\" {:?}", actor.get_path(), actor);
|
||||
actor
|
||||
.signals()
|
||||
.turn_ended()
|
||||
.builder()
|
||||
.flags(ConnectFlags::ONE_SHOT)
|
||||
.connect_other_mut(self, Self::on_actor_turn_end);
|
||||
actor.bind_mut().start_turn();
|
||||
} else {
|
||||
self.unregister(&actor);
|
||||
self.start_next_turn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_sibling_actors(&self) -> Array<Gd<TurnActor>> {
|
||||
let mut actors: Array<Gd<TurnActor>> = Array::new();
|
||||
self.base()
|
||||
.get_parent()
|
||||
.unwrap()
|
||||
.get_children()
|
||||
.iter_shared()
|
||||
.filter_map(|node| node.try_cast::<TurnActor>().ok())
|
||||
.for_each(|actor| actors.push(&actor));
|
||||
actors
|
||||
fn on_actor_turn_end(&mut self, _action: GString) {
|
||||
self.start_next_turn();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,6 +117,14 @@ pub struct TurnActor {
|
|||
#[godot_api]
|
||||
impl INode2D for TurnActor {
|
||||
fn ready(&mut self) {}
|
||||
|
||||
fn enter_tree(&mut self) {
|
||||
let manager: Option<Gd<TurnManager>> = find_in_parents(self.to_gd());
|
||||
match manager {
|
||||
Some(mut manager) => manager.bind_mut().register(self.to_gd()),
|
||||
None => godot_error!("No TurnManager found for TurnActor"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
|
|
@ -99,18 +134,6 @@ impl TurnActor {
|
|||
self.state
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn find_from_node(node: Gd<Node>) -> Option<Gd<Self>> {
|
||||
let mut current = node.clone();
|
||||
while let Some(parent) = current.get_parent() {
|
||||
match parent.try_cast::<Self>() {
|
||||
Ok(level) => return Some(level),
|
||||
Err(other) => current = other,
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn get_current_action(&self) -> Variant {
|
||||
match self.current_action.clone() {
|
||||
|
|
|
|||
|
|
@ -14,3 +14,30 @@ where
|
|||
}
|
||||
None
|
||||
}
|
||||
|
||||
// /// Try to find a child of type `T` with the name `T::class_name()`
|
||||
// pub fn find_by_class_name_in_children<T, U>(parent: Gd<U>) -> Option<Gd<T>>
|
||||
// where
|
||||
// T: Inherits<Node>,
|
||||
// U: Inherits<Node>,
|
||||
// {
|
||||
// parent
|
||||
// .upcast::<Node>()
|
||||
// .try_get_node_as::<T>(&T::class_name().to_string())
|
||||
// }
|
||||
|
||||
// /// Try to find a child of type `T` by iterating over children.
|
||||
// ///
|
||||
// /// Returns only the first result.
|
||||
// pub fn find_by_type_in_children<T, U>(parent: Gd<U>) -> Option<Gd<T>>
|
||||
// where
|
||||
// T: Inherits<Node>,
|
||||
// U: Inherits<Node>,
|
||||
// {
|
||||
// for child in parent.upcast::<Node>().get_children().iter_shared() {
|
||||
// if let Ok(result) = child.try_cast::<T>() {
|
||||
// return Some(result);
|
||||
// }
|
||||
// }
|
||||
// None
|
||||
// }
|
||||
|
|
|
|||
Loading…
Reference in New Issue