about summary refs log tree commit diff stats
path: root/app/jobs
Commit message (Collapse)AuthorAgeFilesLines
* Added Pokédex viewing pageKelly Rauchenberger2018-01-291-0/+10
| | | | Currently a work in progress. The queries used to display the Pokémon for each species are very inefficient. The text at the top of the page is also very specific to the author.
* Fixed incorrect icon eager loading bug on front pageKelly Rauchenberger2018-01-131-1/+1
| | | | A bug was causing a Vigoroth which had evolved into a Slaking to still show up as a Vigoroth on the front page of the engine, even though it showed up properly on its show page. This was deemed to be caused by eager loading.
* Moved species from Pokémon to revisionKelly Rauchenberger2018-01-131-2/+2
| | | | | | | | The migration will set all of the revisions of each Pokémon to have the species that that Pokémon was set to. If reversed, the migration sets the Pokémon's species to the first revision's species, which mimics the behavior of the engine from before this change, but do note that running the migration backwards like this can lose data. This change slightly affects the loading time of the front page. See #2. refs #3
* Pokémon now show the Poké Ball that they're inKelly Rauchenberger2017-10-041-0/+1
| | | | Also fixed a bug with viewing Pokémon that aren't in any game.
* Added generic met message for Pokémon from OrreKelly Rauchenberger2017-10-041-1/+3
| | | | | | Pokémon from Orre now display "Met in a trade" instead of an entirely incorrect met location, because we're not currently equipped to display the proper met data for them (see hatkirby/gen3uploader#6).
* Removed box modelKelly Rauchenberger2017-10-031-16/+25
| | | | | | | | | | | | | It seemed kind of strange to have a model that there should always be exactly 14 of for each of the parent (Trainer) model instances, so the box names were moved into the Trainer model, and the Box model was removed. This commit also adds some eager loading to speed up page loading times. Also made a small change to the way the gift ribbons are extracted. refs #2
* Made "met location" into an actual associationKelly Rauchenberger2017-10-031-2/+2
|
* Added hold itemsKelly Rauchenberger2017-09-301-1/+1
| | | | | | | | | | | | | | | | | | | | | | An items model was created, but the seed only contains items that can be held, which excludes key items and HMs. Berry Juice, while unobtainable, is still included. The item model contains three description fields: one for Ruby/Sapphire, one for FireRed/LeafGreen, and one for Emerald. This is because the descriptions for items are different between the games. In a lot of cases, the Emerald description is the same as the Ruby/Sapphire one, so in those cases, the Emerald description is nil. The purpose of having the different descriptions is so that when a Pokémon holds an item, the website can display the description that is accurate to the game that that Pokémon is currently in. In order to fully support TMs, the move model was improved to additionally contain type and also the three description fields which operate similarly to those of the item model. For TMs, the description fields on the item are usually nil. However, some TMs in Ruby/Sapphire, as well as Emerald, have different descriptions than the moves that they correspond with. In these cases, those descriptions are in the item model, and override the move descriptions when the move is looked at as a TM.
* Added gift ribbon descriptionsKelly Rauchenberger2017-09-301-0/+30
| | | | | | This is basically just for completeness because it is unknown whether gift ribbons other than the National Ribbon and Earth Ribbon from Pokémon Colosseum were ever distributed.
* Added ribbonsKelly Rauchenberger2017-09-291-0/+18
| | | | | | Gift ribbons currently partially work: the correct ribbon image and name is shown, but the ribbon description is not yet extracted from the game and thus is just blank.
* Added met location dataKelly Rauchenberger2017-09-251-0/+7
| | | | | Note that the met location for Pokémon from Orre is completely incorrect.
* Added box namesKelly Rauchenberger2017-09-241-0/+6
|
* Added storage location information to PokémonKelly Rauchenberger2017-09-241-5/+15
|
* Added OT gender fieldKelly Rauchenberger2017-09-241-0/+1
|
* Started working on UIKelly Rauchenberger2017-09-241-2/+8
| | | | | This commit imports a lot of assets from veekun, as well as a font from http://www.victoryroad.net/showthread.php?t=1507
* Started writing extractorKelly Rauchenberger2017-09-231-0/+88
|
* Initial commitKelly Rauchenberger2017-09-161-0/+4
2'>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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247







                                                     










                                                                                            




















                                                                                        





                                                                 





                                                                                            
















                                                                            

                                                                             



























                                                                                                    


                                                                                                                                 


















                                                                                            













































                                                                                                 

                                                                                    








                                                                                                 










                                                                                             





                                                                                        
 


                                            



                                                                                   



                                    

 









                                                         



























                                                                                            
extends "res://scripts/load.gd"


func _load():
	global._print("Hooked Load Start")

	var apclient = global.get_node("Archipelago")

	# Override the YOU panel with the AP slot name.
	if self.get_node_or_null("Panels/Color Arrow Room/Panel_you") != null:
		self.get_node("Panels/Color Arrow Room/Panel_you").answer = apclient.ap_user
	for node in get_tree().get_nodes_in_group("text_you"):
		if "text" in node:
			node.text = apclient.ap_user
		elif "value" in node:
			node.value = apclient.ap_user
	for node in get_tree().get_nodes_in_group("answer_you"):
		if "answer" in node:
			node.answer = apclient.ap_user

	# This is the best time to create the location nodes, since the map is now
	# loaded but the panels haven't been solved from the save file yet.
	var panels_parent = self.get_node("Panels")
	var location_script = ResourceLoader.load("user://maps/Archipelago/location.gd")
	for location_name in apclient._location_name_to_id:
		var location = location_script.new()
		location.ap_name = location_name
		location.ap_id = apclient._location_name_to_id[location_name]
		location.name = "AP_location_" + location.ap_id
		self.add_child(location)

		var panels = apclient._panel_ids_by_location[String(location.ap_id)]
		location.total = panels.size()

		for panel in panels:
			var that_panel = panels_parent.get_node(panel)
			that_panel.get_node("Viewport/GUI/Panel/TextEdit").connect(
				"answer_correct", location, "handle_correct"
			)

	# Randomize the panels, if necessary.
	var rng = RandomNumberGenerator.new()
	rng.seed = apclient._slot_seed

	var gamedata = apclient.get_node("Gamedata")
	if apclient._panel_shuffle == apclient.kREARRANGE_PANELS:
		# Move ZERO in front of the black wall, and replace the puzzle because
		# it has to be a black puzzle now.
		self.get_node("Panels/Backside Room/Panel_zero_zero").translation.z = 16.499
		set_static_panel("Backside Room/Panel_zero_zero", "reknits", "stinker")

		# Do the actual shuffling.
		var panel_pools = {}
		for panel in gamedata.panels:
			if not panel_pools.has(panel["tag"]):
				panel_pools[panel["tag"]] = {}
			var pool = panel_pools[panel["tag"]]
			var subtag = "default"
			if panel.has("subtag"):
				subtag = panel["subtag"]
			if not pool.has(subtag):
				pool[subtag] = []

			var panel_node = panels_parent.get_node(panel["id"])
			pool[subtag].append(
				{
					"id": panel["id"],
					"hint": panel_node.text,
					"answer": panel_node.answer,
					"link": panel["link"],
					"copy_to_sign": panel["copy_to_sign"]
				}
			)

		for tag in panel_pools.keys():
			if tag == "forbid":
				continue

			var pool = panel_pools[tag]
			for subtag in pool.keys():
				pool[subtag].sort_custom(self, "sort_by_link")

			var count = pool[pool.keys()[0]].size()
			var iota = range(0, count)
			var order = []
			while not iota.empty():
				var i = rng.randi_range(0, iota.size() - 1)
				order.append(iota[i])
				iota.remove(i)

			for subtag in pool.keys():
				for i in range(0, count):
					var source = pool[subtag][i]
					var target = pool[subtag][order[i]]
					var target_panel_node = panels_parent.get_node(target["id"])

					target_panel_node.text = source["hint"]
					target_panel_node.answer = source["answer"]

					for sign_name in target["copy_to_sign"]:
						self.get_node("Decorations/PanelSign").get_node(sign_name).value = source["hint"]

	# Handle our other static panels after panel randomization, so that the old
	# values can enter the pool, if necessary.
	set_static_panel("Entry Room/Panel_hi_hi", "hi")
	set_static_panel("Entry Room/Panel_write_write", "seed")
	set_static_panel("Entry Room/Panel_same_same", str(apclient._slot_seed))
	set_static_panel("Entry Room/Panel_type_type", "victory")

	var victory_condition = "unknown"
	if apclient._victory_condition == apclient.kTHE_END:
		victory_condition = "the end"
	elif apclient._victory_condition == apclient.kTHE_MASTER:
		victory_condition = "the master"

	set_static_panel("Entry Room/Panel_this_this", victory_condition)
	set_static_panel("Entry Room/Panel_hidden_hidden", "hewwo")
	set_static_panel("Entry Room/Panel_hi_high", "goode", "good")
	set_static_panel("Entry Room/Panel_low_low", "serendipity", "luck")
	set_static_panel("Shuffle Room/Panel_secret_secret", "trans rights", "human rights")

	# Randomize the paintings, if necessary.
	if apclient._painting_shuffle:
		var pd_script = ResourceLoader.load("user://maps/Archipelago/paintingdata.gd")
		var pd = pd_script.new()
		pd.set_name("AP_Paintings")
		self.add_child(pd)

		var all_paintings = pd.kALL_PAINTINGS

		var classes = {}
		for painting in apclient._paintings_mapping.values():
			if not classes.has(painting):
				var i = rng.randi_range(0, all_paintings.size() - 1)
				var chosen = all_paintings[i]
				classes[painting] = chosen
				all_paintings.remove(i)

		var randomized = []
		for painting in apclient._paintings_mapping.values():
			var painting_class = classes[painting]
			instantiate_painting(painting, painting_class)
			randomized.append(painting)

		for source_painting in apclient._paintings_mapping.keys():
			var target_painting = apclient._paintings_mapping[source_painting]
			var painting_class = classes[target_painting]
			var new_source = instantiate_painting(source_painting, painting_class)
			new_source.target = pd.get_node(target_painting).get_node("Script")
			randomized.append(source_painting)

		var remaining_size = classes.size() / 2
		if remaining_size >= all_paintings.size():
			remaining_size = all_paintings.size()
		var remaining = []
		for i in range(0, remaining_size):
			var j = rng.randi_range(0, all_paintings.size() - 1)
			remaining.append(all_paintings[j])
			all_paintings.remove(j)

		for painting in apclient._paintings.keys():
			if randomized.has(painting):
				continue

			var chosen_painting = remaining[rng.randi_range(0, remaining.size() - 1)]
			instantiate_painting(painting, chosen_painting)

	# Attach a script to every panel so that we can do things like conditionally
	# disable them.
	var panel_script = ResourceLoader.load("user://maps/Archipelago/panel.gd")
	for panel in gamedata.panels:
		var panel_node = panels_parent.get_node(panel["id"])
		var script_instance = panel_script.new()
		script_instance.name = "AP_Panel"
		script_instance.data = panel
		panel_node.add_child(script_instance)
		apclient.connect("evaluate_solvability", script_instance, "evaluate_solvability")

	# Hook up the goal panel.
	if apclient._victory_condition == 1:
		var the_master = self.get_node("Panels/Countdown Panels/Panel_master_master")
		the_master.get_node("Viewport/GUI/Panel/TextEdit").connect(
			"answer_correct", apclient, "completedGoal"
		)
	else:
		var the_end = self.get_node("Decorations/EndPanel/Panel_end_end")
		the_end.get_node("Viewport/GUI/Panel/TextEdit").connect(
			"answer_correct", apclient, "completedGoal"
		)

	# Create the messages node.
	var messages_script = ResourceLoader.load("user://maps/Archipelago/messages.gd")
	var messages = messages_script.new()
	messages.set_name("AP_Messages")
	self.add_child(messages)

	# Proceed with the rest of the load.
	global._print("Hooked Load End")
	._load()

	# Process any items received while the map was loading, and send the checks
	# from the save load.
	apclient.mapFinishedLoading()


func sort_by_link(a, b):
	return a["link"] < b["link"]


func set_static_panel(name, question, answer = ""):
	if answer == "":
		answer = question

	var node = self.get_node("Panels").get_node(name)

	node.text = question
	node.answer = answer


func instantiate_painting(name, scene):
	var apclient = global.get_node("Archipelago")

	var scene_path = "res://nodes/paintings/%s.tscn" % scene
	var painting_scene = load(scene_path)
	var new_painting = painting_scene.instance()
	new_painting.set_name(name)

	var old_painting = self.get_node("Decorations/Paintings").get_node(name)
	new_painting.translation = old_painting.translation
	new_painting.rotation = old_painting.rotation

	var mypainting_script = ResourceLoader.load("user://maps/Archipelago/mypainting.gd")
	var mps_inst = mypainting_script.new()
	mps_inst.set_name("Script")

	var pconfig = apclient._paintings[name]
	mps_inst.orientation = pconfig["orientation"]
	if pconfig["move"]:
		mps_inst.move = true
		mps_inst.move_to_x = old_painting.move_to_x
		mps_inst.move_to_z = old_painting.move_to_z
		mps_inst.key = old_painting.key

	self.get_node("AP_Paintings").add_child(new_painting)
	new_painting.add_child(mps_inst)
	old_painting.queue_free()
	return mps_inst