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


signal transitioned_to

@export var can_plant_bomb: bool = true


func _ready():
	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:
		exited_area.set_collision_mask_value(Utilities.Collision.Layer.PLAYER, false)
	
	$TileMap.process_mode = PROCESS_MODE_INHERIT
	$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:
		exited_area.get_node("TileMap").process_mode = PROCESS_MODE_DISABLED
		
		# animate sprite
		var sprite: AnimatedSprite2D = player.get_node("AnimatedSprite2D")
		var bounds: Rect2 = Utilities.get_collision_shape_bounds($CollisionShape2D)
		
		var sprite_direction = ""
		if player.global_position.x <= bounds.position.x:
			sprite_direction = "right"
		elif player.global_position.x >= bounds.end.x:
			sprite_direction = "left"
		elif player.global_position.y <= bounds.position.y:
			sprite_direction = "down"
		elif player.global_position.y >= bounds.end.y:
			sprite_direction = "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)
		)
		
		position_tween = get_tree().create_tween()
		position_tween.tween_property(
			player, "global_position", player.global_position + player.DIRECTION * (16 + 8), 1.25
		)
		position_tween.tween_callback(func():
			exited_area.get_node("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
	
	# TODO: handle different child entity groups inside TileMap


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