Added simple goblonoid creature
parent
56c993e856
commit
e5b39e4bf5
|
|
@ -0,0 +1,10 @@
|
|||
@icon("res://icons/turn_action.svg")
|
||||
extends ActionDecider
|
||||
|
||||
@export var mover: Mover
|
||||
|
||||
func handle_decide_action():
|
||||
var directions = [Vector2i.UP, Vector2i.DOWN, Vector2i.LEFT, Vector2i.RIGHT]
|
||||
if try_perform(MoveAction.new(mover, directions.pick_random())):
|
||||
return
|
||||
try_perform(SkipAction.new())
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://hbrne8wt101n
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://dgiy7a67o1c6i"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://doscvutq8uqmd" path="res://sprites/sheet.png" id="1_4ufx4"]
|
||||
[ext_resource type="Script" uid="uid://swwas6oe75sc" path="res://nodes/mover_sprite_flipper.gd" id="2_d3j4p"]
|
||||
[ext_resource type="Script" uid="uid://hbrne8wt101n" path="res://nodes/creature/ai_wanderer.gd" id="3_4ufx4"]
|
||||
|
||||
[node name="Goblonoid" type="GridPosition"]
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="." node_paths=PackedStringArray("mover")]
|
||||
texture = ExtResource("1_4ufx4")
|
||||
hframes = 8
|
||||
vframes = 8
|
||||
frame = 8
|
||||
script = ExtResource("2_d3j4p")
|
||||
mover = NodePath("../Mover")
|
||||
|
||||
[node name="TurnActor" type="TurnActor" parent="."]
|
||||
|
||||
[node name="ActionDecider" type="Node" parent="." node_paths=PackedStringArray("mover", "actor")]
|
||||
script = ExtResource("3_4ufx4")
|
||||
mover = NodePath("../Mover")
|
||||
actor = NodePath("../TurnActor")
|
||||
metadata/_custom_type_script = "uid://okxdlbfuvb1b"
|
||||
|
||||
[node name="Mover" type="Mover" parent="."]
|
||||
movement_speed = 100.0
|
||||
|
||||
[node name="Gatherer" type="Gatherer" parent="."]
|
||||
|
|
@ -28,9 +28,8 @@ zoom = Vector2(2, 2)
|
|||
|
||||
[node name="TurnActor" type="TurnActor" parent="."]
|
||||
|
||||
[node name="ActionDecider" type="Node2D" parent="." node_paths=PackedStringArray("grid", "mover", "actor")]
|
||||
[node name="ActionDecider" type="Node2D" parent="." node_paths=PackedStringArray("mover", "actor")]
|
||||
script = ExtResource("2_rdx4y")
|
||||
grid = NodePath("..")
|
||||
mover = NodePath("../Mover")
|
||||
actor = NodePath("../TurnActor")
|
||||
metadata/_custom_type_script = "uid://okxdlbfuvb1b"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
@icon("res://icons/turn_action.svg")
|
||||
extends ActionDecider
|
||||
|
||||
@export var grid: GridPosition
|
||||
@export var mover: Mover
|
||||
|
||||
func poll_movement_dir():
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ var manager: GameManager
|
|||
|
||||
func _ready():
|
||||
manager = GameManager.from_node(self)
|
||||
manager.time().time_advanced.connect(_on_time_advance)
|
||||
manager.time().time_of_day_changed.connect(_on_time_of_day_changed)
|
||||
player.entity_inventory.inventory.changed.connect(_on_player_inventory_changed)
|
||||
update_inventory_ui()
|
||||
update_clock_hand(manager.time().day_progress())
|
||||
|
|
@ -21,11 +21,8 @@ func _on_player_inventory_changed():
|
|||
func update_inventory_ui():
|
||||
inventory_ui.update(player.get_inventory())
|
||||
|
||||
func _on_time_advance(_now: int, _advanced_by: int):
|
||||
func _on_time_of_day_changed(_time_of_day: int):
|
||||
update_clock_hand(manager.time().day_progress())
|
||||
|
||||
func update_clock_hand(progress: float):
|
||||
clock_hand.rotation = progress * PI * 2.0
|
||||
|
||||
func on_day_end():
|
||||
print("Day over!")
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ tile_map_data = PackedByteArray("AAD8//z/AQAAAAQAAAD8//3/AQAAAAQAAAD8//7/AQAAAAQ
|
|||
tile_set = ExtResource("1_m1b5j")
|
||||
|
||||
[node name="Foreground" type="TileMapLayer" parent="World"]
|
||||
tile_map_data = PackedByteArray("AAD/////AQAAAAMAAAD8//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/wAAAQABAAMAAAD6/wQAAAAAAAAAAgD5/wQAAAAAAAAAAgD5/wMAAAAAAAAAAgAEAAEAAAAAAAAAAQADAAEAAAAAAAAAAQADAAIAAAAAAAAAAQADAAMAAAAAAAAAAQACAAMAAAAAAAAAAQA=")
|
||||
tile_map_data = PackedByteArray("AAD/////AQAAAAMAAAD8//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/wAAAQABAAMAAAD6/wQAAAAAAAAAAgD5/wQAAAAAAAAAAgD5/wMAAAAAAAAAAgAEAAEAAAAAAAAAAQADAAEAAAAAAAAAAQADAAIAAAAAAAAAAQADAAMAAAAAAAAAAQACAAMAAAAAAAAAAQAEAAMAAAAAAAAAAQAFAAMAAAAAAAAAAQAFAAIAAAAAAAAAAQAFAAEAAAAAAAAAAQAEAAIAAAAAAAAAAwD7//7/AAAAAAAAAwA=")
|
||||
tile_set = ExtResource("2_u2ss0")
|
||||
|
||||
[node name="Player" parent="World" instance=ExtResource("3_u2ss0")]
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.1 KiB |
|
|
@ -1,13 +1,15 @@
|
|||
[gd_resource type="TileSet" load_steps=6 format=3 uid="uid://bxwohuw2p43k1"]
|
||||
[gd_resource type="TileSet" load_steps=7 format=3 uid="uid://bxwohuw2p43k1"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://doscvutq8uqmd" path="res://sprites/sheet.png" id="1_oe62d"]
|
||||
[ext_resource type="PackedScene" uid="uid://8xuvjmyjkpeo" path="res://prefabs/tiles/blueberry.tscn" id="1_rc83b"]
|
||||
[ext_resource type="PackedScene" uid="uid://l72f05nek0y4" path="res://prefabs/tiles/cowberry.tscn" id="2_w3v7n"]
|
||||
[ext_resource type="PackedScene" uid="uid://dgiy7a67o1c6i" path="res://prefabs/creatures/goblonoid.tscn" id="3_nsg88"]
|
||||
|
||||
[sub_resource type="TileSetScenesCollectionSource" id="TileSetScenesCollectionSource_w3v7n"]
|
||||
resource_name = "Entities"
|
||||
scenes/1/scene = ExtResource("1_rc83b")
|
||||
scenes/2/scene = ExtResource("2_w3v7n")
|
||||
scenes/3/scene = ExtResource("3_nsg88")
|
||||
|
||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_rc83b"]
|
||||
texture = ExtResource("1_oe62d")
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ pub struct TimeManager {
|
|||
#[init(val = 40)]
|
||||
day_length: i32,
|
||||
|
||||
#[var(get, set = set_time_of_day)]
|
||||
#[init(val = -1)]
|
||||
day: i32,
|
||||
|
||||
#[var(get)]
|
||||
time_of_day: i32,
|
||||
|
||||
|
|
@ -65,21 +69,37 @@ impl INode for TimeManager {}
|
|||
#[godot_api]
|
||||
impl TimeManager {
|
||||
#[func]
|
||||
pub fn reset_time(&mut self) {
|
||||
self.time_of_day = 0;
|
||||
self.signals().time_resetted().emit();
|
||||
pub fn set_time_of_day(&mut self, value: i32) {
|
||||
self.time_of_day = value;
|
||||
self.signals().time_of_day_changed().emit(value);
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn set_day(&mut self, value: i32) {
|
||||
self.day = value;
|
||||
self.signals().day_changed().emit(value);
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn start_new_day(&mut self) {
|
||||
self.set_time_of_day(0);
|
||||
self.set_day(self.day + 1);
|
||||
GameManager::get(self.to_gd()).propagate_call(calls::ON_DAY_START);
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn advance_time(&mut self, amount: i32) {
|
||||
let new_time = self.time_of_day + amount;
|
||||
self.time_of_day = new_time;
|
||||
self.signals().time_advanced().emit(new_time, amount);
|
||||
if self.time_of_day >= self.day_length {
|
||||
self.set_time_of_day(self.time_of_day + amount);
|
||||
if self.is_day_over() {
|
||||
GameManager::get(self.to_gd()).propagate_call(calls::ON_DAY_END);
|
||||
}
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn is_day_over(&self) -> bool {
|
||||
self.time_of_day >= self.day_length
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn day_progress(&self) -> f32 {
|
||||
self.time_of_day as f32 / self.day_length as f32
|
||||
|
|
@ -91,8 +111,8 @@ impl TimeManager {
|
|||
}
|
||||
|
||||
#[signal]
|
||||
fn time_resetted();
|
||||
fn day_changed(day: i32);
|
||||
|
||||
#[signal]
|
||||
fn time_advanced(now: i32, advanced_by: i32);
|
||||
fn time_of_day_changed(time_of_day: i32);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use godot::{classes::*, prelude::*};
|
||||
use godot::{classes::*, obj::WithBaseField, prelude::*};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
|
|
@ -46,6 +46,20 @@ pub struct Gatherable {
|
|||
base: Base<Node>,
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl INode for Gatherable {
|
||||
fn ready(&mut self) {
|
||||
GameManager::get(self.to_gd())
|
||||
.bind()
|
||||
.turn()
|
||||
.signals()
|
||||
.action_taken()
|
||||
.connect_other(self, |this, actor, action| {
|
||||
this.on_action_taken(actor, action)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl Gatherable {
|
||||
#[func]
|
||||
|
|
@ -63,14 +77,10 @@ impl Gatherable {
|
|||
}
|
||||
|
||||
#[func]
|
||||
fn on_turn_end(&mut self, actor: Option<Gd<TurnActor>>, _action: GString) {
|
||||
fn on_action_taken(&mut self, actor: Gd<TurnActor>, _action: GString) {
|
||||
if self.get_is_picked() {
|
||||
return;
|
||||
}
|
||||
let actor = match actor {
|
||||
Some(actor) => actor,
|
||||
None => return,
|
||||
};
|
||||
let actor_grid = match find_in_parents::<GridPosition, TurnActor>(actor.clone()) {
|
||||
Some(grid) => grid,
|
||||
None => return,
|
||||
|
|
|
|||
|
|
@ -70,9 +70,15 @@ impl TurnManager {
|
|||
.signals()
|
||||
.turn_ended()
|
||||
.builder()
|
||||
.flags(ConnectFlags::ONE_SHOT)
|
||||
// `ConnectFlags::Deferred` prevents double-borrow errors.
|
||||
// The double-borrow occurs when there are 2 actors, and the first one
|
||||
// immediately skips their turn.
|
||||
//
|
||||
// This should be investigated further.
|
||||
.flags(ConnectFlags::ONE_SHOT | ConnectFlags::DEFERRED)
|
||||
.connect_other_mut(self, Self::on_actor_turn_end);
|
||||
actor.bind_mut().start_turn();
|
||||
GameManager::get(self.to_gd()).propagate_call(calls::ON_TURN_START);
|
||||
} else {
|
||||
self.unregister(&actor);
|
||||
self.start_next_turn();
|
||||
|
|
@ -83,12 +89,14 @@ impl TurnManager {
|
|||
}
|
||||
|
||||
fn on_actor_turn_end(&mut self, action: GString) {
|
||||
GameManager::get(self.to_gd())
|
||||
.propagate_call_ex(calls::ON_TURN_END)
|
||||
.args(&varray![self.current_actor, action])
|
||||
.done();
|
||||
GameManager::get(self.to_gd()).propagate_call(calls::ON_TURN_END);
|
||||
let actor = self.current_actor.clone().unwrap();
|
||||
self.signals().action_taken().emit(&actor, &action);
|
||||
self.start_next_turn();
|
||||
}
|
||||
|
||||
#[signal]
|
||||
pub fn action_taken(actor: Gd<TurnActor>, action: GString);
|
||||
}
|
||||
|
||||
#[derive(GodotConvert, Var, Export, Clone, Copy, Default, Debug, PartialEq, Eq)]
|
||||
|
|
|
|||
|
|
@ -1,10 +1,17 @@
|
|||
use godot::prelude::*;
|
||||
|
||||
/// Contains hard-coded method names for `propagate_call`.
|
||||
///
|
||||
/// This project uses the convention, that `propagate_call` should never pass arguments, and if
|
||||
/// arguments are needed, signals should be used instead. `propagate_call` should be called from
|
||||
/// the `GameManager` node.
|
||||
pub mod calls {
|
||||
pub const ON_DAY_START: &str = "on_day_start";
|
||||
pub const ON_DAY_END: &str = "on_day_end";
|
||||
pub const ON_ROUND_START: &str = "on_round_start";
|
||||
pub const ON_ROUND_END: &str = "on_round_end";
|
||||
pub const ON_TURN_START: &str = "on_turn_start";
|
||||
pub const ON_TURN_END: &str = "on_turn_end";
|
||||
pub const ON_DAY_END: &str = "on_day_end";
|
||||
}
|
||||
|
||||
pub fn find_in_parents<T, U>(from: Gd<U>) -> Option<Gd<T>>
|
||||
|
|
|
|||
Loading…
Reference in New Issue