Add defend command
This commit is contained in:
parent
83b9617edd
commit
2b94671759
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
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
19
core/tools.gd
Normal 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)
|
|
@ -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):
|
||||
|
|
|
@ -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="."]
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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():
|
||||
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:
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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": ""
|
||||
}
|
||||
|
|
BIN
tac/assets/commands/defend.png
Normal file
BIN
tac/assets/commands/defend.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
34
tac/assets/commands/defend.png.import
Normal file
34
tac/assets/commands/defend.png.import
Normal 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
11
tac/commands/defend.tscn
Normal 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")
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue