diff --git a/core/battlefield.gd b/core/battlefield.gd index a1ff695..d3ae50f 100644 --- a/core/battlefield.gd +++ b/core/battlefield.gd @@ -7,7 +7,6 @@ func _physics_process(delta): if _ticker1 > 1.0: _ticker1 -= 1.0 ticker("ticker1") - + func ticker(group_name: String): - for node in get_tree().get_nodes_in_group(group_name): - node.tick() + get_tree().call_group_flags(SceneTree.GROUP_CALL_DEFERRED, group_name, "tick") diff --git a/core/unit.gd b/core/unit.gd index 579abd9..0ecdeb2 100644 --- a/core/unit.gd +++ b/core/unit.gd @@ -13,24 +13,38 @@ extends Composer player = val else: player = null + _check_compose() @export var hitpoints := 1 +@export var rotation_offset := 0.0 + +var chief_ref := WeakRef.new() var target_reached = true -var target_position: Vector2 - +var target_position := Vector2.ZERO +var is_chief := false +var subordinates := 0 + +func _ready(): + target_position = global_position + super._ready() + func _compose(): $sprite.texture = sprite if player: # TODO something more subtle - modulate = player.color + $sprite.self_modulate = player.color if player.code and not Engine.is_editor_hint(): add_to_group("player:" + player.code) func _physics_process(delta): if not target_reached: # TODO use position instead of global_position, once parented to battlefield + var previous = global_position global_position += (target_position - global_position).normalized() * 100.0 * delta + var diff = global_position - previous + if diff.length() > 0.001: + $sprite.rotation = rotation_offset + diff.angle() if global_position == target_position: target_reached = true @@ -44,5 +58,24 @@ func damage(lost_hitpoints: float): if hitpoints <= 0: die() +func get_chief(): + return chief_ref.get_ref() + func die(): + var chief = get_chief() + if chief: + chief.subordinates -= 1 queue_free() + +func promote_chief(): + is_chief = true + if player: + add_to_group("chief:" + player.code) + +func set_chief(chief): + if chief is Unit and chief.is_chief and chief != self: + chief_ref = weakref(chief) + chief.subordinates += 1 + +func list_chiefs(): + return get_tree().get_nodes_in_group("chief:" + player.code) diff --git a/main.tscn b/main.tscn index 3efe8ec..5702f78 100644 --- a/main.tscn +++ b/main.tscn @@ -57,10 +57,12 @@ code = "p2" [node name="factory1" parent="battlefield" node_paths=PackedStringArray("player") instance=ExtResource("2_wnc50")] position = Vector2(270, 222) player = NodePath("../player1") +rotation_offset = null [node name="factory2" parent="battlefield" node_paths=PackedStringArray("player") instance=ExtResource("2_wnc50")] position = Vector2(929, 429) player = NodePath("../player2") +rotation_offset = null [node name="ui" type="CanvasLayer" parent="."] diff --git a/tac/assets/chief.png b/tac/assets/chief.png new file mode 100644 index 0000000..cf9bd69 Binary files /dev/null and b/tac/assets/chief.png differ diff --git a/tac/assets/chief.png.import b/tac/assets/chief.png.import new file mode 100644 index 0000000..8a5d2fd --- /dev/null +++ b/tac/assets/chief.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://thd5ewkoyqys" +path="res://.godot/imported/chief.png-a6284578a3bad27396c97bd14c2503f3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://tac/assets/chief.png" +dest_files=["res://.godot/imported/chief.png-a6284578a3bad27396c97bd14c2503f3.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 diff --git a/tac/units/fighter.gd b/tac/units/fighter.gd index e6fe6ec..ad88b36 100644 --- a/tac/units/fighter.gd +++ b/tac/units/fighter.gd @@ -1,6 +1,12 @@ extends Unit +func _compose(): + $chief.visible = is_chief + super._compose() + func tick(): + chief_maintenance() + # go to nearest enemy var enemy: Unit = null var closest := INF @@ -13,3 +19,19 @@ func tick(): if enemy: move_to(enemy.global_position + Vector2.from_angle(randf_range(0.0, PI * 2.0)) * randf_range(100.0, 300.0)) $turret.set_target(enemy) + +func chief_maintenance(): + if is_chief: + # already chief + return + + var chief = get_chief() + if chief == null: + # find a chief + var chiefs = list_chiefs() + # TODO sort by distance, experience and subordinate count + if chiefs.size() > 0: + chief = chiefs[0] + else: + promote_chief() + _compose() diff --git a/tac/units/fighter.tscn b/tac/units/fighter.tscn index 226ebaf..1776095 100644 --- a/tac/units/fighter.tscn +++ b/tac/units/fighter.tscn @@ -1,15 +1,23 @@ -[gd_scene load_steps=5 format=3 uid="uid://b05ykot10q8no"] +[gd_scene load_steps=6 format=3 uid="uid://b05ykot10q8no"] [ext_resource type="PackedScene" uid="uid://bft45rcp7v3a6" path="res://core/unit.tscn" id="1_2ka4q"] [ext_resource type="Script" path="res://tac/units/fighter.gd" id="2_evq3k"] [ext_resource type="Texture2D" uid="uid://2nhprnyswhyh" path="res://tac/assets/ship_small_1.png" id="2_oablw"] [ext_resource type="PackedScene" uid="uid://byg2bmiy2gia0" path="res://tac/weapons/turret.tscn" id="3_rt3r8"] +[ext_resource type="Texture2D" uid="uid://thd5ewkoyqys" path="res://tac/assets/chief.png" id="4_vo18x"] [node name="fighter" groups=["ticker1"] instance=ExtResource("1_2ka4q")] script = ExtResource("2_evq3k") +sprite = ExtResource("2_oablw") hitpoints = 20 +rotation_offset = 1.5708 [node name="sprite" parent="." index="0"] texture = ExtResource("2_oablw") -[node name="turret" parent="." index="1" instance=ExtResource("3_rt3r8")] +[node name="chief" type="Sprite2D" parent="." index="1"] +position = Vector2(17, -29) +scale = Vector2(0.04, 0.04) +texture = ExtResource("4_vo18x") + +[node name="turret" parent="." index="2" instance=ExtResource("3_rt3r8")]