diff options
-rw-r--r-- | Game/Client.gd | 30 | ||||
-rw-r--r-- | Game/Network.gd | 9 | ||||
-rw-r--r-- | Game/Selection/multi_select_area.gd | 3 | ||||
-rw-r--r-- | Game/States/Build/StateBuild.gd | 9 | ||||
-rw-r--r-- | Stages/Stage.gd | 18 | ||||
-rw-r--r-- | Stages/Wintermaul/HUD.gd | 50 | ||||
-rw-r--r-- | Stages/Wintermaul/HUD.tscn | 256 | ||||
-rw-r--r-- | Stages/Wintermaul/Wintermaul.tscn | 2 | ||||
-rw-r--r-- | Stages/Wintermaul/wintermaul.gd | 52 | ||||
-rw-r--r-- | Towers/Tower.gd | 68 | ||||
-rw-r--r-- | Towers/Tower.tscn | 44 | ||||
-rw-r--r-- | UI/PlayersList.tscn | 5 | ||||
-rw-r--r-- | UI/PlayersListItem.tscn | 9 |
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="."] |