summaryrefslogtreecommitdiff
path: root/Scenes/Components/MapArea.gd
blob: c2212733f3e50fa37af98d886b4172c274ef80f3 (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
class_name MapArea
extends Area2D


signal transitioned_to

@export var can_plant_bomb: bool = true
@export_node_path("TileMap") var _tilemap: NodePath

var tilemap: TileMap


func _ready():
	if not _tilemap:
		tilemap = $TileMap
	else:
		tilemap = get_node(_tilemap)
	
	add_area_edges()


func add_area_edges():
	var area_edges = StaticBody2D.new()
	area_edges.set_collision_layer_value(Utilities.Collision.Layer.SOLID, true)
	area_edges.add_collision_exception_with(Global.player)
	
	var bounds = Utilities.get_collision_shape_bounds($CollisionShape2D)
	var edges = [
		{ "a": bounds.position, "b": Vector2(bounds.end.x, bounds.position.y) },
		{ "a": bounds.position, "b": Vector2(bounds.position.x, bounds.end.y) },
		{ "a": bounds.end, "b": Vector2(bounds.end.x, bounds.position.y) },
		{ "a": bounds.end, "b": Vector2(bounds.position.x, bounds.end.y) },
	]
	
	for edge in edges:
		var collision_shape = CollisionShape2D.new()
		var shape = SegmentShape2D.new()
		shape.a = edge.a
		shape.b = edge.b
		collision_shape.shape = shape
		area_edges.add_child(collision_shape)
	
	add_child(area_edges)


func _on_body_entered(body):
	if body is Player:
		self._on_player_entered(body)


func _on_player_entered(player: Player):
	var exited_area = Global.last_area
	
	if Global.last_area == self:
		return
	
	if exited_area:
		player.process_mode = Node.PROCESS_MODE_ALWAYS
		exited_area.set_collision_mask_value(Utilities.Collision.Layer.PLAYER, false)
	else:
		tilemap.process_mode = Node.PROCESS_MODE_INHERIT
	
	self.set_collision_mask_value(Utilities.Collision.Layer.PLAYER, false)
	tilemap.visible = true
	
	self.adjust_camera_to_area(player)
	
	if not player.get_parent() == tilemap:
		(func(): player.reparent(tilemap)).call_deferred()
	
	var position_tween: Tween
	if exited_area:
		tilemap.process_mode = Node.PROCESS_MODE_DISABLED
		exited_area.tilemap.process_mode = Node.PROCESS_MODE_DISABLED
		
		# animate sprite
		var sprite: AnimatedSprite2D = player.get_node("AnimatedSprite2D")
		var bounds: Rect2 = Utilities.get_collision_shape_bounds($CollisionShape2D)
		
		var sprite_direction = ""
		var direction = Vector2.UP
		if player.global_position.x <= bounds.position.x:
			sprite_direction = "right"
			direction = Vector2.RIGHT
		elif player.global_position.x >= bounds.end.x:
			sprite_direction = "left"
			direction = Vector2.LEFT
		elif player.global_position.y <= bounds.position.y:
			sprite_direction = "down"
			direction = Vector2.DOWN
		elif player.global_position.y >= bounds.end.y:
			sprite_direction = "up"
			direction = Vector2.UP
		
		var sprite_tween = get_tree().create_tween().set_loops(5)
		sprite_tween.tween_interval(0.25)
		sprite_tween.tween_callback(func():
			sprite.play(sprite_direction)
		)
		
		player.set_process(false)
		
		position_tween = get_tree().create_tween()
		position_tween.tween_property(
			player, "global_position", player.global_position + direction * (16 + 8), 1.25
		)
		position_tween.tween_callback(func():
			tilemap.process_mode = Node.PROCESS_MODE_INHERIT
			player.process_mode = Node.PROCESS_MODE_INHERIT
			player.set_process(true)
			
			exited_area.tilemap.visible = false
			sprite_tween.kill()
			sprite.play("idle_" + sprite_direction)
			exited_area.set_collision_mask_value(Utilities.Collision.Layer.PLAYER, true)
			
			transitioned_to.emit()
		)
		
	Global.last_area = self


func adjust_camera_to_area(player: Player) -> Camera2D:
	var camera: Camera2D = player.get_node("Camera2D")
	var bounds: Rect2 = Utilities.get_collision_shape_bounds($CollisionShape2D)
	
	var duration = 0
	if Global.last_area:
		duration = 1.25
		
	var tween = get_tree().create_tween().set_parallel().set_ease(Tween.EASE_OUT)

	tween.tween_property(camera, "limit_top", bounds.position.y,  duration)
	tween.tween_property(camera, "limit_right", bounds.end.x,  duration)
	tween.tween_property(camera, "limit_bottom", bounds.end.y, duration)
	tween.tween_property(camera, "limit_left", bounds.position.x,  duration)
	
	return camera