Skip to content

Commit

Permalink
Make rally point settable to units, closes #102
Browse files Browse the repository at this point in the history
Co-authored-by: dyachan <[email protected]>
  • Loading branch information
Scony and dyachan committed Jan 7, 2025
1 parent f6573cd commit a628ad3
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 30 deletions.
1 change: 1 addition & 0 deletions source/match/MatchSignals.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ signal deselect_all_units
signal setup_and_spawn_unit(unit, transform, player)
signal place_structure(structure_prototype)
signal schedule_navigation_rebake(domain)
signal navigate_unit_to_rally_point(unit, rally_point) # currently, only for human players

# notifications
signal match_started
Expand Down
75 changes: 52 additions & 23 deletions source/match/players/human/UnitActionsController.gd
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
extends Node

const Structure = preload("res://source/match/units/Structure.gd")
const ResourceUnit = preload("res://source/match/units/non-player/ResourceUnit.gd")


class Actions:
Expand All @@ -18,6 +19,7 @@ func _ready():
MatchSignals.terrain_targeted.connect(_on_terrain_targeted)
MatchSignals.unit_targeted.connect(_on_unit_targeted)
MatchSignals.unit_spawned.connect(_on_unit_spawned)
MatchSignals.navigate_unit_to_rally_point.connect(_on_navigate_unit_to_rally_point)


func _try_navigating_selected_units_towards_position(target_point):
Expand Down Expand Up @@ -57,6 +59,7 @@ func _try_setting_rally_points(target_point: Vector3):
for structure in controlled_structures:
var rally_point = structure.find_child("RallyPoint")
if rally_point != null:
rally_point.target_unit = null
rally_point.global_position = target_point


Expand All @@ -76,32 +79,51 @@ func _try_ordering_selected_workers_to_construct_structure(potential_structure):


func _navigate_selected_units_towards_unit(target_unit):
var units_navigated = 0
var at_least_one_unit_navigated = false
for unit in get_tree().get_nodes_in_group("selected_units"):
if not unit.is_in_group("controlled_units"):
continue
if Actions.CollectingResourcesSequentially.is_applicable(unit, target_unit):
unit.action = Actions.CollectingResourcesSequentially.new(target_unit)
units_navigated += 1
elif Actions.AutoAttacking.is_applicable(unit, target_unit):
unit.action = Actions.AutoAttacking.new(target_unit)
units_navigated += 1
elif Actions.Constructing.is_applicable(unit, target_unit):
unit.action = Actions.Constructing.new(target_unit)
units_navigated += 1
elif (
(
target_unit.is_in_group("adversary_units")
or target_unit.is_in_group("controlled_units")
)
and Actions.Following.is_applicable(unit)
):
unit.action = Actions.Following.new(target_unit)
units_navigated += 1
elif Actions.MovingToUnit.is_applicable(unit):
unit.action = Actions.MovingToUnit.new(target_unit)
units_navigated += 1
return units_navigated > 0
if _navigate_unit_towards_unit(unit, target_unit):
at_least_one_unit_navigated = true
return at_least_one_unit_navigated


func _navigate_unit_towards_unit(unit, target_unit):
if Actions.CollectingResourcesSequentially.is_applicable(unit, target_unit):
unit.action = Actions.CollectingResourcesSequentially.new(target_unit)
return true
if Actions.AutoAttacking.is_applicable(unit, target_unit):
unit.action = Actions.AutoAttacking.new(target_unit)
return true
if Actions.Constructing.is_applicable(unit, target_unit):
unit.action = Actions.Constructing.new(target_unit)
return true
if (
(target_unit.is_in_group("adversary_units") or target_unit.is_in_group("controlled_units"))
and Actions.Following.is_applicable(unit)
):
unit.action = Actions.Following.new(target_unit)
return true
if Actions.MovingToUnit.is_applicable(unit):
unit.action = Actions.MovingToUnit.new(target_unit)
return true
if _try_setting_rally_point_to_unit(unit, target_unit):
return true
return false # gdlint: ignore = max-returns


func _try_setting_rally_point_to_unit(unit, target_unit):
if not unit is Structure:
return false
if not target_unit is ResourceUnit and unit.player != target_unit.player:
# it's not allowed to set rally point to enemy at the moment as with current implementation
# the position of enemy unit hidden in the fog of war could be hinted
return false
var rally_point = unit.find_child("RallyPoint")
if rally_point == null:
return false
rally_point.target_unit = target_unit
return true


func _on_terrain_targeted(position):
Expand All @@ -118,3 +140,10 @@ func _on_unit_targeted(unit):

func _on_unit_spawned(unit):
_try_ordering_selected_workers_to_construct_structure(unit)


func _on_navigate_unit_to_rally_point(unit, rally_point):
if rally_point.target_unit != null:
_navigate_unit_towards_unit(unit, rally_point.target_unit)
elif rally_point.global_position != rally_point.get_parent().global_position:
unit.action = Actions.Moving.new(rally_point.global_position)
9 changes: 3 additions & 6 deletions source/match/units/traits/ProductionQueue.gd
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,6 @@ func _finalize_production(former_queue_element):
)
MatchSignals.unit_production_finished.emit(produced_unit, _unit)

# Handle rally point
if _unit.has_node("RallyPoint") and Moving.is_applicable(produced_unit):
var rally_point = _unit.get_node("RallyPoint").global_position

if rally_point != _unit.global_position:
produced_unit.action = Moving.new(rally_point)
var rally_point = _unit.find_child("RallyPoint")
if rally_point != null:
MatchSignals.navigate_unit_to_rally_point.emit(produced_unit, rally_point)
36 changes: 35 additions & 1 deletion source/match/units/traits/RallyPoint.gd
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
extends Node3D

var target_unit = null:
set(a_target_unit):
if target_unit == null and a_target_unit != null:
a_target_unit.tree_exited.connect(_on_target_unit_tree_exited)
hide()
elif target_unit != null and a_target_unit == null:
target_unit.tree_exited.disconnect(_on_target_unit_tree_exited)
_reset_position_to_parent()
if _unit.is_in_group("selected_units"):
show()
target_unit = a_target_unit

@onready var _unit = get_parent()
@onready var _animation_player = find_child("AnimationPlayer")


func _ready():
_animation_player.play("idle")
visible = _unit.is_in_group("selected_units")
_unit.selected.connect(show)
_unit.selected.connect(_show)
_unit.deselected.connect(hide)


func _physics_process(_delta):
if target_unit != null:
global_position = target_unit.global_position


func _show():
if target_unit == null:
show()
else:
var targetability = target_unit.find_child("Targetability")
if targetability != null:
targetability.animate()


func _reset_position_to_parent():
global_position = _unit.global_position


func _on_target_unit_tree_exited():
target_unit = null

0 comments on commit a628ad3

Please sign in to comment.