summaryrefslogtreecommitdiff
path: root/Scenes/Builder.gd
blob: 0eebb5a1f3e8f714c796cf598996f2fb1d5cdbdb (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
extends Node

const Obstacle = preload("res://Scenes/Obstacle.tscn")
const PlateBounce = preload("res://Scenes/PlateBounce.tscn")
const PlateDamage = preload("res://Scenes/PlateDamage.tscn")
const PlateKey = preload("res://Scenes/PlateKey.tscn")
const Crystal = preload("res://Scenes/Crystal.tscn")

const room_size = 6

const room_positions = [
	Vector2(-1, -1),
	Vector2( 0, -1),
	Vector2( 0,  0),
	Vector2(-1,  0)
]

const room_counts = [
	1,
	1,
	2,
	2,
	3,
	4
]

const crystal_counts = [
	1,
	2,
	2,
	3,
	4,
	6
]

enum Divider {
	NONE,
	DOOR,
	TRAP
}

const divider_weight = {
	Divider.NONE: 0.5,
	Divider.DOOR: 0.3,
	Divider.TRAP: 0.2
}

func build(player : Entity, dungeon):
	var room_count = room_counts[Global.current_stage]
	var start = randi() % 4

	var divider_count = 0
	var rooms = {}
	for i in range(start, start + room_count):
		rooms[room_positions[i % 4]] = true

	for key in rooms:
		var length = room_size + 1
		var corner = key * length

		for i in range(0, length):
			if not rooms.has(key + Vector2(-1, 0)):
				build_obstacle(corner + Vector2(0, i), dungeon)

			if not rooms.has(key + Vector2(0, -1)):
				build_obstacle(corner + Vector2(i + 1, 0), dungeon)

			if not rooms.has(key + Vector2(+1, 0)):
				build_obstacle(corner + Vector2(length, i + 1), dungeon)

			if not rooms.has(key + Vector2(0, +1)):
				build_obstacle(corner + Vector2(i, length), dungeon)

		if rooms.has(key + Vector2(-1, 0)):
			divider_count = build_divider(corner, Vector2(0, 1), divider_count, dungeon)

		if rooms.has(key + Vector2(0, -1)):
			divider_count = build_divider(corner, Vector2(1, 0), divider_count, dungeon)

	var pos = Vector2(1, 1)

	dungeon.add_child(player)
	dungeon.set_tile(player, pos)

	var number_crystals = floor(Global.current_stage / 2.0) + 1
	for i in range(number_crystals):
		pos = Vector2(randi()%8 - 4, randi()%8 - 4)
		while dungeon.tiles_entities.has(pos):
			pos = Vector2(randi()%8 - 4, randi()%8 - 4)
		var crystal = Crystal.instance()
		dungeon.set_tile(crystal, pos)
		dungeon.add_child(crystal)

		pos = Vector2(randi()%8 - 4, randi()%8 - 4)
		while dungeon.tiles_entities.has(pos) or dungeon.tiles_floor.has(pos):
			pos = Vector2(randi()%8 - 4, randi()%8 - 4)
		var plate_key = PlateKey.instance()
		plate_key.set_crystal(crystal)
		dungeon.tiles_floor[pos] = plate_key
		dungeon.add_child(plate_key)

	for key in dungeon.tiles_entities:
		dungeon.tiles_entities[key].translation = dungeon.tile_to_pos(key)

	for key in dungeon.tiles_floor:
		dungeon.tiles_floor[key].translation = dungeon.tile_to_pos(key)

func build_obstacle(pos : Vector2, dungeon):
	var object = Obstacle.instance()
	dungeon.add_child(object)
	dungeon.set_tile(object, pos)

func build_plate_damage(pos : Vector2, dungeon):
	var object = PlateDamage.instance()
	dungeon.add_child(object)
	dungeon.set_tile(object, pos)

func build_divider(pos : Vector2, dir : Vector2, count : int, dungeon):
	if count == 3:
		build_obstacle(Vector2.ZERO, dungeon)
		for i in range(0, room_size):
				build_obstacle(pos + dir * (i + 1), dungeon)
		return count

	match choose_divider():
		Divider.DOOR:
			build_divider_door(pos, dir, dungeon)

		Divider.TRAP:
			build_divider_trap(pos, dir, dungeon)

	return count + 1

func build_divider_door(pos : Vector2, dir : Vector2, dungeon):
	var opening = randi() % room_size
	for i in range(0, room_size):
		if i != opening:
			build_obstacle(pos + dir * (i + 1), dungeon)

func build_divider_trap(pos : Vector2, dir : Vector2, dungeon):
	for i in range(randi() % 2, room_size, 2):
		build_plate_damage(pos + dir * (i + 1), dungeon)

func choose_divider() -> int:
	var sum = randf()
	for option in [Divider.NONE, Divider.DOOR, Divider.TRAP]:
		sum -= divider_weight[option]
		if sum < 0:
			return option

	return Divider.NONE