xyz So, I messed around with what you suggested with your most recent code. I got it working very simply, where it would return a dictionary of all the top most cells, so then I sought to tweak it and make it return the top most cells as long as they didn't have a block directly on top of them.
Example a tower of 4 blocks, that was every other cell would return a dictionary of 4 coords at the same xz. However, it would be accessed by the xz coords and then they would be sorted by another dictionary holding their elevations.
Here is the code, it is quite rough, and I am sure not up to snuff.
extends GridMap
var map_cells: Dictionary
func _ready() -> void:
map_cells = _get_top_cells()
func _get_top_cells() -> Dictionary:
var top_cells: Dictionary
for cells in get_used_cells():
var cell_coords: = Vector2i(cells.x,cells.z)
if not top_cells.has(cell_coords):
top_cells[cell_coords] = []
top_cells[cell_coords].push_back(cells)
for x in top_cells.values():
x.sort_custom(func(a,b): return a.y > b.y)
return _get_moveable_cells(top_cells.values())
func _get_moveable_cells(stack: Array) -> Dictionary:
var new_stack: Dictionary
for grp in stack:
var c: Vector3i = grp[0]
if grp.size() == 1:
new_stack[Vector2i(c.x,c.z)] = {c.y:c}
continue
if grp.size() == 2:
if abs(c.y - grp[1].y) >= 2:
new_stack[Vector2i(c.x,c.z)] = {c.y:c,grp[1].y:grp[1]}
continue
new_stack[Vector2i(c.x,c.z)] = {c.y:c}
continue
if grp.size() > 2:
new_stack[Vector2i(c.x,c.z)] = _sort_elevation(grp)
return new_stack
func _sort_elevation(grp: Array) -> Dictionary:
var sorted: Dictionary
var under: bool
for c in grp:
if grp.find(c) + 1 == grp.size():
return sorted
if abs(c.y - grp[grp.find(c) + 1].y) > 1:
if under:
under = false
sorted[grp[grp.find(c) + 1].y] = grp[grp.find(c) + 1]
continue
sorted.merge({c.y:c,grp[grp.find(c) + 1].y:grp[grp.find(c) + 1]})
print(sorted)
continue
if sorted.get(c.y + 1):
continue
sorted[c.y] = c
under = true
return sorted
I am also going to do some research on how to better search/compare elements in an array, maybe I should more of pop elements out of a stack or something of the sort to search elements.
Edit: I wonder if I could do something like this with slice as well? It isn't finished but I need to go to bed.
func _sort_elevation(grp: Array) -> Dictionary:
var sorted_dict: Dictionary
var sorted: Array
var first:bool = true
for x in grp.size() - 1:
var slice = grp.slice(0,2)
if first:
if abs(slice.front().y - slice.back().y) > 1:
sorted.append(slice.back())
sorted.append(grp.pop_front())
first = false
continue
if abs(slice.front().y - slice.back().y) > 1:
sorted.append(slice.back())
grp.pop_front()
return {}