· 6 years ago · Dec 31, 2019, 03:08 AM
1from copy import copy
2import itertools
3import numpy as np
4
5"""
6
7- This script does NOT handle spawners (except for rupee clusters)
8- This script does NOT handle scarecrow memory leak
9
10- This script does not account for ISoT memory leak for solution options
11
12
13FOR DEKU PALACE, THIS DOES NOT ACCOUNT FOR POTENTIALLY NEEDING TO BREAK A POT FOR THE SUPERSLIDE
14
15THIS SCRIPT DOES NOT ACCOUNT FOR GOLD SKULLTULA TOKENS
16
17
18"""
19
20
21
22"""
23
24Note: Node size is 0x10 = 16 on English and 0x30 = 48 on JP
25
26"""
27
28version = 'English'
29
30if version == 'English':
31 node_size = 0x10
32elif version == 'JP':
33 nodesize = 0x30
34else:
35 print('Error: Invalid Version (choose "English" or "JP" )')
36
37
38
39class Actor:
40
41 """
42
43 name: name of the actor, some string
44
45 Id: Actor id, string of 4 integers
46
47 size: the size of an actor instance for this actor (number of bytes, in decimal)
48
49 category: the actor category (category 5 is treated differently than others)
50 For now, giving everything not category 5 a category of 0
51
52 overlay_type: determines where the AF loads in the heap
53
54 unloadable: a boolean for whether or not it is possible to deallocate this actor without changing rooms
55
56 address: the memory address of the actor in decimal (can convert to a hex string for output)
57 Note: The earliest address we handle is 0x40B150 = 4239696. All addresses must be multiples of 16
58
59 room_number: the number of the room these actors are associated with; if the actor is a transition (i..e Plane
60 or Door), then set room_numer = False
61
62
63 priority: an index to differentiate copies of the same instance
64
65 from_spawner: True or False (True if it is from a spawner, like rupees from a cluster; False otherwise)
66
67 transition: False is the actor is not a Loading Plane or a Door. Otherwise, it is a list of the rooms that the transition actor connects, ordered from least to greatest room number
68
69 clearable: True if it is possible to set a flag to make this actor not respawn upon reloading the room (though, unless it it Category 5, it will attempt to reload and then immediately deallocate), False otherwise
70
71 cleared: True if the flag was set to clear this actor, False otherwise
72
73 """
74
75 def __init__(self, name, Id, size, category, overlay_type, unloadable, address, room_number, priority, from_spawner, transition, clearable, cleared):
76 self.name = name
77 self.Id = Id
78 self.size = size
79 self.category = category
80 self.overlay_type = overlay_type
81 self.unloadable = unloadable
82 self.address = address
83 self.room_number = room_number
84 self.priority = priority
85 self.from_spawner = from_spawner
86 self.transition = transition
87 self.clearable = clearable
88 self.cleared = cleared
89
90class Room:
91
92 """
93
94 number: the room number (i.e. Room 0 has number 0)
95
96 priority_queue: this will be the list of actor instances of the room, in order
97
98 clock_exists: boolean for whether or not the clock is an actor in the queue
99
100 clock_priority: if clock_exists == False, then clock_priority will be a number
101 to determine where in the queue the clock should be loaded, for
102 example, if clock_priority is 2, then it means that the clock
103 should be the 3rd actor to appear in the queue (first index is 0)
104
105 """
106
107 def __init__(self, number, priority_queue, clock_exists, clock_priority):
108 self.number = number
109 self.priority_queue = priority_queue
110 self.clock_exists = clock_exists
111 self.clock_priority = clock_priority
112
113class Node:
114
115 """
116 address: which address in memory the node is at (as a base-10 integer for now)
117
118 size: nodes should be 16 bytes (english), so input 16
119
120 """
121
122 def __init__(self, address, size):
123 self.address = address
124 self.size = size
125
126class Overlay:
127
128 def __init__(self, address, Id, size):
129 self.address = address
130 self.Id = Id
131 self.size = size
132
133
134"""
135
136We define the Clock actor ahead of time as it is not necessarily present in each room
137
138"""
139
140
141Clock = Actor(name='Clock', Id='015A', size=340, category=0, overlay_type='A', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
142
143###############################################################################
144
145Palace_Room0_queue = [
146 Actor(name='Loading Plane', Id='0018', size=332, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=[0,1], clearable=False, cleared=False),
147 Actor(name='Loading Plane', Id='0018', size=332, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=1, from_spawner=False, transition=[0,2], clearable=False, cleared=False),
148 Actor(name='Loading Plane', Id='0018', size=332, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=2, from_spawner=False, transition=[0,1], clearable=False, cleared=False),
149 Actor(name='Loading Plane', Id='0018', size=332, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=3, from_spawner=False, transition=[0,2], clearable=False, cleared=False),
150 Actor(name='Loading Plane', Id='0018', size=332, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=4, from_spawner=False, transition=[0,1], clearable=False, cleared=False),
151 Actor(name='???02AE ', Id='02AE', size=0x14C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
152 Actor(name='Deku Scrub Guard (Palace Entrance)', Id='01A0', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
153 Actor(name='Deku Scrub Guard (Palace Entrance)', Id='01A0', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
154 Actor(name='Poisoned/Purified Water Elements', Id='0186', size=0x170, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
155 Actor(name='Poisoned/Purified Water Elements', Id='0186', size=0x170, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
156 Actor(name='Poisoned/Purified Water Elements', Id='0186', size=0x170, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
157 Actor(name='Deku Flower', Id='0183', size=0x284, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
158 Actor(name='Deku Flower', Id='0183', size=0x284, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
159 Actor(name='Deku Flower', Id='0183', size=0x284, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
160 Actor(name='Mushroom Scent Cloud', Id='023B', size=0x144, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
161 Actor(name='Wilted Deku Baba & Mini Baba', Id='0066', size=0x2C8, category=5, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
162 Actor(name='Monkey', Id='019E', size=0x3EC, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
163 Actor(name='Big Octo', Id='01A8', size=0x3F8, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
164 Actor(name='Square Sign', Id='00A8', size=0x1F0, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
165 Actor(name='Square Sign', Id='00A8', size=0x1F0, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
166 Actor(name='Square Sign', Id='00A8', size=0x1F0, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
167 Actor(name='Magic Bean Plant', Id='0091', size=0x204, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
168 Actor(name='Magic Bean Plant', Id='0091', size=0x204, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
169 Actor(name='Clock', Id='015A', size=340, category=0, overlay_type='A', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
170 Actor(name='Bombable Rock', Id='0092', size=0x208, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
171 Actor(name='Bombable Rock', Id='0092', size=0x208, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
172 Actor(name='Directional Sign', Id='0026', size=0x194, category=0, overlay_type='B', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
173 Actor(name='Directional Sign', Id='0026', size=0x194, category=0, overlay_type='B', unloadable=False, address=0, room_number=0, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
174 Actor(name='Directional Sign', Id='0026', size=0x194, category=0, overlay_type='B', unloadable=False, address=0, room_number=0, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
175 Actor(name='Directional Sign', Id='0026', size=0x194, category=0, overlay_type='B', unloadable=False, address=0, room_number=0, priority=3, from_spawner=False, transition=False, clearable=False, cleared=False),
176 Actor(name='???017C', Id='017C', size=0x164, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
177 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
178 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
179 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
180 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=3, from_spawner=False, transition=False, clearable=False, cleared=False),
181 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=4, from_spawner=False, transition=False, clearable=False, cleared=False),
182 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=5, from_spawner=False, transition=False, clearable=False, cleared=False),
183 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=6, from_spawner=False, transition=False, clearable=False, cleared=False),
184 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=7, from_spawner=False, transition=False, clearable=False, cleared=False),
185 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=8, from_spawner=False, transition=False, clearable=False, cleared=False),
186 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=9, from_spawner=False, transition=False, clearable=False, cleared=False),
187 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=10, from_spawner=False, transition=False, clearable=False, cleared=False),
188 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=11, from_spawner=False, transition=False, clearable=False, cleared=False),
189 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=12, from_spawner=False, transition=False, clearable=False, cleared=False),
190 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=13, from_spawner=False, transition=False, clearable=False, cleared=False),
191 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=14, from_spawner=False, transition=False, clearable=False, cleared=False),
192 Actor(name='Lilypad', Id='01B9', size=0x16C, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=15, from_spawner=False, transition=False, clearable=False, cleared=False),
193 ]
194
195
196Palace_Room1_queue = [
197 Palace_Room0_queue[0],
198 Palace_Room0_queue[2],
199 Palace_Room0_queue[4],
200 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
201 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=True, cleared=False),
202 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=1, priority=2, from_spawner=False, transition=False, clearable=True, cleared=False),
203 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=1, priority=3, from_spawner=False, transition=False, clearable=True, cleared=False),
204 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=1, priority=4, from_spawner=False, transition=False, clearable=True, cleared=False),
205 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=1, priority=5, from_spawner=False, transition=False, clearable=True, cleared=False),
206 Actor(name='Grotto Hole', Id='0055', size=0x194, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
207 Actor(name='Poisoned/Purified Water Elements', Id='0186', size=0x170, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
208 Actor(name='Elevator (Deku Palace & Woodfall Temple)', Id='013C', size=0x18C, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
209 Actor(name='Elevator (Deku Palace & Woodfall Temple)', Id='013C', size=0x18C, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
210 Actor(name='Deku Flower', Id='0183', size=0x284, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
211 Actor(name='Deku Flower', Id='0183', size=0x284, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
212 Actor(name='Bronze Boulder', Id='00FC', size=0x1A4, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
213 Actor(name='Bronze Boulder', Id='00FC', size=0x1A4, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
214 Actor(name='Bronze Boulder', Id='00FC', size=0x1A4, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
215 Actor(name='Pot', Id='0082', size=0x19C, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
216 Actor(name='Pot', Id='0082', size=0x19C, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
217 Actor(name='Rupee Cluster', Id='00E8', size=360, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
218 Actor(name='Deku Scrub Guard (Palace Gardens)', Id='017A', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
219 Actor(name='Deku Scrub Guard (Palace Gardens)', Id='017A', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
220 Actor(name='Deku Scrub Guard (Palace Gardens)', Id='017A', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
221 Actor(name='Deku Scrub Guard (Palace Gardens)', Id='017A', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=3, from_spawner=False, transition=False, clearable=False, cleared=False),
222 Actor(name='Deku Scrub Guard (Palace Gardens)', Id='017A', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=4, from_spawner=False, transition=False, clearable=False, cleared=False),
223 Actor(name='Mad Scrub (Field Enemy)', Id='003B', size=0x2C8, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
224 Actor(name='Mad Scrub (Field Enemy)', Id='003B', size=0x2C8, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
225 Actor(name='Torch Stand (Generic)', Id='0039', size=0x1F4, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
226 Actor(name='Torch Stand (Generic)', Id='0039', size=0x1F4, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
227 Actor(name='Clock', Id='015A', size=340, category=0, overlay_type='A', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
228 Actor(name='???017C', Id='017C', size=0x164, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
229 Actor(name='Deku Flower', Id='0183', size=0x284, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
230 Actor(name='Deku Flower', Id='0183', size=0x284, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=3, from_spawner=False, transition=False, clearable=False, cleared=False),
231 ]
232
233
234Palace_Room2_queue = [
235 Palace_Room0_queue[1],
236 Palace_Room0_queue[3],
237 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
238 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=1, from_spawner=False, transition=False, clearable=True, cleared=False),
239 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=2, from_spawner=False, transition=False, clearable=True, cleared=False),
240 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=3, from_spawner=False, transition=False, clearable=True, cleared=False),
241 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=4, from_spawner=False, transition=False, clearable=True, cleared=False),
242 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=5, from_spawner=False, transition=False, clearable=True, cleared=False),
243 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=6, from_spawner=False, transition=False, clearable=True, cleared=False),
244 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=7, from_spawner=False, transition=False, clearable=True, cleared=False),
245 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=8, from_spawner=False, transition=False, clearable=True, cleared=False),
246 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=9, from_spawner=False, transition=False, clearable=True, cleared=False),
247 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=10, from_spawner=False, transition=False, clearable=True, cleared=False),
248 Actor(name='Collectible (Rupee)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=11, from_spawner=False, transition=False, clearable=True, cleared=False),
249 Actor(name='Poisoned/Purified Water Elements', Id='0186', size=0x170, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
250 Actor(name='Elevator (Deku Palace & Woodfall Temple)', Id='013C', size=0x18C, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
251 Actor(name='Elevator (Deku Palace & Woodfall Temple)', Id='013C', size=0x18C, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
252 Actor(name='Deku Flower', Id='0183', size=0x284, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
253 Actor(name='Collectible (Heart Piece)', Id='000E', size=0x1A8, category=0, overlay_type='B', unloadable=True, address=0, room_number=2, priority=12, from_spawner=False, transition=False, clearable=True, cleared=False),
254 Actor(name='Deku Scrub Guard (Palace Gardens)', Id='017A', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
255 Actor(name='Deku Scrub Guard (Palace Gardens)', Id='017A', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
256 Actor(name='Deku Scrub Guard (Palace Gardens)', Id='017A', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
257 Actor(name='Deku Scrub Guard (Palace Gardens)', Id='017A', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=3, from_spawner=False, transition=False, clearable=False, cleared=False),
258 Actor(name='Deku Scrub Guard (Palace Gardens)', Id='017A', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=4, from_spawner=False, transition=False, clearable=False, cleared=False),
259 Actor(name='Deku Scrub Guard (Palace Gardens)', Id='017A', size=0x290, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=5, from_spawner=False, transition=False, clearable=False, cleared=False),
260 Actor(name='Mad Scrub (Field Enemy)', Id='003B', size=0x2C8, category=5, overlay_type='A', unloadable=True, address=0, room_number=2, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
261 Actor(name='Mad Scrub (Field Enemy)', Id='003B', size=0x2C8, category=5, overlay_type='A', unloadable=True, address=0, room_number=2, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
262 Actor(name='Torch Stand (Generic)', Id='0039', size=0x1F4, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
263 Actor(name='Clock', Id='015A', size=340, category=0, overlay_type='A', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
264 Actor(name='???017C', Id='017C', size=0x164, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
265 Actor(name='Torch Stand (Generic)', Id='0039', size=0x1F4, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
266 Actor(name='Torch Stand (Generic)', Id='0039', size=0x1F4, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
267 Actor(name='Torch Stand (Generic)', Id='0039', size=0x1F4, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=3, from_spawner=False, transition=False, clearable=False, cleared=False),
268 Actor(name='Deku Flower', Id='0183', size=0x284, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
269 Actor(name='Deku Flower', Id='0183', size=0x284, category=0, overlay_type='A', unloadable=False, address=0, room_number=2, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
270 ]
271
272###############################################################################
273
274Oceanside_Room3_queue = [
275 Actor(name='Loading Plane', Id='0018', size=332, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=[3,4], clearable=False, cleared=False),
276 Actor(name='Wooden Door', Id='0005', size=0x1CC, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=[2,3], clearable=False, cleared=False),
277 Actor(name='Stalchild (Oceanside Spider House)', Id='02A5', size=0x3EC, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
278 Actor(name='Stalchild (Oceanside Spider House)', Id='02A5', size=0x3EC, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
279 Actor(name='Stalchild (Oceanside Spider House)', Id='02A5', size=0x3EC, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
280 Actor(name='Stalchild (Oceanside Spider House)', Id='02A5', size=0x3EC, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=3, from_spawner=False, transition=False, clearable=False, cleared=False),
281 Actor(name='Pot', Id='0082', size=0x19C, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
282 Actor(name='Pot', Id='0082', size=0x19C, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
283 Actor(name='Oceanside Spider House Skull Kid Painting', Id='0210', size=0x244, category=0, overlay_type='A', unloadable=False, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
284 Actor(name='Oceanside Spider House Skull Kid Painting', Id='0210', size=0x244, category=0, overlay_type='A', unloadable=False, address=0, room_number=3, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
285 Actor(name='Oceanside Spider House Skull Kid Painting', Id='0210', size=0x244, category=0, overlay_type='A', unloadable=False, address=0, room_number=3, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
286 Actor(name='Oceanside Spider House Skull Kid Painting', Id='0210', size=0x244, category=0, overlay_type='A', unloadable=False, address=0, room_number=3, priority=3, from_spawner=False, transition=False, clearable=False, cleared=False),
287 Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=5, overlay_type='A', unloadable=True, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
288 Actor(name='Spiderweb', Id='0125', size=0x2FC, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
289 Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=5, overlay_type='A', unloadable=True, address=0, room_number=3, priority=1, from_spawner=False, transition=False, clearable=True, cleared=False),
290 Actor(name='Bonk Actor (01E7)', Id='01E7', size=0x148, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
291 Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=5, overlay_type='A', unloadable=True, address=0, room_number=3, priority=2, from_spawner=False, transition=False, clearable=True, cleared=False),
292 Actor(name='Bonk Actor (01E7)', Id='01E7', size=0x148, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
293 Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=5, overlay_type='A', unloadable=True, address=0, room_number=3, priority=3, from_spawner=False, transition=False, clearable=True, cleared=False),
294 Actor(name='Bonk Actor (01E7)', Id='01E7', size=0x148, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
295 Actor(name='Tent-Shaped Spider Web', Id='01F4', size=0x3CC, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
296 Actor(name='Oceanside Spider House Fireplace Grate', Id='020F', size=0x284, category=0, overlay_type='A', unloadable=False, address=0, room_number=3, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
297 Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=5, overlay_type='A', unloadable=True, address=0, room_number=3, priority=4, from_spawner=False, transition=False, clearable=True, cleared=False),
298 Actor(name='Bonk Actor (01E7)', Id='01E7', size=0x148, category=0, overlay_type='A', unloadable=True, address=0, room_number=3, priority=3, from_spawner=False, transition=False, clearable=False, cleared=False)
299 ]
300
301
302Oceanside_Room4_queue = [
303 Oceanside_Room3_queue[0],
304 Actor(name='Skulltula', Id='0024', size=0x550, category=5, overlay_type='A', unloadable=True, address=0, room_number=4, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
305 Actor(name='Chest', Id='0006', size=548, category=0, overlay_type='A', unloadable=False, address=0, room_number=4, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
306 ]
307
308
309
310
311
312###############################################################################
313
314Room0_queue = [
315 Actor(name='Wooden Door', Id='0005', size=460, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=[0,3], clearable=False, cleared=False),
316 Actor(name='Loading Plane', Id='0018', size=332, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=[0,1], clearable=False, cleared=False),
317 Actor(name='Rupee Cluster', Id='00E8', size=360, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
318 Actor(name='Dripping Water Effect', Id='0170', size=3644, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
319 Actor(name='Dripping Water Effect', Id='0170', size=3644, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
320 Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
321 Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
322 Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
323 Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
324 Actor(name='???0158', Id='0158', size=328, category=0, overlay_type='A', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
325 ]
326
327
328Room1_queue = [
329 Actor(name='Door Shutter', Id='001E', size=360, category=0, overlay_type='B', unloadable=False, address=0, room_number=False, priority=0, from_spawner=False, transition=[1,2], clearable=False, cleared=False),
330 Room0_queue[1],
331 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=True, cleared=False),
332 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=True, cleared=False),
333 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=2, from_spawner=False, transition=False, clearable=True, cleared=False),
334 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=3, from_spawner=False, transition=False, clearable=True, cleared=False),
335 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=4, from_spawner=False, transition=False, clearable=True, cleared=False),
336 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=5, from_spawner=False, transition=False, clearable=True, cleared=False),
337 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=6, from_spawner=False, transition=False, clearable=True, cleared=False),
338 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=7, from_spawner=False, transition=False, clearable=True, cleared=False),
339 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=8, from_spawner=False, transition=False, clearable=True, cleared=False),
340 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=9, from_spawner=False, transition=False, clearable=True, cleared=False),
341 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=10, from_spawner=False, transition=False, clearable=True, cleared=False),
342 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=11, from_spawner=False, transition=False, clearable=True, cleared=False),
343 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=12, from_spawner=False, transition=False, clearable=True, cleared=False),
344 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=13, from_spawner=False, transition=False, clearable=True, cleared=False),
345 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=14, from_spawner=False, transition=False, clearable=True, cleared=False),
346 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=15, from_spawner=False, transition=False, clearable=True, cleared=False),
347 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=16, from_spawner=False, transition=False, clearable=True, cleared=False),
348 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=17, from_spawner=False, transition=False, clearable=True, cleared=False),
349 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=18, from_spawner=False, transition=False, clearable=True, cleared=False),
350 Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=19, from_spawner=False, transition=False, clearable=True, cleared=False),
351 Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
352 Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
353 Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
354 Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False),
355 Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=1, from_spawner=False, transition=False, clearable=False, cleared=False),
356 Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=2, from_spawner=False, transition=False, clearable=False, cleared=False),
357 Actor(name='Chest', Id='0006', size=548, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
358 ]
359
360###############################################################################
361
362Room0 = Room(0, Room0_queue, False, 2)
363Room1 = Room(1, Room1_queue, False, 2)
364
365
366Oceanside_Room3 = Room(3, Oceanside_Room3_queue, False, 2)
367Oceanside_Room4 = Room(4, Oceanside_Room4_queue, False, 1)
368
369
370Palace_Room0 = Room(0, Palace_Room0_queue, True, -1)
371Palace_Room1 = Room(1, Palace_Room1_queue, True, -1)
372Palace_Room2 = Room(2, Palace_Room2_queue, True, -1)
373
374"""
375
376Define the list of Rooms that we consider
377
378"""
379
380Room_List = [Room0, Room1]
381
382Oceanside_Room_List = [Oceanside_Room3, Oceanside_Room4]
383
384
385"""
386
387In Overlay_dict we collect all of the Overlays of Type A, where the keys are
388the corresponding actor ids
389
390"""
391
392# NOTE: This must be named "Overlay_dict" because it is hardcoded in some functions, like the Deallocate() function
393Overlay_dict = {
394 '015A' : Overlay(address=0, Id='015A', size=6000),
395 '00E8' : Overlay(address=0, Id='00E8', size=1984),
396 '0170' : Overlay(address=0, Id='0170', size=10688),
397 '0039' : Overlay(address=0, Id='0039', size=3552),
398 '0082' : Overlay(address=0, Id='0082', size=9040),
399 '0158' : Overlay(address=0, Id='0158', size=1104),
400 '015B' : Overlay(address=0, Id='015B', size=6048),
401 '0006' : Overlay(address=0, Id='0006', size=8640),
402 '0017' : Overlay(address=0, Id='0017', size=10432),
403 '017B' : Overlay(address=0, Id='017B', size=14320),
404 '007B' : Overlay(address=0, Id='007B', size=5104),
405 '00A2' : Overlay(address=0, Id='00A2', size=24448),
406 '02A5' : Overlay(address=0, Id='02A5', size=0x2660),
407 '0210' : Overlay(address=0, Id='0210', size=0xB90),
408 '0050' : Overlay(address=0, Id='0050', size=0x3540),
409 '0125' : Overlay(address=0, Id='0125', size=0x1490),
410 '01E7' : Overlay(address=0, Id='01E7', size=0x450),
411 '01F4' : Overlay(address=0, Id='01F4', size=0x1A80),
412 '020F' : Overlay(address=0, Id='020F', size=0x780),
413 '0024' : Overlay(address=0, Id='0024', size=0x28E0),
414 '00E3' : Overlay(address=0, Id='00E3', size=0x420),
415 '02AE' : Overlay(address=0, Id='02AE', size=0x540),
416 '01A0' : Overlay(address=0, Id='01A0', size=0xEE0),
417 '0186' : Overlay(address=0, Id='0186', size=0x950),
418 '0183' : Overlay(address=0, Id='0183', size=0xD20),
419 '023B' : Overlay(address=0, Id='023B', size=0x3F0),
420 '0066' : Overlay(address=0, Id='0066', size=0x1EB0),
421 '019E' : Overlay(address=0, Id='019E', size=0x5A90),
422 '01A8' : Overlay(address=0, Id='01A8', size=0x2200),
423 '00A8' : Overlay(address=0, Id='00A8', size=0x3760),
424 '0091' : Overlay(address=0, Id='0091', size=0x26C0),
425 '0092' : Overlay(address=0, Id='0092', size=0x1820),
426 '017C' : Overlay(address=0, Id='017C', size=0x3110),
427 '01B9' : Overlay(address=0, Id='01B9', size=0x670),
428 '0055' : Overlay(address=0, Id='0055', size=0x690),
429 '013C' : Overlay(address=0, Id='013C', size=0xBF0),
430 '00FC' : Overlay(address=0, Id='00FC', size=0xC90),
431 '017A' : Overlay(address=0, Id='017A', size=0xEF0),
432 '003B' : Overlay(address=0, Id='003B', size=0x2040),
433 }
434
435"""
436
437Here we collect a list of the actors that we allow ourselves to spawn
438
439Notes:
440 'Zora Fins' means 2 fins
441 'Bugs' means a set of 3 bugs
442
443
444"""
445
446Allocation_List = [
447 'Nothing',
448 'Bomb',
449 'Smoke',
450 'Arrow',
451 'Hookshot',
452 'Charged Spin Attack',
453 'Chu',
454 'Zora Fins',
455 'Fish',
456 'Bugs'
457 ]
458
459######
460
461
462"""
463
464NOTE: We NEED to have 'Hookshot' and 'Charged Spin Attack' as the last two options
465in order to consider all cases
466
467Don't have 'Bomb' before 'Smoke' to ensure that the Smoke always gets allocated first
468
469maybe in the future you could jumble/randomize the order of things in this list at each step
470of the solver
471
472"""
473Hardcoded_Allocation_List = [
474 'Smoke',
475 'Smoke',
476 'Smoke',
477 'Chu',
478 'Chu',
479 'Chu',
480 'Arrow',
481 'Arrow',
482 'Arrow',
483 'Arrow',
484 'Arrow',
485 'Bomb',
486 'Bomb',
487 'Bomb',
488 'Zora Fins',
489 'Fish',
490 'Fish',
491 'Bugs',
492 'Bugs',
493 'Hookshot',
494 'Charged Spin Attack'
495 ]
496
497"""
498
499Here we collect a list of the Ids grabbable actors that we can use for superslide SRM
500So far this includes:
501
502 0082: Pot
503
504"""
505
506Grabbable_Actors = ['0082']
507
508
509"""
510
511Here we collect a list of Actor Ids for spawners. So far this includes:
512
513 00E8: Rupee Cluster
514
515"""
516
517Spawner_Ids = ['00E8']
518
519
520"""
521
522We initialize the Heap as a list, putting a node with address 0x40B140 in the 0th entry
523and we place a dummy node at the end of the Heap so that there will always exist two
524consecutive nodes for us to define a condition for which free space in the Heap exists
525
526Keep in mind that the 0x5FFFFF address in the dummy node will not reflect the actual
527address of the corresponding node in-game, but it also isn't relevant to heap manipulation
528since it is so far down
529
530"""
531
532
533Heap = [Node(0x40B140, node_size), Node(0x5FFFFF, node_size)]
534
535
536
537def Overlay_In_Heap(Heap, overlay):
538
539 """
540
541 Overlay is the overlay that we want to check whether or not it is in the Heap
542
543 This function will return True if Overlay is in the Heap and False otherwise
544
545 """
546
547 overlay_in_heap = False
548
549 for entry in Heap:
550
551 if type(entry) == Overlay and entry.Id == overlay.Id:
552
553 overlay_in_heap = True
554
555 return overlay_in_heap
556
557
558def Actor_Id_In_Heap(Heap, actor_id):
559
560 """
561
562 actor_id is the Id that we want to check for
563
564 This function will return True if there exists an Actor in the Heap that
565 has actor_id as its Id and it will return False otherwise
566
567 """
568
569 actor_id_in_heap = False
570
571 for entry in Heap:
572
573 if type(entry) == Actor and entry.Id == actor_id:
574
575 actor_id_in_heap = True
576
577 return actor_id_in_heap
578
579
580def Find_Gaps(Heap):
581
582 """
583
584 This function will find all consecutive nodes and output a list of 4-tuples
585 where the first two entries correspond to the indices of each node in the list
586 and the last two entries correspond to the addresses of each node
587
588 The list should be in order, from the start of the Heap to the end of the Heap
589
590 """
591
592 consecutive_node_count = 0
593
594 node_1_address = 0
595 node_2_address = 0
596 node_1_index = 0
597 node_2_index = 0
598
599 consecutive_node_list = []
600 for entry in Heap:
601 if type(entry) == Node and consecutive_node_count == 0:
602 node_1_address = entry.address
603 node_1_index = Heap.index(entry)
604 consecutive_node_count += 1
605 elif type(entry) == Node and consecutive_node_count == 1:
606 node_2_address = entry.address
607 node_2_index = Heap.index(entry)
608
609 consecutive_node_list.append((node_1_index, node_2_index, node_1_address, node_2_address))
610
611 consecutive_node_count += 1
612 elif type(entry) != Node:
613 consecutive_node_count = 0
614 elif type(entry) == Node and consecutive_node_count > 1:
615 consecutive_node_count += 1
616 print("ERROR: More than 2 consecutive nodes!! (Find_Gaps() Error Message)")
617
618
619 return consecutive_node_list
620
621
622
623
624def Allocate(Heap, actor, Overlay_Dict):
625
626 """
627
628 actor is the actor that we want to allocate into the Heap
629
630 Overlay_Dict is a dictionary where the keys are the actor ids which point to the corresponding Overlays
631
632 This function will account for placing nodes and overlays
633
634 """
635
636
637 #Overlay = Overlay_Dict[actor.Id]
638
639 #Overlay_Allocated = False
640
641 #if Overlay_In_Heap(Heap, Overlay) == True:
642 # Overlay_Allocated = True
643
644 Actor_Allocated = False
645
646 """
647 ##### Not yet defined, not sure if I will bother; not really necessary. Probably should for debugging
648 if Actor_In_Heap == True:
649 print('Error: This Actor is already allocated!! (Error message from Allocate() function)')
650 """
651
652 gap_list = Find_Gaps(Heap)
653
654 # Because we initialize the Heap with 2 nodes, there should always be at least one gap
655 if len(gap_list) < 1:
656 print('ERROR: len(gap_list) < 1 in Allocate() function')
657
658
659 # If the Overlay is type A and the Overlay is not already in the Heap, then we want to allocate the overlay first
660 if actor.overlay_type == 'A':
661
662 ##### We only define Overlay for Type A overlays because Overlay_Dict only has Type A overlays
663 Overlay = Overlay_Dict[actor.Id]
664 Overlay_Allocated = False
665
666 if Overlay_In_Heap(Heap, Overlay) == True:
667 Overlay_Allocated = True
668
669
670 if Overlay_In_Heap(Heap, Overlay) == False:
671
672 for gap in gap_list:
673
674 if Overlay_Allocated == True:
675 break ##### This ensures we don't add in the same Overlay multiple times
676
677 node_2_index = gap[1]
678 node_1_address = gap[2]
679 node_2_address = gap[3]
680
681 gap_size = node_2_address - node_1_address - node_size
682
683 ##### Case 1: the Overlay can fit, but there is NOT enough space for an extra node
684 # Note that gap_size is always a multiple of 16
685
686 if Overlay.size <= gap_size and Overlay.size > gap_size - 2*node_size:
687
688 Overlay.address = node_1_address + node_size
689 Heap.insert(node_2_index, Overlay)
690 Overlay_Allocated = True
691
692
693 ##### Case 2: the Overlay can fit and a new node can also fit
694
695 elif Overlay.size <= gap_size and Overlay.size <= gap_size - 2*node_size:
696
697 Overlay.address = node_1_address + node_size
698 Heap.insert(node_2_index, Overlay)
699
700 ########### ADD IN THE NODE HERE
701 if Overlay.size%16 > 0:
702 Heap.insert(node_2_index + 1, Node(address=Overlay.address + Overlay.size + (16 - Overlay.size%16), size=node_size))
703 elif Overlay.size%16 == 0:
704 Heap.insert(node_2_index + 1, Node(address=Overlay.address + Overlay.size, size=node_size))
705
706 Overlay_Allocated = True
707
708 ############ Now the overlay (if applicable) has been allocated. Now we need to allocate the actor.
709
710 ##### We need to update the gaps_list to account for the overlay being allocated in the Heap already
711 gap_list = Find_Gaps(Heap)
712
713 for gap in gap_list:
714
715 if Actor_Allocated == True:
716 break ##### This ensures we don't add in the same Actor multiple times
717
718 node_2_index = gap[1]
719 node_1_address = gap[2]
720 node_2_address = gap[3]
721
722 gap_size = node_2_address - node_1_address - node_size
723
724 ##### Case 1: the Actor can fit, but there is NOT enough space for an extra node
725 # Note that gap_size is always a multiple of 16
726
727 if actor.size <= gap_size and actor.size > gap_size - 2*node_size:
728
729 actor.address = node_1_address + node_size
730 Heap.insert(node_2_index, actor)
731 Actor_Allocated = True
732
733
734 ##### Case 2: the Actor can fit and a new node can also fit
735
736 elif actor.size <= gap_size and actor.size <= gap_size - 2*node_size:
737
738 actor.address = node_1_address + node_size
739 Heap.insert(node_2_index, actor)
740
741 ########### ADD IN THE NODE HERE
742 if actor.size%16 > 0:
743 Heap.insert(node_2_index + 1, Node(address=actor.address + actor.size + (16 - actor.size%16), size=node_size))
744 elif actor.size%16 == 0:
745 Heap.insert(node_2_index + 1, Node(address=actor.address + actor.size, size=node_size))
746
747 Actor_Allocated = True
748
749def Borders_Node(Heap, entry):
750
751 """
752
753 This function takes an entry of the Heap as input and determines whether or
754 not this entry is adjacent to a node in the heap (the purpose of this is to
755 check if a node is bordering another node since actors and overlays should
756 be bordering two nodes under every circumstance)
757
758 Returns True if the entry is bordering a node, returns False otherwise
759
760 """
761
762 borders_node = False
763
764 entry_index = Heap.index(entry)
765
766 border_1_is_node = False
767 border_2_is_node = False
768
769 if entry_index != 0:
770 border_1 = Heap[entry_index - 1]
771 if type(border_1) == Node:
772 border_1_is_node = True
773
774 if entry_index != len(Heap) - 1:
775 border_2 = Heap[entry_index + 1]
776 if type(border_2) == Node:
777 border_2_is_node = True
778
779 if border_1_is_node == True or border_2_is_node == True:
780 borders_node = True
781
782 return borders_node
783
784
785
786def Deallocate(Heap, actor, Overlay_dict):
787
788
789 """
790
791 actor is the actor that we want to be deallocated from the Heap
792
793 This function will account for removing nodes and overlays
794
795 ##### Remove the actor AND node if applicable
796 ##### Check if any actors with the same Id are still in the Heap
797 ##### if not (and the actor has overlay Type A), then remove the overlay
798
799 We only remove a node if it is part of a gap before deallocating the actor
800 That is, we only remove a node if it borders another node before the actor is deallocated
801
802 """
803
804 if type(actor) != Actor:
805 print("ERROR: Attempted to deallocate something other than an Actor (Deallocate() function error message)")
806
807 # The index of where the actor is in the Heap before being deallocated; this will change after we remove the first node
808 actor_index = Heap.index(actor)
809
810 ##### First check the node above the actor in the Heap
811 node_1 = Heap[actor_index - 1]
812 if type(node_1) != Node:
813 print("ERROR: One of the nodes is not actually a node! (Deallocate() function error message)")
814
815 if Borders_Node(Heap, node_1) == True:
816 Heap.remove(node_1)
817
818 ########## Now the first node has been removed and the indices of the Heap shift
819
820 ##### Now we check the node below the actor in the Heap
821
822 # The index of where the actor is in the Heap before being deallocated; this will change after we remove the first node
823 actor_index = Heap.index(actor)
824
825 node_2 = Heap[actor_index + 1]
826 if type(node_2) != Node:
827 print("ERROR: One of the nodes is not actually a node! (Deallocate() function error message)")
828
829 if Borders_Node(Heap, node_2) == True:
830 Heap.remove(node_2)
831
832 ###########################################################################
833 ##### Now we have removed both of the nodes, if applicable and we must remove the actor itself
834
835 Heap.remove(actor)
836
837 """
838
839 Now if the actor has a Type A overlay, then we must check if the Heap contains
840 any other actors that have the same Id as actor and if not, then we must also
841 remove its overlay from the Heap
842
843 We must also account for removing the nodes around the overlay, if applicable
844
845 """
846
847 if actor.overlay_type == 'A' and Actor_Id_In_Heap(Heap, actor.Id) == False:
848
849 ##### First check the node above the overlay
850 overlay_index = Heap.index(Overlay_dict[actor.Id])
851 node1 = Heap[overlay_index - 1]
852
853 if type(node1) != Node:
854 print("ERROR: One of the nodes is not actually a node! (Deallocate() function error message)")
855
856 if Borders_Node(Heap, node1) == True:
857 Heap.remove(node1)
858
859
860 ##### Now we check the node below the overlay
861 overlay_index = Heap.index(Overlay_dict[actor.Id])
862 node2 = Heap[overlay_index + 1]
863
864 if type(node2) != Node:
865 print("ERROR: One of the nodes is not actually a node! (Deallocate() function error message)")
866
867 if Borders_Node(Heap, node2) == True:
868 Heap.remove(node2)
869
870 ###########################################################################
871 ##### Now we have removed both of the nodes, if applicable and we must remove the overlay itself
872
873 Heap.remove(Overlay_dict[actor.Id])
874
875
876
877def Load_Scene(Heap, room, Overlay_dict):
878
879 if len(Heap) != 2:
880 print("ERROR: Attempted to use Load_Scene() with an inappropriate Heap")
881
882 entry_count = 0
883 for entry in room.priority_queue:
884
885 ##### If the clock is not in the room's set of actors, then we must allocate the clock at the appropriate time when we load the scene
886 if entry_count == room.clock_priority and room.clock_exists == False:
887
888 ##### Allocate the 3-Day Clock actor
889 Allocate(Heap, Clock, Overlay_dict)
890 entry_count += 1
891
892 ##### Allocate the entry in the room's priority queue
893 Allocate(Heap, entry, Overlay_dict)
894
895 entry_count += 1
896
897 ##### Now that all of the actors have been allocated, we want to add in all of the actors that the spawners spawn
898
899 """
900
901 NOTE: THIS DOES NOT HANDLE SPAWNERS OTHER THAN RUPEE CLUSTERS AT THE MOMENT
902
903 In the future, it will need to be considered how the actors created by spawners
904 prioritize over each other... Spring MV is maybe the only place where this really matters
905
906 """
907
908 ##### Check for Rupee Cluster
909 if Overlay_In_Heap(Heap, Overlay_dict['00E8']) == True:
910
911 for j in range(7):
912 rupee = Actor(name='Collectible (Rupee from Rupee Cluster)', Id='000E', size=424, category=0, overlay_type='B', unloadable=True, address=0, room_number=room.number, priority=j, from_spawner=True, transition=False, clearable=True, cleared=False)
913
914 Allocate(Heap, rupee, Overlay_dict)
915
916
917
918def Actor_From_Room_In_Heap(Heap, Room_Number):
919
920 """
921
922 This function takes the Heap and the number of the Room in question as input
923 It returns True if there exists an Actor in the Heap with the inputted Room_Number and False otherwise
924
925 """
926
927 actor_from_room_in_heap = False
928
929 for entry in Heap:
930
931 if type(entry) == Actor and entry.room_number is Room_Number:
932
933 actor_from_room_in_heap = True
934
935 return actor_from_room_in_heap
936
937def Cleared_Actor_In_Heap(Heap):
938
939 """
940
941 This function returns True if there is a cleared actor in the Heap and False otherwise
942
943 """
944
945 cleared_actor_in_heap = False
946
947 for entry in Heap:
948
949 if type(entry) == Actor and entry.cleared == True:
950
951 cleared_actor_in_heap = True
952
953 return cleared_actor_in_heap
954
955
956def Shared_Transition_Count(Heap, Room_Number_1, Room_Number_2):
957
958 """
959
960 This function returns the number of transitions (Planes/Doors) that are shared between
961 the two rooms with room numbers Room_Number_1 and Room_Number_2
962
963 """
964
965 shared_transition_count = 0
966
967 for entry in Heap:
968
969 if type(entry) == Actor and entry.transition != False:
970
971 if (entry.transition[0] == Room_Number_1 and entry.transition[1] == Room_Number_2) or (entry.transition[0] == Room_Number_2 and entry.transition[1] == Room_Number_1):
972
973 shared_transition_count += 1
974
975 return shared_transition_count
976
977def Is_Shared_Transition(actor, Room_Number_1, Room_Number_2):
978
979 """
980
981 If actor is a transition shared between Rooms with numbers Room_Number_1 and Room_Number_2,
982 then this function returns True. Otherwise it returns False
983
984 """
985
986 is_shared_transition = False
987
988 if type(actor) == Actor and actor.transition != False:
989
990 if (actor.transition[0] == Room_Number_1 and actor.transition[1] == Room_Number_2) or (actor.transition[0] == Room_Number_2 and actor.transition[1] == Room_Number_1):
991
992 is_shared_transition = True
993
994 return is_shared_transition
995
996
997def Transition_Is_In_Room(actor, Room_Number):
998
999 transition_is_in_room = False
1000
1001 if type(actor) == Actor and actor.transition != False:
1002
1003 if actor.transition[0] == Room_Number or actor.transition[1] == Room_Number:
1004
1005 transition_is_in_room = True
1006
1007 return transition_is_in_room
1008
1009
1010def Find_Clock_List(Heap):
1011
1012 """
1013
1014 This function finds all clock actor instances in the Heap and returns a list of them, in order
1015
1016 """
1017
1018 clock_list = []
1019
1020 for entry in Heap:
1021
1022 if type(entry) == Actor and entry.Id == '015A':
1023
1024 clock_list.append(entry)
1025
1026 return clock_list
1027
1028
1029def Load_Room(Heap, room, transition, Overlay_dict):
1030
1031
1032 """
1033
1034 This function updates the Heap after you enter room through transition
1035 For example, you might enter Room0 through Plane1 or Door3
1036
1037 Before executing the script, should probably define Plane1, Plane2, ...
1038 Door1, Door2, ..., etc. as the corresponding entries from the room queues.
1039 This will make the code more readable when looking for solutions
1040
1041
1042 * First we load all of the actors from the new room
1043 * Next, we deallocate everything (well, not literally everything...) from the previous room
1044
1045
1046 Things that this function needs to handle:
1047
1048 - make sure that you check if each actor was cleared or not (if clearable == True, otherwise it isn't applicable)
1049 and then check if it is Category 5 to determine if it loads and immediately deallocates or not
1050
1051 - checking which clock to deallocate (i.e. deallocate the one that comes later
1052 on in the Heap if there are more than one). Maybe define a Find_Clocks function
1053
1054 - make sure transition never deallocates and never attempts to allocate
1055
1056 - make sure that the other Transitions unload and then reload (if applicable) after all of
1057 the stuff from the previous room deallocated
1058
1059 - when deallocating stuff from the room that isn't the room you're entering, be sure
1060 not to deallocate the clock. Also be careful of relevant Transitions as they don't have
1061 actual room numbers (replaced with False)
1062
1063 - allocate stuff from spawners after the fact (even after planes)
1064
1065
1066 """
1067
1068 if transition not in Heap:
1069 print('2222222222')
1070
1071 if transition not in room.priority_queue:
1072 print('44444444')
1073
1074 if (transition not in Heap) or (transition not in room.priority_queue):
1075 print("ERROR: Attempted to use Load_Room() with an invalid transition")
1076
1077 current_room_number = -1
1078 new_room_number = room.number
1079
1080 if transition.transition[0] == room.number:
1081 current_room_number = transition.transition[1]
1082 elif transition.transition[1] == room.number:
1083 current_room_number = transition.transition[0]
1084 else:
1085 print("ERROR: Error with transition list (Load_Room() error message)")
1086
1087 """
1088 First we load all of the actors from the new room, EXCEPT for: the plane/door
1089 we pass through AND any other shared transitions AND any actors with both
1090 cleared == True and Category == 5 (these ones never attempt to load)
1091 """
1092
1093 for actor in room.priority_queue:
1094
1095 ### If the actor is not a Transition OR if the actor is a transition but doesn't connect to the current room
1096 if (actor.transition == False) or (actor.transition != False and actor.transition[0] != current_room_number and actor.transition[1] != current_room_number):
1097
1098 ### If the actor is Category 5, then only attempt to load it if it has not been cleared
1099 if actor.category != 5 or actor.cleared == False:
1100
1101 Allocate(Heap, actor, Overlay_dict)
1102
1103 """
1104 - Now all of the relevant actors from the new room have been allocated
1105 - Now we need to immediately deallocate any actors with Clearable == True and Cleared == True
1106 - We also need to deallocate any transitions which are shared between the current room and the new room
1107 EXCEPT for transition itself (the transition that we passed through to get to the new room)
1108 - We also need to deallocate the second clock actor in the Heap if it exists (do this after everything else for simplicity)
1109
1110 Note that "current_room_number" is the room number of the room we were in before loading the new room
1111 """
1112
1113 while Actor_From_Room_In_Heap(Heap, current_room_number) == True or Cleared_Actor_In_Heap(Heap) == True or Shared_Transition_Count(Heap, current_room_number, new_room_number) > 1:
1114
1115 for entry in Heap:
1116
1117 if (type(entry) == Actor) and (entry.room_number is current_room_number or entry.cleared == True or Is_Shared_Transition(entry, current_room_number, new_room_number) == True or (entry.transition != False and Transition_Is_In_Room(entry, new_room_number) == False ) ) and (entry != transition):
1118
1119 Deallocate(Heap, entry, Overlay_dict)
1120
1121 ########## Now we will find all of the clocks and deallocate the second clock if it exists (and report error if more than two clocks)
1122
1123 Clock_List = Find_Clock_List(Heap)
1124
1125 if len(Clock_List) > 2:
1126 print("ERROR: More than 2 Clocks in the Actor Heap (Load_Room() Error Message)")
1127 elif len(Clock_List) < 1:
1128 print("ERROR: No Clock Actor Instance in the Actor Heap (Load_Room() Error Message)")
1129
1130 ##### If there are two clocks, then we deallocate the second clock that appears in the Heap
1131 if len(Clock_List) > 1:
1132
1133 Deallocate(Heap, Clock_List[1], Overlay_dict)
1134
1135
1136 ##### Now we allocate any shared transitions EXCEPT for transition itself (the door/plane we entered to get into this room)
1137
1138 for entry in room.priority_queue:
1139
1140 # If entry is a shared transition and is NOT the transition that we passed through
1141 if (type(entry) == Actor) and (entry.transition != False) and Is_Shared_Transition(entry, current_room_number, new_room_number) == True and (entry != transition):
1142
1143 Allocate(Heap, entry, Overlay_dict)
1144
1145 ###################################### Now we only have to account for allocating things from spawners
1146
1147
1148 """
1149
1150 NOTE: THIS DOES NOT HANDLE SPAWNERS OTHER THAN RUPEE CLUSTERS AT THE MOMENT
1151
1152 In the future, it will need to be considered how the actors created by spawners
1153 prioritize over each other... Spring MV is maybe the only place where this really matters
1154
1155 """
1156
1157 ##### Check for Rupee Cluster
1158 if Overlay_In_Heap(Heap, Overlay_dict['00E8']) == True:
1159
1160 for j in range(7):
1161 rupee = Actor(name='Collectible (Rupee from Rupee Cluster)', Id='000E', size=424, category=0, overlay_type='B', unloadable=True, address=0, room_number=room.number, priority=j, from_spawner=True, transition=False, clearable=True, cleared=False)
1162
1163 Allocate(Heap, rupee, Overlay_dict)
1164
1165
1166
1167
1168
1169def Display_Heap(Heap):
1170
1171 for entry in Heap:
1172
1173 if type(entry) == Node:
1174
1175 print(hex(entry.address) + '-----' + 'NODE-----------------')
1176
1177 elif type(entry) == Overlay:
1178
1179 print(hex(entry.address) + ' ' + entry.Id + ' ' + 'OVERLAY')
1180
1181 elif type(entry) == Actor:
1182
1183 print(hex(entry.address) + ' ' + entry.Id + ' ' + 'INSTANCE')
1184
1185 else:
1186 print("ERROR!!! Unexpected Entry Type in Heap!!!!!!!!!")
1187
1188
1189###############################################################################
1190###############################################################################
1191###############################################################################
1192###############################################################################
1193###############################################################################
1194###############################################################################
1195
1196def Allocate_Fish(Heap, Room_Number, Overlay_dict):
1197
1198 Fish = Actor(name='Fish', Id='0017', size=636, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1199
1200 Allocate(Heap, Fish, Overlay_dict)
1201
1202
1203def Allocate_Bugs(Heap, Room_Number, Overlay_dict):
1204
1205 """
1206
1207 This function allocates a set of 3 bugs to the Heap
1208
1209 """
1210
1211 for i in range(3):
1212 Bug = Actor(name='Bug', Id='017B', size=884, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=i, from_spawner=False, transition=False, clearable=False, cleared=False)
1213
1214 Allocate(Heap, Bug, Overlay_dict)
1215
1216
1217def Allocate_Bomb(Heap, Room_Number, Overlay_dict):
1218
1219 Bomb = Actor(name='Bomb', Id='0009', size=516, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1220
1221 Allocate(Heap, Bomb, Overlay_dict)
1222
1223
1224def Allocate_Smoke(Heap, Room_Number, Overlay_dict):
1225
1226 """
1227
1228 This function allocates a bomb, then allocates smoke (this happens when the bomb explodes)
1229 and then deallocates the bomb (we bothered allocating the bomb to ensure that the smoke
1230 appears in the right spot in the Heap)
1231
1232 Note that we should never allow ourselves to allocate smoke AFTER calling Allocate_Bomb()
1233 because in reality the first bomb would explode first (this isn't strictly true, but we should
1234 do it this way at least in the simple script)
1235
1236 """
1237
1238 Bomb = Actor(name='Bomb', Id='0009', size=516, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1239
1240 Allocate(Heap, Bomb, Overlay_dict)
1241
1242 Smoke = Actor(name='Smoke', Id='00A2', size=11908, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1243
1244 Allocate(Heap, Smoke, Overlay_dict)
1245
1246 Deallocate(Heap, Bomb, Overlay_dict)
1247
1248def Allocate_Arrow(Heap, Room_Number, Overlay_dict):
1249
1250 """
1251
1252 This function allocates an arrow into the heap. Note that Deku Bubbles are
1253 the same actor as arrows (in that they're both 000F)
1254
1255 """
1256
1257 Arrow = Actor(name='Arrow', Id='000F', size=632, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1258
1259 Allocate(Heap, Arrow, Overlay_dict)
1260
1261
1262def Allocate_Hookshot(Heap, Room_Number, Overlay_dict):
1263
1264 Hookshot = Actor(name='Hookshot', Id='003D', size=528, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1265
1266 Allocate(Heap, Hookshot, Overlay_dict)
1267
1268
1269def Allocate_Chu(Heap, Room_Number, Overlay_dict):
1270
1271 Chu = Actor(name='Chu', Id='006A', size=480, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1272
1273 Allocate(Heap, Chu, Overlay_dict)
1274
1275
1276def Allocate_Zora_Fins(Heap, Room_Number, Overlay_dict):
1277
1278 """
1279
1280 This function allocates 2 Zora Fin actor instances
1281
1282 """
1283
1284 for i in range(2):
1285
1286 Zora_Fin = Actor(name='Zora Fin', Id='0020', size=500, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1287
1288 Allocate(Heap, Zora_Fin, Overlay_dict)
1289
1290
1291def Allocate_Charged_Spin_Attack(Heap, Room_Number, Overlay_dict):
1292
1293 """
1294
1295 This functions allocates the Spin Attack & Sword Beam Effects and then the
1296 Spin Attack Charge Particles (This is the order they get allocated in when
1297 you charge a spin attack)
1298
1299 """
1300
1301 Spin_Attack_and_Sword_Beam_Effects = Actor(name='Spin Attack & Sword Beam Effects', Id='0035', size=452, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1302
1303 Allocate(Heap, Spin_Attack_and_Sword_Beam_Effects, Overlay_dict)
1304
1305 Spin_Attack_Charge_Particles = Actor(name='Spin Attack Charge Particles', Id='007B', size=1367, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1306
1307 Allocate(Heap, Spin_Attack_Charge_Particles, Overlay_dict)
1308
1309
1310
1311
1312def Allocate_Gold_Skulltula_With_Hookshot(Heap, Room_Number, Overlay_dict):
1313
1314 """
1315
1316 This function allocates a gold skulltula (for example, if you shoot a skull-
1317 kid painting that reveals a gold skulltula, it allocates a gold skulltula)
1318
1319 It first allocates an hookshot, then the gold skulltula, then deallocates the hookshot
1320
1321 THIS FUNCTION HARDCODES THE PRIORITY OF THE GOLD SKULLTULA TO BE 5 BECAUSE
1322 I ONLY CARE ABOUT ROOM 3 OF OCEANSIDE SPIDERHOUSE
1323
1324 """
1325
1326 Gold_Skulltula = Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=5, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=5, from_spawner=False, transition=False, clearable=True, cleared=False)
1327
1328 if Gold_Skulltula.room_number != 3:
1329 print("ERROR: Gold_Skulltula has room_number != 3 ?????? (Allocate_Gold_Skulltula() Error Message)")
1330
1331
1332 Hookshot = Actor(name='Hookshot', Id='003D', size=528, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1333
1334 Allocate(Heap, Hookshot, Overlay_dict)
1335
1336 Allocate(Heap, Gold_Skulltula, Overlay_dict)
1337
1338 Deallocate(Heap, Hookshot, Overlay_dict)
1339
1340
1341def Allocate_Gold_Skulltula_With_Arrow(Heap, Room_Number, Overlay_dict):
1342
1343 """
1344
1345 This function allocates a gold skulltula (for example, if you shoot a skull-
1346 kid painting that reveals a gold skulltula, it allocates a gold skulltula)
1347
1348 It first allocates an arrow, then the gold skulltula, then deallocates the arrow
1349
1350 THIS FUNCTION HARDCODES THE PRIORITY OF THE GOLD SKULLTULA TO BE 5 BECAUSE
1351 I ONLY CARE ABOUT ROOM 3 OF OCEANSIDE SPIDERHOUSE
1352
1353 """
1354
1355 Gold_Skulltula = Actor(name='Gold Skulltula', Id='0050', size=0x4A4, category=5, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=5, from_spawner=False, transition=False, clearable=True, cleared=False)
1356
1357 if Gold_Skulltula.room_number != 3:
1358 print("ERROR: Gold_Skulltula has room_number != 3 ?????? (Allocate_Gold_Skulltula() Error Message)")
1359
1360
1361 Arrow = Actor(name='Arrow', Id='000F', size=632, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1362
1363 Allocate(Heap, Arrow, Overlay_dict)
1364
1365 Allocate(Heap, Gold_Skulltula, Overlay_dict)
1366
1367 Deallocate(Heap, Arrow, Overlay_dict)
1368
1369
1370def Kill_Gold_Skulltula(Heap, Gold_Skulltula, Room_Number, Overlay_dict):
1371
1372 """
1373
1374 TODO: can implement this for more oceanside possibilties
1375
1376 This function kills a gold skulltula to spawn a gold skulltula token
1377 WITHOUT using something that spawns an actor (like hookshot or an arrow)
1378
1379
1380 it matters how you kill it because the token needs to allocate (hookshot, arrow, sword, fins)
1381
1382 """
1383
1384 if Gold_Skulltula.Id != '0050':
1385 print("ERROR: Gold_Skulltula is not actually a gold skulltula (Kill_Gold_Skulltula() Error Message)")
1386
1387 Gold_Skulltula_Token = Actor(name='Gold Skulltula Token', Id='00E3', size=0x1A0, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=Gold_Skulltula.priority, from_spawner=False, transition=False, clearable=True, cleared=False)
1388
1389 Allocate(Heap, Gold_Skulltula_Token, Overlay_dict)
1390
1391 Deallocate(Heap, Gold_Skulltula, Overlay_dict)
1392
1393
1394def Kill_Gold_Skulltula_With_Hookshot(Heap, Gold_Skulltula, Room_Number, Overlay_dict):
1395
1396 """
1397
1398 TODO: can implement this for more oceanside possibilties
1399
1400 This function kills a gold skulltula to spawn a gold skulltula token with hookshot
1401
1402
1403 it matters how you kill it because the token needs to allocate (hookshot, arrow, sword, fins)
1404
1405 """
1406
1407 if Gold_Skulltula.Id != '0050':
1408 print("ERROR: Gold_Skulltula is not actually a gold skulltula (Kill_Gold_Skulltula_With_Hookshot() Error Message)")
1409
1410 Gold_Skulltula_Token = Actor(name='Gold Skulltula Token', Id='00E3', size=0x1A0, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=Gold_Skulltula.priority, from_spawner=False, transition=False, clearable=True, cleared=False)
1411
1412 Hookshot = Actor(name='Hookshot', Id='003D', size=528, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1413
1414 Allocate(Heap, Hookshot, Overlay_dict)
1415
1416 Allocate(Heap, Gold_Skulltula_Token, Overlay_dict)
1417
1418 Deallocate(Heap, Gold_Skulltula, Overlay_dict)
1419
1420 Deallocate(Heap, Hookshot, Overlay_dict)
1421
1422
1423def Kill_Gold_Skulltula_With_Arrow(Heap, Gold_Skulltula, Room_Number, Overlay_dict):
1424
1425 """
1426
1427 TODO: can implement this for more oceanside possibilties
1428
1429 This function kills a gold skulltula to spawn a gold skulltula token with hookshot
1430
1431
1432 it matters how you kill it because the token needs to allocate (hookshot, arrow, sword, fins)
1433
1434 """
1435
1436 if Gold_Skulltula.Id != '0050':
1437 print("ERROR: Gold_Skulltula is not actually a gold skulltula (Kill_Gold_Skulltula_With_Arrow() Error Message)")
1438
1439 Gold_Skulltula_Token = Actor(name='Gold Skulltula Token', Id='00E3', size=0x1A0, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=Gold_Skulltula.priority, from_spawner=False, transition=False, clearable=True, cleared=False)
1440
1441 Arrow = Actor(name='Arrow', Id='000F', size=632, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
1442
1443 Allocate(Heap, Arrow, Overlay_dict)
1444
1445 Allocate(Heap, Gold_Skulltula_Token, Overlay_dict)
1446
1447 Deallocate(Heap, Gold_Skulltula, Overlay_dict)
1448
1449 Deallocate(Heap, Arrow, Overlay_dict)
1450
1451
1452
1453"""
1454
1455Before proceeding, we should define all of the transitions we plan on passing through
1456
1457Since "Beneath the Graveyard" is relatively simple and I currently only want to consider
1458passing through a single plane, I will just define Plane_1 to be the plane shared between
1459Room0 and Room1
1460
1461This loading plane happens the be the second element in Room0_queue, so I will define it based on that
1462
1463"""
1464
1465Plane_1 = Room0_queue[1]
1466
1467
1468Transition_List= [Plane_1]
1469
1470
1471"""
1472
1473 Grabbable_dict is a dictionary of the grabbable actors (such as pots) that
1474 we want to attempt to use for superslide SRM where the keys are the grabbable
1475 actors and the values are lists with 3-bit strings where each bit means:
1476
1477 100 : Possible to enter Plane with both Bomb and Smoke loaded
1478 010 : Possible to enter Plane with Smoke loaded, but no Bomb loaded
1479 001 : Possible to enter Plane with no Smoke loaded
1480
1481 and Transitions, where the transitions are the ones you can superslide through
1482
1483
1484
1485"""
1486
1487Grabbable_dict = {
1488 Room0_queue[6] : ['100', Plane_1],
1489 Room0_queue[7] : ['100', Plane_1],
1490 Room1_queue[25] : ['110', Plane_1],
1491 Room1_queue[26] : ['100', Plane_1],
1492 Room1_queue[27] : ['011', Plane_1]
1493 }
1494
1495
1496"""
1497
1498Below this we can consider a sequence of Room loads and then display the Heap
1499
1500"""
1501
1502
1503#Load_Scene(Heap, Room0)
1504
1505
1506#Load_Room(Heap, Room1, Plane_1, Overlay_dict)
1507
1508#Load_Room(Heap, Room0, Plane_1, Overlay_dict)
1509
1510#Load_Room(Heap, Room1, Plane_1, Overlay_dict)
1511
1512#Load_Room(Heap, Room0, Plane_1, Overlay_dict)
1513
1514
1515#Display_Heap(Heap)
1516
1517###############################################################################
1518###############################################################################
1519###############################################################################
1520###############################################################################
1521###############################################################################
1522###############################################################################
1523
1524
1525def Grabbable_In_Room(room, grabbable_actor_list):
1526
1527 """
1528
1529 This function checks the inputted room to see if it contains a grabbale actor
1530 that we can use for the superslide for SRM (in theory at least...)
1531
1532 """
1533
1534 grabbable_in_room = False
1535
1536 for actor in room.priority_queue:
1537
1538 if type(actor) == Actor and actor.Id in grabbable_actor_list:
1539
1540 grabbable_in_room = True
1541
1542 return grabbable_in_room
1543
1544
1545def Valid_Grabbable_In_Room(room, grabbable_actor_dict):
1546
1547 """
1548
1549 This function checks the inputted room to see if it contains a grabbale actor
1550 that we can use for the superslide for SRM
1551
1552 """
1553
1554 valid_grabbable_in_room = False
1555
1556 for actor in room.priority_queue:
1557
1558 if actor in grabbable_actor_dict.keys():
1559
1560 valid_grabbable_in_room = True
1561
1562 return valid_grabbable_in_room
1563
1564
1565def Chest_In_Room(room):
1566
1567 """
1568
1569 This function checks the inputted room to see if it contains a chest
1570
1571 """
1572
1573 chest_in_room = False
1574
1575 for actor in room.priority_queue:
1576
1577 if type(actor) == Actor and actor.Id == '0006':
1578
1579 chest_in_room = True
1580
1581 return chest_in_room
1582
1583
1584def Deku_Guard_In_Room(room):
1585
1586 """
1587
1588 This function checks the inputted room to see if it contains a Deku Guard
1589
1590 """
1591
1592 deku_guard_in_room = False
1593
1594 for actor in room.priority_queue:
1595
1596 if type(actor) == Actor and actor.Id == '017A':
1597
1598 deku_guard_in_room = True
1599
1600 return deku_guard_in_room
1601
1602
1603def Transition_List(room):
1604
1605 """
1606
1607 This function takes a room as input and returns a list of all of its transitions
1608 (i.e. doors/loading planes that lead to other rooms)
1609
1610 """
1611
1612 transition_list = []
1613
1614 for actor in room.priority_queue:
1615
1616 if actor.transition != False:
1617
1618 transition_list.append(actor)
1619
1620 return transition_list
1621
1622
1623def Shared_Transitions(room1, room2):
1624
1625 """
1626
1627 This function takes two Rooms as input and returns a list of their shared transitions
1628 (essentially returns the edges connecting these rooms if we view the rooms are nodes
1629 in a graph)
1630
1631 """
1632
1633 shared_transitions = []
1634
1635 for transition in Transition_List(room1):
1636
1637 if Is_Shared_Transition(transition, room1.number, room2.number) == True:
1638
1639 shared_transitions.append(transition)
1640
1641 return shared_transitions
1642
1643
1644def Shared_Transition_Exists(room1, room2):
1645
1646 """
1647
1648 This function takes two Rooms as input and returns True if they share a transition
1649 and False otherwise
1650
1651 """
1652
1653 shared_transition_exists = False
1654
1655 for transition in Transition_List(room1):
1656
1657 if Is_Shared_Transition(transition, room1.number, room2.number) == True:
1658
1659 shared_transition_exists = True
1660
1661 return shared_transition_exists
1662
1663
1664def Neighbors(room, Room_List):
1665
1666 """
1667
1668 This function takes a room as input along with a list of all potential rooms
1669 and returns a list of all rooms that share a transition with this room (excluding itself)
1670
1671 """
1672
1673 neighbors = []
1674
1675 for ROOM in Room_List:
1676
1677 if ROOM != room and Shared_Transition_Exists(room, ROOM) == True:
1678
1679 neighbors.append(ROOM)
1680
1681 return neighbors
1682
1683
1684def New_Room(room, transition, Room_List):
1685
1686 """
1687
1688 This function takes a room, a transition, and a list of all available rooms
1689 as input and returns the room that you would be in if you started in room
1690 and passed through transition
1691
1692 """
1693
1694 if transition not in Transition_List(room):
1695 print("ERROR: Invalid input into New_Room() function; transition is not in room")
1696
1697 for ROOM in Room_List:
1698
1699 if ROOM != room and (transition.transition[0] == ROOM.number or transition.transition[1] == ROOM.number) and ROOM.number != room.number:
1700
1701 new_room = ROOM
1702
1703 return new_room
1704
1705
1706def Current_Room(Room_Load_Permutation, Room_List):
1707
1708 """
1709
1710 Room_Load_Permutation is a list whose first element is the initial room that is started at
1711
1712 All subsequent entries are transitions (Actor class objects with transition != False)
1713
1714
1715 Room_List is a list of all available Rooms
1716
1717
1718 This function returns what Room you would be in after entering every transition listed in
1719 the permutation, assuming that you start in the initial room
1720
1721 """
1722
1723 if type(Room_Load_Permutation[0]) != Room:
1724 print("ERROR: no initial room in permutation (Current_Room() function error message)")
1725
1726 current_room = Room_Load_Permutation[0]
1727
1728 if len(Room_Load_Permutation) > 1:
1729
1730 for transition in Room_Load_Permutation[1:len(Room_Load_Permutation)]:
1731
1732 current_room = New_Room(current_room, transition, Room_List)
1733
1734 return current_room
1735
1736
1737def Room_Order_List(Room_Load_Permutation, Room_List):
1738
1739 """
1740
1741 Room_Load_Permutation is a list whose first element is the initial room that is started at
1742
1743 All subsequent entries are transitions (Actor class objects with transition != False)
1744
1745
1746 Room_List is a list of all available Rooms
1747
1748
1749 This function returns a list of what Room you would be in at each step of
1750 entering transitions
1751
1752 """
1753
1754 if type(Room_Load_Permutation[0]) != Room:
1755 print("ERROR: no initial room in permutation (Get_Room_Load_List() function error message)")
1756
1757 room_order_list = []
1758
1759 for i in range(0, len(Room_Load_Permutation)):
1760
1761 current_room = Current_Room(Room_Load_Permutation[0:i+1], Room_List)
1762
1763 room_order_list.append(current_room)
1764
1765 return room_order_list
1766
1767
1768def Generate_Room_Load_Permutations(Initial_Room, Room_List, Max_Transition_Count):
1769
1770 """
1771
1772 TODO: Debug this function... try calling: Generate_Room_Load_Permutations(Room0, Room_List, 1)
1773
1774
1775 This function seems to run for now, but it is untested for when we have multiple planes
1776 I will test this once I do Deku Palace input
1777
1778 """
1779
1780 """
1781
1782 This function takes as input the initial room (Initial_Room) that the scene was loaded in
1783 the list of all Rooms we want to consider visiting (Room_List), and Max_Transition_Count
1784 which is the maximum number of times we want to allow ourselves to load a new room
1785
1786 This function returns a list of all permutations of ways to enter new rooms after starting
1787 from the initial room (while limiting the number of room loads we do to be exactly Max_Transition_Count)
1788 where each permutation is a list in the form [Initial_Room, Transition1, Transition2, Transition3, ..., TransitionX]
1789 for X = Max_Transition_Count (so to get all permutations for X <= Max_Transition_Count, just
1790 use a for loop and call this function in each iteration of the foor loop and concatenate the lists)
1791
1792 """
1793
1794 if Max_Transition_Count == 0:
1795
1796 new_permutation_list = [[Initial_Room]]
1797
1798 return new_permutation_list
1799
1800
1801 else:
1802
1803 new_permutation_list = []
1804 permutation_list = Generate_Room_Load_Permutations(Initial_Room, Room_List, Max_Transition_Count - 1)
1805
1806 for permutation in permutation_list:
1807 for room in Neighbors(Current_Room(permutation, Room_List), Room_List):
1808 for transition in Shared_Transitions(Current_Room(permutation, Room_List), room):
1809 new_permutation = copy(permutation)
1810 new_permutation.append(transition)
1811 #permutation_list.append(new_permutation)
1812 new_permutation_list.append(new_permutation)
1813
1814 return new_permutation_list
1815
1816
1817def Generate_All_Room_Load_Permutations(Initial_Room, Room_List, Max_Transition_Count):
1818
1819 """
1820
1821 This function returns all permutations of ways to load a room starting from the initial room
1822 where the number of room loads is <= Max_Transition_Count
1823
1824 """
1825
1826 permutation_list = []
1827
1828 for N in range(Max_Transition_Count):
1829
1830 new_permutation_list = Generate_Room_Load_Permutations(Initial_Room, Room_List, N)
1831 permutation_list = permutation_list + new_permutation_list
1832
1833 return permutation_list
1834
1835
1836def Generate_Almost_All_Room_Load_Permutations(Initial_Room, Room_List, Max_Transition_Count):
1837
1838 """
1839
1840 This function returns all permutations of ways to load a room starting from the initial room
1841 where the number of room loads is <= Max_Transition_Count
1842
1843 this will always output a list with length at least 2, which is why it is different
1844 from Generate_All_Room_Load_Permutations
1845
1846 """
1847
1848 permutation_list = []
1849
1850 for N in range(1, Max_Transition_Count):
1851
1852 new_permutation_list = Generate_Room_Load_Permutations(Initial_Room, Room_List, N)
1853 permutation_list = permutation_list + new_permutation_list
1854
1855 return permutation_list
1856
1857
1858def Generate_All_Room_Order_Lists(Initial_Room, Room_List, Max_Transition_Count):
1859
1860 """
1861
1862 This function returns all permutations of ways to traverse through rooms, starting
1863 from the initial room where the number of room loads is <= Max_Transition_Count
1864
1865 The distinction between this and Generate_All_Room_Load_Permutations is that
1866 this will, instead of listing transitions, list the Room you're currently in
1867 at each step
1868
1869 """
1870
1871 room_order_permutation_list = []
1872
1873 room_load_permutation_list = Generate_All_Room_Load_Permutations(Initial_Room, Room_List, Max_Transition_Count)
1874
1875
1876 iteration_count = 0
1877 for room_load_permutation in room_load_permutation_list:
1878
1879 print("Generate_All_Room_Order_Lists: %d out of %d" %(iteration_count, len(room_load_permutation_list)))
1880 iteration_count += 1
1881
1882 room_order_list = Room_Order_List(room_load_permutation, Room_List)
1883
1884 room_order_permutation_list.append(room_order_list)
1885
1886 return room_order_permutation_list
1887
1888
1889def Generate_Allocation_Permutations(allocation_list):
1890
1891 """
1892
1893 Whatever, I'm just hardcoding a list of all of the actor names I want to allow
1894 and then using itertools to make a list of all of the permutations
1895
1896 """
1897
1898 """
1899
1900 TODO: Finish this function, also generalize it in the future
1901
1902 """
1903
1904 """
1905
1906 THIS FUNCTION IS SIMPLIFIED AT THE MOMENT AND COULD BE IMPROVED TO GENERATE
1907 EVEN MORE POSSIBLE PERMUTATIONS
1908
1909 allocation_list is a list of strings of things to allocate
1910
1911 for example:
1912
1913 allocation_list = [
1914 'Nothing',
1915 'Bomb',
1916 'Smoke',
1917 'Arrow',
1918 'Hookshot',
1919 'Charged Spin Attack',
1920 'Chu',
1921 'Zora Fins',
1922 'Fish',
1923 'Bugs'
1924 ]
1925
1926 """
1927
1928 allocation_permutation_list = []
1929
1930
1931 for i in range(len(allocation_list) + 1):
1932
1933 print("Generate_Allocation_Permutations: %d out of %d" %(i, len(allocation_list)))
1934
1935
1936 Permutations = list(itertools.permutations(allocation_list, i))
1937
1938 allocation_permutation_list = allocation_permutation_list + Permutations
1939
1940 return allocation_permutation_list
1941
1942
1943def Clear_Instances(actor_id, room):
1944
1945 """
1946
1947 This function takes an actor_id and room as input and sets actor.cleared = True
1948 for all actors with actor.id == actor_id in room
1949
1950 Call this before loading the scene or anything if you want some specific
1951 actor cleared already. For example, I'd call Clear_Instances('015B', Room1)
1952 to clear all of the bad bats in Beneath the Graveyard
1953
1954 """
1955
1956 for actor in room.priority_queue:
1957
1958 if actor.Id == actor_id and actor.clearable == True:
1959
1960 actor.cleared = True
1961
1962
1963def Clear_Instance(actor, room):
1964
1965 """
1966
1967 This function takes a specific actor in a room as input and sets
1968 actor.cleared = True
1969
1970 """
1971
1972 if actor.clearable == True:
1973
1974 actor.cleared = True
1975
1976
1977def Generate_Deallocation_Combinations(room):
1978
1979 """
1980 ##### Note: we actually get combinations instead of permutations because
1981 the order in which we deallocate actors doesn't matter
1982
1983 This function returns a list of combinations (stored as tuples of Actors)
1984
1985
1986
1987 Some things this (or maybe some other) function needs to account for:
1988
1989 if any rupee from a rupee cluster is deallocated in a deallocation step,
1990 then clear the rupee cluster actor instance (00E8) [note that there is
1991 at most one rupee cluster instance in every room in the game, so there is
1992 no need to check which cluster the rupees are associated with]
1993
1994 if all bad bats are deallocated on the same deallocation step, then they
1995 must all be cleared... actually, stronger: if all Category 5 actors with
1996 the same Id in a given room are deallocated on the same deallocation step,
1997 then clear all instances... actually this isn't good enough (need to add
1998 this into the input I believe or just treat bad bats as a special case)
1999
2000
2001 """
2002
2003 deallocation_list = []
2004
2005 for actor in room.priority_queue:
2006
2007 if actor.cleared == False and actor.unloadable == True:
2008
2009 deallocation_list.append(actor)
2010
2011 ##### Now we have a list of all actors in room that we have the option of deallocationg
2012
2013 ##### Now want want to generate a list of permutations
2014 ########## ACTUALLY, order doesn't matter for deallocation, so all combinations suffices
2015
2016 combination_list = []
2017
2018 for i in range(len(deallocation_list) + 1):
2019
2020 Combinations = list(itertools.combinations(deallocation_list, i))
2021
2022 combination_list = combination_list + Combinations
2023
2024 return combination_list
2025
2026
2027
2028
2029def Build_Room_Deallocation_Combination_Graph(room_order_list):
2030
2031
2032 """
2033
2034 This function takes a room_order_list as input (that is, a list in the form
2035 [initial_room, Room1, Room2, Room3, ..., RoomN] which describes the order we
2036 visit rooms in (note that Roomi could be equal to Roomj even for i =/= j)) and
2037 returns a dictionary where the keys are vertices whose values are lists of the
2038 other vertices that they are connected to. Each vertex represents a deallocation
2039 combination for the room that it corresponds to.
2040
2041 If the edges are directed, then this can be viewed as a multitree with some
2042 dummy root vertex and then each generation corresponds to a Room.
2043
2044 """
2045
2046 room_count = 0
2047
2048 #### Encode a dummy root node to make finding paths easier
2049 graph = {('root', room_count - 1) : []}
2050
2051
2052 iteration_count = 0
2053 ### for all rooms except for the last one
2054 for room in room_order_list[0:len(room_order_list)-1]:
2055
2056 print("Build_Room_Deallocation_Combination_Graph: %d out of %d" %(iteration_count, len(room_order_list) - 1))
2057 iteration_count += 1
2058
2059 combination_list = Generate_Deallocation_Combinations(room)
2060
2061 for combination in combination_list:
2062
2063 for key in graph.keys():
2064
2065 ### If the key is from the previous generation, then append every combination to its list
2066 if key[1] == room_count - 1:
2067
2068 graph[key].append(combination)
2069
2070 graph[(combination, room_count)] = []
2071
2072 room_count += 1
2073
2074 return graph
2075
2076
2077def Find_Leaves(graph):
2078
2079 """
2080
2081 This function takes a graph (really a dictionary) created by Build_Room_Deallocation_Combination_Graph()
2082 and returns a list of all of its leaves
2083
2084 """
2085
2086 leaf_list = []
2087
2088 for key in graph:
2089 # only leaves will point to empty lists
2090 if graph[key] == []:
2091 leaf_list.append(key)
2092
2093 return leaf_list
2094
2095
2096def Find_All_Paths(graph, start, end, path=[]):
2097
2098 """
2099
2100 This function takes a graph (really a dictionary) and start and end vertices
2101 as input and returns a list of all paths from start to end
2102
2103 TODO: maybe don't rely on hardcoding what the root's key is and instead write
2104 a function to find it (though hardcode is prob faster if you don't make mistakes)
2105
2106 I will use this to find all paths from ('root', -1) [note that I am hardcoding
2107 this instead of just finding a root without any parent] to a given lead, and
2108 I will do this for all leafs (which I can get by doing Find_Leaves(graph))
2109
2110 """
2111
2112
2113 path = path + [start]
2114 if start == end:
2115 return [path]
2116 if not (start in graph):
2117 return []
2118 paths = []
2119 for vertex in graph[start]:
2120 if vertex not in path:
2121 newpaths = Find_All_Paths(graph, vertex, end, path)
2122 for newpath in newpaths:
2123 paths.append(newpath)
2124 return paths
2125
2126
2127def Find_All_Deallocation_Combination_Paths(graph):
2128
2129 """
2130
2131 TODO: Note that I hardcode what the key of the root vertex is: ('root', -1)
2132
2133 This returns a list of all (n-1)-permutations of deallocation combinations
2134 for a given room_order_list (where we assume there are n rooms we travel to
2135 including the initial room). This gives us the thing we called D1
2136
2137 """
2138
2139 all_deallocation_combination_paths = []
2140
2141 leaf_list = Find_Leaves(graph)
2142
2143 iteration_count = 0
2144 for leaf in leaf_list:
2145
2146 print("Find_All_Deallocation_Combination_Paths: %d out of %d" %(iteration_count, len(leaf_list)))
2147 iteration_count += 1
2148
2149 # I hardcode the root key to be ('root', -1)
2150 path_to_leaf = Find_All_Paths(graph, ('root', -1), leaf)
2151
2152 all_deallocation_combination_paths = all_deallocation_combination_paths + path_to_leaf
2153
2154
2155 ##### Since every key is a tuple in the form (combination, number), get rid of number part
2156 for path in all_deallocation_combination_paths:
2157 for vertex in path:
2158 path[path.index(vertex)] = vertex[0]
2159
2160 return all_deallocation_combination_paths
2161
2162
2163
2164
2165def Generate_Action_Permutations(room_order_list, allocation_list):
2166
2167 """
2168
2169 THIS IS THE FUNCTION THAT FINALLY GIVES US ALL OF THE PERMUTATIONS OF THINGS
2170 TO DO FOR A GIVEN room_order_list and the allocation_list.
2171
2172
2173
2174 WE WILL RUN THIS FUNCTION ON EVERY PERMUTATION OF ROOM ORDER LISTS USING
2175 Generate_All_Room_Order_Lists(Initial_Room, Room_List, Max_Transition_Count)
2176
2177
2178 ONCE WE DO THAT WE WILL HAVE EVERY SINGLE PERMUTATION THAT WE WANT TO TEST
2179
2180 """
2181
2182 allocation_permutations = Generate_Allocation_Permutations(allocation_list)
2183
2184 ##### Now we want all (n-1)-permutations of allocation permutations
2185 A1 = list(itertools.permutations(allocation_permutations, len(room_order_list) - 1))
2186
2187 #### deallocation combination graph
2188 graph = Build_Room_Deallocation_Combination_Graph(room_order_list)
2189
2190 D1 = Find_All_Deallocation_Combination_Paths(graph)
2191
2192 ###########################################################################
2193
2194 # create output list o
2195 o = []
2196 for i in range(len(A1)):
2197
2198 print("Generate_Action_Permutations: %d out of %d" %(i, len(A1)))
2199
2200 for j in range(len(D1)):
2201 for b in range(2**(len(room_order_list) - 1)):
2202 # create new empty list p
2203 p = []
2204 for k in range(len(room_order_list) - 1):
2205 p.append(room_order_list[k])
2206
2207 if bin(b)[2:].zfill(len(room_order_list)-1) == 1:
2208
2209 # add each element of A1[i][k] to p
2210 for element in A1[i][k]:
2211 p.append(element)
2212 # add each element of D1[j][k] to p
2213 for element in D1[j][k]:
2214 p.append(element)
2215
2216 elif bin(b)[2:].zfill(len(room_order_list)-1) == 0:
2217
2218 # add each element of D1[j][k] to p
2219 for element in D1[j][k]:
2220 p.append(element)
2221 # add each element of A1[i][k] to p
2222 for element in A1[i][k]:
2223 p.append(element)
2224
2225 # Add the last room to p
2226 p.append(room_order_list[len(room_order_list)-1])
2227 # append p to o
2228 o = o + p
2229
2230 return o
2231
2232
2233
2234def Generate_Heap_Permutations(Initial_Room, Room_List, Max_Transition_Count, allocation_list):
2235
2236 """
2237
2238 This function takes the initial room, the Room List, the Maximum Number of Transitions
2239 that we want to allow, and the allocation list as input and returns every permutation
2240 for heap manip setups to try (possibilities currently mostly limited by allocation_list)
2241
2242 WE WILL USE THIS FUNCTION IN THE HEAP MANIP SOLVER
2243
2244 """
2245
2246 heap_permutations = []
2247
2248 All_Room_Order_Lists = Generate_All_Room_Order_Lists(Initial_Room, Room_List, Max_Transition_Count)
2249
2250 iteration_count= 0
2251 for room_order_list in All_Room_Order_Lists:
2252
2253 print("Iteration %d out of %d" %(iteration_count, len(All_Room_Order_Lists)))
2254
2255 action_permutations = Generate_Action_Permutations(room_order_list, allocation_list)
2256
2257 heap_permutations = heap_permutations + action_permutations
2258
2259 iteration_count += 1
2260
2261
2262 print("HEAP PERMUTATION GENERATION COMPLETE")
2263
2264 return heap_permutations
2265
2266
2267
2268###############################################################################
2269###############################################################################
2270###############################################################################
2271###############################################################################
2272###############################################################################
2273###############################################################################
2274###############################################################################
2275
2276def Actor_Is_In_Heap(Heap, actor):
2277
2278 """
2279
2280 actor is the Actor that we want to check for
2281
2282 This function will return True if this Actor is in the Heap and False otherwise
2283
2284 """
2285
2286 actor_is_in_heap = False
2287
2288 for entry in Heap:
2289
2290 if type(entry) == Actor and entry == actor:
2291
2292 actor_is_in_heap = True
2293
2294 return actor_is_in_heap
2295
2296def Actor_Is_In_Room(room, actor):
2297
2298 """
2299
2300 actor is the Actor that we want to check for
2301
2302 This function will return True if this Actor is in the room and False otherwise
2303
2304 """
2305
2306 actor_is_in_room = False
2307
2308 for entry in room.priority_queue:
2309
2310 if type(entry) == Actor and entry == actor:
2311
2312 actor_is_in_room = True
2313
2314 return actor_is_in_room
2315
2316
2317
2318def Bomb_And_Smoke_Superslide(Heap, Room_Number, Overlay_dict):
2319
2320 """
2321
2322 This function allocates a bomb, then allocates smoke (this happens when the bomb explodes)
2323
2324 """
2325
2326 Bomb = Actor(name='Bomb', Id='0009', size=516, category=0, overlay_type='B', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
2327
2328 Allocate(Heap, Bomb, Overlay_dict)
2329
2330 Smoke = Actor(name='Smoke', Id='00A2', size=11908, category=0, overlay_type='A', unloadable=True, address=0, room_number=Room_Number, priority=0, from_spawner=False, transition=False, clearable=False, cleared=False)
2331
2332 Allocate(Heap, Smoke, Overlay_dict)
2333
2334
2335
2336
2337
2338def Copy_Room_List(Room_List):
2339
2340 """
2341
2342 This function takes a list of all Rooms, Room_List, as input
2343 and returns a list of copies of all of the Rooms in Room_List
2344
2345 """
2346
2347 ##### First we want a list of all shared entries between the Room priority queues
2348
2349 shared_actor_list = []
2350
2351 for room1 in Room_List:
2352 for room2 in Room_List:
2353
2354 if room2 != room1:
2355
2356 for actor1 in room1.priority_queue:
2357 for actor2 in room2.priority_queue:
2358 if (actor1 == actor2) and (actor1 not in shared_actor_list):
2359
2360 shared_actor_list.append(actor1)
2361
2362 ##### Now make a list of copies of each entry of the above list
2363
2364 shared_actor_copy_list = []
2365 for actor in shared_actor_list:
2366 shared_actor_copy_list.append(copy(actor))
2367
2368 Room_List_Copy = []
2369
2370 for room in Room_List:
2371
2372 priority_queue_copy = []
2373
2374 for actor in room.priority_queue:
2375
2376 if actor not in shared_actor_list:
2377
2378 priority_queue_copy.append(copy(actor))
2379
2380 elif actor in shared_actor_list:
2381 append_count = 0
2382 for actor2 in shared_actor_copy_list:
2383
2384 # If all attributes of the actor and the copy are the same, then assume they are copies of each other
2385 if actor2.name == actor.name and actor2.Id == actor.Id and actor2.size == actor.size and actor2.category == actor.category and actor2.overlay_type == actor.overlay_type and actor2.unloadable == actor.unloadable and actor2.address == actor.address and actor2.room_number == actor.room_number and actor2.priority == actor.priority and actor2.from_spawner == actor.from_spawner and actor2.transition == actor.transition and actor2.clearable == actor.clearable and actor2.cleared == actor.cleared:
2386 # append the copy
2387 priority_queue_copy.append(actor2)
2388 append_count += 1
2389
2390 if append_count > 1:
2391 print("ERROR: There were two or more copies of the same Actor in shared_actor_copy_list (Copy_Room_List() error message)")
2392
2393
2394 room_copy = Room(number=room.number, priority_queue=priority_queue_copy, clock_exists=room.clock_exists, clock_priority=room.clock_priority)
2395
2396 Room_List_Copy.append(room_copy)
2397
2398 return Room_List_Copy
2399
2400
2401
2402
2403def Main_Actor_Attributes_Match(actor1, actor2):
2404
2405 """
2406
2407 This function returns True is the two Actors taken as input have the same
2408 values for all of their main attributes and False otherwise
2409
2410 the main attributes do not include things like "address" and such that can
2411 change as the state updates
2412
2413 """
2414
2415 main_actor_attributes_match = False
2416
2417 if actor1.name == actor2.name and actor1.Id == actor2.Id and actor1.size == actor2.size and actor1.category == actor2.category and actor1.overlay_type == actor2.overlay_type and actor1.unloadable == actor2.unloadable and actor1.room_number is actor2.room_number and actor1.priority is actor2.priority and actor1.from_spawner == actor2.from_spawner and actor1.transition == actor2.transition and actor1.clearable == actor2.clearable:
2418 main_actor_attributes_match = True
2419
2420 return main_actor_attributes_match
2421
2422
2423def Main_Overlay_Attributes_Match(overlay1, overlay2):
2424
2425 main_overlay_attributes_match = False
2426
2427 if overlay1.Id == overlay2.Id and overlay1.size == overlay2.size:
2428 main_overlay_attributes_match = True
2429
2430 return main_overlay_attributes_match
2431
2432
2433def Copy_Overlay_Dict(Overlay_Dict):
2434
2435 overlay_dict_copy = {}
2436
2437 for key in Overlay_Dict:
2438 overlay_dict_copy[key] = copy(Overlay_Dict[key])
2439
2440 return overlay_dict_copy
2441
2442
2443def Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy):
2444
2445 """
2446
2447 This function takes the Heap as input and returns a copy of the Heap where
2448 every actor copy in the Heap copy is the same class instance as each corresponding
2449 actor in the room list copy priority queues (same for Overlay_Dict_Copy)
2450
2451 """
2452
2453 Heap_Copy = []
2454
2455 for entry in Heap:
2456
2457 entry_allocated = False
2458 not_allocated_count = 0
2459 while entry_allocated is False:
2460
2461 if not_allocated_count > 4:
2462 print("UHHHHHHHHHHHHHHHHHHHHHHHH (Copy_Heap() Error Message)")
2463
2464 if type(entry) == Node:
2465
2466 Heap_Copy.append(copy(entry))
2467 entry_allocated = True
2468
2469 elif type(entry) == Overlay:
2470
2471 for key in Overlay_Dict_Copy:
2472 if Main_Overlay_Attributes_Match(Overlay_Dict_Copy[key], entry) == True:
2473 Heap_Copy.append(Overlay_Dict_Copy[key])
2474 entry_allocated = True
2475
2476 elif type(entry) == Actor:
2477
2478 allocated_count = 0
2479 for room in Room_List_Copy:
2480
2481 if entry_allocated == True:
2482 break
2483
2484 for actor in room.priority_queue:
2485
2486 if allocated_count > 1:
2487 print("ERROR: tried to allocate multiple copies (Copy_Heap() Error Message)")
2488
2489 if Main_Actor_Attributes_Match(entry, actor) == True:
2490 Heap_Copy.append(actor)
2491 allocated_count += 1
2492 entry_allocated = True
2493 break
2494
2495 # If it isn't in any of the priority queues, then it must be something you spawned
2496 if entry_allocated == False:
2497 Heap_Copy.append(copy(entry))
2498 entry_allocated = True
2499
2500 else:
2501 print("ERROR: entry in Heap is not an Actor, Node, or Overlay (Copy_Heap() error message)")
2502
2503 not_allocated_count += 1
2504 return Heap_Copy
2505
2506
2507def Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy):
2508
2509 """
2510
2511 This function takes the Grabbable_Dict as input and returns a copy of the it where
2512 each transition in it is a the same Actor class instance copy as the ones used in
2513 the priority queues of the Rooms in Room_List_Copy
2514
2515 """
2516
2517 grabbable_dict_copy = {}
2518
2519 for pot in Grabbable_Dict:
2520
2521 pot_in_dict = False
2522
2523
2524 for room in Room_List_Copy:
2525 if pot_in_dict == True:
2526 break
2527 for actor in room.priority_queue:
2528 if Main_Actor_Attributes_Match(pot, actor) == True:
2529
2530 key = actor
2531
2532 for room1 in Room_List_Copy:
2533 if pot_in_dict == True:
2534 break
2535 for actor1 in room1.priority_queue:
2536
2537 # Finding the transition
2538 if Main_Actor_Attributes_Match(Grabbable_Dict[pot][1], actor1):
2539
2540 grabbable_dict_copy[key] = [Grabbable_Dict[pot][0], actor1]
2541 pot_in_dict = True
2542
2543 return grabbable_dict_copy
2544
2545
2546def Find_Actor_Copy(actor, Room_List_Copy):
2547
2548 """
2549
2550 This function takes an Actor as input (actor) and a copy of the list of rooms
2551 (Room_List_Copy) and returns the copy of the inputted actor that is found in
2552 the priority queue of a Room in Room_List_Copy
2553
2554 """
2555
2556 actor_copy = None
2557
2558 copy_found = False
2559 for room in Room_List_Copy:
2560 if copy_found == True:
2561 break
2562 for actor1 in room.priority_queue:
2563 if Main_Actor_Attributes_Match(actor1, actor):
2564 actor_copy = actor1
2565 copy_found = True
2566 break
2567
2568 return actor_copy
2569
2570
2571"""
2572
2573TODO: Make the solver take the initial heap layout as input so that it is easy
2574to test successive heap manip setups in the future
2575
2576DO NOT FORGET TO CLEAR ALL OF THE BAD BATS IF YOU THINK THAT THAT IS SOMETHING
2577THAT YOU WANT TO DO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2578
2579ALSO IGNORE THAT FUNCTION BELOW, COMPLETELY REWRITE FROM SCRATCH BUT MAYBE READ
2580IT FIRST TO SEE IF IT REMINDS YOU OF ANY IDEAS YOU HAD
2581
2582"""
2583
2584
2585def Randomized_Solver(Initial_Room, Room_List, Max_Transition_Count, allocation_list_dict, Grabbable_Dict, Overlay_Dict, filename, Offset_List, Initial_Heap):
2586
2587 """
2588
2589 This function does not currently account for the possibility that you might need to break
2590 another pot in order to superslide off of a given pot. While this might not be strictly
2591 true for the pot we currently use in deku palace, it would be good at add more information
2592 to Grabbable_Dict to account for this
2593
2594 """
2595
2596 """
2597
2598 Okay, the Initial_Heap argument will not work as I initially intended because of things
2599 like rupee clusters being cleared, etc. So if I want to test a Heap from an initial Heap
2600 distribution, then I will have to hardcode it to perform the necessary steps to get to it each time
2601
2602 """
2603
2604 """
2605
2606 filename is the complete name (i.e. including the path) that we want to write to
2607
2608 This function will randomly choose solutions to test (it may have repeats)
2609
2610 Offset_List is a list of offsets that we want to check for. The grabbable object (e.g. a pot)
2611 will be first when calculating the offset. So if doing chest SRM, we want
2612 pot - chest = 0x160 or pot - chest = 0x1F0, so we want Offset_List = [0x160, 0x1F0]
2613 We make this Offset_List by default
2614
2615 Grabbable_dict is a dictionary of the grabbable actors (such as pots) that
2616 we want to attempt to use for superslide SRM where the keys are the grabbable
2617 actors and the values are 3-bit strings where each bit means:
2618
2619 100 : Possible to enter Plane with both Bomb and Smoke loaded
2620 010 : Possible to enter Plane with Smoke loaded, but no Bomb loaded
2621 001 : Possible to enter Plane with no Smoke loaded
2622
2623 """
2624
2625 angle_solution_count = 0
2626 position_solution_count = 0
2627 permutation_count = 0
2628
2629 ### Keep doing this forever (infinite loop so we keep trying new permutations)
2630 while True:
2631
2632 all_room_load_lists = Generate_Almost_All_Room_Load_Permutations(Initial_Room, Room_List, Max_Transition_Count)
2633
2634 for room_load_list in all_room_load_lists:
2635
2636 if permutation_count%500 == 0:
2637 print("%d Permutations Tested %d Angle Solutions %d Position Solutions" %(permutation_count, angle_solution_count, position_solution_count))
2638 permutation_count += 1
2639
2640 Heap = copy(Initial_Heap)
2641
2642 ##### Initialize the actor addresses and other attributes each time
2643
2644 for room in Room_List:
2645
2646 for actor in room.priority_queue:
2647
2648 actor.address = 0
2649 actor.cleared = False
2650
2651 ##### Clear all bad bats (optional, but I want to do this for beneath the graveyard)
2652 Clear_Instances('015B', room)
2653 ###################################################################
2654
2655 #####
2656 ##### Perform seuqence of steps here if you want to initialize your heap to something
2657 #####
2658
2659 # We will use this to collect things we do in the permutation to help output the solution
2660 action_list = []
2661
2662 room_count = 0
2663 # NOTE: the first "transition" is actually not a transition; it is the initial room
2664 for transition in room_load_list[0:len(room_load_list)-1]:
2665
2666 room = Current_Room(room_load_list[0:room_count + 1], Room_List)
2667
2668 # If this is the Initial_Room AND the Heap is empty, then we want to load the scene
2669 if (room_count is 0) and (len(Heap) == 2):
2670
2671 if room != Initial_Room:
2672 print("ERROR: first entry in room_load_list is not Initial_Room (Randomnized_Solver() Error Message)")
2673
2674 Load_Scene(Heap, Initial_Room, Overlay_Dict)
2675 action_list.append("Load Scene: Room %d" %(Initial_Room.number))
2676
2677 ##### NOW WE DO DEALLOCATION/ALLOCATION STEPS AFTER LOADING THE SCENE
2678
2679
2680 """
2681
2682 Now randomly (with some chosen distribution) choose things to allocate
2683 and/or things to deallocate (in your current room). Make it so that
2684 you can only choose a specific action once. For example, if allocation_list
2685 has ['bomb', 'bomb, 'bomb', 'fish'] in it, then make it so you can only use
2686 fish once, but you can use bomb 3 times
2687
2688 Somehow try to encode that hookshot/charged spin are mutually exclusive
2689 and that if either of them exist then they must be the last action
2690
2691 Allow yourself to deallocate things before allocating things even
2692 though it might be impossible or slow in some cases
2693
2694 """
2695
2696 # Do a coinflip to decide between allocating or deallocating first
2697 #decision_coin_flip = np.random.uniform(0,1)
2698 ##### Deterministically do deallocation step first
2699 decision_coin_flip = 0
2700
2701 # With probability 1/2, we allocate first and deallocate second
2702 # if we allocate first, don't allow 'Charged Spin Attack'
2703 if decision_coin_flip > .5:
2704
2705 explosive_count = 0
2706 droppable_count = 0
2707
2708 ##### ALLOCATION
2709 for action in allocation_list_dict[room.number]:
2710
2711 # whether or not we add an action is based off of this
2712 coin_flip = np.random.uniform(0,1)
2713
2714 if action == 'Smoke' and coin_flip > .5:
2715
2716 Allocate_Smoke(Heap, room.number, Overlay_Dict)
2717 action_list.append("Allocate: Smoke")
2718
2719 elif action == 'Chu' and coin_flip > .5 and explosive_count < 3:
2720
2721 Allocate_Chu(Heap, room.number, Overlay_Dict)
2722 action_list.append("Allocate: Chu")
2723 explosive_count += 1
2724
2725 elif action == 'Arrow' and coin_flip > .5:
2726
2727 Allocate_Arrow(Heap, room.number, Overlay_Dict)
2728 action_list.append("Allocate: Arrow")
2729
2730 elif action == 'Bomb' and coin_flip > .5 and explosive_count < 3:
2731
2732 Allocate_Bomb(Heap, room.number, Overlay_Dict)
2733 action_list.append("Allocate: Bomb")
2734 explosive_count += 1
2735
2736 elif action == 'Zora Fins' and coin_flip > .5:
2737
2738 Allocate_Zora_Fins(Heap, room.number, Overlay_Dict)
2739 action_list.append("Allocate: Zora Fins")
2740
2741 elif action == 'Fish' and coin_flip > .5 and droppable_count < 2:
2742
2743 Allocate_Fish(Heap, room.number, Overlay_Dict)
2744 action_list.append("Allocate: Fish")
2745 droppable_count += 1
2746
2747 elif action == 'Bugs' and coin_flip > .5 and droppable_count < 2:
2748
2749 Allocate_Bugs(Heap, room.number, Overlay_Dict)
2750 action_list.append("Allocate: Bugs")
2751 droppable_count += 1
2752
2753 elif action == 'Hookshot' and coin_flip > .5:
2754
2755 Allocate_Hookshot(Heap, room.number, Overlay_Dict)
2756 action_list.append("Allocate: Hookshot")
2757
2758 elif action == 'Gold Skulltula' and coin_flip > .5:
2759
2760 projectile_coin_flip = np.random.uniform(0,1)
2761
2762 if projectile_coin_flip > .5:
2763 Allocate_Gold_Skulltula_With_Hookshot(Heap, room.number, Overlay_Dict)
2764 action_list.append("Allocate: Gold Skulltula with Hookshot (hit painting)")
2765
2766 elif projectile_coin_flip <= .5:
2767 Allocate_Gold_Skulltula_With_Arrow(Heap, room.number, Overlay_Dict)
2768 action_list.append("Allocate: Gold Skulltula with Arrow (hit painting)")
2769
2770 ### We don't include 'Charged Spin Attack' in this
2771
2772 ##### DEALLOCATION
2773 for actor in room.priority_queue:
2774
2775 # whether or not we deallocate an actor is based off of this
2776 coin_flip = np.random.uniform(0,1)
2777
2778 ##### HARDCODE TO NOT ALLOW GOLD SKULLTULA OR SPIDER WEBS DEALLOCATE BECAUSE FASTER FOR 100%
2779 if actor.unloadable == True and Actor_Is_In_Heap(Heap, actor) == True and coin_flip > .5 and actor.Id != '0050' and actor.Id != '01F4' and actor.Id != '0125':
2780
2781
2782 if actor.Id == '00E8' or actor.name == 'Collectible (Rupee from Rupee Cluster)':
2783
2784 Deallocate(Heap, actor, Overlay_Dict)
2785 # There is at most one rupee cluster per room, so this is fine to clear it
2786 Clear_Instances('00E8', room)
2787 action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
2788
2789 # THESE PRIORITIES ARE HARDCODED FOR ROOM 3 OF OCEANSIDE!!!!!!!
2790 elif actor.Id == '01E7' and (actor.priority == 0 or actor.priority == 1 or actor.priority == 2):
2791
2792 table_bonk_deallocation_count = 0
2793 for entry in Heap:
2794 if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 0:
2795 Deallocate(Heap, entry, Overlay_Dict)
2796 table_bonk_deallocation_count += 1
2797
2798 for entry in Heap:
2799 if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 1:
2800 Deallocate(Heap, entry, Overlay_Dict)
2801 table_bonk_deallocation_count += 1
2802
2803 for entry in Heap:
2804 if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 2:
2805 Deallocate(Heap, entry, Overlay_Dict)
2806 table_bonk_deallocation_count += 1
2807
2808 if table_bonk_deallocation_count != 3:
2809 print("ERROR: table_bonk_deallocation_count is not 3 (Randomized_Solver() error)")
2810
2811 action_list.append("Deallocate: " + actor.name + " (Priority 0, 1, and 2) [Bonk Oceanside Table]")
2812
2813
2814 # if the actor is clearable AND isn't a bad bat, then clear it when deallocating it if it isn't already cleared
2815 elif actor.clearable == True and actor.cleared == False and actor.Id != '015B':
2816
2817 Deallocate(Heap, actor, Overlay_Dict)
2818 action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
2819 # CLEAR THE ACTOR
2820 Clear_Instance(actor, room)
2821
2822 else:
2823
2824 Deallocate(Heap, actor, Overlay_Dict)
2825 action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
2826
2827
2828 # With probability 1/2, we deallocate first and allocate second
2829 elif decision_coin_flip <= .5:
2830
2831 explosive_count = 0
2832 droppable_count = 0
2833 hookshot_exists = False
2834
2835 ##### DEALLOCATION
2836 for actor in room.priority_queue:
2837
2838 # whether or not we deallocate an actor is based off of this
2839 coin_flip = np.random.uniform(0,1)
2840
2841 ##### HARDCODE TO NOT ALLOW GOLD SKULLTULA OR SPIDER WEBS DEALLOCATE BECAUSE FASTER FOR 100%
2842 if actor.unloadable == True and Actor_Is_In_Heap(Heap, actor) == True and coin_flip > .5 and actor.Id != '0050' and actor.Id != '01F4' and actor.Id != '0125':
2843
2844
2845 if actor.Id == '00E8' or actor.name == 'Collectible (Rupee from Rupee Cluster)':
2846
2847 Deallocate(Heap, actor, Overlay_Dict)
2848 # There is at most one rupee cluster per room, so this is fine to clear it
2849 Clear_Instances('00E8', room)
2850 action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
2851
2852 # THESE PRIORITIES ARE HARDCODED FOR ROOM 3 OF OCEANSIDE!!!!!!!
2853 elif actor.Id == '01E7' and (actor.priority == 0 or actor.priority == 1 or actor.priority == 2):
2854
2855 table_bonk_deallocation_count = 0
2856 for entry in Heap:
2857 if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 0:
2858 Deallocate(Heap, entry, Overlay_Dict)
2859 table_bonk_deallocation_count += 1
2860
2861 for entry in Heap:
2862 if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 1:
2863 Deallocate(Heap, entry, Overlay_Dict)
2864 table_bonk_deallocation_count += 1
2865
2866 for entry in Heap:
2867 if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 2:
2868 Deallocate(Heap, entry, Overlay_Dict)
2869 table_bonk_deallocation_count += 1
2870
2871 if table_bonk_deallocation_count != 3:
2872 print("ERROR: table_bonk_deallocation_count is not 3 (Randomized_Solver() error)")
2873
2874 action_list.append("Deallocate: " + actor.name + " (Priority 0, 1, and 2) [Bonk Oceanside Table]")
2875
2876
2877 # if the actor is clearable AND isn't a bad bat, then clear it when deallocating it if it isn't already cleared
2878 elif actor.clearable == True and actor.cleared == False and actor.Id != '015B':
2879
2880 Deallocate(Heap, actor, Overlay_Dict)
2881 action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
2882 # CLEAR THE ACTOR
2883 Clear_Instance(actor, room)
2884
2885 else:
2886
2887 Deallocate(Heap, actor, Overlay_Dict)
2888 action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
2889
2890
2891 ##### ALLOCATION
2892 for action in allocation_list_dict[room.number]:
2893
2894 # whether or not we add an action is based off of this
2895 coin_flip = np.random.uniform(0,1)
2896
2897 if action == 'Smoke' and coin_flip > .5:
2898
2899 Allocate_Smoke(Heap, room.number, Overlay_Dict)
2900 action_list.append("Allocate: Smoke")
2901
2902 elif action == 'Chu' and coin_flip > .5 and explosive_count < 3:
2903
2904 Allocate_Chu(Heap, room.number, Overlay_Dict)
2905 action_list.append("Allocate: Chu")
2906 explosive_count += 1
2907
2908 elif action == 'Arrow' and coin_flip > .5:
2909
2910 Allocate_Arrow(Heap, room.number, Overlay_Dict)
2911 action_list.append("Allocate: Arrow")
2912
2913 elif action == 'Bomb' and coin_flip > .5 and explosive_count < 3:
2914
2915 Allocate_Bomb(Heap, room.number, Overlay_Dict)
2916 action_list.append("Allocate: Bomb")
2917 explosive_count += 1
2918
2919 elif action == 'Zora Fins' and coin_flip > .5:
2920
2921 Allocate_Zora_Fins(Heap, room.number, Overlay_Dict)
2922 action_list.append("Allocate: Zora Fins")
2923
2924 elif action == 'Fish' and coin_flip > .5 and droppable_count < 2:
2925
2926 Allocate_Fish(Heap, room.number, Overlay_Dict)
2927 action_list.append("Allocate: Fish")
2928 droppable_count += 1
2929
2930 elif action == 'Bugs' and coin_flip > .5 and droppable_count < 2:
2931
2932 Allocate_Bugs(Heap, room.number, Overlay_Dict)
2933 action_list.append("Allocate: Bugs")
2934 droppable_count += 1
2935
2936 elif action == 'Hookshot' and coin_flip > .5:
2937
2938 Allocate_Hookshot(Heap, room.number, Overlay_Dict)
2939 action_list.append("Allocate: Hookshot")
2940 hookshot_exists = True
2941
2942 elif action == 'Charged Spin Attack' and (hookshot_exists is False) and coin_flip > .5:
2943
2944 Allocate_Charged_Spin_Attack(Heap, room.number, Overlay_Dict)
2945 action_list.append("Allocate: Charged Spin Attack")
2946
2947 elif action == 'Gold Skulltula' and coin_flip > .5:
2948
2949 projectile_coin_flip = np.random.uniform(0,1)
2950
2951 if projectile_coin_flip > .5:
2952 Allocate_Gold_Skulltula_With_Hookshot(Heap, room.number, Overlay_Dict)
2953 action_list.append("Allocate: Gold Skulltula with Hookshot (hit painting)")
2954
2955 elif projectile_coin_flip <= .5:
2956 Allocate_Gold_Skulltula_With_Arrow(Heap, room.number, Overlay_Dict)
2957 action_list.append("Allocate: Gold Skulltula with Arrow (hit painting)")
2958
2959 else:
2960
2961 Load_Room(Heap, room, transition, Overlay_Dict)
2962
2963 action_list.append("Load Room: Room %d" %(room.number) + " with " + transition.name + " %d" %(transition.priority))
2964
2965 """
2966
2967 Now randomly (with some chosen distribution) choose things to allocate
2968 and/or things to deallocate (in your current room). Make it so that
2969 you can only choose a specific action once. For example, if allocation_list
2970 has ['bomb', 'bomb, 'bomb', 'fish'] in it, then make it so you can only use
2971 fish once, but you can use bomb 3 times
2972
2973 Somehow try to encode that hookshot/charged spin are mutually exclusive
2974 and that if either of them exist then they must be the last action
2975
2976 Allow yourself to deallocate things before allocating things even
2977 though it might be impossible or slow in some cases
2978
2979 """
2980
2981 # Do a coinflip to decide between allocating or deallocating first
2982 #decision_coin_flip = np.random.uniform(0,1)
2983 ##### Deterministically do deallocation step first
2984 decision_coin_flip = 0
2985
2986 # With probability 1/2, we allocate first and deallocate second
2987 # if we allocate first, don't allow 'Charged Spin Attack'
2988 if decision_coin_flip > .5:
2989
2990 explosive_count = 0
2991 droppable_count = 0
2992
2993 ##### ALLOCATION
2994 for action in allocation_list_dict[room.number]:
2995
2996 # whether or not we add an action is based off of this
2997 coin_flip = np.random.uniform(0,1)
2998
2999 if action == 'Smoke' and coin_flip > .5:
3000
3001 Allocate_Smoke(Heap, room.number, Overlay_Dict)
3002 action_list.append("Allocate: Smoke")
3003
3004 elif action == 'Chu' and coin_flip > .5 and explosive_count < 3:
3005
3006 Allocate_Chu(Heap, room.number, Overlay_Dict)
3007 action_list.append("Allocate: Chu")
3008 explosive_count += 1
3009
3010 elif action == 'Arrow' and coin_flip > .5:
3011
3012 Allocate_Arrow(Heap, room.number, Overlay_Dict)
3013 action_list.append("Allocate: Arrow")
3014
3015 elif action == 'Bomb' and coin_flip > .5 and explosive_count < 3:
3016
3017 Allocate_Bomb(Heap, room.number, Overlay_Dict)
3018 action_list.append("Allocate: Bomb")
3019 explosive_count += 1
3020
3021 elif action == 'Zora Fins' and coin_flip > .5:
3022
3023 Allocate_Zora_Fins(Heap, room.number, Overlay_Dict)
3024 action_list.append("Allocate: Zora Fins")
3025
3026 elif action == 'Fish' and coin_flip > .5 and droppable_count < 2:
3027
3028 Allocate_Fish(Heap, room.number, Overlay_Dict)
3029 action_list.append("Allocate: Fish")
3030 droppable_count += 1
3031
3032 elif action == 'Bugs' and coin_flip > .5 and droppable_count < 2:
3033
3034 Allocate_Bugs(Heap, room.number, Overlay_Dict)
3035 action_list.append("Allocate: Bugs")
3036 droppable_count += 1
3037
3038 elif action == 'Hookshot' and coin_flip > .5:
3039
3040 Allocate_Hookshot(Heap, room.number, Overlay_Dict)
3041 action_list.append("Allocate: Hookshot")
3042
3043 elif action == 'Gold Skulltula' and coin_flip > .5:
3044
3045 projectile_coin_flip = np.random.uniform(0,1)
3046
3047 if projectile_coin_flip > .5:
3048 Allocate_Gold_Skulltula_With_Hookshot(Heap, room.number, Overlay_Dict)
3049 action_list.append("Allocate: Gold Skulltula with Hookshot (hit painting)")
3050
3051 elif projectile_coin_flip <= .5:
3052 Allocate_Gold_Skulltula_With_Arrow(Heap, room.number, Overlay_Dict)
3053 action_list.append("Allocate: Gold Skulltula with Arrow (hit painting)")
3054
3055 ### We don't include 'Charged Spin Attack' in this
3056
3057 ##### DEALLOCATION
3058 for actor in room.priority_queue:
3059
3060 # whether or not we deallocate an actor is based off of this
3061 coin_flip = np.random.uniform(0,1)
3062
3063 ##### HARDCODE TO NOT ALLOW GOLD SKULLTULA OR SPIDER WEBS DEALLOCATE BECAUSE FASTER FOR 100%
3064 if actor.unloadable == True and Actor_Is_In_Heap(Heap, actor) == True and coin_flip > .5 and actor.Id != '0050' and actor.Id != '01F4' and actor.Id != '0125':
3065
3066
3067 if actor.Id == '00E8' or actor.name == 'Collectible (Rupee from Rupee Cluster)':
3068
3069 Deallocate(Heap, actor, Overlay_Dict)
3070 # There is at most one rupee cluster per room, so this is fine to clear it
3071 Clear_Instances('00E8', room)
3072 action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
3073
3074 # THESE PRIORITIES ARE HARDCODED FOR ROOM 3 OF OCEANSIDE!!!!!!!
3075 elif actor.Id == '01E7' and (actor.priority == 0 or actor.priority == 1 or actor.priority == 2):
3076
3077 table_bonk_deallocation_count = 0
3078 for entry in Heap:
3079 if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 0:
3080 Deallocate(Heap, entry, Overlay_Dict)
3081 table_bonk_deallocation_count += 1
3082
3083 for entry in Heap:
3084 if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 1:
3085 Deallocate(Heap, entry, Overlay_Dict)
3086 table_bonk_deallocation_count += 1
3087
3088 for entry in Heap:
3089 if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 2:
3090 Deallocate(Heap, entry, Overlay_Dict)
3091 table_bonk_deallocation_count += 1
3092
3093 if table_bonk_deallocation_count != 3:
3094 print("ERROR: table_bonk_deallocation_count is not 3 (Randomized_Solver() error)")
3095
3096 action_list.append("Deallocate: " + actor.name + " (Priority 0, 1, and 2) [Bonk Oceanside Table]")
3097
3098
3099 # if the actor is clearable AND isn't a bad bat, then clear it when deallocating it if it isn't already cleared
3100 elif actor.clearable == True and actor.cleared == False and actor.Id != '015B':
3101
3102 Deallocate(Heap, actor, Overlay_Dict)
3103 action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
3104 # CLEAR THE ACTOR
3105 Clear_Instance(actor, room)
3106
3107 else:
3108
3109 Deallocate(Heap, actor, Overlay_Dict)
3110 action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
3111
3112
3113 # With probability 1/2, we deallocate first and allocate second
3114 elif decision_coin_flip <= .5:
3115
3116 explosive_count = 0
3117 droppable_count = 0
3118 hookshot_exists = False
3119
3120 ##### DEALLOCATION
3121 for actor in room.priority_queue:
3122
3123 # whether or not we deallocate an actor is based off of this
3124 coin_flip = np.random.uniform(0,1)
3125
3126 ##### HARDCODE TO NOT ALLOW GOLD SKULLTULA OR SPIDER WEBS DEALLOCATE BECAUSE FASTER FOR 100%
3127 if actor.unloadable == True and Actor_Is_In_Heap(Heap, actor) == True and coin_flip > .5 and actor.Id != '0050' and actor.Id != '01F4' and actor.Id != '0125':
3128
3129
3130 if actor.Id == '00E8' or actor.name == 'Collectible (Rupee from Rupee Cluster)':
3131
3132 Deallocate(Heap, actor, Overlay_Dict)
3133 # There is at most one rupee cluster per room, so this is fine to clear it
3134 Clear_Instances('00E8', room)
3135 action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
3136
3137 # THESE PRIORITIES ARE HARDCODED FOR ROOM 3 OF OCEANSIDE!!!!!!!
3138 elif actor.Id == '01E7' and (actor.priority == 0 or actor.priority == 1 or actor.priority == 2):
3139
3140 table_bonk_deallocation_count = 0
3141 for entry in Heap:
3142 if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 0:
3143 Deallocate(Heap, entry, Overlay_Dict)
3144 table_bonk_deallocation_count += 1
3145
3146 for entry in Heap:
3147 if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 1:
3148 Deallocate(Heap, entry, Overlay_Dict)
3149 table_bonk_deallocation_count += 1
3150
3151 for entry in Heap:
3152 if type(entry) == Actor and entry.Id == '01E7' and entry.priority == 2:
3153 Deallocate(Heap, entry, Overlay_Dict)
3154 table_bonk_deallocation_count += 1
3155
3156 if table_bonk_deallocation_count != 3:
3157 print("ERROR: table_bonk_deallocation_count is not 3 (Randomized_Solver() error)")
3158
3159 action_list.append("Deallocate: " + actor.name + " (Priority 0, 1, and 2) [Bonk Oceanside Table]")
3160
3161
3162 # if the actor is clearable AND isn't a bad bat, then clear it when deallocating it if it isn't already cleared
3163 elif actor.clearable == True and actor.cleared == False and actor.Id != '015B':
3164
3165 Deallocate(Heap, actor, Overlay_Dict)
3166 action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
3167 # CLEAR THE ACTOR
3168 Clear_Instance(actor, room)
3169
3170 else:
3171
3172 Deallocate(Heap, actor, Overlay_Dict)
3173 action_list.append("Deallocate: " + actor.name + " (Priority %d)" %(actor.priority))
3174
3175
3176 ##### ALLOCATION
3177 for action in allocation_list_dict[room.number]:
3178
3179 # whether or not we add an action is based off of this
3180 coin_flip = np.random.uniform(0,1)
3181
3182 if action == 'Smoke' and coin_flip > .5:
3183
3184 Allocate_Smoke(Heap, room.number, Overlay_Dict)
3185 action_list.append("Allocate: Smoke")
3186
3187 elif action == 'Chu' and coin_flip > .5 and explosive_count < 3:
3188
3189 Allocate_Chu(Heap, room.number, Overlay_Dict)
3190 action_list.append("Allocate: Chu")
3191 explosive_count += 1
3192
3193 elif action == 'Arrow' and coin_flip > .5:
3194
3195 Allocate_Arrow(Heap, room.number, Overlay_Dict)
3196 action_list.append("Allocate: Arrow")
3197
3198 elif action == 'Bomb' and coin_flip > .5 and explosive_count < 3:
3199
3200 Allocate_Bomb(Heap, room.number, Overlay_Dict)
3201 action_list.append("Allocate: Bomb")
3202 explosive_count += 1
3203
3204 elif action == 'Zora Fins' and coin_flip > .5:
3205
3206 Allocate_Zora_Fins(Heap, room.number, Overlay_Dict)
3207 action_list.append("Allocate: Zora Fins")
3208
3209 elif action == 'Fish' and coin_flip > .5 and droppable_count < 2:
3210
3211 Allocate_Fish(Heap, room.number, Overlay_Dict)
3212 action_list.append("Allocate: Fish")
3213 droppable_count += 1
3214
3215 elif action == 'Bugs' and coin_flip > .5 and droppable_count < 2:
3216
3217 Allocate_Bugs(Heap, room.number, Overlay_Dict)
3218 action_list.append("Allocate: Bugs")
3219 droppable_count += 1
3220
3221 elif action == 'Hookshot' and coin_flip > .5:
3222
3223 Allocate_Hookshot(Heap, room.number, Overlay_Dict)
3224 action_list.append("Allocate: Hookshot")
3225 hookshot_exists = True
3226
3227 elif action == 'Charged Spin Attack' and (hookshot_exists is False) and coin_flip > .5:
3228
3229 Allocate_Charged_Spin_Attack(Heap, room.number, Overlay_Dict)
3230 action_list.append("Allocate: Charged Spin Attack")
3231
3232 elif action == 'Gold Skulltula' and coin_flip > .5:
3233
3234 projectile_coin_flip = np.random.uniform(0,1)
3235
3236 if projectile_coin_flip > .5:
3237 Allocate_Gold_Skulltula_With_Hookshot(Heap, room.number, Overlay_Dict)
3238 action_list.append("Allocate: Gold Skulltula with Hookshot (hit painting)")
3239
3240 elif projectile_coin_flip <= .5:
3241 Allocate_Gold_Skulltula_With_Arrow(Heap, room.number, Overlay_Dict)
3242 action_list.append("Allocate: Gold Skulltula with Arrow (hit painting)")
3243
3244 room_count += 1
3245
3246 ##### Now we load the last room in room_order_list
3247 current_room = Current_Room(room_load_list, Room_List)
3248 most_recent_transition = room_load_list[-1]
3249 Load_Room(Heap, current_room, most_recent_transition, Overlay_Dict)
3250
3251 action_list.append("Load Room: Room %d" %(current_room.number) + " with " + most_recent_transition.name + " %d" %(most_recent_transition.priority))
3252
3253
3254 """
3255
3256 Now that we have iterated through all of the rooms, we want to check to see
3257 if we are in a room with a valid grabbale object. If so, then store the addresses
3258 of all of them and make a copy of the current Heap state. From here, we want to try
3259 every possibility in the sense that we want to check every valid grabbable object
3260 in every room that we can get to and also check every superslide case that is possible
3261 (based on the binary number associated with each valid grabbable object) and then
3262 check if either the Angle or Position (input this into the function via Offset_List)
3263 line up with the chest or deku guard
3264
3265 There aren't too many possibilities from here in practice, so we might as well check them all
3266
3267 Also encode that if we superslide into a room with a chest/deku guard, then we must
3268 exit the room and then reenter it (or enter another room with a chest/deku guard; we will
3269 test every case) and after doing that we will check the chest/deku guard addresses
3270 and see if any of them line up with any of the pots that we stored the addresses of
3271
3272 We'll eventually want to write stuff to a text file, so maybe set file as an input argument
3273 or just hardcode it, not sure
3274
3275 """
3276
3277 """
3278
3279 WE MAKE THE ASSUMPTION THAT YOU LAND IN A ROOM THAT EITHER IS A ROOM
3280 WITH A CHEST/DEKU GUARD OR A ROOM THAT NEIGHBORS A ROOM WITH A CHEST/DEKU GUARD
3281 BECAUSE I CANNOT THINK OF ANY PLACES WHERE THIS WOULDN'T HAPPEN WHEN TESTING
3282 SUPERSLIDE SRM (ZORA FIN WOULD BE DIFFERENT, BUT THIS SOLVER DOESN'T TEST IT)
3283
3284 Also, before supersliding, we assume that you're in a room that either has
3285 a valid grabbable object, or is next to a room with a valid grabbable object.
3286 Of course, this means fewer possibilities are being tested in a place like
3287 oceanside, but there are already so many possibilities to test to begin with that
3288 this probably isn't a big deal for now. This also affects deku palace, but maybe
3289 I'll change this by the time I work on deku palace (because if you end in Room2,
3290 then nothing happens)
3291
3292 """
3293
3294 """
3295
3296 Nevermind some of those other comments, here is what I'm really assuming.
3297
3298 I will be assuming that if you end in a room without a valid grabbable
3299 actor, then it will search all neighbors of that room for valid grabbable
3300 actors and if none of those have valid grabbable objects then it will
3301 search all of those neighbors and choose the first one it finds (this
3302 will allow for ending in Room 2 in Deku Palace). Otherwise it does nothing
3303 (though this will never happen for the cases I plan on checking for now)
3304
3305 (*Coded)If you are in a room with a valid grabbable actor and no chest/deku guard,
3306 then we will check the addresses of all valid grabbable actors in this room
3307 and superslide into the chest room, exit and reenter it. Then we will check the address of the
3308 chest and see if it lines up with any of the pot addresses from the previous
3309 room.
3310
3311 (*Coded)If you are in a room with a valid grabbable actor AND a chest/deku guard, then
3312 you will record the valid grabbable actor addresses then superslide to exit the
3313 room and then check all neighbors of the room you enter for having a chest/deku guard
3314 and test all of them
3315
3316
3317
3318 """
3319
3320 valid_grabbable_actor_room_list = []
3321
3322 for room in Room_List:
3323 if Valid_Grabbable_In_Room(room, Grabbable_Dict) is True:
3324 valid_grabbable_actor_room_list.append(room)
3325
3326 # This gives a list of all ways we can exit our current room
3327 #transition_list_possibilities = Generate_Room_Load_Permutations(current_room, Room_List, 1)
3328
3329 ##### Case 1: there is a valid grabbable actor in the current room, but no chest/deku guard (the guard thing doesn't matter because this never happens in palace anyway)
3330 if (current_room in valid_grabbable_actor_room_list) and (Chest_In_Room(current_room) is False) and (Deku_Guard_In_Room(current_room) is False):
3331
3332 valid_pot_list = []
3333 pot_address_list = []
3334
3335 for pot in Grabbable_Dict:
3336
3337 if Actor_Is_In_Room(current_room, pot) is True:
3338 valid_pot_list.append(pot)
3339 pot_address_list.append(pot.address)
3340
3341 """
3342
3343 Now for each pot in valid_pot_list, we want to test every applicable
3344 superslide scenario
3345
3346 Before each one, we need to copy the current state and then modify the copies
3347 to check for the solution
3348
3349 """
3350
3351 for pot in valid_pot_list:
3352
3353 # both bomb and smoke loaded on superslide
3354 if Grabbable_Dict[pot][0][0] == '1':
3355
3356 action_list100 = []
3357
3358 # COPY STATE
3359 #######################################################
3360 Room_List_Copy = Copy_Room_List(Room_List)
3361 Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
3362
3363 room_copy_dict = {}
3364 for room in Room_List_Copy:
3365 room_copy_dict[room.number] = room
3366
3367 Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
3368
3369 Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
3370 #######################################################
3371
3372 Bomb_And_Smoke_Superslide(Heap_Copy, current_room.number, Overlay_Dict_Copy)
3373 action_list100.append("Superslide with Bomb and Smoke still allocated")
3374
3375 # The room we superslide into through the plane corresponding to the given pot
3376 destination_room = Current_Room([current_room, Grabbable_Dict[pot][1]], Room_List)
3377
3378 destination_room_copy = room_copy_dict[destination_room.number]
3379 current_room_copy = room_copy_dict[current_room.number]
3380
3381 pot_copy = Find_Actor_Copy(pot, Room_List_Copy)
3382 superslide_transition_copy = Grabbable_Dict_Copy[pot_copy][1]
3383
3384 Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
3385 action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
3386
3387 # Now exit the chest room
3388 Load_Room(Heap_Copy, current_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
3389 action_list100.append("Load Room: Room %d" %(current_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
3390
3391 # Now reenter the chest room
3392 Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
3393 action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
3394
3395 ##### Now check for chests/deku guards
3396
3397 chest_guard_list = []
3398
3399 for entry in Heap_Copy:
3400
3401 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
3402 chest_guard_list.append(entry)
3403
3404 soln_found = False
3405 for entry in chest_guard_list:
3406 if (pot.address - entry.address) in Offset_List:
3407
3408 action_list100.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
3409
3410 if (pot.address - entry.address) == 0x160:
3411 angle_solution_count += 1
3412 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
3413 elif (pot.address - entry.address) == 0x1F0:
3414 position_solution_count += 1
3415 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
3416
3417 soln_found = True
3418
3419 if soln_found is True:
3420 total_action_list = action_list + action_list100
3421
3422 # the "a" argument is important so we don't overwrite previous solutions
3423 with open(filename, "a") as file:
3424
3425 for action in total_action_list:
3426
3427 file.write(action + "\n")
3428 file.write("-----\n")
3429
3430
3431 ##### Only smoke is loaded from superslide
3432 elif Grabbable_Dict[pot][0][1] == '1':
3433
3434 action_list010 = []
3435
3436 # COPY STATE
3437 #######################################################
3438 Room_List_Copy = Copy_Room_List(Room_List)
3439 Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
3440
3441 room_copy_dict = {}
3442 for room in Room_List_Copy:
3443 room_copy_dict[room.number] = room
3444
3445 Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
3446
3447 Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
3448 #######################################################
3449
3450 Allocate_Smoke(Heap_Copy, current_room.number, Overlay_Dict_Copy)
3451 action_list010.append("Superslide with Smoke still allocated")
3452
3453 # The room we superslide into through the plane corresponding to the given pot
3454 destination_room = Current_Room([current_room, Grabbable_Dict[pot][1]], Room_List)
3455
3456 destination_room_copy = room_copy_dict[destination_room.number]
3457 current_room_copy = room_copy_dict[current_room.number]
3458
3459 pot_copy = Find_Actor_Copy(pot, Room_List_Copy)
3460 superslide_transition_copy = Grabbable_Dict_Copy[pot_copy][1]
3461
3462 Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
3463 action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
3464
3465 # Now exit the chest room
3466 Load_Room(Heap_Copy, current_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
3467 action_list010.append("Load Room: Room %d" %(current_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
3468
3469 # Now reenter the chest room
3470 Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
3471 action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
3472
3473
3474 ##### Now check for chests/deku guards
3475
3476 chest_guard_list = []
3477
3478 for entry in Heap_Copy:
3479
3480 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
3481 chest_guard_list.append(entry)
3482
3483 soln_found = False
3484 for entry in chest_guard_list:
3485 if (pot.address - entry.address) in Offset_List:
3486
3487 action_list010.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
3488
3489 if (pot.address - entry.address) == 0x160:
3490 angle_solution_count += 1
3491 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
3492 elif (pot.address - entry.address) == 0x1F0:
3493 position_solution_count += 1
3494 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
3495
3496 soln_found = True
3497
3498 if soln_found is True:
3499 total_action_list = action_list + action_list010
3500
3501 # the "a" argument is important so we don't overwrite previous solutions
3502 with open(filename, "a") as file:
3503
3504 for action in total_action_list:
3505
3506 file.write(action + "\n")
3507 file.write("-----\n")
3508
3509
3510 #### Bomb and Smoke are both unloaded
3511 elif Grabbable_Dict[pot][0][2] == '1':
3512
3513 action_list001 = []
3514
3515 # COPY STATE
3516 #######################################################
3517 Room_List_Copy = Copy_Room_List(Room_List)
3518 Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
3519
3520 room_copy_dict = {}
3521 for room in Room_List_Copy:
3522 room_copy_dict[room.number] = room
3523
3524 Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
3525
3526 Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
3527 #######################################################
3528
3529 # Do not allocate anything
3530 action_list001.append("Superslide with Bomb and Smoke unloaded when passing plane")
3531
3532 # The room we superslide into through the plane corresponding to the given pot
3533 destination_room = Current_Room([current_room, Grabbable_Dict[pot][1]], Room_List)
3534
3535 destination_room_copy = room_copy_dict[destination_room.number]
3536 current_room_copy = room_copy_dict[current_room.number]
3537
3538 pot_copy = Find_Actor_Copy(pot, Room_List_Copy)
3539 superslide_transition_copy = Grabbable_Dict_Copy[pot_copy][1]
3540
3541 Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
3542 action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
3543
3544 # Now exit the chest room
3545 Load_Room(Heap_Copy, current_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
3546 action_list001.append("Load Room: Room %d" %(current_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
3547
3548 # Now reenter the chest room
3549 Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
3550 action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
3551
3552
3553 ##### Now check for chests/deku guards
3554
3555 chest_guard_list = []
3556
3557 for entry in Heap_Copy:
3558
3559 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
3560 chest_guard_list.append(entry)
3561
3562 soln_found = False
3563 for entry in chest_guard_list:
3564 if (pot.address - entry.address) in Offset_List:
3565
3566 action_list001.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
3567
3568 if (pot.address - entry.address) == 0x160:
3569 angle_solution_count += 1
3570 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
3571 elif (pot.address - entry.address) == 0x1F0:
3572 position_solution_count += 1
3573 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
3574
3575 soln_found = True
3576
3577 if soln_found is True:
3578 total_action_list = action_list + action_list001
3579
3580 # the "a" argument is important so we don't overwrite previous solutions
3581 with open(filename, "a") as file:
3582
3583 for action in total_action_list:
3584
3585 file.write(action + "\n")
3586 file.write("-----\n")
3587
3588
3589
3590 # Case 2: there is a valid grabbable actor in the current room AND there is a chest or deku guard
3591 elif (current_room in valid_grabbable_actor_room_list) and ((Chest_In_Room(current_room) is True) or (Deku_Guard_In_Room(current_room) is True)):
3592
3593 valid_pot_list = []
3594 pot_address_list = []
3595
3596 for pot in Grabbable_Dict:
3597
3598 if Actor_Is_In_Room(current_room, pot) is True:
3599 valid_pot_list.append(pot)
3600 pot_address_list.append(pot.address)
3601
3602
3603 """
3604
3605 Now for each pot in valid_pot_list, we want to test every applicable
3606 superslide scenario
3607
3608 Before each one, we need to copy the current state and then modify the copies
3609 to check for the solution
3610
3611 Also, for every case, we need to consider every possible room that contains
3612 a chest/deku guard that neighbors the room we just entered (meaning you
3613 will need to make copies of the copies of the state)
3614
3615 """
3616
3617 for pot in valid_pot_list:
3618
3619 # both bomb and smoke loaded on superslide
3620 if Grabbable_Dict[pot][0][0] == '1':
3621
3622 action_list100 = []
3623
3624 # COPY STATE
3625 #######################################################
3626 Room_List_Copy = Copy_Room_List(Room_List)
3627 Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
3628
3629 room_copy_dict = {}
3630 for room in Room_List_Copy:
3631 room_copy_dict[room.number] = room
3632
3633 Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
3634
3635 Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
3636 #######################################################
3637
3638 Bomb_And_Smoke_Superslide(Heap_Copy, current_room.number, Overlay_Dict_Copy)
3639 action_list100.append("Superslide with Bomb and Smoke still allocated")
3640
3641 # The room we superslide into through the plane corresponding to the given pot
3642 destination_room = Current_Room([current_room, Grabbable_Dict[pot][1]], Room_List)
3643
3644 destination_room_copy = room_copy_dict[destination_room.number]
3645
3646 pot_copy = Find_Actor_Copy(pot, Room_List_Copy)
3647 superslide_transition_copy = Grabbable_Dict_Copy[pot_copy][1]
3648
3649 Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
3650 action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
3651
3652 """
3653
3654 Now we check all neighbors of our current room (destination_room) and for
3655 each neighbor that has a chest or deku guard in it, we will create a copy
3656 of our copy of the state, then enter each of them through each possible
3657 loading plane and then check the chest/guard addresses and see if anything
3658 lines up
3659
3660 """
3661
3662 for neighbor in Neighbors(destination_room, Room_List):
3663
3664 if Chest_In_Room(neighbor) == True or Deku_Guard_In_Room(neighbor) == True:
3665
3666 for transition in Shared_Transitions(destination_room, neighbor):
3667
3668 # COPY STATE
3669 #######################################################
3670 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
3671 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
3672
3673 room_copy_dict_2 = {}
3674 for room in Room_List_Copy_2:
3675 room_copy_dict_2[room.number] = room
3676
3677 Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
3678
3679 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
3680 #######################################################
3681
3682 action_list_2 = []
3683
3684 transition_copy = Find_Actor_Copy(transition, Room_List_Copy_2)
3685
3686 neighbor_copy = room_copy_dict_2[neighbor.number]
3687
3688 Load_Room(Heap_Copy_2, neighbor_copy, transition_copy, Overlay_Dict_Copy_2)
3689 action_list_2.append("Load Room: Room %d" %(neighbor_copy.number) + " with " + transition_copy.name + " %d" %(transition_copy.priority))
3690
3691
3692 ##### Now check for chests/deku guards
3693
3694 chest_guard_list = []
3695
3696 for entry in Heap_Copy_2:
3697
3698 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
3699 chest_guard_list.append(entry)
3700
3701 soln_found = False
3702 for entry in chest_guard_list:
3703 if (pot.address - entry.address) in Offset_List:
3704
3705 action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
3706
3707 if (pot.address - entry.address) == 0x160:
3708 angle_solution_count += 1
3709 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
3710 elif (pot.address - entry.address) == 0x1F0:
3711 position_solution_count += 1
3712 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
3713
3714 soln_found = True
3715
3716 if soln_found is True:
3717 total_action_list = action_list + action_list100 + action_list_2
3718
3719 # the "a" argument is important so we don't overwrite previous solutions
3720 with open(filename, "a") as file:
3721
3722 for action in total_action_list:
3723
3724 file.write(action + "\n")
3725 file.write("-----\n")
3726
3727
3728 ##### Only smoke is loaded from superslide
3729 elif Grabbable_Dict[pot][0][1] == '1':
3730
3731 action_list010 = []
3732
3733 # COPY STATE
3734 #######################################################
3735 Room_List_Copy = Copy_Room_List(Room_List)
3736 Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
3737
3738 room_copy_dict = {}
3739 for room in Room_List_Copy:
3740 room_copy_dict[room.number] = room
3741
3742 Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
3743
3744 Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
3745 #######################################################
3746
3747 Allocate_Smoke(Heap_Copy, current_room.number, Overlay_Dict_Copy)
3748 action_list010.append("Superslide with Smoke still allocated")
3749
3750 # The room we superslide into through the plane corresponding to the given pot
3751 destination_room = Current_Room([current_room, Grabbable_Dict[pot][1]], Room_List)
3752
3753 destination_room_copy = room_copy_dict[destination_room.number]
3754
3755 pot_copy = Find_Actor_Copy(pot, Room_List_Copy)
3756 superslide_transition_copy = Grabbable_Dict_Copy[pot_copy][1]
3757
3758 Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
3759 action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
3760
3761 """
3762
3763 Now we check all neighbors of our current room (destination_room) and for
3764 each neighbor that has a chest or deku guard in it, we will create a copy
3765 of our copy of the state, then enter each of them through each possible
3766 loading plane and then check the chest/guard addresses and see if anything
3767 lines up
3768
3769 """
3770
3771 for neighbor in Neighbors(destination_room, Room_List):
3772
3773 if Chest_In_Room(neighbor) == True or Deku_Guard_In_Room(neighbor) == True:
3774
3775 for transition in Shared_Transitions(destination_room, neighbor):
3776
3777 # COPY STATE
3778 #######################################################
3779 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
3780 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
3781
3782 room_copy_dict_2 = {}
3783 for room in Room_List_Copy_2:
3784 room_copy_dict_2[room.number] = room
3785
3786 Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
3787
3788 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
3789 #######################################################
3790
3791 action_list_2 = []
3792
3793 transition_copy = Find_Actor_Copy(transition, Room_List_Copy_2)
3794
3795 neighbor_copy = room_copy_dict_2[neighbor.number]
3796
3797 Load_Room(Heap_Copy_2, neighbor_copy, transition_copy, Overlay_Dict_Copy_2)
3798 action_list_2.append("Load Room: Room %d" %(neighbor_copy.number) + " with " + transition_copy.name + " %d" %(transition_copy.priority))
3799
3800
3801 ##### Now check for chests/deku guards
3802
3803 chest_guard_list = []
3804
3805 for entry in Heap_Copy_2:
3806
3807 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
3808 chest_guard_list.append(entry)
3809
3810 soln_found = False
3811 for entry in chest_guard_list:
3812 if (pot.address - entry.address) in Offset_List:
3813
3814 action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
3815
3816 if (pot.address - entry.address) == 0x160:
3817 angle_solution_count += 1
3818 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
3819 elif (pot.address - entry.address) == 0x1F0:
3820 position_solution_count += 1
3821 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
3822
3823 soln_found = True
3824
3825 if soln_found is True:
3826 total_action_list = action_list + action_list010 + action_list_2
3827
3828 # the "a" argument is important so we don't overwrite previous solutions
3829 with open(filename, "a") as file:
3830
3831 for action in total_action_list:
3832
3833 file.write(action + "\n")
3834 file.write("-----\n")
3835
3836
3837 #### Bomb and Smoke are both unloaded
3838 elif Grabbable_Dict[pot][0][2] == '1':
3839
3840 action_list001 = []
3841
3842 # COPY STATE
3843 #######################################################
3844 Room_List_Copy = Copy_Room_List(Room_List)
3845 Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
3846
3847 room_copy_dict = {}
3848 for room in Room_List_Copy:
3849 room_copy_dict[room.number] = room
3850
3851 Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
3852
3853 Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
3854 #######################################################
3855
3856 # Do not allocate anything
3857 action_list001.append("Superslide with Bomb and Smoke unloaded when passing plane")
3858
3859 # The room we superslide into through the plane corresponding to the given pot
3860 destination_room = Current_Room([current_room, Grabbable_Dict[pot][1]], Room_List)
3861
3862 destination_room_copy = room_copy_dict[destination_room.number]
3863
3864 pot_copy = Find_Actor_Copy(pot, Room_List_Copy)
3865 superslide_transition_copy = Grabbable_Dict_Copy[pot_copy][1]
3866
3867 Load_Room(Heap_Copy, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy)
3868 action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
3869
3870 """
3871
3872 Now we check all neighbors of our current room (destination_room) and for
3873 each neighbor that has a chest or deku guard in it, we will create a copy
3874 of our copy of the state, then enter each of them through each possible
3875 loading plane and then check the chest/guard addresses and see if anything
3876 lines up
3877
3878 """
3879
3880 for neighbor in Neighbors(destination_room, Room_List):
3881
3882 if Chest_In_Room(neighbor) == True or Deku_Guard_In_Room(neighbor) == True:
3883
3884 for transition in Shared_Transitions(destination_room, neighbor):
3885
3886 # COPY STATE
3887 #######################################################
3888 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
3889 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
3890
3891 room_copy_dict_2 = {}
3892 for room in Room_List_Copy_2:
3893 room_copy_dict_2[room.number] = room
3894
3895 Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
3896
3897 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
3898 #######################################################
3899
3900 action_list_2 = []
3901
3902 transition_copy = Find_Actor_Copy(transition, Room_List_Copy_2)
3903
3904 neighbor_copy = room_copy_dict_2[neighbor.number]
3905
3906 Load_Room(Heap_Copy_2, neighbor_copy, transition_copy, Overlay_Dict_Copy_2)
3907 action_list_2.append("Load Room: Room %d" %(neighbor_copy.number) + " with " + transition_copy.name + " %d" %(transition_copy.priority))
3908
3909
3910 ##### Now check for chests/deku guards
3911
3912 chest_guard_list = []
3913
3914 for entry in Heap_Copy_2:
3915
3916 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
3917 chest_guard_list.append(entry)
3918
3919 soln_found = False
3920 for entry in chest_guard_list:
3921 if (pot.address - entry.address) in Offset_List:
3922
3923 action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
3924
3925 if (pot.address - entry.address) == 0x160:
3926 angle_solution_count += 1
3927 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
3928 elif (pot.address - entry.address) == 0x1F0:
3929 position_solution_count += 1
3930 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
3931
3932 soln_found = True
3933
3934 if soln_found is True:
3935 total_action_list = action_list + action_list001 + action_list_2
3936
3937 # the "a" argument is important so we don't overwrite previous solutions
3938 with open(filename, "a") as file:
3939
3940 for action in total_action_list:
3941
3942 file.write(action + "\n")
3943 file.write("-----\n")
3944
3945
3946 ##### Case 3: there is NOT a valid grabbable actor in the current room
3947 elif (current_room not in valid_grabbable_actor_room_list):
3948
3949 for neighbor in Neighbors(current_room, Room_List):
3950
3951 ##### Valid grabbable actor in neighbor
3952 if neighbor in valid_grabbable_actor_room_list:
3953
3954
3955 # For every transition in Shared_Transitions(current_room, neighbor)
3956 for transition in Shared_Transitions(current_room, neighbor):
3957
3958 action_list_transition = []
3959
3960 ##### COPY THE STATE
3961 #######################################################
3962 Room_List_Copy = Copy_Room_List(Room_List)
3963 Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
3964
3965 room_copy_dict = {}
3966 for room in Room_List_Copy:
3967 room_copy_dict[room.number] = room
3968
3969 Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
3970
3971 Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
3972 #######################################################
3973
3974 ##### ENTER neighbor after copying it
3975
3976 neighbor_copy = room_copy_dict[neighbor.number]
3977 transition_copy = Find_Actor_Copy(transition, Room_List_Copy)
3978
3979 Load_Room(Heap_Copy, neighbor_copy, transition_copy, Overlay_Dict_Copy)
3980 action_list_transition.append("Load Room: Room %d" %(neighbor_copy.number) + " with " + transition_copy.name + " %d" %(transition_copy.priority))
3981
3982
3983 ##### Iterate through all pots in this room
3984
3985 valid_pot_list = []
3986 pot_address_list = []
3987
3988 for pot in Grabbable_Dict_Copy:
3989
3990 if Actor_Is_In_Room(neighbor_copy, pot) is True:
3991 valid_pot_list.append(pot)
3992 pot_address_list.append(pot.address)
3993
3994
3995
3996 # If there is a chest/guard, superslide, then check neighbors for chests/guards and test all (copy state)
3997 if Chest_In_Room(neighbor) == True or Deku_Guard_In_Room(neighbor) == True:
3998
3999 for pot in valid_pot_list:
4000
4001 # both bomb and smoke loaded on superslide
4002 if Grabbable_Dict_Copy[pot][0][0] == '1':
4003
4004 action_list100 = []
4005
4006 # COPY STATE
4007 #######################################################
4008 Room_List_Copy_SS = Copy_Room_List(Room_List_Copy)
4009 Overlay_Dict_Copy_SS = Copy_Overlay_Dict(Overlay_Dict_Copy)
4010
4011 room_copy_dict_SS = {}
4012 for room in Room_List_Copy_SS:
4013 room_copy_dict_SS[room.number] = room
4014
4015 Heap_Copy_SS = Copy_Heap(Heap_Copy, Room_List_Copy_SS, Overlay_Dict_Copy_SS)
4016
4017 Grabbable_Dict_Copy_SS = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_SS)
4018 #######################################################
4019
4020 Bomb_And_Smoke_Superslide(Heap_Copy_SS, neighbor.number, Overlay_Dict_Copy_SS)
4021 action_list100.append("Superslide with Bomb and Smoke still allocated")
4022
4023 # The room we superslide into through the plane corresponding to the given pot
4024 destination_room = Current_Room([neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
4025
4026 destination_room_copy = room_copy_dict_SS[destination_room.number]
4027
4028 pot_copy = Find_Actor_Copy(pot, Room_List_Copy_SS)
4029 superslide_transition_copy = Grabbable_Dict_Copy_SS[pot_copy][1]
4030
4031 Load_Room(Heap_Copy_SS, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_SS)
4032 action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4033
4034 """
4035
4036 Now we check all neighbors of our current room (destination_room) and for
4037 each neighbor that has a chest or deku guard in it, we will create a copy
4038 of our copy of the state, then enter each of them through each possible
4039 loading plane and then check the chest/guard addresses and see if anything
4040 lines up
4041
4042 """
4043
4044 for bordering_room in Neighbors(destination_room, Room_List):
4045
4046 if Chest_In_Room(bordering_room) == True or Deku_Guard_In_Room(bordering_room) == True:
4047
4048 for loading_plane in Shared_Transitions(destination_room, bordering_room):
4049
4050 # COPY STATE
4051 #######################################################
4052 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy_SS)
4053 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy_SS)
4054
4055 room_copy_dict_2 = {}
4056 for room in Room_List_Copy_2:
4057 room_copy_dict_2[room.number] = room
4058
4059 Heap_Copy_2 = Copy_Heap(Heap_Copy_SS, Room_List_Copy_2, Overlay_Dict_Copy_2)
4060
4061 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy_SS, Room_List_Copy_2)
4062 #######################################################
4063
4064 action_list_2 = []
4065
4066 loading_plane_copy = Find_Actor_Copy(loading_plane, Room_List_Copy_2)
4067
4068 bordering_room_copy = room_copy_dict_2[bordering_room.number]
4069
4070 Load_Room(Heap_Copy_2, bordering_room_copy, loading_plane_copy, Overlay_Dict_Copy_2)
4071 action_list_2.append("Load Room: Room %d" %(bordering_room_copy.number) + " with " + loading_plane_copy.name + " %d" %(loading_plane_copy.priority))
4072
4073
4074 ##### Now check for chests/deku guards
4075
4076 chest_guard_list = []
4077
4078 for entry in Heap_Copy_2:
4079
4080 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
4081 chest_guard_list.append(entry)
4082
4083 soln_found = False
4084 for entry in chest_guard_list:
4085 if (pot.address - entry.address) in Offset_List:
4086
4087 action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
4088
4089 if (pot.address - entry.address) == 0x160:
4090 angle_solution_count += 1
4091 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4092 elif (pot.address - entry.address) == 0x1F0:
4093 position_solution_count += 1
4094 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4095
4096 soln_found = True
4097
4098 if soln_found is True:
4099 total_action_list = action_list + action_list_transition + action_list100 + action_list_2
4100
4101 # the "a" argument is important so we don't overwrite previous solutions
4102 with open(filename, "a") as file:
4103
4104 for action in total_action_list:
4105
4106 file.write(action + "\n")
4107 file.write("-----\n")
4108
4109
4110
4111 ##### Only smoke is loaded from superslide
4112 elif Grabbable_Dict_Copy[pot][0][1] == '1':
4113
4114 action_list010 = []
4115
4116 # COPY STATE
4117 #######################################################
4118 Room_List_Copy_SS = Copy_Room_List(Room_List_Copy)
4119 Overlay_Dict_Copy_SS = Copy_Overlay_Dict(Overlay_Dict_Copy)
4120
4121 room_copy_dict_SS = {}
4122 for room in Room_List_Copy_SS:
4123 room_copy_dict_SS[room.number] = room
4124
4125 Heap_Copy_SS = Copy_Heap(Heap_Copy, Room_List_Copy_SS, Overlay_Dict_Copy_SS)
4126
4127 Grabbable_Dict_Copy_SS = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_SS)
4128 #######################################################
4129
4130 Allocate_Smoke(Heap_Copy_SS, neighbor.number, Overlay_Dict_Copy_SS)
4131 action_list010.append("Superslide with Smoke still allocated")
4132
4133 # The room we superslide into through the plane corresponding to the given pot
4134 destination_room = Current_Room([neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
4135
4136 destination_room_copy = room_copy_dict_SS[destination_room.number]
4137
4138 pot_copy = Find_Actor_Copy(pot, Room_List_Copy_SS)
4139 superslide_transition_copy = Grabbable_Dict_Copy_SS[pot_copy][1]
4140
4141 Load_Room(Heap_Copy_SS, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_SS)
4142 action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4143
4144 """
4145
4146 Now we check all neighbors of our current room (destination_room) and for
4147 each neighbor that has a chest or deku guard in it, we will create a copy
4148 of our copy of the state, then enter each of them through each possible
4149 loading plane and then check the chest/guard addresses and see if anything
4150 lines up
4151
4152 """
4153
4154 for bordering_room in Neighbors(destination_room, Room_List):
4155
4156 if Chest_In_Room(bordering_room) == True or Deku_Guard_In_Room(bordering_room) == True:
4157
4158 for loading_plane in Shared_Transitions(destination_room, bordering_room):
4159
4160 # COPY STATE
4161 #######################################################
4162 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy_SS)
4163 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy_SS)
4164
4165 room_copy_dict_2 = {}
4166 for room in Room_List_Copy_2:
4167 room_copy_dict_2[room.number] = room
4168
4169 Heap_Copy_2 = Copy_Heap(Heap_Copy_SS, Room_List_Copy_2, Overlay_Dict_Copy_2)
4170
4171 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy_SS, Room_List_Copy_2)
4172 #######################################################
4173
4174 action_list_2 = []
4175
4176 loading_plane_copy = Find_Actor_Copy(loading_plane, Room_List_Copy_2)
4177
4178 bordering_room_copy = room_copy_dict_2[bordering_room.number]
4179
4180 Load_Room(Heap_Copy_2, bordering_room_copy, loading_plane_copy, Overlay_Dict_Copy_2)
4181 action_list_2.append("Load Room: Room %d" %(bordering_room_copy.number) + " with " + loading_plane_copy.name + " %d" %(loading_plane_copy.priority))
4182
4183
4184 ##### Now check for chests/deku guards
4185
4186 chest_guard_list = []
4187
4188 for entry in Heap_Copy_2:
4189
4190 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
4191 chest_guard_list.append(entry)
4192
4193 soln_found = False
4194 for entry in chest_guard_list:
4195 if (pot.address - entry.address) in Offset_List:
4196
4197 action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
4198
4199 if (pot.address - entry.address) == 0x160:
4200 angle_solution_count += 1
4201 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4202 elif (pot.address - entry.address) == 0x1F0:
4203 position_solution_count += 1
4204 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4205
4206 soln_found = True
4207
4208 if soln_found is True:
4209 total_action_list = action_list + action_list_transition + action_list010 + action_list_2
4210
4211 # the "a" argument is important so we don't overwrite previous solutions
4212 with open(filename, "a") as file:
4213
4214 for action in total_action_list:
4215
4216 file.write(action + "\n")
4217 file.write("-----\n")
4218
4219
4220 #### Bomb and Smoke are both unloaded
4221 elif Grabbable_Dict_Copy[pot][0][2] == '1':
4222
4223 action_list001 = []
4224
4225 # COPY STATE
4226 #######################################################
4227 Room_List_Copy_SS = Copy_Room_List(Room_List_Copy)
4228 Overlay_Dict_Copy_SS = Copy_Overlay_Dict(Overlay_Dict_Copy)
4229
4230 room_copy_dict_SS = {}
4231 for room in Room_List_Copy_SS:
4232 room_copy_dict_SS[room.number] = room
4233
4234 Heap_Copy_SS = Copy_Heap(Heap_Copy, Room_List_Copy_SS, Overlay_Dict_Copy_SS)
4235
4236 Grabbable_Dict_Copy_SS = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_SS)
4237 #######################################################
4238
4239 # Do not allocate anything
4240 action_list001.append("Superslide with Bomb and Smoke unloaded when passing plane")
4241
4242 # The room we superslide into through the plane corresponding to the given pot
4243 destination_room = Current_Room([neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
4244
4245 destination_room_copy = room_copy_dict_SS[destination_room.number]
4246
4247 pot_copy = Find_Actor_Copy(pot, Room_List_Copy_SS)
4248 superslide_transition_copy = Grabbable_Dict_Copy_SS[pot_copy][1]
4249
4250 Load_Room(Heap_Copy_SS, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_SS)
4251 action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4252
4253 """
4254
4255 Now we check all neighbors of our current room (destination_room) and for
4256 each neighbor that has a chest or deku guard in it, we will create a copy
4257 of our copy of the state, then enter each of them through each possible
4258 loading plane and then check the chest/guard addresses and see if anything
4259 lines up
4260
4261 """
4262
4263 for bordering_room in Neighbors(destination_room, Room_List):
4264
4265 if Chest_In_Room(bordering_room) == True or Deku_Guard_In_Room(bordering_room) == True:
4266
4267 for loading_plane in Shared_Transitions(destination_room, bordering_room):
4268
4269 # COPY STATE
4270 #######################################################
4271 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy_SS)
4272 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy_SS)
4273
4274 room_copy_dict_2 = {}
4275 for room in Room_List_Copy_2:
4276 room_copy_dict_2[room.number] = room
4277
4278 Heap_Copy_2 = Copy_Heap(Heap_Copy_SS, Room_List_Copy_2, Overlay_Dict_Copy_2)
4279
4280 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy_SS, Room_List_Copy_2)
4281 #######################################################
4282
4283 action_list_2 = []
4284
4285 loading_plane_copy = Find_Actor_Copy(loading_plane, Room_List_Copy_2)
4286
4287 bordering_room_copy = room_copy_dict_2[bordering_room.number]
4288
4289 Load_Room(Heap_Copy_2, bordering_room_copy, loading_plane_copy, Overlay_Dict_Copy_2)
4290 action_list_2.append("Load Room: Room %d" %(bordering_room_copy.number) + " with " + loading_plane_copy.name + " %d" %(loading_plane_copy.priority))
4291
4292
4293 ##### Now check for chests/deku guards
4294
4295 chest_guard_list = []
4296
4297 for entry in Heap_Copy_2:
4298
4299 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
4300 chest_guard_list.append(entry)
4301
4302 soln_found = False
4303 for entry in chest_guard_list:
4304 if (pot.address - entry.address) in Offset_List:
4305
4306 action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
4307
4308 if (pot.address - entry.address) == 0x160:
4309 angle_solution_count += 1
4310 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4311 elif (pot.address - entry.address) == 0x1F0:
4312 position_solution_count += 1
4313 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4314
4315 soln_found = True
4316
4317 if soln_found is True:
4318 total_action_list = action_list + action_list_transition + action_list001 + action_list_2
4319
4320 # the "a" argument is important so we don't overwrite previous solutions
4321 with open(filename, "a") as file:
4322
4323 for action in total_action_list:
4324
4325 file.write(action + "\n")
4326 file.write("-----\n")
4327
4328
4329
4330 # If there isn't a chest/guard, superslide (into chest/guard room by assumption), then exit then reenter it (this case never happens in palace, so this is an okay assumption)
4331 elif Chest_In_Room(neighbor) == False and Deku_Guard_In_Room(neighbor) == False:
4332
4333 for pot in valid_pot_list:
4334
4335 # both bomb and smoke loaded on superslide
4336 if Grabbable_Dict_Copy[pot][0][0] == '1':
4337
4338 action_list100 = []
4339
4340 # COPY STATE
4341 #######################################################
4342 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
4343 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
4344
4345 room_copy_dict_2 = {}
4346 for room in Room_List_Copy_2:
4347 room_copy_dict_2[room.number] = room
4348
4349 Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
4350
4351 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
4352 #######################################################
4353
4354 Bomb_And_Smoke_Superslide(Heap_Copy_2, neighbor_copy.number, Overlay_Dict_Copy_2)
4355 action_list100.append("Superslide with Bomb and Smoke still allocated")
4356
4357 # The room we superslide into through the plane corresponding to the given pot
4358 destination_room = Current_Room([neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
4359
4360 destination_room_copy = room_copy_dict_2[destination_room.number]
4361 neighbor_copy_2 = room_copy_dict_2[neighbor_copy.number]
4362
4363 pot_copy = Find_Actor_Copy(pot, Room_List_Copy_2)
4364 superslide_transition_copy = Grabbable_Dict_Copy_2[pot_copy][1]
4365
4366 Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
4367 action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4368
4369 # Now exit the chest room
4370 Load_Room(Heap_Copy_2, neighbor_copy_2, superslide_transition_copy, Overlay_Dict_Copy_2)
4371 action_list100.append("Load Room: Room %d" %(neighbor_copy_2.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4372
4373 # Now reenter the chest room
4374 Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
4375 action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4376
4377 ##### Now check for chests/deku guards
4378
4379 chest_guard_list = []
4380
4381 for entry in Heap_Copy_2:
4382
4383 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
4384 chest_guard_list.append(entry)
4385
4386 soln_found = False
4387 for entry in chest_guard_list:
4388 if (pot.address - entry.address) in Offset_List:
4389
4390 action_list100.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
4391
4392 if (pot.address - entry.address) == 0x160:
4393 angle_solution_count += 1
4394 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4395 elif (pot.address - entry.address) == 0x1F0:
4396 position_solution_count += 1
4397 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4398
4399 soln_found = True
4400
4401 if soln_found is True:
4402 total_action_list = action_list + action_list_transition + action_list100
4403
4404 # the "a" argument is important so we don't overwrite previous solutions
4405 with open(filename, "a") as file:
4406
4407 for action in total_action_list:
4408
4409 file.write(action + "\n")
4410 file.write("-----\n")
4411
4412
4413
4414 ##### Only smoke is loaded from superslide
4415 elif Grabbable_Dict_Copy[pot][0][1] == '1':
4416
4417 action_list010 = []
4418
4419 # COPY STATE
4420 #######################################################
4421 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
4422 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
4423
4424 room_copy_dict_2 = {}
4425 for room in Room_List_Copy_2:
4426 room_copy_dict_2[room.number] = room
4427
4428 Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
4429
4430 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
4431 #######################################################
4432
4433 Allocate_Smoke(Heap_Copy_2, neighbor_copy.number, Overlay_Dict_Copy_2)
4434 action_list010.append("Superslide with Smoke still allocated")
4435
4436 # The room we superslide into through the plane corresponding to the given pot
4437 destination_room = Current_Room([neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
4438
4439 destination_room_copy = room_copy_dict_2[destination_room.number]
4440 neighbor_copy_2 = room_copy_dict_2[neighbor_copy.number]
4441
4442 pot_copy = Find_Actor_Copy(pot, Room_List_Copy_2)
4443 superslide_transition_copy = Grabbable_Dict_Copy_2[pot_copy][1]
4444
4445 Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
4446 action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4447
4448 # Now exit the chest room
4449 Load_Room(Heap_Copy_2, neighbor_copy_2, superslide_transition_copy, Overlay_Dict_Copy_2)
4450 action_list010.append("Load Room: Room %d" %(neighbor_copy_2.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4451
4452 # Now reenter the chest room
4453 Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
4454 action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4455
4456 ##### Now check for chests/deku guards
4457
4458 chest_guard_list = []
4459
4460 for entry in Heap_Copy_2:
4461
4462 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
4463 chest_guard_list.append(entry)
4464
4465 soln_found = False
4466 for entry in chest_guard_list:
4467 if (pot.address - entry.address) in Offset_List:
4468
4469 action_list010.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
4470
4471 if (pot.address - entry.address) == 0x160:
4472 angle_solution_count += 1
4473 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4474 elif (pot.address - entry.address) == 0x1F0:
4475 position_solution_count += 1
4476 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4477
4478 soln_found = True
4479
4480 if soln_found is True:
4481 total_action_list = action_list + action_list_transition + action_list010
4482
4483 # the "a" argument is important so we don't overwrite previous solutions
4484 with open(filename, "a") as file:
4485
4486 for action in total_action_list:
4487
4488 file.write(action + "\n")
4489 file.write("-----\n")
4490
4491
4492
4493 #### Bomb and Smoke are both unloaded
4494 elif Grabbable_Dict_Copy[pot][0][2] == '1':
4495
4496 action_list001 = []
4497
4498 # COPY STATE
4499 #######################################################
4500 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
4501 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
4502
4503 room_copy_dict_2 = {}
4504 for room in Room_List_Copy_2:
4505 room_copy_dict_2[room.number] = room
4506
4507 Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
4508
4509 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
4510 #######################################################
4511
4512 # Do not allocate anything
4513 action_list001.append("Superslide with Bomb and Smoke unloaded when passing plane")
4514
4515 # The room we superslide into through the plane corresponding to the given pot
4516 destination_room = Current_Room([neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
4517
4518 destination_room_copy = room_copy_dict_2[destination_room.number]
4519 neighbor_copy_2 = room_copy_dict_2[neighbor_copy.number]
4520
4521 pot_copy = Find_Actor_Copy(pot, Room_List_Copy_2)
4522 superslide_transition_copy = Grabbable_Dict_Copy_2[pot_copy][1]
4523
4524 Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
4525 action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4526
4527 # Now exit the chest room
4528 Load_Room(Heap_Copy_2, neighbor_copy_2, superslide_transition_copy, Overlay_Dict_Copy_2)
4529 action_list001.append("Load Room: Room %d" %(neighbor_copy_2.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4530
4531 # Now reenter the chest room
4532 Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
4533 action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4534
4535 ##### Now check for chests/deku guards
4536
4537 chest_guard_list = []
4538
4539 for entry in Heap_Copy_2:
4540
4541 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
4542 chest_guard_list.append(entry)
4543
4544 soln_found = False
4545 for entry in chest_guard_list:
4546 if (pot.address - entry.address) in Offset_List:
4547
4548 action_list001.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
4549
4550 if (pot.address - entry.address) == 0x160:
4551 angle_solution_count += 1
4552 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4553 elif (pot.address - entry.address) == 0x1F0:
4554 position_solution_count += 1
4555 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4556
4557 soln_found = True
4558
4559 if soln_found is True:
4560 total_action_list = action_list + action_list_transition + action_list001
4561
4562 # the "a" argument is important so we don't overwrite previous solutions
4563 with open(filename, "a") as file:
4564
4565 for action in total_action_list:
4566
4567 file.write(action + "\n")
4568 file.write("-----\n")
4569
4570
4571 ##### No valid grabbable actor in neighbor
4572 elif neighbor not in valid_grabbable_actor_room_list:
4573
4574 for new_neighbor in Neighbors(neighbor, Room_List):
4575
4576 # if new neighbor has a valid grabbable actor... (Otherwise, we do nothing)
4577 if new_neighbor in valid_grabbable_actor_room_list:
4578
4579
4580 for neighbor_transition in Shared_Transitions(current_room, neighbor):
4581 for new_neighbor_transition in Shared_Transitions(neighbor, new_neighbor):
4582
4583 action_list_transition = []
4584
4585 ##### COPY THE STATE
4586 #######################################################
4587 Room_List_Copy = Copy_Room_List(Room_List)
4588 Overlay_Dict_Copy = Copy_Overlay_Dict(Overlay_Dict)
4589
4590 room_copy_dict = {}
4591 for room in Room_List_Copy:
4592 room_copy_dict[room.number] = room
4593
4594 Heap_Copy = Copy_Heap(Heap, Room_List_Copy, Overlay_Dict_Copy)
4595
4596 Grabbable_Dict_Copy = Copy_Grabbable_Dict(Grabbable_Dict, Room_List_Copy)
4597 #######################################################
4598
4599 neighbor_copy = room_copy_dict[neighbor.number]
4600 neighbor_transition_copy = Find_Actor_Copy(neighbor_transition, Room_List_Copy)
4601
4602 new_neighbor_copy = room_copy_dict[new_neighbor.number]
4603 new_neighbor_transition_copy = Find_Actor_Copy(new_neighbor_transition, Room_List_Copy)
4604
4605 ##### ENTER neighbor
4606
4607 Load_Room(Heap_Copy, neighbor_copy, neighbor_transition_copy, Overlay_Dict_Copy)
4608 action_list_transition.append("Load Room: Room %d" %(neighbor_copy.number) + " with " + neighbor_transition_copy.name + " %d" %(neighbor_transition_copy.priority))
4609
4610 ##### ENTER new_neighbor
4611
4612 Load_Room(Heap_Copy, new_neighbor_copy, new_neighbor_transition_copy, Overlay_Dict_Copy)
4613 action_list_transition.append("Load Room: Room %d" %(new_neighbor_copy.number) + " with " + new_neighbor_transition_copy.name + " %d" %(new_neighbor_transition_copy.priority))
4614
4615
4616 ##### Iterate through all pots in this room
4617
4618 valid_pot_list = []
4619 pot_address_list = []
4620
4621 for pot in Grabbable_Dict_Copy:
4622
4623 if Actor_Is_In_Room(new_neighbor_copy, pot) is True:
4624 valid_pot_list.append(pot)
4625 pot_address_list.append(pot.address)
4626
4627 # If there is a chest/guard, superslide, then check neighbors for chests/guards and test all (copy state)
4628 if Chest_In_Room(new_neighbor) == True or Deku_Guard_In_Room(new_neighbor) == True:
4629
4630 for pot in valid_pot_list:
4631
4632 # both bomb and smoke loaded on superslide
4633 if Grabbable_Dict_Copy[pot][0][0] == '1':
4634
4635 action_list100 = []
4636
4637 # COPY STATE
4638 #######################################################
4639 Room_List_Copy_SS = Copy_Room_List(Room_List_Copy)
4640 Overlay_Dict_Copy_SS = Copy_Overlay_Dict(Overlay_Dict_Copy)
4641
4642 room_copy_dict_SS = {}
4643 for room in Room_List_Copy_SS:
4644 room_copy_dict_SS[room.number] = room
4645
4646 Heap_Copy_SS = Copy_Heap(Heap_Copy, Room_List_Copy_SS, Overlay_Dict_Copy_SS)
4647
4648 Grabbable_Dict_Copy_SS = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_SS)
4649 #######################################################
4650
4651 Bomb_And_Smoke_Superslide(Heap_Copy_SS, new_neighbor.number, Overlay_Dict_Copy_SS)
4652 action_list100.append("Superslide with Bomb and Smoke still allocated")
4653
4654 # The room we superslide into through the plane corresponding to the given pot
4655 destination_room = Current_Room([new_neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
4656
4657 destination_room_copy = room_copy_dict_SS[destination_room.number]
4658
4659 pot_copy = Find_Actor_Copy(pot, Room_List_Copy_SS)
4660 superslide_transition_copy = Grabbable_Dict_Copy_SS[pot_copy][1]
4661
4662 Load_Room(Heap_Copy_SS, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_SS)
4663 action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4664
4665 """
4666
4667 Now we check all neighbors of our current room (destination_room) and for
4668 each neighbor that has a chest or deku guard in it, we will create a copy
4669 of our copy of the state, then enter each of them through each possible
4670 loading plane and then check the chest/guard addresses and see if anything
4671 lines up
4672
4673 """
4674
4675 for bordering_room in Neighbors(destination_room, Room_List):
4676
4677 if Chest_In_Room(bordering_room) == True or Deku_Guard_In_Room(bordering_room) == True:
4678
4679 for loading_plane in Shared_Transitions(destination_room, bordering_room):
4680
4681 # COPY STATE
4682 #######################################################
4683 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy_SS)
4684 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy_SS)
4685
4686 room_copy_dict_2 = {}
4687 for room in Room_List_Copy_2:
4688 room_copy_dict_2[room.number] = room
4689
4690 Heap_Copy_2 = Copy_Heap(Heap_Copy_SS, Room_List_Copy_2, Overlay_Dict_Copy_2)
4691
4692 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy_SS, Room_List_Copy_2)
4693 #######################################################
4694
4695 action_list_2 = []
4696
4697 loading_plane_copy = Find_Actor_Copy(loading_plane, Room_List_Copy_2)
4698
4699 bordering_room_copy = room_copy_dict_2[bordering_room.number]
4700
4701 Load_Room(Heap_Copy_2, bordering_room_copy, loading_plane_copy, Overlay_Dict_Copy_2)
4702 action_list_2.append("Load Room: Room %d" %(bordering_room_copy.number) + " with " + loading_plane_copy.name + " %d" %(loading_plane_copy.priority))
4703
4704
4705 ##### Now check for chests/deku guards
4706
4707 chest_guard_list = []
4708
4709 for entry in Heap_Copy_2:
4710
4711 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
4712 chest_guard_list.append(entry)
4713
4714 soln_found = False
4715 for entry in chest_guard_list:
4716 if (pot.address - entry.address) in Offset_List:
4717
4718 action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
4719
4720 if (pot.address - entry.address) == 0x160:
4721 angle_solution_count += 1
4722 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4723 elif (pot.address - entry.address) == 0x1F0:
4724 position_solution_count += 1
4725 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4726
4727 soln_found = True
4728
4729 if soln_found is True:
4730 total_action_list = action_list + action_list_transition + action_list100 + action_list_2
4731
4732 # the "a" argument is important so we don't overwrite previous solutions
4733 with open(filename, "a") as file:
4734
4735 for action in total_action_list:
4736
4737 file.write(action + "\n")
4738 file.write("-----\n")
4739
4740
4741
4742 ##### Only smoke is loaded from superslide
4743 elif Grabbable_Dict_Copy[pot][0][1] == '1':
4744
4745 action_list010 = []
4746
4747 # COPY STATE
4748 #######################################################
4749 Room_List_Copy_SS = Copy_Room_List(Room_List_Copy)
4750 Overlay_Dict_Copy_SS = Copy_Overlay_Dict(Overlay_Dict_Copy)
4751
4752 room_copy_dict_SS = {}
4753 for room in Room_List_Copy_SS:
4754 room_copy_dict_SS[room.number] = room
4755
4756 Heap_Copy_SS = Copy_Heap(Heap_Copy, Room_List_Copy_SS, Overlay_Dict_Copy_SS)
4757
4758 Grabbable_Dict_Copy_SS = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_SS)
4759 #######################################################
4760
4761 Allocate_Smoke(Heap_Copy_SS, new_neighbor.number, Overlay_Dict_Copy_SS)
4762 action_list010.append("Superslide with Smoke still allocated")
4763
4764 # The room we superslide into through the plane corresponding to the given pot
4765 destination_room = Current_Room([new_neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
4766
4767 destination_room_copy = room_copy_dict_SS[destination_room.number]
4768
4769 pot_copy = Find_Actor_Copy(pot, Room_List_Copy_SS)
4770 superslide_transition_copy = Grabbable_Dict_Copy_SS[pot_copy][1]
4771
4772 Load_Room(Heap_Copy_SS, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_SS)
4773 action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4774
4775 """
4776
4777 Now we check all neighbors of our current room (destination_room) and for
4778 each neighbor that has a chest or deku guard in it, we will create a copy
4779 of our copy of the state, then enter each of them through each possible
4780 loading plane and then check the chest/guard addresses and see if anything
4781 lines up
4782
4783 """
4784
4785 for bordering_room in Neighbors(destination_room, Room_List):
4786
4787 if Chest_In_Room(bordering_room) == True or Deku_Guard_In_Room(bordering_room) == True:
4788
4789 for loading_plane in Shared_Transitions(destination_room, bordering_room):
4790
4791 # COPY STATE
4792 #######################################################
4793 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy_SS)
4794 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy_SS)
4795
4796 room_copy_dict_2 = {}
4797 for room in Room_List_Copy_2:
4798 room_copy_dict_2[room.number] = room
4799
4800 Heap_Copy_2 = Copy_Heap(Heap_Copy_SS, Room_List_Copy_2, Overlay_Dict_Copy_2)
4801
4802 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy_SS, Room_List_Copy_2)
4803 #######################################################
4804
4805 action_list_2 = []
4806
4807 loading_plane_copy = Find_Actor_Copy(loading_plane, Room_List_Copy_2)
4808
4809 bordering_room_copy = room_copy_dict_2[bordering_room.number]
4810
4811 Load_Room(Heap_Copy_2, bordering_room_copy, loading_plane_copy, Overlay_Dict_Copy_2)
4812 action_list_2.append("Load Room: Room %d" %(bordering_room_copy.number) + " with " + loading_plane_copy.name + " %d" %(loading_plane_copy.priority))
4813
4814
4815 ##### Now check for chests/deku guards
4816
4817 chest_guard_list = []
4818
4819 for entry in Heap_Copy_2:
4820
4821 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
4822 chest_guard_list.append(entry)
4823
4824 soln_found = False
4825 for entry in chest_guard_list:
4826 if (pot.address - entry.address) in Offset_List:
4827
4828 action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
4829
4830 if (pot.address - entry.address) == 0x160:
4831 angle_solution_count += 1
4832 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4833 elif (pot.address - entry.address) == 0x1F0:
4834 position_solution_count += 1
4835 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4836
4837 soln_found = True
4838
4839 if soln_found is True:
4840 total_action_list = action_list + action_list_transition + action_list010 + action_list_2
4841
4842 # the "a" argument is important so we don't overwrite previous solutions
4843 with open(filename, "a") as file:
4844
4845 for action in total_action_list:
4846
4847 file.write(action + "\n")
4848 file.write("-----\n")
4849
4850
4851 #### Bomb and Smoke are both unloaded
4852 elif Grabbable_Dict_Copy[pot][0][2] == '1':
4853
4854 action_list001 = []
4855
4856 # COPY STATE
4857 #######################################################
4858 Room_List_Copy_SS = Copy_Room_List(Room_List_Copy)
4859 Overlay_Dict_Copy_SS = Copy_Overlay_Dict(Overlay_Dict_Copy)
4860
4861 room_copy_dict_SS = {}
4862 for room in Room_List_Copy_SS:
4863 room_copy_dict_SS[room.number] = room
4864
4865 Heap_Copy_SS = Copy_Heap(Heap_Copy, Room_List_Copy_SS, Overlay_Dict_Copy_SS)
4866
4867 Grabbable_Dict_Copy_SS = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_SS)
4868 #######################################################
4869
4870 # Do not allocate anything
4871 action_list001.append("Superslide with Bomb and Smoke unloaded when passing plane")
4872
4873 # The room we superslide into through the plane corresponding to the given pot
4874 destination_room = Current_Room([new_neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
4875
4876 destination_room_copy = room_copy_dict_SS[destination_room.number]
4877
4878 pot_copy = Find_Actor_Copy(pot, Room_List_Copy_SS)
4879 superslide_transition_copy = Grabbable_Dict_Copy_SS[pot_copy][1]
4880
4881 Load_Room(Heap_Copy_SS, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_SS)
4882 action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4883
4884 """
4885
4886 Now we check all neighbors of our current room (destination_room) and for
4887 each neighbor that has a chest or deku guard in it, we will create a copy
4888 of our copy of the state, then enter each of them through each possible
4889 loading plane and then check the chest/guard addresses and see if anything
4890 lines up
4891
4892 """
4893
4894 for bordering_room in Neighbors(destination_room, Room_List):
4895
4896 if Chest_In_Room(bordering_room) == True or Deku_Guard_In_Room(bordering_room) == True:
4897
4898 for loading_plane in Shared_Transitions(destination_room, bordering_room):
4899
4900 # COPY STATE
4901 #######################################################
4902 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy_SS)
4903 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy_SS)
4904
4905 room_copy_dict_2 = {}
4906 for room in Room_List_Copy_2:
4907 room_copy_dict_2[room.number] = room
4908
4909 Heap_Copy_2 = Copy_Heap(Heap_Copy_SS, Room_List_Copy_2, Overlay_Dict_Copy_2)
4910
4911 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy_SS, Room_List_Copy_2)
4912 #######################################################
4913
4914 action_list_2 = []
4915
4916 loading_plane_copy = Find_Actor_Copy(loading_plane, Room_List_Copy_2)
4917
4918 bordering_room_copy = room_copy_dict_2[bordering_room.number]
4919
4920 Load_Room(Heap_Copy_2, bordering_room_copy, loading_plane_copy, Overlay_Dict_Copy_2)
4921 action_list_2.append("Load Room: Room %d" %(bordering_room_copy.number) + " with " + loading_plane_copy.name + " %d" %(loading_plane_copy.priority))
4922
4923
4924 ##### Now check for chests/deku guards
4925
4926 chest_guard_list = []
4927
4928 for entry in Heap_Copy_2:
4929
4930 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
4931 chest_guard_list.append(entry)
4932
4933 soln_found = False
4934 for entry in chest_guard_list:
4935 if (pot.address - entry.address) in Offset_List:
4936
4937 action_list_2.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
4938
4939 if (pot.address - entry.address) == 0x160:
4940 angle_solution_count += 1
4941 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4942 elif (pot.address - entry.address) == 0x1F0:
4943 position_solution_count += 1
4944 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
4945
4946 soln_found = True
4947
4948 if soln_found is True:
4949 total_action_list = action_list + action_list_transition + action_list001 + action_list_2
4950
4951 # the "a" argument is important so we don't overwrite previous solutions
4952 with open(filename, "a") as file:
4953
4954 for action in total_action_list:
4955
4956 file.write(action + "\n")
4957 file.write("-----\n")
4958
4959
4960
4961 # If there isn't a chest/guard, superslide (into chest/guard room by assumption), then exit then reenter it (this case never happens in palace, so this is an okay assumption)
4962 elif Chest_In_Room(new_neighbor) == False and Deku_Guard_In_Room(new_neighbor) == False:
4963
4964 for pot in valid_pot_list:
4965
4966 # both bomb and smoke loaded on superslide
4967 if Grabbable_Dict_Copy[pot][0][0] == '1':
4968
4969 action_list100 = []
4970
4971 # COPY STATE
4972 #######################################################
4973 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
4974 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
4975
4976 room_copy_dict_2 = {}
4977 for room in Room_List_Copy_2:
4978 room_copy_dict_2[room.number] = room
4979
4980 Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
4981
4982 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
4983 #######################################################
4984
4985 Bomb_And_Smoke_Superslide(Heap_Copy_2, new_neighbor_copy.number, Overlay_Dict_Copy_2)
4986 action_list100.append("Superslide with Bomb and Smoke still allocated")
4987
4988 # The room we superslide into through the plane corresponding to the given pot
4989 destination_room = Current_Room([new_neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
4990
4991 destination_room_copy = room_copy_dict_2[destination_room.number]
4992 new_neighbor_copy_2 = room_copy_dict_2[new_neighbor_copy.number]
4993
4994 pot_copy = Find_Actor_Copy(pot, Room_List_Copy_2)
4995 superslide_transition_copy = Grabbable_Dict_Copy_2[pot_copy][1]
4996
4997 Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
4998 action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
4999
5000 # Now exit the chest room
5001 Load_Room(Heap_Copy_2, new_neighbor_copy_2, superslide_transition_copy, Overlay_Dict_Copy_2)
5002 action_list100.append("Load Room: Room %d" %(new_neighbor_copy_2.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
5003
5004 # Now reenter the chest room
5005 Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
5006 action_list100.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
5007
5008 ##### Now check for chests/deku guards
5009
5010 chest_guard_list = []
5011
5012 for entry in Heap_Copy_2:
5013
5014 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
5015 chest_guard_list.append(entry)
5016
5017 soln_found = False
5018 for entry in chest_guard_list:
5019 if (pot.address - entry.address) in Offset_List:
5020
5021 action_list100.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
5022
5023 if (pot.address - entry.address) == 0x160:
5024 angle_solution_count += 1
5025 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
5026 elif (pot.address - entry.address) == 0x1F0:
5027 position_solution_count += 1
5028 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
5029
5030 soln_found = True
5031
5032 if soln_found is True:
5033 total_action_list = action_list + action_list_transition + action_list100
5034
5035 # the "a" argument is important so we don't overwrite previous solutions
5036 with open(filename, "a") as file:
5037
5038 for action in total_action_list:
5039
5040 file.write(action + "\n")
5041 file.write("-----\n")
5042
5043
5044
5045 ##### Only smoke is loaded from superslide
5046 elif Grabbable_Dict_Copy[pot][0][1] == '1':
5047
5048 action_list010 = []
5049
5050 # COPY STATE
5051 #######################################################
5052 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
5053 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
5054
5055 room_copy_dict_2 = {}
5056 for room in Room_List_Copy_2:
5057 room_copy_dict_2[room.number] = room
5058
5059 Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
5060
5061 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
5062 #######################################################
5063
5064 Allocate_Smoke(Heap_Copy_2, new_neighbor_copy.number, Overlay_Dict_Copy_2)
5065 action_list010.append("Superslide with Smoke still allocated")
5066
5067 # The room we superslide into through the plane corresponding to the given pot
5068 destination_room = Current_Room([new_neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
5069
5070 destination_room_copy = room_copy_dict_2[destination_room.number]
5071 new_neighbor_copy_2 = room_copy_dict_2[new_neighbor_copy.number]
5072
5073 pot_copy = Find_Actor_Copy(pot, Room_List_Copy_2)
5074 superslide_transition_copy = Grabbable_Dict_Copy_2[pot_copy][1]
5075
5076 Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
5077 action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
5078
5079 # Now exit the chest room
5080 Load_Room(Heap_Copy_2, new_neighbor_copy_2, superslide_transition_copy, Overlay_Dict_Copy_2)
5081 action_list010.append("Load Room: Room %d" %(new_neighbor_copy_2.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
5082
5083 # Now reenter the chest room
5084 Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
5085 action_list010.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
5086
5087 ##### Now check for chests/deku guards
5088
5089 chest_guard_list = []
5090
5091 for entry in Heap_Copy_2:
5092
5093 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
5094 chest_guard_list.append(entry)
5095
5096 soln_found = False
5097 for entry in chest_guard_list:
5098 if (pot.address - entry.address) in Offset_List:
5099
5100 action_list010.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
5101
5102 if (pot.address - entry.address) == 0x160:
5103 angle_solution_count += 1
5104 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
5105 elif (pot.address - entry.address) == 0x1F0:
5106 position_solution_count += 1
5107 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
5108
5109 soln_found = True
5110
5111 if soln_found is True:
5112 total_action_list = action_list + action_list_transition + action_list010
5113
5114 # the "a" argument is important so we don't overwrite previous solutions
5115 with open(filename, "a") as file:
5116
5117 for action in total_action_list:
5118
5119 file.write(action + "\n")
5120 file.write("-----\n")
5121
5122
5123
5124 #### Bomb and Smoke are both unloaded
5125 elif Grabbable_Dict_Copy[pot][0][2] == '1':
5126
5127 action_list001 = []
5128
5129 # COPY STATE
5130 #######################################################
5131 Room_List_Copy_2 = Copy_Room_List(Room_List_Copy)
5132 Overlay_Dict_Copy_2 = Copy_Overlay_Dict(Overlay_Dict_Copy)
5133
5134 room_copy_dict_2 = {}
5135 for room in Room_List_Copy_2:
5136 room_copy_dict_2[room.number] = room
5137
5138 Heap_Copy_2 = Copy_Heap(Heap_Copy, Room_List_Copy_2, Overlay_Dict_Copy_2)
5139
5140 Grabbable_Dict_Copy_2 = Copy_Grabbable_Dict(Grabbable_Dict_Copy, Room_List_Copy_2)
5141 #######################################################
5142
5143 # Do not allocate anything
5144 action_list001.append("Superslide with Bomb and Smoke unloaded when passing plane")
5145
5146 # The room we superslide into through the plane corresponding to the given pot
5147 destination_room = Current_Room([new_neighbor_copy, Grabbable_Dict_Copy[pot][1]], Room_List_Copy)
5148
5149 destination_room_copy = room_copy_dict_2[destination_room.number]
5150 new_neighbor_copy_2 = room_copy_dict_2[new_neighbor_copy.number]
5151
5152 pot_copy = Find_Actor_Copy(pot, Room_List_Copy_2)
5153 superslide_transition_copy = Grabbable_Dict_Copy_2[pot_copy][1]
5154
5155 Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
5156 action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
5157
5158 # Now exit the chest room
5159 Load_Room(Heap_Copy_2, new_neighbor_copy_2, superslide_transition_copy, Overlay_Dict_Copy_2)
5160 action_list001.append("Load Room: Room %d" %(new_neighbor_copy_2.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
5161
5162 # Now reenter the chest room
5163 Load_Room(Heap_Copy_2, destination_room_copy, superslide_transition_copy, Overlay_Dict_Copy_2)
5164 action_list001.append("Load Room: Room %d" %(destination_room_copy.number) + " with " + superslide_transition_copy.name + " %d" %(superslide_transition_copy.priority))
5165
5166 ##### Now check for chests/deku guards
5167
5168 chest_guard_list = []
5169
5170 for entry in Heap_Copy_2:
5171
5172 if type(entry) == Actor and (entry.Id == '0006' or entry.Id == '017A'):
5173 chest_guard_list.append(entry)
5174
5175 soln_found = False
5176 for entry in chest_guard_list:
5177 if (pot.address - entry.address) in Offset_List:
5178
5179 action_list001.append("SOLUTION: " + pot.name + " (Priority %d)" %(pot.priority) + " from Room %d" %(pot.room_number) + " lines up with " + entry.name + " (Priority %d)" %(entry.priority) + " from Room %d" %(entry.room_number) + " with offset: " + hex(pot.address - entry.address))
5180
5181 if (pot.address - entry.address) == 0x160:
5182 angle_solution_count += 1
5183 print("ANGLE SOLUTION FOUND (CHEST)!!!!!!!!!!!")
5184 elif (pot.address - entry.address) == 0x1F0:
5185 position_solution_count += 1
5186 print("Z POSITION SOLUTION FOUND (CHEST)!!!!!!!!!!!")
5187
5188 soln_found = True
5189
5190 if soln_found is True:
5191 total_action_list = action_list + action_list_transition + action_list001
5192
5193 # the "a" argument is important so we don't overwrite previous solutions
5194 with open(filename, "a") as file:
5195
5196 for action in total_action_list:
5197
5198 file.write(action + "\n")
5199 file.write("-----\n")
5200
5201
5202
5203
5204###############################################################################
5205###############################################################################
5206###############################################################################
5207###############################################################################
5208###############################################################################
5209###############################################################################
5210###############################################################################
5211###############################################################################
5212###############################################################################
5213###############################################################################
5214###############################################################################
5215###############################################################################
5216###############################################################################
5217###############################################################################
5218###############################################################################
5219###############################################################################
5220###############################################################################
5221###############################################################################
5222###############################################################################
5223###############################################################################
5224###############################################################################
5225###############################################################################
5226###############################################################################
5227###############################################################################
5228###############################################################################
5229###############################################################################
5230###############################################################################
5231###############################################################################
5232###############################################################################
5233###############################################################################
5234###############################################################################
5235###############################################################################
5236###############################################################################
5237###############################################################################
5238###############################################################################
5239###############################################################################
5240###############################################################################
5241###############################################################################
5242###############################################################################
5243###############################################################################
5244###############################################################################
5245###############################################################################
5246###############################################################################
5247###############################################################################
5248###############################################################################
5249###############################################################################
5250###############################################################################
5251###############################################################################
5252
5253
5254
5255
5256
5257
5258
5259"""
5260
5261 Before proceeding, we should define all of the transitions we plan on passing through
5262
5263 Since "Beneath the Graveyard" is relatively simple and I currently only want to consider
5264 passing through a single plane, I will just define Plane_1 to be the plane shared between
5265 Room0 and Room1
5266
5267 This loading plane happens the be the second element in Room0_queue, so I will define it based on that
5268
5269"""
5270
5271Oceanside_Plane_0 = Oceanside_Room3_queue[0]
5272
5273
5274
5275Palace_Plane_0 = Palace_Room0_queue[0]
5276
5277"""
5278
5279 Grabbable_dict is a dictionary of the grabbable actors (such as pots) that
5280 we want to attempt to use for superslide SRM where the keys are the grabbable
5281 actors and the values are lists with 3-bit strings where each bit means:
5282
5283 100 : Possible to enter Plane with both Bomb and Smoke loaded
5284 010 : Possible to enter Plane with Smoke loaded, but no Bomb loaded
5285 001 : Possible to enter Plane with no Smoke loaded
5286
5287 and Transitions, where the transitions are the ones you can superslide through
5288
5289
5290"""
5291
5292Oceanside_Grabbable_dict = {
5293 Oceanside_Room3_queue[6] : ['010', Oceanside_Plane_0],
5294 Oceanside_Room3_queue[7] : ['010', Oceanside_Plane_0]
5295 }
5296
5297Palace_Grabbable_dict = {
5298 Palace_Room1_queue[18] : ['010', Palace_Plane_0]
5299 }
5300
5301
5302Hardcoded_Allocation_List_0 = [
5303 'Fish',
5304 'Fish',
5305 'Bugs',
5306 'Bugs',
5307 'Smoke',
5308 'Chu',
5309 'Chu',
5310 'Chu',
5311 'Arrow',
5312 'Arrow',
5313 'Arrow',
5314 'Arrow',
5315 'Arrow',
5316 'Bomb',
5317 'Bomb',
5318 'Bomb',
5319 'Zora Fins',
5320 'Hookshot',
5321 'Charged Spin Attack'
5322 ]
5323
5324Hardcoded_Allocation_List_2 = [
5325 'Smoke',
5326 'Arrow',
5327 'Arrow',
5328 'Arrow',
5329 'Arrow',
5330 'Arrow',
5331 'Bomb',
5332 'Bomb',
5333 'Bomb',
5334 'Hookshot',
5335 'Charged Spin Attack'
5336 ]
5337
5338Hardcoded_Allocation_List_2_G = [
5339 'Gold Skulltula'
5340 'Smoke',
5341 'Arrow',
5342 'Arrow',
5343 'Arrow',
5344 'Arrow',
5345 'Arrow',
5346 'Bomb',
5347 'Bomb',
5348 'Bomb',
5349 'Hookshot',
5350 'Charged Spin Attack'
5351 ]
5352
5353Hardcoded_Allocation_List_3 = [
5354 'Bomb',
5355 'Bomb',
5356 'Bomb',
5357 'Hookshot',
5358 'Charged Spin Attack'
5359 ]
5360
5361Hardcoded_Allocation_List_4 = [
5362 'Arrow',
5363 'Arrow',
5364 'Arrow',
5365 'Arrow',
5366 'Arrow',
5367 'Bomb',
5368 'Bomb',
5369 'Bomb',
5370 'Hookshot',
5371 'Charged Spin Attack'
5372 ]
5373
5374
5375
5376
5377Allocation_List_0 = [
5378 'Fish',
5379 'Smoke',
5380 'Arrow',
5381 'Arrow',
5382 'Arrow',
5383 'Bomb',
5384 'Bomb',
5385 'Bomb',
5386 'Zora Fins',
5387 'Hookshot',
5388 'Charged Spin Attack'
5389 ]
5390
5391Allocation_List_0_G = [
5392 'Gold Skulltula',
5393 'Fish',
5394 'Smoke',
5395 'Arrow',
5396 'Arrow',
5397 'Arrow',
5398 'Bomb',
5399 'Bomb',
5400 'Bomb',
5401 'Zora Fins',
5402 'Hookshot',
5403 'Charged Spin Attack'
5404 ]
5405
5406
5407
5408Allocation_List_5 = [
5409 'Smoke',
5410 'Arrow',
5411 'Arrow',
5412 'Arrow',
5413 'Bomb',
5414 'Bomb',
5415 'Bomb',
5416 'Zora Fins',
5417 'Hookshot',
5418 'Charged Spin Attack'
5419 ]
5420
5421Allocation_List_5_G = [
5422 'Gold Skulltula',
5423 'Smoke',
5424 'Arrow',
5425 'Arrow',
5426 'Arrow',
5427 'Bomb',
5428 'Bomb',
5429 'Bomb',
5430 'Zora Fins',
5431 'Hookshot',
5432 'Charged Spin Attack'
5433 ]
5434
5435Hardcoded_Allocation_List_4 = [
5436 'Arrow',
5437 'Hookshot',
5438 'Charged Spin Attack'
5439 ]
5440
5441Oceanside_Allocation_List_6 = [
5442 'Fish',
5443 'Fish'
5444 'Smoke',
5445 'Chu',
5446 'Chu',
5447 'Chu',
5448 'Arrow',
5449 'Arrow',
5450 'Arrow',
5451 'Arrow',
5452 'Arrow',
5453 'Bomb',
5454 'Bomb',
5455 'Bomb',
5456 'Hookshot',
5457 'Charged Spin Attack'
5458 ]
5459
5460Oceanside_Allocation_List_6_G = [
5461 'Gold Skulltula',
5462 'Fish',
5463 'Fish'
5464 'Smoke',
5465 'Chu',
5466 'Chu',
5467 'Chu',
5468 'Arrow',
5469 'Arrow',
5470 'Arrow',
5471 'Arrow',
5472 'Arrow',
5473 'Bomb',
5474 'Bomb',
5475 'Bomb',
5476 'Hookshot',
5477 'Charged Spin Attack'
5478 ]
5479
5480Allocation_List_Dict_Grave_0 = {
5481 0 : Hardcoded_Allocation_List_3,
5482 1 : Hardcoded_Allocation_List_3
5483 }
5484
5485Allocation_List_Dict_Grave_4 = {
5486 0 : Hardcoded_Allocation_List_4,
5487 1 : Hardcoded_Allocation_List_4
5488 }
5489
5490Allocation_List_Dict_Oceanside_0 = {
5491 3 : Hardcoded_Allocation_List_2_G,
5492 4 : Hardcoded_Allocation_List_2
5493 }
5494
5495Allocation_List_Dict_Oceanside_1 = {
5496 3 : Allocation_List_0_G,
5497 4 : Allocation_List_0
5498 }
5499
5500Allocation_List_Dict_Oceanside_5 = {
5501 3 : Allocation_List_5_G,
5502 4 : Allocation_List_5
5503 }
5504
5505Allocation_List_Dict_Oceanside_6 = {
5506 3 : Oceanside_Allocation_List_6_G,
5507 4 : Oceanside_Allocation_List_6
5508 }
5509
5510save_path = "C:\\Users\\xyzabc\\Documents\\Bizhawk RAM Watch\\scripts\\"
5511name_of_file = "osh"
5512complete_name = save_path + name_of_file + ".txt"
5513
5514Heap = [Node(0x40B140, node_size), Node(0x5FFFFF, node_size)]
5515
5516##### OCEANSIDE
5517Randomized_Solver(Oceanside_Room3, Oceanside_Room_List, 5, Allocation_List_Dict_Oceanside_6, Oceanside_Grabbable_dict, Overlay_dict, complete_name, [0x160, 0x1F0], Heap)
5518
5519
5520##### BENEATH THE GRAVEYARD
5521#Randomized_Solver(Room0, Room_List, 5, Allocation_List_Dict_Grave_4, Grabbable_dict, Overlay_dict, complete_name, [0x160, 0x1F0], Heap)
5522
5523
5524"""
5525
5526SOME ASSUMPTIONS ABOUT THIS SCRIPT:
5527
5528 - THE SOLVER AUTOMATICALLY CLEARS ALL BAD BATS AT THE START
5529
5530 - WE DO NOT DEALLOCATE WEBS OR GOLD SKULLTULAS IN OCEANSIDE BECAUSE WE WANT
5531 A SETUP THAT DOES NOT NEED SONG OF TIME STORAGE TO DO REPEATEDLY. EVEN IF IT
5532 ALLOWED DEALLOCATIONG GOLD SKULLTULAS, IT DOES NOT ACCOUNT FOR THE TOKENS AND
5533 IT ASSUMES DEALLOCATING A GOLD SKULLTULA IS EQUIVALENT TO PICKING UP ITS TOKEN
5534
5535 - WE ASSUME THAT WE ALWAYS PERFORM THE DEALLOCATION STEPS BEFORE THE ALLOCATION
5536 STEPS BECAUSE IT IS EASIER TO DEAL WITH SOLUTIONS WITH THIS QUALITY
5537
5538 - THIS SCRIPT HARDCODES HOW WE DEALLOCATE THE 01E7 BONK ACTORS FOR THE OCEANSIDE
5539 ROOM 3 TABLE
5540
5541 - ALLOCATING GOLD SKULLTULAS IS SPECIFIC TO ROOM 3 OF OCEANSIDE (SHOOTING THE
5542 PAINTING ALLOCATES A GOLD SKULLTULA)
5543
5544 TODO: (DEKU PALACE CONTEXT) WANT A WAY TO ASSERT THAT A POT NEEDS
5545 TO BREAK BEFORE PALACE SUPERSLIDE FOR ONE OF THE POTS (I THINK; NEEDS TESTING)
5546
5547 TODO: Load_Room() always assumes that cluster is loaded after the previous room
5548 deallocates, Load_Room_No_Rupee_Cluster() will load the room but not the rupees
5549 from the cluster (though it technically still loads the cluster actor 00E8 itself,
5550 just not the 000E rupees it spawns), and Load_Room_Rupee_Cluster_Before_Previous_Unloads()
5551 assumes the cluster loads before the previous room deallocates (and this one will only
5552 apply to graveyard)
5553
5554
5555
5556"""
5557
5558"""
5559Overlay_Dict = Overlay_dict
5560Room_List = Oceanside_Room_List
5561
5562
5563Load_Scene(Heap, Room_List[0], Overlay_Dict)
5564
5565#Display_Heap(Heap)
5566
5567print('***********************************************************************')
5568print('***********************************************************************')
5569print('***********************************************************************')
5570
5571
5572Deallocate(Heap, Room_List[0].priority_queue[2], Overlay_Dict)
5573Deallocate(Heap, Room_List[0].priority_queue[5], Overlay_Dict)
5574Deallocate(Heap, Room_List[0].priority_queue[6], Overlay_Dict)
5575Deallocate(Heap, Room_List[0].priority_queue[7], Overlay_Dict)
5576Deallocate(Heap, Room_List[0].priority_queue[15], Overlay_Dict)
5577Deallocate(Heap, Room_List[0].priority_queue[17], Overlay_Dict)
5578Deallocate(Heap, Room_List[0].priority_queue[19], Overlay_Dict)
5579
5580#Display_Heap(Heap)
5581
5582print('DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD')
5583
5584Allocate_Arrow(Heap, 3, Overlay_Dict) # 3 for Room 3
5585Allocate_Arrow(Heap, 3, Overlay_Dict) # 3 for Room 3
5586Allocate_Bomb(Heap, 3, Overlay_Dict) # 3 for Room 3
5587Allocate_Bomb(Heap, 3, Overlay_Dict) # 3 for Room 3
5588
5589#Display_Heap(Heap)
5590
5591print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
5592
5593Load_Room(Heap, Room_List[1], Room_List[0].priority_queue[0], Overlay_Dict)
5594
5595#Display_Heap(Heap)
5596
5597print('***********************************************************************')
5598print('***********************************************************************')
5599print('***********************************************************************')
5600
5601
5602Allocate_Smoke(Heap, 4, Overlay_Dict)
5603Allocate_Arrow(Heap, 4, Overlay_Dict)
5604Allocate_Arrow(Heap, 4, Overlay_Dict)
5605Allocate_Arrow(Heap, 4, Overlay_Dict)
5606Allocate_Arrow(Heap, 4, Overlay_Dict)
5607Allocate_Bomb(Heap, 4, Overlay_Dict)
5608Allocate_Bomb(Heap, 4, Overlay_Dict)
5609Allocate_Charged_Spin_Attack(Heap, 4, Overlay_Dict)
5610
5611Display_Heap(Heap)
5612
5613print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
5614
5615Load_Room(Heap, Room_List[0], Room_List[0].priority_queue[0], Overlay_Dict)
5616
5617Display_Heap(Heap)
5618
5619print('***********************************************************************')
5620print('***********************************************************************')
5621print('***********************************************************************')
5622
5623
5624Deallocate(Heap, Room_List[0].priority_queue[2], Overlay_Dict)
5625Deallocate(Heap, Room_List[0].priority_queue[4], Overlay_Dict)
5626Deallocate(Heap, Room_List[0].priority_queue[15], Overlay_Dict)
5627Deallocate(Heap, Room_List[0].priority_queue[17], Overlay_Dict)
5628Deallocate(Heap, Room_List[0].priority_queue[19], Overlay_Dict)
5629Deallocate(Heap, Room_List[0].priority_queue[23], Overlay_Dict)
5630
5631Display_Heap(Heap)
5632
5633print('DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD')
5634
5635Allocate_Smoke(Heap, 3, Overlay_Dict)
5636Allocate_Arrow(Heap, 3, Overlay_Dict)
5637Allocate_Arrow(Heap, 3, Overlay_Dict)
5638
5639Display_Heap(Heap)
5640
5641print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
5642
5643Load_Room(Heap, Room_List[1], Room_List[0].priority_queue[0], Overlay_Dict)
5644
5645Display_Heap(Heap)
5646
5647print('***********************************************************************')
5648print('***********************************************************************')
5649print('***********************************************************************')
5650
5651
5652Allocate_Smoke(Heap, 4, Overlay_Dict)
5653Allocate_Bomb(Heap, 4, Overlay_Dict)
5654
5655Display_Heap(Heap)
5656
5657print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
5658
5659Load_Room(Heap, Room_List[0], Room_List[0].priority_queue[0], Overlay_Dict)
5660
5661Display_Heap(Heap)
5662
5663print('***********************************************************************')
5664print('***********************************************************************')
5665print('***********************************************************************')
5666
5667Allocate_Smoke(Heap, 3, Overlay_Dict) # superslide with smoke still allocated
5668
5669Display_Heap(Heap)
5670
5671print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
5672
5673Load_Room(Heap, Room_List[1], Room_List[0].priority_queue[0], Overlay_Dict)
5674
5675Display_Heap(Heap)
5676
5677print('***********************************************************************')
5678print('***********************************************************************')
5679print('***********************************************************************')
5680
5681
5682Load_Room(Heap, Room_List[0], Room_List[0].priority_queue[0], Overlay_Dict)
5683
5684Display_Heap(Heap)
5685
5686print('***********************************************************************')
5687print('***********************************************************************')
5688print('***********************************************************************')
5689
5690
5691Load_Room(Heap, Room_List[1], Room_List[0].priority_queue[0], Overlay_Dict)
5692
5693
5694Display_Heap(Heap)
5695
5696"""