summaryrefslogtreecommitdiff
path: root/Stages/Stage.gd
blob: 40c805a100ed89859a0ce47c69e1b9eee84fd38f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
class_name Stage
extends Node


signal path_grid_changed

static var maps: Array[Node]
static var map: TileMapLayer
static var path_grid: AStarGrid2D
static var last_solid_set_points: Array[Vector2]

class Settings extends Resource:
	pass
var settings: Resource


func _init() -> void:
	Client.initialize_stage(self)


func _ready() -> void:
	Client.ready_stage(self)
	
	multiplayer.peer_disconnected.connect(_on_peer_disconnected)
	
	maps = find_children("*", "TileMapLayer")
	map = maps[0]
	
	path_grid = AStarGrid2D.new()
	path_grid.region = map.get_used_rect()
	path_grid.cell_size = map.tile_set.tile_size
	path_grid.offset = map.tile_set.tile_size / 2
	path_grid.diagonal_mode = AStarGrid2D.DIAGONAL_MODE_AT_LEAST_ONE_WALKABLE
	path_grid.update()
	
	assert(get_node("%StateManager"), "StateManager missing")
	assert(get_node("%StateManager").get_children().size() > 0, "StateManager has no States")
	
	@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)


## supposed to be overridden
func place_tower(_remote_data: Dictionary) -> void:
	pass

func _place_tower(parent: Node2D, tower: Tower):
	var player: Player = Network.get_player(tower.owner_id)
	tower.get_node("AnimatedSprite2D").modulate = player.get_color()
	tower.get_node("%ComponentsAnchor").modulate = player.get_color()
	
	fill_tower_region(tower, true)
	
	var particles = preload("res://Towers/PlacementParticles.tscn").instantiate()
	particles.global_position = tower.get_node("GroundAnchor").global_position
	particles.play_sound = multiplayer.get_unique_id() == tower.owner_id
	particles.scale = tower.scale
	parent.add_child(particles)
	
	parent.add_child(tower, true)


func destroy_tower(tower: Tower):
	fill_tower_region(tower, false)
	tower.queue_free()


func fill_tower_region(tower: Tower, solid = true):
	var region = tower.get_region().size.snapped(path_grid.cell_size)
	var tower_position = map.local_to_map(tower.global_position)
	
	last_solid_set_points = []
	if solid:
		for x in (region / path_grid.cell_size).x + 1:
			for y in (region / path_grid.cell_size).y + 1:
				last_solid_set_points.append(
					map.map_to_local(tower_position + Vector2i(x, y))
				)
	
	path_grid.fill_solid_region(
		Rect2i(
			map.local_to_map(tower.global_position),
			(region / path_grid.cell_size)
		),
		solid
	)
	path_grid_changed.emit()


## supposed to be overridden
func spawn_unit(_remote_data: Dictionary) -> void:
	pass

func _spawn_unit(parent: Node2D, unit: Unit):
	var player: Player = Network.get_player(unit.owner_id)
	unit.sprite.modulate = player.get_color()
	
	parent.add_child(unit, true)


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
		)
		for property in property_list:
			previous_values[property.name] = player[property.name]
		
		player.set_script(script)
		for property in previous_values:
			player[property] = previous_values[property]


func add_status_message(message: String):
	var label = Label.new()
	label.text = message
	$HUD.get_node("%StatusMessages").add_child(label)
	await get_tree().create_timer(3.0).timeout
	label.queue_free()


## get spawn node
func get_spawn():
	pass

## get target after spawn to overwrite default spawn target
func get_overwrite_target():
	pass


func _on_peer_disconnected(id):
	Network._on_peer_disconnected(id)