destination indicator update
This commit is contained in:
@@ -74,6 +74,9 @@ var selected_is_home := false
|
||||
var completed_scout_count := 0
|
||||
var completed_archer_count := 0
|
||||
var completed_peasant_count := 0
|
||||
var selected_scout_q := 9999
|
||||
var selected_scout_r := 9999
|
||||
var selected_scout_count := 0
|
||||
var selected_peasant_id := ""
|
||||
var selected_peasant_q := 9999
|
||||
var selected_peasant_r := 9999
|
||||
@@ -518,8 +521,23 @@ func _handle_unit_selection_or_move(q: int, r: int) -> bool:
|
||||
return false
|
||||
|
||||
var archer_count: int = grid_view.get_archer_count_at(q, r)
|
||||
var scout_count: int = grid_view.get_scout_count_at(q, r)
|
||||
var peasant_id: String = grid_view.get_peasant_id_at(q, r)
|
||||
var peasant_count: int = grid_view.get_peasant_count_at(q, r)
|
||||
if scout_count > 0:
|
||||
if unit_action_popup:
|
||||
unit_action_popup.hide()
|
||||
selected_scout_q = q
|
||||
selected_scout_r = r
|
||||
selected_scout_count = scout_count
|
||||
selected_archer_count = 0
|
||||
selected_peasant_count = 0
|
||||
selected_peasant_id = ""
|
||||
grid_view.set_selected_unit_tile(q, r)
|
||||
if coordinate_label:
|
||||
coordinate_label.text = "Selected Scout squad: %d at q:%d r:%d. Right-click a visible tile for orders." % [scout_count, q, r]
|
||||
return true
|
||||
|
||||
if peasant_count > 0:
|
||||
if unit_action_popup:
|
||||
unit_action_popup.hide()
|
||||
@@ -527,6 +545,7 @@ func _handle_unit_selection_or_move(q: int, r: int) -> bool:
|
||||
selected_peasant_q = q
|
||||
selected_peasant_r = r
|
||||
selected_peasant_count = peasant_count
|
||||
selected_scout_count = 0
|
||||
selected_archer_count = 0
|
||||
grid_view.set_selected_unit_tile(q, r)
|
||||
if coordinate_label:
|
||||
@@ -539,6 +558,7 @@ func _handle_unit_selection_or_move(q: int, r: int) -> bool:
|
||||
selected_archer_q = q
|
||||
selected_archer_r = r
|
||||
selected_archer_count = archer_count
|
||||
selected_scout_count = 0
|
||||
selected_peasant_id = ""
|
||||
selected_peasant_count = 0
|
||||
grid_view.set_selected_unit_tile(q, r)
|
||||
@@ -556,7 +576,8 @@ func _on_tile_action_requested(q: int, r: int, _terrain: String, screen_position
|
||||
var has_building := _location_has_completed_building(location)
|
||||
var has_worker := not _nullable_string(location.get("workerUnitId", "")).is_empty()
|
||||
var selected_peasants := selected_peasant_count > 0
|
||||
if selected_archer_count <= 0 and not selected_peasants and not has_worker:
|
||||
var selected_scouts := selected_scout_count > 0
|
||||
if selected_archer_count <= 0 and not selected_scouts and not selected_peasants and not has_worker:
|
||||
if unit_action_popup:
|
||||
unit_action_popup.hide()
|
||||
if coordinate_label:
|
||||
@@ -566,6 +587,10 @@ func _on_tile_action_requested(q: int, r: int, _terrain: String, screen_position
|
||||
if coordinate_label:
|
||||
coordinate_label.text = "Archer squad is already on that tile."
|
||||
return
|
||||
if selected_scouts and q == selected_scout_q and r == selected_scout_r:
|
||||
if coordinate_label:
|
||||
coordinate_label.text = "Scout squad is already on that tile."
|
||||
return
|
||||
if selected_peasants and not grid_view.is_owned_tile(q, r):
|
||||
if coordinate_label:
|
||||
coordinate_label.text = "Peasants can only move within controlled territory."
|
||||
@@ -580,7 +605,7 @@ func _on_tile_action_requested(q: int, r: int, _terrain: String, screen_position
|
||||
if coordinate_label:
|
||||
coordinate_label.text = "Orders for q:%d r:%d." % [q, r]
|
||||
if unit_action_popup:
|
||||
unit_action_move_button.visible = selected_archer_count > 0 or selected_peasants
|
||||
unit_action_move_button.visible = selected_archer_count > 0 or selected_scouts or selected_peasants
|
||||
unit_action_assign_button.visible = not selected_peasant_id.is_empty() and has_building and not has_worker
|
||||
unit_action_deassign_button.visible = has_worker
|
||||
var popup_size := Vector2i(116, 132)
|
||||
@@ -598,6 +623,8 @@ func _confirm_unit_move() -> void:
|
||||
return
|
||||
if selected_archer_count > 0:
|
||||
_move_selected_archers(pending_move_q, pending_move_r)
|
||||
elif selected_scout_count > 0:
|
||||
_move_selected_scouts(pending_move_q, pending_move_r)
|
||||
elif selected_peasant_count > 0:
|
||||
_move_selected_peasants(pending_move_q, pending_move_r)
|
||||
|
||||
@@ -696,6 +723,9 @@ func _update_action_buttons() -> void:
|
||||
|
||||
|
||||
func _clear_selected_archers() -> void:
|
||||
selected_scout_q = 9999
|
||||
selected_scout_r = 9999
|
||||
selected_scout_count = 0
|
||||
selected_archer_q = 9999
|
||||
selected_archer_r = 9999
|
||||
selected_archer_count = 0
|
||||
@@ -1229,6 +1259,44 @@ func _move_selected_archers(to_q: int, to_r: int) -> void:
|
||||
coordinate_label.text = "Could not contact the unit move service."
|
||||
|
||||
|
||||
func _move_selected_scouts(to_q: int, to_r: int) -> void:
|
||||
if selected_scout_count <= 0:
|
||||
return
|
||||
if to_q == selected_scout_q and to_r == selected_scout_r:
|
||||
coordinate_label.text = "Scout squad is already on that tile."
|
||||
return
|
||||
if not grid_view.is_visible_tile(to_q, to_r):
|
||||
coordinate_label.text = "Scouts can only move to visible tiles."
|
||||
return
|
||||
|
||||
var access_token: String = str(session.get("accessToken", ""))
|
||||
if access_token.is_empty():
|
||||
coordinate_label.text = "No auth token available. Scout squad was not moved."
|
||||
return
|
||||
|
||||
if move_units_request.get_http_client_status() != HTTPClient.STATUS_DISCONNECTED:
|
||||
return
|
||||
|
||||
coordinate_label.text = "Ordering %d Scouts to move to q:%d r:%d..." % [selected_scout_count, to_q, to_r]
|
||||
var error: int = move_units_request.request(
|
||||
LOCATIONS_BASE_URL + "/api/units/move",
|
||||
PackedStringArray([
|
||||
"Content-Type: application/json",
|
||||
"Authorization: Bearer %s" % access_token
|
||||
]),
|
||||
HTTPClient.METHOD_POST,
|
||||
JSON.stringify({
|
||||
"unitType": "Scout",
|
||||
"fromQ": selected_scout_q,
|
||||
"fromR": selected_scout_r,
|
||||
"toQ": to_q,
|
||||
"toR": to_r
|
||||
})
|
||||
)
|
||||
if error != OK:
|
||||
coordinate_label.text = "Could not contact the unit move service."
|
||||
|
||||
|
||||
func _move_selected_peasants(to_q: int, to_r: int) -> void:
|
||||
if selected_peasant_count <= 0:
|
||||
return
|
||||
|
||||
@@ -261,18 +261,99 @@ func _draw_movement_indicators() -> void:
|
||||
var from_r := int(unit.get("r", 0))
|
||||
var to_q := int(unit.get("destinationQ", 0))
|
||||
var to_r := int(unit.get("destinationR", 0))
|
||||
var from_center := _tile_center(from_q, from_r)
|
||||
var route := _movement_route(Vector2i(from_q, from_r), Vector2i(to_q, to_r), str(unit.get("unitType", "")))
|
||||
if route.size() < 2:
|
||||
continue
|
||||
|
||||
var to_center := _tile_center(to_q, to_r)
|
||||
var target_tile: Dictionary = _tile_data(to_q, to_r)
|
||||
var target_height := float(target_tile.get("height", _tile_height(to_q, to_r)))
|
||||
var marker_color := Color(0.98, 0.82, 0.28, 0.92) if str(unit.get("unitType", "")) == "Peasant" else Color(0.38, 0.86, 1.0, 0.92)
|
||||
|
||||
draw_line(from_center, to_center, Color(marker_color.r, marker_color.g, marker_color.b, 0.72), 3.0)
|
||||
draw_circle(from_center, 4.0, Color(marker_color.r, marker_color.g, marker_color.b, 0.88))
|
||||
for index in range(route.size() - 1):
|
||||
var from_center := _tile_center(route[index].x, route[index].y)
|
||||
var next_center := _tile_center(route[index + 1].x, route[index + 1].y)
|
||||
draw_line(from_center, next_center, Color(marker_color.r, marker_color.g, marker_color.b, 0.72), 3.0)
|
||||
draw_circle(from_center, 4.0, Color(marker_color.r, marker_color.g, marker_color.b, 0.88))
|
||||
if index > 0:
|
||||
draw_circle(from_center, 2.5, Color(marker_color.r, marker_color.g, marker_color.b, 0.95))
|
||||
draw_polyline(_closed_points(_hex_points(to_center, target_height + 3.0)), marker_color, 4.0)
|
||||
draw_circle(to_center, 7.0, Color(marker_color.r, marker_color.g, marker_color.b, 0.76))
|
||||
|
||||
|
||||
func _movement_route(start: Vector2i, target: Vector2i, unit_type: String) -> Array[Vector2i]:
|
||||
if unit_type == "Peasant":
|
||||
var owned_route := _owned_route(start, target)
|
||||
if not owned_route.is_empty():
|
||||
return owned_route
|
||||
return _direct_hex_route(start, target)
|
||||
|
||||
|
||||
func _owned_route(start: Vector2i, target: Vector2i) -> Array[Vector2i]:
|
||||
if not owned_tiles.has(_tile_key(target.x, target.y)):
|
||||
return []
|
||||
|
||||
var queue: Array[Vector2i] = [start]
|
||||
var visited := { start: true }
|
||||
var previous := {}
|
||||
var cursor := 0
|
||||
while cursor < queue.size():
|
||||
var current: Vector2i = queue[cursor]
|
||||
cursor += 1
|
||||
if current == target:
|
||||
break
|
||||
|
||||
var neighbors := _neighbor_coordinates(current.x, current.y)
|
||||
neighbors.sort_custom(func(a: Vector2i, b: Vector2i) -> bool:
|
||||
var distance_a := _hex_distance(a.x, a.y, target.x, target.y)
|
||||
var distance_b := _hex_distance(b.x, b.y, target.x, target.y)
|
||||
if distance_a == distance_b:
|
||||
return a.x < b.x if a.y == b.y else a.y < b.y
|
||||
return distance_a < distance_b
|
||||
)
|
||||
for neighbor in neighbors:
|
||||
if visited.has(neighbor) or not owned_tiles.has(_tile_key(neighbor.x, neighbor.y)):
|
||||
continue
|
||||
visited[neighbor] = true
|
||||
previous[neighbor] = current
|
||||
queue.append(neighbor)
|
||||
|
||||
if not visited.has(target):
|
||||
return []
|
||||
|
||||
var route: Array[Vector2i] = [target]
|
||||
var step := target
|
||||
while previous.has(step):
|
||||
step = previous[step]
|
||||
route.push_front(step)
|
||||
return route
|
||||
|
||||
|
||||
func _direct_hex_route(start: Vector2i, target: Vector2i) -> Array[Vector2i]:
|
||||
var route: Array[Vector2i] = [start]
|
||||
var current := start
|
||||
var guard := 0
|
||||
while current != target and guard < 128:
|
||||
var neighbors := _neighbor_coordinates(current.x, current.y)
|
||||
neighbors.sort_custom(func(a: Vector2i, b: Vector2i) -> bool:
|
||||
var distance_a := _hex_distance(a.x, a.y, target.x, target.y)
|
||||
var distance_b := _hex_distance(b.x, b.y, target.x, target.y)
|
||||
if distance_a == distance_b:
|
||||
return a.x < b.x if a.y == b.y else a.y < b.y
|
||||
return distance_a < distance_b
|
||||
)
|
||||
current = neighbors[0]
|
||||
route.append(current)
|
||||
guard += 1
|
||||
return route
|
||||
|
||||
|
||||
func _hex_distance(q1: int, r1: int, q2: int, r2: int) -> int:
|
||||
var s1 := -q1 - r1
|
||||
var s2 := -q2 - r2
|
||||
return max(max(abs(q1 - q2), abs(r1 - r2)), abs(s1 - s2))
|
||||
|
||||
|
||||
func _update_hover(mouse_position: Vector2) -> void:
|
||||
var closest := _closest_tile_at(mouse_position)
|
||||
|
||||
@@ -712,6 +793,10 @@ func is_neighbor(q1: int, r1: int, q2: int, r2: int) -> bool:
|
||||
return false
|
||||
|
||||
|
||||
func get_scout_count_at(q: int, r: int) -> int:
|
||||
return _scout_count_at(q, r)
|
||||
|
||||
|
||||
func set_completed_archers(count: int) -> void:
|
||||
completed_archer_count = max(0, count)
|
||||
queue_redraw()
|
||||
|
||||
@@ -186,9 +186,9 @@ public class UnitTrainingService
|
||||
await RefillMovementAsync(username);
|
||||
|
||||
var normalizedUnitType = NormalizeUnitType(request.UnitType);
|
||||
if (normalizedUnitType != ArcherUnitType && normalizedUnitType != PeasantUnitType)
|
||||
if (normalizedUnitType != ScoutUnitType && normalizedUnitType != ArcherUnitType && normalizedUnitType != PeasantUnitType)
|
||||
{
|
||||
throw new ArgumentException("Only Archers and Peasants can be moved right now.", nameof(request.UnitType));
|
||||
throw new ArgumentException("Only Scouts, Archers, and Peasants can be moved right now.", nameof(request.UnitType));
|
||||
}
|
||||
|
||||
if (request.FromQ == request.ToQ && request.FromR == request.ToR)
|
||||
|
||||
Reference in New Issue
Block a user