1
0
Fork 0

Add defend command

This commit is contained in:
Michaël Lemaire 2022-10-26 20:29:17 +02:00
parent 83b9617edd
commit 2b94671759
14 changed files with 153 additions and 43 deletions

View File

@ -1,8 +1,14 @@
extends Node2D
class_name BattleField
@export var commands: Node
var _ticker1 := 0.0
func _ready():
if not commands:
push_warning("No commands manager set to battlefield")
func _physics_process(delta):
_ticker1 += delta
if _ticker1 > 1.0:
@ -12,5 +18,14 @@ func _physics_process(delta):
func ticker(group_name: String):
get_tree().call_group_flags(SceneTree.GROUP_CALL_DEFERRED, group_name, "tick")
func _on_commands_changed(commander, commands):
get_tree().call_group("unit", "_on_commands_changed", commander, commands)
func _on_commands_changed(comms):
get_tree().call_group("unit", "_on_commands_changed", comms)
func _on_child_entered_tree(node):
if node is Unit:
node.promoted.connect(_send_commands_to_unit.bind(node))
_send_commands_to_unit(node)
func _send_commands_to_unit(unit: Unit):
if commands:
unit._on_commands_changed(commands.get_active())

View File

@ -30,13 +30,19 @@ func _physics_process(delta):
if _spawning_since > spawn_duration:
spawn()
func get_battlefield() -> BattleField:
return find_parent("battlefield") as BattleField
func spawn():
if unit_type:
var unit := unit_type.instantiate()
if unit is Unit:
_spawning_since = min(0.0, _spawning_since - spawn_duration)
# FIXME add to battlefield
unit.player = player
add_child(unit)
var battlefield := get_battlefield()
if battlefield:
battlefield.add_child(unit)
else:
add_child(unit)
unit.global_position = global_position
unit.move_to(delivery)

19
core/tools.gd Normal file
View File

@ -0,0 +1,19 @@
class_name Tools
# Get the nearest node from a list, satisfying a predicate
static func get_nearest(from: Node2D, nodes: Array[Node], predicate: Callable) -> Node2D:
var from_position := from.global_position
var nearest: Node2D = null
var distance := INF
for node in nodes:
if predicate.call(node):
var d := from_position.distance_to(node.global_position)
if d < distance:
distance = d
nearest = node
return nearest
# Get a random position around a fixed position, in a given radius
static func jitter(pos: Vector2, min_dist = 0.0, max_dist = 100.0) -> Vector2:
# TODO uniform distribution
return pos + Vector2.from_angle(randf_range(0.0, PI * 2.0)) * randf_range(min_dist, max_dist)

View File

@ -12,19 +12,19 @@ signal clicked
icon = PlaceholderTexture2D.new()
_check_compose()
@export var color: Color:
@export var player: Node:
set(val):
if val is Color:
color = val
if val is Player:
player = val
else:
color = Color.BLACK
player = null
_check_compose()
@export var code: String
func _compose():
%icon.texture = icon
%badge.self_modulate = color
%badge.self_modulate = player.color if player else Color.GRAY
super._compose()
func apply(container: Node2D, pos: Vector2):

View File

@ -16,7 +16,6 @@ fill_to = Vector2(0.5, 0)
[node name="command" type="Node2D"]
script = ExtResource("1_bwbsk")
color = Color(0, 0, 0, 1)
code = ""
[node name="badge" type="TextureButton" parent="."]

View File

@ -11,7 +11,7 @@ extends Node2D
@export var available_commands: Array[PackedScene]
signal commands_changed(commander, commands)
signal commands_changed(commands)
func _ready():
%stock.visible = false
@ -20,6 +20,7 @@ func _ready():
if available_commands:
for command_scene in available_commands:
var command := command_scene.instantiate()
command.player = player
%stock.add_child(command)
func _show_command_wheel(pos: Vector2):
@ -37,7 +38,6 @@ func _show_command_wheel(pos: Vector2):
for command in %stock.get_children():
# TODO only available
command = command.duplicate()
command.color = player.color
command.position = Vector2.from_angle(inc * idx) * 200.0
command.connect("clicked", _on_wheel_command_clicked.bind(command), CONNECT_ONE_SHOT)
var line := Line2D.new()
@ -55,11 +55,11 @@ func _on_wheel_command_clicked(command: Command):
command.apply(%active, %wheel.position)
command.scale *= 0.5
command.connect("clicked", _on_active_command_clicked.bind(command))
commands_changed.emit(player, %active.get_children())
commands_changed.emit(%active.get_children())
func _on_active_command_clicked(command: Command):
command.queue_free()
commands_changed.emit(player, %active.get_children())
commands_changed.emit(%active.get_children())
func background_clicked(pos):
if %wheel.visible:
@ -68,3 +68,6 @@ func background_clicked(pos):
if camera:
pos = get_viewport().canvas_transform.affine_inverse() * pos
_show_command_wheel(pos)
func get_active():
return %active.get_children()

View File

@ -2,6 +2,8 @@
class_name Unit
extends Composer
signal promoted
@export var sprite: Texture2D:
set(val):
sprite = val
@ -68,9 +70,11 @@ func die():
queue_free()
func promote_chief():
is_chief = true
if player:
add_to_group("chief:" + player.code)
if not is_chief:
is_chief = true
if player:
add_to_group("chief:" + player.code)
promoted.emit()
func set_chief(chief):
if chief is Unit and chief.is_chief and chief != self:

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=8 format=3 uid="uid://c6omib6txy3qh"]
[gd_scene load_steps=9 format=3 uid="uid://c6omib6txy3qh"]
[ext_resource type="PackedScene" uid="uid://ck41r2je85sm3" path="res://core/ui/camera.tscn" id="1_7evrt"]
[ext_resource type="PackedScene" uid="uid://brbtq46uk18gg" path="res://core/battlefield.tscn" id="1_x63ik"]
@ -7,6 +7,7 @@
[ext_resource type="PackedScene" uid="uid://b8uik6q4v35o3" path="res://tac/units/factory.tscn" id="2_wnc50"]
[ext_resource type="PackedScene" uid="uid://xoup4vukp3ni" path="res://core/ui/commands.tscn" id="4_1gkbi"]
[ext_resource type="PackedScene" uid="uid://dr1e0h27nuam" path="res://tac/commands/delivery.tscn" id="5_fi2mi"]
[ext_resource type="PackedScene" uid="uid://cmaup0f5ud8vr" path="res://tac/commands/defend.tscn" id="5_fmegp"]
[node name="main" type="Node2D"]
@ -17,7 +18,7 @@
[node name="commands" parent="." node_paths=PackedStringArray("player", "camera") instance=ExtResource("4_1gkbi")]
player = NodePath("../world/player1")
camera = NodePath("../camera")
available_commands = [ExtResource("5_fi2mi")]
available_commands = [ExtResource("5_fi2mi"), ExtResource("5_fmegp")]
[node name="world" type="Node2D" parent="."]
@ -29,7 +30,8 @@ code = "p1"
color = Color(1, 0, 0, 1)
code = "p2"
[node name="battlefield" parent="world" instance=ExtResource("1_x63ik")]
[node name="battlefield" parent="world" node_paths=PackedStringArray("commands") instance=ExtResource("1_x63ik")]
commands = NodePath("../../commands")
[node name="factory1" parent="world/battlefield" node_paths=PackedStringArray("player") instance=ExtResource("2_wnc50")]
position = Vector2(270, 222)
@ -43,3 +45,4 @@ player = NodePath("../../player2")
[connection signal="scrolled" from="inputs" to="camera" method="scroll"]
[connection signal="zoomed" from="inputs" to="camera" method="change_zoom"]
[connection signal="commands_changed" from="commands" to="world/battlefield" method="_on_commands_changed"]
[connection signal="child_entered_tree" from="world/battlefield" to="world/battlefield" method="_on_child_entered_tree"]

View File

@ -34,6 +34,11 @@ _global_script_classes=[{
"language": &"GDScript",
"path": "res://core/spawner.gd"
}, {
"base": "RefCounted",
"class": &"Tools",
"language": &"GDScript",
"path": "res://core/tools.gd"
}, {
"base": "Composer",
"class": &"Unit",
"language": &"GDScript",
@ -50,6 +55,7 @@ _global_script_class_icons={
"Composer": "",
"Player": "",
"Spawner": "",
"Tools": "",
"Unit": "",
"Weapon": ""
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dgatvtgtb6j8d"
path="res://.godot/imported/defend.png-0d992a483323ca4da1938cf20130bd2f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://tac/assets/commands/defend.png"
dest_files=["res://.godot/imported/defend.png-0d992a483323ca4da1938cf20130bd2f.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

11
tac/commands/defend.tscn Normal file
View File

@ -0,0 +1,11 @@
[gd_scene load_steps=3 format=3 uid="uid://cmaup0f5ud8vr"]
[ext_resource type="PackedScene" uid="uid://b3l4jfjieucrc" path="res://core/ui/command.tscn" id="1_s822j"]
[ext_resource type="Texture2D" uid="uid://dgatvtgtb6j8d" path="res://tac/assets/commands/defend.png" id="2_6gky5"]
[node name="command_defend" instance=ExtResource("1_s822j")]
icon = ExtResource("2_6gky5")
code = "defend"
[node name="icon" parent="." index="1"]
texture = ExtResource("2_6gky5")

View File

@ -11,15 +11,8 @@ func _compose():
$spawner.player = player
super._compose()
func _on_commands_changed(commander, commands):
if commander == player:
var nearest := Vector2(INF, INF)
var distance := INF
for command in commands:
if command.code == "delivery":
var d := position.distance_to(command.position)
if d < distance:
distance = d
nearest = command.position
if distance != INF:
$spawner.delivery = nearest
func _on_commands_changed(commands):
var delivery = Tools.get_nearest(self, commands,
func filter(command): return command.player == player and command.code == "delivery")
if delivery:
$spawner.delivery = delivery.global_position

View File

@ -1,5 +1,7 @@
extends Unit
var current_command := WeakRef.new()
func _compose():
$chief.visible = is_chief
super._compose()
@ -7,17 +9,24 @@ func _compose():
func tick():
chief_maintenance()
# go to nearest enemy
var enemy: Unit = null
var closest := INF
for unit in get_tree().get_nodes_in_group("unit"):
if unit is Unit and unit.player != player:
var distance := global_position.distance_to(unit.global_position)
if distance < closest:
closest = distance
enemy = unit
if is_chief:
var command := current_command.get_ref() as Command
if command and command.global_position.distance_to(global_position) > 100.0:
# go near current command
move_to(Tools.jitter(command.global_position, 50.0, 100.0))
return
else:
var chief = get_chief()
if chief and chief.global_position.distance_to(global_position) > 100.0:
# go near chief
move_to(Tools.jitter(chief.global_position, 50.0, 100.0))
return
var enemy := Tools.get_nearest(self, get_tree().get_nodes_in_group("unit"),
func filter(unit): return unit is Unit and unit.player != player)
if enemy:
move_to(enemy.global_position + Vector2.from_angle(randf_range(0.0, PI * 2.0)) * randf_range(100.0, 300.0))
# go near current target enemy
move_to(Tools.jitter(enemy.global_position, 100.0, 300.0))
$turret.set_target(enemy)
func chief_maintenance():
@ -31,7 +40,15 @@ func chief_maintenance():
var chiefs = list_chiefs()
# TODO sort by distance, experience and subordinate count
if chiefs.size() > 0:
chief = chiefs[0]
set_chief(chiefs[0])
else:
promote_chief()
_compose()
func _on_commands_changed(commands):
if is_chief:
var defend := Tools.get_nearest(self, commands,
func filter(command): return command.player == player and command.code == "defend")
if defend:
current_command = weakref(defend)