TODO: Fix UI Button reaching 0 not greying out, fix state behaviour for selected tiles
This commit is contained in:
parent
b9df0b4361
commit
5b79dc9822
9 changed files with 325 additions and 95 deletions
|
|
@ -5,6 +5,9 @@ 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)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,18 +21,23 @@ var used_cells: Dictionary = {}
|
|||
|
||||
# have all used_cells be saved as Vector4i (q, r, s, y)
|
||||
|
||||
class CellStorage:
|
||||
var cells: Dictionary = {}
|
||||
class TileStorage:
|
||||
var tiles: Dictionary = {}
|
||||
# we use a vector4i for coordinates
|
||||
# q r s y (layer)
|
||||
|
||||
func add_cell(coords: CubeCoordinates, layer: int = 0) -> void:
|
||||
func add_tile(tile: InsectTile, coords: CubeCoordinates, layer: int = 0) -> void:
|
||||
tiles[Vector4i(coords.q, coords.r, coords.s, layer)] = tile
|
||||
pass
|
||||
|
||||
func remove_cell(coords: CubeCoordinates, layer: int = 0) -> void:
|
||||
func remove_tile(coords: CubeCoordinates, layer: int = 0) -> void:
|
||||
pass
|
||||
|
||||
func has_cell(cords: CubeCoordinates, layer: int = 0) -> bool:
|
||||
return false
|
||||
func has_tile(coords: CubeCoordinates, layer: int = 0) -> bool:
|
||||
return tiles.has(Vector4i(coords.q, coords.r, coords.s, layer))
|
||||
|
||||
func get_tile(coords: CubeCoordinates, layer: int = 0) -> InsectTile:
|
||||
return tiles[Vector4i(coords.q, coords.r, coords.s, layer)]
|
||||
|
||||
|
||||
class CubeCoordinates:
|
||||
|
|
@ -63,6 +68,9 @@ 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:
|
||||
return flat_hex_to_world_position(cube_to_axial(coords))
|
||||
|
||||
#func world_to_hex_tile(world_pos: Vector3) -> Vector2:
|
||||
# var q = (2.0/3.0 * world_pos.x)
|
||||
# var r = (-1.0/3.0 * world_pos.x + sqrt(3.0)/3.0 * world_pos.z)
|
||||
|
|
@ -118,16 +126,23 @@ func get_3d_pos(position2D: Vector2):
|
|||
|
||||
var placements: Dictionary = {}
|
||||
|
||||
func is_cell_empty(coords: Vector2i) -> bool:
|
||||
return !used_cells.has(coords)
|
||||
func is_cell_empty(coords: CubeCoordinates) -> bool:
|
||||
return !used_cells.has(Vector4i(coords.q, coords.r, coords.s, 0))
|
||||
|
||||
func get_empty_neighbours(coords: Vector2i) -> Array[Vector2i]:
|
||||
func is_cell_not_empty(coords: CubeCoordinates) -> bool:
|
||||
return !is_cell_empty(coords)
|
||||
|
||||
func get_empty_neighbours(coords: CubeCoordinates) -> Array[CubeCoordinates]:
|
||||
return get_neighbours(coords).filter(is_cell_empty)
|
||||
|
||||
func get_neighbours(coords: Vector2i) -> Array[Vector2i]:
|
||||
func get_neighbours(coords: CubeCoordinates) -> Array[CubeCoordinates]:
|
||||
return [
|
||||
Vector2i(coords.x + 1, coords.y), Vector2i(coords.x + 1, coords.y - 1), Vector2i(coords.x, coords.y - 1),
|
||||
Vector2i(coords.x - 1, coords.y), Vector2i(coords.x - 1, coords.y + 1), Vector2i(coords.x, coords.y + 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),
|
||||
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)
|
||||
]
|
||||
|
||||
var current_tile: Node3D
|
||||
|
|
@ -145,27 +160,28 @@ func _on_insect_selected(insect_resource: TileResource, is_black: bool) -> void:
|
|||
# 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 hex_pos = flat_hex_to_world_position(AxialCoordinates.new(0, 0))
|
||||
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.hex_pos = Vector2i(0, 0)
|
||||
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(single_cell)
|
||||
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 = flat_hex_to_world_position(AxialCoordinates.new(neighbour.x, neighbour.y))
|
||||
var hex_pos = cube_to_world_pos(neighbour)
|
||||
outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
outline.hex_pos = neighbour
|
||||
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:
|
||||
|
|
@ -174,40 +190,35 @@ func _on_insect_selected(insect_resource: TileResource, is_black: bool) -> void:
|
|||
var possible_placements: Dictionary = {}
|
||||
|
||||
for hex in used_cells.keys():
|
||||
var neighbours = [
|
||||
Vector2i(hex.x + 1, hex.y), Vector2i(hex.x + 1, hex.y - 1), Vector2i(hex.x, hex.y - 1),
|
||||
Vector2i(hex.x - 1, hex.y), Vector2i(hex.x - 1, hex.y + 1), Vector2i(hex.x, hex.y + 1)
|
||||
]
|
||||
#var eligible: bool = true
|
||||
for neighbour in neighbours:
|
||||
if not used_cells.has(neighbour):
|
||||
possible_placements[neighbour] = 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 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 neighbours:
|
||||
|
||||
if not used_cells.has(neighbour):
|
||||
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[neighbour].is_black != is_black:
|
||||
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 = flat_hex_to_world_position(AxialCoordinates.new(p.x, p.y))
|
||||
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.hex_pos = p
|
||||
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
|
||||
|
||||
|
|
@ -223,9 +234,9 @@ 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: Vector2i) -> void:
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: CubeCoordinates) -> void:
|
||||
var tile_copy = INSECT_TILE.instantiate()
|
||||
var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(pos.x, pos.y))
|
||||
var hex_pos = cube_to_world_pos(pos)
|
||||
|
||||
tile_copy.position = Vector3(hex_pos.x, 20.0, hex_pos.y)
|
||||
tile_copy.resource = resource
|
||||
|
|
@ -233,7 +244,7 @@ func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector2i) ->
|
|||
tile_copy.coordinates = pos
|
||||
var target_pos = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
|
||||
used_cells[Vector2i(pos.x, pos.y)] = tile_copy
|
||||
used_cells[Vector4i(pos.q, pos.r, pos.s, 0)] = tile_copy
|
||||
|
||||
add_child(tile_copy)
|
||||
|
||||
|
|
@ -244,14 +255,34 @@ func _on_insect_tile_selected(tile: InsectTile) -> void:
|
|||
if tile.resource.movement_behaviour == null:
|
||||
return
|
||||
|
||||
var pos = world_to_hex_tile(Vector2(tile.position.x, tile.position.z))
|
||||
var spaces = tile.resource.movement_behaviour.get_available_spaces(Vector2i(pos.q, pos.r), self)
|
||||
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)
|
||||
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:
|
||||
continue
|
||||
|
||||
var outline = HEX_OUTLINE.instantiate()
|
||||
var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(space.x, space.y))
|
||||
var hex_pos = cube_to_world_pos(space) # flat_hex_to_world_position(AxialCoordinates.new(space.x, space.y))
|
||||
outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
outline.hex_pos = space
|
||||
outline.coordinates = space
|
||||
outline.visible = true
|
||||
outline.insect_tile = tile
|
||||
outline.is_moving = true
|
||||
|
|
@ -261,10 +292,10 @@ func _on_insect_tile_selected(tile: InsectTile) -> void:
|
|||
placements[space] = outline
|
||||
|
||||
|
||||
func _on_insect_tile_moved(tile: InsectTile, target: Vector2i) -> void:
|
||||
used_cells.erase(tile.coordinates)
|
||||
func _on_insect_tile_moved(tile: InsectTile, target: CubeCoordinates) -> void:
|
||||
used_cells.erase(Vector4i(tile.coordinates.q, tile.coordinates.r, tile.coordinates.s, 0))
|
||||
|
||||
var new_hex_pos = flat_hex_to_world_position(AxialCoordinates.new(target.x, target.y))
|
||||
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)
|
||||
var ground_new_hex_pos = Vector3(new_hex_pos.x, 0.0, new_hex_pos.y)
|
||||
#
|
||||
|
|
@ -278,7 +309,43 @@ func _on_insect_tile_moved(tile: InsectTile, target: Vector2i) -> void:
|
|||
|
||||
tile.coordinates = target
|
||||
|
||||
used_cells[target] = tile
|
||||
used_cells[Vector4i(target.q, target.r, target.s, 0)] = tile
|
||||
|
||||
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
|
||||
# tile would be empty space
|
||||
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)
|
||||
|
||||
# tiles_available has all remaining tiles, we just need to visit every tile from a (random) starting tile
|
||||
# and compare the size with these of all tiles - 1 (our to be moved one)
|
||||
var start: Vector4i = tiles_available.front()
|
||||
tiles_reached.push_back(start)
|
||||
var queue: Array[Vector4i] = [start]
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
|
@ -286,24 +353,7 @@ func _ready() -> void:
|
|||
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)
|
||||
|
||||
return
|
||||
|
||||
for x in range(-6, 5):
|
||||
for y in range(-6, 5):
|
||||
var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(x, y))
|
||||
|
||||
if randi_range(0, 1) == 0:
|
||||
var new_hex = INSECT_TILE.instantiate()
|
||||
new_hex.resource = preload("res://Tile/Prefabs/Bee.tres")
|
||||
new_hex.is_black = false
|
||||
new_hex.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||||
var hex_id = world_to_hex_tile(Vector2(hex_pos.x, hex_pos.y))
|
||||
add_child(new_hex)
|
||||
used_cells[Vector2i(x, y)] = new_hex
|
||||
else:
|
||||
continue
|
||||
|
||||
GameEvents.insect_tile_request_selection.connect(_on_insect_tile_request_selection)
|
||||
|
||||
#func spawn_random_tile() -> void:
|
||||
#var tile_copy = hex.duplicate()
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ extends Area3D
|
|||
|
||||
var hovered: bool = false
|
||||
|
||||
var coordinates: HexGrid.CubeCoordinates
|
||||
|
||||
var insect_resource: TileResource
|
||||
var is_black: bool = false
|
||||
|
||||
var insect_tile: InsectTile
|
||||
|
||||
var hex_pos: Vector2i = Vector2i.ZERO
|
||||
|
||||
var tile: Node3D
|
||||
|
||||
var is_moving: bool = false
|
||||
|
|
@ -25,10 +25,10 @@ func _ready():
|
|||
else:
|
||||
GameEvents.insect_placed.connect(_on_insect_placed)
|
||||
|
||||
func _on_insect_tile_moved(tile: InsectTile, to: Vector2i) -> void:
|
||||
func _on_insect_tile_moved(tile: InsectTile, to: HexGrid.CubeCoordinates) -> void:
|
||||
queue_free()
|
||||
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector2i) -> void:
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: HexGrid.CubeCoordinates) -> void:
|
||||
queue_free()
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
|
|
@ -36,9 +36,9 @@ func _process(delta):
|
|||
if Input.is_action_just_pressed("place_tile"):
|
||||
if hovered:
|
||||
if is_moving:
|
||||
GameEvents.insect_tile_moved.emit(insect_tile, hex_pos)
|
||||
GameEvents.insect_tile_moved.emit(insect_tile, coordinates)
|
||||
else:
|
||||
GameEvents.insect_placed.emit(insect_resource, is_black, hex_pos)
|
||||
GameEvents.insect_placed.emit(insect_resource, is_black, coordinates)
|
||||
|
||||
func _on_mouse_entered():
|
||||
hovered = true
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ func _on_placement_cancelled() -> void:
|
|||
enable()
|
||||
return
|
||||
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector2i) -> void:
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: HexGrid.CubeCoordinates) -> void:
|
||||
if selected:
|
||||
selected = false
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ func _ready():
|
|||
if is_black:
|
||||
hex.texture = HEX_BLACK
|
||||
|
||||
func _on_insect_selected(_resource, _is_black) -> void:
|
||||
func _on_insect_selected(_resource: TileResource, _is_black: bool) -> void:
|
||||
disabled = true
|
||||
|
||||
if _resource == insect_resource and _is_black == is_black:
|
||||
|
|
@ -119,8 +119,6 @@ func _on_pressed():
|
|||
if selected:
|
||||
return
|
||||
|
||||
print("??")
|
||||
|
||||
if tile_count <= 0:
|
||||
return
|
||||
|
||||
|
|
|
|||
11
InsectTiles/SelectionFailedMat.tres
Normal file
11
InsectTiles/SelectionFailedMat.tres
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://djlhrbvvbgpd0"]
|
||||
|
||||
[ext_resource type="Shader" path="res://InsectTiles/HoverShader.gdshader" id="1_8diwm"]
|
||||
|
||||
[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/emission_amount = 5.0
|
||||
shader_parameter/rim_steepness = 0.214
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
extends Resource
|
||||
class_name MovementBehaviour
|
||||
|
||||
func get_available_spaces(pos: Vector2i, map: HexGrid) -> Array[Vector2i]:
|
||||
func get_available_spaces(pos: HexGrid.CubeCoordinates, map: HexGrid) -> Array[HexGrid.CubeCoordinates]:
|
||||
return []
|
||||
|
|
|
|||
|
|
@ -1,35 +1,35 @@
|
|||
extends MovementBehaviour
|
||||
class_name MovementBehaviourBee
|
||||
|
||||
func can_reach(start: Vector2i, target: Vector2i, map: HexGrid) -> bool:
|
||||
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 = map.axial_to_cube(HexGrid.AxialCoordinates.new(start.x, start.y))
|
||||
var cubecoord = map.axial_to_cube(HexGrid.AxialCoordinates.new(target.x, target.y))
|
||||
var cubepos: HexGrid.CubeCoordinates = start
|
||||
var cubecoord: HexGrid.CubeCoordinates = target
|
||||
|
||||
var cubetest: HexGrid.CubeCoordinates = map.axial_to_cube(HexGrid.AxialCoordinates.new(0, 0))
|
||||
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(Vector3i(cubetest.q, cubetest.r, cubetest.s))
|
||||
var right = get_right_neighbour(Vector3i(cubetest.q, cubetest.r, cubetest.s))
|
||||
var left = get_left_neighbour(cubetest)
|
||||
var right = get_right_neighbour(cubetest)
|
||||
|
||||
var left_coord = map.cube_to_axial(HexGrid.CubeCoordinates.new(left.x + cubepos.q, left.y + cubepos.r, left.z + cubepos.s))
|
||||
var right_coord = map.cube_to_axial(HexGrid.CubeCoordinates.new(right.x + cubepos.q, right.y + cubepos.r, right.z + cubepos.s))
|
||||
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(Vector2i(left_coord.q, left_coord.r)) or map.is_cell_empty(Vector2i(right_coord.q, right_coord.r))
|
||||
return map.is_cell_empty(left_coord) or map.is_cell_empty(right_coord)
|
||||
|
||||
func get_left_neighbour(pos: Vector3i) -> Vector3i:
|
||||
return Vector3(-pos.z, -pos.x, -pos.y)
|
||||
func get_left_neighbour(pos: HexGrid.CubeCoordinates) -> HexGrid.CubeCoordinates:
|
||||
return HexGrid.CubeCoordinates.new(-pos.s, -pos.q, -pos.r)
|
||||
|
||||
func get_right_neighbour(pos: Vector3i) -> Vector3i:
|
||||
return Vector3(-pos.y, -pos.z, -pos.x)
|
||||
func get_right_neighbour(pos: HexGrid.CubeCoordinates) -> HexGrid.CubeCoordinates:
|
||||
return HexGrid.CubeCoordinates.new(-pos.r, -pos.s, -pos.q)
|
||||
|
||||
func get_available_spaces(pos: Vector2i, map: HexGrid) -> Array[Vector2i]:
|
||||
func get_available_spaces(pos: HexGrid.CubeCoordinates, map: HexGrid) -> Array[HexGrid.CubeCoordinates]:
|
||||
var potential_spaces = map.get_empty_neighbours(pos)
|
||||
|
||||
var target_spaces: Array[Vector2i] = []
|
||||
var target_spaces: Array[HexGrid.CubeCoordinates] = []
|
||||
|
||||
for neighbour in potential_spaces:
|
||||
if can_reach(pos, neighbour, map):
|
||||
|
|
|
|||
117
Tile/Tile.gd
117
Tile/Tile.gd
|
|
@ -2,18 +2,31 @@ extends Area3D
|
|||
class_name InsectTile
|
||||
|
||||
|
||||
@export var coordinates: Vector2i
|
||||
var coordinates: HexGrid.CubeCoordinates
|
||||
var layer: int = 0
|
||||
|
||||
@export var is_black: bool = false
|
||||
@export var resource: TileResource
|
||||
|
||||
@onready var hexagon_small = $HexagonSmall
|
||||
|
||||
var build_in_progress: bool = false
|
||||
var move_in_progress: bool = false
|
||||
|
||||
var hovered: bool = false
|
||||
|
||||
var selected: bool = false
|
||||
|
||||
var hover_shader: ShaderMaterial = preload("res://InsectTiles/HoverShader.tres")
|
||||
|
||||
const SELECTION_FAILED_MAT: ShaderMaterial = preload("res://InsectTiles/SelectionFailedMat.tres")
|
||||
|
||||
var mat: StandardMaterial3D
|
||||
|
||||
var tween: Tween
|
||||
|
||||
var tweening: bool = false
|
||||
|
||||
func _ready() -> void:
|
||||
if is_black:
|
||||
hexagon_small.set_surface_override_material(0, resource.material_black.duplicate())
|
||||
|
|
@ -22,17 +35,109 @@ 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)
|
||||
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_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:
|
||||
move_in_progress = false
|
||||
selected = false
|
||||
|
||||
if tile == self:
|
||||
hovered = false
|
||||
if not tweening:
|
||||
mat.next_pass = null
|
||||
|
||||
func _on_insect_tile_deselected(tile: InsectTile) -> void:
|
||||
move_in_progress = false
|
||||
selected = false
|
||||
|
||||
func _on_insect_tile_selected(tile: InsectTile) -> void:
|
||||
move_in_progress = true
|
||||
if tile == self:
|
||||
selected = true
|
||||
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: HexGrid.CubeCoordinates) -> 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:
|
||||
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:
|
||||
GameEvents.insect_tile_selected.emit(self)
|
||||
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
|
||||
|
||||
GameEvents.insect_tile_request_selection.emit(self)
|
||||
|
||||
func _on_insect_tile_request_failed(tile) -> void:
|
||||
move_in_progress = false
|
||||
selected = false
|
||||
|
||||
if tile != self:
|
||||
return
|
||||
|
||||
hovered = false
|
||||
|
||||
# siomulate a failed selection request
|
||||
mat.next_pass = SELECTION_FAILED_MAT
|
||||
|
||||
tweening = true
|
||||
|
||||
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)
|
||||
|
||||
GameEvents.insect_tile_deselected.emit(self)
|
||||
|
||||
func _on_mouse_entered():
|
||||
if build_in_progress or move_in_progress:
|
||||
return
|
||||
|
||||
if GameData.is_player_black == is_black:
|
||||
mat.next_pass = hover_shader
|
||||
if tween == null:
|
||||
mat.next_pass = hover_shader
|
||||
hovered = true
|
||||
|
||||
func _on_mouse_exited():
|
||||
hovered = false
|
||||
mat.next_pass = null
|
||||
if selected:
|
||||
return
|
||||
|
||||
hovered = false
|
||||
if tween == null:
|
||||
mat.next_pass = null
|
||||
|
||||
|
|
|
|||
|
|
@ -35,3 +35,66 @@ progressive_web_app/icon_144x144=""
|
|||
progressive_web_app/icon_180x180=""
|
||||
progressive_web_app/icon_512x512=""
|
||||
progressive_web_app/background_color=Color(0, 0, 0, 1)
|
||||
|
||||
[preset.1]
|
||||
|
||||
name="Windows Desktop"
|
||||
platform="Windows Desktop"
|
||||
runnable=true
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path=""
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
||||
|
||||
[preset.1.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
debug/export_console_wrapper=1
|
||||
binary_format/embed_pck=false
|
||||
texture_format/bptc=true
|
||||
texture_format/s3tc=true
|
||||
texture_format/etc=false
|
||||
texture_format/etc2=false
|
||||
binary_format/architecture="x86_64"
|
||||
codesign/enable=false
|
||||
codesign/timestamp=true
|
||||
codesign/timestamp_server_url=""
|
||||
codesign/digest_algorithm=1
|
||||
codesign/description=""
|
||||
codesign/custom_options=PackedStringArray()
|
||||
application/modify_resources=true
|
||||
application/icon=""
|
||||
application/console_wrapper_icon=""
|
||||
application/icon_interpolation=4
|
||||
application/file_version=""
|
||||
application/product_version=""
|
||||
application/company_name=""
|
||||
application/product_name=""
|
||||
application/file_description=""
|
||||
application/copyright=""
|
||||
application/trademarks=""
|
||||
application/export_angle=0
|
||||
ssh_remote_deploy/enabled=false
|
||||
ssh_remote_deploy/host="user@host_ip"
|
||||
ssh_remote_deploy/port="22"
|
||||
ssh_remote_deploy/extra_args_ssh=""
|
||||
ssh_remote_deploy/extra_args_scp=""
|
||||
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
|
||||
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
|
||||
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
|
||||
$settings = New-ScheduledTaskSettingsSet
|
||||
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
|
||||
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
|
||||
Start-ScheduledTask -TaskName godot_remote_debug
|
||||
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
|
||||
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
|
||||
Remove-Item -Recurse -Force '{temp_dir}'"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue