summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Effects/BurnEffect.tscn6
-rw-r--r--Effects/SlowEffect.gd14
-rw-r--r--Effects/burn_effect.gd20
-rw-r--r--Game/Client.gd31
-rw-r--r--Game/Network.gd51
-rw-r--r--Game/Player.gd2
-rw-r--r--Game/Selection/selectable_area.gd12
-rw-r--r--Game/Selection/selection_rectangle.gd15
-rw-r--r--Game/States/Build/BuilderElement.gd11
-rw-r--r--Game/States/Build/StateBuild.gd22
-rw-r--r--Game/States/Default/StateDefault.gd10
-rw-r--r--Game/States/StateManager.gd4
-rw-r--r--Stages/Stage.gd15
-rw-r--r--Towers/Components/Assets/attack-component.png (renamed from Towers/Assets/attack-component.png)bin191 -> 191 bytes
-rw-r--r--Towers/Components/Assets/attack-component.png.import (renamed from Towers/Assets/attack-component.png.import)6
-rw-r--r--Towers/Components/Assets/attack-component.png~ (renamed from Towers/Assets/attack-component.png~)bin206 -> 206 bytes
-rw-r--r--Towers/Components/Assets/burn-component.png (renamed from Towers/Assets/burn-component.png)bin175 -> 175 bytes
-rw-r--r--Towers/Components/Assets/burn-component.png.import (renamed from Towers/Assets/burn-component.png.import)6
-rw-r--r--Towers/Components/Assets/burn-component.png~ (renamed from Towers/Assets/burn-component.png~)bin175 -> 175 bytes
-rw-r--r--Towers/Components/Assets/frost-component.png (renamed from Towers/Assets/frost-component.png)bin176 -> 176 bytes
-rw-r--r--Towers/Components/Assets/frost-component.png.import (renamed from Towers/Assets/frost-component.png.import)6
-rw-r--r--Towers/Components/Assets/range-component.png (renamed from Towers/Assets/range-component.png)bin162 -> 162 bytes
-rw-r--r--Towers/Components/Assets/range-component.png.import (renamed from Towers/Assets/range-component.png.import)6
-rw-r--r--Towers/Components/Assets/range-component.png~ (renamed from Towers/Assets/range-component.png~)bin176 -> 176 bytes
-rw-r--r--Towers/Components/BurnComponent.gd11
-rw-r--r--Towers/Components/FrostComponent.gd11
-rw-r--r--Towers/Components/TowerComponent.gd15
-rw-r--r--Towers/Tower.gd120
-rw-r--r--Towers/Tower.tscn70
-rw-r--r--UI/Camera.tscn2
-rw-r--r--UI/HUD.tscn33
-rw-r--r--UI/Lobby.gd9
-rw-r--r--UI/Lobby.tscn6
-rw-r--r--UI/PlayersList.tscn4
-rw-r--r--UI/PlayersListItem.tscn3
-rw-r--r--UI/players_list.gd2
-rw-r--r--UI/tower_configuration.gd9
-rw-r--r--Units/Unit.gd101
-rw-r--r--Units/Unit.tscn22
-rw-r--r--Units/UnitPathLine.tscn10
-rw-r--r--export_presets.cfg4
41 files changed, 522 insertions, 147 deletions
diff --git a/Effects/BurnEffect.tscn b/Effects/BurnEffect.tscn
new file mode 100644
index 0000000..a8e1ed0
--- /dev/null
+++ b/Effects/BurnEffect.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://dmj3et5exg4s5"]
+
+[ext_resource type="Script" path="res://Effects/burn_effect.gd" id="1_8my4q"]
+
+[node name="BurnEffect" type="Node2D"]
+script = ExtResource("1_8my4q")
diff --git a/Effects/SlowEffect.gd b/Effects/SlowEffect.gd
index 27dcc59..a3070ca 100644
--- a/Effects/SlowEffect.gd
+++ b/Effects/SlowEffect.gd
@@ -12,15 +12,11 @@ var magnitude: float = 0.5 :
func _ready():
- if self.name != "SlowEffect" and unit.has_node("SlowEffect"):
- unit.get_node("SlowEffect").set_duration(5.0)
- queue_free()
- else:
- add()
- set_duration(5.0)
- duration_finished.connect(func():
- remove()
- )
+ add()
+ set_duration(5.0)
+ duration_finished.connect(func():
+ remove()
+ )
func add():
diff --git a/Effects/burn_effect.gd b/Effects/burn_effect.gd
new file mode 100644
index 0000000..9693292
--- /dev/null
+++ b/Effects/burn_effect.gd
@@ -0,0 +1,20 @@
+extends Effect
+
+
+@onready var unit: Unit = get_parent()
+
+var base_modulate: Color
+
+
+func _ready():
+ base_modulate = unit.get_node("Sprite2D").self_modulate
+
+ set_duration(5.0)
+
+ set_tick(1.0)
+ tick_finished.connect(func():
+ unit.set_hp(unit.hp - 5)
+ unit.get_node("Sprite2D").self_modulate = Color(1, 0, 0)
+ await get_tree().create_timer(0.1).timeout
+ unit.get_node("Sprite2D").self_modulate = base_modulate
+ )
diff --git a/Game/Client.gd b/Game/Client.gd
index 3d9cf34..dbaf69e 100644
--- a/Game/Client.gd
+++ b/Game/Client.gd
@@ -9,11 +9,11 @@ var state: State :
stage_state_changed.emit(value)
var stage: Stage
-var player: Player
+var player: Player = Player.new()
func _ready():
- player = Player.new()
+ #player = Player.new()
player.id = multiplayer.get_unique_id()
@@ -29,11 +29,12 @@ func initialize_stage(current_stage: Stage):
func place_tower(tower: Tower, position: Vector2):
var network_id = multiplayer.get_unique_id()
tower.owner_id = network_id
- tower.set_multiplayer_authority(network_id)
+ #tower.set_multiplayer_authority(network_id)
tower.name = "Tower@" + str(network_id) + "@" + str(Time.get_ticks_usec())
stage.place_tower(tower, position)
- Network.place_tower.rpc(Network.to_rpc_object(tower), position)
+ Network.place_tower.rpc(inst_to_dict(tower.to_network_data()))
+ #Network.place_tower.rpc(Network.to_rpc_object(tower), position)
player.towers[position] = tower
player.score += 1
@@ -48,8 +49,10 @@ func remove_tower(tower: Tower):
func destroy_tower(tower: Tower):
- stage.destroy_tower(tower)
- Network.destroy_tower.rpc(Network.to_rpc_object(tower))
+ if multiplayer.is_server():
+ stage.destroy_tower(tower)
+ else:
+ Network.destroy_tower.rpc_id(1, tower.global_position)
player.towers.erase(tower.global_position)
update_player()
@@ -66,19 +69,27 @@ func deselect_tower():
tower.is_selected = false
+func update_tower(tower: Tower, data: Dictionary):
+ Network.update_tower.rpc(tower.get_path(), data)
+
+
func spawn_unit(unit: Unit, spawn: Spawn):
var network_id = multiplayer.get_unique_id()
unit.owner_id = network_id
- unit.set_multiplayer_authority(network_id)
+ #unit.set_multiplayer_authority(network_id)
unit.name = "Unit@" + str(network_id) + "@" + str(Time.get_ticks_usec())
unit.global_position = spawn.spawn_position
- unit.target = spawn.next_node
+ unit.target = spawn.next_node.path_position
unit.hp = randi_range(50, 150) #20000b
unit.speed = randi_range(100, 150)
- stage.spawn_unit(unit, spawn)
- Network.spawn_unit.rpc(Network.to_rpc_object(unit), Network.to_rpc_object(spawn))
+ stage.spawn_unit(unit)
+
+ #var data := UnitCreationData.fromUnit(unit)
+ var data := unit.to_network_data()
+ Network.spawn_unit.rpc(inst_to_dict(data))
+ #Network.spawn_unit.rpc(Network.to_rpc_object(unit), Network.to_rpc_object(spawn))
func array_intersect(first, second):
diff --git a/Game/Network.gd b/Game/Network.gd
index 9349245..48558ce 100644
--- a/Game/Network.gd
+++ b/Game/Network.gd
@@ -156,35 +156,55 @@ func get_nested_node_and_property(node: Node, property: String) -> Dictionary:
@rpc("any_peer")
-func place_tower(remote_tower: Dictionary, position: Vector2):
+#func place_tower(remote_tower: Dictionary, position: Vector2):
+func place_tower(remote_data: Dictionary):
+ var data: Tower.NetworkData = dict_to_inst(remote_data)
var remote_player_id = multiplayer.get_remote_sender_id()
- var tower = from_rpc_object(remote_tower, "res://Towers/Tower.tscn")
+ var tower = Tower.from_network_data(data)
tower.owner_id = remote_player_id
players[remote_player_id].towers[tower.global_position] = tower
- Client.stage.place_tower(tower, position)
+ Client.stage.place_tower(tower, tower.global_position)
@rpc("any_peer")
-func destroy_tower(remote_tower: Dictionary):
- var player = players[remote_tower.owner_id] as Player
- var tower = player.towers.get(remote_tower.global_position)
+#func destroy_tower(remote_tower: Dictionary):
+func destroy_tower(position: Vector2):
+ var owner_id = multiplayer.get_remote_sender_id()
+ var player = players[owner_id] as Player
+ var tower = player.towers.get(position)
Client.stage.destroy_tower(tower)
@rpc("any_peer")
-func spawn_unit(remote_unit: Dictionary, remote_spawn: Dictionary):
- var unit = from_rpc_object(remote_unit, "res://Units/Unit.tscn")
- var spawn = from_rpc_object(remote_spawn, "res://Stages/Paths/Spawn.tscn")
+func update_tower(remote_tower_node_path, data):
+ var tower: Tower = get_tree().current_scene.get_node_or_null(remote_tower_node_path)
+ if tower:
+ if "components" in data:
+ for c in tower.components.duplicate():
+ tower.remove_component(c.name)
+ for c in data.components:
+ tower.add_component(
+ load("res://Towers/Components/" + c + "Component.gd").new()
+ )
+
+
+@rpc("any_peer")
+func spawn_unit(remote_data: Dictionary):#, _remote_spawn: Dictionary):
+ #print(remote_data)
+ var data: Unit.NetworkData = dict_to_inst(remote_data)
+ var unit := Unit.from_network_data(data)
+ #var spawn = from_rpc_object(remote_spawn, "res://Stages/Paths/Spawn.tscn")
var remote_id = multiplayer.get_remote_sender_id()
unit.owner_id = remote_id
- unit.set_multiplayer_authority(remote_id)
+ #unit.set_multiplayer_authority(remote_id)
- Client.stage.spawn_unit(unit, spawn)
+ Client.stage.spawn_unit(unit)
+
@rpc("any_peer")
func remove_unit(remote_unit_node_path):
@@ -192,13 +212,20 @@ func remove_unit(remote_unit_node_path):
if unit:
unit.queue_free()
+
@rpc("any_peer")
func update_unit(remote_unit_node_path, data):
var unit: Unit = get_tree().current_scene.get_node_or_null(remote_unit_node_path)
if unit:
+ if "hp" in data:
+ unit.hp = data.hp
if "position" in data:
unit.position = data.position
- unit.hp = data.hp
if "sprite" in data:
unit.get_node("Sprite2D").self_modulate = data.sprite.self_modulate
+ if "current_path" in data:
+ unit.current_path = data.current_path
+ unit.line.points = PackedVector2Array(data.current_path)
+ if "current_path_idx" in data:
+ unit.current_path_idx = data.current_path_idx
diff --git a/Game/Player.gd b/Game/Player.gd
index 43856d5..dce19db 100644
--- a/Game/Player.gd
+++ b/Game/Player.gd
@@ -5,6 +5,7 @@ extends Resource
signal score_changed
var id := 1
+var name := ""
var towers: Dictionary :
set(value):
@@ -32,5 +33,6 @@ func get_color():
func get_rpc_properties() -> Dictionary:
return {
"id": null,
+ "name": null,
"score": null,
}
diff --git a/Game/Selection/selectable_area.gd b/Game/Selection/selectable_area.gd
index 59d4be7..b3336f1 100644
--- a/Game/Selection/selectable_area.gd
+++ b/Game/Selection/selectable_area.gd
@@ -6,12 +6,12 @@ signal hover_exit
signal select(event: InputEvent)
-func _on_area_entered(_area: Area2D) -> void:
- hover_enter.emit()
-
-
-func _on_area_exited(_area: Area2D) -> void:
- hover_exit.emit()
+#func _on_area_entered(_area: Area2D) -> void:
+ #hover_enter.emit()
+#
+#
+#func _on_area_exited(_area: Area2D) -> void:
+ #hover_exit.emit()
func _on_mouse_entered() -> void:
diff --git a/Game/Selection/selection_rectangle.gd b/Game/Selection/selection_rectangle.gd
index a57f25b..5e7d1c1 100644
--- a/Game/Selection/selection_rectangle.gd
+++ b/Game/Selection/selection_rectangle.gd
@@ -14,7 +14,9 @@ var size: Vector2 = Vector2.ZERO :
var is_active: bool :
get():
- return abs(size) > Vector2(1, 1)
+ return abs(size) > Vector2(1, 1) and Client.state is StateDefault
+
+@onready var camera: Camera2D = get_tree().get_first_node_in_group("camera")
func _process(_delta: float) -> void:
@@ -30,7 +32,8 @@ func _process(_delta: float) -> void:
if is_active and Input.is_action_just_released("select"):
for area in get_overlapping_areas():
if "is_selected" in area.get_parent():
- area.get_parent().is_selected = true
+ if area.get_parent().owner_id == multiplayer.get_unique_id():
+ area.get_parent().is_selected = true
size = Vector2.ZERO
queue_redraw()
@@ -40,12 +43,14 @@ func _draw():
if is_active:
var rect = Rect2(Vector2.ZERO, size)
draw_rect(rect, color_background)
- draw_rect(rect, color_border, false, 2.0)
+ draw_rect(rect, color_border, false, 1.25 / max(camera.zoom.x, camera.zoom.y))
func _on_area_entered(area: Area2D) -> void:
- area.get_parent().is_hovered = true
+ if area.get_parent().owner_id == multiplayer.get_unique_id():
+ area.get_parent().is_hovered = true
func _on_area_exited(area: Area2D) -> void:
- area.get_parent().is_hovered = false
+ if area.get_parent().owner_id == multiplayer.get_unique_id():
+ area.get_parent().is_hovered = false
diff --git a/Game/States/Build/BuilderElement.gd b/Game/States/Build/BuilderElement.gd
index bb10b06..c698f07 100644
--- a/Game/States/Build/BuilderElement.gd
+++ b/Game/States/Build/BuilderElement.gd
@@ -2,7 +2,8 @@ class_name BuilderElement
extends Node2D
-@export var element: Node2D
+@export var element: Resource
+var instance: Tower
var collision_shape: Shape2D
@@ -12,14 +13,16 @@ var collision_areas: Array[Area2D] = []
func _ready():
- var element_sprite: Sprite2D = element.get_node("Sprite2D")
+ instance = element.instantiate()
+
+ var element_sprite: Sprite2D = instance.get_node("Sprite2D")
$Sprite2D.texture = element_sprite.texture
$Sprite2D.region_enabled = element_sprite.region_enabled
$Sprite2D.region_rect = element_sprite.region_rect
$Sprite2D.scale = element_sprite.scale
$Sprite2D.position = element_sprite.position
- var element_collision_shape = element.get_node("CollisionShape2D").duplicate() as CollisionShape2D
+ var element_collision_shape = instance.get_node("CollisionShape2D").duplicate() as CollisionShape2D
collision_shape = element_collision_shape.shape
var tile_size = Client.stage.map.tile_set.tile_size
@@ -54,7 +57,7 @@ func _ready():
func _draw():
draw_circle(
Client.stage.map.tile_set.tile_size,
- 8 + element.attack_range,
+ 8 + instance.attack_range,
Color(1, 1, 1, 0.75),
false,
1.0
diff --git a/Game/States/Build/StateBuild.gd b/Game/States/Build/StateBuild.gd
index d2fb39d..f16ee3d 100644
--- a/Game/States/Build/StateBuild.gd
+++ b/Game/States/Build/StateBuild.gd
@@ -17,14 +17,14 @@ func _state_input(event: InputEvent):
if event.is_action_pressed("builder_tower_select"):
if current_builder_element and current_builder_element.can_build():
- var placed_tower = current_builder_element.element.duplicate() as Tower
- Client.place_tower(placed_tower, current_builder_element.global_position)
+ var placed_tower = current_builder_element.element.instantiate() as Tower
+ placed_tower.attack_range = [
+ Client.stage.map.tile_set.tile_size.x * 2,
+ Client.stage.map.tile_set.tile_size.x * 3,
+ Client.stage.map.tile_set.tile_size.x * 4,
+ ].pick_random()
- placed_tower.selected.connect(func():
- Client.stage.hud.tower.text = "Range: %s - Power: %s - Speed: %s" % [
- placed_tower.attack_range, placed_tower.attack_power, placed_tower.attack_speed
- ]
- )
+ Client.place_tower(placed_tower, current_builder_element.global_position)
if not Input.is_action_pressed("builder_tower_place_keep"):
current_builder_element.queue_free()
@@ -38,3 +38,11 @@ func _state_input(event: InputEvent):
current_builder_element = null
set_state("StateDefault")
+
+ if event.is_action_pressed("builder_cancel") and current_builder_element:
+ current_builder_element.queue_free()
+ current_builder_element = null
+
+
+func _state_unhandled_input(_event: InputEvent) -> void:
+ pass
diff --git a/Game/States/Default/StateDefault.gd b/Game/States/Default/StateDefault.gd
index 1d2dd9f..b7b630c 100644
--- a/Game/States/Default/StateDefault.gd
+++ b/Game/States/Default/StateDefault.gd
@@ -6,6 +6,12 @@ func _state_input(event: InputEvent) -> void:
if event.is_action_pressed("build_mode_start"):
set_state("StateBuild")
+ if event.is_action_pressed("select"):
+ if Unit.selected_unit:
+ Unit.selected_unit.is_selected = false
+
+
+func _state_unhandled_input(event: InputEvent) -> void:
# deselect
if event.is_action_pressed("select"):
# if not multi selecting
@@ -13,7 +19,3 @@ func _state_input(event: InputEvent) -> void:
if Tower.selected_towers:
for tower in Tower.selected_towers.duplicate():
tower.is_selected = false
-
- if event.is_action_pressed("select"):
- if Unit.selected_unit:
- Unit.selected_unit.is_selected = false
diff --git a/Game/States/StateManager.gd b/Game/States/StateManager.gd
index e62cdb4..5a176e2 100644
--- a/Game/States/StateManager.gd
+++ b/Game/States/StateManager.gd
@@ -10,6 +10,10 @@ func _input(event: InputEvent) -> void:
Client.state._state_input(event)
+func _unhandled_input(event: InputEvent) -> void:
+ Client.state._state_unhandled_input(event)
+
+
func set_state(state: Variant):
if state is not State:
state = get_node(state)
diff --git a/Stages/Stage.gd b/Stages/Stage.gd
index 963ee46..1f73a09 100644
--- a/Stages/Stage.gd
+++ b/Stages/Stage.gd
@@ -25,10 +25,10 @@ func _ready() -> void:
path_grid.diagonal_mode = AStarGrid2D.DIAGONAL_MODE_AT_LEAST_ONE_WALKABLE
path_grid.update()
- #towers = get_node("%Towers") # y-sort?
- towers = self
- #units = get_node("%Units") # y-sort?
- units = self
+ towers = get_node("%Towers") # y-sort?
+ #towers = self
+ units = get_node("%Units") # y-sort?
+ #units = self
spawn = get_node("%Spawn")
hud = get_node("%HUD")
@@ -39,10 +39,11 @@ func _ready() -> void:
func place_tower(tower: Tower, position: Vector2):
var player: Player = Network.players[tower.owner_id]
tower.get_node("Sprite2D").modulate = player.get_color()
+ tower.get_node("ComponentsAnchor").modulate = player.get_color()
tower.global_position = position
fill_tower_region(tower, true)
- towers.add_child(tower)
+ towers.add_child(tower, true)
func destroy_tower(tower: Tower):
@@ -73,8 +74,8 @@ func fill_tower_region(tower: Tower, solid = true):
@warning_ignore("shadowed_variable")
-func spawn_unit(unit: Unit, _spawn: Spawn):
+func spawn_unit(unit: Unit):#, _spawn: Spawn):
var player: Player = Network.players[unit.owner_id]
unit.get_node("Sprite2D").modulate = player.get_color()
- units.add_child(unit)
+ units.add_child(unit, true)
diff --git a/Towers/Assets/attack-component.png b/Towers/Components/Assets/attack-component.png
index bb9250c..bb9250c 100644
--- a/Towers/Assets/attack-component.png
+++ b/Towers/Components/Assets/attack-component.png
Binary files differ
diff --git a/Towers/Assets/attack-component.png.import b/Towers/Components/Assets/attack-component.png.import
index ef9a73b..4000c58 100644
--- a/Towers/Assets/attack-component.png.import
+++ b/Towers/Components/Assets/attack-component.png.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://gbknvb38euuq"
-path="res://.godot/imported/attack-component.png-648f34932bc6754ec1b1094b76b170bc.ctex"
+path="res://.godot/imported/attack-component.png-64ebd1f55ef8067c9f5d485d7df578be.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://Towers/Assets/attack-component.png"
-dest_files=["res://.godot/imported/attack-component.png-648f34932bc6754ec1b1094b76b170bc.ctex"]
+source_file="res://Towers/Components/Assets/attack-component.png"
+dest_files=["res://.godot/imported/attack-component.png-64ebd1f55ef8067c9f5d485d7df578be.ctex"]
[params]
diff --git a/Towers/Assets/attack-component.png~ b/Towers/Components/Assets/attack-component.png~
index e2f80bc..e2f80bc 100644
--- a/Towers/Assets/attack-component.png~
+++ b/Towers/Components/Assets/attack-component.png~
Binary files differ
diff --git a/Towers/Assets/burn-component.png b/Towers/Components/Assets/burn-component.png
index 33f9f7e..33f9f7e 100644
--- a/Towers/Assets/burn-component.png
+++ b/Towers/Components/Assets/burn-component.png
Binary files differ
diff --git a/Towers/Assets/burn-component.png.import b/Towers/Components/Assets/burn-component.png.import
index 0783a55..433699a 100644
--- a/Towers/Assets/burn-component.png.import
+++ b/Towers/Components/Assets/burn-component.png.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://2djpswd6sgng"
-path="res://.godot/imported/burn-component.png-c625b666f5c33be88ffb5514acf984cb.ctex"
+path="res://.godot/imported/burn-component.png-de3b76cc035d6d043dda7fb037e0c7e4.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://Towers/Assets/burn-component.png"
-dest_files=["res://.godot/imported/burn-component.png-c625b666f5c33be88ffb5514acf984cb.ctex"]
+source_file="res://Towers/Components/Assets/burn-component.png"
+dest_files=["res://.godot/imported/burn-component.png-de3b76cc035d6d043dda7fb037e0c7e4.ctex"]
[params]
diff --git a/Towers/Assets/burn-component.png~ b/Towers/Components/Assets/burn-component.png~
index c9c1619..c9c1619 100644
--- a/Towers/Assets/burn-component.png~
+++ b/Towers/Components/Assets/burn-component.png~
Binary files differ
diff --git a/Towers/Assets/frost-component.png b/Towers/Components/Assets/frost-component.png
index e1c12f7..e1c12f7 100644
--- a/Towers/Assets/frost-component.png
+++ b/Towers/Components/Assets/frost-component.png
Binary files differ
diff --git a/Towers/Assets/frost-component.png.import b/Towers/Components/Assets/frost-component.png.import
index d22126b..9ebc0d6 100644
--- a/Towers/Assets/frost-component.png.import
+++ b/Towers/Components/Assets/frost-component.png.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://ba3dmlce1wv2p"
-path="res://.godot/imported/frost-component.png-e1bd3aee287cb92be940679bf3553e5f.ctex"
+path="res://.godot/imported/frost-component.png-09974dabb6d634a6ff1c953d1b9c629b.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://Towers/Assets/frost-component.png"
-dest_files=["res://.godot/imported/frost-component.png-e1bd3aee287cb92be940679bf3553e5f.ctex"]
+source_file="res://Towers/Components/Assets/frost-component.png"
+dest_files=["res://.godot/imported/frost-component.png-09974dabb6d634a6ff1c953d1b9c629b.ctex"]
[params]
diff --git a/Towers/Assets/range-component.png b/Towers/Components/Assets/range-component.png
index e5ef51e..e5ef51e 100644
--- a/Towers/Assets/range-component.png
+++ b/Towers/Components/Assets/range-component.png
Binary files differ
diff --git a/Towers/Assets/range-component.png.import b/Towers/Components/Assets/range-component.png.import
index c626726..9500e69 100644
--- a/Towers/Assets/range-component.png.import
+++ b/Towers/Components/Assets/range-component.png.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dx07y4scyi5a1"
-path="res://.godot/imported/range-component.png-5b23d157d3796cb80d7b2edb7addabe5.ctex"
+path="res://.godot/imported/range-component.png-e61b3503df71027fb6ac2a7fbd9e5943.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://Towers/Assets/range-component.png"
-dest_files=["res://.godot/imported/range-component.png-5b23d157d3796cb80d7b2edb7addabe5.ctex"]
+source_file="res://Towers/Components/Assets/range-component.png"
+dest_files=["res://.godot/imported/range-component.png-e61b3503df71027fb6ac2a7fbd9e5943.ctex"]
[params]
diff --git a/Towers/Assets/range-component.png~ b/Towers/Components/Assets/range-component.png~
index e1c12f7..e1c12f7 100644
--- a/Towers/Assets/range-component.png~
+++ b/Towers/Components/Assets/range-component.png~
Binary files differ
diff --git a/Towers/Components/BurnComponent.gd b/Towers/Components/BurnComponent.gd
new file mode 100644
index 0000000..11e9e3f
--- /dev/null
+++ b/Towers/Components/BurnComponent.gd
@@ -0,0 +1,11 @@
+extends TowerComponent
+
+
+func _init() -> void:
+ name = "Burn"
+ set_sprite(preload("res://Towers/Components/Assets/burn-component.png"))
+
+
+func on_shoot(target: Unit):
+ var effect = preload("res://Effects/BurnEffect.tscn").instantiate()
+ target.add_effect(effect)
diff --git a/Towers/Components/FrostComponent.gd b/Towers/Components/FrostComponent.gd
new file mode 100644
index 0000000..d6384a7
--- /dev/null
+++ b/Towers/Components/FrostComponent.gd
@@ -0,0 +1,11 @@
+extends TowerComponent
+
+
+func _init() -> void:
+ name = "Frost"
+ set_sprite(preload("res://Towers/Components/Assets/frost-component.png"))
+
+
+func on_shoot(target: Unit):
+ var effect = preload("res://Effects/SlowEffect.tscn").instantiate()
+ target.add_effect(effect)
diff --git a/Towers/Components/TowerComponent.gd b/Towers/Components/TowerComponent.gd
new file mode 100644
index 0000000..570b442
--- /dev/null
+++ b/Towers/Components/TowerComponent.gd
@@ -0,0 +1,15 @@
+class_name TowerComponent
+extends Resource
+
+
+var name: String
+var sprite: Sprite2D = Sprite2D.new()
+
+
+func set_sprite(texture: Texture2D):
+ sprite.texture = texture
+
+ sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
+ sprite.centered = false
+ sprite.scale = Vector2(2, 2)
+ sprite.name = name
diff --git a/Towers/Tower.gd b/Towers/Tower.gd
index 54687fd..4262af1 100644
--- a/Towers/Tower.gd
+++ b/Towers/Tower.gd
@@ -6,6 +6,7 @@ signal selected
signal deselected
static var selected_towers: Array[Tower]
+static var hovered_tower: Tower
var is_selected = false :
set(value):
@@ -16,12 +17,19 @@ var is_selected = false :
else:
Tower.selected_towers.erase(self)
deselected.emit()
- Client.stage.hud.tower.text = ""
is_selected = value
queue_redraw()
+ toggle_ui()
var is_hovered = false :
set(value):
+ if value:
+ hovered_tower = self
+ Input.set_default_cursor_shape(Input.CURSOR_POINTING_HAND)
+ else:
+ if hovered_tower == self:
+ hovered_tower = null
+ Input.set_default_cursor_shape(Input.CURSOR_ARROW)
is_hovered = value
queue_redraw()
@@ -30,16 +38,26 @@ var mobs_in_range: Array = []
#var selection_area: Area2D
# rpc owner id
-var owner_id = 1
+@export var owner_id = 1
@export var attack_range: int = 32
@export var attack_power: int = 1
@export var attack_speed: int = 1
+@export var components: Array[TowerComponent] = []
+
func _ready():
$Range/CollisionShape2D.shape.radius = attack_range
$ShootCooldown.wait_time = attack_speed
+
+ toggle_ui()
+
+ #for component in [
+ #preload("res://Towers/Components/FrostComponent.gd").new(),
+ #preload("res://Towers/Components/BurnComponent.gd").new(),
+ #]:
+ #add_component(component)
func _draw():
@@ -122,26 +140,50 @@ func _on_selectable_area_select(event: InputEvent) -> void:
+func add_component(component: TowerComponent):
+ components.append(component)
+ var sprite = component.sprite
+ $ComponentsAnchor.add_child(sprite)
+ redraw_components()
+
+func remove_component(component_name: String):
+ for component in components:
+ if component.name == component_name:
+ components.erase(component)
+ $ComponentsAnchor.remove_child($ComponentsAnchor.get_node(NodePath(component.name)))
+ break
+ redraw_components()
+
+func redraw_components():
+ for idx in range(components.size()):
+ var component = components[idx]
+ var sprite = $ComponentsAnchor.get_node(NodePath(component.name))
+ sprite.position.y = (idx + 1) * -16
+
+
func is_melee_range():
return attack_range <= (Client.stage.map.tile_set.tile_size.x * 2)
func shoot():
- if get_multiplayer_authority() != multiplayer.get_unique_id():
+ if not multiplayer.is_server():
# TODO: do shoot animation, but don't subtract hp
return
var target = mobs_in_range[0] as Unit
+ for component in components:
+ if component.has_method("on_shoot"):
+ component.on_shoot(target)
+
if is_melee_range():
target.set_hp(target.hp - 1)
else: # TODO
target.set_hp(target.hp - 1)
-func show_ui():
- # todo: show ui
- pass
+func toggle_ui():
+ $HUD.visible = is_selected
func get_region():
@@ -163,4 +205,70 @@ func get_rpc_properties() -> Dictionary:
"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()
+
+ for tower in selected_towers:
+ var found = false
+ for idx in range(tower.components.size()):
+ var component = tower.components[idx]
+ if component.name == "Frost":
+ found = true
+ tower.remove_component(component.name)
+ break
+
+ if not found:
+ tower.add_component(preload("res://Towers/Components/FrostComponent.gd").new())
+
+ var data = {"components": []}
+ for c in tower.components:
+ data["components"].append(c.name)
+ Client.update_tower(tower, data)
+
+
+func _on_h_box_container_2_gui_input(event: InputEvent) -> void:
+ if event.is_action_pressed("select"):
+ get_viewport().set_input_as_handled()
+
+ for tower in selected_towers:
+ var found = false
+ for idx in range(tower.components.size()):
+ var component = tower.components[idx]
+ if component.name == "Burn":
+ found = true
+ tower.remove_component(component.name)
+ break
+
+ if not found:
+ tower.add_component(preload("res://Towers/Components/BurnComponent.gd").new())
+
+ var data = {"components": []}
+ for c in tower.components:
+ data["components"].append(c.name)
+ Client.update_tower(tower, data)
+
+
+class NetworkData extends Resource:
+ var name: String
+ var position: Vector2
+
+func to_network_data() -> NetworkData:
+ var data = NetworkData.new()
+
+ data.name = name
+ data.position = global_position
+
+ return data
+
+static func from_network_data(data: NetworkData) -> Tower:
+ var tower: Tower = preload("res://Towers/Tower.tscn").instantiate()
+
+ tower.name = data.name
+ tower.global_position = data.position
+
+ return tower
diff --git a/Towers/Tower.tscn b/Towers/Tower.tscn
index 4177a3a..6bff2e3 100644
--- a/Towers/Tower.tscn
+++ b/Towers/Tower.tscn
@@ -1,8 +1,10 @@
-[gd_scene load_steps=7 format=3 uid="uid://by1x56w21o165"]
+[gd_scene load_steps=10 format=3 uid="uid://by1x56w21o165"]
[ext_resource type="Script" path="res://Towers/Tower.gd" id="1_axo1d"]
[ext_resource type="Texture2D" uid="uid://b1b18rd0tqbar" path="res://core_outdoor.png" id="1_mrep8"]
[ext_resource type="PackedScene" uid="uid://cqktpc8c7ecn3" path="res://Game/Selection/SelectableArea.tscn" id="3_57d5u"]
+[ext_resource type="Texture2D" uid="uid://ba3dmlce1wv2p" path="res://Towers/Components/Assets/frost-component.png" id="4_ccrqc"]
+[ext_resource type="Texture2D" uid="uid://2djpswd6sgng" path="res://Towers/Components/Assets/burn-component.png" id="5_y7tf5"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_atm5x"]
size = Vector2(31, 31)
@@ -12,6 +14,23 @@ size = Vector2(31, 31)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_312i7"]
size = Vector2(32, 32)
+[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_spp26"]
+properties/0/path = NodePath(".:position")
+properties/0/spawn = true
+properties/0/replication_mode = 0
+properties/1/path = NodePath(".:owner_id")
+properties/1/spawn = true
+properties/1/replication_mode = 0
+properties/2/path = NodePath(".:attack_range")
+properties/2/spawn = true
+properties/2/replication_mode = 2
+properties/3/path = NodePath("Sprite2D:modulate")
+properties/3/spawn = true
+properties/3/replication_mode = 0
+properties/4/path = NodePath("ComponentsAnchor:modulate")
+properties/4/spawn = true
+properties/4/replication_mode = 0
+
[node name="Tower" type="StaticBody2D"]
y_sort_enabled = true
collision_layer = 4
@@ -48,6 +67,53 @@ one_shot = true
position = Vector2(16, 16)
shape = SubResource("RectangleShape2D_312i7")
+[node name="ComponentsAnchor" type="Marker2D" parent="."]
+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
+grow_horizontal = 2
+grow_vertical = 0
+
+[node name="VBoxContainer" type="VBoxContainer" parent="HUD/CenterContainer"]
+layout_mode = 2
+
+[node name="HBoxContainer" type="HBoxContainer" parent="HUD/CenterContainer/VBoxContainer"]
+layout_mode = 2
+mouse_default_cursor_shape = 2
+
+[node name="TextureRect" type="TextureRect" parent="HUD/CenterContainer/VBoxContainer/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"]
+layout_mode = 2
+text = "Frost"
+
+[node name="HBoxContainer2" type="HBoxContainer" parent="HUD/CenterContainer/VBoxContainer"]
+layout_mode = 2
+mouse_default_cursor_shape = 2
+
+[node name="TextureRect" type="TextureRect" parent="HUD/CenterContainer/VBoxContainer/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"]
+layout_mode = 2
+text = "Burn"
+
+[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
+replication_config = SubResource("SceneReplicationConfig_spp26")
+
[connection signal="input_event" from="." to="." method="_on_input_event"]
[connection signal="mouse_entered" from="." to="." method="_on_mouse_entered"]
[connection signal="mouse_exited" from="." to="." method="_on_mouse_exited"]
@@ -57,3 +123,5 @@ shape = SubResource("RectangleShape2D_312i7")
[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"]
diff --git a/UI/Camera.tscn b/UI/Camera.tscn
index 7080711..869cd53 100644
--- a/UI/Camera.tscn
+++ b/UI/Camera.tscn
@@ -2,6 +2,6 @@
[ext_resource type="Script" path="res://UI/Camera.gd" id="1_yiia3"]
-[node name="Camera" type="Camera2D"]
+[node name="Camera" type="Camera2D" groups=["camera"]]
anchor_mode = 0
script = ExtResource("1_yiia3")
diff --git a/UI/HUD.tscn b/UI/HUD.tscn
index b4756cd..f968c16 100644
--- a/UI/HUD.tscn
+++ b/UI/HUD.tscn
@@ -139,18 +139,6 @@ text = "0"
custom_minimum_size = Vector2(0, 1)
layout_mode = 2
-[node name="CenterContainer" type="CenterContainer" parent="."]
-anchors_preset = 12
-anchor_top = 1.0
-anchor_right = 1.0
-anchor_bottom = 1.0
-grow_horizontal = 2
-grow_vertical = 0
-
-[node name="Tower" type="Label" parent="CenterContainer"]
-unique_name_in_owner = true
-layout_mode = 2
-
[node name="SpawnBox" type="PanelContainer" parent="."]
unique_name_in_owner = true
anchors_preset = 3
@@ -260,12 +248,25 @@ unique_name_in_owner = true
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
-offset_left = -144.0
-offset_top = 42.0
-offset_right = -5.0
-offset_bottom = 85.0
+offset_left = -204.0
+offset_top = 41.0
+offset_right = -4.0
+offset_bottom = 84.0
grow_horizontal = 0
+[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
diff --git a/UI/Lobby.gd b/UI/Lobby.gd
index 4fea0bc..68d843c 100644
--- a/UI/Lobby.gd
+++ b/UI/Lobby.gd
@@ -1,6 +1,13 @@
extends Control
+func _ready():
+ if OS.has_environment("USER"):
+ %Name.text = OS.get_environment("USER")
+ elif OS.has_environment("USERNAME"):
+ %Name.text = OS.get_environment("USERNAME")
+
+
func get_ip():
var ip := "127.0.0.1"
if %IP.text:
@@ -17,10 +24,12 @@ func get_port():
return port
func _on_host_pressed() -> void:
+ Client.player.name = %Name.text
Network.host_game(get_port())
get_tree().change_scene_to_file("res://Stages/world.tscn")
func _on_join_pressed() -> void:
+ Client.player.name = %Name.text
Network.join_game(get_ip(), get_port())
get_tree().change_scene_to_file("res://Stages/world.tscn")
diff --git a/UI/Lobby.tscn b/UI/Lobby.tscn
index f3775d8..4060f88 100644
--- a/UI/Lobby.tscn
+++ b/UI/Lobby.tscn
@@ -22,6 +22,12 @@ grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
layout_mode = 2
+[node name="Name" type="TextEdit" parent="CenterContainer/VBoxContainer"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(0, 50)
+layout_mode = 2
+placeholder_text = "Name"
+
[node name="Host" type="Button" parent="CenterContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
diff --git a/UI/PlayersList.tscn b/UI/PlayersList.tscn
index b1106b5..12bdf37 100644
--- a/UI/PlayersList.tscn
+++ b/UI/PlayersList.tscn
@@ -4,8 +4,8 @@
[ext_resource type="PackedScene" uid="uid://wxe1hpn013y8" path="res://UI/PlayersListItem.tscn" id="2_ug8m7"]
[node name="PlayersList" type="PanelContainer"]
-offset_right = 40.0
-offset_bottom = 40.0
+offset_right = 96.0
+offset_bottom = 43.0
script = ExtResource("1_67rpy")
[node name="MarginContainer" type="MarginContainer" parent="."]
diff --git a/UI/PlayersListItem.tscn b/UI/PlayersListItem.tscn
index 8349b05..53b98f9 100644
--- a/UI/PlayersListItem.tscn
+++ b/UI/PlayersListItem.tscn
@@ -13,13 +13,12 @@ layout_mode = 2
[node name="ID" type="Label" parent="HBoxContainer"]
unique_name_in_owner = true
-custom_minimum_size = Vector2(10, 0)
layout_mode = 2
size_flags_horizontal = 3
text = "1"
horizontal_alignment = 1
clip_text = true
-text_overrun_behavior = 1
+text_overrun_behavior = 3
[node name="VSeparator" type="VSeparator" parent="HBoxContainer"]
visible = false
diff --git a/UI/players_list.gd b/UI/players_list.gd
index c1ca00f..04bfe6b 100644
--- a/UI/players_list.gd
+++ b/UI/players_list.gd
@@ -24,7 +24,7 @@ func update_players():
control.get_node("%Indicator").visible = id == multiplayer.get_unique_id()
list.add_child(control)
- control.get_node("%ID").text = str(id)
+ control.get_node("%ID").text = str(player.name)
control.get_node("%Score").text = str(player.score)
list.move_child(control, Network.get_ordered_player_ids().find(id) + 1)
diff --git a/UI/tower_configuration.gd b/UI/tower_configuration.gd
index 9eb12cd..7031de5 100644
--- a/UI/tower_configuration.gd
+++ b/UI/tower_configuration.gd
@@ -23,13 +23,6 @@ func _on_texture_rect_gui_input(event: InputEvent) -> void:
var builder_element_scene = preload("res://Game/States/Build/BuilderElement.tscn")
var builder_element = builder_element_scene.instantiate()
- var tower = preload("res://Towers/Tower.tscn").instantiate() as Tower
- tower.attack_range = [
- Client.stage.map.tile_set.tile_size.x * 2,
- Client.stage.map.tile_set.tile_size.x * 3,
- Client.stage.map.tile_set.tile_size.x * 4,
- ].pick_random()
-
- builder_element.element = tower
+ builder_element.element = preload("res://Towers/Tower.tscn")
get_tree().current_scene.add_child(builder_element)
state.current_builder_element = builder_element
diff --git a/Units/Unit.gd b/Units/Unit.gd
index 8373a59..3b91d73 100644
--- a/Units/Unit.gd
+++ b/Units/Unit.gd
@@ -31,7 +31,7 @@ var is_hovered = false :
is_hovered = value
queue_redraw()
-var target: Node2D :
+var target: Vector2 :
set(value):
target = value
reset_path()
@@ -52,7 +52,7 @@ var stuck_position_accumulator = 0.0
var roaming_mode = false
# rpc owner id
-var owner_id = 1
+@export var owner_id = 1
@export var base_speed: float = 100
@export var speed: float = base_speed
@@ -61,12 +61,12 @@ var owner_id = 1
@onready var line: Line2D = $UnitPathLine.duplicate()
-@onready var sprite = $Sprite2D
+@onready var sprite: Sprite2D = $Sprite2D
func _ready():
if not target:
- target = Client.stage.get_node("%Goal")
+ target = Client.stage.get_node("%Goal").path_position
Client.stage.units.add_child(line)
@@ -91,10 +91,10 @@ func _ready():
func _physics_process(delta):
- if get_multiplayer_authority() != multiplayer.get_unique_id():
- Network.update_unit.rpc(get_path(), {
- "hp": hp,
- })
+ if not multiplayer.is_server():
+ #Network.update_unit.rpc(get_path(), {
+ #"hp": hp,
+ #})
return
previous_position = global_position
@@ -122,11 +122,13 @@ func _physics_process(delta):
else:
stuck_position_accumulator = 0
- Network.update_unit.rpc(get_path(), {
- "position": global_position,
- "hp": hp,
- "sprite": {"self_modulate": $Sprite2D.self_modulate}
- })
+ #Network.update_unit.rpc(get_path(), {
+ #"position": global_position,
+ #"hp": hp,
+ #"sprite": {"self_modulate": $Sprite2D.self_modulate},
+ #"current_path_idx": current_path_idx,
+ #"current_path": current_path,
+ #})
func _draw():
@@ -153,7 +155,7 @@ func _draw():
func _on_navigation_base_area_entered(area: Area2D):
- if get_multiplayer_authority() != multiplayer.get_unique_id():
+ if not multiplayer.is_server():
return
if area.is_in_group("goal"):
@@ -161,9 +163,9 @@ func _on_navigation_base_area_entered(area: Area2D):
Client.update_player()
queue_free()
if area.is_in_group("path"):
- var path_node = area.get_parent()
- if path_node.path_position == target.path_position:
- target = path_node.next_node
+ var path_node: PathNode = area.get_parent()
+ if path_node.path_position == target:
+ target = path_node.next_node.path_position
func walk_along_path(path: PackedVector2Array, index: int, delta: float):
@@ -206,6 +208,13 @@ func get_effects():
return effects
+func add_effect(effect: Effect):
+ var node = get_node_or_null(NodePath(effect.name)) as Effect
+ if node:
+ node.set_duration(node.duration)
+ else:
+ add_child(effect)
+
func reset_path():
roaming_mode = false
@@ -221,12 +230,12 @@ func reset_path():
# reached end of partial path
if current_path.size() == 1 and current_path[0] == global_position:
roaming_mode = true
- current_path = PackedVector2Array([target.path_position + Vector2(16,16)])
+ current_path = PackedVector2Array([target + Vector2(16,16)])
# iterating between one or more closest paths
elif recent_closest_paths.count(current_path) >= 2:
roaming_mode = true
- current_path = PackedVector2Array([target.path_position + Vector2(16,16)])
+ current_path = PackedVector2Array([target + Vector2(16,16)])
recent_closest_paths = []
else:
recent_closest_paths = []
@@ -241,7 +250,7 @@ func reset_path():
func get_grid_path(partial = false):
return Client.stage.path_grid.get_point_path(
Client.stage.map.local_to_map(global_position),
- Client.stage.map.local_to_map(target.path_position),
+ Client.stage.map.local_to_map(target),
partial
)
@@ -257,7 +266,6 @@ func _on_selection_area_input_event(_viewport: Node, event: InputEvent, _shape_i
selected_unit.is_selected = false
is_selected = true
$Label.text = str(hp)
- add_child(preload("res://Effects/SlowEffect.tscn").instantiate())
func _on_selection_area_mouse_entered() -> void:
@@ -277,13 +285,46 @@ func _on_tree_exiting() -> void:
func get_rpc_properties():
return {
- "name": null,
- "global_position": null,
- "target": "res://Stages/Paths/PathNode.tscn",
- "hp": null,
- "speed": null,
- "current_path": null,
- "current_path_idx": null,
- "sprite": "node://Sprite2D",
- "owner_id": null,
+ #"name": null,
+ #"global_position": null,
+ #"target": "res://Stages/Paths/PathNode.tscn",
+ #"hp": null,
+ #"speed": null,
+ #"current_path": null,
+ #"current_path_idx": null,
+ #"sprite": "node://Sprite2D",
+ #"owner_id": null,
}
+
+
+class NetworkData extends Resource:
+ var name: String
+ var position: Vector2
+ var target_position: Vector2
+ var hp: int
+ var speed: float
+ var texture_path: String
+
+func to_network_data() -> NetworkData:
+ var data = NetworkData.new()
+
+ data.name = name
+ data.position = global_position
+ data.target_position = target
+ data.hp = hp
+ data.speed = speed
+ data.texture_path = get_node("Sprite2D").texture.resource_path
+
+ return data
+
+static func from_network_data(data: NetworkData) -> Unit:
+ var unit: Unit = preload("res://Units/Unit.tscn").instantiate()
+
+ unit.name = data.name
+ unit.global_position = data.position
+ unit.target = data.target_position
+ unit.hp = data.hp
+ unit.speed = data.speed
+ unit.get_node("Sprite2D").texture = load(data.texture_path)
+
+ return unit
diff --git a/Units/Unit.tscn b/Units/Unit.tscn
index 879df08..7e6acbc 100644
--- a/Units/Unit.tscn
+++ b/Units/Unit.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=8 format=3 uid="uid://cslaufgh6ber3"]
+[gd_scene load_steps=9 format=3 uid="uid://cslaufgh6ber3"]
[ext_resource type="Script" path="res://Units/Unit.gd" id="1_bbcew"]
[ext_resource type="Texture2D" uid="uid://dsy7k2v5fhh6v" path="res://Assets/Mobs/angesnow-front.png" id="2_rxqq1"]
@@ -14,6 +14,23 @@ size = Vector2(8, 8)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_o5ax3"]
size = Vector2(16, 16)
+[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_0buot"]
+properties/0/path = NodePath(".:position")
+properties/0/spawn = true
+properties/0/replication_mode = 2
+properties/1/path = NodePath(".:hp")
+properties/1/spawn = true
+properties/1/replication_mode = 2
+properties/2/path = NodePath("Sprite2D:self_modulate")
+properties/2/spawn = true
+properties/2/replication_mode = 2
+properties/3/path = NodePath(".:owner_id")
+properties/3/spawn = true
+properties/3/replication_mode = 0
+properties/4/path = NodePath("Sprite2D:modulate")
+properties/4/spawn = true
+properties/4/replication_mode = 2
+
[node name="Unit" type="CharacterBody2D"]
y_sort_enabled = true
collision_mask = 4
@@ -65,6 +82,9 @@ width = 1.0
default_color = Color(1, 1, 1, 0.392157)
target_circle_radius = 4.0
+[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
+replication_config = SubResource("SceneReplicationConfig_0buot")
+
[connection signal="tree_exiting" from="." to="." method="_on_tree_exiting"]
[connection signal="area_entered" from="NavigationBase" to="." method="_on_navigation_base_area_entered"]
[connection signal="input_event" from="SelectionArea" to="." method="_on_selection_area_input_event"]
diff --git a/Units/UnitPathLine.tscn b/Units/UnitPathLine.tscn
index 62458c4..c0ac3ab 100644
--- a/Units/UnitPathLine.tscn
+++ b/Units/UnitPathLine.tscn
@@ -1,6 +1,14 @@
-[gd_scene load_steps=2 format=3 uid="uid://cifs0kcy5r0x2"]
+[gd_scene load_steps=3 format=3 uid="uid://cifs0kcy5r0x2"]
[ext_resource type="Script" path="res://Units/unit_path_line.gd" id="1_qbhs7"]
+[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_wfkop"]
+properties/0/path = NodePath(".:points")
+properties/0/spawn = true
+properties/0/replication_mode = 2
+
[node name="UnitPathLine" type="Line2D"]
script = ExtResource("1_qbhs7")
+
+[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
+replication_config = SubResource("SceneReplicationConfig_wfkop")
diff --git a/export_presets.cfg b/export_presets.cfg
index 4654bba..7ce6e7a 100644
--- a/export_presets.cfg
+++ b/export_presets.cfg
@@ -9,7 +9,7 @@ custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
-export_path="../../../../Applications/Godot/TD.exe"
+export_path="../../../../Applications/Godot/Exports/TD.exe"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
@@ -20,7 +20,7 @@ script_export_mode=2
custom_template/debug=""
custom_template/release=""
-debug/export_console_wrapper=1
+debug/export_console_wrapper=0
binary_format/embed_pck=false
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false