Compare commits
2 commits
491d0a0b32
...
7b95fc4959
Author | SHA1 | Date | |
---|---|---|---|
7b95fc4959 | |||
a613e3e735 |
13 changed files with 208 additions and 73 deletions
23
main.tscn
23
main.tscn
|
@ -1,7 +1,6 @@
|
||||||
[gd_scene load_steps=21 format=3 uid="uid://cdaf4bh0jaa45"]
|
[gd_scene load_steps=18 format=3 uid="uid://cdaf4bh0jaa45"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://scripts/game_logic.gd" id="1_uj8ti"]
|
[ext_resource type="Script" path="res://scripts/game_logic.gd" id="1_uj8ti"]
|
||||||
[ext_resource type="Resource" uid="uid://cp0dudi0f5r62" path="res://scenes/templates/templates.tres" id="2_1lypt"]
|
|
||||||
[ext_resource type="Script" path="res://scripts/player.gd" id="2_plgh6"]
|
[ext_resource type="Script" path="res://scripts/player.gd" id="2_plgh6"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bydmcc5d53ldx" path="res://icons/paw_print.svg" id="3_mxakn"]
|
[ext_resource type="Texture2D" uid="uid://bydmcc5d53ldx" path="res://icons/paw_print.svg" id="3_mxakn"]
|
||||||
[ext_resource type="Texture2D" uid="uid://1xh0qil16bkh" path="res://icons/character.svg" id="3_qxmev"]
|
[ext_resource type="Texture2D" uid="uid://1xh0qil16bkh" path="res://icons/character.svg" id="3_qxmev"]
|
||||||
|
@ -11,8 +10,6 @@
|
||||||
[ext_resource type="PackedScene" uid="uid://dtlatmtuggp6x" path="res://scenes/background_nebula/background_nebula.tscn" id="7_sv4lv"]
|
[ext_resource type="PackedScene" uid="uid://dtlatmtuggp6x" path="res://scenes/background_nebula/background_nebula.tscn" id="7_sv4lv"]
|
||||||
[ext_resource type="Script" path="res://scripts/player_ai.gd" id="7_v73fw"]
|
[ext_resource type="Script" path="res://scripts/player_ai.gd" id="7_v73fw"]
|
||||||
[ext_resource type="Script" path="res://scripts/planet.gd" id="8_ve3b1"]
|
[ext_resource type="Script" path="res://scripts/planet.gd" id="8_ve3b1"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cpffyaoh8x5bp" path="res://scenes/ships_fleet/ships_fleet.tscn" id="9_be18b"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://ckfk1xgxfk1c3" path="res://scenes/trail/trail.tscn" id="10_b5ql7"]
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_mxp7y"]
|
[sub_resource type="Resource" id="Resource_mxp7y"]
|
||||||
script = ExtResource("2_plgh6")
|
script = ExtResource("2_plgh6")
|
||||||
|
@ -51,10 +48,11 @@ type = 0
|
||||||
|
|
||||||
[node name="Main" type="Node"]
|
[node name="Main" type="Node"]
|
||||||
|
|
||||||
[node name="GameLogic" type="Node" parent="." node_paths=PackedStringArray("planets_container", "planets_ui")]
|
[node name="GameLogic" type="Node" parent="." node_paths=PackedStringArray("planets_container", "trails_container", "fleets_container", "planets_ui")]
|
||||||
script = ExtResource("1_uj8ti")
|
script = ExtResource("1_uj8ti")
|
||||||
templates = ExtResource("2_1lypt")
|
|
||||||
planets_container = NodePath("../Planets")
|
planets_container = NodePath("../Planets")
|
||||||
|
trails_container = NodePath("../Trails")
|
||||||
|
fleets_container = NodePath("../Fleets")
|
||||||
planets_ui = NodePath("../PlanetsUI")
|
planets_ui = NodePath("../PlanetsUI")
|
||||||
players = Array[ExtResource("2_plgh6")]([SubResource("Resource_mxp7y"), SubResource("Resource_1dtpf"), SubResource("Resource_7wtc7")])
|
players = Array[ExtResource("2_plgh6")]([SubResource("Resource_mxp7y"), SubResource("Resource_1dtpf"), SubResource("Resource_7wtc7")])
|
||||||
planets = Array[ExtResource("8_ve3b1")]([SubResource("Resource_50eg2"), SubResource("Resource_2525o"), SubResource("Resource_irtww"), SubResource("Resource_wdycy")])
|
planets = Array[ExtResource("8_ve3b1")]([SubResource("Resource_50eg2"), SubResource("Resource_2525o"), SubResource("Resource_irtww"), SubResource("Resource_wdycy")])
|
||||||
|
@ -63,11 +61,11 @@ planets = Array[ExtResource("8_ve3b1")]([SubResource("Resource_50eg2"), SubResou
|
||||||
|
|
||||||
[node name="Planets" type="Node2D" parent="."]
|
[node name="Planets" type="Node2D" parent="."]
|
||||||
|
|
||||||
[node name="ShipsFleet" parent="." instance=ExtResource("9_be18b")]
|
[node name="Trails" type="Node2D" parent="."]
|
||||||
position = Vector2(246, 394)
|
|
||||||
count = 29
|
|
||||||
|
|
||||||
[node name="PlanetsUI" type="Control" parent="." node_paths=PackedStringArray("trail")]
|
[node name="Fleets" type="Node2D" parent="."]
|
||||||
|
|
||||||
|
[node name="PlanetsUI" type="Control" parent="." node_paths=PackedStringArray("trails_container")]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
|
@ -76,7 +74,4 @@ grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
script = ExtResource("7_khbdl")
|
script = ExtResource("7_khbdl")
|
||||||
trail = NodePath("Trail")
|
trails_container = NodePath("../Trails")
|
||||||
|
|
||||||
[node name="Trail" parent="PlanetsUI" instance=ExtResource("10_b5ql7")]
|
|
||||||
visible = false
|
|
||||||
|
|
|
@ -12,10 +12,11 @@ config_version=5
|
||||||
|
|
||||||
config/name="Space Capture"
|
config/name="Space Capture"
|
||||||
run/main_scene="res://main.tscn"
|
run/main_scene="res://main.tscn"
|
||||||
config/features=PackedStringArray("4.2", "GL Compatibility")
|
config/features=PackedStringArray("4.3", "GL Compatibility")
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
[rendering]
|
[rendering]
|
||||||
|
|
||||||
renderer/rendering_method="mobile"
|
renderer/rendering_method="gl_compatibility"
|
||||||
|
renderer/rendering_method.mobile="gl_compatibility"
|
||||||
environment/defaults/default_clear_color=Color(0, 0, 0, 1)
|
environment/defaults/default_clear_color=Color(0, 0, 0, 1)
|
||||||
|
|
|
@ -15,6 +15,7 @@ seamless = true
|
||||||
noise = SubResource("FastNoiseLite_xihql")
|
noise = SubResource("FastNoiseLite_xihql")
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_m4mhh"]
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_m4mhh"]
|
||||||
|
resource_local_to_scene = true
|
||||||
shader = ExtResource("1_tl7a6")
|
shader = ExtResource("1_tl7a6")
|
||||||
shader_parameter/size = 100.0
|
shader_parameter/size = 100.0
|
||||||
shader_parameter/rotationSpeed = 0.05
|
shader_parameter/rotationSpeed = 0.05
|
||||||
|
|
|
@ -1,37 +1,70 @@
|
||||||
extends Node2D
|
extends Node2D
|
||||||
class_name ShipFleet
|
class_name ShipsFleet
|
||||||
|
|
||||||
@export var departed_at: int
|
@export var departed_at: float # Time.get_ticks_msec()
|
||||||
|
|
||||||
@export var arrives_at: int
|
@export var arrives_at: float # Time.get_ticks_msec()
|
||||||
|
|
||||||
@export var from: Vector2
|
@export var from: Vector2
|
||||||
|
|
||||||
@export var to: Vector2
|
@export var to: Vector2
|
||||||
|
|
||||||
|
@export var player: Player
|
||||||
|
|
||||||
@export var count: int :
|
@export var count: int :
|
||||||
set(value):
|
set(value):
|
||||||
count = value
|
count = value
|
||||||
_update_instances_count()
|
_update__instances_count()
|
||||||
|
|
||||||
|
@export var trail: Trail
|
||||||
|
|
||||||
|
var _game: GameState
|
||||||
|
|
||||||
|
func register_game(game: GameState) -> void:
|
||||||
|
_game = game
|
||||||
|
_game.game_ticked.connect(_update_position)
|
||||||
|
_update_position(game.current_tick)
|
||||||
|
|
||||||
|
func _exit_tree() -> void:
|
||||||
|
if _game != null:
|
||||||
|
_game.game_ticked.disconnect(_update_position)
|
||||||
|
_game = null
|
||||||
|
|
||||||
#region Graphics
|
#region Graphics
|
||||||
|
|
||||||
var instances: Array[Node2D] = []
|
var _instances: Array[Node2D] = []
|
||||||
|
|
||||||
@export var ship_template: PackedScene
|
@export var ship_template: PackedScene
|
||||||
|
|
||||||
func _update_instances_count() -> void :
|
func _update__instances_count() -> void:
|
||||||
var diff = count - instances.size()
|
var diff = count - _instances.size()
|
||||||
|
|
||||||
for i in range(diff):
|
for i in range(diff):
|
||||||
var j = float(1 + instances.size())
|
var j = float(1 + _instances.size())
|
||||||
var ship := ship_template.instantiate()
|
var ship := ship_template.instantiate()
|
||||||
add_child(ship)
|
add_child(ship)
|
||||||
ship.position = Vector2.from_angle(j) * j * 2.
|
ship.position = Vector2.from_angle(j) * j * 2.
|
||||||
instances.push_back(ship)
|
_instances.push_back(ship)
|
||||||
|
|
||||||
for i in range(-diff):
|
for i in range(-diff):
|
||||||
var ship: Node2D = instances.pop_back()
|
var ship: Node2D = _instances.pop_back()
|
||||||
remove_child(ship)
|
remove_child(ship)
|
||||||
|
|
||||||
|
var _arrived := false
|
||||||
|
|
||||||
|
func _update_position(tick: int) -> void:
|
||||||
|
if not _arrived:
|
||||||
|
var clamped_tick := clampi(tick, departed_at, arrives_at)
|
||||||
|
var progress := float(clamped_tick - departed_at) / float(arrives_at - departed_at)
|
||||||
|
position = lerp(from, to, smoothstep(0., 1., progress))
|
||||||
|
if tick >= arrives_at:
|
||||||
|
_arrived = true
|
||||||
|
trail.show = false
|
||||||
|
|
||||||
|
for ship in _instances:
|
||||||
|
ship.emitting = false
|
||||||
|
|
||||||
|
await get_tree().create_timer(5.).timeout
|
||||||
|
queue_free()
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
10
scenes/templates/scene_templates.gd
Normal file
10
scenes/templates/scene_templates.gd
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
class_name SceneTemplates
|
||||||
|
extends Resource
|
||||||
|
|
||||||
|
static var scenes = preload("res://scenes/templates/scene_templates.tres")
|
||||||
|
|
||||||
|
@export var control_planet: PackedScene
|
||||||
|
|
||||||
|
@export var trail: PackedScene
|
||||||
|
|
||||||
|
@export var ships_fleet: PackedScene
|
12
scenes/templates/scene_templates.tres
Normal file
12
scenes/templates/scene_templates.tres
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[gd_resource type="Resource" script_class="TemplateScenes" load_steps=5 format=3 uid="uid://cp0dudi0f5r62"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dq00mi6jwsa1f" path="res://scenes/control_planet/control_planet.tscn" id="1_3rbtf"]
|
||||||
|
[ext_resource type="Script" path="res://scenes/templates/scene_templates.gd" id="1_yvn3m"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cpffyaoh8x5bp" path="res://scenes/ships_fleet/ships_fleet.tscn" id="3_x17ul"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://ckfk1xgxfk1c3" path="res://scenes/trail/trail.tscn" id="4_hiuw1"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1_yvn3m")
|
||||||
|
control_planet = ExtResource("1_3rbtf")
|
||||||
|
trail = ExtResource("4_hiuw1")
|
||||||
|
ships_fleet = ExtResource("3_x17ul")
|
|
@ -1,4 +0,0 @@
|
||||||
class_name TemplateScenes
|
|
||||||
extends Resource
|
|
||||||
|
|
||||||
@export var control_planet: PackedScene
|
|
|
@ -1,8 +0,0 @@
|
||||||
[gd_resource type="Resource" script_class="TemplateScenes" load_steps=3 format=3 uid="uid://cp0dudi0f5r62"]
|
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://dq00mi6jwsa1f" path="res://scenes/control_planet/control_planet.tscn" id="1_3rbtf"]
|
|
||||||
[ext_resource type="Script" path="res://scenes/templates/template_scenes.gd" id="1_yvn3m"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
script = ExtResource("1_yvn3m")
|
|
||||||
control_planet = ExtResource("1_3rbtf")
|
|
|
@ -1,11 +1,19 @@
|
||||||
extends Sprite2D
|
extends Sprite2D
|
||||||
class_name Trail
|
class_name Trail
|
||||||
|
|
||||||
@onready var inv_texture_width = 1. / texture.get_width()
|
static var _inv_texture_width := NAN
|
||||||
|
|
||||||
@export var color: Color :
|
@export var color: Color :
|
||||||
set(value):
|
set(value):
|
||||||
material.set_shader_parameter('color', value)
|
color = value
|
||||||
|
_update_color(color)
|
||||||
|
|
||||||
|
@export var show: bool = true :
|
||||||
|
set(value):
|
||||||
|
show = value
|
||||||
|
visible = true
|
||||||
|
|
||||||
|
@export var auto_free: bool
|
||||||
|
|
||||||
var start_position: Vector2 :
|
var start_position: Vector2 :
|
||||||
set(value):
|
set(value):
|
||||||
|
@ -17,7 +25,31 @@ var end_position: Vector2 :
|
||||||
end_position = value
|
end_position = value
|
||||||
_update_transform(start_position, value)
|
_update_transform(start_position, value)
|
||||||
|
|
||||||
|
var _opacity := 0.
|
||||||
|
|
||||||
func _update_transform(start: Vector2, end: Vector2) -> void:
|
func _update_transform(start: Vector2, end: Vector2) -> void:
|
||||||
global_position = (start + end) * .5
|
global_position = (start + end) * .5
|
||||||
look_at(end)
|
look_at(end)
|
||||||
scale = Vector2((end - start).length() * inv_texture_width, 1.)
|
|
||||||
|
if is_nan(_inv_texture_width):
|
||||||
|
_inv_texture_width = 1. / texture.get_width()
|
||||||
|
|
||||||
|
scale = Vector2((end - start).length() * _inv_texture_width, 1.)
|
||||||
|
|
||||||
|
func _update_color(color: Color) -> void:
|
||||||
|
var c := Color(color.r, color.g, color.b, color.a * _opacity)
|
||||||
|
material.set_shader_parameter('color', c)
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
var prev_opacity := _opacity
|
||||||
|
_opacity = Utils.damp(_opacity, 1. if show else 0., 1e-4, delta)
|
||||||
|
if _opacity != prev_opacity:
|
||||||
|
if _opacity < .01:
|
||||||
|
_opacity = 0.
|
||||||
|
visible = false
|
||||||
|
if auto_free:
|
||||||
|
queue_free()
|
||||||
|
elif _opacity > .99:
|
||||||
|
_opacity = 1.
|
||||||
|
|
||||||
|
_update_color(color)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
[ext_resource type="Script" path="res://scenes/trail/trail.gd" id="3_cnvkj"]
|
[ext_resource type="Script" path="res://scenes/trail/trail.gd" id="3_cnvkj"]
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_f7lnm"]
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_f7lnm"]
|
||||||
|
resource_local_to_scene = true
|
||||||
shader = ExtResource("1_fjdrv")
|
shader = ExtResource("1_fjdrv")
|
||||||
shader_parameter/color = Color(1, 0, 1, 1)
|
shader_parameter/color = Color(1, 0, 1, 1)
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,14 @@ extends Node
|
||||||
const LOGIC_TICKS_PER_SECOND := 20.
|
const LOGIC_TICKS_PER_SECOND := 20.
|
||||||
const LOGIC_SECONDS_PER_TICK := 1. / LOGIC_TICKS_PER_SECOND
|
const LOGIC_SECONDS_PER_TICK := 1. / LOGIC_TICKS_PER_SECOND
|
||||||
|
|
||||||
## Templates for spawnable stuff.
|
|
||||||
@export var templates: TemplateScenes
|
|
||||||
|
|
||||||
## Container for planets.
|
## Container for planets.
|
||||||
@export var planets_container: Node2D
|
@export var planets_container: Node2D
|
||||||
|
## Container for trails.
|
||||||
|
@export var trails_container: Node2D
|
||||||
|
## Container for fleets.
|
||||||
|
@export var fleets_container: Node2D
|
||||||
|
|
||||||
## Interface to interact with planets.
|
## UI to interact with planets.
|
||||||
@export var planets_ui: PlanetsUI
|
@export var planets_ui: PlanetsUI
|
||||||
|
|
||||||
## Game players.
|
## Game players.
|
||||||
|
@ -43,7 +44,7 @@ func _ready() -> void:
|
||||||
_game.add_planet(data)
|
_game.add_planet(data)
|
||||||
|
|
||||||
# UI control.
|
# UI control.
|
||||||
var control: ControlPlanet = templates.control_planet.instantiate()
|
var control: ControlPlanet = SceneTemplates.scenes.control_planet.instantiate()
|
||||||
control.position = planets[i].location
|
control.position = planets[i].location
|
||||||
control.player = players[data.player_id]
|
control.player = players[data.player_id]
|
||||||
control.population = data.population
|
control.population = data.population
|
||||||
|
@ -54,6 +55,7 @@ func _ready() -> void:
|
||||||
# Register UI signals.
|
# Register UI signals.
|
||||||
_game.planet_player_changed.connect(_set_planet_player)
|
_game.planet_player_changed.connect(_set_planet_player)
|
||||||
_game.planet_population_changed.connect(_set_planet_population)
|
_game.planet_population_changed.connect(_set_planet_population)
|
||||||
|
_game.fleet_dispatched.connect(_show_dispatched_fleet)
|
||||||
planets_ui.fleet_dispatched.connect(_dispatch_fleet)
|
planets_ui.fleet_dispatched.connect(_dispatch_fleet)
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
|
@ -63,15 +65,43 @@ func _process(delta: float) -> void:
|
||||||
_extra_time -= LOGIC_SECONDS_PER_TICK
|
_extra_time -= LOGIC_SECONDS_PER_TICK
|
||||||
_game.tick()
|
_game.tick()
|
||||||
|
|
||||||
|
#region Graphics
|
||||||
|
|
||||||
func _set_planet_player(planet_id: int, player_id: int) -> void:
|
func _set_planet_player(planet_id: int, player_id: int) -> void:
|
||||||
_planet_controls[planet_id].player = players[player_id]
|
_planet_controls[planet_id].player = players[player_id]
|
||||||
|
|
||||||
func _set_planet_population(planet_id: int, population: int) -> void:
|
func _set_planet_population(planet_id: int, population: int) -> void:
|
||||||
_planet_controls[planet_id].population = population
|
_planet_controls[planet_id].population = population
|
||||||
|
|
||||||
|
func _show_dispatched_fleet(from_planet_id: int, to_planet_id: int, count: int, player_id: int, departed_at_tick: int, arrives_at_tick: int) -> void:
|
||||||
|
var trail: Trail = SceneTemplates.scenes.trail.instantiate()
|
||||||
|
trail.start_position = planets[from_planet_id].location
|
||||||
|
trail.end_position = planets[to_planet_id].location
|
||||||
|
trail.color = players[player_id].color
|
||||||
|
trail.auto_free = true
|
||||||
|
trails_container.add_child(trail)
|
||||||
|
|
||||||
|
var fleet: ShipsFleet = SceneTemplates.scenes.ships_fleet.instantiate()
|
||||||
|
fleet.departed_at = departed_at_tick
|
||||||
|
fleet.arrives_at = arrives_at_tick
|
||||||
|
fleet.from = planets[from_planet_id].location
|
||||||
|
fleet.to = planets[to_planet_id].location
|
||||||
|
fleet.player = players[player_id]
|
||||||
|
fleet.count = count
|
||||||
|
fleet.trail = trail
|
||||||
|
fleets_container.add_child(fleet)
|
||||||
|
|
||||||
|
fleet.register_game(_game)
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Commands
|
||||||
|
|
||||||
func _dispatch_fleet(from: ControlPlanet, to: ControlPlanet) -> void:
|
func _dispatch_fleet(from: ControlPlanet, to: ControlPlanet) -> void:
|
||||||
var player_id := players.find(from.player)
|
var player_id := players.find(from.player)
|
||||||
var from_planet_id := _planet_controls.find(from)
|
var from_planet_id := _planet_controls.find(from)
|
||||||
var to_planet_id := _planet_controls.find(to)
|
var to_planet_id := _planet_controls.find(to)
|
||||||
var max_count: int = ceil(from.population / 2.)
|
var max_count: int = ceil(from.population / 2.)
|
||||||
_game.dispatch_fleet(player_id, from_planet_id, to_planet_id, max_count)
|
_game.dispatch_fleet(player_id, from_planet_id, to_planet_id, max_count)
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
|
@ -7,11 +7,14 @@ class PlayerData:
|
||||||
class PlanetData:
|
class PlanetData:
|
||||||
var position: Vector2i
|
var position: Vector2i
|
||||||
var grow_every_ticks: int
|
var grow_every_ticks: int
|
||||||
var player_id: int ## 0 = none
|
var player_id: int
|
||||||
var population: int
|
var population: int
|
||||||
|
|
||||||
class FleetData:
|
class FleetData:
|
||||||
var count: int
|
var count: int
|
||||||
|
var player_id: int
|
||||||
|
var to_planet_id: int
|
||||||
|
var arrives_at_tick: int
|
||||||
|
|
||||||
enum CommandType {
|
enum CommandType {
|
||||||
DISPATCH_FLEET,
|
DISPATCH_FLEET,
|
||||||
|
@ -28,9 +31,14 @@ class DispatchFleedCommand extends Command:
|
||||||
func _init():
|
func _init():
|
||||||
type = CommandType.DISPATCH_FLEET
|
type = CommandType.DISPATCH_FLEET
|
||||||
|
|
||||||
|
const NEUTRAL_PLAYER_ID := 0
|
||||||
|
const FLEET_TAKEOFF_PLUS_LANDING_TIME := 20 # ticks
|
||||||
|
const FLEET_SPEED := 2 # pixels/tick
|
||||||
|
|
||||||
signal game_ticked(tick: int)
|
signal game_ticked(tick: int)
|
||||||
signal planet_population_changed(planet_id: int, population: int)
|
signal planet_population_changed(planet_id: int, population: int)
|
||||||
signal planet_player_changed(planet_id: int, player_id: int)
|
signal planet_player_changed(planet_id: int, player_id: int)
|
||||||
|
signal fleet_dispatched(from_planet_id: int, to_planet_id: int, count: int, player_id: int, departed_at_tick: int, arrives_at_tick: int)
|
||||||
|
|
||||||
var _players: Array[PlayerData] = []
|
var _players: Array[PlayerData] = []
|
||||||
var _planets: Array[PlanetData] = []
|
var _planets: Array[PlanetData] = []
|
||||||
|
@ -54,12 +62,14 @@ func add_planet(data := PlanetData.new()) -> int:
|
||||||
func tick() -> void:
|
func tick() -> void:
|
||||||
current_tick += 1
|
current_tick += 1
|
||||||
|
|
||||||
|
# Handle planets growth.
|
||||||
for planet_id in range(_planets.size()):
|
for planet_id in range(_planets.size()):
|
||||||
var planet := _planets[planet_id]
|
var planet := _planets[planet_id]
|
||||||
if planet.player_id != 0 and current_tick % planet.grow_every_ticks == 0:
|
if planet.player_id != NEUTRAL_PLAYER_ID and current_tick % planet.grow_every_ticks == 0:
|
||||||
planet.population += 1
|
planet.population += 1
|
||||||
planet_population_changed.emit(planet_id, planet.population)
|
planet_population_changed.emit(planet_id, planet.population)
|
||||||
|
|
||||||
|
# Handle player commands.
|
||||||
for player_id in range(_players.size()):
|
for player_id in range(_players.size()):
|
||||||
var player := _players[player_id]
|
var player := _players[player_id]
|
||||||
if player.commands.size() > 0 && current_tick >= player.commands[0].wait_tick:
|
if player.commands.size() > 0 && current_tick >= player.commands[0].wait_tick:
|
||||||
|
@ -70,6 +80,11 @@ func tick() -> void:
|
||||||
_:
|
_:
|
||||||
assert(false, "Unknown command: %s" % [command])
|
assert(false, "Unknown command: %s" % [command])
|
||||||
|
|
||||||
|
# Handle fleets arrival.
|
||||||
|
while _fleets.size() > 0 && current_tick >= _fleets[0].arrives_at_tick:
|
||||||
|
var fleet: FleetData = _fleets.pop_back()
|
||||||
|
_handle_fleet_arrival(fleet)
|
||||||
|
|
||||||
game_ticked.emit(current_tick)
|
game_ticked.emit(current_tick)
|
||||||
|
|
||||||
## Dispatch a fleet.
|
## Dispatch a fleet.
|
||||||
|
@ -87,16 +102,31 @@ func _issue_command(player_id: int, command: Command) -> void:
|
||||||
|
|
||||||
func _handle_dispatch_fleet(player_id: int, dispatch: DispatchFleedCommand) -> void:
|
func _handle_dispatch_fleet(player_id: int, dispatch: DispatchFleedCommand) -> void:
|
||||||
var from = _planets[dispatch.from_planet_id]
|
var from = _planets[dispatch.from_planet_id]
|
||||||
|
if from.player_id == player_id:
|
||||||
var to = _planets[dispatch.to_planet_id]
|
var to = _planets[dispatch.to_planet_id]
|
||||||
var count = min(dispatch.max_count, from.population)
|
var count = min(dispatch.max_count, from.population)
|
||||||
from.population -= count
|
from.population -= count
|
||||||
if from.player_id == to.player_id:
|
|
||||||
to.population += count
|
|
||||||
else:
|
|
||||||
to.population -= count
|
|
||||||
if to.population <= 0:
|
|
||||||
to.player_id = from.player_id
|
|
||||||
to.population = abs(from.population)
|
|
||||||
planet_player_changed.emit(dispatch.to_planet_id, to.player_id)
|
|
||||||
planet_population_changed.emit(dispatch.from_planet_id, from.population)
|
planet_population_changed.emit(dispatch.from_planet_id, from.population)
|
||||||
planet_population_changed.emit(dispatch.to_planet_id, to.population)
|
|
||||||
|
var fleet := FleetData.new()
|
||||||
|
fleet.count = count
|
||||||
|
fleet.player_id = player_id
|
||||||
|
fleet.to_planet_id = dispatch.to_planet_id
|
||||||
|
fleet.arrives_at_tick = current_tick + FLEET_TAKEOFF_PLUS_LANDING_TIME + ceili(from.position.distance_to(to.position) / FLEET_SPEED)
|
||||||
|
|
||||||
|
var index := _fleets.map(func (x): return x.arrives_at_tick).bsearch(fleet.arrives_at_tick, false)
|
||||||
|
_fleets.insert(index, fleet)
|
||||||
|
|
||||||
|
fleet_dispatched.emit(dispatch.from_planet_id, fleet.to_planet_id, fleet.count, fleet.player_id, current_tick, fleet.arrives_at_tick)
|
||||||
|
|
||||||
|
func _handle_fleet_arrival(fleet: FleetData) -> void:
|
||||||
|
var to = _planets[fleet.to_planet_id]
|
||||||
|
if fleet.player_id == to.player_id:
|
||||||
|
to.population += fleet.count
|
||||||
|
else:
|
||||||
|
to.population -= fleet.count
|
||||||
|
if to.population <= 0:
|
||||||
|
to.player_id = fleet.player_id
|
||||||
|
to.population = abs(to.population)
|
||||||
|
planet_player_changed.emit(fleet.to_planet_id, to.player_id)
|
||||||
|
planet_population_changed.emit(fleet.to_planet_id, to.population)
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
class_name PlanetsUI
|
class_name PlanetsUI
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
@export var trail: Trail
|
## Container for trails.
|
||||||
|
@export var trails_container: Node2D
|
||||||
|
|
||||||
|
var _trail: Trail
|
||||||
|
|
||||||
signal fleet_dispatched(from: ControlPlanet, to: ControlPlanet)
|
signal fleet_dispatched(from: ControlPlanet, to: ControlPlanet)
|
||||||
|
|
||||||
|
@ -10,6 +13,11 @@ func register_planet(control: ControlPlanet) -> void:
|
||||||
control.pointer_entered.connect(_on_planet_pointer_entered)
|
control.pointer_entered.connect(_on_planet_pointer_entered)
|
||||||
control.pointer_exited.connect(_on_planet_pointer_exited)
|
control.pointer_exited.connect(_on_planet_pointer_exited)
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
_trail = SceneTemplates.scenes.trail.instantiate()
|
||||||
|
_trail.visible = false
|
||||||
|
trails_container.add_child(_trail)
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
_update_trail(delta, false)
|
_update_trail(delta, false)
|
||||||
|
|
||||||
|
@ -63,18 +71,12 @@ func _on_planet_pointer_exited(planet: ControlPlanet) -> void:
|
||||||
|
|
||||||
#region Trail
|
#region Trail
|
||||||
|
|
||||||
var _trail_opacity := 0.
|
|
||||||
|
|
||||||
func _update_trail(delta: float, snap_position: bool) -> void:
|
func _update_trail(delta: float, snap_position: bool) -> void:
|
||||||
var show_trail := _dragging_from_planet and _selected_planet != null and _selected_planet.player is LocalPlayer
|
_trail.show = _dragging_from_planet and _selected_planet != null and _selected_planet.player is LocalPlayer
|
||||||
if show_trail or trail.visible:
|
if _trail.show:
|
||||||
_trail_opacity = Utils.damp(_trail_opacity, 1. if show_trail else 0., 1e-4, delta)
|
_trail.color = _selected_planet.player.color
|
||||||
trail.color = Color(_selected_planet.player.color, _trail_opacity)
|
|
||||||
trail.visible = _trail_opacity > .01
|
|
||||||
|
|
||||||
if show_trail:
|
|
||||||
var target_position = _last_cursor_position if _pointed_planet == null else _pointed_planet.global_position
|
var target_position = _last_cursor_position if _pointed_planet == null else _pointed_planet.global_position
|
||||||
trail.start_position = _selected_planet.global_position
|
_trail.start_position = _selected_planet.global_position
|
||||||
trail.end_position = target_position if snap_position else Utils.damp(trail.end_position, target_position, 1e-20, delta)
|
_trail.end_position = target_position if snap_position else Utils.damp(_trail.end_position, target_position, 1e-20, delta)
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
Loading…
Reference in a new issue