Prepared Movement behaviour. Fixed multi-tile placement bug
This commit is contained in:
parent
62eef907d3
commit
397082f966
17 changed files with 395 additions and 75 deletions
|
|
@ -1,11 +1,11 @@
|
|||
extends Resource
|
||||
class_name ActionBehaviour
|
||||
|
||||
func do_action() -> void:
|
||||
func do_action(source_tile: InsectTile, action_tile: InsectTile, map: HexGrid) -> void:
|
||||
pass
|
||||
|
||||
func select_targets(source_pos: Vector4i, map: HexGrid) -> void:
|
||||
pass
|
||||
func get_targets(source_pos: Vector4i, map: HexGrid) -> Array[InsectTile]:
|
||||
return []
|
||||
|
||||
# NOTE: When selecting a tile, check if there is an action behaviour
|
||||
# If yes: In addition to showing moveable spaces (0 for the mosquito by default)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,18 @@
|
|||
extends ActionBehaviour
|
||||
class_name ActionBehaviourMosquito
|
||||
|
||||
func do_action(source_tile: InsectTile, action_tile: InsectTile, map: HexGrid) -> void:
|
||||
pass
|
||||
|
||||
# GameEvents.insect_tiles_selected_for_action
|
||||
func select_targets(source_pos: Vector4i, map: HexGrid): # -> Array[InsectTile]:
|
||||
func get_targets(source_pos: Vector4i, map: HexGrid) -> Array[InsectTile]:
|
||||
# if on the hive, i.e. layer > 0, we always move like a beetle
|
||||
# so we can't use our action unless we're on layer 0
|
||||
# TODO: Update movement selection
|
||||
if source_pos.w > 0:
|
||||
map.debug_label(Vector3(source_pos.x, source_pos.y, source_pos.z), "TODO: Implement Beetle Movement")
|
||||
return []
|
||||
|
||||
var neighbours = map.get_neighbours(source_pos)
|
||||
# Filter out other mosquitos
|
||||
var possible_action_targets: Array[InsectTile] = []
|
||||
|
|
@ -10,8 +20,9 @@ func select_targets(source_pos: Vector4i, map: HexGrid): # -> Array[InsectTile]:
|
|||
var tile = map.get_tile(neighbour)
|
||||
if tile != null:
|
||||
# TODO: Find better way to see what tile we have...
|
||||
pass
|
||||
#if not tile.resource.movement_behaviour is MovementBehaviourMosquito:
|
||||
# possible_action_targets.push_back(tile)
|
||||
if not tile.resource.movement_behaviour is MovementBehaviourMosquito:
|
||||
possible_action_targets.push_back(tile)
|
||||
|
||||
GameEvents.insect_tiles_selected_for_action.emit(source_pos, possible_action_targets)
|
||||
#GameEvents.insect_tiles_selected_for_action.emit(source_pos, possible_action_targets)
|
||||
|
||||
return possible_action_targets
|
||||
|
|
|
|||
|
|
@ -1,12 +1,24 @@
|
|||
extends ActionBehaviour
|
||||
class_name ActionBehaviourPillbug
|
||||
|
||||
func select_targets(source_pos: Vector4i, map: HexGrid): # -> Array[InsectTile]:
|
||||
func do_action(source_tile: InsectTile, action_tile: InsectTile, map: HexGrid) -> void:
|
||||
pass
|
||||
|
||||
func get_targets(source_pos: Vector4i, map: HexGrid) -> Array[InsectTile]:
|
||||
var neighbours = map.get_neighbours(source_pos)
|
||||
var possible_action_targets: Array[InsectTile] = []
|
||||
|
||||
for neighbour in neighbours:
|
||||
var tile = map.get_tile(neighbour)
|
||||
if tile != null:
|
||||
if not tile.is_in_stack() and tile.can_move():
|
||||
possible_action_targets.push_back(tile)
|
||||
|
||||
GameEvents.insect_tiles_selected_for_action.emit(source_pos, possible_action_targets)
|
||||
#GameEvents.insect_tiles_selected_for_action.emit(source_pos, possible_action_targets)
|
||||
|
||||
return possible_action_targets
|
||||
|
||||
|
||||
# 2nd level has to be clear (move through narrow gap rule)
|
||||
# We could do the following: Get neighbours in 2nd level of source (pillbug) and target
|
||||
# we we have two overlapping/same neighbours, we have a narrow gap and can't move the target
|
||||
|
|
|
|||
11
Game.gd
11
Game.gd
|
|
@ -10,7 +10,7 @@ var current_turn: int = 1
|
|||
func _ready():
|
||||
GameEvents.insect_tile_finished_moving.connect(_on_insect_tile_finished_moving)
|
||||
GameEvents.insect_tile_created.connect(_on_insect_tile_created)
|
||||
|
||||
GameEvents.pass_round.connect(_on_pass_round)
|
||||
# since we sealed in webrtc,
|
||||
# and limited players to 1 in enet
|
||||
# this should only happen when the opponent disconnects
|
||||
|
|
@ -21,6 +21,14 @@ func _ready():
|
|||
|
||||
GameEvents.game_started.emit()
|
||||
|
||||
|
||||
@rpc("any_peer", "call_local")
|
||||
func pass_round() -> void:
|
||||
advance_turn()
|
||||
|
||||
func _on_pass_round() -> void:
|
||||
pass_round.rpc()
|
||||
|
||||
func _on_peer_disconnected(id: int) -> void:
|
||||
GameData.disconnect_reason = "Connection to other peer closed unexpectedly"
|
||||
#Networking.disconnect_all()
|
||||
|
|
@ -31,6 +39,7 @@ func _on_peer_disconnected(id: int) -> void:
|
|||
#Networking.disconnect_all()
|
||||
# get_tree().change_scene_to_file("res://UI/main_menu.tscn")
|
||||
|
||||
|
||||
func advance_turn():
|
||||
GameEvents.turn_ended.emit(current_turn, map)
|
||||
is_blacks_turn = !is_blacks_turn
|
||||
|
|
|
|||
75
Game.tscn
75
Game.tscn
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=23 format=3 uid="uid://bx0bbrwdr0h40"]
|
||||
[gd_scene load_steps=24 format=3 uid="uid://bx0bbrwdr0h40"]
|
||||
|
||||
[ext_resource type="Script" path="res://Game.gd" id="1_dgt1j"]
|
||||
[ext_resource type="Script" path="res://CameraPivot.gd" id="2_71xp1"]
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
[ext_resource type="Script" path="res://TurnTexture.gd" id="12_kjwp8"]
|
||||
[ext_resource type="Script" path="res://addons/awesome_input_icons/classes/InputIconTextureRect.gd" id="13_mbmni"]
|
||||
[ext_resource type="Texture2D" uid="uid://20wqrthwoqr0" path="res://addons/awesome_input_icons/assets/keyboard and mouse vector/mouse_move.svg" id="14_t8b21"]
|
||||
[ext_resource type="Script" path="res://UI/ActionMoveMenu.gd" id="15_gc6p8"]
|
||||
|
||||
[sub_resource type="PlaneMesh" id="PlaneMesh_cu5ir"]
|
||||
material = ExtResource("5_u4p4p")
|
||||
|
|
@ -250,6 +251,19 @@ offset_bottom = 40.0
|
|||
layout_mode = 2
|
||||
text = "Menu"
|
||||
|
||||
[node name="PassRoundButton" type="Button" parent="MenuButtons/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Pass"
|
||||
|
||||
[node name="SurrenderButton" type="Button" parent="MenuButtons/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Surrender"
|
||||
|
||||
[node name="OfferDrawButton" type="Button" parent="MenuButtons/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
disabled = true
|
||||
text = "Offer Draw"
|
||||
|
||||
[node name="RulesButton" type="Button" parent="MenuButtons/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Rules"
|
||||
|
|
@ -465,6 +479,65 @@ theme_override_font_sizes/font_size = 20
|
|||
text = "Show/Hide controls"
|
||||
horizontal_alignment = 2
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="ActionMoveMenu" type="Control" parent="CanvasLayer"]
|
||||
visible = false
|
||||
layout_mode = 3
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
script = ExtResource("15_gc6p8")
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="CanvasLayer/ActionMoveMenu"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="CanvasLayer/ActionMoveMenu/PanelContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
theme_override_constants/margin_left = 15
|
||||
theme_override_constants/margin_top = 15
|
||||
theme_override_constants/margin_right = 15
|
||||
theme_override_constants/margin_bottom = 15
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/ActionMoveMenu/PanelContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
|
||||
[node name="MoveButton" type="Button" parent="CanvasLayer/ActionMoveMenu/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Use action of #Name"
|
||||
|
||||
[node name="ActionButton" type="Button" parent="CanvasLayer/ActionMoveMenu/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Move as #Name"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="CanvasLayer/ActionMoveMenu/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="CancelButton" type="Button" parent="CanvasLayer/ActionMoveMenu/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Cancel"
|
||||
|
||||
[connection signal="pressed" from="MenuButtons/VBoxContainer/MenuButton" to="MenuButtons" method="_on_menu_button_pressed"]
|
||||
[connection signal="pressed" from="MenuButtons/VBoxContainer/PassRoundButton" to="MenuButtons" method="_on_pass_round_button_pressed"]
|
||||
[connection signal="pressed" from="MenuButtons/VBoxContainer/SurrenderButton" to="MenuButtons" method="_on_surrender_button_pressed"]
|
||||
[connection signal="pressed" from="MenuButtons/VBoxContainer/OfferDrawButton" to="MenuButtons" method="_on_menu_button_pressed"]
|
||||
[connection signal="pressed" from="MenuButtons/VBoxContainer/RulesButton" to="MenuButtons" method="_on_rules_button_pressed"]
|
||||
[connection signal="pressed" from="GameOverMenu/Control/PanelContainer/VBoxContainer/Button" to="GameOverMenu" method="_on_button_pressed"]
|
||||
[connection signal="pressed" from="CanvasLayer/ActionMoveMenu/PanelContainer/MarginContainer/VBoxContainer/MoveButton" to="CanvasLayer/ActionMoveMenu" method="_on_move_button_pressed"]
|
||||
[connection signal="pressed" from="CanvasLayer/ActionMoveMenu/PanelContainer/MarginContainer/VBoxContainer/ActionButton" to="CanvasLayer/ActionMoveMenu" method="_on_action_button_pressed"]
|
||||
[connection signal="pressed" from="CanvasLayer/ActionMoveMenu/PanelContainer/MarginContainer/VBoxContainer/CancelButton" to="CanvasLayer/ActionMoveMenu" method="_on_cancel_button_pressed"]
|
||||
|
|
|
|||
|
|
@ -22,4 +22,5 @@ func _on_game_over(black_lost: bool, white_lost: bool) -> void:
|
|||
|
||||
func _on_button_pressed():
|
||||
#WSClient.close()
|
||||
get_tree().change_scene_to_file("res://main_menu.tscn")
|
||||
Networking.disconnect_all()
|
||||
get_tree().change_scene_to_file("res://UI/main_menu.tscn")
|
||||
|
|
|
|||
|
|
@ -6,15 +6,21 @@ signal insect_placement_cancelled
|
|||
|
||||
signal insect_tile_created(tile, pos)
|
||||
signal insect_tile_selected(tile)
|
||||
signal insect_tile_selecetion_failed(tile)
|
||||
signal insect_tile_deselected(tile)
|
||||
signal insect_tile_moved(tile, to)
|
||||
signal insect_tile_finished_moving(tile, to)
|
||||
|
||||
signal insect_tiles_selected_for_action(source_tile, target_tiles, action)
|
||||
signal insect_action_cancelled()
|
||||
signal insect_action_done() # ??? Maybe? Right no we have a gameendchecker...
|
||||
signal insect_action_done() # ??? Maybe? Right now we have a gameendchecker...
|
||||
|
||||
signal choose_action_or_move(tile, has_action_targets, has_move_targets)
|
||||
signal insect_tile_move_started(tile)
|
||||
signal insect_tile_action_started(tile)
|
||||
|
||||
# Turn started could work implicitly? We'll see...
|
||||
signal pass_round
|
||||
signal turn_started(turn_num, map, is_blacks_turn)
|
||||
signal turn_ended(turn_num, map)
|
||||
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ func debug_label(pos, text) -> void:
|
|||
var label = Label3D.new()
|
||||
label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
|
||||
label.text = text
|
||||
label.no_depth_test = true
|
||||
var p = cube_to_world_pos(pos)
|
||||
label.position = Vector3(p.x, 0.2, p.y)
|
||||
add_child(label)
|
||||
|
|
@ -289,23 +290,37 @@ func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) ->
|
|||
place_insect_tile.rpc(resource_path, is_black, pos)
|
||||
|
||||
func can_move(tile: InsectTile) -> bool:
|
||||
return can_hive_exist_without_tile(tile)
|
||||
if not can_hive_exist_without_tile(tile):
|
||||
return false
|
||||
|
||||
func _on_insect_tile_selected(tile: InsectTile) -> void:
|
||||
var spaces = tile.resource.movement_behaviour.get_available_spaces(tile.coordinates, self)
|
||||
|
||||
if spaces.is_empty():
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
func has_action_targets(tile: InsectTile) -> bool:
|
||||
if tile.resource.action_behaviour == null:
|
||||
return false
|
||||
|
||||
var targets: Array[InsectTile] = tile.resource.action_behaviour.get_targets(tile.coordinates, self)
|
||||
|
||||
return !targets.is_empty()
|
||||
|
||||
func _on_insect_tile_action_started(tile: InsectTile) -> void:
|
||||
do_action(tile)
|
||||
|
||||
func _on_insect_tile_move_started(tile: InsectTile) -> void:
|
||||
do_move(tile)
|
||||
|
||||
func do_action(tile: InsectTile) -> void:
|
||||
pass
|
||||
|
||||
func do_move(tile: InsectTile) -> void:
|
||||
for child in placement_visualizer.get_children():
|
||||
child.queue_free()
|
||||
|
||||
if not can_hive_exist_without_tile(tile):
|
||||
print("Would break hive")
|
||||
return
|
||||
|
||||
if tile.resource.movement_behaviour == null:
|
||||
#print("no movement behaviour")
|
||||
return
|
||||
|
||||
#if tile.resource.action_behaviour != null:
|
||||
#tile.resource.action_behaviour.select_targets(tile.coordinates, self)
|
||||
|
||||
var spaces = tile.resource.movement_behaviour.get_available_spaces(tile.coordinates, self)
|
||||
|
||||
if spaces.is_empty():
|
||||
|
|
@ -356,6 +371,26 @@ func _on_insect_tile_selected(tile: InsectTile) -> void:
|
|||
placement_visualizer.add_child(outline)
|
||||
placements[space] = outline
|
||||
|
||||
func _on_insect_tile_selected(tile: InsectTile) -> void:
|
||||
# check the following:
|
||||
# if the insect is selectable for an action (has action_callback data set) -> do that action
|
||||
# else:
|
||||
# if the unit has no action
|
||||
# try moving
|
||||
# else:
|
||||
# show action/move panel, grey out action/or move if there are no target or can't move?
|
||||
if tile.action_callback.is_valid():
|
||||
tile.action_callback.call()
|
||||
return
|
||||
else:
|
||||
# if tile has an action
|
||||
if tile.resource.action_behaviour != null:
|
||||
GameEvents.choose_action_or_move.emit(tile, has_action_targets(tile), can_move(tile))
|
||||
return
|
||||
|
||||
if can_move(tile):
|
||||
do_move(tile)
|
||||
|
||||
func get_tile(pos: Vector4i) -> InsectTile:
|
||||
return used_cells.get(pos)
|
||||
|
||||
|
|
@ -458,3 +493,5 @@ 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)
|
||||
GameEvents.insect_tile_action_started.connect(_on_insect_tile_action_started)
|
||||
GameEvents.insect_tile_move_started.connect(_on_insect_tile_move_started)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ var is_moving: bool = false
|
|||
|
||||
var map_reference: HexGrid
|
||||
|
||||
var is_active: bool = true
|
||||
|
||||
const BUILD_GHOST = preload("res://InsectTiles/BuildGhost.tscn")
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
|
|
@ -28,14 +30,17 @@ func _ready():
|
|||
GameEvents.insect_placed.connect(_on_insect_placed)
|
||||
|
||||
func _on_insect_tile_moved(tile: InsectTile, to: Vector4i) -> void:
|
||||
is_active = false
|
||||
queue_free()
|
||||
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) -> void:
|
||||
is_active = false
|
||||
queue_free()
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
if Input.is_action_just_pressed("place_tile"):
|
||||
#func _process(delta):
|
||||
func _input_event(camera, event, position, normal, shape_idx):
|
||||
if Input.is_action_just_pressed("place_tile") and is_active:
|
||||
if hovered:
|
||||
if is_moving:
|
||||
GameEvents.insect_tile_moved.emit(insect_tile, coordinates)
|
||||
|
|
@ -50,10 +55,8 @@ func _on_mouse_entered():
|
|||
tile.is_black = is_black
|
||||
tile.map_reference = map_reference
|
||||
|
||||
|
||||
add_child(tile)
|
||||
|
||||
|
||||
func _on_input_event(camera, event, position, normal, shape_idx):
|
||||
pass # Replace with function body.
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,6 @@ func hide_panel() -> void:
|
|||
|
||||
tween.finished.connect(_on_panel_hidden)
|
||||
|
||||
|
||||
|
||||
func _on_panel_hidden() -> void:
|
||||
visible = false
|
||||
queue_free()
|
||||
|
|
|
|||
|
|
@ -2,10 +2,20 @@ extends Control
|
|||
|
||||
const IN_GAME_MENU = preload("res://UI/InGameMenu/InGameMenu.tscn")
|
||||
const RULES = preload("res://UI/Rules/Rules.tscn")
|
||||
|
||||
@onready var surrender_button = $VBoxContainer/SurrenderButton
|
||||
@onready var pass_round_button = $VBoxContainer/PassRoundButton
|
||||
|
||||
var is_blacks_turn: bool = false
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
GameEvents.turn_started.connect(_on_turn_started)
|
||||
|
||||
func _on_turn_started(round_num: int, map: HexGrid, _is_blacks_turn: bool) -> void:
|
||||
is_blacks_turn = _is_blacks_turn
|
||||
surrender_button.disabled = GameData.is_player_black != _is_blacks_turn and not GameData.is_hot_seat
|
||||
pass_round_button.disabled = GameData.is_player_black != _is_blacks_turn and not GameData.is_hot_seat
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
|
|
@ -25,3 +35,16 @@ func _on_menu_button_pressed():
|
|||
get_tree().root.add_child(in_game_menu)
|
||||
|
||||
in_game_menu.show_panel()
|
||||
|
||||
@rpc("any_peer", "call_local")
|
||||
func surrender() -> void:
|
||||
if is_blacks_turn:
|
||||
GameEvents.game_over.emit(true, false)
|
||||
else:
|
||||
GameEvents.game_over.emit(false, true)
|
||||
|
||||
func _on_surrender_button_pressed():
|
||||
surrender.rpc()
|
||||
|
||||
func _on_pass_round_button_pressed():
|
||||
GameEvents.pass_round.emit()
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ func simulate_move_recursive(start: Vector4i, max_num: int, exclude: Array[Vecto
|
|||
|
||||
visited.append(start)
|
||||
|
||||
|
||||
if max_num < 1:
|
||||
return [start]
|
||||
|
||||
|
|
@ -19,8 +20,8 @@ func simulate_move_recursive(start: Vector4i, max_num: int, exclude: Array[Vecto
|
|||
neighbours = map.get_empty_neighbours(start)
|
||||
|
||||
for neighbour in neighbours:
|
||||
if neighbour in visited:
|
||||
continue
|
||||
#if neighbour in visited:
|
||||
# continue
|
||||
|
||||
#var same_neighbours = map.get_same_neighbours(start, neighbour)
|
||||
#for e in exclude:
|
||||
|
|
@ -28,6 +29,7 @@ func simulate_move_recursive(start: Vector4i, max_num: int, exclude: Array[Vecto
|
|||
|
||||
#if same_neighbours.size() > 0:
|
||||
visited.append(neighbour)
|
||||
|
||||
possible.append_array(simulate_move_recursive(neighbour, max_num - 1, exclude, map, visited))
|
||||
|
||||
return possible
|
||||
|
|
@ -37,4 +39,11 @@ func get_available_spaces(pos: Vector4i, map: HexGrid) -> Array[Vector4i]:
|
|||
|
||||
possible_places = simulate_move_recursive(pos, max_movement_reach, [pos], map)
|
||||
|
||||
var possible_places_dict: Dictionary = {}
|
||||
for p in possible_places:
|
||||
possible_places_dict[p] = p
|
||||
|
||||
possible_places.clear()
|
||||
possible_places.assign(possible_places_dict.values())
|
||||
|
||||
return possible_places
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@ extends MovementBehaviour
|
|||
class_name MovementBehaviourMosquito
|
||||
|
||||
func get_available_spaces(pos: Vector4i, map: HexGrid) -> Array[Vector4i]:
|
||||
var target_spaces: Array[Vector4i] = []
|
||||
|
||||
for neighbour in map.get_neighbours(pos):
|
||||
if map.is_cell_empty(neighbour):
|
||||
continue
|
||||
|
||||
target_spaces.append_array(map.get_tile(neighbour).resource.movement_behaviour.get_available_spaces(pos, map))
|
||||
|
||||
return target_spaces
|
||||
return []
|
||||
#var target_spaces: Array[Vector4i] = []
|
||||
#
|
||||
#for neighbour in map.get_neighbours(pos):
|
||||
#if map.is_cell_empty(neighbour):
|
||||
#continue
|
||||
#
|
||||
#target_spaces.append_array(map.get_tile(neighbour).resource.movement_behaviour.get_available_spaces(pos, map))
|
||||
#
|
||||
#return target_spaces
|
||||
|
|
|
|||
102
Tile/Tile.gd
102
Tile/Tile.gd
|
|
@ -6,7 +6,6 @@ var map_reference: HexGrid
|
|||
var is_blacks_turn: bool = false
|
||||
|
||||
var coordinates: Vector4i
|
||||
var layer: int = 0
|
||||
|
||||
@export var is_black: bool = false
|
||||
@export var resource: TileResource
|
||||
|
|
@ -18,17 +17,14 @@ 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
|
||||
|
||||
var hover_shader: ShaderMaterial = preload("res://InsectTiles/HoverShader.tres")
|
||||
|
||||
const SELECTION_FAILED_MAT: ShaderMaterial = preload("res://InsectTiles/SelectionFailedMat.tres")
|
||||
const ACTION_SHADER = preload("res://InsectTiles/ActionShader.tres")
|
||||
var hover_shader: ShaderMaterial = preload("res://InsectTiles/HoverShader.tres")
|
||||
#const SELECTION_FAILED_MAT: ShaderMaterial = preload("res://InsectTiles/SelectionFailedMat.tres")
|
||||
#const ACTION_SHADER = preload("res://InsectTiles/ActionShader.tres")
|
||||
|
||||
var mat: StandardMaterial3D
|
||||
|
||||
|
|
@ -37,8 +33,25 @@ var tween: Tween
|
|||
var tweening: bool = false
|
||||
|
||||
var selected_for_action: bool = false
|
||||
var action_callback: Callable = Callable()
|
||||
|
||||
|
||||
var can_be_selected: bool = false
|
||||
|
||||
var move_round_penalty: int = 0
|
||||
|
||||
func is_in_stack() -> bool:
|
||||
return hat != null or coordinates.w != 0
|
||||
|
||||
func can_move() -> bool:
|
||||
# if any tile gets moved, set move_round_penalty to 2
|
||||
# on turn start subtract 1
|
||||
# we can't move if its 1, so we have to wait an additional round
|
||||
# this is ued for the pillbug ability
|
||||
# also if we move, we also set it to 2
|
||||
|
||||
return move_round_penalty == 0
|
||||
|
||||
func is_players_turn() -> bool:
|
||||
return is_blacks_turn == is_black
|
||||
|
||||
|
|
@ -69,18 +82,45 @@ func _ready() -> void:
|
|||
hexagon_small.rotation.y = PI
|
||||
|
||||
GameEvents.insect_selected.connect(_on_insect_selected)
|
||||
GameEvents.insect_tile_selecetion_failed.connect(_on_selection_failed)
|
||||
GameEvents.insect_placed.connect(_on_insect_placed)
|
||||
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)
|
||||
|
||||
GameEvents.insect_tiles_selected_for_action.connect(_on_tiles_selected_for_action)
|
||||
GameEvents.insect_action_cancelled.connect(_on_action_cancelled)
|
||||
|
||||
GameEvents.turn_started.connect(_on_turn_started)
|
||||
|
||||
func _on_action_cancelled() -> void:
|
||||
selected_for_action = false
|
||||
move_in_progress = false
|
||||
selected = false
|
||||
|
||||
if hovered:
|
||||
hover()
|
||||
else:
|
||||
if tween != null:
|
||||
tween.kill()
|
||||
|
||||
tween.tween_method(tween_shader, mat.next_pass.get_shader_parameter("albedo"), Color(1, 1, 1, 0), 0.5).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO)
|
||||
|
||||
|
||||
func _on_selection_failed(tile: InsectTile) -> void:
|
||||
if tile != self:
|
||||
return
|
||||
|
||||
# Show selection failed mat
|
||||
|
||||
func _on_turn_started(turn_num: int, map: HexGrid, _is_blacks_turn: bool) -> void:
|
||||
is_blacks_turn = _is_blacks_turn
|
||||
|
||||
move_round_penalty -= 1
|
||||
if move_round_penalty < 0:
|
||||
move_round_penalty = 0
|
||||
|
||||
can_be_selected = GameData.bees_placed.has(is_black)
|
||||
#print(GameData.has_bee_been_placed)
|
||||
if turn_num >= 7 and not GameData.bees_placed.has(is_black):
|
||||
|
|
@ -89,7 +129,12 @@ func _on_turn_started(turn_num: int, map: HexGrid, _is_blacks_turn: bool) -> voi
|
|||
func _on_tiles_selected_for_action(source_pos: Vector4i, targets: Array[InsectTile]) -> void:
|
||||
if self in targets:
|
||||
selected_for_action = true
|
||||
mat.next_pass = ACTION_SHADER
|
||||
if tween != null:
|
||||
tween.kill()
|
||||
|
||||
tween = get_tree().create_tween()
|
||||
#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_shader, Color(0, 0.6, 0, 0), Color(0, 0.6, 0, 0.8), 0.5).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO)
|
||||
return
|
||||
|
||||
deactivated = true
|
||||
|
|
@ -98,35 +143,49 @@ func _on_tiles_selected_for_action(source_pos: Vector4i, targets: Array[InsectTi
|
|||
func _on_insect_tile_moved(tile: InsectTile, to: Vector4i) -> void:
|
||||
move_in_progress = false
|
||||
selected = false
|
||||
deactivated = false
|
||||
|
||||
if tile == self:
|
||||
hovered = false
|
||||
if not tweening:
|
||||
mat.next_pass = null
|
||||
move_round_penalty == 2
|
||||
|
||||
func _on_insect_tile_deselected(tile: InsectTile) -> void:
|
||||
move_in_progress = false
|
||||
selected = false
|
||||
deactivated = false
|
||||
|
||||
if hovered:
|
||||
hover()
|
||||
else:
|
||||
if tween != null:
|
||||
tween.kill()
|
||||
|
||||
#tween.tween_method(tween_shader, mat.next_pass.get_shader_parameter("albedo"), Color(1, 1, 1, 0), 0.5).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO)
|
||||
|
||||
func _on_insect_tile_selected(tile: InsectTile) -> void:
|
||||
deactivated = true
|
||||
if tile == self:
|
||||
selected = true
|
||||
return
|
||||
|
||||
func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) -> void:
|
||||
build_in_progress = false
|
||||
deactivated = false
|
||||
|
||||
func _on_insect_placement_cancelled() -> void:
|
||||
build_in_progress = false
|
||||
deactivated = false
|
||||
|
||||
func _on_insect_selected(button: InsectButton, is_black: bool) -> void:
|
||||
build_in_progress = true
|
||||
deactivated = true
|
||||
|
||||
func _process(delta):
|
||||
#func _process(delta):
|
||||
func _input_event(camera, event, position, normal, shape_idx):
|
||||
if Input.is_action_just_pressed("place_tile"):
|
||||
if not can_be_selected:
|
||||
if deactivated:
|
||||
return
|
||||
|
||||
if deactivated:
|
||||
if not can_be_selected:
|
||||
return
|
||||
|
||||
if not hovered:
|
||||
|
|
@ -157,16 +216,17 @@ func hover() -> void:
|
|||
if is_blacks_turn != is_black:
|
||||
return
|
||||
|
||||
# mat.next_pass = hover_shader.duplicate()
|
||||
|
||||
if tween != null:
|
||||
tween.kill()
|
||||
|
||||
tween = get_tree().create_tween()
|
||||
#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)
|
||||
tween.tween_method(tween_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:
|
||||
func tween_shader(color: Color) -> void:
|
||||
mat.next_pass.set_shader_parameter("albedo", color)
|
||||
mat.next_pass.set_shader_parameter("emission_color", color)
|
||||
|
||||
|
|
@ -179,16 +239,22 @@ func unhover() -> void:
|
|||
|
||||
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)
|
||||
tween.tween_method(tween_shader, Color(0, 0, 0, 1), Color(0, 0, 0, 0), 0.25).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO)
|
||||
|
||||
|
||||
func _on_mouse_entered():
|
||||
if hat != null:
|
||||
return
|
||||
|
||||
hovered = true
|
||||
|
||||
if not deactivated and not selected_for_action:
|
||||
hover()
|
||||
|
||||
func _on_mouse_exited():
|
||||
if hat != null:
|
||||
return
|
||||
|
||||
hovered = false
|
||||
|
||||
if not selected and not selected_for_action:
|
||||
|
|
|
|||
71
UI/ActionMoveMenu.gd
Normal file
71
UI/ActionMoveMenu.gd
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
extends Control
|
||||
|
||||
@onready var move_button = $PanelContainer/MarginContainer/VBoxContainer/MoveButton
|
||||
@onready var action_button = $PanelContainer/MarginContainer/VBoxContainer/ActionButton
|
||||
|
||||
var current_tile: InsectTile = null
|
||||
var tween: Tween = null
|
||||
|
||||
func show_panel() -> void:
|
||||
scale = Vector2.ZERO
|
||||
|
||||
visible = true
|
||||
if tween != null:
|
||||
tween.kill()
|
||||
|
||||
tween = get_tree().create_tween()
|
||||
tween.tween_property(self, "scale", Vector2(1.0, 1.0), 0.35).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_SPRING)
|
||||
|
||||
func hide_panel() -> void:
|
||||
current_tile = null
|
||||
|
||||
if tween != null:
|
||||
tween.kill()
|
||||
|
||||
tween = get_tree().create_tween()
|
||||
tween.tween_property(self, "scale", Vector2(0.0, 0.0), 0.35).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_EXPO)
|
||||
|
||||
tween.finished.connect(_on_panel_hidden)
|
||||
pass
|
||||
|
||||
func _on_panel_hidden() -> void:
|
||||
visible = false
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
GameEvents.choose_action_or_move.connect(_on_choose_action_or_move)
|
||||
GameEvents.insect_tile_deselected.connect(_on_tile_deselected)
|
||||
|
||||
func _on_tile_deselected(tile: InsectTile) -> void:
|
||||
hide_panel()
|
||||
|
||||
|
||||
func _on_choose_action_or_move(tile: InsectTile, has_action_targets: bool, can_move: bool) -> void:
|
||||
current_tile = tile
|
||||
move_button.text = "Move as %s" % tile.resource.tile_name
|
||||
move_button.disabled = !can_move
|
||||
|
||||
action_button.text = "Use action of %s" % tile.resource.tile_name
|
||||
action_button.disabled = !has_action_targets
|
||||
show_panel()
|
||||
pass
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
func _on_action_button_pressed():
|
||||
GameEvents.insect_tile_action_started.emit(current_tile)
|
||||
hide_panel()
|
||||
|
||||
|
||||
func _on_move_button_pressed():
|
||||
GameEvents.insect_tile_move_started.emit(current_tile)
|
||||
hide_panel()
|
||||
|
||||
|
||||
func _on_cancel_button_pressed():
|
||||
GameEvents.insect_tile_deselected.emit(current_tile)
|
||||
pass # Replace with function body.
|
||||
|
|
@ -11,9 +11,9 @@ const default_insects = {
|
|||
preload("res://Tile/Prefabs/Beetle.tres"): 2,
|
||||
preload("res://Tile/Prefabs/Grasshopper.tres"): 3,
|
||||
preload("res://Tile/Prefabs/Spider.tres"): 2,
|
||||
#preload("res://Tile/Prefabs/Ladybug.tres"): 1,
|
||||
#preload("res://Tile/Prefabs/Mosquito.tres"): 1,
|
||||
#preload("res://Tile/Prefabs/Pillbug.tres"): 1
|
||||
preload("res://Tile/Prefabs/Ladybug.tres"): 1,
|
||||
preload("res://Tile/Prefabs/Mosquito.tres"): 1,
|
||||
preload("res://Tile/Prefabs/Pillbug.tres"): 1
|
||||
}
|
||||
|
||||
var local_bee_button: InsectButton
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ text = "Join Game"
|
|||
[node name="SingleplayerButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
disabled = true
|
||||
text = "Singleplayer"
|
||||
text = "Singleplayer (vs AI)"
|
||||
|
||||
[node name="HSeparator2" type="HSeparator" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue