summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Game/Client.gd30
-rw-r--r--Game/Network.gd9
-rw-r--r--Game/Selection/multi_select_area.gd3
-rw-r--r--Game/States/Build/StateBuild.gd9
-rw-r--r--Stages/Stage.gd18
-rw-r--r--Stages/Wintermaul/HUD.gd50
-rw-r--r--Stages/Wintermaul/HUD.tscn256
-rw-r--r--Stages/Wintermaul/Wintermaul.tscn2
-rw-r--r--Stages/Wintermaul/wintermaul.gd52
-rw-r--r--Towers/Tower.gd68
-rw-r--r--Towers/Tower.tscn44
-rw-r--r--UI/PlayersList.tscn5
-rw-r--r--UI/PlayersListItem.tscn9
13 files changed, 336 insertions, 219 deletions
diff --git a/Game/Client.gd b/Game/Client.gd
index 60efbb8..98a8e6c 100644
--- a/Game/Client.gd
+++ b/Game/Client.gd
@@ -3,6 +3,10 @@ extends Node
signal stage_state_changed(state: State)
+@warning_ignore("unused_signal")
+signal placed_tower(tower: Tower)
+
+
var state: State :
set(value):
state = value
@@ -31,6 +35,14 @@ func place_tower(tower: Tower):
tower.owner_id = network_id
tower.name = "Tower@" + str(network_id) + "@" + str(Time.get_ticks_usec())
+ tower.attack_range = [
+ current_stage.map.tile_set.tile_size.x * 2,
+ current_stage.map.tile_set.tile_size.x * 3,
+ current_stage.map.tile_set.tile_size.x * 4,
+ ].pick_random()
+ tower.attack_power = [1, 2, 3, 4].pick_random()
+ tower.attack_speed = [1, 2, 3, 4].pick_random()
+
current_stage.place_tower.rpc(inst_to_dict(tower.to_network_data()))
@@ -41,7 +53,7 @@ func remove_tower(tower: Tower):
func destroy_tower(tower: Tower):
current_stage.destroy_tower(tower)
- Network.destroy_tower.rpc(tower.global_position)
+ Network.destroy_tower.rpc(inst_to_dict(tower.to_network_data()))
player.towers.erase(tower.global_position)
@@ -51,10 +63,14 @@ func select_tower(tower: Tower):
tower.is_selected = true
-func deselect_tower():
- if not Tower.selected_towers.is_empty():
- for tower in Tower.selected_towers:
- tower.is_selected = false
+func multi_select(layer: int):
+ var selection_area = preload("res://Game/Selection/MultiSelectArea.tscn").instantiate()
+ selection_area.set_collision_mask_value(layer, true)
+ selection_area.select.connect(func(nodes):
+ for node in nodes:
+ Client.select_tower(node)
+ )
+ get_tree().current_scene.add_child(selection_area)
func update_tower(path: NodePath, data: Tower.NetworkData):
@@ -71,8 +87,8 @@ func spawn_unit(unit: Unit, spawn: Spawn, overwrite_target: PathNode = null):
unit.global_position = spawn.spawn_position
unit.target = spawn.next_node
- unit.hp = randi_range(50, 150) #20000b
- unit.speed = randi_range(100, 150)
+ unit.hp = randi_range(5, 10) #20000b
+ unit.speed = randi_range(50, 150)
if overwrite_target:
unit.target = overwrite_target
diff --git a/Game/Network.gd b/Game/Network.gd
index 5a435b7..be5bb20 100644
--- a/Game/Network.gd
+++ b/Game/Network.gd
@@ -114,10 +114,11 @@ func update_player(id: int, remote_data: Dictionary):
@rpc("any_peer")
#func destroy_tower(remote_tower: Dictionary):
-func destroy_tower(position: Vector2):
- var owner_id = multiplayer.get_remote_sender_id()
- var player = get_player(owner_id)
- var tower = player.towers.get(position)
+func destroy_tower(remote_data: Dictionary):
+ var data: Tower.NetworkData = dict_to_inst(remote_data)
+ var remote_tower = Tower.from_network_data(data)
+ var player = get_player(remote_tower.owner_id)
+ var tower = player.towers.get(remote_tower.global_position)
Client.current_stage.destroy_tower(tower)
diff --git a/Game/Selection/multi_select_area.gd b/Game/Selection/multi_select_area.gd
index c3cc902..88e4f7f 100644
--- a/Game/Selection/multi_select_area.gd
+++ b/Game/Selection/multi_select_area.gd
@@ -5,7 +5,8 @@ signal select(nodes: Array)
func _ready() -> void:
- var camera_rect = Client.current_stage.get_node("Camera").get_rect()
+ var camera: Camera = get_viewport().get_camera_2d()
+ var camera_rect = camera.get_rect()
global_position = camera_rect.position + camera_rect.size / 2
diff --git a/Game/States/Build/StateBuild.gd b/Game/States/Build/StateBuild.gd
index dee5084..e7f122d 100644
--- a/Game/States/Build/StateBuild.gd
+++ b/Game/States/Build/StateBuild.gd
@@ -7,6 +7,10 @@ static var current_builder_element: BuilderElement
func _state_enter():
%BuildGrid.visible = true
+
+ if Tower.selected_towers:
+ for tower in Tower.selected_towers.duplicate():
+ tower.is_selected = false
func _state_exit():
@@ -20,11 +24,6 @@ func _state_input(event: InputEvent):
var placed_tower = current_builder_element.element.instantiate() as Tower
placed_tower.global_position = current_builder_element.global_position
- placed_tower.attack_range = [
- Client.current_stage.map.tile_set.tile_size.x * 2,
- Client.current_stage.map.tile_set.tile_size.x * 3,
- Client.current_stage.map.tile_set.tile_size.x * 4,
- ].pick_random()
Client.place_tower(placed_tower)
diff --git a/Stages/Stage.gd b/Stages/Stage.gd
index cdffca9..a3608ee 100644
--- a/Stages/Stage.gd
+++ b/Stages/Stage.gd
@@ -4,6 +4,7 @@ extends Node
signal path_grid_changed
+static var maps: Array[TileMapLayer]
static var map: TileMapLayer
static var path_grid: AStarGrid2D
static var last_solid_set_points: Array[Vector2]
@@ -14,7 +15,8 @@ func _init() -> void:
func _ready() -> void:
- map = get_node("%Map")
+ maps = [get_node("%Map")]
+ map = maps[0]
path_grid = AStarGrid2D.new()
path_grid.region = map.get_used_rect()
@@ -26,10 +28,12 @@ func _ready() -> void:
assert(get_node("%StateManager"), "StateManager missing")
assert(get_node("%StateManager").get_children().size() > 0, "StateManager has no States")
- for cell in map.get_used_cells():
- var tile_data = map.get_cell_tile_data(cell)
- if tile_data.get_collision_polygons_count(0) > 0:
- path_grid.set_point_solid(cell, true)
+ @warning_ignore("shadowed_variable")
+ for map in maps:
+ for cell in map.get_used_cells():
+ var tile_data = map.get_cell_tile_data(cell)
+ if tile_data.get_collision_polygons_count(0) > 0:
+ path_grid.set_point_solid(cell, true)
func place_tower(_remote_data: Dictionary) -> void:
@@ -81,8 +85,8 @@ func _spawn_unit(parent: Node2D, unit: Unit):
parent.add_child(unit, true)
-func transform_players(script: Script):
- for player in Network.get_node("%Players").get_children():
+func set_player_script(script: Script):
+ for player in Network.get_players():
var previous_values := {}
var property_list = player.get_script().get_script_property_list().filter(func(item):
return item.type != 0
diff --git a/Stages/Wintermaul/HUD.gd b/Stages/Wintermaul/HUD.gd
index b6722ae..6eeb7da 100644
--- a/Stages/Wintermaul/HUD.gd
+++ b/Stages/Wintermaul/HUD.gd
@@ -2,9 +2,9 @@ class_name HUD
extends CanvasLayer
+@onready var time: Label = %Time
@onready var money: Label = %Money
@onready var income: Label = %Income
-@onready var tower: Label = %Tower
@onready var spawn_box: Control = %SpawnBox
@onready var team_top: PanelContainer = %TeamTop
@onready var team_bottom: PanelContainer = %TeamBottom
@@ -27,9 +27,53 @@ func _ready():
Client.stage_state_changed.connect(func(state: State):
if state is StateBuild:
- $TowerConfigurationsContainer.visible = true
+ %TowerConfigurationsContainer.visible = true
else:
- $TowerConfigurationsContainer.visible = false
+ %TowerConfigurationsContainer.visible = false
+ )
+
+ # TODO: fix multi select
+ %SelectionContainer.visible = false
+ %SelectionData.get_child(0).queue_free()
+ %MultiSelectionContainer.visible = false
+ Client.placed_tower.connect(func(tower: Tower):
+ tower.selected.connect(func():
+ var hud_data = tower.get_hud()
+ hud_data.name = tower.name
+
+ var groups = {"md5:1": [], "md5_2": []}
+ var selected_group = "md5"
+ # TODO: build groups from current component configurations matches. md5 of property values?
+ # TODO: do in tower.gd at select?
+
+ if Tower.selected_towers.size() == 1:
+ %SelectionContainer.visible = true
+ %MultiSelectionContainer.visible = false
+
+ %SelectionData.add_child(hud_data)
+ %MultiSelectionList.add_child(hud_data.duplicate())
+ elif Tower.selected_towers.size() > 1:
+ %SelectionContainer.visible = false
+ %MultiSelectionContainer.visible = true
+
+ %MultiSelectionList.add_child(hud_data)
+ )
+ tower.deselected.connect(func():
+ if Tower.selected_towers.size() == 0:
+ %SelectionContainer.visible = false
+ %MultiSelectionContainer.visible = false
+
+ for child in %SelectionData.get_children():
+ child.queue_free()
+ for child in %MultiSelectionList.get_children():
+ child.queue_free()
+ elif Tower.selected_towers.size() == 1:
+ %MultiSelectionContainer.visible = false
+ %SelectionContainer.visible = true
+ elif Tower.selected_towers.size() > 1:
+ # only remove deselected tower from list
+ %MultiSelectionList.get_node(NodePath(tower.name)).queue_free()
+ )
)
diff --git a/Stages/Wintermaul/HUD.tscn b/Stages/Wintermaul/HUD.tscn
index cb14d33..024910f 100644
--- a/Stages/Wintermaul/HUD.tscn
+++ b/Stages/Wintermaul/HUD.tscn
@@ -133,6 +133,11 @@ theme_override_constants/margin_right = 8
[node name="HBoxContainer" type="HBoxContainer" parent="Panel/VBoxContainer/Container/MarginContainer"]
layout_mode = 2
+[node name="Time" type="Label" parent="Panel/VBoxContainer/Container/MarginContainer/HBoxContainer"]
+unique_name_in_owner = true
+layout_mode = 2
+text = "0"
+
[node name="Money" type="Label" parent="Panel/VBoxContainer/Container/MarginContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
@@ -147,34 +152,150 @@ text = "0"
custom_minimum_size = Vector2(0, 1)
layout_mode = 2
-[node name="SpawnBox" type="PanelContainer" parent="."]
-unique_name_in_owner = true
-anchors_preset = 3
+[node name="VBoxContainer" type="VBoxContainer" parent="."]
+anchors_preset = 1
anchor_left = 1.0
-anchor_top = 1.0
anchor_right = 1.0
-anchor_bottom = 1.0
-offset_left = -148.0
-offset_top = -116.0
+offset_left = -288.0
+offset_top = 41.0
offset_right = -4.0
-offset_bottom = -4.0
+offset_bottom = 131.0
grow_horizontal = 0
+mouse_filter = 0
+
+[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
+layout_mode = 2
+mouse_filter = 0
+
+[node name="LivesTop" type="Label" parent="VBoxContainer/HBoxContainer"]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 0
+text = "Lives"
+
+[node name="TeamTop" parent="VBoxContainer/HBoxContainer" instance=ExtResource("16_mq4um")]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer"]
+layout_mode = 2
+mouse_filter = 0
+
+[node name="LivesBottom" type="Label" parent="VBoxContainer/HBoxContainer2"]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 0
+text = "Lives"
+
+[node name="TeamBottom" parent="VBoxContainer/HBoxContainer2" instance=ExtResource("16_mq4um")]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="MarginContainer" type="MarginContainer" parent="."]
+anchors_preset = 12
+anchor_top = 1.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_top = -120.0
+grow_horizontal = 2
grow_vertical = 0
+theme_override_constants/margin_left = 4
+theme_override_constants/margin_top = 4
+theme_override_constants/margin_right = 4
+theme_override_constants/margin_bottom = 4
+
+[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"]
+layout_mode = 2
+
+[node name="TowerConfigurationsContainer" type="PanelContainer" parent="MarginContainer/HBoxContainer"]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_stretch_ratio = 100.0
+mouse_filter = 1
+
+[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/HBoxContainer/TowerConfigurationsContainer"]
+layout_mode = 2
+theme_override_constants/margin_left = 8
+theme_override_constants/margin_top = 8
+theme_override_constants/margin_right = 8
+theme_override_constants/margin_bottom = 8
+
+[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer/HBoxContainer/TowerConfigurationsContainer/MarginContainer"]
+layout_mode = 2
+vertical_scroll_mode = 0
+
+[node name="TowerConfigurations" type="HBoxContainer" parent="MarginContainer/HBoxContainer/TowerConfigurationsContainer/MarginContainer/ScrollContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+
+[node name="TextureRect" parent="MarginContainer/HBoxContainer/TowerConfigurationsContainer/MarginContainer/ScrollContainer/TowerConfigurations" instance=ExtResource("17_1c5dq")]
+layout_mode = 2
+
+[node name="MultiSelectionContainer" type="PanelContainer" parent="MarginContainer/HBoxContainer"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(200, 0)
+layout_mode = 2
+size_flags_horizontal = 6
+size_flags_stretch_ratio = 2.0
+
+[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/HBoxContainer/MultiSelectionContainer"]
+layout_mode = 2
+theme_override_constants/margin_left = 4
+theme_override_constants/margin_top = 4
+theme_override_constants/margin_right = 4
+theme_override_constants/margin_bottom = 4
+
+[node name="MultiSelectionList" type="HFlowContainer" parent="MarginContainer/HBoxContainer/MultiSelectionContainer/MarginContainer"]
+unique_name_in_owner = true
+layout_mode = 2
+last_wrap_alignment = 1
+
+[node name="SelectionContainer" type="PanelContainer" parent="MarginContainer/HBoxContainer"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(200, 0)
+layout_mode = 2
+size_flags_horizontal = 6
+size_flags_stretch_ratio = 2.0
+
+[node name="SelectionData" type="MarginContainer" parent="MarginContainer/HBoxContainer/SelectionContainer"]
+unique_name_in_owner = true
+layout_mode = 2
+theme_override_constants/margin_left = 4
+theme_override_constants/margin_top = 4
+theme_override_constants/margin_right = 4
+theme_override_constants/margin_bottom = 4
+
+[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HBoxContainer/SelectionContainer/SelectionData"]
+layout_mode = 2
+
+[node name="Label" type="Label" parent="MarginContainer/HBoxContainer/SelectionContainer/SelectionData/VBoxContainer"]
+layout_mode = 2
+text = "T"
+
+[node name="SpawnBox" type="PanelContainer" parent="MarginContainer/HBoxContainer"]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_horizontal = 10
+size_flags_stretch_ratio = 0.0
-[node name="MarginContainer" type="MarginContainer" parent="SpawnBox"]
+[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/HBoxContainer/SpawnBox"]
layout_mode = 2
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
-[node name="GridContainer" type="GridContainer" parent="SpawnBox/MarginContainer"]
+[node name="GridContainer" type="GridContainer" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer"]
layout_mode = 2
theme_override_constants/h_separation = 0
theme_override_constants/v_separation = 0
columns = 4
-[node name="SpawnButton" parent="SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
+[node name="SpawnButton" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
layout_mode = 2
theme = ExtResource("5_121ry")
texture_normal = ExtResource("4_w7sef")
@@ -182,166 +303,75 @@ texture_pressed = ExtResource("5_xcxr8")
texture_hover = ExtResource("6_4go2d")
texture = ExtResource("7_ba5tw")
-[node name="SpawnButton2" parent="SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
+[node name="SpawnButton2" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
layout_mode = 2
shortcut = SubResource("Shortcut_i6rmj")
texture_normal = ExtResource("8_wmbg8")
texture_hover = ExtResource("6_4go2d")
texture = ExtResource("9_nmd8t")
-[node name="SpawnButton3" parent="SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
+[node name="SpawnButton3" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
layout_mode = 2
texture_normal = ExtResource("10_daowa")
texture_pressed = ExtResource("5_xcxr8")
texture_hover = ExtResource("6_4go2d")
texture = ExtResource("11_yxcwt")
-[node name="SpawnButton4" parent="SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
+[node name="SpawnButton4" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
layout_mode = 2
texture_normal = ExtResource("12_20egp")
texture_pressed = ExtResource("5_xcxr8")
texture_hover = ExtResource("6_4go2d")
texture = ExtResource("13_iq5a7")
-[node name="SpawnButton5" parent="SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
+[node name="SpawnButton5" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
layout_mode = 2
texture_normal = ExtResource("14_t3qlu")
texture_pressed = ExtResource("5_xcxr8")
texture_hover = ExtResource("6_4go2d")
-[node name="SpawnButton6" parent="SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
+[node name="SpawnButton6" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
layout_mode = 2
texture_normal = ExtResource("14_t3qlu")
texture_pressed = ExtResource("5_xcxr8")
texture_hover = ExtResource("6_4go2d")
-[node name="SpawnButton7" parent="SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
+[node name="SpawnButton7" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
layout_mode = 2
texture_normal = ExtResource("14_t3qlu")
texture_pressed = ExtResource("5_xcxr8")
texture_hover = ExtResource("6_4go2d")
-[node name="SpawnButton8" parent="SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
+[node name="SpawnButton8" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
layout_mode = 2
texture_normal = ExtResource("14_t3qlu")
texture_pressed = ExtResource("5_xcxr8")
texture_hover = ExtResource("6_4go2d")
-[node name="SpawnButton9" parent="SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
+[node name="SpawnButton9" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
layout_mode = 2
texture_normal = ExtResource("14_t3qlu")
texture_pressed = ExtResource("5_xcxr8")
texture_hover = ExtResource("6_4go2d")
-[node name="SpawnButton10" parent="SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
+[node name="SpawnButton10" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
layout_mode = 2
texture_normal = ExtResource("14_t3qlu")
texture_pressed = ExtResource("5_xcxr8")
texture_hover = ExtResource("6_4go2d")
-[node name="SpawnButton11" parent="SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
+[node name="SpawnButton11" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
layout_mode = 2
texture_normal = ExtResource("14_t3qlu")
texture_pressed = ExtResource("5_xcxr8")
texture_hover = ExtResource("6_4go2d")
-[node name="SpawnButton12" parent="SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
+[node name="SpawnButton12" parent="MarginContainer/HBoxContainer/SpawnBox/MarginContainer/GridContainer" instance=ExtResource("3_7eaea")]
layout_mode = 2
texture_normal = ExtResource("14_t3qlu")
texture_pressed = ExtResource("5_xcxr8")
texture_hover = ExtResource("6_4go2d")
-[node name="VBoxContainer" type="VBoxContainer" parent="."]
-anchors_preset = 1
-anchor_left = 1.0
-anchor_right = 1.0
-offset_left = -256.0
-offset_top = 41.0
-offset_right = -4.0
-offset_bottom = 131.0
-grow_horizontal = 0
-mouse_filter = 0
-
-[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
-layout_mode = 2
-mouse_filter = 0
-
-[node name="LivesTop" type="Label" parent="VBoxContainer/HBoxContainer"]
-unique_name_in_owner = true
-layout_mode = 2
-size_flags_horizontal = 0
-text = "Lives"
-
-[node name="TeamTop" parent="VBoxContainer/HBoxContainer" instance=ExtResource("16_mq4um")]
-unique_name_in_owner = true
-layout_mode = 2
-size_flags_horizontal = 3
-
-[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer"]
-layout_mode = 2
-mouse_filter = 0
-
-[node name="LivesBottom" type="Label" parent="VBoxContainer/HBoxContainer2"]
-unique_name_in_owner = true
-layout_mode = 2
-size_flags_horizontal = 0
-text = "Lives"
-
-[node name="TeamBottom" parent="VBoxContainer/HBoxContainer2" instance=ExtResource("16_mq4um")]
-unique_name_in_owner = true
-layout_mode = 2
-size_flags_horizontal = 3
-
-[node name="CenterContainer" type="CenterContainer" parent="."]
-anchors_preset = 12
-anchor_top = 1.0
-anchor_right = 1.0
-anchor_bottom = 1.0
-offset_top = -23.0
-grow_horizontal = 2
-grow_vertical = 0
-
-[node name="Tower" type="Label" parent="CenterContainer"]
-unique_name_in_owner = true
-layout_mode = 2
-
-[node name="TowerConfigurationsContainer" type="MarginContainer" parent="."]
-visible = false
-anchors_preset = 12
-anchor_top = 1.0
-anchor_right = 1.0
-anchor_bottom = 1.0
-offset_top = -120.0
-offset_right = -152.0
-grow_horizontal = 2
-grow_vertical = 0
-theme_override_constants/margin_left = 4
-theme_override_constants/margin_top = 4
-theme_override_constants/margin_right = 4
-theme_override_constants/margin_bottom = 4
-
-[node name="PanelContainer" type="PanelContainer" parent="TowerConfigurationsContainer"]
-layout_mode = 2
-
-[node name="MarginContainer" type="MarginContainer" parent="TowerConfigurationsContainer/PanelContainer"]
-layout_mode = 2
-theme_override_constants/margin_left = 8
-theme_override_constants/margin_top = 8
-theme_override_constants/margin_right = 8
-theme_override_constants/margin_bottom = 8
-
-[node name="ScrollContainer" type="ScrollContainer" parent="TowerConfigurationsContainer/PanelContainer/MarginContainer"]
-layout_mode = 2
-vertical_scroll_mode = 0
-
-[node name="TowerConfigurations" type="HBoxContainer" parent="TowerConfigurationsContainer/PanelContainer/MarginContainer/ScrollContainer"]
-layout_mode = 2
-size_flags_horizontal = 3
-size_flags_vertical = 3
-
-[node name="TextureRect" parent="TowerConfigurationsContainer/PanelContainer/MarginContainer/ScrollContainer/TowerConfigurations" instance=ExtResource("17_1c5dq")]
-layout_mode = 2
-
[connection signal="gui_input" from="Panel/VBoxContainer/Container/GridContainer/MarginContainer/HBoxContainer/BuildModeButton" to="." method="_on_build_mode_button_gui_input"]
[connection signal="gui_input" from="Panel/VBoxContainer/Container/GridContainer/MarginContainer2/HBoxContainer2/SpawnerBoxButton" to="." method="_on_spawner_box_button_gui_input"]
[connection signal="gui_input" from="Panel/VBoxContainer/Container/GridContainer/MarginContainer3/HBoxContainer2/PlayerListButton" to="." method="_on_player_list_button_gui_input"]
diff --git a/Stages/Wintermaul/Wintermaul.tscn b/Stages/Wintermaul/Wintermaul.tscn
index 1fe8b26..6cf2d05 100644
--- a/Stages/Wintermaul/Wintermaul.tscn
+++ b/Stages/Wintermaul/Wintermaul.tscn
@@ -138,6 +138,6 @@ position = Vector2(2200, 1192)
shape = SubResource("RectangleShape2D_cwpxx")
[node name="IncomeTimer" type="Timer" parent="."]
-wait_time = 15.0
+one_shot = true
[connection signal="timeout" from="IncomeTimer" to="." method="_on_income_timer_timeout"]
diff --git a/Stages/Wintermaul/wintermaul.gd b/Stages/Wintermaul/wintermaul.gd
index 680f692..b638c97 100644
--- a/Stages/Wintermaul/wintermaul.gd
+++ b/Stages/Wintermaul/wintermaul.gd
@@ -16,11 +16,13 @@ class Team extends Resource:
var teams := Teams.new()
+var income_frequency := 15.0
+
func _init():
super._init()
- transform_players(preload("res://Stages/Wintermaul/player.gd"))
+ set_player_script(preload("res://Stages/Wintermaul/player.gd"))
teams.top.lives = 10
teams.bottom.lives = 10
@@ -33,8 +35,8 @@ func _ready():
if multiplayer.is_server():
for player in Network.get_players():
Network.update_player.rpc(player.id, {
- "money": 5,
- "income": 1,
+ "money": 50,
+ "income": 5,
})
# set camera limits
@@ -58,36 +60,43 @@ func _ready():
%HUD.get_node("%TeamTop").players = teams.top.players
%HUD.get_node("%TeamBottom").players = teams.bottom.players
- # start timer on server
- if multiplayer.is_server():
- $IncomeTimer.start()
+ # initialize timer and start
+ $IncomeTimer.wait_time = income_frequency
+ $IncomeTimer.start()
# initialize lives display
update_lives("top", 0)
update_lives("bottom", 0)
+func _process(_delta: float) -> void:
+ %HUD.time.text = "Time: %.0fs" % clamp($IncomeTimer.time_left + 0.5, 0, $IncomeTimer.wait_time)
+
+
@rpc("any_peer", "call_local")
func place_tower(remote_data: Dictionary):
var data: Tower.NetworkData = dict_to_inst(remote_data)
var tower = Tower.from_network_data(data)
- Network.get_player(tower.owner_id).towers[tower.global_position] = tower
+ var player = Network.get_player(tower.owner_id)
+ player.towers[tower.global_position] = tower
if multiplayer.is_server():
- var player = Network.get_player(tower.owner_id)
- Network.update_player.rpc(player.id, {"money": -1})
+ Network.update_player.rpc(player.id, {"money": -5})
_place_tower(%Towers, tower)
+ Client.placed_tower.emit(tower)
+
@rpc("any_peer", "call_local")
func spawn_unit(remote_data: Dictionary):
var data: Unit.NetworkData = dict_to_inst(remote_data)
var unit := Unit.from_network_data(data)
+ var player = Network.get_player(unit.owner_id)
+ player.units.append(unit)
+
if multiplayer.is_server():
- var player = Network.get_player(unit.owner_id)
-
unit.reached_goal.connect(func():
var team = get_team(player)
if team == teams.top:
@@ -97,7 +106,7 @@ func spawn_unit(remote_data: Dictionary):
)
Network.update_player.rpc(player.id, {
- "money": -1,
+ "money": -5,
"income": 1,
})
@@ -105,14 +114,14 @@ func spawn_unit(remote_data: Dictionary):
func can_place_tower():
- if Client.player.money < 1:
+ if Client.player.money < 5:
print("Not enough money to build tower")
return false
return true
func can_spawn_unit():
- if Client.player.money < 1:
+ if Client.player.money < 5:
print("Not enough money to spawn unit")
return false
@@ -156,10 +165,17 @@ func get_builder_collision_masks():
func _on_income_timer_timeout() -> void:
- for player in Network.get_players():
- Network.update_player.rpc(player.id, {
- "money": player.income,
- })
+ if multiplayer.is_server():
+ for player in Network.get_players():
+ Network.update_player.rpc(player.id, {
+ "money": player.income,
+ })
+ reset_timer.rpc()
+
+@rpc("authority", "call_local")
+func reset_timer():
+ $IncomeTimer.wait_time = income_frequency
+ $IncomeTimer.start()
@rpc("authority", "call_local")
diff --git a/Towers/Tower.gd b/Towers/Tower.gd
index 30af802..7eb8bf6 100644
--- a/Towers/Tower.gd
+++ b/Towers/Tower.gd
@@ -13,13 +13,12 @@ var is_selected = false :
if value:
if not Tower.selected_towers.has(self):
Tower.selected_towers.append(self)
- selected.emit()
+ selected.emit()
else:
Tower.selected_towers.erase(self)
deselected.emit()
is_selected = value
queue_redraw()
- toggle_ui()
var is_hovered = false :
set(value):
@@ -51,7 +50,10 @@ func _ready():
$Range/CollisionShape2D.shape.radius = attack_range
$ShootCooldown.wait_time = attack_speed
- toggle_ui()
+ %Data.text = "Range: %s - Power: %s - Speed: %s" % [
+ attack_range, attack_power, attack_speed
+ ]
+
#for component in [
#preload("res://Towers/Components/FrostComponent.gd").new(),
@@ -61,16 +63,9 @@ func _ready():
func _draw():
- if is_selected:
- draw_circle(
- Client.current_stage.map.tile_set.tile_size,
- 8 + attack_range,
- Color(1, 1, 1, 0.75),
- false,
- 1.0
- )
- modulate = Color(1.5, 1.5, 1.5)
- elif is_hovered:
+ modulate = Color(1, 1, 1)
+
+ if is_hovered:
if Client.state is StateDefault:
draw_circle(
Client.current_stage.map.tile_set.tile_size,
@@ -80,8 +75,9 @@ func _draw():
1.0
)
modulate = Color(1.25, 1.25, 1.25)
- else:
- modulate = Color(1, 1, 1)
+
+ if is_selected:
+ modulate = Color(1.5, 1.5, 1.5)
func _process(_delta: float) -> void:
@@ -126,16 +122,13 @@ func _on_selectable_area_select(event: InputEvent) -> void:
return
if Client.state is StateDefault:
- Client.select_tower(self)
-
- if event.is_double_click():
- var selection_area = preload("res://Game/Selection/MultiSelectArea.tscn").instantiate()
- selection_area.set_collision_mask_value(3, true)
- selection_area.select.connect(func(nodes):
- for node in nodes:
- Client.select_tower(node)
- )
- get_tree().current_scene.add_child(selection_area)
+ if Input.is_action_pressed("select_multiple") and is_selected:
+ is_selected = false
+ else:
+ Client.select_tower(self)
+
+ if event.is_double_click():
+ Client.multi_select(3)
@@ -182,8 +175,8 @@ func shoot():
target.set_hp(target.hp - 1)
-func toggle_ui():
- $HUD.visible = is_selected
+func get_hud():
+ return %HUD.get_child(0).duplicate()
func get_region():
@@ -200,15 +193,6 @@ func _on_tree_exiting() -> void:
is_selected = false
-func get_rpc_properties() -> Dictionary:
- return {
- "name": null,
- "global_position": null,
- "owner_id": null,
- "attack_range": null,
- }
-
-
func _on_h_box_container_gui_input(event: InputEvent) -> void:
if event.is_action_pressed("select"):
get_viewport().set_input_as_handled()
@@ -251,6 +235,10 @@ class NetworkData extends Resource:
var name: String
var owner_id: int
var position: Vector2
+
+ var attack_range: int
+ var attack_power: int
+ var attack_speed: int
var components: Array
var sprite_modulate: Color
@@ -262,6 +250,10 @@ func to_network_data() -> NetworkData:
data.name = name
data.owner_id = owner_id
data.position = global_position
+
+ data.attack_range = attack_range
+ data.attack_power = attack_power
+ data.attack_speed = attack_speed
data.components = components.map(func(item: TowerComponent):
return item.name
)
@@ -289,4 +281,8 @@ static func from_network_data(data: NetworkData) -> Tower:
tower.owner_id = data.owner_id
tower.global_position = data.position
+ tower.attack_range = data.attack_range
+ tower.attack_power = data.attack_power
+ tower.attack_speed = data.attack_speed
+
return tower
diff --git a/Towers/Tower.tscn b/Towers/Tower.tscn
index 43c3c35..55ae928 100644
--- a/Towers/Tower.tscn
+++ b/Towers/Tower.tscn
@@ -71,43 +71,55 @@ shape = SubResource("RectangleShape2D_312i7")
position = Vector2(0, 32)
[node name="HUD" type="CanvasLayer" parent="."]
-
-[node name="CenterContainer" type="CenterContainer" parent="HUD"]
-anchors_preset = 12
-anchor_top = 1.0
-anchor_right = 1.0
-anchor_bottom = 1.0
+unique_name_in_owner = true
+visible = false
+
+[node name="VBoxContainer" type="VBoxContainer" parent="HUD"]
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -38.0
+offset_top = -25.0
+offset_right = 38.0
+offset_bottom = 25.0
grow_horizontal = 2
-grow_vertical = 0
+grow_vertical = 2
+
+[node name="Data" type="Label" parent="HUD/VBoxContainer"]
+unique_name_in_owner = true
+layout_mode = 2
-[node name="VBoxContainer" type="VBoxContainer" parent="HUD/CenterContainer"]
+[node name="Components" type="VBoxContainer" parent="HUD/VBoxContainer"]
+unique_name_in_owner = true
layout_mode = 2
-[node name="HBoxContainer" type="HBoxContainer" parent="HUD/CenterContainer/VBoxContainer"]
+[node name="HBoxContainer" type="HBoxContainer" parent="HUD/VBoxContainer/Components"]
layout_mode = 2
mouse_default_cursor_shape = 2
-[node name="TextureRect" type="TextureRect" parent="HUD/CenterContainer/VBoxContainer/HBoxContainer"]
+[node name="TextureRect" type="TextureRect" parent="HUD/VBoxContainer/Components/HBoxContainer"]
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
texture = ExtResource("4_ccrqc")
stretch_mode = 5
-[node name="Label" type="Label" parent="HUD/CenterContainer/VBoxContainer/HBoxContainer"]
+[node name="Label" type="Label" parent="HUD/VBoxContainer/Components/HBoxContainer"]
layout_mode = 2
text = "Frost"
-[node name="HBoxContainer2" type="HBoxContainer" parent="HUD/CenterContainer/VBoxContainer"]
+[node name="HBoxContainer2" type="HBoxContainer" parent="HUD/VBoxContainer/Components"]
layout_mode = 2
mouse_default_cursor_shape = 2
-[node name="TextureRect" type="TextureRect" parent="HUD/CenterContainer/VBoxContainer/HBoxContainer2"]
+[node name="TextureRect" type="TextureRect" parent="HUD/VBoxContainer/Components/HBoxContainer2"]
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
texture = ExtResource("5_y7tf5")
stretch_mode = 5
-[node name="Label" type="Label" parent="HUD/CenterContainer/VBoxContainer/HBoxContainer2"]
+[node name="Label" type="Label" parent="HUD/VBoxContainer/Components/HBoxContainer2"]
layout_mode = 2
text = "Burn"
@@ -121,5 +133,5 @@ replication_config = SubResource("SceneReplicationConfig_spp26")
[connection signal="hover_enter" from="SelectableArea" to="." method="_on_selectable_area_hover_enter"]
[connection signal="hover_exit" from="SelectableArea" to="." method="_on_selectable_area_hover_exit"]
[connection signal="select" from="SelectableArea" to="." method="_on_selectable_area_select"]
-[connection signal="gui_input" from="HUD/CenterContainer/VBoxContainer/HBoxContainer" to="." method="_on_h_box_container_gui_input"]
-[connection signal="gui_input" from="HUD/CenterContainer/VBoxContainer/HBoxContainer2" to="." method="_on_h_box_container_2_gui_input"]
+[connection signal="gui_input" from="HUD/VBoxContainer/Components/HBoxContainer" to="." method="_on_h_box_container_gui_input"]
+[connection signal="gui_input" from="HUD/VBoxContainer/Components/HBoxContainer2" to="." method="_on_h_box_container_2_gui_input"]
diff --git a/UI/PlayersList.tscn b/UI/PlayersList.tscn
index 2575b73..4ba62f7 100644
--- a/UI/PlayersList.tscn
+++ b/UI/PlayersList.tscn
@@ -4,7 +4,7 @@
[ext_resource type="PackedScene" uid="uid://wxe1hpn013y8" path="res://UI/PlayersListItem.tscn" id="2_ug8m7"]
[node name="PlayersList" type="PanelContainer"]
-offset_right = 96.0
+offset_right = 192.0
offset_bottom = 43.0
script = ExtResource("1_67rpy")
@@ -22,9 +22,6 @@ layout_mode = 2
[node name="Header" parent="MarginContainer/List" instance=ExtResource("2_ug8m7")]
layout_mode = 2
-[node name="ID" parent="MarginContainer/List/Header/HBoxContainer" index="0"]
-text = "ID"
-
[node name="Score" parent="MarginContainer/List/Header/HBoxContainer" index="2"]
text = "Income"
diff --git a/UI/PlayersListItem.tscn b/UI/PlayersListItem.tscn
index 36a934b..1544c35 100644
--- a/UI/PlayersListItem.tscn
+++ b/UI/PlayersListItem.tscn
@@ -1,8 +1,8 @@
[gd_scene format=3 uid="uid://wxe1hpn013y8"]
[node name="PlayersListItem" type="MarginContainer"]
-offset_right = 6.0
-offset_bottom = 23.0
+offset_right = 192.0
+offset_bottom = 27.0
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 2
theme_override_constants/margin_right = 8
@@ -15,8 +15,9 @@ layout_mode = 2
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
+size_flags_stretch_ratio = 2.0
mouse_filter = 1
-text = "1"
+text = "ID"
horizontal_alignment = 1
clip_text = true
text_overrun_behavior = 3
@@ -30,7 +31,7 @@ size_flags_horizontal = 3
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
-text = "0"
+text = "Score"
horizontal_alignment = 1
[node name="Indicator" type="Control" parent="."]