movemeent tweaks
This commit is contained in:
@@ -54,6 +54,8 @@ var claim_button: Button
|
||||
var build_log_camp_button: Button
|
||||
var build_mine_button: Button
|
||||
var build_barracks_button: Button
|
||||
var unit_action_popup: PopupPanel
|
||||
var unit_action_move_button: Button
|
||||
var selected_q := 0
|
||||
var selected_r := 0
|
||||
var selected_can_claim := false
|
||||
@@ -67,6 +69,8 @@ var completed_archer_count := 0
|
||||
var selected_archer_q := 9999
|
||||
var selected_archer_r := 9999
|
||||
var selected_archer_count := 0
|
||||
var pending_move_q := 9999
|
||||
var pending_move_r := 9999
|
||||
var refresh_prompt_active := false
|
||||
var refresh_request_active := false
|
||||
|
||||
@@ -170,9 +174,11 @@ func _build_ui() -> void:
|
||||
grid_view.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
grid_view.tile_hovered.connect(_on_tile_hovered)
|
||||
grid_view.tile_selected.connect(_on_tile_selected)
|
||||
grid_view.tile_action_requested.connect(_on_tile_action_requested)
|
||||
map_layer.add_child(grid_view)
|
||||
|
||||
_build_map_overlays(map_layer)
|
||||
_build_unit_action_menu()
|
||||
|
||||
var bottom_bar := PanelContainer.new()
|
||||
bottom_bar.custom_minimum_size = Vector2(0, 46)
|
||||
@@ -412,6 +418,28 @@ func _build_refresh_dialog() -> void:
|
||||
add_child(refresh_dialog)
|
||||
|
||||
|
||||
func _build_unit_action_menu() -> void:
|
||||
unit_action_popup = PopupPanel.new()
|
||||
unit_action_popup.transparent_bg = true
|
||||
add_child(unit_action_popup)
|
||||
|
||||
var panel := PanelContainer.new()
|
||||
panel.add_theme_stylebox_override("panel", _panel_style(Color(0.06, 0.09, 0.09, 0.96), Color(0.17, 0.78, 0.83), 1, 6))
|
||||
unit_action_popup.add_child(panel)
|
||||
|
||||
var margin := MarginContainer.new()
|
||||
margin.add_theme_constant_override("margin_left", 8)
|
||||
margin.add_theme_constant_override("margin_right", 8)
|
||||
margin.add_theme_constant_override("margin_top", 8)
|
||||
margin.add_theme_constant_override("margin_bottom", 8)
|
||||
panel.add_child(margin)
|
||||
|
||||
unit_action_move_button = _small_button("Move")
|
||||
unit_action_move_button.custom_minimum_size = Vector2(92, 34)
|
||||
unit_action_move_button.pressed.connect(_confirm_unit_move)
|
||||
margin.add_child(unit_action_move_button)
|
||||
|
||||
|
||||
func _on_tile_hovered(q: int, r: int, terrain: String) -> void:
|
||||
if coordinate_label:
|
||||
coordinate_label.text = "Hex q:%d r:%d | %s" % [q, r, terrain]
|
||||
@@ -440,21 +468,62 @@ func _handle_unit_selection_or_move(q: int, r: int) -> bool:
|
||||
|
||||
var archer_count: int = grid_view.get_archer_count_at(q, r)
|
||||
if archer_count > 0:
|
||||
if unit_action_popup:
|
||||
unit_action_popup.hide()
|
||||
selected_archer_q = q
|
||||
selected_archer_r = r
|
||||
selected_archer_count = archer_count
|
||||
grid_view.set_selected_unit_tile(q, r)
|
||||
if coordinate_label:
|
||||
coordinate_label.text = "Selected Archer squad: %d at q:%d r:%d. Select a visible non-rival tile to move." % [archer_count, q, r]
|
||||
return true
|
||||
|
||||
if selected_archer_count > 0:
|
||||
_move_selected_archers(q, r)
|
||||
coordinate_label.text = "Selected Archer squad: %d at q:%d r:%d. Right-click an adjacent visible tile for orders." % [archer_count, q, r]
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
|
||||
func _on_tile_action_requested(q: int, r: int, _terrain: String, screen_position: Vector2) -> void:
|
||||
if not grid_view:
|
||||
return
|
||||
if selected_archer_count <= 0:
|
||||
if unit_action_popup:
|
||||
unit_action_popup.hide()
|
||||
if coordinate_label:
|
||||
coordinate_label.text = "Select an Archer squad before giving orders."
|
||||
return
|
||||
if q == selected_archer_q and r == selected_archer_r:
|
||||
if coordinate_label:
|
||||
coordinate_label.text = "Archer squad is already on that tile."
|
||||
return
|
||||
if not grid_view.is_neighbor(selected_archer_q, selected_archer_r, q, r):
|
||||
if coordinate_label:
|
||||
coordinate_label.text = "Archers can only move to an adjacent tile."
|
||||
return
|
||||
if not grid_view.is_visible_non_rival_tile(q, r):
|
||||
if coordinate_label:
|
||||
coordinate_label.text = "Archers can only move to visible non-rival tiles."
|
||||
return
|
||||
|
||||
pending_move_q = q
|
||||
pending_move_r = r
|
||||
if coordinate_label:
|
||||
coordinate_label.text = "Orders for Archer squad: q:%d r:%d." % [q, r]
|
||||
if unit_action_popup:
|
||||
var popup_size := Vector2i(116, 52)
|
||||
var visible_rect := get_viewport().get_visible_rect()
|
||||
var max_x := int(max(0.0, visible_rect.size.x - popup_size.x - 8.0))
|
||||
var max_y := int(max(0.0, visible_rect.size.y - popup_size.y - 8.0))
|
||||
var popup_position := Vector2i(clampi(int(screen_position.x), 8, max_x), clampi(int(screen_position.y), 8, max_y))
|
||||
unit_action_popup.popup(Rect2i(popup_position, popup_size))
|
||||
|
||||
|
||||
func _confirm_unit_move() -> void:
|
||||
if unit_action_popup:
|
||||
unit_action_popup.hide()
|
||||
if pending_move_q == 9999:
|
||||
return
|
||||
_move_selected_archers(pending_move_q, pending_move_r)
|
||||
|
||||
|
||||
func _can_build_log_camp_on_selected_tile() -> bool:
|
||||
return _can_build_on_selected_tile("Forest")
|
||||
|
||||
@@ -517,6 +586,10 @@ func _clear_selected_archers() -> void:
|
||||
selected_archer_q = 9999
|
||||
selected_archer_r = 9999
|
||||
selected_archer_count = 0
|
||||
pending_move_q = 9999
|
||||
pending_move_r = 9999
|
||||
if unit_action_popup:
|
||||
unit_action_popup.hide()
|
||||
if grid_view:
|
||||
grid_view.clear_selected_unit_tile()
|
||||
|
||||
@@ -961,6 +1034,9 @@ func _move_selected_archers(to_q: int, to_r: int) -> void:
|
||||
if to_q == selected_archer_q and to_r == selected_archer_r:
|
||||
coordinate_label.text = "Archer squad is already on that tile."
|
||||
return
|
||||
if not grid_view.is_neighbor(selected_archer_q, selected_archer_r, to_q, to_r):
|
||||
coordinate_label.text = "Archers can only move to an adjacent tile."
|
||||
return
|
||||
if not grid_view.is_visible_non_rival_tile(to_q, to_r):
|
||||
coordinate_label.text = "Archers can only move to visible non-rival tiles."
|
||||
return
|
||||
|
||||
@@ -2,6 +2,7 @@ extends Control
|
||||
|
||||
signal tile_hovered(q: int, r: int, terrain: String)
|
||||
signal tile_selected(q: int, r: int, terrain: String)
|
||||
signal tile_action_requested(q: int, r: int, terrain: String, screen_position: Vector2)
|
||||
|
||||
const HEX_SIZE := 42.0
|
||||
const ISO_Y_SCALE := 0.56
|
||||
@@ -80,6 +81,14 @@ func _gui_input(event: InputEvent) -> void:
|
||||
var label: String = _tile_display_label(key, data) if visible_tiles.has(key) else "Unexplored"
|
||||
tile_selected.emit(selected_tile.x, selected_tile.y, label)
|
||||
queue_redraw()
|
||||
elif event.button_index == MOUSE_BUTTON_RIGHT and event.pressed:
|
||||
var action_tile := _closest_tile_at(event.position)
|
||||
if action_tile.x != 9999:
|
||||
var action_data: Dictionary = _tile_data(action_tile.x, action_tile.y)
|
||||
var action_key: String = _tile_key(action_tile.x, action_tile.y)
|
||||
var action_label: String = _tile_display_label(action_key, action_data) if visible_tiles.has(action_key) else "Unexplored"
|
||||
tile_action_requested.emit(action_tile.x, action_tile.y, action_label, get_global_mouse_position())
|
||||
accept_event()
|
||||
elif event.button_index == MOUSE_BUTTON_WHEEL_UP and event.pressed:
|
||||
zoom = clampf(zoom + 0.08, 0.65, 1.6)
|
||||
queue_redraw()
|
||||
@@ -229,7 +238,20 @@ func _draw_control_layer(control_tiles: Array, control: String, layer_scale: flo
|
||||
|
||||
|
||||
func _update_hover(mouse_position: Vector2) -> void:
|
||||
var closest: Vector2i = Vector2i(9999, 9999)
|
||||
var closest := _closest_tile_at(mouse_position)
|
||||
|
||||
if closest != hovered_tile:
|
||||
hovered_tile = closest
|
||||
if hovered_tile.x != 9999:
|
||||
var data: Dictionary = _tile_data(hovered_tile.x, hovered_tile.y)
|
||||
var key: String = _tile_key(hovered_tile.x, hovered_tile.y)
|
||||
var terrain: String = _tile_display_label(key, data) if visible_tiles.has(key) else "Unexplored"
|
||||
tile_hovered.emit(hovered_tile.x, hovered_tile.y, terrain)
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _closest_tile_at(mouse_position: Vector2) -> Vector2i:
|
||||
var closest := Vector2i(9999, 9999)
|
||||
var closest_distance: float = 999999.0
|
||||
|
||||
for tile in tiles:
|
||||
@@ -244,14 +266,7 @@ func _update_hover(mouse_position: Vector2) -> void:
|
||||
if closest_distance > HEX_SIZE * zoom:
|
||||
closest = Vector2i(9999, 9999)
|
||||
|
||||
if closest != hovered_tile:
|
||||
hovered_tile = closest
|
||||
if hovered_tile.x != 9999:
|
||||
var data: Dictionary = _tile_data(hovered_tile.x, hovered_tile.y)
|
||||
var key: String = _tile_key(hovered_tile.x, hovered_tile.y)
|
||||
var terrain: String = _tile_display_label(key, data) if visible_tiles.has(key) else "Unexplored"
|
||||
tile_hovered.emit(hovered_tile.x, hovered_tile.y, terrain)
|
||||
queue_redraw()
|
||||
return closest
|
||||
|
||||
|
||||
func _tile_center(q: int, r: int) -> Vector2:
|
||||
@@ -529,6 +544,13 @@ func has_owned_neighbor(q: int, r: int) -> bool:
|
||||
return false
|
||||
|
||||
|
||||
func is_neighbor(q1: int, r1: int, q2: int, r2: int) -> bool:
|
||||
for neighbor in _neighbor_coordinates(q1, r1):
|
||||
if neighbor.x == q2 and neighbor.y == r2:
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func set_completed_archers(count: int) -> void:
|
||||
completed_archer_count = max(0, count)
|
||||
queue_redraw()
|
||||
@@ -660,7 +682,7 @@ func _archer_count_at(q: int, r: int) -> int:
|
||||
if int(unit.get("q", 0)) == q and int(unit.get("r", 0)) == r:
|
||||
count += 1
|
||||
|
||||
if count == 0 and completed_archer_count > 0 and Vector2i(q, r) == _archer_station_tile():
|
||||
if unit_instances.is_empty() and count == 0 and completed_archer_count > 0 and Vector2i(q, r) == _archer_station_tile():
|
||||
count = completed_archer_count
|
||||
|
||||
return count
|
||||
|
||||
@@ -153,6 +153,11 @@ public class UnitTrainingService
|
||||
throw new InvalidOperationException("Select a different destination tile.");
|
||||
}
|
||||
|
||||
if (HexDistance(request.FromQ, request.FromR, request.ToQ, request.ToR) != 1)
|
||||
{
|
||||
throw new InvalidOperationException("Archers can only move to adjacent tiles.");
|
||||
}
|
||||
|
||||
if (!await CanMoveToAsync(username, request.ToQ, request.ToR))
|
||||
{
|
||||
throw new InvalidOperationException("Archers can only move to visible non-rival tiles.");
|
||||
|
||||
Reference in New Issue
Block a user