summaryrefslogtreecommitdiff
path: root/Scenes/Utilities.gd
blob: 092e85351be2b2525467948e97737d0c2f1bd74b (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
extends Node


const TILE_SIZE = 16
const SCREEN_FADE_DURATION = 0.25

static var has_dialog = false


func get_level_position(scene) -> Vector2:
	return self.from_position_to_grid(scene.position)
	#var x = floor(scene.position.x / 16)
	#var y = floor(scene.position.y / 16)
	
	#return Vector2(x, y)


func get_level_position_grid(scene) -> Vector2:
	return self.from_grid_to_position(self.from_position_to_grid(scene.position))
	#return (self.get_level_position(scene) * self.TILE_SIZE) + Vector2(self.TILE_SIZE / 2, self.TILE_SIZE / 2)


func from_position_to_grid(position: Vector2) -> Vector2:
	return floor(position / self.TILE_SIZE)


func from_grid_to_position(grid_position: Vector2) -> Vector2:
	return (grid_position * self.TILE_SIZE) + Vector2(self.TILE_SIZE / 2.0, self.TILE_SIZE / 2.0)


func change_scene(scene):
	get_tree().root.add_child(scene)
	get_tree().current_scene.queue_free()
	get_tree().current_scene = scene


func change_scene_with_fade(scene):
	self.change_scene(scene)
	self.fade_screen(Color(0, 0, 0, 1), Color(0, 0, 0, 0))


func change_scene_with_player_to_position(
	scene: Node2D,
	player: Player,
	targetPlayerPositionNodePath: NodePath,
	facing: String
):
	Global.player = player
	Global.last_area = null
	
	player.get_node("AnimatedSprite2D").play("idle_" + facing)
	
	var targetPlayerPositionNode = scene.get_node(targetPlayerPositionNodePath)
	player.position = targetPlayerPositionNode.position
	scene.add_child(player)
	
	call_deferred("change_scene_with_fade", scene)


func fade_screen(from: Color, to: Color, duration: float = SCREEN_FADE_DURATION) -> Tween:
	var canvas = CanvasLayer.new()
	var rect = ColorRect.new()
	rect.color = from
	rect.size = get_viewport().get_visible_rect().size
	canvas.add_child(rect)
	get_tree().root.add_child(canvas)
	
	Global.player.set_process(false)
	var tween = get_tree().create_tween()
	tween.tween_property(rect, "color", to, duration)
	tween.tween_callback(func():
		get_tree().root.remove_child(canvas)
		Global.player.set_process(true)
	)
	
	return tween


func fade_bg_music(duration: float = SCREEN_FADE_DURATION):
	if get_tree().current_scene.has_node("MusicBackground"):
		var music = get_tree().current_scene.get_node("MusicBackground")
		var tween = get_tree().create_tween()
		tween.tween_property(
			music,
			"volume_db",
			ProjectSettings.get_setting("audio/buses/channel_disable_threshold_db"),
			duration
		)


func dialog(timeline: Variant):
	if not self.has_dialog:
		self.has_dialog = true
		get_tree().paused = true
		Dialogic.start(timeline).process_mode = Node.PROCESS_MODE_ALWAYS
		Dialogic.process_mode = PROCESS_MODE_ALWAYS
		await Dialogic.timeline_ended
		get_tree().paused = false
		await get_tree().create_timer(0.5).timeout
		self.has_dialog = false


func get_enemy_children(parent: Node):
	return parent.get_children().filter(
		func(child: Node2D): return child.is_in_group("enemies")
	)


func get_all_children(parent: Node):
	var children = []
	
	for child in parent.get_children():
		children.append(child)
		children += get_all_children(child)
	
	return children


func get_collision_shape_bounds(collision_shape: CollisionShape2D):
	var shape: Shape2D = collision_shape.shape
	var bounds
	
	if shape is RectangleShape2D:
		bounds = Rect2(
			collision_shape.global_position - shape.get_rect().size/2,
			shape.get_rect().size
		)
	
	return bounds


func add_collision_area(node: Node2D, original_collision_shape: Node2D):
	var collision_area = Collision.Area.new(node, original_collision_shape)
	
	# add area to node
	node.add_child(collision_area)
	
	return collision_area


class Collision:
	class Area extends Area2D:
		signal collided
		
		func _init(node: Node2D, original_collision_shape: Node2D, expand: bool = true):
			self.name = "CollisionArea"
			#super()
			
			# setup area
			self.collision_layer = node.collision_layer
			self.collision_mask = node.collision_mask
			
			for group in node.get_groups():
				self.add_to_group(group)
			
			self.connect("area_entered", func(area): emit_signal("collided", area))
			
			# copy shape and expand it
			var collision_shape = original_collision_shape.duplicate()
			if collision_shape is CollisionShape2D:
				var shape = collision_shape.shape.duplicate()
				
				if expand:
					if shape is RectangleShape2D:
						shape.set_size(shape.get_size() + Vector2(1, 1))
					elif shape is CapsuleShape2D:
						shape.set_height(shape.get_height() + 1)
						shape.set_radius(shape.get_radius() + 1)
					elif shape is CircleShape2D:
						shape.set_radius(shape.get_radius() + 1)
					else:
						print("collision shape type not implemented for " + str(shape))
					
				collision_shape.set_shape(shape)
				
			elif collision_shape is CollisionPolygon2D:
				var polygon = collision_shape.polygon.duplicate()
				
				if expand:
					pass
				
				collision_shape.set_polygon(polygon)
				pass
				
			self.add_child(collision_shape)
	
	
	class Layer:
		const PLAYER = 2
		const BOMB = 3
		const SOLID = 4
		const ENEMY = 5
		const EXPLOSION = 6
	
	
class Condition:
	signal fulfilled
	var function: Callable
	
	func check():
		var is_fulfilled = function.call()
		if is_fulfilled:
			fulfilled.emit()
		
		return is_fulfilled