bugfix, desync, and add UI function
This commit is contained in:
@@ -223,27 +223,64 @@ func find_best_tile_to_grab() -> Dictionary:
|
||||
return best_tile
|
||||
|
||||
func find_nearest_tile_of_type(tile_types: Array) -> Vector2i:
|
||||
"""Find nearest tile matching any type in array."""
|
||||
"""Find nearest tile matching any type in array using optimized spiral search."""
|
||||
var current_pos = actor.current_position
|
||||
var nearest_pos = Vector2i(-1, -1)
|
||||
var nearest_dist = 999999
|
||||
|
||||
if not enhanced_gridmap:
|
||||
return nearest_pos
|
||||
return Vector2i(-1, -1)
|
||||
|
||||
for x in range(enhanced_gridmap.columns):
|
||||
for z in range(enhanced_gridmap.rows):
|
||||
var pos = Vector2i(x, z)
|
||||
var cell = Vector3i(x, 1, z)
|
||||
var item = enhanced_gridmap.get_cell_item(cell)
|
||||
# Optimization: Start check at simple radius
|
||||
# If we find something in the spiral, it is guaranteed to be one of the nearest (by Chebyshev distance logic broadly, or just good enough)
|
||||
|
||||
var max_radius = 25 # Limit search range to prevent full map scans on huge maps
|
||||
if OS.has_feature("mobile"):
|
||||
max_radius = 15 # Stricter limit on mobile
|
||||
|
||||
# Check center first
|
||||
var center_cell = Vector3i(current_pos.x, 1, current_pos.y)
|
||||
if enhanced_gridmap.get_cell_item(center_cell) in tile_types:
|
||||
return current_pos
|
||||
|
||||
for r in range(1, max_radius + 1):
|
||||
# Spiral perimeter:
|
||||
# Top row: (x-r, y-r) to (x+r, y-r)
|
||||
# Bottom row: (x-r, y+r) to (x+r, y+r)
|
||||
# Left col: (x-r, y-r+1) to (x-r, y+r-1)
|
||||
# Right col: (x+r, y-r+1) to (x+r, y+r-1)
|
||||
var found_in_layer = []
|
||||
|
||||
# We'll check the ring. Note: Manhattan distance might be better metric for "nearest"
|
||||
# but layer-by-layer is efficient for finding "close enough" quickly.
|
||||
|
||||
for x_off in range(-r, r + 1):
|
||||
_check_spiral_cell(current_pos.x + x_off, current_pos.y - r, tile_types, found_in_layer) # Top
|
||||
_check_spiral_cell(current_pos.x + x_off, current_pos.y + r, tile_types, found_in_layer) # Bottom
|
||||
|
||||
if item in tile_types:
|
||||
for y_off in range(-r + 1, r):
|
||||
_check_spiral_cell(current_pos.x - r, current_pos.y + y_off, tile_types, found_in_layer) # Left
|
||||
_check_spiral_cell(current_pos.x + r, current_pos.y + y_off, tile_types, found_in_layer) # Right
|
||||
|
||||
if found_in_layer.size() > 0:
|
||||
# If we found candidates in this layer, pick the physically closest one (Euclidean/Manhattan refinement)
|
||||
var nearest_in_layer = found_in_layer[0]
|
||||
var min_dist = 999999
|
||||
for pos in found_in_layer:
|
||||
var dist = abs(pos.x - current_pos.x) + abs(pos.y - current_pos.y)
|
||||
if dist < nearest_dist:
|
||||
nearest_dist = dist
|
||||
nearest_pos = pos
|
||||
if dist < min_dist:
|
||||
min_dist = dist
|
||||
nearest_in_layer = pos
|
||||
return nearest_in_layer
|
||||
|
||||
return nearest_pos
|
||||
return Vector2i(-1, -1)
|
||||
|
||||
func _check_spiral_cell(x: int, z: int, tile_types: Array, result_array: Array):
|
||||
if x < 0 or z < 0 or x >= enhanced_gridmap.columns or z >= enhanced_gridmap.rows:
|
||||
return
|
||||
|
||||
var cell = Vector3i(x, 1, z)
|
||||
var item = enhanced_gridmap.get_cell_item(cell)
|
||||
if item in tile_types:
|
||||
result_array.append(Vector2i(x, z))
|
||||
|
||||
# =============================================================================
|
||||
# Movement Strategy
|
||||
|
||||
Reference in New Issue
Block a user