Refactored to use Vector4i. Added Spider/Grasshopper. TODO: Ant
This commit is contained in:
parent
ff4aa93845
commit
11f8a71f52
19 changed files with 482 additions and 326 deletions
|
|
@ -1,3 +1,4 @@
|
|||
extends Node
|
||||
|
||||
var is_player_black: bool = false
|
||||
var debug: bool = true
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
extends Node
|
||||
|
||||
signal insect_selected(insect_resource, is_black)
|
||||
signal insect_selected(button, is_black)
|
||||
signal insect_placed(insect_resource, is_black, position)
|
||||
signal insect_placement_cancelled
|
||||
|
||||
signal insect_tile_selected(tile)
|
||||
signal insect_tile_request_selection(tile)
|
||||
signal insect_tile_selection_request_successful(tile)
|
||||
signal insect_tile_selection_request_failed(tile)
|
||||
signal insect_tile_deselected(tile)
|
||||
signal insect_tile_moved(tile, to)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,13 @@ const DIR_ALL: Array[Vector3] = [DIR_N, DIR_NE, DIR_SE, DIR_S, DIR_SW, DIR_NW]
|
|||
|
||||
#const size = Vector2(1, sqrt(3.0)/2.0)
|
||||
|
||||
# We can hover all of our tiles (will show on-hover shader)
|
||||
# If we click on a placed tile, we do the following
|
||||
# Check if we would split the hive -> deny selection
|
||||
# Get possible movement tiles (via MovementBehaviour)
|
||||
# If 0 -> Deny
|
||||
# Filter remaining movement spots to not include hive-splitting moves(?)
|
||||
|
||||
const size: float = 0.5
|
||||
|
||||
var used_cells: Dictionary = {}
|
||||
|
|
@ -26,30 +33,20 @@ class TileStorage:
|
|||
# we use a vector4i for coordinates
|
||||
# q r s y (layer)
|
||||
|
||||
func add_tile(tile: InsectTile, coords: CubeCoordinates, layer: int = 0) -> void:
|
||||
tiles[Vector4i(coords.q, coords.r, coords.s, layer)] = tile
|
||||
func add_tile(tile: InsectTile, coords: Vector4i) -> void:
|
||||
tiles[coords] = tile
|
||||
pass
|
||||
|
||||
func remove_tile(coords: CubeCoordinates, layer: int = 0) -> void:
|
||||
func remove_tile(coords: Vector4i) -> void:
|
||||
pass
|
||||
|
||||
func has_tile(coords: CubeCoordinates, layer: int = 0) -> bool:
|
||||
return tiles.has(Vector4i(coords.q, coords.r, coords.s, layer))
|
||||
func has_tile(coords: Vector4i) -> bool:
|
||||
return tiles.has(coords)
|
||||
|
||||
func get_tile(coords: CubeCoordinates, layer: int = 0) -> InsectTile:
|
||||
return tiles[Vector4i(coords.q, coords.r, coords.s, layer)]
|
||||
func get_tile(coords: Vector4i) -> InsectTile:
|
||||
return tiles[coords]
|
||||
|
||||
|
||||
class CubeCoordinates:
|
||||
var q: float
|
||||
var r: float
|
||||
var s: float
|
||||
|
||||
func _init(_q: float, _r: float, _s: float):
|
||||
q = _q
|
||||
r = _r
|
||||
s = _s
|
||||
|
||||
class AxialCoordinates:
|
||||
var q: float
|
||||
var r: float
|
||||
|
|
@ -68,7 +65,7 @@ func flat_hex_to_world_position(coords: AxialCoordinates) -> Vector2:
|
|||
var y = size * (sqrt(3.0)/2.0 * coords.q + sqrt(3.0) * coords.r)
|
||||
return Vector2(x, y)
|
||||
|
||||
func cube_to_world_pos(coords: CubeCoordinates) -> Vector2:
|
||||
func cube_to_world_pos(coords: Vector4i) -> Vector2:
|
||||
return flat_hex_to_world_position(cube_to_axial(coords))
|
||||
|
||||
#func world_to_hex_tile(world_pos: Vector3) -> Vector2:
|
||||
|
|
@ -86,28 +83,28 @@ func world_to_hex_tile(coords: Vector2) -> AxialCoordinates:
|
|||
var r = (-1.0/3.0 * coords.x + sqrt(3.0)/3.0 * coords.y) / size
|
||||
return axial_round(AxialCoordinates.new(q, r))
|
||||
|
||||
func axial_to_cube(coords: AxialCoordinates) -> CubeCoordinates:
|
||||
var q = coords.q
|
||||
var r = coords.r
|
||||
var s = -q-r
|
||||
return CubeCoordinates.new(q, r, s)
|
||||
|
||||
func cube_to_axial(coords: CubeCoordinates) -> AxialCoordinates:
|
||||
var q = coords.q
|
||||
var r = coords.r
|
||||
func cube_to_axial(coords: Vector4i) -> AxialCoordinates:
|
||||
var q = coords.x
|
||||
var r = coords.y
|
||||
return AxialCoordinates.new(q, r)
|
||||
|
||||
func axial_round(coords: AxialCoordinates) -> AxialCoordinates:
|
||||
return cube_to_axial(cube_round(axial_to_cube(coords)))
|
||||
|
||||
func cube_round(coords: CubeCoordinates) -> CubeCoordinates:
|
||||
var q: float = round(coords.q)
|
||||
var r: float = round(coords.r)
|
||||
var s: float = round(coords.s)
|
||||
func axial_to_cube(coords: AxialCoordinates) -> Vector4i:
|
||||
var q = coords.q
|
||||
var r = coords.r
|
||||
var s = -q-r
|
||||
return Vector4i(q, r, s, 0)
|
||||
|
||||
var q_diff: float = abs(q - coords.q)
|
||||
var r_diff: float = abs(r - coords.r)
|
||||
var s_diff: float = abs(s - coords.s)
|
||||
func cube_round(coords: Vector4i) -> Vector4i:
|
||||
var q: float = round(coords.x)
|
||||
var r: float = round(coords.y)
|
||||
var s: float = round(coords.z)
|
||||
|
||||
var q_diff: float = abs(q - coords.x)
|
||||
var r_diff: float = abs(r - coords.y)
|
||||
var s_diff: float = abs(s - coords.z)
|
||||
|
||||
if q_diff > r_diff and q_diff > s_diff:
|
||||
q = -r-s
|
||||
|
|
@ -116,7 +113,7 @@ func cube_round(coords: CubeCoordinates) -> CubeCoordinates:
|
|||
else:
|
||||
s = -q-r
|
||||
|
||||
return CubeCoordinates.new(q, r, s)
|
||||
return Vector4i(q, r, s, 0)
|
||||
|
||||
@export var dragging_intersect_plane_normal: Vector3 = Vector3.UP
|
||||
@export var dragging_intersect_plane_distance: float = 0.0
|
||||
|
|
@ -126,105 +123,173 @@ func get_3d_pos(position2D: Vector2):
|
|||
|
||||
var placements: Dictionary = {}
|
||||
|
||||
func is_cell_empty(coords: CubeCoordinates) -> bool:
|
||||
return !used_cells.has(Vector4i(coords.q, coords.r, coords.s, 0))
|
||||
func is_cell_empty(coords: Vector4i) -> bool:
|
||||
return !used_cells.has(coords)
|
||||
|
||||
func is_cell_not_empty(coords: CubeCoordinates) -> bool:
|
||||
func is_cell_not_empty(coords: Vector4i) -> bool:
|
||||
return !is_cell_empty(coords)
|
||||
|
||||
func get_empty_neighbours(coords: CubeCoordinates) -> Array[CubeCoordinates]:
|
||||
func get_empty_neighbours(coords: Vector4i) -> Array[Vector4i]:
|
||||
return get_neighbours(coords).filter(is_cell_empty)
|
||||
|
||||
func get_neighbours(coords: CubeCoordinates) -> Array[CubeCoordinates]:
|
||||
func get_neighbours(coords: Vector4i) -> Array[Vector4i]:
|
||||
return [
|
||||
CubeCoordinates.new(coords.q + 1, coords.r, coords.s - 1),
|
||||
CubeCoordinates.new(coords.q + 1, coords.r - 1, coords.s),
|
||||
CubeCoordinates.new(coords.q, coords.r - 1, coords.s + 1),
|
||||
CubeCoordinates.new(coords.q - 1, coords.r, coords.s + 1),
|
||||
CubeCoordinates.new(coords.q - 1, coords.r + 1, coords.s),
|
||||
CubeCoordinates.new(coords.q, coords.r + 1, coords.s - 1)
|
||||
Vector4i(coords.x + 1, coords.y, coords.z - 1, coords.w),
|
||||
Vector4i(coords.x + 1, coords.y - 1, coords.z, coords.w),
|
||||
Vector4i(coords.x, coords.y - 1, coords.z + 1, coords.w),
|
||||
Vector4i(coords.x - 1, coords.y, coords.z + 1, coords.w),
|
||||
Vector4i(coords.x - 1, coords.y + 1, coords.z, coords.w),
|
||||
Vector4i(coords.x, coords.y + 1, coords.z - 1, coords.w)
|
||||
]
|
||||
|
||||
var current_tile: Node3D
|
||||
|
||||
const HEX_OUTLINE = preload("res://hex_outline.tscn")
|
||||
|
||||
func _on_insect_selected(insect_resource: TileResource, is_black: bool) -> void:
|
||||
func get_placeable_positions(button: InsectButton) -> Array:
|
||||
if used_cells.size() == 0:
|
||||
return [Vector4i.ZERO]
|
||||
elif used_cells.size() == 1:
|
||||
var single_cell = used_cells.keys().front()
|
||||
var neighbours = get_neighbours(single_cell)
|
||||
var positions = []
|
||||
|
||||
for neighbour in neighbours:
|
||||
#var hex_pos = cube_to_world_pos(neighbour)
|
||||
positions.push_back(neighbour)
|
||||
return positions
|
||||
|
||||
var possible_placements: Dictionary = {}
|
||||
var positions = []
|
||||
|
||||
for hex in used_cells.keys():
|
||||
for neighbour in get_empty_neighbours(hex):
|
||||
if not used_cells.has(neighbour):
|
||||
possible_placements[neighbour] = true
|
||||
|
||||
for p in possible_placements:
|
||||
var eligible: bool = true
|
||||
|
||||
for neighbour in get_neighbours(p):
|
||||
if not used_cells.has(neighbour):
|
||||
continue
|
||||
|
||||
if used_cells[neighbour].is_black != button.is_black:
|
||||
eligible = false
|
||||
break
|
||||
|
||||
if eligible:
|
||||
positions.push_back(p)
|
||||
|
||||
return positions
|
||||
|
||||
|
||||
func get_left_neighbour(pos: Vector4i) -> Vector4i:
|
||||
return Vector4i(-pos.z, -pos.x, -pos.y, 0)
|
||||
|
||||
func get_right_neighbour(pos: Vector4i) -> Vector4i:
|
||||
return Vector4i(-pos.y, -pos.z, -pos.x, 0)
|
||||
|
||||
func can_reach(start: Vector4i, target: Vector4i) -> bool:
|
||||
# if we have 5 potential spaces it can never be blocked
|
||||
var offset: Vector4i = Vector4i.ZERO
|
||||
|
||||
offset.x = target.x - start.x
|
||||
offset.y = target.y - start.y
|
||||
offset.z = target.z - start.z
|
||||
|
||||
var left = get_left_neighbour(offset)
|
||||
var right = get_right_neighbour(offset)
|
||||
|
||||
var left_coord = Vector4i(left.x + start.x, left.y + start.y, left.z + start.z, 0)
|
||||
var right_coord = Vector4i(right.x + start.x, right.y + start.y, right.z + start.z, 0)
|
||||
|
||||
return is_cell_empty(left_coord) or is_cell_empty(right_coord)
|
||||
|
||||
func _on_insect_selected(button: InsectButton, is_black: bool) -> void:
|
||||
var positions = get_placeable_positions(button)
|
||||
for p in positions:
|
||||
var outline = HEX_OUTLINE.instantiate()
|
||||
var hex_pos = cube_to_world_pos(p)
|
||||
outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
outline.visible = true
|
||||
outline.insect_resource = button.insect_resource
|
||||
outline.is_black = is_black
|
||||
outline.coordinates = p
|
||||
outline.map_reference = self
|
||||
placement_visualizer.add_child(outline)
|
||||
#placements[p] = outline
|
||||
|
||||
# create a hexagon with insect resource data
|
||||
#var tile = INSECT_TILE.instantiate()
|
||||
#tile.resource = insect_resource
|
||||
#tile.is_black = is_black
|
||||
#current_tile = tile
|
||||
#add_child(tile)
|
||||
|
||||
# spawn possible placement locations :)
|
||||
if used_cells.size() == 0: # we have no cells placed, display a placement outline at 0, 0
|
||||
var outline = HEX_OUTLINE.instantiate()
|
||||
var cubepos = CubeCoordinates.new(0, 0, 0)
|
||||
var hex_pos = cube_to_world_pos(cubepos)
|
||||
outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
outline.visible = true
|
||||
outline.insect_resource = insect_resource
|
||||
outline.is_black = is_black
|
||||
outline.coordinates = cubepos
|
||||
placement_visualizer.add_child(outline)
|
||||
placements[hex_pos] = outline
|
||||
elif used_cells.size() == 1: # we have ONE cell placed, this is a special case in which
|
||||
# the opposing player is allowed to place a tile that touches the enemy color
|
||||
# We display outline placement around all spaces of this single cell
|
||||
var single_cell = used_cells.keys().front()
|
||||
var neighbours = get_neighbours(CubeCoordinates.new(single_cell.x, single_cell.y, single_cell.z))
|
||||
for neighbour in neighbours:
|
||||
var outline = HEX_OUTLINE.instantiate()
|
||||
var hex_pos = cube_to_world_pos(neighbour)
|
||||
outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
outline.visible = true
|
||||
outline.insect_resource = insect_resource
|
||||
outline.is_black = is_black
|
||||
outline.coordinates = neighbour
|
||||
placement_visualizer.add_child(outline)
|
||||
placements[hex_pos] = outline
|
||||
else:
|
||||
# iterate over all used_cells, get all empty cells surrounding those cells
|
||||
# iterate over all those empty cells, check if they only neighbour the same color
|
||||
var possible_placements: Dictionary = {}
|
||||
|
||||
for hex in used_cells.keys():
|
||||
#var insect_resource: TileResource = button.insect_resource
|
||||
#
|
||||
## spawn possible placement locations :)
|
||||
#if used_cells.size() == 0: # we have no cells placed, display a placement outline at 0, 0
|
||||
#var outline = HEX_OUTLINE.instantiate()
|
||||
#var cubepos = Vector4i.new(0, 0, 0)
|
||||
#var hex_pos = cube_to_world_pos(cubepos)
|
||||
#outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
#outline.visible = true
|
||||
#outline.insect_resource = insect_resource
|
||||
#outline.is_black = is_black
|
||||
#outline.coordinates = cubepos
|
||||
#outline.map_reference = self
|
||||
#placement_visualizer.add_child(outline)
|
||||
#placements[hex_pos] = outline
|
||||
#elif used_cells.size() == 1: # we have ONE cell placed, this is a special case in which
|
||||
## the opposing player is allowed to place a tile that touches the enemy color
|
||||
## We display outline placement around all spaces of this single cell
|
||||
#var single_cell = used_cells.keys().front()
|
||||
#var neighbours = get_neighbours(Vector4i.new(single_cell.x, single_cell.y, single_cell.z))
|
||||
#for neighbour in neighbours:
|
||||
#var outline = HEX_OUTLINE.instantiate()
|
||||
#var hex_pos = cube_to_world_pos(neighbour)
|
||||
#outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
#outline.visible = true
|
||||
#outline.insect_resource = insect_resource
|
||||
#outline.is_black = is_black
|
||||
#outline.coordinates = neighbour
|
||||
#outline.map_reference = self
|
||||
#placement_visualizer.add_child(outline)
|
||||
#placements[hex_pos] = outline
|
||||
#else:
|
||||
## iterate over all used_cells, get all empty cells surrounding those cells
|
||||
## iterate over all those empty cells, check if they only neighbour the same color
|
||||
#var possible_placements: Dictionary = {}
|
||||
#
|
||||
#for hex in used_cells.keys():
|
||||
##var eligible: bool = true
|
||||
#for neighbour in get_empty_neighbours(Vector4i.new(hex.x, hex.y, hex.z)):
|
||||
#if not used_cells.has(Vector4(neighbour.q, neighbour.r, neighbour.s, 0)):
|
||||
#possible_placements[Vector4i(neighbour.q, neighbour.r, neighbour.s, 0)] = true
|
||||
#
|
||||
#for p in possible_placements:
|
||||
#var eligible: bool = true
|
||||
for neighbour in get_empty_neighbours(CubeCoordinates.new(hex.x, hex.y, hex.z)):
|
||||
if not used_cells.has(Vector4(neighbour.q, neighbour.r, neighbour.s, 0)):
|
||||
possible_placements[Vector4i(neighbour.q, neighbour.r, neighbour.s, 0)] = true
|
||||
|
||||
for p in possible_placements:
|
||||
#var neighbours = [
|
||||
# Vector2i(p.x + 1, p.y), Vector2i(p.x + 1, p.y - 1), Vector2i(p.x, p.y - 1),
|
||||
# Vector2i(p.x - 1, p.y), Vector2i(p.x - 1, p.y + 1), Vector2i(p.x, p.y + 1)
|
||||
#]
|
||||
|
||||
var eligible: bool = true
|
||||
|
||||
for neighbour in get_neighbours(CubeCoordinates.new(p.x, p.y, p.z)):
|
||||
if not used_cells.has(Vector4i(neighbour.q, neighbour.r, neighbour.s, 0)):
|
||||
continue
|
||||
|
||||
if used_cells[Vector4i(neighbour.q, neighbour.r, neighbour.s, 0)].is_black != is_black:
|
||||
eligible = false
|
||||
break
|
||||
|
||||
if eligible:
|
||||
var outline = HEX_OUTLINE.instantiate()
|
||||
var hex_pos = cube_to_world_pos(CubeCoordinates.new(p.x, p.y, p.z))
|
||||
outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
outline.visible = true
|
||||
outline.insect_resource = insect_resource
|
||||
outline.is_black = is_black
|
||||
outline.coordinates = CubeCoordinates.new(p.x, p.y, p.z)
|
||||
placement_visualizer.add_child(outline)
|
||||
placements[p] = outline
|
||||
|
||||
pass
|
||||
|
||||
pass
|
||||
#
|
||||
#for neighbour in get_neighbours(Vector4i.new(p.x, p.y, p.z)):
|
||||
#if not used_cells.has(Vector4i(neighbour.q, neighbour.r, neighbour.s, 0)):
|
||||
#continue
|
||||
#
|
||||
#if used_cells[Vector4i(neighbour.q, neighbour.r, neighbour.s, 0)].is_black != is_black:
|
||||
#eligible = false
|
||||
#break
|
||||
#
|
||||
#if eligible:
|
||||
#var outline = HEX_OUTLINE.instantiate()
|
||||
#var hex_pos = cube_to_world_pos(Vector4i.new(p.x, p.y, p.z))
|
||||
#outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
#outline.visible = true
|
||||
#outline.insect_resource = insect_resource
|
||||
#outline.is_black = is_black
|
||||
#outline.coordinates = Vector4i.new(p.x, p.y, p.z)
|
||||
#outline.map_reference = self
|
||||
#placement_visualizer.add_child(outline)
|
||||
#placements[p] = outline
|
||||
|
||||
func _on_insect_placement_cancelled() -> void:
|
||||
if current_tile:
|
||||
|
|
@ -234,7 +299,7 @@ func _on_insect_placement_cancelled() -> void:
|
|||
for child in placement_visualizer.get_children():
|
||||
child.queue_free()
|
||||
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: CubeCoordinates) -> void:
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) -> void:
|
||||
var tile_copy = INSECT_TILE.instantiate()
|
||||
var hex_pos = cube_to_world_pos(pos)
|
||||
|
||||
|
|
@ -242,41 +307,42 @@ func _on_insect_placed(resource: TileResource, is_black: bool, pos: CubeCoordina
|
|||
tile_copy.resource = resource
|
||||
tile_copy.is_black = is_black
|
||||
tile_copy.coordinates = pos
|
||||
tile_copy.map_reference = self
|
||||
var target_pos = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
|
||||
used_cells[Vector4i(pos.q, pos.r, pos.s, 0)] = tile_copy
|
||||
used_cells[pos] = tile_copy
|
||||
|
||||
add_child(tile_copy)
|
||||
|
||||
var tween = get_tree().create_tween()
|
||||
tween.tween_property(tile_copy, "position", target_pos, 1.0).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_EXPO)
|
||||
|
||||
func can_move(tile: InsectTile) -> bool:
|
||||
return can_hive_exist_without_tile(tile)
|
||||
|
||||
func create_move_positions() -> void:
|
||||
pass
|
||||
|
||||
func _on_insect_tile_selected(tile: InsectTile) -> void:
|
||||
if not can_hive_exist_without_tile(tile):
|
||||
return
|
||||
|
||||
if tile.resource.movement_behaviour == null:
|
||||
return
|
||||
|
||||
var spaces = tile.resource.movement_behaviour.get_available_spaces(tile.coordinates, self)
|
||||
|
||||
print(spaces.size())
|
||||
|
||||
if spaces.is_empty():
|
||||
GameEvents.insect_tile_selection_request_failed.emit(tile)
|
||||
#GameEvents.insect_tile_selection_request_failed.emit(tile)
|
||||
return
|
||||
|
||||
for space in spaces:
|
||||
var neighbours = get_neighbours(space)
|
||||
# if all neighbours are empty, move would disconnect us from the hive
|
||||
# so we discard it
|
||||
# also: if there are 5 empty space and the only remaining one is our current tile...
|
||||
# we would also be disconnected after the move
|
||||
# maybe the 6 check is not needed
|
||||
var non_empty_neighbours = neighbours.filter(is_cell_not_empty)
|
||||
var coords_vec4: Vector4i = Vector4i(tile.coordinates.q, tile.coordinates.r, tile.coordinates.s, 0)
|
||||
|
||||
if non_empty_neighbours.size() == 1:
|
||||
var occupied_neighbour = non_empty_neighbours.front()
|
||||
var neighbour_vec4: Vector4i = Vector4i(occupied_neighbour.q, occupied_neighbour.r, occupied_neighbour.s, 0)
|
||||
if neighbour_vec4 == coords_vec4:
|
||||
if occupied_neighbour == tile.coordinates:
|
||||
continue
|
||||
|
||||
var outline = HEX_OUTLINE.instantiate()
|
||||
|
|
@ -292,8 +358,8 @@ func _on_insect_tile_selected(tile: InsectTile) -> void:
|
|||
placements[space] = outline
|
||||
|
||||
|
||||
func _on_insect_tile_moved(tile: InsectTile, target: CubeCoordinates) -> void:
|
||||
used_cells.erase(Vector4i(tile.coordinates.q, tile.coordinates.r, tile.coordinates.s, 0))
|
||||
func _on_insect_tile_moved(tile: InsectTile, target: Vector4i) -> void:
|
||||
used_cells.erase(tile.coordinates)
|
||||
|
||||
var new_hex_pos = cube_to_world_pos(target)
|
||||
var sky_new_hex_pos = Vector3(new_hex_pos.x, 20.0, new_hex_pos.y)
|
||||
|
|
@ -309,7 +375,24 @@ func _on_insect_tile_moved(tile: InsectTile, target: CubeCoordinates) -> void:
|
|||
|
||||
tile.coordinates = target
|
||||
|
||||
used_cells[Vector4i(target.q, target.r, target.s, 0)] = tile
|
||||
used_cells[tile.coordinates] = tile
|
||||
|
||||
func get_same_neighbours(cell1: Vector4i, cell2: Vector4i) -> Array[Vector4i]:
|
||||
var neighbours1 = get_neighbours(cell1).filter(is_cell_not_empty)
|
||||
var neighbours2 = get_neighbours(cell2).filter(is_cell_not_empty)
|
||||
|
||||
var shared_neighbours: Array[Vector4i] = []
|
||||
|
||||
for n1 in neighbours1:
|
||||
for n2 in neighbours2:
|
||||
if n1 == n2:
|
||||
if n1 not in shared_neighbours:
|
||||
shared_neighbours.push_back(n1)
|
||||
|
||||
return shared_neighbours
|
||||
|
||||
func is_position_on_hive(pos: Vector4i) -> bool:
|
||||
return get_empty_neighbours(pos).size() > 0
|
||||
|
||||
func can_hive_exist_without_tile(tile: InsectTile) -> bool:
|
||||
# TODO: BFS-Search from random cell to see if all other cells could still be reached when this
|
||||
|
|
@ -317,11 +400,9 @@ func can_hive_exist_without_tile(tile: InsectTile) -> bool:
|
|||
if get_empty_neighbours(tile.coordinates).size() == 5: # we only have one real neighbour, so can't break anything
|
||||
return true
|
||||
|
||||
var vector_coords: Vector4i = Vector4i(tile.coordinates.q, tile.coordinates.r, tile.coordinates.s, 0)
|
||||
|
||||
# DO BFS
|
||||
var tiles_reached: Array = []
|
||||
var tiles_available: Array = used_cells.keys().filter(func(coords): return coords != vector_coords)
|
||||
var tiles_available: Array = used_cells.keys().filter(func(coords): return coords != tile.coordinates)
|
||||
|
||||
if tiles_available.size() <= 1:
|
||||
# If we only have 1 or 2 total tiles, we can always move
|
||||
|
|
@ -338,65 +419,17 @@ func can_hive_exist_without_tile(tile: InsectTile) -> bool:
|
|||
while queue.size() > 0:
|
||||
var m = queue.pop_front()
|
||||
|
||||
for neighbour in get_neighbours(CubeCoordinates.new(m.x, m.y, m.z)):
|
||||
var neighbour_vec4: Vector4i = Vector4i(neighbour.q, neighbour.r, neighbour.s, 0)
|
||||
if neighbour_vec4 not in tiles_reached and neighbour_vec4 != vector_coords:
|
||||
if used_cells.has(neighbour_vec4):
|
||||
tiles_reached.push_back(neighbour_vec4)
|
||||
queue.push_back(neighbour_vec4)
|
||||
for neighbour in get_neighbours(m):
|
||||
if neighbour not in tiles_reached and neighbour != tile.coordinates:
|
||||
if used_cells.has(neighbour):
|
||||
tiles_reached.push_back(neighbour)
|
||||
queue.push_back(neighbour)
|
||||
|
||||
return tiles_reached.size() == used_cells.size() - 1
|
||||
|
||||
func _on_insect_tile_request_selection(tile: InsectTile) -> void:
|
||||
if can_hive_exist_without_tile(tile):
|
||||
GameEvents.insect_tile_selection_request_successful.emit(tile)
|
||||
else:
|
||||
GameEvents.insect_tile_selection_request_failed.emit(tile)
|
||||
|
||||
func _ready() -> void:
|
||||
GameEvents.insect_selected.connect(_on_insect_selected)
|
||||
GameEvents.insect_placement_cancelled.connect(_on_insect_placement_cancelled)
|
||||
GameEvents.insect_placed.connect(_on_insect_placed)
|
||||
GameEvents.insect_tile_selected.connect(_on_insect_tile_selected)
|
||||
GameEvents.insect_tile_moved.connect(_on_insect_tile_moved)
|
||||
GameEvents.insect_tile_request_selection.connect(_on_insect_tile_request_selection)
|
||||
|
||||
#func spawn_random_tile() -> void:
|
||||
#var tile_copy = hex.duplicate()
|
||||
#var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(randi_range(-20, 20), randi_range(-20, 20)))
|
||||
#
|
||||
#tile_copy.position = Vector3(hex_pos.x, 20.0, hex_pos.y)
|
||||
#var target_pos = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
#
|
||||
#add_child(tile_copy)
|
||||
#
|
||||
#var tween = get_tree().create_tween()
|
||||
#tween.tween_property(tile_copy, "position", target_pos, 1.0).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_EXPO)
|
||||
#
|
||||
#func move_tile_to_random_position() -> void:
|
||||
#var new_hex_pos = flat_hex_to_world_position(AxialCoordinates.new(randi_range(-20, 20), randi_range(-20, 20)))
|
||||
#var sky_new_hex_pos = Vector3(new_hex_pos.x, 20.0, new_hex_pos.y)
|
||||
#var ground_new_hex_pos = Vector3(new_hex_pos.x, 0.0, new_hex_pos.y)
|
||||
#
|
||||
#var current_hex_pos = hex.position
|
||||
#var sky_current_hex_pos = hex.position + Vector3(0.0, 20.0, 0.0)
|
||||
#
|
||||
#var tween = get_tree().create_tween()
|
||||
#tween.tween_property(hex, "position", sky_current_hex_pos, 0.5).set_ease(Tween.EASE_IN).set_trans(Tween.TRANS_EXPO)
|
||||
#tween.tween_property(hex, "position", sky_new_hex_pos, 0.0)
|
||||
#tween.tween_property(hex, "position", ground_new_hex_pos, 1.0).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_EXPO)
|
||||
|
||||
func _process(delta) -> void:
|
||||
#if Input.is_action_just_pressed("ui_accept"):
|
||||
# print("yay")
|
||||
# spawn_random_tile()
|
||||
return
|
||||
|
||||
if current_tile == null:
|
||||
return
|
||||
|
||||
#var pos3d = get_3d_pos(get_viewport().get_mouse_position())
|
||||
#if pos3d:
|
||||
#var hex_pos = flat_hex_to_world_position(world_to_hex_tile(Vector2(pos3d.x, pos3d.z)))
|
||||
#current_tile.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
#coord_label.text = "%d, %d" % [hex_pos.x, hex_pos.y]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ extends Area3D
|
|||
|
||||
var hovered: bool = false
|
||||
|
||||
var coordinates: HexGrid.CubeCoordinates
|
||||
var coordinates: Vector4i
|
||||
|
||||
var insect_resource: TileResource
|
||||
var is_black: bool = false
|
||||
|
|
@ -13,6 +13,8 @@ var tile: Node3D
|
|||
|
||||
var is_moving: bool = false
|
||||
|
||||
var map_reference: HexGrid
|
||||
|
||||
const BUILD_GHOST = preload("res://InsectTiles/BuildGhost.tscn")
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
|
|
@ -25,10 +27,10 @@ func _ready():
|
|||
else:
|
||||
GameEvents.insect_placed.connect(_on_insect_placed)
|
||||
|
||||
func _on_insect_tile_moved(tile: InsectTile, to: HexGrid.CubeCoordinates) -> void:
|
||||
func _on_insect_tile_moved(tile: InsectTile, to: Vector4i) -> void:
|
||||
queue_free()
|
||||
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: HexGrid.CubeCoordinates) -> void:
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) -> void:
|
||||
queue_free()
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
|
|
@ -46,6 +48,7 @@ func _on_mouse_entered():
|
|||
tile = BUILD_GHOST.instantiate()
|
||||
tile.resource = insect_resource
|
||||
tile.is_black = is_black
|
||||
tile.map_reference = map_reference
|
||||
|
||||
|
||||
add_child(tile)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
extends TextureButton
|
||||
class_name InsectButton
|
||||
|
||||
@onready var hex = $Hex
|
||||
@onready var tile_count_label = $Hex/TileCountLabel
|
||||
|
|
@ -45,6 +46,15 @@ func enable() -> void:
|
|||
|
||||
|
||||
func _on_placement_cancelled() -> void:
|
||||
refresh_state()
|
||||
|
||||
func _on_insect_placed(resource: TileResource, _is_black: bool, pos: Vector4i) -> void:
|
||||
refresh_state()
|
||||
|
||||
if insect_resource == resource and _is_black == is_black:
|
||||
decrement_tile_count()
|
||||
|
||||
func refresh_state() -> void:
|
||||
selected = false
|
||||
|
||||
if not is_empty():
|
||||
|
|
@ -55,21 +65,6 @@ func _on_placement_cancelled() -> void:
|
|||
else:
|
||||
unhover()
|
||||
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: HexGrid.CubeCoordinates) -> void:
|
||||
selected = false
|
||||
|
||||
if not is_empty():
|
||||
enable()
|
||||
|
||||
if hovered and not is_empty():
|
||||
hover()
|
||||
else:
|
||||
unhover()
|
||||
|
||||
if insect_resource == resource:
|
||||
decrement_tile_count()
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
if is_black:
|
||||
|
|
@ -78,33 +73,40 @@ func _ready() -> void:
|
|||
update_tile_count_display()
|
||||
insect_icon.texture = insect_resource.ui_texture
|
||||
|
||||
if is_black != GameData.is_player_black:
|
||||
#disabled = true
|
||||
#return
|
||||
pass
|
||||
if is_black != GameData.is_player_black and not GameData.debug:
|
||||
disabled = true
|
||||
return
|
||||
|
||||
GameEvents.insect_selected.connect(_on_insect_selected)
|
||||
GameEvents.insect_placement_cancelled.connect(_on_placement_cancelled)
|
||||
GameEvents.insect_placed.connect(_on_insect_placed)
|
||||
GameEvents.insect_tile_selected.connect(_on_insect_tile_selected)
|
||||
GameEvents.insect_tile_moved.connect(_on_insect_tile_moved)
|
||||
GameEvents.insect_tile_deselected.connect(_on_insect_tile_deselected)
|
||||
|
||||
func _on_insect_selected(_resource: TileResource, _is_black: bool) -> void:
|
||||
if _resource != insect_resource:
|
||||
func _on_insect_tile_deselected(tile: InsectTile) -> void:
|
||||
refresh_state()
|
||||
|
||||
func _on_insect_tile_selected(tile: InsectTile) -> void:
|
||||
disable()
|
||||
|
||||
func _on_insect_tile_moved(tile: InsectTile, to: Vector4i) -> void:
|
||||
refresh_state()
|
||||
|
||||
func _on_insect_selected(button: InsectButton, _is_black: bool) -> void:
|
||||
if button != self:
|
||||
disable()
|
||||
|
||||
pass
|
||||
|
||||
func hover() -> void:
|
||||
if GameData.is_player_black != is_black:
|
||||
pass
|
||||
#return
|
||||
if GameData.is_player_black != is_black and not GameData.debug:
|
||||
return
|
||||
|
||||
var tween = get_tree().create_tween()
|
||||
tween.tween_property(hex, "position", Vector2(0, -16), 0.1).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_SPRING)
|
||||
|
||||
func unhover() -> void:
|
||||
if GameData.is_player_black != is_black:
|
||||
pass
|
||||
#return
|
||||
if GameData.is_player_black != is_black and not GameData.debug:
|
||||
return
|
||||
|
||||
var tween = get_tree().create_tween()
|
||||
tween.tween_property(hex, "position", Vector2(0, 0), 0.25).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_SPRING)
|
||||
|
|
@ -127,7 +129,7 @@ func _on_pressed():
|
|||
|
||||
selected = true
|
||||
|
||||
GameEvents.insect_selected.emit(insect_resource, is_black)
|
||||
GameEvents.insect_selected.emit(self, is_black)
|
||||
|
||||
release_focus()
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ extends Area3D
|
|||
@export var is_black: bool = false
|
||||
@export var resource: TileResource
|
||||
|
||||
var map_reference: HexGrid
|
||||
|
||||
@onready var hexagon_small = $HexagonSmall
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
|
|||
|
|
@ -6,6 +6,6 @@
|
|||
render_priority = 0
|
||||
shader = ExtResource("1_pk3ok")
|
||||
shader_parameter/albedo = Color(0, 0, 0, 1)
|
||||
shader_parameter/emission_color = Color(0, 0, 0, 1)
|
||||
shader_parameter/emission_color = Color(0, 0, 0, 0)
|
||||
shader_parameter/emission_amount = 5.0
|
||||
shader_parameter/rim_steepness = 0.214
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
[resource]
|
||||
render_priority = 0
|
||||
shader = ExtResource("1_8diwm")
|
||||
shader_parameter/albedo = Color(0, 0, 0, 1)
|
||||
shader_parameter/emission_color = Color(0, 0, 0, 1)
|
||||
shader_parameter/albedo = Color(0, 0, 0, 0)
|
||||
shader_parameter/emission_color = Color(0, 0, 0, 0)
|
||||
shader_parameter/emission_amount = 5.0
|
||||
shader_parameter/rim_steepness = 0.214
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
extends Resource
|
||||
class_name MovementBehaviour
|
||||
|
||||
func get_available_spaces(pos: HexGrid.CubeCoordinates, map: HexGrid) -> Array[HexGrid.CubeCoordinates]:
|
||||
func get_available_spaces(pos: Vector4i, map: HexGrid) -> Array[Vector4i]:
|
||||
return []
|
||||
|
|
|
|||
|
|
@ -1,2 +1,38 @@
|
|||
extends MovementBehaviour
|
||||
class_name MovementBehaviourAnt
|
||||
|
||||
# Ant uses a modified BFS? It's basically a supercharged spider with limitlesss movement range
|
||||
# Naive approach: BFS from all neighbours, don't go to already visited cells, check if can reach
|
||||
# Maybe better: Get al "placecable tiles" from the map, go over those. Might be faster but more complicated
|
||||
|
||||
func simulate_move_recursive(start: Vector4i, exclude: Array[Vector4i], map: HexGrid, visited_cells: Array[Vector4i] = []) -> Array[Vector4i]:
|
||||
var visited = visited_cells
|
||||
var possible: Array[Vector4i] = []
|
||||
|
||||
#if max_num < 1:
|
||||
# return [start]
|
||||
|
||||
for neighbour in map.get_empty_neighbours(start):
|
||||
if neighbour in visited:
|
||||
continue
|
||||
|
||||
if not map.can_reach(start, neighbour):
|
||||
continue
|
||||
|
||||
var same_neighbours = map.get_same_neighbours(start, neighbour)
|
||||
for e in exclude:
|
||||
same_neighbours.erase(e)
|
||||
|
||||
if same_neighbours.size() > 0:
|
||||
visited.append(neighbour)
|
||||
print("yay?")
|
||||
possible.append_array(simulate_move_recursive(neighbour, exclude, map, visited))
|
||||
|
||||
return possible
|
||||
|
||||
func get_available_spaces(pos: Vector4i, map: HexGrid) -> Array[Vector4i]:
|
||||
var possible_places: Array[Vector4i] = []
|
||||
|
||||
possible_places = simulate_move_recursive(pos, [pos], map)
|
||||
|
||||
return possible_places
|
||||
|
|
|
|||
|
|
@ -1,38 +1,13 @@
|
|||
extends MovementBehaviour
|
||||
class_name MovementBehaviourBee
|
||||
|
||||
func can_reach(start: HexGrid.CubeCoordinates, target: HexGrid.CubeCoordinates, map: HexGrid) -> bool:
|
||||
# if we have 5 potential spaces it can never be blocked
|
||||
var cubepos: HexGrid.CubeCoordinates = start
|
||||
var cubecoord: HexGrid.CubeCoordinates = target
|
||||
|
||||
var cubetest: HexGrid.CubeCoordinates = HexGrid.CubeCoordinates.new(0, 0, 0)
|
||||
|
||||
cubetest.q = cubecoord.q - cubepos.q
|
||||
cubetest.r = cubecoord.r - cubepos.r
|
||||
cubetest.s = cubecoord.s - cubepos.s
|
||||
|
||||
var left = get_left_neighbour(cubetest)
|
||||
var right = get_right_neighbour(cubetest)
|
||||
|
||||
var left_coord = HexGrid.CubeCoordinates.new(left.q + cubepos.q, left.r + cubepos.r, left.s + cubepos.s)
|
||||
var right_coord = HexGrid.CubeCoordinates.new(right.q + cubepos.q, right.r + cubepos.r, right.s + cubepos.s)
|
||||
|
||||
return map.is_cell_empty(left_coord) or map.is_cell_empty(right_coord)
|
||||
|
||||
func get_left_neighbour(pos: HexGrid.CubeCoordinates) -> HexGrid.CubeCoordinates:
|
||||
return HexGrid.CubeCoordinates.new(-pos.s, -pos.q, -pos.r)
|
||||
|
||||
func get_right_neighbour(pos: HexGrid.CubeCoordinates) -> HexGrid.CubeCoordinates:
|
||||
return HexGrid.CubeCoordinates.new(-pos.r, -pos.s, -pos.q)
|
||||
|
||||
func get_available_spaces(pos: HexGrid.CubeCoordinates, map: HexGrid) -> Array[HexGrid.CubeCoordinates]:
|
||||
func get_available_spaces(pos: Vector4i, map: HexGrid) -> Array[Vector4i]:
|
||||
var potential_spaces = map.get_empty_neighbours(pos)
|
||||
|
||||
var target_spaces: Array[HexGrid.CubeCoordinates] = []
|
||||
var target_spaces: Array[Vector4i] = []
|
||||
|
||||
for neighbour in potential_spaces:
|
||||
if can_reach(pos, neighbour, map):
|
||||
if map.can_reach(pos, neighbour):
|
||||
target_spaces.append(neighbour)
|
||||
|
||||
return target_spaces
|
||||
|
|
|
|||
|
|
@ -1,2 +1,38 @@
|
|||
extends MovementBehaviour
|
||||
class_name MovementBehaviourGrasshopper
|
||||
|
||||
const DIRS = [
|
||||
Vector4i(0, -1, +1, 0), #UP
|
||||
Vector4i(-1, 0, +1, 0), #UP_LEFT
|
||||
Vector4i(-1, +1, 0, 0), #DOWN_LEFT
|
||||
Vector4i(0, +1, -1, 0), #DOWN
|
||||
Vector4i(+1, 0, -1, 0), #DOWN_RIGHT
|
||||
Vector4i(+1, -1, 0, 0), #UP_RIGHT
|
||||
]
|
||||
|
||||
func simulate_move_dirs(start: Vector4i, map: HexGrid) -> Array[Vector4i]:
|
||||
var possible: Array[Vector4i] = []
|
||||
for dir in DIRS:
|
||||
possible.push_back(simulate_move_recursive(start, dir, map))
|
||||
|
||||
return possible
|
||||
|
||||
func simulate_move_recursive(start: Vector4i, dir: Vector4i, map: HexGrid) -> Vector4i:
|
||||
var possible: Array[Vector4i] = []
|
||||
|
||||
var target: Vector4i = start + dir
|
||||
|
||||
if map.is_cell_empty(target):
|
||||
return target
|
||||
|
||||
return simulate_move_recursive(target, dir, map)
|
||||
|
||||
func get_available_spaces(pos: Vector4i, map: HexGrid) -> Array[Vector4i]:
|
||||
var possible_places: Array[Vector4i] = []
|
||||
|
||||
possible_places = simulate_move_dirs(pos, map)
|
||||
|
||||
for neighbour in map.get_empty_neighbours(pos):
|
||||
possible_places.erase(neighbour)
|
||||
|
||||
return possible_places
|
||||
|
|
|
|||
|
|
@ -1,2 +1,38 @@
|
|||
extends MovementBehaviour
|
||||
class_name MovementBehaviourSpider
|
||||
|
||||
@export var max_movement_reach: int = 3
|
||||
|
||||
func simulate_move_recursive(start: Vector4i, max_num: int, exclude: Array[Vector4i], map: HexGrid, visited_cells: Array[Vector4i] = []) -> Array[Vector4i]:
|
||||
var visited = visited_cells.duplicate()
|
||||
var possible: Array[Vector4i] = []
|
||||
|
||||
visited.append(start)
|
||||
|
||||
if max_num < 1:
|
||||
return [start]
|
||||
|
||||
for neighbour in map.get_empty_neighbours(start):
|
||||
if neighbour in visited:
|
||||
continue
|
||||
|
||||
if not map.can_reach(start, neighbour):
|
||||
continue
|
||||
|
||||
var same_neighbours = map.get_same_neighbours(start, neighbour)
|
||||
for e in exclude:
|
||||
same_neighbours.erase(e)
|
||||
|
||||
if same_neighbours.size() > 0:
|
||||
visited.append(neighbour)
|
||||
print("yay?")
|
||||
possible.append_array(simulate_move_recursive(neighbour, max_num - 1, exclude, map, visited))
|
||||
|
||||
return possible
|
||||
|
||||
func get_available_spaces(pos: Vector4i, map: HexGrid) -> Array[Vector4i]:
|
||||
var possible_places: Array[Vector4i] = []
|
||||
|
||||
possible_places = simulate_move_recursive(pos, max_movement_reach, [pos], map)
|
||||
|
||||
return possible_places
|
||||
|
|
|
|||
15
PlayerInventory.gd
Normal file
15
PlayerInventory.gd
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
extends HBoxContainer
|
||||
|
||||
|
||||
var available_insects: Array[TileResource] = []
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
# create all neccessary buttons for the inventory
|
||||
# when an insect gets placed, we can check it here and
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
pass
|
||||
|
|
@ -1,13 +1,18 @@
|
|||
[gd_resource type="Resource" script_class="TileResource" load_steps=5 format=3 uid="uid://chuci1mu106hs"]
|
||||
[gd_resource type="Resource" script_class="TileResource" load_steps=7 format=3 uid="uid://chuci1mu106hs"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://tbfvmxogabnr" path="res://InsectTiles/Materials/Grasshopper_Black.tres" id="1_vut3o"]
|
||||
[ext_resource type="Material" uid="uid://csuox1kvmm78p" path="res://InsectTiles/Materials/Grasshopper_White.tres" id="2_gc341"]
|
||||
[ext_resource type="Script" path="res://Tile/TileResource.gd" id="3_t3kan"]
|
||||
[ext_resource type="Script" path="res://MovementBehaviour/Prefabs/MovementBehaviourGrasshopper.gd" id="3_tid3l"]
|
||||
[ext_resource type="Texture2D" uid="uid://dhnrq0gxmv7cr" path="res://InsectTiles/Assets/UI/grasshopper.png" id="4_tpusd"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_ynqk8"]
|
||||
script = ExtResource("3_tid3l")
|
||||
|
||||
[resource]
|
||||
script = ExtResource("3_t3kan")
|
||||
tile_name = "Grasshopper"
|
||||
movement_behaviour = SubResource("Resource_ynqk8")
|
||||
material_black = ExtResource("1_vut3o")
|
||||
material_white = ExtResource("2_gc341")
|
||||
ui_texture = ExtResource("4_tpusd")
|
||||
|
|
|
|||
|
|
@ -1,13 +1,19 @@
|
|||
[gd_resource type="Resource" script_class="TileResource" load_steps=5 format=3 uid="uid://dhvfn1adyay8i"]
|
||||
[gd_resource type="Resource" script_class="TileResource" load_steps=7 format=3 uid="uid://dhvfn1adyay8i"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://csjte7l8m4gwp" path="res://InsectTiles/Materials/Spider_Black.tres" id="1_htbqr"]
|
||||
[ext_resource type="Material" uid="uid://dh2ehs3h106sb" path="res://InsectTiles/Materials/Spider_White.tres" id="2_ji24g"]
|
||||
[ext_resource type="Script" path="res://MovementBehaviour/Prefabs/MovementBehaviourSpider.gd" id="3_8daio"]
|
||||
[ext_resource type="Script" path="res://Tile/TileResource.gd" id="3_semk6"]
|
||||
[ext_resource type="Texture2D" uid="uid://bgyve5fappdn5" path="res://InsectTiles/Assets/UI/spider.png" id="4_e73ch"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_pm2yd"]
|
||||
script = ExtResource("3_8daio")
|
||||
max_movement_reach = 3
|
||||
|
||||
[resource]
|
||||
script = ExtResource("3_semk6")
|
||||
tile_name = "Spider"
|
||||
movement_behaviour = SubResource("Resource_pm2yd")
|
||||
material_black = ExtResource("1_htbqr")
|
||||
material_white = ExtResource("2_ji24g")
|
||||
ui_texture = ExtResource("4_e73ch")
|
||||
|
|
|
|||
118
Tile/Tile.gd
118
Tile/Tile.gd
|
|
@ -1,8 +1,10 @@
|
|||
extends Area3D
|
||||
class_name InsectTile
|
||||
|
||||
var map_reference: HexGrid
|
||||
|
||||
var coordinates: HexGrid.CubeCoordinates
|
||||
|
||||
var coordinates: Vector4i
|
||||
var layer: int = 0
|
||||
|
||||
@export var is_black: bool = false
|
||||
|
|
@ -10,9 +12,14 @@ var layer: int = 0
|
|||
|
||||
@onready var hexagon_small = $HexagonSmall
|
||||
|
||||
var hat: InsectTile = null
|
||||
|
||||
var build_in_progress: bool = false
|
||||
var move_in_progress: bool = false
|
||||
|
||||
|
||||
var deactivated: bool = false
|
||||
|
||||
var hovered: bool = false
|
||||
|
||||
var selected: bool = false
|
||||
|
|
@ -35,16 +42,17 @@ func _ready() -> void:
|
|||
|
||||
mat = hexagon_small.get_surface_override_material(0)
|
||||
|
||||
GameEvents.insect_tile_selection_request_failed.connect(_on_insect_tile_request_failed)
|
||||
GameEvents.insect_tile_selection_request_successful.connect(_on_insect_tile_selection_request_sucessful)
|
||||
mat.next_pass = hover_shader.duplicate()
|
||||
|
||||
GameEvents.insect_selected.connect(_on_insect_selected)
|
||||
GameEvents.insect_placed.connect(_on_insect_placed)
|
||||
GameEvents.insect_placement_cancelled.connect(_on_insect_placement_cancelled)
|
||||
GameEvents.insect_placement_cancelled.connect(_on_insect_placement_cancelled, CONNECT_DEFERRED)
|
||||
GameEvents.insect_tile_selected.connect(_on_insect_tile_selected)
|
||||
GameEvents.insect_tile_deselected.connect(_on_insect_tile_deselected)
|
||||
GameEvents.insect_tile_moved.connect(_on_insect_tile_moved)
|
||||
|
||||
func _on_insect_tile_moved(tile: InsectTile, to: HexGrid.CubeCoordinates) -> void:
|
||||
|
||||
func _on_insect_tile_moved(tile: InsectTile, to: Vector4i) -> void:
|
||||
move_in_progress = false
|
||||
selected = false
|
||||
|
||||
|
|
@ -62,82 +70,78 @@ func _on_insect_tile_selected(tile: InsectTile) -> void:
|
|||
if tile == self:
|
||||
selected = true
|
||||
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: HexGrid.CubeCoordinates) -> void:
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) -> void:
|
||||
build_in_progress = false
|
||||
|
||||
func _on_insect_placement_cancelled() -> void:
|
||||
build_in_progress = false
|
||||
|
||||
func _on_insect_selected(resource: TileResource, is_black: bool) -> void:
|
||||
func _on_insect_selected(button: InsectButton, is_black: bool) -> void:
|
||||
build_in_progress = true
|
||||
|
||||
func _on_insect_tile_selection_request_sucessful(tile: InsectTile) -> void:
|
||||
if tile != self:
|
||||
return
|
||||
|
||||
GameEvents.insect_tile_selected.emit(self)
|
||||
|
||||
func _tween_shader(value: Color) -> void:
|
||||
var shader: ShaderMaterial = mat.next_pass
|
||||
shader.set_shader_parameter("albedo", value)
|
||||
pass
|
||||
|
||||
func _shader_done() -> void:
|
||||
tweening = false
|
||||
|
||||
if hovered:
|
||||
mat.next_pass = hover_shader
|
||||
else:
|
||||
mat.next_pass = null
|
||||
|
||||
func _process(delta):
|
||||
if Input.is_action_just_pressed("place_tile"):
|
||||
if hovered and not (build_in_progress or move_in_progress):
|
||||
# check if is movable, either with direct reference to the map, or by ping-ponging a signal
|
||||
# request_selection
|
||||
# selection_reguest_successfull
|
||||
# selection_request_failed
|
||||
if deactivated:
|
||||
return
|
||||
|
||||
GameEvents.insect_tile_request_selection.emit(self)
|
||||
if not hovered:
|
||||
return
|
||||
|
||||
func _on_insect_tile_request_failed(tile) -> void:
|
||||
move_in_progress = false
|
||||
selected = false
|
||||
## Check with map if we can be placed
|
||||
#if not map_reference.can_move(self):
|
||||
#return
|
||||
#
|
||||
#
|
||||
#if resource.movement_behaviour == null:
|
||||
## TODO: Play fail animation/tween
|
||||
#return
|
||||
#
|
||||
#var spaces = resource.movement_behaviour.get_available_spaces(coordinates, map_reference)
|
||||
#
|
||||
#if spaces.is_empty():
|
||||
##GameEvents.insect_tile_selection_request_failed.emit(tile)
|
||||
#return
|
||||
|
||||
if tile != self:
|
||||
return
|
||||
|
||||
hovered = false
|
||||
GameEvents.insect_tile_selected.emit(self)
|
||||
|
||||
# siomulate a failed selection request
|
||||
mat.next_pass = SELECTION_FAILED_MAT
|
||||
|
||||
tweening = true
|
||||
func hover() -> void:
|
||||
#if GameData.is_player_black != is_black:
|
||||
#return
|
||||
|
||||
if tween != null:
|
||||
tween.kill()
|
||||
|
||||
tween = get_tree().create_tween()
|
||||
tween.tween_method(_tween_shader, Color.BLACK, Color.DARK_RED, 0.1).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO)
|
||||
tween.tween_method(_tween_shader, Color.DARK_RED, Color.BLACK, 0.35).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO)
|
||||
tween.tween_callback(_shader_done)
|
||||
#tween.tween_property(self, "position", Vector3(0, 0, 5), 0.5).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_SPRING)
|
||||
tween.tween_method(tween_hover_shader, Color(0, 0, 0, 0), Color(0, 0, 0, 1), 0.1).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO)
|
||||
|
||||
|
||||
func tween_hover_shader(color: Color) -> void:
|
||||
if mat.next_pass != null:
|
||||
mat.next_pass.set_shader_parameter("albedo", color)
|
||||
mat.next_pass.set_shader_parameter("emission_color", color)
|
||||
|
||||
func unhover() -> void:
|
||||
#if GameData.is_player_black != is_black:
|
||||
#return
|
||||
|
||||
if tween != null:
|
||||
tween.kill()
|
||||
|
||||
tween = get_tree().create_tween()
|
||||
#tween.tween_property(hex, "position", Vector2(0, -16), 0.1).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_SPRING)
|
||||
tween.tween_method(tween_hover_shader, Color(0, 0, 0, 1), Color(0, 0, 0, 0), 0.25).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO)
|
||||
|
||||
GameEvents.insect_tile_deselected.emit(self)
|
||||
|
||||
func _on_mouse_entered():
|
||||
if build_in_progress or move_in_progress:
|
||||
return
|
||||
hovered = true
|
||||
|
||||
if GameData.is_player_black == is_black:
|
||||
if tween == null:
|
||||
mat.next_pass = hover_shader
|
||||
hovered = true
|
||||
if not deactivated:
|
||||
hover()
|
||||
|
||||
func _on_mouse_exited():
|
||||
if selected:
|
||||
return
|
||||
|
||||
hovered = false
|
||||
if tween == null:
|
||||
mat.next_pass = null
|
||||
|
||||
if not selected:
|
||||
unhover()
|
||||
|
|
|
|||
|
|
@ -8,3 +8,6 @@ class_name TileResource
|
|||
@export var material_white: StandardMaterial3D
|
||||
|
||||
@export var ui_texture: Texture2D
|
||||
|
||||
func _to_string() -> String:
|
||||
return tile_name
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
[gd_scene load_steps=18 format=3 uid="uid://bx0bbrwdr0h40"]
|
||||
[gd_scene load_steps=19 format=3 uid="uid://bx0bbrwdr0h40"]
|
||||
|
||||
[ext_resource type="Script" path="res://HexGrid3D/HexGrid3D.gd" id="2_xcbqy"]
|
||||
[ext_resource type="Script" path="res://WebLightChecker.gd" id="6_uu0ab"]
|
||||
[ext_resource type="Texture2D" uid="uid://cilgpyanfb3a8" path="res://Testbed/textures/wood_table_001_diff_4k.jpg" id="6_x76sf"]
|
||||
[ext_resource type="Texture2D" uid="uid://diamo44e2x4if" path="res://Testbed/textures/wood_table_001_disp_4k.png" id="7_xr322"]
|
||||
[ext_resource type="Script" path="res://PlayerInventory.gd" id="8_kqchc"]
|
||||
[ext_resource type="Script" path="res://BuildMenu.gd" id="8_lxt1e"]
|
||||
[ext_resource type="Texture2D" uid="uid://b6ejmikbfrprs" path="res://Testbed/textures/wood_table_001_rough_4k.jpg" id="8_wvt2u"]
|
||||
[ext_resource type="PackedScene" uid="uid://bo8hgq66dbbb6" path="res://UI/insect_button.tscn" id="11_pmmaq"]
|
||||
|
|
@ -82,7 +83,7 @@ camera_attributes = SubResource("CameraAttributesPractical_41x5h")
|
|||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||
transform = Transform3D(0.843961, -0.46784, 0.262404, -0.0775016, 0.377705, 0.922677, -0.530777, -0.79904, 0.28251, 0.262159, 3.27869, -0.104568)
|
||||
light_color = Color(1, 0.803922, 0.631373, 1)
|
||||
light_color = Color(1, 0.941176, 0.823529, 1)
|
||||
shadow_enabled = true
|
||||
directional_shadow_blend_splits = true
|
||||
script = ExtResource("6_uu0ab")
|
||||
|
|
@ -148,6 +149,7 @@ alignment = 1
|
|||
[node name="LocalPlayerInsects" type="HBoxContainer" parent="BuildMenu/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2"]
|
||||
layout_mode = 2
|
||||
mouse_filter = 0
|
||||
script = ExtResource("8_kqchc")
|
||||
|
||||
[node name="InsectButton" parent="BuildMenu/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2/LocalPlayerInsects" instance=ExtResource("11_pmmaq")]
|
||||
layout_mode = 2
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue