diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..ece96da77 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +/data/rom_patch.txt binary +/data/symbols.json binary diff --git a/.gitignore b/.gitignore index b7687ceef..91ea2db35 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,13 @@ .*.sw* .sw* *.pyc +/.vs +settings.sav +ARCHIVE.bin +output/* +*.z64 +*.z64.bak +*.pyo +*.spec +dist/ +build/ diff --git a/ASM/.gitattributes b/ASM/.gitattributes new file mode 100644 index 000000000..f153601a9 --- /dev/null +++ b/ASM/.gitattributes @@ -0,0 +1,2 @@ +*.bin binary +/build/* binary diff --git a/ASM/.gitignore b/ASM/.gitignore index fda3bd009..dbe12b034 100644 --- a/ASM/.gitignore +++ b/ASM/.gitignore @@ -1,5 +1,5 @@ /inject /roms/* -/temp/* +/c/*.o armips* !.gitkeep diff --git a/ASM/README.md b/ASM/README.md index 68654ceaa..2f2f0a226 100644 --- a/ASM/README.md +++ b/ASM/README.md @@ -1,8 +1,13 @@ -- Download the armips assembler: and put the - executable in the `scripts` directory, or somewhere in your PATH +- Download the armips assembler: and put + the executable in the `scripts` directory, or somewhere in your PATH - Put the ROM you want to patch at `roms/base.z64` -- Run `python3 scripts/build.py`, which will create `roms/patched.z64` -- To update the front-end patch file, run: - ```python3 scripts/rom_diff.py roms/base.z64 roms/patched.z64 ../data/base2current.json``` +- Run `python scripts/build.py`, which will: + - create `roms/patched.z64` + - update `../data/rom_patch.txt` and `../data/symbols.json` -To generate debugging symbols for the Project 64 debugger, run `python3 scripts/build.py --pj64sym 'path_to_pj64/Saves/THE LEGEND OF ZELDA.sym'` +To generate debugging symbols for the Project 64 debugger, use the `--pj64sym` +option: +`python scripts/build.py --pj64sym 'path_to_pj64/Saves/THE LEGEND OF ZELDA.sym'`. + +To recompile the C modules, use the `--compile-c` option. This requires the +N64 development tools to be installed: diff --git a/ASM/temp/.gitkeep b/ASM/build/.gitkeep similarity index 100% rename from ASM/temp/.gitkeep rename to ASM/build/.gitkeep diff --git a/ASM/build/asm_symbols.txt b/ASM/build/asm_symbols.txt new file mode 100644 index 000000000..6701a0219 --- /dev/null +++ b/ASM/build/asm_symbols.txt @@ -0,0 +1,1109 @@ +00000000 0 +00000000 .byt:4000000 +00000010 .dbl:0008 +00000010 ITEM_TABLE_ROW_SIZE +000005B4 Shop_Item_Save_Offset +0000D260 .dbl:0010 +0000D270 .dbl:0010 +0089E800 .byt:0400 +00B529A0 skip_GS_BGS_text +00BAF750 .byt:0048 +00D74990 skip_steal_tunic +00D7E178 @@not_in_ranch +00D7E18C @@return +00D7E18C return_from_the_other_function +00D7E3AC @@hyrule_check +00D7E3CC @@lon_lon_check +00D7E3F4 @@return_false +00D7E7A4 @@set_ev0 +00D7E7B8 set_ev1 +00D7E8A8 @@unsafe +00D7E8C0 @@safe +00D7E8D4 @@not_hyrule +00D7E920 ev0_return +00DB13D3 .byt:0001 +00DF264F .byt:0001 +00E2F093 .byt:0001 +00EBB8B0 @Deku_Check_True +00EBB8C0 @Deku_Check_False +00EC68D0 .byt:0014 +00EC69C0 .byt:0014 +00EC9CE7 .byt:0001 +8011A5D0 SAVE_CONTEXT +801C84A0 GLOBAL_CONTEXT +801D8C00 SUBSCREEN_CONTEXT +801DAA30 PLAYER_ACTOR +803A9E7E GET_ITEMTABLE +80400000 init +80400050 DebugOutput +80401000 .byt:0800 +80401000 ITEM_OVERRIDES +80401800 .byt:0400 +80401800 INITIAL_SAVE_DATA +80401C00 .byt:0001 +80401C00 PLAYER_ID +80401C01 .byt:0001 +80401C01 COOP_GET_ITEM +80401C02 .byt:0001 +80401C02 PLAYER_NAME_ID +80401C03 .byt:0100 +80401C03 PLAYER_NAMES +80401D03 .byt:0001 +80401D03 LIGHT_ARROW_ITEM +80401D04 .byt:0001 +80401D04 FAIRY_OCARINA_ITEM +80401D05 .byt:0001 +80401D05 FAIRY_ITEMS +80401D06 .byt:0001 +80401D07 .byt:0001 +80401D08 .byt:0001 +80401D09 .byt:0001 +80401D0A .byt:0001 +80401D0C .byt:02F4 +80402000 .dbl:0008 +80402000 PLAYER_OVERRIDE_DATA +80402008 .dbl:0010 +80402008 EXTENDED_ITEM_DATA +80402018 .byt:0001 +80402018 PENDING_SPECIAL_ITEM +80402019 .byt:0001 +8040201A .byt:0001 +8040201B .byt:0001 +8040201B PENDING_SPECIAL_ITEM_END +8040201C .dbl:0004 +8040201C TIME_TRAVEL_SAVED_EQUIPS +80402020 .dbl:0004 +80402024 .wrd:0002 +80402026 .wrd:0002 +80402028 .byt:0028 +80402050 .byt:0001 +80402050 ITEM_TABLE +80402051 .byt:0001 +80402052 .byt:0001 +80402053 .byt:0001 +80402054 .wrd:0002 +80402056 .byt:0001 +80402057 .byt:0001 +80402058 .dbl:0004 +8040205C .dbl:0004 +80402060 .byt:0001 +80402061 .byt:0001 +80402062 .byt:0001 +80402063 .byt:0001 +80402064 .wrd:0002 +80402066 .byt:0001 +80402067 .byt:0001 +80402068 .dbl:0004 +8040206C .dbl:0004 +80402070 .byt:0001 +80402071 .byt:0001 +80402072 .byt:0001 +80402073 .byt:0001 +80402074 .wrd:0002 +80402076 .byt:0001 +80402077 .byt:0001 +80402078 .dbl:0004 +8040207C .dbl:0004 +80402080 .byt:0001 +80402081 .byt:0001 +80402082 .byt:0001 +80402083 .byt:0001 +80402084 .wrd:0002 +80402086 .byt:0001 +80402087 .byt:0001 +80402088 .dbl:0004 +8040208C .dbl:0004 +80402090 .byt:0001 +80402091 .byt:0001 +80402092 .byt:0001 +80402093 .byt:0001 +80402094 .wrd:0002 +80402096 .byt:0001 +80402097 .byt:0001 +80402098 .dbl:0004 +8040209C .dbl:0004 +804020A0 .byt:0001 +804020A1 .byt:0001 +804020A2 .byt:0001 +804020A3 .byt:0001 +804020A4 .wrd:0002 +804020A6 .byt:0001 +804020A7 .byt:0001 +804020A8 .dbl:0004 +804020AC .dbl:0004 +804020B0 .byt:0001 +804020B1 .byt:0001 +804020B2 .byt:0001 +804020B3 .byt:0001 +804020B4 .wrd:0002 +804020B6 .byt:0001 +804020B7 .byt:0001 +804020B8 .dbl:0004 +804020BC .dbl:0004 +804020C0 .byt:0001 +804020C1 .byt:0001 +804020C2 .byt:0001 +804020C3 .byt:0001 +804020C4 .wrd:0002 +804020C6 .byt:0001 +804020C7 .byt:0001 +804020C8 .dbl:0004 +804020CC .dbl:0004 +804020D0 .byt:0001 +804020D1 .byt:0001 +804020D2 .byt:0001 +804020D3 .byt:0001 +804020D4 .wrd:0002 +804020D6 .byt:0001 +804020D7 .byt:0001 +804020D8 .dbl:0004 +804020DC .dbl:0004 +804020E0 .byt:0001 +804020E1 .byt:0001 +804020E2 .byt:0001 +804020E3 .byt:0001 +804020E4 .wrd:0002 +804020E6 .byt:0001 +804020E7 .byt:0001 +804020E8 .dbl:0004 +804020EC .dbl:0004 +804020F0 .byt:0001 +804020F1 .byt:0001 +804020F2 .byt:0001 +804020F3 .byt:0001 +804020F4 .wrd:0002 +804020F6 .byt:0001 +804020F7 .byt:0001 +804020F8 .dbl:0004 +804020FC .dbl:0004 +80402100 .byt:0001 +80402101 .byt:0001 +80402102 .byt:0001 +80402103 .byt:0001 +80402104 .wrd:0002 +80402106 .byt:0001 +80402107 .byt:0001 +80402108 .dbl:0004 +8040210C .dbl:0004 +80402110 .byt:0001 +80402111 .byt:0001 +80402112 .byt:0001 +80402113 .byt:0001 +80402114 .wrd:0002 +80402116 .byt:0001 +80402117 .byt:0001 +80402118 .dbl:0004 +8040211C .dbl:0004 +80402120 .byt:0001 +80402121 .byt:0001 +80402122 .byt:0001 +80402123 .byt:0001 +80402124 .wrd:0002 +80402126 .byt:0001 +80402127 .byt:0001 +80402128 .dbl:0004 +8040212C .dbl:0004 +80402130 .byt:0001 +80402131 .byt:0001 +80402132 .byt:0001 +80402133 .byt:0001 +80402134 .wrd:0002 +80402136 .byt:0001 +80402137 .byt:0001 +80402138 .dbl:0004 +8040213C .dbl:0004 +80402140 .byt:0001 +80402141 .byt:0001 +80402142 .byt:0001 +80402143 .byt:0001 +80402144 .wrd:0002 +80402146 .byt:0001 +80402147 .byt:0001 +80402148 .dbl:0004 +8040214C .dbl:0004 +80402150 .byt:0001 +80402151 .byt:0001 +80402152 .byt:0001 +80402153 .byt:0001 +80402154 .wrd:0002 +80402156 .byt:0001 +80402157 .byt:0001 +80402158 .dbl:0004 +8040215C .dbl:0004 +80402160 .byt:0001 +80402161 .byt:0001 +80402162 .byt:0001 +80402163 .byt:0001 +80402164 .wrd:0002 +80402166 .byt:0001 +80402167 .byt:0001 +80402168 .dbl:0004 +8040216C .dbl:0004 +80402170 .byt:0001 +80402171 .byt:0001 +80402172 .byt:0001 +80402173 .byt:0001 +80402174 .wrd:0002 +80402176 .byt:0001 +80402177 .byt:0001 +80402178 .dbl:0004 +8040217C .dbl:0004 +80402180 .byt:0001 +80402181 .byt:0001 +80402182 .byt:0001 +80402183 .byt:0001 +80402184 .wrd:0002 +80402186 .byt:0001 +80402187 .byt:0001 +80402188 .dbl:0004 +8040218C .dbl:0004 +80402190 .byt:0001 +80402191 .byt:0001 +80402192 .byt:0001 +80402193 .byt:0001 +80402194 .wrd:0002 +80402196 .byt:0001 +80402197 .byt:0001 +80402198 .dbl:0004 +8040219C .dbl:0004 +804021A0 .byt:0001 +804021A1 .byt:0001 +804021A2 .byt:0001 +804021A3 .byt:0001 +804021A4 .wrd:0002 +804021A6 .byt:0001 +804021A7 .byt:0001 +804021A8 .dbl:0004 +804021AC .dbl:0004 +804021B0 .byt:0001 +804021B1 .byt:0001 +804021B2 .byt:0001 +804021B3 .byt:0001 +804021B4 .wrd:0002 +804021B6 .byt:0001 +804021B7 .byt:0001 +804021B8 .dbl:0004 +804021BC .dbl:0004 +804021C0 .byt:0001 +804021C1 .byt:0001 +804021C2 .byt:0001 +804021C3 .byt:0001 +804021C4 .wrd:0002 +804021C6 .byt:0001 +804021C7 .byt:0001 +804021C8 .dbl:0004 +804021CC .dbl:0004 +804021D0 .byt:0001 +804021D1 .byt:0001 +804021D2 .byt:0001 +804021D3 .byt:0001 +804021D4 .wrd:0002 +804021D6 .byt:0001 +804021D7 .byt:0001 +804021D8 .dbl:0004 +804021DC .dbl:0004 +804021E0 .byt:0001 +804021E1 .byt:0001 +804021E2 .byt:0001 +804021E3 .byt:0001 +804021E4 .wrd:0002 +804021E6 .byt:0001 +804021E7 .byt:0001 +804021E8 .dbl:0004 +804021EC .dbl:0004 +804021F0 .byt:0001 +804021F1 .byt:0001 +804021F2 .byt:0001 +804021F3 .byt:0001 +804021F4 .wrd:0002 +804021F6 .byt:0001 +804021F7 .byt:0001 +804021F8 .dbl:0004 +804021FC .dbl:0004 +80402200 .byt:0001 +80402201 .byt:0001 +80402202 .byt:0001 +80402203 .byt:0001 +80402204 .wrd:0002 +80402206 .byt:0001 +80402207 .byt:0001 +80402208 .dbl:0004 +8040220C .dbl:0004 +80402210 .byt:0001 +80402211 .byt:0001 +80402212 .byt:0001 +80402213 .byt:0001 +80402214 .wrd:0002 +80402216 .byt:0001 +80402217 .byt:0001 +80402218 .dbl:0004 +8040221C .dbl:0004 +80402220 .byt:0001 +80402221 .byt:0001 +80402222 .byt:0001 +80402223 .byt:0001 +80402224 .wrd:0002 +80402226 .byt:0001 +80402227 .byt:0001 +80402228 .dbl:0004 +8040222C .dbl:0004 +80402230 .byt:0001 +80402231 .byt:0001 +80402232 .byt:0001 +80402233 .byt:0001 +80402234 .wrd:0002 +80402236 .byt:0001 +80402237 .byt:0001 +80402238 .dbl:0004 +8040223C .dbl:0004 +80402240 .byt:0001 +80402241 .byt:0001 +80402242 .byt:0001 +80402243 .byt:0001 +80402244 .wrd:0002 +80402246 .byt:0001 +80402247 .byt:0001 +80402248 .dbl:0004 +8040224C .dbl:0004 +80402250 .byt:0001 +80402251 .byt:0001 +80402252 .byt:0001 +80402253 .byt:0001 +80402254 .wrd:0002 +80402256 .byt:0001 +80402257 .byt:0001 +80402258 .dbl:0004 +8040225C .dbl:0004 +80402260 .byt:0001 +80402261 .byt:0001 +80402262 .byt:0001 +80402263 .byt:0001 +80402264 .wrd:0002 +80402266 .byt:0001 +80402267 .byt:0001 +80402268 .dbl:0004 +8040226C .dbl:0004 +80402270 .byt:0001 +80402271 .byt:0001 +80402272 .byt:0001 +80402273 .byt:0001 +80402274 .wrd:0002 +80402276 .byt:0001 +80402277 .byt:0001 +80402278 .dbl:0004 +8040227C .dbl:0004 +80402280 .byt:0001 +80402281 .byt:0001 +80402282 .byt:0001 +80402283 .byt:0001 +80402284 .wrd:0002 +80402286 .byt:0001 +80402287 .byt:0001 +80402288 .dbl:0004 +8040228C .dbl:0004 +80402290 .byt:0001 +80402291 .byt:0001 +80402292 .byt:0001 +80402293 .byt:0001 +80402294 .wrd:0002 +80402296 .byt:0001 +80402297 .byt:0001 +80402298 .dbl:0004 +8040229C .dbl:0004 +804022A0 .byt:0001 +804022A1 .byt:0001 +804022A2 .byt:0001 +804022A3 .byt:0001 +804022A4 .wrd:0002 +804022A6 .byt:0001 +804022A7 .byt:0001 +804022A8 .dbl:0004 +804022AC .dbl:0004 +804022B0 .byt:0001 +804022B1 .byt:0001 +804022B2 .byt:0001 +804022B3 .byt:0001 +804022B4 .wrd:0002 +804022B6 .byt:0001 +804022B7 .byt:0001 +804022B8 .dbl:0004 +804022BC .dbl:0004 +804022C0 .byt:0001 +804022C1 .byt:0001 +804022C2 .byt:0001 +804022C3 .byt:0001 +804022C4 .wrd:0002 +804022C6 .byt:0001 +804022C7 .byt:0001 +804022C8 .dbl:0004 +804022CC .dbl:0004 +804022D0 .byt:0001 +804022D1 .byt:0001 +804022D2 .byt:0001 +804022D3 .byt:0001 +804022D4 .wrd:0002 +804022D6 .byt:0001 +804022D7 .byt:0001 +804022D8 .dbl:0004 +804022DC .dbl:0004 +804022E0 .byt:0001 +804022E1 .byt:0001 +804022E2 .byt:0001 +804022E3 .byt:0001 +804022E4 .wrd:0002 +804022E6 .byt:0001 +804022E7 .byt:0001 +804022E8 .dbl:0004 +804022EC .dbl:0004 +804022F0 .byt:0001 +804022F1 .byt:0001 +804022F2 .byt:0001 +804022F3 .byt:0001 +804022F4 .wrd:0002 +804022F6 .byt:0001 +804022F7 .byt:0001 +804022F8 .dbl:0004 +804022FC .dbl:0004 +80402300 .byt:0001 +80402301 .byt:0001 +80402302 .byt:0001 +80402303 .byt:0001 +80402304 .wrd:0002 +80402306 .byt:0001 +80402307 .byt:0001 +80402308 .dbl:0004 +8040230C .dbl:0004 +80402310 .byt:0001 +80402311 .byt:0001 +80402312 .byt:0001 +80402313 .byt:0001 +80402314 .wrd:0002 +80402316 .byt:0001 +80402317 .byt:0001 +80402318 .dbl:0004 +8040231C .dbl:0004 +80402320 .byt:0001 +80402321 .byt:0001 +80402322 .byt:0001 +80402323 .byt:0001 +80402324 .wrd:0002 +80402326 .byt:0001 +80402327 .byt:0001 +80402328 .dbl:0004 +8040232C .dbl:0004 +80402330 .byt:0001 +80402331 .byt:0001 +80402332 .byt:0001 +80402333 .byt:0001 +80402334 .wrd:0002 +80402336 .byt:0001 +80402337 .byt:0001 +80402338 .dbl:0004 +8040233C .dbl:0004 +80402340 .byt:0001 +80402341 .byt:0001 +80402342 .byt:0001 +80402343 .byt:0001 +80402344 .wrd:0002 +80402346 .byt:0001 +80402347 .byt:0001 +80402348 .dbl:0004 +8040234C .dbl:0004 +80402350 .byt:0001 +80402351 .byt:0001 +80402352 .byt:0001 +80402353 .byt:0001 +80402354 .wrd:0002 +80402356 .byt:0001 +80402357 .byt:0001 +80402358 .dbl:0004 +8040235C .dbl:0004 +80402360 .byt:0001 +80402361 .byt:0001 +80402362 .byt:0001 +80402363 .byt:0001 +80402364 .wrd:0002 +80402366 .byt:0001 +80402367 .byt:0001 +80402368 .dbl:0004 +8040236C .dbl:0004 +80402370 .byt:0001 +80402371 .byt:0001 +80402372 .byt:0001 +80402373 .byt:0001 +80402374 .wrd:0002 +80402376 .byt:0001 +80402377 .byt:0001 +80402378 .dbl:0004 +8040237C .dbl:0004 +80402380 .byt:0001 +80402381 .byt:0001 +80402382 .byt:0001 +80402383 .byt:0001 +80402384 .wrd:0002 +80402386 .byt:0001 +80402387 .byt:0001 +80402388 .dbl:0004 +8040238C .dbl:0004 +80402390 .byt:0001 +80402391 .byt:0001 +80402392 .byt:0001 +80402393 .byt:0001 +80402394 .wrd:0002 +80402396 .byt:0001 +80402397 .byt:0001 +80402398 .dbl:0004 +8040239C .dbl:0004 +804023A0 .byt:0001 +804023A1 .byt:0001 +804023A2 .byt:0001 +804023A3 .byt:0001 +804023A4 .wrd:0002 +804023A6 .byt:0001 +804023A7 .byt:0001 +804023A8 .dbl:0004 +804023AC .dbl:0004 +804023B0 .byt:0001 +804023B1 .byt:0001 +804023B2 .byt:0001 +804023B3 .byt:0001 +804023B4 .wrd:0002 +804023B6 .byt:0001 +804023B7 .byt:0001 +804023B8 .dbl:0004 +804023BC .dbl:0004 +804023C0 .byt:0001 +804023C1 .byt:0001 +804023C2 .byt:0001 +804023C3 .byt:0001 +804023C4 .wrd:0002 +804023C6 .byt:0001 +804023C7 .byt:0001 +804023C8 .dbl:0004 +804023CC .dbl:0004 +804023D0 .byt:0001 +804023D1 .byt:0001 +804023D2 .byt:0001 +804023D3 .byt:0001 +804023D4 .wrd:0002 +804023D6 .byt:0001 +804023D7 .byt:0001 +804023D8 .dbl:0004 +804023DC .dbl:0004 +804023E0 .byt:0001 +804023E1 .byt:0001 +804023E2 .byt:0001 +804023E3 .byt:0001 +804023E4 .wrd:0002 +804023E6 .byt:0001 +804023E7 .byt:0001 +804023E8 .dbl:0004 +804023EC .dbl:0004 +804023F0 .byt:0001 +804023F1 .byt:0001 +804023F2 .byt:0001 +804023F3 .byt:0001 +804023F4 .wrd:0002 +804023F6 .byt:0001 +804023F7 .byt:0001 +804023F8 .dbl:0004 +804023FC .dbl:0004 +80402400 .byt:0001 +80402401 .byt:0001 +80402402 .byt:0001 +80402403 .byt:0001 +80402404 .wrd:0002 +80402406 .byt:0001 +80402407 .byt:0001 +80402408 .dbl:0004 +8040240C .dbl:0004 +80402410 .byt:0001 +80402411 .byt:0001 +80402412 .byt:0001 +80402413 .byt:0001 +80402414 .wrd:0002 +80402416 .byt:0001 +80402417 .byt:0001 +80402418 .dbl:0004 +8040241C .dbl:0004 +80402420 .byt:0001 +80402421 .byt:0001 +80402422 .byt:0001 +80402423 .byt:0001 +80402424 .wrd:0002 +80402426 .byt:0001 +80402427 .byt:0001 +80402428 .dbl:0004 +8040242C .dbl:0004 +80402430 .byt:0001 +80402431 .byt:0001 +80402432 .byt:0001 +80402433 .byt:0001 +80402434 .wrd:0002 +80402436 .byt:0001 +80402437 .byt:0001 +80402438 .dbl:0004 +8040243C .dbl:0004 +80402440 .byt:0001 +80402441 .byt:0001 +80402442 .byt:0001 +80402443 .byt:0001 +80402444 .wrd:0002 +80402446 .byt:0001 +80402447 .byt:0001 +80402448 .dbl:0004 +8040244C .dbl:0004 +80402450 .byt:0001 +80402451 .byt:0001 +80402452 .byt:0001 +80402453 .byt:0001 +80402454 .wrd:0002 +80402456 .byt:0001 +80402457 .byt:0001 +80402458 .dbl:0004 +8040245C .dbl:0004 +80402460 .byt:0001 +80402461 .byt:0001 +80402462 .byt:0001 +80402463 .byt:0001 +80402464 .wrd:0002 +80402466 .byt:0001 +80402467 .byt:0001 +80402468 .dbl:0004 +8040246C .dbl:0004 +80402470 .byt:0001 +80402471 .byt:0001 +80402472 .byt:0001 +80402473 .byt:0001 +80402474 .wrd:0002 +80402476 .byt:0001 +80402477 .byt:0001 +80402478 .dbl:0004 +8040247C .dbl:0004 +80402480 .byt:0001 +80402481 .byt:0001 +80402482 .byt:0001 +80402483 .byt:0001 +80402484 .wrd:0002 +80402486 .byt:0001 +80402487 .byt:0001 +80402488 .dbl:0004 +8040248C .dbl:0004 +80402490 .byt:0001 +80402491 .byt:0001 +80402492 .byt:0001 +80402493 .byt:0001 +80402494 .wrd:0002 +80402496 .byt:0001 +80402497 .byt:0001 +80402498 .dbl:0004 +8040249C .dbl:0004 +804024A0 .byt:0001 +804024A1 .byt:0001 +804024A2 .byt:0001 +804024A3 .byt:0001 +804024A4 .wrd:0002 +804024A6 .byt:0001 +804024A7 .byt:0001 +804024A8 .dbl:0004 +804024AC .dbl:0004 +804024B0 .byt:0001 +804024B1 .byt:0001 +804024B2 .byt:0001 +804024B3 .byt:0001 +804024B4 .wrd:0002 +804024B6 .byt:0001 +804024B7 .byt:0001 +804024B8 .dbl:0004 +804024BC .dbl:0004 +804024C0 .byt:0001 +804024C1 .byt:0001 +804024C2 .byt:0001 +804024C3 .byt:0001 +804024C4 .wrd:0002 +804024C6 .byt:0001 +804024C7 .byt:0001 +804024C8 .dbl:0004 +804024CC .dbl:0004 +804024D0 .byt:0001 +804024D1 .byt:0001 +804024D2 .byt:0001 +804024D3 .byt:0001 +804024D4 .wrd:0002 +804024D6 .byt:0001 +804024D7 .byt:0001 +804024D8 .dbl:0004 +804024DC .dbl:0004 +804024E0 .byt:0001 +804024E1 .byt:0001 +804024E2 .byt:0001 +804024E3 .byt:0001 +804024E4 .wrd:0002 +804024E6 .byt:0001 +804024E7 .byt:0001 +804024E8 .dbl:0004 +804024EC .dbl:0004 +804024F0 .byt:0001 +804024F1 .byt:0001 +804024F2 .byt:0001 +804024F3 .byt:0001 +804024F4 .wrd:0002 +804024F6 .byt:0001 +804024F7 .byt:0001 +804024F8 .dbl:0004 +804024FC .dbl:0004 +80402500 .byt:0001 +80402501 .byt:0001 +80402502 .byt:0001 +80402503 .byt:0001 +80402504 .wrd:0002 +80402506 .byt:0001 +80402507 .byt:0001 +80402508 .dbl:0004 +8040250C .dbl:0004 +80402510 .byt:0001 +80402511 .byt:0001 +80402512 .byt:0001 +80402513 .byt:0001 +80402514 .wrd:0002 +80402516 .byt:0001 +80402517 .byt:0001 +80402518 .dbl:0004 +8040251C .dbl:0004 +80402520 .byt:0001 +80402521 .byt:0001 +80402522 .byt:0001 +80402523 .byt:0001 +80402524 .wrd:0002 +80402526 .byt:0001 +80402527 .byt:0001 +80402528 .dbl:0004 +8040252C .dbl:0004 +80402530 .byt:0001 +80402531 .byt:0001 +80402532 .byt:0001 +80402533 .byt:0001 +80402534 .wrd:0002 +80402536 .byt:0001 +80402537 .byt:0001 +80402538 .dbl:0004 +8040253C .dbl:0004 +80402540 .byt:0001 +80402541 .byt:0001 +80402542 .byt:0001 +80402543 .byt:0001 +80402544 .wrd:0002 +80402546 .byt:0001 +80402547 .byt:0001 +80402548 .dbl:0004 +8040254C .dbl:0004 +80402550 .byt:0001 +80402551 .byt:0001 +80402552 .byt:0001 +80402553 .byt:0001 +80402554 .wrd:0002 +80402556 .byt:0001 +80402557 .byt:0001 +80402558 .dbl:0004 +8040255C .dbl:0004 +80402560 .byt:0001 +80402561 .byt:0001 +80402562 .byt:0001 +80402563 .byt:0001 +80402564 .wrd:0002 +80402566 .byt:0001 +80402567 .byt:0001 +80402568 .dbl:0004 +8040256C .dbl:0004 +80402570 .byt:0001 +80402571 .byt:0001 +80402572 .byt:0001 +80402573 .byt:0001 +80402574 .wrd:0002 +80402576 .byt:0001 +80402577 .byt:0001 +80402578 .dbl:0004 +8040257C .dbl:0004 +80402580 .byt:0001 +80402581 .byt:0001 +80402582 .byt:0001 +80402583 .byt:0001 +80402584 .wrd:0002 +80402586 .byt:0001 +80402587 .byt:0001 +80402588 .dbl:0004 +8040258C .dbl:0004 +80402590 no_upgrade +80402598 hookshot_upgrade +804025AC @@return +804025B4 strength_upgrade +804025D4 @@return +804025DC bomb_bag_upgrade +804025FC @@return +80402604 bow_upgrade +80402624 @@return +8040262C slingshot_upgrade +8040264C @@return +80402654 wallet_upgrade +80402674 @@return +8040267C tycoon_wallet +80402690 scale_upgrade +804026A4 @@return +804026AC nut_upgrade +804026C0 @@return +804026C8 stick_upgrade +804026DC @@return +804026E4 magic_upgrade +804026F4 @@return +804026FC arrows_to_rupee +80402710 @@return +80402718 bombs_to_rupee +8040272C @@return +80402734 seeds_to_rupee +80402748 @@return +80402750 no_effect +80402758 give_biggoron_sword +80402768 give_bottle +80402770 @@loop +8040279C @@return +804027A4 give_dungeon_item +804027C0 give_small_key +804027D8 @not_negative +804027E8 give_defense +80402808 give_magic +80402828 double_magic +80402850 bombchu_upgrade +80402874 @@return +8040287C ocarina_upgrade +80402890 @@return +80402898 give_fairy_ocarina +804028A8 give_song +804028C4 inventory_check +80402930 @@return +80402938 override_skulltula_token +80402958 @@in_table +8040299C @@extended_effect +804029D0 @@not_extended +80402A18 @@item_effect +80402A24 @@return +80402A38 override_object_npc +80402A48 override_object_chest +80402A58 override_object +80402A70 @@return +80402AB4 @@no_count_inc +80402AB8 @@no_pending_clear +80402AC0 override_graphic +80402AD8 @@return +80402AF0 override_text +80402B0C @@return +80402B14 override_action +80402B3C @@no_player_override +80402B98 @@return +80402BA0 store_item_data_hook +80402BD4 store_item_data +80402C68 @@update_base_game +80402C98 @@not_chest +80402CA8 @@not_negative +80402CAC @@return +80402CBC lookup_override +80402CE4 @@return +80402CF4 get_override_search_key +80402D34 @@not_skulltula +80402D6C @@valid_chest +80402D74 @@not_chest +80402DA4 @@valid_collectable +80402DAC @@not_collectable +80402DD4 @@not_grotto_deku_scrub +80402DE4 @@return +80402DEC scan_override_table +80402E30 @@not_coop_item +80402E38 @@lookup_loop +80402E6C @@lookup_item_found +80402EA0 @@return +80402EA8 resolve_extended_item +80402EBC @@loop +80402F10 @@not_extended +80402F14 @@return +80402F2C override_great_fairy_cutscene +80402F84 @@item_fairy +80402FA4 @@give_item +80402FD0 @@return +80402FD8 override_light_arrow_cutscene +80402FEC override_fairy_ocarina_cutscene +80403000 override_ocarina_songs +80403014 override_requiem_song +80403020 override_epona_song +80403040 override_suns_song +80403060 override_song_of_time +80403070 store_pending_special_item +80403080 @@find_duplicate_loop +8040309C @@find_empty_loop +804030B4 @@return +804030BC override_saria_song_check +804030D8 @@get_item +804030E0 set_saria_song_flag +80403100 set_dungeon_knowledge +8040312C @@set_flag +80403144 Shop_Check_Sold_Out +80403190 @@return +80403198 Shop_Set_Sold_Out +804031D0 @@return +804031D8 Shop_Keeper_Init_ID +804031F4 @@return +80403204 Deku_Check_Sold_Out +80403228 @@continue +80403258 Deku_Set_Sold_Out +8040327C @@continue +804032B0 before_game_state_update +80403300 @@loop +80403358 @@no_pending_item +8040336C after_game_state_update +80403390 item_menu_prevent_empty_equip +804033A0 @@return +804033A8 equipment_menu_prevent_empty_equip +804033C8 @@return +804033DC menu_use_blank_description +80403410 @@not_equip_menu +80403420 @@return +80403438 equipment_menu_slot_filled +80403488 give_master_sword +804034A0 before_time_travel +804034D8 after_time_travel +80403514 @@going_back +8040351C @@done +8040354C update_c_button +80403578 @@return +80403580 after_going_forward +804035BC @@no_init +804035CC after_going_back +804035FC @@not_swordless +80403604 initialize_adult +8040362C @@no_mirror_shield +8040366C init_adult_button +80403698 @@empty +804036A0 @@loop +804036F8 @@set_empty +80403704 @@return +8040370C .byt:0001 +8040370C ADULT_INIT_ITEMS +8040370D .byt:0001 +8040370E .byt:0001 +8040370F .byt:0001 +80403710 .byt:0001 +80403711 .byt:0001 +80403712 .byt:0001 +80403713 .byt:0001 +80403714 .byt:0001 +80403718 .byt:0001 +80403718 ADULT_VALID_ITEMS +80403719 .byt:0001 +8040371A .byt:0001 +8040371B .byt:0001 +8040371C .byt:0001 +8040371D .byt:0001 +8040371E .byt:0001 +8040371F .byt:0001 +80403720 .byt:0001 +80403721 .byt:0001 +80403722 .byt:0001 +80403723 .byt:0001 +80403724 .byt:0001 +80403725 .byt:0001 +80403726 .byt:0001 +80403727 .byt:0001 +80403728 .byt:0001 +80403729 .byt:0001 +8040372A .byt:0001 +8040372B .byt:0001 +8040372C .byt:0001 +8040372D .byt:0001 +8040372E .byt:0001 +8040372F .byt:0001 +80403730 suns_song_fix_event +80403764 @@child +80403774 @@return +8040377C suns_song_fix +80403790 @@check_suns_status +804037AC @@disable_suns +804037B4 @@return +804037BC warp_song_fix +804037E8 @@child +804037F8 @@return +80403800 Check_Has_Epona_Song +8040384C @@return +80403854 save_scarecrow_song +80403898 @@copy_song +804038A0 write_initial_save +804038AC @@save_data_loop +804038DC @@overwrite_type +804038E4 @@return +804038EC get_name_char_1 +80403908 get_name_char_2 +80403924 get_name_char +80403950 @@coop_player_name +80403968 @@return +80403970 reset_player_name_id +80403990 .byt:06C0 +80405000 text_init,0000002C +8040502C text_print,000000A8 +804050D4 text_flush,00000148 +8040521C draw_dungeon_info,000009B8 +80405BD4 c_init,0000002C +80405C00 c_after_game_state_update,00000088 +80405C88 heap_init,00000014 +80405C9C heap_alloc,00000034 +80405CD0 file_init,00000044 +80405D14 disp_buf_init,00000018 +80405D2C sprite_bytes_per_tile,00000028 +80405D54 sprite_bytes,00000030 +80405D84 sprite_load,000001A0 +80405F24 sprite_draw,000000F0 +80406014 draw_setup,000001DC +804061F0 gfx_init,00000178 +80406368 draw_file_select_hash,00000234 +804065A8 .byt:000E +804065A8 cfg_dungeon_rewards +804065B8 .byt:0012 +804065B8 medal_colors +804065CC .byt:009C +804065CC dungeons +80406668 .byt:0010 +80406668 font_sprite +80406678 .byt:0010 +80406678 quest_items_sprite +80406688 .byt:0010 +80406688 items_sprite +80406698 .byt:0010 +80406698 medals_sprite +804066A8 .byt:0010 +804066A8 stones_sprite +804066B8 .byt:0040 +804066B8 hash_symbols +804066F8 .byt:0004 +804066F8 cfg_dungeon_info_enable +804066FC .byt:0004 +804066FC dungeon_count +80406700 .byt:0008 +80406700 hash_sprites +80406710 .byt:0004 +80406710 cfg_dungeon_info_reward_need_altar +80406714 .byt:0004 +80406714 cfg_dungeon_info_reward_need_compass +80406718 .byt:0004 +80406718 cfg_dungeon_info_mq_need_map +8040671C .byt:0004 +8040671C cfg_dungeon_info_mq_enable +80406720 .byt:0004 +80406720 heap_next +80406724 .byt:0004 +80406724 cfg_file_select_hash +80406728 .byt:000E +80406728 cfg_dungeon_is_mq +80406738 .byt:0010 +80406738 setup_db +80406748 .byt:14C8 +80406748 FONT_TEXTURE +80407C10 .byt:83F0 +80480000 DUMMY_ACTOR +80500000 C_HEAP + \ No newline at end of file diff --git a/ASM/build/bundle.o b/ASM/build/bundle.o new file mode 100644 index 000000000..9dec7528b Binary files /dev/null and b/ASM/build/bundle.o differ diff --git a/ASM/build/c_symbols.txt b/ASM/build/c_symbols.txt new file mode 100644 index 000000000..3bb76f2f5 --- /dev/null +++ b/ASM/build/c_symbols.txt @@ -0,0 +1,67 @@ + +../build/bundle.o: file format elf32-bigmips + +SYMBOL TABLE: +00000000 l d .MIPS.abiflags 00000000 .MIPS.abiflags +00000000 l d .reginfo 00000000 .reginfo +00000000 l d .text 00000000 .text +00000000 l d .rodata.str1.4 00000000 .rodata.str1.4 +00000000 l d .data 00000000 .data +00000000 l d .sdata 00000000 .sdata +00000000 l d .sbss 00000000 .sbss +00000000 l d .bss 00000000 .bss +00000000 l d .comment 00000000 .comment +00000000 l d .pdr 00000000 .pdr +00000000 l d .gnu.attributes 00000000 .gnu.attributes +00000000 l d .mdebug.abi32 00000000 .mdebug.abi32 +00000000 l df *ABS* 00000000 text.c +00000004 l O .sbss 00000004 text_buf +00000000 l O .sbss 00000004 text_end +00000000 l df *ABS* 00000000 dungeon_info.c +00000000 l .rodata.str1.4 00000000 $LC0 +00000004 l .rodata.str1.4 00000000 $LC1 +00000000 l df *ABS* 00000000 main.c +00000000 l df *ABS* 00000000 util.c +00000000 l df *ABS* 00000000 gfx.c +00000000 l df *ABS* 00000000 file_select.c +00000000 g F .text 0000002c text_init +000000e0 g O .data 00000010 items_sprite +00000008 g O .sdata 00000008 hash_sprites +0000001c g O .sbss 00000004 cfg_file_select_hash +000000d4 g F .text 00000148 text_flush +000000f0 g O .data 00000010 medals_sprite +00000004 g O .sdata 00000004 dungeon_count +000000d0 g O .data 00000010 quest_items_sprite +00000c9c g F .text 00000034 heap_alloc +0000021c g F .text 000009b8 draw_dungeon_info +00000000 *UND* 00000000 FONT_TEXTURE +00001368 g F .text 00000234 draw_file_select_hash +00000f24 g F .text 000000f0 sprite_draw +00000d84 g F .text 000001a0 sprite_load +00000100 g O .data 00000010 stones_sprite +00000010 g O .bss 00000010 setup_db +00001014 g F .text 000001dc draw_setup +000000c0 g O .data 00000010 font_sprite +00000d54 g F .text 00000030 sprite_bytes +00000010 g O .sbss 00000004 cfg_dungeon_info_mq_need_map +000011f0 g F .text 00000178 gfx_init +00000d14 g F .text 00000018 disp_buf_init +00000000 g O .bss 0000000e cfg_dungeon_is_mq +00000024 g O .data 0000009c dungeons +00000010 g O .data 00000012 medal_colors +0000002c g F .text 000000a8 text_print +00000bd4 g F .text 0000002c c_init +00000018 g O .sbss 00000004 heap_next +00000000 g O .data 0000000e cfg_dungeon_rewards +00000c00 g F .text 00000088 c_after_game_state_update +00000110 g O .data 00000040 hash_symbols +00000c88 g F .text 00000014 heap_init +0000000c g O .sbss 00000004 cfg_dungeon_info_reward_need_compass +00000014 g O .sbss 00000004 cfg_dungeon_info_mq_enable +00000000 *UND* 00000000 C_HEAP +00000d2c g F .text 00000028 sprite_bytes_per_tile +00000cd0 g F .text 00000044 file_init +00000008 g O .sbss 00000004 cfg_dungeon_info_reward_need_altar +00000000 g O .sdata 00000004 cfg_dungeon_info_enable + + diff --git a/ASM/c/Makefile b/ASM/c/Makefile new file mode 100644 index 000000000..fd099a29b --- /dev/null +++ b/ASM/c/Makefile @@ -0,0 +1,28 @@ +CC = mips64-gcc +LD = mips64-ld +OBJDUMP = mips64-objdump + +CFLAGS = -march=vr4300 -mtune=vr4300 -mabi=32 -mno-gpopt -mdivide-breaks \ + -O1 -fno-reorder-blocks \ + -DZ64_VERSION=Z64_OOT10 + +OBJECTS = $(patsubst %.c,%.o,$(wildcard *.c)) +HEADERS = $(wildcard *.h) + +OUTDIR = ../build + +.PHONY: all clean bundle symbols + +all: clean bundle symbols + +%.o: %.c $(HEADERS) + $(CC) -c $< $(CFLAGS) + +bundle: $(OBJECTS) + $(LD) -o $(OUTDIR)/bundle.o -i -L. $(patsubst %.o,-l:%.o,$(OBJECTS)) + +symbols: bundle + $(OBJDUMP) -t $(OUTDIR)/bundle.o > $(OUTDIR)/c_symbols.txt + +clean: + rm -f *.o diff --git a/ASM/c/dungeon_info.c b/ASM/c/dungeon_info.c new file mode 100644 index 000000000..547de20c6 --- /dev/null +++ b/ASM/c/dungeon_info.c @@ -0,0 +1,282 @@ +#include "dungeon_info.h" + +#include "gfx.h" +#include "text.h" +#include "util.h" +#include "z64.h" + +typedef struct { + uint8_t index; + struct { + uint8_t has_keys : 1; + uint8_t has_boss_key : 1; + uint8_t has_card : 1; + uint8_t has_map : 1; + }; + char name[10]; +} dungeon_entry_t; + +dungeon_entry_t dungeons[] = { + { 0, 0, 0, 0, 1, "Deku" }, + { 1, 0, 0, 0, 1, "Dodongo" }, + { 2, 0, 0, 0, 1, "Jabu" }, + + { 3, 1, 1, 0, 1, "Forest" }, + { 4, 1, 1, 0, 1, "Fire" }, + { 5, 1, 1, 0, 1, "Water" }, + { 7, 1, 1, 0, 1, "Shadow" }, + { 6, 1, 1, 0, 1, "Spirit" }, + + { 8, 1, 0, 0, 1, "BotW" }, + { 9, 0, 0, 0, 1, "Ice" }, + { 12, 1, 0, 1, 0, "Gerudo" }, + { 11, 1, 0, 0, 0, "GTG" }, + { 13, 1, 1, 0, 0, "Ganon" }, +}; + +int dungeon_count = array_size(dungeons); + +typedef struct { + uint8_t r; + uint8_t g; + uint8_t b; +} medal_color_t; + +medal_color_t medal_colors[] = { + { 0x00, 0xFF, 0x00 }, // Forest + { 0xFF, 0x3C, 0x00 }, // Fire + { 0x00, 0x64, 0xFF }, // Water + { 0xFF, 0x82, 0x00 }, // Spirit + { 0xC8, 0x32, 0xFF }, // Shadow + { 0xC8, 0xC8, 0x00 }, // Light +}; + +uint32_t cfg_dungeon_info_enable = 1; +uint32_t cfg_dungeon_info_mq_enable = 0; +uint32_t cfg_dungeon_info_mq_need_map = 0; +uint32_t cfg_dungeon_info_reward_need_compass = 0; +uint32_t cfg_dungeon_info_reward_need_altar = 0; + +int8_t cfg_dungeon_rewards[] = { 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1 }; +uint8_t cfg_dungeon_is_mq[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +void draw_dungeon_info(z64_disp_buf_t *db) { + if (!cfg_dungeon_info_enable) return; + + db->p = db->buf; + + // Call setup display list + gSPDisplayList(db->p++, setup_db.buf); + + uint16_t altar_flags = z64_file.inf_table[27]; + int show_medals = !cfg_dungeon_info_reward_need_altar || (altar_flags & 1); + int show_stones = !cfg_dungeon_info_reward_need_altar || (altar_flags & 2); + int show_keys = 1; + int show_map_compass = 1; + int show_mq = cfg_dungeon_info_mq_enable; + + // Set up dimensions + + int icon_size = 16; + int padding = 1; + int rows = 13; + int mq_width = show_mq ? + ((6 * font_sprite.tile_w) + padding) : + 0; + int bg_width = + (5 * icon_size) + + (8 * font_sprite.tile_w) + + (7 * padding) + + mq_width; + int bg_height = (rows * icon_size) + ((rows + 1) * padding); + int bg_left = (Z64_SCREEN_WIDTH - bg_width) / 2; + int bg_top = (Z64_SCREEN_HEIGHT - bg_height) / 2; + + int left = bg_left + padding; + int start_top = bg_top + padding; + + // Draw background + + gDPSetCombineMode(db->p++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); + gDPSetPrimColor(db->p++, 0, 0, 0x00, 0x00, 0x00, 0xD0); + gSPTextureRectangle(db->p++, + bg_left<<2, bg_top<<2, + (bg_left + bg_width)<<2, (bg_top + bg_height)<<2, + 0, + 0, 0, + 1<<10, 1<<10); + + gDPPipeSync(db->p++); + gDPSetCombineMode(db->p++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + + // Draw medals + + if (show_medals) { + sprite_load(db, &medals_sprite, 0, medals_sprite.tile_count); + + for (int i = 0; i < dungeon_count; i++) { + dungeon_entry_t *d = &(dungeons[i]); + if (cfg_dungeon_info_reward_need_compass && + !z64_file.dungeon_items[d->index].compass) { + continue; + } + int reward = cfg_dungeon_rewards[d->index]; + if (reward < 3) continue; + reward -= 3; + + medal_color_t *c = &(medal_colors[reward]); + gDPSetPrimColor(db->p++, 0, 0, c->r, c->g, c->b, 0xFF); + + int top = start_top + ((icon_size + padding) * i); + sprite_draw(db, &medals_sprite, reward, + left, top, icon_size, icon_size); + } + } + + gDPSetPrimColor(db->p++, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF); + + // Draw stones + + if (show_stones) { + sprite_load(db, &stones_sprite, 0, stones_sprite.tile_count); + + for (int i = 0; i < dungeon_count; i++) { + dungeon_entry_t *d = &(dungeons[i]); + if (cfg_dungeon_info_reward_need_compass && + !z64_file.dungeon_items[d->index].compass) { + continue; + } + int reward = cfg_dungeon_rewards[d->index]; + if (reward < 0 || reward >= 3) continue; + + int top = start_top + ((icon_size + padding) * i); + sprite_draw(db, &stones_sprite, reward, + left, top, icon_size, icon_size); + } + } + + left += icon_size + padding; + + // Draw dungeon names + + for (int i = 0; i < dungeon_count; i++) { + dungeon_entry_t *d = &(dungeons[i]); + int top = start_top + ((icon_size + padding) * i) + 1; + text_print(d->name, left, top); + } + + left += (8 * font_sprite.tile_w) + padding; + + // Draw keys + + if (show_keys) { + // Draw small key counts + + sprite_load(db, &quest_items_sprite, 17, 1); + + for (int i = 0; i < dungeon_count; i++) { + dungeon_entry_t *d = &(dungeons[i]); + if (!d->has_keys) continue; + + int8_t keys = z64_file.dungeon_keys[d->index]; + if (keys < 0) keys = 0; + if (keys > 9) keys = 9; + + char count[2] = "0"; + count[0] += keys; + int top = start_top + ((icon_size + padding) * i) + 1; + text_print(count, left, top); + } + + left += icon_size + padding; + + // Draw boss keys + + sprite_load(db, &quest_items_sprite, 14, 1); + + for (int i = 0; i < dungeon_count; i++) { + dungeon_entry_t *d = &(dungeons[i]); + // Replace index 13 (Ganon's Castle) with 10 (Ganon's Tower) + int index = d->index == 13 ? 10 : d->index; + + if (d->has_boss_key && z64_file.dungeon_items[index].boss_key) { + int top = start_top + ((icon_size + padding) * i); + sprite_draw(db, &quest_items_sprite, 0, + left, top, icon_size, icon_size); + } + } + + // Draw gerudo card + + sprite_load(db, &quest_items_sprite, 10, 1); + + for (int i = 0; i < dungeon_count; i++) { + dungeon_entry_t *d = &(dungeons[i]); + if (d->has_card && z64_file.gerudos_card) { + int top = start_top + ((icon_size + padding) * i); + sprite_draw(db, &quest_items_sprite, 0, + left, top, icon_size, icon_size); + } + } + + left += icon_size + padding; + } + + // Draw maps and compasses + + if (show_map_compass) { + // Draw maps + + sprite_load(db, &quest_items_sprite, 16, 1); + + for (int i = 0; i < dungeon_count; i++) { + dungeon_entry_t *d = &(dungeons[i]); + if (d->has_map && z64_file.dungeon_items[d->index].map) { + int top = start_top + ((icon_size + padding) * i); + sprite_draw(db, &quest_items_sprite, 0, + left, top, icon_size, icon_size); + } + } + + left += icon_size + padding; + + // Draw compasses + + sprite_load(db, &quest_items_sprite, 15, 1); + + for (int i = 0; i < dungeon_count; i++) { + dungeon_entry_t *d = &(dungeons[i]); + if (d->has_map && z64_file.dungeon_items[d->index].compass) { + int top = start_top + ((icon_size + padding) * i); + sprite_draw(db, &quest_items_sprite, 0, + left, top, icon_size, icon_size); + } + } + + left += icon_size + padding; + } + + // Draw master quest dungeons + + if (show_mq) { + for (int i = 0; i < dungeon_count; i++) { + dungeon_entry_t *d = &(dungeons[i]); + if (cfg_dungeon_info_mq_need_map && d->has_map && + !z64_file.dungeon_items[d->index].map) { + continue; + } + char *str = cfg_dungeon_is_mq[d->index] ? "MQ" : "Normal"; + int top = start_top + ((icon_size + padding) * i) + 1; + text_print(str, left, top); + } + + left += icon_size + padding; + } + + // Finish + + text_flush(db); + + gDPFullSync(db->p++); + gSPEndDisplayList(db->p++); +} diff --git a/ASM/c/dungeon_info.h b/ASM/c/dungeon_info.h new file mode 100644 index 000000000..435af14b7 --- /dev/null +++ b/ASM/c/dungeon_info.h @@ -0,0 +1,8 @@ +#ifndef DUNGEON_INFO_H +#define DUNGEON_INFO_H + +#include "z64.h" + +void draw_dungeon_info(z64_disp_buf_t *db); + +#endif diff --git a/ASM/c/file_select.c b/ASM/c/file_select.c new file mode 100644 index 000000000..332c979a1 --- /dev/null +++ b/ASM/c/file_select.c @@ -0,0 +1,96 @@ +#include "file_select.h" + +#include "gfx.h" +#include "text.h" +#include "util.h" +#include "z64.h" + +sprite_t *hash_sprites[2] = { + &items_sprite, + &quest_items_sprite, +}; + +typedef struct { + uint8_t sprite_index; + uint8_t tile_index; +} hash_symbol_t; + +hash_symbol_t hash_symbols[32] = { + { 0, 0 }, // Deku Stick + { 0, 1 }, // Deku Nut + { 0, 3 }, // Bow + { 0, 6 }, // Slingshot + { 0, 7 }, // Fairy Ocarina + { 0, 9 }, // Bombchu + { 0, 11 }, // Longshot + { 0, 14 }, // Boomerang + { 0, 15 }, // Lens of Truth + { 0, 16 }, // Beans + { 0, 17 }, // Hammer + { 0, 25 }, // Bottled Fish + { 0, 26 }, // Bottled Milk + { 0, 43 }, // Mask of Truth + { 0, 44 }, // SOLD OUT + { 0, 46 }, // Cucco + { 0, 48 }, // Mushroom + { 0, 50 }, // Saw + { 0, 53 }, // Frog + { 0, 60 }, // Master Sword + { 0, 64 }, // Mirror Shield + { 0, 65 }, // Kokiri Tunic + { 0, 70 }, // Hover Boots + { 0, 81 }, // Silver Gauntlets + { 0, 84 }, // Gold Scale + { 1, 9 }, // Stone of Agony + { 1, 11 }, // Skull Token + { 1, 12 }, // Heart Container + { 1, 14 }, // Boss Key + { 1, 15 }, // Compass + { 1, 16 }, // Map + { 1, 19 }, // Big Magic +}; + +uint32_t cfg_file_select_hash = 0; + +void draw_file_select_hash(uint32_t fade_out_alpha) { + z64_disp_buf_t *db = &(z64_ctxt.gfx->poly_opa); + + // Call setup display list + gSPDisplayList(db->p++, setup_db.buf); + + int icon_count = 5; + int icon_size = 24; + int padding = 8; + int width = (icon_count * icon_size) + ((icon_count - 1) * padding); + int left = (Z64_SCREEN_WIDTH - width) / 2; + int top = 12; + + gDPPipeSync(db->p++); + gDPSetCombineMode(db->p++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + gDPSetPrimColor(db->p++, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF); + + int hash = cfg_file_select_hash; + for (int i = 0; i < icon_count; i++) { + int sym_index = hash & 0x1F; + hash >>= 5; + hash_symbol_t *sym_desc = &(hash_symbols[sym_index]); + sprite_t *sym_sprite = hash_sprites[sym_desc->sprite_index]; + + sprite_load(db, sym_sprite, sym_desc->tile_index, 1); + sprite_draw(db, sym_sprite, 0, left, top, icon_size, icon_size); + + left += icon_size + padding; + } + + // Fade out once a file is selected + + gDPPipeSync(db->p++); + gDPSetCombineMode(db->p++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); + gDPSetPrimColor(db->p++, 0, 0, 0x00, 0x00, 0x00, fade_out_alpha); + gSPTextureRectangle(db->p++, + 0, 0, + Z64_SCREEN_WIDTH<<2, Z64_SCREEN_HEIGHT<<2, + 0, + 0, 0, + 1<<10, 1<<10); +} diff --git a/ASM/c/file_select.h b/ASM/c/file_select.h new file mode 100644 index 000000000..a276aebfe --- /dev/null +++ b/ASM/c/file_select.h @@ -0,0 +1,8 @@ +#ifndef FILE_SELECT_H +#define FILE_SELECT_H + +#include "z64.h" + +void draw_file_select_hash(uint32_t fade_out_alpha); + +#endif diff --git a/ASM/c/gfx.c b/ASM/c/gfx.c new file mode 100644 index 000000000..3927a06bb --- /dev/null +++ b/ASM/c/gfx.c @@ -0,0 +1,137 @@ +#include "gfx.h" + +#include "util.h" +#include "z64.h" + +void disp_buf_init(z64_disp_buf_t *db, Gfx *buf, int size) { + db->size = size; + db->buf = buf; + db->p = buf; + db->d = (Gfx *)((char *)buf + size); +} + +sprite_t stones_sprite = { + NULL, 16, 16, 3, + G_IM_FMT_RGBA, G_IM_SIZ_32b, 4 +}; + +sprite_t medals_sprite = { + NULL, 16, 16, 6, + G_IM_FMT_IA, G_IM_SIZ_8b, 1 +}; + +sprite_t items_sprite = { + NULL, 32, 32, 90, + G_IM_FMT_RGBA, G_IM_SIZ_32b, 4 +}; + +sprite_t quest_items_sprite = { + NULL, 24, 24, 20, + G_IM_FMT_RGBA, G_IM_SIZ_32b, 4 +}; + +sprite_t font_sprite = { + NULL, 8, 14, 95, + G_IM_FMT_IA, G_IM_SIZ_8b, 1 +}; + +int sprite_bytes_per_tile(sprite_t *sprite) { + return sprite->tile_w * sprite->tile_h * sprite->bytes_per_texel; +} + +int sprite_bytes(sprite_t *sprite) { + return sprite->tile_count * sprite_bytes_per_tile(sprite); +} + +void sprite_load(z64_disp_buf_t *db, sprite_t *sprite, + int start_tile, int tile_count) { + int width = sprite->tile_w; + int height = sprite->tile_h * tile_count; + gDPLoadTextureTile(db->p++, + sprite->buf + (start_tile * sprite_bytes_per_tile(sprite)), + sprite->im_fmt, sprite->im_siz, + width, height, + 0, 0, + width - 1, height - 1, + 0, + G_TX_WRAP, G_TX_WRAP, + G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); +} + +void sprite_draw(z64_disp_buf_t *db, sprite_t *sprite, int tile_index, + int left, int top, int width, int height) { + int width_factor = (1<<10) * sprite->tile_w / width; + int height_factor = (1<<10) * sprite->tile_h / height; + + gSPTextureRectangle(db->p++, + left<<2, top<<2, + (left + width)<<2, (top + height)<<2, + 0, + 0, (tile_index * sprite->tile_h)<<5, + width_factor, height_factor); +} + +z64_disp_buf_t setup_db = {}; + +void draw_setup(z64_disp_buf_t *db) { + gDPPipeSync(db->p++); + + gSPLoadGeometryMode(db->p++, 0); + gDPSetScissor(db->p++, G_SC_NON_INTERLACE, + 0, 0, Z64_SCREEN_WIDTH, Z64_SCREEN_HEIGHT); + gDPSetAlphaDither(db->p++, G_AD_DISABLE); + gDPSetColorDither(db->p++, G_CD_DISABLE); + gDPSetAlphaCompare(db->p++, G_AC_NONE); + gDPSetDepthSource(db->p++, G_ZS_PRIM); + gDPSetCombineKey(db->p++, G_CK_NONE); + gDPSetTextureConvert(db->p++, G_TC_FILT); + gDPSetTextureDetail(db->p++, G_TD_CLAMP); + gDPSetTexturePersp(db->p++, G_TP_NONE); + gDPSetTextureLOD(db->p++, G_TL_TILE); + gDPSetTextureLUT(db->p++, G_TT_NONE); + gDPPipelineMode(db->p++, G_PM_NPRIMITIVE); + + gDPSetCycleType(db->p++, G_CYC_1CYCLE); + gDPSetRenderMode(db->p++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + gDPSetTextureFilter(db->p++, G_TF_BILERP); + + gSPEndDisplayList(db->p++); +} + +extern char FONT_TEXTURE; +#define font_texture_raw ((uint8_t *)&FONT_TEXTURE) + +void gfx_init() { + file_t title_static = { + NULL, z64_file_select_static_vaddr, z64_file_select_static_vsize + }; + file_init(&title_static); + + file_t icon_item_24_static = { + NULL, z64_icon_item_24_static_vaddr, z64_icon_item_24_static_vsize + }; + file_init(&icon_item_24_static); + + file_t icon_item_static = { + NULL, z64_icon_item_static_vaddr, z64_icon_item_static_vsize + }; + file_init(&icon_item_static); + + stones_sprite.buf = title_static.buf + 0x2A300; + medals_sprite.buf = title_static.buf + 0x2980; + items_sprite.buf = icon_item_static.buf; + quest_items_sprite.buf = icon_item_24_static.buf; + + int font_bytes = sprite_bytes(&font_sprite); + font_sprite.buf = heap_alloc(font_bytes); + for (int i = 0; i < font_bytes / 2; i++) { + font_sprite.buf[2*i] = (font_texture_raw[i] >> 4) | 0xF0; + font_sprite.buf[2*i + 1] = font_texture_raw[i] | 0xF0; + } + + int setup_size = 32 * sizeof(Gfx); + Gfx *setup_buf = heap_alloc(setup_size); + disp_buf_init(&setup_db, setup_buf, setup_size); + draw_setup(&setup_db); +} diff --git a/ASM/c/gfx.h b/ASM/c/gfx.h new file mode 100644 index 000000000..8db392278 --- /dev/null +++ b/ASM/c/gfx.h @@ -0,0 +1,32 @@ +#ifndef GFX_H +#define GFX_H + +#include "z64.h" + +z64_disp_buf_t setup_db; + +typedef struct { + uint8_t *buf; + uint16_t tile_w; + uint16_t tile_h; + uint16_t tile_count; + uint8_t im_fmt; + uint8_t im_siz; + uint8_t bytes_per_texel; +} sprite_t; + +sprite_t stones_sprite; +sprite_t medals_sprite; +sprite_t items_sprite; +sprite_t quest_items_sprite; +sprite_t font_sprite; + +void disp_buf_init(z64_disp_buf_t *db, Gfx *buf, int size); +void gfx_init(); + +void sprite_load(z64_disp_buf_t *db, sprite_t *sprite, + int start_tile, int tile_count); +void sprite_draw(z64_disp_buf_t *db, sprite_t *sprite, int tile_index, + int left, int top, int width, int height); + +#endif diff --git a/ASM/c/main.c b/ASM/c/main.c new file mode 100644 index 000000000..d28a4947d --- /dev/null +++ b/ASM/c/main.c @@ -0,0 +1,22 @@ +#include "dungeon_info.h" +#include "file_select.h" +#include "gfx.h" +#include "text.h" +#include "util.h" +#include "z64.h" + +void c_init() { + heap_init(); + gfx_init(); + text_init(); +} + +void c_after_game_state_update() { + if (z64_game.pause_state == 6 && + z64_game.pause_screen == 0 && + !z64_game.pause_screen_changing && + z64_ctxt.input[0].raw.a) { + z64_disp_buf_t *db = &(z64_ctxt.gfx->overlay); + draw_dungeon_info(db); + } +} diff --git a/ASM/c/text.c b/ASM/c/text.c new file mode 100644 index 000000000..6e03f933a --- /dev/null +++ b/ASM/c/text.c @@ -0,0 +1,60 @@ +#include "text.h" + +#include "gfx.h" +#include "util.h" +#include "z64.h" + +#define text_max_chars 256 +#define text_bucket_count 6 +#define text_bucket_size 18 + +typedef struct { + uint32_t c : 8; + uint32_t left : 12; + uint32_t top : 12; +} text_char_t; + +static text_char_t *text_buf = NULL; +static text_char_t *text_end = NULL; + +void text_init() { + text_buf = heap_alloc(text_max_chars * sizeof(text_char_t)); + text_end = text_buf; +} + +void text_print(char *s, int left, int top) { + char c; + while (c = *(s++)) { + if (text_end >= text_buf + text_max_chars) break; + text_end->c = c; + text_end->left = left; + text_end->top = top; + text_end++; + left += font_sprite.tile_w; + } +} + +void text_flush(z64_disp_buf_t *db) { + for (int i = 0; i < text_bucket_count; i++) { + sprite_load(db, &font_sprite, + i * text_bucket_size, text_bucket_size); + + text_char_t *text_p = text_buf; + while (text_p < text_end) { + char c = text_p->c; + int left = text_p->left; + int top = text_p->top; + text_p++; + + int bucket = (c - 32) / text_bucket_size; + if (bucket != i) continue; + + int tile_index = (c - 32) % text_bucket_size; + sprite_draw(db, &font_sprite, tile_index, + left, top, + font_sprite.tile_w, font_sprite.tile_h); + } + } + + text_end = text_buf; +} diff --git a/ASM/c/text.h b/ASM/c/text.h new file mode 100644 index 000000000..a12863e97 --- /dev/null +++ b/ASM/c/text.h @@ -0,0 +1,10 @@ +#ifndef TEXT_H +#define TEXT_H + +#include "z64.h" + +void text_init(); +void text_print(char *s, int left, int top); +void text_flush(z64_disp_buf_t *db); + +#endif diff --git a/ASM/c/util.c b/ASM/c/util.c new file mode 100644 index 000000000..874e95b21 --- /dev/null +++ b/ASM/c/util.c @@ -0,0 +1,23 @@ +#include "util.h" + +extern char C_HEAP; +char *heap_next = NULL; + +void heap_init() { + heap_next = &C_HEAP; +} + +void *heap_alloc(int bytes) { + int rem = bytes % 16; + if (rem) bytes += 16 - rem; + + void *result = heap_next; + heap_next += bytes; + return result; +} + + +void file_init(file_t *file) { + file->buf = heap_alloc(file->size); + read_file(file->buf, file->vrom_start, file->size); +} diff --git a/ASM/c/util.h b/ASM/c/util.h new file mode 100644 index 000000000..3e894271a --- /dev/null +++ b/ASM/c/util.h @@ -0,0 +1,23 @@ +#ifndef UTIL_H +#define UTIL_H + +#include + +#define array_size(a) (sizeof(a) / sizeof(a[0])) + +void heap_init(); +void *heap_alloc(int bytes); + +typedef struct { + uint8_t *buf; + uint32_t vrom_start; + uint32_t size; +} file_t; + +typedef void (*read_file_fn)(void *mem_addr, uint32_t vrom_addr, + uint32_t size); +#define read_file ((read_file_fn)0x80000DF0) + +void file_init(file_t *file); + +#endif diff --git a/ASM/c/z64.h b/ASM/c/z64.h new file mode 100644 index 000000000..2b0104d02 --- /dev/null +++ b/ASM/c/z64.h @@ -0,0 +1,1291 @@ +#ifndef Z64_H +#define Z64_H +#include +#include + +#ifndef Z64_VERSION +#error no z64 version specified +#endif + +#define Z64_OOT10 0x00 +#define Z64_OOT11 0x01 +#define Z64_OOT12 0x02 + +#define Z64_SCREEN_WIDTH 320 +#define Z64_SCREEN_HEIGHT 240 + +#define Z64_SEG_PHYS 0x00 +#define Z64_SEG_TITLE 0x01 +#define Z64_SEG_SCENE 0x02 +#define Z64_SEG_ROOM 0x03 +#define Z64_SEG_KEEP 0x04 +#define Z64_SEG_SKEEP 0x05 +#define Z64_SEG_OBJ 0x06 +#define Z64_SEG_ZIMG 0x0E +#define Z64_SEG_CIMG 0x0F + +#define Z64_ETAB_LENGTH 0x0614 + +typedef struct +{ + int16_t x; + int16_t y; + int16_t z; +} z64_xyz_t; + +typedef struct +{ + float x; + float y; + float z; +} z64_xyzf_t; + +typedef uint16_t z64_angle_t; +typedef struct +{ + z64_angle_t x; + z64_angle_t y; + z64_angle_t z; +} z64_rot_t; + +typedef struct +{ + /* index of z64_col_type in scene file */ + uint16_t type; + /* vertex indices, a and b are bitmasked for some reason */ + struct + { + uint16_t unk_00_ : 3; + uint16_t va : 13; + }; + struct + { + uint16_t unk_01_ : 3; + uint16_t vb : 13; + }; + uint16_t vc; + /* normal vector */ + z64_xyz_t norm; + /* plane distance from origin */ + int16_t dist; +} z64_col_poly_t; + +typedef struct +{ + struct + { + uint32_t unk_00_ : 1; + uint32_t drop : 1; /* link drops one unit into the floor */ + uint32_t special : 4; + uint32_t interaction : 5; + uint32_t unk_01_ : 3; + uint32_t behavior : 5; + uint32_t exit : 5; + uint32_t camera : 8; + } flags_1; /* 0x0000 */ + struct + { + uint32_t pad_00_ : 4; + uint32_t wall_damage : 1; + uint32_t unk_00_ : 6; + uint32_t unk_01_ : 3; + uint32_t hookshot : 1; + uint32_t echo : 6; + uint32_t unk_02_ : 5; + uint32_t terrain : 2; + uint32_t material : 4; + } flags_2; /* 0x0004 */ +} z64_col_type_t; + +typedef struct +{ + z64_xyz_t pos; + z64_xyz_t rot; + int16_t fov; + int16_t unk_00_; +} z64_camera_params_t; + +typedef struct +{ + uint16_t mode; + uint16_t unk_01_; + uint32_t seg_params; /* segment address of z64_camera_params_t */ +} z64_camera_t; + +typedef struct +{ + z64_xyz_t pos; + int16_t width; + int16_t depth; + struct + { + uint32_t unk_00_ : 12; + uint32_t active : 1; + uint32_t group : 6; /* ? */ + uint32_t unk_01_ : 5; + uint32_t camera : 8; + } flags; +} z64_col_water_t; + +typedef struct +{ + z64_xyz_t min; + z64_xyz_t max; + uint16_t n_vtx; + z64_xyz_t *vtx; + uint16_t n_poly; + z64_col_poly_t *poly; + z64_col_type_t *type; + z64_camera_t *camera; + uint16_t n_water; + z64_col_water_t *water; +} z64_col_hdr_t; + +typedef enum +{ + Z64_ITEM_NULL = -1, + Z64_ITEM_STICK, + Z64_ITEM_NUT, + Z64_ITEM_BOMB, + Z64_ITEM_BOW, + Z64_ITEM_FIRE_ARROW, + Z64_ITEM_DINS_FIRE, + Z64_ITEM_SLINGSHOT, + Z64_ITEM_FAIRY_OCARINA, + Z64_ITEM_OCARINA_OF_TIME, + Z64_ITEM_BOMBCHU, + Z64_ITEM_HOOKSHOT, + Z64_ITEM_LONGSHOT, + Z64_ITEM_ICE_ARROW, + Z64_ITEM_FARORES_WIND, + Z64_ITEM_BOOMERANG, + Z64_ITEM_LENS, + Z64_ITEM_BEANS, + Z64_ITEM_HAMMER, + Z64_ITEM_LIGHT_ARROW, + Z64_ITEM_NAYRUS_LOVE, + Z64_ITEM_BOTTLE, + Z64_ITEM_RED_POTION, + Z64_ITEM_GREEN_POTION, + Z64_ITEM_BLUE_POTION, + Z64_ITEM_FAIRY, + Z64_ITEM_FISH, + Z64_ITEM_MILK, + Z64_ITEM_LETTER, + Z64_ITEM_BLUE_FIRE, + Z64_ITEM_BUG, + Z64_ITEM_BIG_POE, + Z64_ITEM_HALF_MILK, + Z64_ITEM_POE, + Z64_ITEM_WEIRD_EGG, + Z64_ITEM_CHICKEN, + Z64_ITEM_ZELDAS_LETTER, + Z64_ITEM_KEATON_MASK, + Z64_ITEM_SKULL_MASK, + Z64_ITEM_SPOOKY_MASK, + Z64_ITEM_BUNNY_HOOD, + Z64_ITEM_GORON_MASK, + Z64_ITEM_ZORA_MASK, + Z64_ITEM_GERUDO_MASK, + Z64_ITEM_MASK_OF_TRUTH, + Z64_ITEM_SOLD_OUT, + Z64_ITEM_POCKET_EGG, + Z64_ITEM_POCKET_CUCCO, + Z64_ITEM_COJIRO, + Z64_ITEM_ODD_MUSHROOM, + Z64_ITEM_ODD_POTION, + Z64_ITEM_POACHERS_SAW, + Z64_ITEM_BROKEN_GORONS_SWORD, + Z64_ITEM_PRESCRIPTION, + Z64_ITEM_EYEBALL_FROG, + Z64_ITEM_EYE_DROPS, + Z64_ITEM_CLAIM_CHECK, + Z64_ITEM_BOW_FIRE_ARROW, + Z64_ITEM_BOW_ICE_ARROW, + Z64_ITEM_BOW_LIGHT_ARROW, + Z64_ITEM_KOKIRI_SWORD, + Z64_ITEM_MASTER_SWORD, + Z64_ITEM_BIGGORON_SWORD, + Z64_ITEM_DEKU_SHIELD, + Z64_ITEM_HYLIAN_SHIELD, + Z64_ITEM_MIRROR_SHIELD, + Z64_ITEM_KOKIRI_TUNIC, + Z64_ITEM_GORON_TUNIC, + Z64_ITEM_ZORA_TUNIC, + Z64_ITEM_KOKIRI_BOOTS, + Z64_ITEM_IRON_BOOTS, + Z64_ITEM_HOVER_BOOTS, + Z64_ITEM_BULLET_BAG_30, + Z64_ITEM_BULLET_BAG_40, + Z64_ITEM_BULLET_BAG_50, + Z64_ITEM_QUIVER_30, + Z64_ITEM_QUIVER_40, + Z64_ITEM_QUIVER_50, + Z64_ITEM_BOMB_BAG_20, + Z64_ITEM_BOMB_BAG_30, + Z64_ITEM_BOMB_BAG_40, + Z64_ITEM_GORONS_BRACELET, + Z64_ITEM_SILVER_GAUNTLETS, + Z64_ITEM_GOLDEN_GAUNTLETS, + Z64_ITEM_SILVER_SCALE, + Z64_ITEM_GOLDEN_SCALE, + Z64_ITEM_BROKEN_GIANTS_KNIFE, + Z64_ITEM_ADULTS_WALLET, + Z64_ITEM_GIANTS_WALLET, + Z64_ITEM_DEKU_SEEDS, + Z64_ITEM_FISHING_POLE, + Z64_ITEM_MINUET, + Z64_ITEM_BOLERO, + Z64_ITEM_SERENADE, + Z64_ITEM_REQUIEM, + Z64_ITEM_NOCTURNE, + Z64_ITEM_PRELUDE, + Z64_ITEM_ZELDAS_LULLABY, + Z64_ITEM_EPONAS_SONG, + Z64_ITEM_SARIAS_SONG, + Z64_ITEM_SUNS_SONG, + Z64_ITEM_SONG_OF_TIME, + Z64_ITEM_SONG_OF_STORMS, + Z64_ITEM_FOREST_MEDALLION, + Z64_ITEM_FIRE_MEDALLION, + Z64_ITEM_WATER_MEDALLION, + Z64_ITEM_SPIRIT_MEDALLION, + Z64_ITEM_SHADOW_MEDALLION, + Z64_ITEM_LIGHT_MEDALLION, + Z64_ITEM_KOKIRIS_EMERALD, + Z64_ITEM_GORONS_RUBY, + Z64_ITEM_ZORAS_SAPPHIRE, + Z64_ITEM_STONE_OF_AGONY, + Z64_ITEM_GERUDOS_CARD, + Z64_ITEM_GOLD_SKULLTULA, + Z64_ITEM_HEART_CONTAINER, + Z64_ITEM_PIECE_OF_HEART, + Z64_ITEM_BOSS_KEY, + Z64_ITEM_COMPASS, + Z64_ITEM_DUNGEON_MAP, + Z64_ITEM_SMALL_KEY, +} z64_item_t; + +typedef enum +{ + Z64_SLOT_STICK, + Z64_SLOT_NUT, + Z64_SLOT_BOMB, + Z64_SLOT_BOW, + Z64_SLOT_FIRE_ARROW, + Z64_SLOT_DINS_FIRE, + Z64_SLOT_SLINGSHOT, + Z64_SLOT_OCARINA, + Z64_SLOT_BOMBCHU, + Z64_SLOT_HOOKSHOT, + Z64_SLOT_ICE_ARROW, + Z64_SLOT_FARORES_WIND, + Z64_SLOT_BOOMERANG, + Z64_SLOT_LENS, + Z64_SLOT_BEANS, + Z64_SLOT_HAMMER, + Z64_SLOT_LIGHT_ARROW, + Z64_SLOT_NAYRUS_LOVE, + Z64_SLOT_BOTTLE_1, + Z64_SLOT_BOTTLE_2, + Z64_SLOT_BOTTLE_3, + Z64_SLOT_BOTTLE_4, + Z64_SLOT_ADULT_TRADE, + Z64_SLOT_CHILD_TRADE, +} z64_slot_t; + +typedef enum +{ + Z64_ITEMBTN_B, + Z64_ITEMBTN_CL, + Z64_ITEMBTN_CD, + Z64_ITEMBTN_CR, +} z64_itembtn_t; + +typedef struct +{ + char unk_00_[0x006E]; /* 0x0000 */ + int16_t run_speed_limit; /* 0x006E */ + char unk_01_[0x0004]; /* 0x0070 */ + int16_t run_speed_max_anim; /* 0x0074 */ + char unk_02_[0x0026]; /* 0x0076 */ + int16_t gravity; /* 0x009C */ + char unk_03_[0x0072]; /* 0x009E */ + uint16_t update_rate; /* 0x0110 */ + char unk_04_[0x0022]; /* 0x0112 */ + int16_t override_aspect; /* 0x0134 */ + uint16_t aspect_width; /* 0x0136 */ + uint16_t aspect_height; /* 0x0138 */ + char unk_05_[0x0050]; /* 0x013A */ + int16_t game_playing; /* 0x018A */ + char unk_06_[0x03B8]; /* 0x018C */ + uint16_t c_up_icon_x; /* 0x0544 */ + uint16_t c_up_icon_y; /* 0x0546 */ + char unk_07_[0x021C]; /* 0x0548 */ + uint16_t game_freeze; /* 0x0764 */ + char unk_08_[0x002E]; /* 0x0766 */ + uint16_t magic_fill_r; /* 0x0794 */ + uint16_t magic_fill_g; /* 0x0796 */ + uint16_t magic_fill_b; /* 0x0798 */ + char unk_09_[0x004A]; /* 0x079A */ + uint16_t c_button_r; /* 0x07E4 */ + uint16_t c_button_g; /* 0x07E6 */ + uint16_t c_button_b; /* 0x07E8 */ + uint16_t b_button_r; /* 0x07EA */ + uint16_t b_button_g; /* 0x07EC */ + uint16_t b_button_b; /* 0x07EE */ + char unk_0A_[0x0004]; /* 0x07F0 */ + qs510_t start_icon_dd; /* 0x07F4 */ + int16_t start_icon_scale; /* 0x07F6 */ + char unk_0B_[0x0006]; /* 0x07F8 */ + uint16_t start_icon_y; /* 0x07FE */ + char unk_0C_[0x0002]; /* 0x0800 */ + uint16_t start_icon_x; /* 0x0802 */ + char unk_0D_[0x000C]; /* 0x0804 */ + uint16_t c_up_button_x; /* 0x0810 */ + uint16_t c_up_button_y; /* 0x0812 */ + char unk_0E_[0x0008]; /* 0x0814 */ + uint16_t start_button_x; /* 0x081C */ + uint16_t start_button_y; /* 0x081E */ + uint16_t item_button_x[4]; /* 0x0820 */ + uint16_t item_button_y[4]; /* 0x0828 */ + qs510_t item_button_dd[4]; /* 0x0830 */ + uint16_t item_icon_x[4]; /* 0x0838 */ + uint16_t item_icon_y[4]; /* 0x0840 */ + qs510_t item_icon_dd[4]; /* 0x0848 */ + char unk_0F_[0x0264]; /* 0x0850 */ + uint16_t a_button_y; /* 0x0AB4 */ + uint16_t a_button_x; /* 0x0AB6 */ + char unk_10_[0x0002]; /* 0x0AB8 */ + uint16_t a_button_icon_y; /* 0x0ABA */ + uint16_t a_button_icon_x; /* 0x0ABC */ + char unk_11_[0x0002]; /* 0x0ABE */ + uint16_t a_button_r; /* 0x0AC0 */ + uint16_t a_button_g; /* 0x0AC2 */ + uint16_t a_button_b; /* 0x0AC4 */ + char unk_12_[0x0030]; /* 0x0AC6 */ + uint16_t magic_bar_x; /* 0x0AF6 */ + uint16_t magic_bar_y; /* 0x0AF8 */ + uint16_t magic_fill_x; /* 0x0AFA */ + char unk_13_[0x02D6]; /* 0x0AFC */ + int16_t minimap_disabled; /* 0x0DD2 */ + char unk_14_[0x01C0]; /* 0x0DD4 */ + uint16_t item_ammo_x[4]; /* 0x0F94 */ + uint16_t item_ammo_y[4]; /* 0x0F9C */ + char unk_15_[0x0008]; /* 0x0FA4 */ + uint16_t item_icon_space[4]; /* 0x0FAC */ + uint16_t item_button_space[4]; /* 0x0FB4 */ + /* 0x0FBC */ +} z64_gameinfo_t; + +typedef struct +{ + int32_t entrance_index; /* 0x0000 */ + int32_t link_age; /* 0x0004 */ + char unk_00_[0x0002]; /* 0x0008 */ + uint16_t cutscene_index; /* 0x000A */ + uint16_t day_time; /* 0x000C */ + char unk_01_[0x0002]; /* 0x000E */ + int32_t night_flag; /* 0x0010 */ + char unk_02_[0x0008]; /* 0x0014 */ + char id[6]; /* 0x001C */ + int16_t deaths; /* 0x0022 */ + char file_name[0x08]; /* 0x0024 */ + int16_t n64dd_flag; /* 0x002C */ + int16_t energy_capacity; /* 0x002E */ + int16_t energy; /* 0x0030 */ + uint8_t magic_capacity_set; /* 0x0032 */ + uint8_t magic; /* 0x0033 */ + uint16_t rupees; /* 0x0034 */ + uint16_t bgs_hits_left; /* 0x0036 */ + uint16_t navi_timer; /* 0x0038 */ + uint8_t magic_acquired; /* 0x003A */ + char unk_03_; /* 0x003B */ + uint8_t magic_capacity; /* 0x003C */ + int8_t double_defense; /* 0x003D */ + int8_t bgs_flag; /* 0x003E */ + char unk_05_; /* 0x003F */ + int8_t child_button_items[4]; /* 0x0040 */ + int8_t child_c_button_slots[3]; /* 0x0044 */ + union + { + uint16_t child_equips; /* 0x0048 */ + struct + { + uint16_t child_equip_boots : 4; + uint16_t child_equip_tunic : 4; + uint16_t child_equip_shield : 4; + uint16_t child_equip_sword : 4; + }; + }; + int8_t adult_button_items[4]; /* 0x004A */ + int8_t adult_c_button_slots[3]; /* 0x004E */ + union + { + uint16_t adult_equips; /* 0x0052 */ + struct + { + uint16_t adult_equip_boots : 4; + uint16_t adult_equip_tunic : 4; + uint16_t adult_equip_shield : 4; + uint16_t adult_equip_sword : 4; + }; + }; + char unk_06_[0x0012]; /* 0x0054 */ + int16_t scene_index; /* 0x0066 */ + int8_t button_items[4]; /* 0x0068 */ + int8_t c_button_slots[3]; /* 0x006C */ + union + { + uint16_t equips; /* 0x0070 */ + struct + { + uint16_t equip_boots : 4; + uint16_t equip_tunic : 4; + uint16_t equip_shield : 4; + uint16_t equip_sword : 4; + }; + }; + char unk_07_[0x0002]; /* 0x0072 */ + int8_t items[24]; /* 0x0074 */ + int8_t ammo[15]; /* 0x008C */ + uint8_t magic_beans_sold; /* 0x009B */ + union + { + uint16_t equipment; /* 0x009C */ + struct + { + uint16_t : 1; + uint16_t hover_boots : 1; + uint16_t iron_boots : 1; + uint16_t kokiri_boots : 1; + uint16_t : 1; + uint16_t zora_tunic : 1; + uint16_t goron_tunic : 1; + uint16_t kokiri_tunic : 1; + uint16_t : 1; + uint16_t mirror_shield : 1; + uint16_t hylian_shield : 1; + uint16_t deku_shield : 1; + uint16_t broken_giants_knife : 1; + uint16_t giants_knife : 1; + uint16_t master_sword : 1; + uint16_t kokiri_sword : 1; + }; + }; + char unk_08_[0x0002]; /* 0x009E */ + union + { + uint32_t equipment_items; /* 0x00A0 */ + struct + { + uint32_t : 9; + uint32_t nut_upgrade : 3; + uint32_t stick_upgrade : 3; + uint32_t bullet_bag : 3; + uint32_t wallet : 2; + uint32_t diving_upgrade : 3; + uint32_t strength_upgrade : 3; + uint32_t bomb_bag : 3; + uint32_t quiver : 3; + }; + }; + union + { + uint32_t quest_items; /* 0x00A4 */ + struct + { + uint32_t heart_pieces : 8; + uint32_t gold_skulltula : 1; + uint32_t gerudos_card : 1; + uint32_t stone_of_agony : 1; + uint32_t zoras_sapphire : 1; + uint32_t gorons_ruby : 1; + uint32_t kokiris_emerald : 1; + uint32_t song_of_storms : 1; + uint32_t song_of_time : 1; + uint32_t suns_song : 1; + uint32_t sarias_song : 1; + uint32_t eponas_song : 1; + uint32_t zeldas_lullaby : 1; + uint32_t prelude_of_light : 1; + uint32_t nocturne_of_shadow : 1; + uint32_t requiem_of_spirit : 1; + uint32_t serenade_of_water : 1; + uint32_t bolero_of_fire : 1; + uint32_t minuet_of_forest : 1; + uint32_t light_medallion : 1; + uint32_t shadow_medallion : 1; + uint32_t spirit_medallion : 1; + uint32_t water_medallion : 1; + uint32_t fire_medallion : 1; + uint32_t forest_medallion : 1; + }; + }; + union + { + uint8_t items; + struct + { + uint8_t : 5; + uint8_t map : 1; + uint8_t compass : 1; + uint8_t boss_key : 1; + }; + } dungeon_items[20]; /* 0x00A8 */ + int8_t dungeon_keys[19]; /* 0x00BC */ + uint8_t defense_hearts; /* 0x00CF */ + int16_t gs_tokens; /* 0x00D0 */ + char unk_09_[0x0002]; /* 0x00D2 */ + struct + { + uint32_t chest; + uint32_t swch; + uint32_t clear; + uint32_t collect; + uint32_t unk_00_; + uint32_t rooms_1; + uint32_t rooms_2; + } scene_flags[101]; /* 0x00D4 */ + char unk_0A_[0x0284]; /* 0x0BE0 */ + z64_xyzf_t fw_pos; /* 0x0E64 */ + z64_angle_t fw_yaw; /* 0x0E70 */ + char unk_0B_[0x0008]; /* 0x0E72 */ + uint16_t fw_scene_index; /* 0x0E7A */ + uint32_t fw_room_index; /* 0x0E7C */ + int32_t fw_set; /* 0x0E80 */ + char unk_0C_[0x0018]; /* 0x0E84 */ + uint8_t gs_flags[56]; /* 0x0E9C */ + uint16_t event_chk_inf[14]; /* 0x0ED4 */ + uint16_t item_get_inf[4]; /* 0x0EF0 */ + uint16_t inf_table[30]; /* 0x0EF8 */ + char unk_0D_[0x041E]; /* 0x0F34 */ + uint16_t checksum; /* 0x1352 */ + char unk_0E_[0x0003]; /* 0x1354 */ + int8_t file_index; /* 0x1357 */ + char unk_0F_[0x0004]; /* 0x1358 */ + int32_t interface_flag; /* 0x135C */ + uint32_t scene_setup_index; /* 0x1360 */ + int32_t void_flag; /* 0x1364 */ + z64_xyzf_t void_pos; /* 0x1368 */ + z64_angle_t void_yaw; /* 0x1374 */ + int16_t void_var; /* 0x1376 */ + int16_t void_entrance; /* 0x1378 */ + int8_t void_room_index; /* 0x137A */ + int8_t unk_10_; /* 0x137B */ + uint32_t temp_swch_flags; /* 0x137C */ + uint32_t temp_collect_flags; /* 0x1380 */ + char unk_11_[0x0044]; /* 0x1384 */ + uint16_t nayrus_love_timer; /* 0x13C8 */ + char unk_12_[0x0004]; /* 0x13CA */ + int16_t timer_1_state; /* 0x13CE */ + int16_t timer_1_value; /* 0x13D0 */ + int16_t timer_2_state; /* 0x13D2 */ + int16_t timer_2_value; /* 0x13D4 */ + char unk_13_[0x000A]; /* 0x13D6 */ + int8_t seq_index; /* 0x13E0 */ + int8_t night_sfx; /* 0x13E1 */ + char unk_14_[0x0018]; /* 0x13E2 */ + uint16_t event_inf[4]; /* 0x13FA */ + char unk_15_[0x0001]; /* 0x1402 */ + uint8_t minimap_index; /* 0x1403 */ + int16_t minigame_state; /* 0x1404 */ + char unk_16_[0x0003]; /* 0x1406 */ + uint8_t language; /* 0x1409 */ + char unk_17_[0x0002]; /* 0x140A */ + uint8_t z_targeting; /* 0x140C */ + char unk_18_[0x0001]; /* 0x140D */ + uint16_t disable_music_flag; /* 0x140E */ + char unk_19_[0x0020]; /* 0x1410 */ + z64_gameinfo_t *gameinfo; /* 0x1430 */ + char unk_1A_[0x001C]; /* 0x1434 */ + /* 0x1450 */ +} z64_file_t; + +typedef struct +{ + uint32_t seg[16]; +} z64_stab_t; + +typedef struct +{ + uint8_t scene_index; + uint8_t entrance_index; + union + { + uint16_t variable; + struct + { + uint16_t transition_out : 7; + uint16_t transition_in : 7; + uint16_t unk_00_ : 1; + uint16_t continue_music : 1; + }; + }; +} z64_entrance_table_t; + +typedef struct +{ + uint32_t scene_vrom_start; + uint32_t scene_vrom_end; + uint32_t title_vrom_start; + uint32_t title_vrom_end; + char unk_00_; + uint8_t scene_config; + char unk_01_; + char padding_00_; +} z64_scene_table_t; + +typedef struct +{ + uint32_t size; /* 0x0000 */ + Gfx *buf; /* 0x0004 */ + Gfx *p; /* 0x0008 */ + Gfx *d; /* 0x000C */ +} z64_disp_buf_t; + +typedef struct +{ + Gfx *poly_opa_w; /* 0x0000 */ + Gfx *poly_xlu_w; /* 0x0004 */ + char unk_00_[0x0008]; /* 0x0008 */ + Gfx *overlay_w; /* 0x0010 */ + char unk_01_[0x00A4]; /* 0x0014 */ + Gfx *work_c; /* 0x00B8 */ + uint32_t work_c_size; /* 0x00BC */ + char unk_02_[0x00F0]; /* 0x00C0 */ + Gfx *work_w; /* 0x01B0 */ + z64_disp_buf_t work; /* 0x01B4 */ + char unk_03_[0x00E4]; /* 0x01C4 */ + z64_disp_buf_t overlay; /* 0x02A8 */ + z64_disp_buf_t poly_opa; /* 0x02B8 */ + z64_disp_buf_t poly_xlu; /* 0x02C8 */ + uint32_t frame_count_1; /* 0x02D8 */ + void *frame_buffer; /* 0x02DC */ + char unk_04_[0x0008]; /* 0x02E0 */ + uint32_t frame_count_2; /* 0x02E8 */ + /* 0x02EC */ +} z64_gfx_t; + +typedef struct +{ + union + { + struct + { + uint16_t a : 1; + uint16_t b : 1; + uint16_t z : 1; + uint16_t s : 1; + uint16_t du : 1; + uint16_t dd : 1; + uint16_t dl : 1; + uint16_t dr : 1; + uint16_t : 2; + uint16_t l : 1; + uint16_t r : 1; + uint16_t cu : 1; + uint16_t cd : 1; + uint16_t cl : 1; + uint16_t cr : 1; + }; + uint16_t pad; + }; + int8_t x; + int8_t y; +} z64_controller_t; + +typedef struct z64_actor_s z64_actor_t; +struct z64_actor_s +{ + int16_t actor_id; /* 0x0000 */ + uint8_t actor_type; /* 0x0002 */ + int8_t room_index; /* 0x0003 */ + uint32_t flags; /* 0x0004 */ + z64_xyzf_t pos_1; /* 0x0008 */ + z64_rot_t rot_init; /* 0x0014 */ + char unk_01_[0x0002]; /* 0x001A */ + uint16_t variable; /* 0x001C */ + uint8_t alloc_index; /* 0x001E */ + char unk_02_; /* 0x001F */ + uint16_t sound_effect; /* 0x0020 */ + char unk_03_[0x0002]; /* 0x0022 */ + z64_xyzf_t pos_2; /* 0x0024 */ + char unk_04_[0x0002]; /* 0x0030 */ + uint16_t xz_dir; /* 0x0032 */ + char unk_05_[0x0004]; /* 0x0034 */ + z64_xyzf_t pos_3; /* 0x0038 */ + z64_rot_t rot_1; /* 0x0044 */ + char unk_06_[0x0002]; /* 0x004A */ + float unk_07_; /* 0x004C */ + z64_xyzf_t scale; /* 0x0050 */ + z64_xyzf_t vel_1; /* 0x005C */ + float xz_speed; /* 0x0068 */ + float gravity; /* 0x006C */ + float min_vel_y; /* 0x0070 */ + void *unk_08_; /* 0x0074 */ + z64_col_poly_t *floor_poly; /* 0x0078 */ + char unk_0A_[0x001C]; /* 0x007C */ + void *damage_table; /* 0x0098 */ + z64_xyzf_t vel_2; /* 0x009C */ + char unk_0B_[0x0006]; /* 0x00A8 */ + int16_t health; /* 0x00AE */ + char unk_0C_; /* 0x00B0 */ + uint8_t damage_effect; /* 0x00B1 */ + char unk_0D_[0x0002]; /* 0x00B2 */ + z64_rot_t rot_2; /* 0x00B4 */ + char unk_0E_[0x0046]; /* 0x00BA */ + z64_xyzf_t pos_4; /* 0x0100 */ + uint16_t unk_0F_; /* 0x010C */ + uint16_t text_id; /* 0x010E */ + int16_t frozen; /* 0x0110 */ + char unk_10_[0x0003]; /* 0x0112 */ + uint8_t active; /* 0x0115 */ + char unk_11_[0x0002]; /* 0x0116 */ + z64_actor_t *unk_12_; /* 0x0118 */ + char unk_13_[0x0004]; /* 0x011C */ + z64_actor_t *prev; /* 0x0120 */ + z64_actor_t *next; /* 0x0124 */ + void *ctor; /* 0x0128 */ + void *dtor; /* 0x012C */ + void *main_proc; /* 0x0130 */ + void *draw_proc; /* 0x0134 */ + void *code_entry; /* 0x0138 */ + /* 0x013C */ +}; + +typedef struct +{ + z64_actor_t common; /* 0x0000 */ + char unk_00_[0x02F8]; /* 0x013C */ + uint8_t action; /* 0x0434 */ + char unk_01_[0x0237]; /* 0x0435 */ + uint32_t state_flags_1; /* 0x066C */ + uint32_t state_flags_2; /* 0x0670 */ + char unk_02_[0x01B4]; /* 0x0674 */ + float linear_vel; /* 0x0828 */ + char unk_03_[0x0002]; /* 0x082C */ + uint16_t target_yaw; /* 0x082E */ + char unk_04_[0x0003]; /* 0x0830 */ + int8_t sword_state; /* 0x0833 */ + char unk_05_[0x0050]; /* 0x0834 */ + int16_t drop_y; /* 0x0884 */ + int16_t drop_distance; /* 0x0886 */ + /* 0x0888 */ +} z64_link_t; + +typedef struct +{ + z64_controller_t raw; + uint16_t unk_00_; + z64_controller_t raw_prev; + uint16_t unk_01_; + uint16_t pad_pressed; + int8_t x_diff; + int8_t y_diff; + char unk_02_[0x0002]; + uint16_t pad_released; + int8_t adjusted_x; + int8_t adjusted_y; + char unk_03_[0x0002]; +} z64_input_t; + +/* context base */ +typedef struct +{ + z64_gfx_t *gfx; /* 0x0000 */ + void *state_main; /* 0x0004 */ + void *state_dtor; /* 0x0008 */ + void *next_ctor; /* 0x000C */ + uint32_t next_size; /* 0x0010 */ + z64_input_t input[4]; /* 0x0014 */ + uint32_t state_heap_size; /* 0x0074 */ + void *state_heap; /* 0x0078 */ + void *heap_start; /* 0x007C */ + void *heap_end; /* 0x0080 */ + void *state_heap_node; /* 0x0084 */ + char unk_00_[0x0010]; /* 0x0088 */ + int32_t state_continue; /* 0x0098 */ + int32_t state_frames; /* 0x009C */ + uint32_t unk_01_; /* 0x00A0 */ + /* 0x00A4 */ +} z64_ctxt_t; + +typedef struct +{ + /* file loading params */ + uint32_t vrom_addr; + void *dram_addr; + uint32_t size; + /* unknown, seem to be unused */ + void *unk_00_; + uint32_t unk_01_; + uint32_t unk_02_; + /* completion notification params */ + OSMesgQueue *notify_queue; + OSMesg notify_message; +} z64_getfile_t; + +/* object structs */ +typedef struct +{ + int16_t id; + void *data; + z64_getfile_t getfile; + OSMesgQueue load_mq; + OSMesg load_m; +} z64_mem_obj_t; + +typedef struct +{ + void *obj_space_start; + void *obj_space_end; + uint8_t n_objects; + char unk_00_; + uint8_t keep_index; + uint8_t skeep_index; + z64_mem_obj_t objects[19]; +} z64_obj_ctxt_t; + +typedef struct +{ + uint32_t vrom_start; + uint32_t vrom_end; +} z64_object_table_t; + +/* lighting structs */ +typedef struct +{ + int8_t dir[3]; + uint8_t col[3]; +} z64_light1_t; + +typedef struct +{ + int16_t x; + int16_t y; + int16_t z; + uint8_t col[3]; + int16_t intensity; +} z64_light2_t; + +typedef union +{ + z64_light1_t light1; + z64_light2_t light2; +} z64_lightn_t; + +typedef struct +{ + uint8_t type; + z64_lightn_t lightn; +} z64_light_t; + +typedef struct z64_light_node_s z64_light_node_t; +struct z64_light_node_s +{ + z64_light_t *light; + z64_light_node_t *prev; + z64_light_node_t *next; +}; + +typedef struct +{ + z64_light_node_t *light_list; + uint8_t ambient[3]; + uint8_t fog[3]; + int16_t fog_position; + int16_t draw_distance; +} z64_lighting_t; + +typedef struct +{ + int8_t numlights; + Lightsn lites; +} z64_gbi_lights_t; + +typedef void (*z64_light_handler_t)(z64_gbi_lights_t*, z64_lightn_t*, + z64_actor_t*); + +/* game context */ +typedef struct +{ + z64_ctxt_t common; /* 0x00000 */ + uint16_t scene_index; /* 0x000A4 */ + char unk_00_[0x001A]; /* 0x000A6 */ + uint32_t screen_top; /* 0x000C0 */ + uint32_t screen_bottom; /* 0x000C4 */ + uint32_t screen_left; /* 0x000C8 */ + uint32_t screen_right; /* 0x000CC */ + float camera_distance; /* 0x000D0 */ + float fog_distance; /* 0x000D4 */ + float z_distance; /* 0x000D8 */ + float unk_01_; /* 0x000DC */ + char unk_02_[0x0190]; /* 0x000E0 */ + z64_actor_t *camera_focus; /* 0x00270 */ + char unk_03_[0x00AE]; /* 0x00274 */ + uint16_t camera_mode; /* 0x00322 */ + char unk_04_[0x001A]; /* 0x00324 */ + uint16_t camera_flag_1; /* 0x0033E */ + char unk_05_[0x016C]; /* 0x00340 */ + int16_t event_flag; /* 0x004AC */ + char unk_06_[0x02FA]; /* 0x004AE */ + z64_lighting_t lighting; /* 0x007A8 */ + char unk_07_[0x0008]; /* 0x007B8 */ + z64_col_hdr_t *col_hdr; /* 0x007C0 */ + char unk_08_[0x1460]; /* 0x007C4 */ + char actor_ctxt[0x0008]; /* 0x01C24 */ + uint8_t n_actors_loaded; /* 0x01C2C */ + char unk_09_[0x0003]; /* 0x01C2D */ + struct + { + uint32_t length; + z64_actor_t *first; + } actor_list[12]; /* 0x01C30 */ + char unk_0A_[0x0038]; /* 0x01C90 */ + z64_actor_t *arrow_actor; /* 0x01CC8 */ + z64_actor_t *target_actor; /* 0x01CCC */ + char unk_0B_[0x0058]; /* 0x01CD0 */ + uint32_t swch_flags; /* 0x01D28 */ + uint32_t temp_swch_flags; /* 0x01D2C */ + uint32_t unk_flags_0; /* 0x01D30 */ + uint32_t unk_flags_1; /* 0x01D34 */ + uint32_t chest_flags; /* 0x01D38 */ + uint32_t clear_flags; /* 0x01D3C */ + uint32_t temp_clear_flags; /* 0x01D40 */ + uint32_t collect_flags; /* 0x01D44 */ + uint32_t temp_collect_flags; /* 0x01D48 */ + void *title_card_texture; /* 0x01D4C */ + char unk_0C_[0x0007]; /* 0x01D50 */ + uint8_t title_card_delay; /* 0x01D57 */ + char unk_0D_[0x0010]; /* 0x01D58 */ + void *cutscene_ptr; /* 0x01D68 */ + int8_t cutscene_state; /* 0x01D6C */ + char unk_0E_[0xE66F]; /* 0x01D6D */ + uint8_t textbox_state_1; /* 0x103DC */ + char unk_0F_[0x00DF]; /* 0x103DD */ + uint8_t textbox_state_2; /* 0x104BC */ + char unk_10_[0x0002]; /* 0x104BD */ + uint8_t textbox_state_3; /* 0x104BF */ + char unk_11_[0x0292]; /* 0x104C0 */ + struct + { + uint8_t unk_00_; + uint8_t b_button; + uint8_t unk_01_; + uint8_t bottles; + uint8_t trade_items; + uint8_t hookshot; + uint8_t ocarina; + uint8_t warp_songs; + uint8_t suns_song; + uint8_t farores_wind; + uint8_t dfnl; + uint8_t all; + } restriction_flags; /* 0x10752 */ + char unk_12_[0x01D6]; /* 0x1075E */ + uint16_t pause_state; /* 0x10934 */ + char unk_13_[0x000E]; /* 0x10936 */ + uint16_t pause_screen_changing; /* 0x10944 */ + uint16_t pause_screen_prev; /* 0x10946 */ + uint16_t pause_screen; /* 0x10948 */ + char unk_14_[0x002E]; /* 0x1094A */ + int16_t item_screen_cursor; /* 0x10978 */ + char unk_15_[0x0002]; /* 0x1097A */ + int16_t quest_screen_cursor; /* 0x1097C */ + int16_t equip_screen_cursor; /* 0x1097E */ + int16_t map_screen_cursor; /* 0x10980 */ + int16_t item_screen_x; /* 0x10982 */ + char unk_16_[0x0004]; /* 0x10984 */ + int16_t equipment_screen_x; /* 0x10988 */ + char unk_17_[0x0002]; /* 0x1098A */ + int16_t item_screen_y; /* 0x1098C */ + char unk_18_[0x0004]; /* 0x1099E */ + int16_t equipment_screen_y; /* 0x10992 */ + char unk_19_[0x0004]; /* 0x10994 */ + int16_t pause_screen_cursor; /* 0x10998 */ + char unk_1A_[0x0002]; /* 0x1099A */ + int16_t pause_screen_item; /* 0x1099C */ + int16_t item_screen_item; /* 0x1099E */ + int16_t map_screen_item; /* 0x109A0 */ + int16_t quest_screen_item; /* 0x109A2 */ + int16_t equip_screen_item; /* 0x109A4 */ + char unk_1B_[0x0004]; /* 0x109A6 */ + int16_t quest_screen_hilite; /* 0x109AA */ + char unk_1C_[0x0018]; /* 0x109AC */ + int16_t quest_screen_song; /* 0x109C4 */ + char unk_1D_[0x0DDE]; /* 0x109C6 */ + z64_obj_ctxt_t obj_ctxt; /* 0x117A4 */ + int8_t room_index; /* 0x11CBC */ + char unk_1E_[0x000B]; /* 0x11CBD */ + void *room_ptr; /* 0x11CC8 */ + char unk_1F_[0x0118]; /* 0x11CCC */ + uint32_t gameplay_frames; /* 0x11DE4 */ + uint8_t link_age; /* 0x11DE8 */ + char unk_20_; /* 0x11DE9 */ + uint8_t spawn_index; /* 0x11DEA */ + uint8_t n_map_actors; /* 0x11DEB */ + uint8_t n_rooms; /* 0x11DEC */ + char unk_21_[0x000B]; /* 0x11DED */ + void *map_actor_list; /* 0x11DF8 */ + char unk_22_[0x0008]; /* 0x11DFC */ + void *scene_exit_list; /* 0x11E04 */ + char unk_23_[0x000C]; /* 0x11E08 */ + uint8_t skybox_type; /* 0x11E14 */ + int8_t scene_load_flag; /* 0x11E15 */ + char unk_24_[0x0004]; /* 0x11E16 */ + int16_t entrance_index; /* 0x11E1A */ + char unk_25_[0x0042]; /* 0x11E1C */ + uint8_t fadeout_transition; /* 0x11E5E */ + /* 0x11E5F */ +} z64_game_t; + +#if Z64_VERSION == Z64_OOT10 + +/* dram addresses */ +#define z64_osSendMesg_addr 0x80001E20 +#define z64_osRecvMesg_addr 0x80002030 +#define z64_osCreateMesgQueue_addr 0x80004220 +#define z64_file_mq_addr 0x80007D40 +#define z64_vi_counter_addr 0x80009E8C +#define z64_DrawActors_addr 0x80024AB4 +#define z64_DeleteActor_addr 0x80024FE0 +#define z64_SpawnActor_addr 0x80025110 +#define z64_minimap_disable_1_addr 0x8006CD50 +#define z64_minimap_disable_2_addr 0x8006D4E4 +#define z64_SwitchAgeEquips_addr 0x8006F804 +#define z64_UpdateItemButton_addr 0x8006FB50 +#define z64_UpdateEquipment_addr 0x80079764 +#define z64_LoadRoom_addr 0x80080A3C +#define z64_UnloadRoom_addr 0x80080C98 +#define z64_Io_addr 0x80091474 +#define z64_entrance_offset_hook_addr 0x8009AA44 +#define z64_frame_update_func_addr 0x8009AF1C +#define z64_frame_update_call_addr 0x8009CAE8 +#define z64_disp_swap_1_addr 0x800A1198 +#define z64_disp_swap_2_addr 0x800A11B0 +#define z64_disp_swap_3_addr 0x800A11C8 +#define z64_disp_swap_4_addr 0x800A11E4 +#define z64_frame_input_func_addr 0x800A0BA0 +#define z64_main_hook_addr 0x800A0C3C +#define z64_frame_input_call_addr 0x800A16AC +#define gspF3DEX2_NoN_fifoTextStart 0x800E3F70 +#define z64_day_speed_addr 0x800F1650 +#define z64_light_handlers_addr 0x800F1B40 +#define z64_object_table_addr 0x800F8FF8 +#define z64_entrance_table_addr 0x800F9C90 +#define z64_scene_table_addr 0x800FB4E0 +#define z64_scene_config_table_addr 0x800FBD18 +#define z64_seq_pos_addr 0x801043B0 +#define gspF3DEX2_NoN_fifoDataStart 0x801145C0 +#define z64_file_addr 0x8011A5D0 +#define z64_input_direct_addr 0x8011D730 +#define z64_stab_addr 0x80120C38 +#define z64_seq_buf_addr 0x80124800 +#define z64_ctxt_addr 0x801C84A0 +#define z64_link_addr 0x801DAA30 + +/* rom addresses */ +#define z64_icon_item_static_vaddr 0x007BD000 +#define z64_icon_item_static_vsize 0x000888A0 +#define z64_icon_item_24_static_vaddr 0x00846000 +#define z64_icon_item_24_static_vsize 0x0000B400 +#define z64_nes_font_static_vaddr 0x00928000 +#define z64_nes_font_static_vsize 0x00004580 +#define z64_file_select_static_vaddr 0x01A02000 +#define z64_file_select_static_vsize 0x000395C0 +#define z64_parameter_static_vaddr 0x01A3C000 +#define z64_parameter_static_vsize 0x00003B00 + +/* context info */ +#define z64_ctxt_filemenu_ctor 0x80812394 +#define z64_ctxt_filemenu_size 0x0001CAD0 +#define z64_ctxt_game_ctor 0x8009A750 +#define z64_ctxt_game_size 0x00012518 + +#elif Z64_VERSION == Z64_OOT11 + +/* dram ddresses */ +#define z64_osSendMesg_addr 0x80001E20 +#define z64_osRecvMesg_addr 0x80002030 +#define z64_osCreateMesgQueue_addr 0x80004220 +#define z64_file_mq_addr 0x80007D40 +#define z64_vi_counter_addr 0x80009E8C +#define z64_DrawActors_addr 0x80024AB4 +#define z64_DeleteActor_addr 0x80024FE0 +#define z64_SpawnActor_addr 0x80025110 +#define z64_minimap_disable_1_addr 0x8006CD50 +#define z64_minimap_disable_2_addr 0x8006D4E4 +#define z64_SwitchAgeEquips_addr 0x8006F804 +#define z64_UpdateItemButton_addr 0x8006FB50 +#define z64_UpdateEquipment_addr 0x80079764 +#define z64_LoadRoom_addr 0x80080A3C +#define z64_UnloadRoom_addr 0x80080C98 +#define z64_Io_addr 0x80091484 +#define z64_entrance_offset_hook_addr 0x8009AA54 +#define z64_frame_update_func_addr 0x8009AF2C +#define z64_frame_update_call_addr 0x8009CAF8 +#define z64_disp_swap_1_addr 0x800A11A8 +#define z64_disp_swap_2_addr 0x800A11C0 +#define z64_disp_swap_3_addr 0x800A11D8 +#define z64_disp_swap_4_addr 0x800A11F4 +#define z64_frame_input_func_addr 0x800A0BB0 +#define z64_main_hook_addr 0x800A0C4C +#define z64_frame_input_call_addr 0x800A16BC +#define gspF3DEX2_NoN_fifoTextStart 0x800E4130 +#define z64_day_speed_addr 0x800F1810 +#define z64_light_handlers_addr 0x800F1D00 +#define z64_object_table_addr 0x800F91B8 +#define z64_entrance_table_addr 0x800F9E50 +#define z64_scene_table_addr 0x800FB6A0 +#define z64_scene_config_table_addr 0x800FBED8 +#define z64_seq_pos_addr 0x80104570 +#define gspF3DEX2_NoN_fifoDataStart 0x80114780 +#define z64_file_addr 0x8011A790 +#define z64_input_direct_addr 0x8011D8F0 +#define z64_stab_addr 0x80120DF8 +#define z64_seq_buf_addr 0x801249C0 +#define z64_ctxt_addr 0x801C8660 +#define z64_link_addr 0x801DABF0 + +/* rom addresses */ +#define z64_icon_item_static_vaddr 0x007BD000 +#define z64_icon_item_static_vsize 0x000888A0 +#define z64_icon_item_24_static_vaddr 0x00846000 +#define z64_icon_item_24_static_vsize 0x0000B400 +#define z64_nes_font_static_vaddr 0x008ED000 +#define z64_nes_font_static_vsize 0x00004580 +#define z64_parameter_static_vaddr 0x01A3C000 +#define z64_parameter_static_vsize 0x00003B00 + +/* context info */ +#define z64_ctxt_filemenu_ctor 0x80812394 +#define z64_ctxt_filemenu_size 0x0001CAD0 +#define z64_ctxt_game_ctor 0x8009A760 +#define z64_ctxt_game_size 0x00012518 + +#elif Z64_VERSION == Z64_OOT12 + +/* dram ddresses */ +#define z64_osSendMesg_addr 0x80001FD0 +#define z64_osRecvMesg_addr 0x800021F0 +#define z64_osCreateMesgQueue_addr 0x800043E0 +#define z64_file_mq_addr 0x80008A30 +#define z64_vi_counter_addr 0x8000A4CC +#define z64_DrawActors_addr 0x800250F4 +#define z64_DeleteActor_addr 0x80025620 +#define z64_SpawnActor_addr 0x80025750 +#define z64_minimap_disable_1_addr 0x8006D3B0 +#define z64_minimap_disable_2_addr 0x8006DB44 +#define z64_SwitchAgeEquips_addr 0x8006FE64 +#define z64_UpdateItemButton_addr 0x800701B0 +#define z64_UpdateEquipment_addr 0x80079DF4 +#define z64_LoadRoom_addr 0x80081064 +#define z64_UnloadRoom_addr 0x800812C0 +#define z64_Io_addr 0x80091AB4 +#define z64_entrance_offset_hook_addr 0x8009B134 +#define z64_frame_update_func_addr 0x8009B60C +#define z64_frame_update_call_addr 0x8009D1D8 +#define z64_disp_swap_1_addr 0x800A1848 +#define z64_disp_swap_2_addr 0x800A1860 +#define z64_disp_swap_3_addr 0x800A1878 +#define z64_disp_swap_4_addr 0x800A1894 +#define z64_frame_input_func_addr 0x800A1290 +#define z64_main_hook_addr 0x800A1328 +#define z64_frame_input_call_addr 0x800A1D8C +#define gspF3DEX2_NoN_fifoTextStart 0x800E45B0 +#define z64_day_speed_addr 0x800F1C90 +#define z64_light_handlers_addr 0x800F2180 +#define z64_object_table_addr 0x800F9648 +#define z64_entrance_table_addr 0x800FA2E0 +#define z64_scene_table_addr 0x800FBB30 +#define z64_scene_config_table_addr 0x800FC368 +#define z64_seq_pos_addr 0x801049F0 +#define gspF3DEX2_NoN_fifoDataStart 0x80114C70 +#define z64_file_addr 0x8011AC80 +#define z64_input_direct_addr 0x8011DE00 +#define z64_stab_addr 0x80121508 +#define z64_seq_buf_addr 0x801250D0 +#define z64_ctxt_addr 0x801C8D60 +#define z64_link_addr 0x801DB2F0 + +/* rom addresses */ +#define z64_icon_item_static_vaddr 0x007BD000 +#define z64_icon_item_static_vsize 0x000888A0 +#define z64_icon_item_24_static_vaddr 0x00846000 +#define z64_icon_item_24_static_vsize 0x0000B400 +#define z64_nes_font_static_vaddr 0x008ED000 +#define z64_nes_font_static_vsize 0x00004580 +#define z64_parameter_static_vaddr 0x01A3C000 +#define z64_parameter_static_vsize 0x00003B00 + +/* context info */ +#define z64_ctxt_filemenu_ctor 0x80812394 +#define z64_ctxt_filemenu_size 0x0001CAD0 +#define z64_ctxt_game_ctor 0x8009AE40 +#define z64_ctxt_game_size 0x00012518 + +#endif + +/* function prototypes */ +typedef void (*z64_DrawActors_proc) (z64_game_t *game, void *actor_ctxt); +typedef void (*z64_DeleteActor_proc) (z64_game_t *game, void *actor_ctxt, + z64_actor_t *actor); +typedef void (*z64_SpawnActor_proc) (void *actor_ctxt, z64_game_t *game, + int actor_id, float x, float y, + float z, uint16_t rx, uint16_t ry, + uint16_t rz, uint16_t variable); +typedef void (*z64_SwitchAgeEquips_proc) (void); +typedef void (*z64_UpdateItemButton_proc) (z64_game_t *game, int button_index); +typedef void (*z64_UpdateEquipment_proc) (z64_game_t *game, z64_link_t *link); +typedef void (*z64_LoadRoom_proc) (z64_game_t *game, + void *p_ctxt_room_index, + uint8_t room_index); +typedef void (*z64_UnloadRoom_proc) (z64_game_t *game, + void *p_ctxt_room_index); +typedef void (*z64_Io_proc) (uint32_t dev_addr, void *dram_addr, + uint32_t size, int32_t direction); +typedef void (*z64_SceneConfig_proc) (z64_game_t *game); + +/* data */ +#define z64_file_mq (*(OSMesgQueue*) z64_file_mq_addr) +#define z64_vi_counter (*(uint32_t*) z64_vi_counter_addr) +#define z64_stab (*(z64_stab_t*) z64_stab_addr) +#define z64_scene_table ( (z64_scene_table_t*)z64_scene_table_addr) +#define z64_day_speed (*(uint16_t*) z64_day_speed_addr) +#define z64_light_handlers ( (z64_light_handler_t*) \ + z64_light_handlers_addr) +#define z64_object_table ( (z64_object_table_t*) \ + z64_object_table_addr) +#define z64_entrance_table ( (z64_entrance_table_t*) \ + z64_entrance_table_addr) +#define z64_scene_config_table ( (z64_SceneConfig_proc*) \ + z64_scene_config_table_addr) +#define z64_file (*(z64_file_t*) z64_file_addr) +#define z64_input_direct (*(z64_input_t*) z64_input_direct_addr) +#define z64_gameinfo (* z64_file.gameinfo) +#define z64_ctxt (*(z64_ctxt_t*) z64_ctxt_addr) +#define z64_game (*(z64_game_t*) &z64_ctxt) +#define z64_link (*(z64_link_t*) z64_link_addr) + +/* functions */ +#define z64_osSendMesg ((osSendMesg_t) z64_osSendMesg_addr) +#define z64_osRecvMesg ((osRecvMesg_t) z64_osRecvMesg_addr) +#define z64_osCreateMesgQueue ((osCreateMesgQueue_t) \ + z64_osCreateMesgQueue_addr) +#define z64_DrawActors ((z64_DrawActors_proc)z64_DrawActors_addr) +#define z64_DeleteActor ((z64_DeleteActor_proc) \ + z64_DeleteActor_addr) +#define z64_SpawnActor ((z64_SpawnActor_proc)z64_SpawnActor_addr) +#define z64_SwitchAgeEquips ((z64_SwitchAgeEquips_proc) \ + z64_SwitchAgeEquips_addr) +#define z64_UpdateItemButton ((z64_UpdateItemButton_proc) \ + z64_UpdateItemButton_addr) +#define z64_UpdateEquipment ((z64_UpdateEquipment_proc) \ + z64_UpdateEquipment_addr) +#define z64_LoadRoom ((z64_LoadRoom_proc) z64_LoadRoom_addr) +#define z64_UnloadRoom ((z64_UnloadRoom_proc) \ + z64_UnloadRoom_addr) +#define z64_Io ((z64_Io_proc) z64_Io_addr) + +#endif diff --git a/ASM/notes/notes.txt b/ASM/notes/notes.txt index efc28faef..38e1cb73c 100755 --- a/ASM/notes/notes.txt +++ b/ASM/notes/notes.txt @@ -38,3 +38,13 @@ Equipment (relative to save context): silver gauntlets warp: checks at 0x803A4BE0 (in player instance) T6: Destination (e.g. 0x00A0) T8: Cutscene index? (e.g. 0xFFF0) + +8039F114 item/equipment usability table + +801D8C00 subscreen context + +0x138 (801D8D38) pointer to item description texture + +0x1E8 (801D8DE8) pause screen + +0x21E (801D8E1E) equips cursor index + +0x228 (801D8E28) equips horizontal cursor + +0x232 (801D8E32) equips vertical cursor + +0x23C (801D8E3C) item under cursor \ No newline at end of file diff --git a/ASM/quick_build.bat b/ASM/quick_build.bat new file mode 100644 index 000000000..4d6dcbc2d --- /dev/null +++ b/ASM/quick_build.bat @@ -0,0 +1,2 @@ +python scripts/build.py +pause \ No newline at end of file diff --git a/ASM/resources/font.bin b/ASM/resources/font.bin new file mode 100644 index 000000000..b894248be Binary files /dev/null and b/ASM/resources/font.bin differ diff --git a/ASM/scripts/build.py b/ASM/scripts/build.py index 7d729e65a..87f98382c 100644 --- a/ASM/scripts/build.py +++ b/ASM/scripts/build.py @@ -1,22 +1,99 @@ -#!/usr/bin/env python3 import argparse +import json import os -import subprocess +import re +from subprocess import check_call as call +from rom_diff import create_diff parser = argparse.ArgumentParser() parser.add_argument('--pj64sym', help="Output path for PJ64 debugging symbols") +parser.add_argument('--compile-c', action='store_true', help="Recompile C modules") + args = parser.parse_args() pj64_sym_path = args.pj64sym -if pj64_sym_path: - pj64_sym_path = os.path.realpath(pj64_sym_path) +compile_c = args.compile_c script_dir = os.path.dirname(os.path.realpath(__file__)) -os.chdir(script_dir) +run_dir = script_dir + '/..' +os.chdir(run_dir) + +# Compile code + +os.environ['PATH'] = script_dir + os.pathsep + os.environ['PATH'] + +if compile_c: + os.chdir(run_dir + '/c') + call(['make']) + +os.chdir(run_dir + '/src') +call(['armips', '-sym2', '../build/asm_symbols.txt', 'build.asm']) +os.chdir(run_dir) + +# Parse symbols -try: - subprocess.call(['./armips', '-sym2', '../temp/symbols', '../src/build.asm']) -except FileNotFoundError: - subprocess.call(['armips', '-sym2', '../temp/symbols', '../src/build.asm']) +c_sym_types = {} + +with open('build/c_symbols.txt', 'r') as f: + for line in f: + m = re.match(''' + ^ + [0-9a-fA-F]+ + .* + \. + ([^\s]+) + \s+ + [0-9a-fA-F]+ + \s+ + ([^.$][^\s]+) + \s+$ + ''', line, re.VERBOSE) + if m: + sym_type = m.group(1) + name = m.group(2) + c_sym_types[name] = 'code' if sym_type == 'text' else 'data' + +symbols = {} + +with open('build/asm_symbols.txt', 'r') as f: + for line in f: + parts = line.strip().split(' ') + if len(parts) < 2: + continue + address, sym_name = parts + if address[0] != '8': + continue + if sym_name[0] in ['.', '@']: + continue + sym_type = c_sym_types.get(sym_name) or ('data' if sym_name.isupper() else 'code') + symbols[sym_name] = { + 'type': sym_type, + 'address': address, + } + +# Output symbols + +os.chdir(run_dir) + +data_symbols = {} +for (name, sym) in symbols.items(): + if sym['type'] == 'data': + addr = int(sym['address'], 16) + if 0x80400000 <= addr < 0x80405000: + addr = addr - 0x80400000 + 0x03480000 + elif 0x80405000 <= addr < 0x80410000: + addr = addr - 0x80405000 + 0x034B3000 + else: + continue + data_symbols[name] = '{0:08X}'.format(addr) +with open('../data/symbols.json', 'w') as f: + json.dump(data_symbols, f, indent=4, sort_keys=True) if pj64_sym_path: - subprocess.call(['python3', 'sym2pj64.py', '../temp/symbols', pj64_sym_path]) + pj64_sym_path = os.path.realpath(pj64_sym_path) + with open(pj64_sym_path, 'w') as f: + key = lambda pair: pair[1]['address'] + for sym_name, sym in sorted(symbols.items(), key=key): + f.write('{0},{1},{2}\n'.format(sym['address'], sym['type'], sym_name)) + +# Diff ROMs +create_diff('roms/base.z64', 'roms/patched.z64', '../data/rom_patch.txt') diff --git a/ASM/scripts/rom_diff.py b/ASM/scripts/rom_diff.py index 2355b0b2d..0103d927c 100644 --- a/ASM/scripts/rom_diff.py +++ b/ASM/scripts/rom_diff.py @@ -1,30 +1,38 @@ -#!/usr/bin/env python3 - import json import sys -if len(sys.argv) < 4: - raise RuntimeError("Usage: python3 rom_diff.py BASE_FILE COMPARISON_FILE OUTPUT_FILE") +def main(): + if len(sys.argv) < 4: + raise RuntimeError("Usage: python rom_diff.py BASE_FILE COMPARISON_FILE OUTPUT_FILE") -base_path = sys.argv[1] -compare_path = sys.argv[2] -output_path = sys.argv[3] + base_path = sys.argv[1] + compare_path = sys.argv[2] + output_path = sys.argv[3] + create_diff(base_path, compare_path, output_path) + +def unequal_chunks(file1, file2): + chunk_size = 2048 + i = 0 + while True: + chunk1 = file1.read(chunk_size) + chunk2 = file2.read(chunk_size) + if not chunk1: + return + if chunk1 != chunk2: + yield (i * chunk_size, chunk1, chunk2) + i += 1 -with open(base_path, 'rb') as base_file: - base_data = base_file.read() -with open(compare_path, 'rb') as compare_file: - compare_data = compare_file.read() +def create_diff(base_path, compare_path, output_path): + diffs = [] + with open(base_path, 'rb') as base_f, open(compare_path, 'rb') as comp_f: + for (i, base_c, comp_c) in unequal_chunks(base_f, comp_f): + for j in range(len(base_c)): + if comp_c[j] != base_c[j]: + diffs.append((i + j, comp_c[j])) -diffs = [] -run = [] -for i in range(0, len(base_data)): - if base_data[i] != compare_data[i]: - if run and run[-1][0] != i - 1: - diffs.append({ run[0][0]: [value for (_, value) in run] }) - run = [] - run.append((i, compare_data[i])) -if run: - diffs.append({ run[0][0]: [value for (_, value) in run] }) + with open(output_path, 'w') as out_f: + for (i, b) in diffs: + out_f.write('{0:x},{1:x}\n'.format(i, b)) -with open(output_path, 'w') as output_file: - json.dump(diffs, output_file) +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/ASM/scripts/sym2pj64.py b/ASM/scripts/sym2pj64.py deleted file mode 100644 index aef4eb7b4..000000000 --- a/ASM/scripts/sym2pj64.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python3 - -import sys - -if len(sys.argv) < 3: - raise RuntimeError("Usage: python3 sym2pj64.py IN_FILE OUT_FILE") - -in_path = sys.argv[1] -out_path = sys.argv[2] - -in_file = open(in_path, 'r') -out_file = open(out_path, 'w') - -for line in in_file: - parts = line.strip().split(' ') - if len(parts) < 2: - continue - address, label = parts - if address[0] != '8': - continue - if label[0] == '.': - continue - label_type = 'data' if label.isupper() else 'code' - out_line = ','.join([address, label_type, label]) - print(out_line, file=out_file) - -in_file.close() -out_file.close() diff --git a/ASM/src/boot.asm b/ASM/src/boot.asm new file mode 100644 index 000000000..4f701b297 --- /dev/null +++ b/ASM/src/boot.asm @@ -0,0 +1,31 @@ +; Update CRC +.org 0x10 + .word 0x9345AE5B, 0x97DB4131 + +; Add dmatable entries for new code +.org 0xD260 + .word 0x03480000, 0x03485000, 0x03480000, 0 + .word 0x034B3000, 0x034BE000, 0x034B3000, 0 + +; Load new code from ROM +; Replaces: +; lui v0, 0x8012 +; addiu v0, v0, 0xD2A0 +; sw ra, 0x001C (sp) +; sw a0, 0x0140 (sp) +; addiu t6, r0, 0x0140 +; lui at, 0x8010 +; sw t6, 0xE500 (at) +; lui at, 0x8010 +.org 0xB17BB4 ; In memory: 0x800A1C54 + sw ra, 0x001C (sp) + sw a0, 0x0140 (sp) + + ; Load first code file from ROM + lui a0, 0x8040 + lui a1, 0x0348 + jal 0x80000DF0 + ori a2, r0, 0x5000 + + jal init + nop diff --git a/ASM/src/build.asm b/ASM/src/build.asm index d636834ad..318e14ce7 100755 --- a/ASM/src/build.asm +++ b/ASM/src/build.asm @@ -8,7 +8,9 @@ ; Base game editing region ;================================================================================================== +.include "boot.asm" .include "hacks.asm" +.include "malon.asm" ;================================================================================================== ; New code region @@ -16,22 +18,47 @@ .headersize (0x80400000 - 0x03480000) +.include "constants.asm" + +.org 0x80400000 +.area 0x1000 +.include "init.asm" +DebugOutput: +.include "debug.asm" +.endarea + .org 0x80401000 .area 0x1000, 0 .include "config.asm" .endarea .org 0x80402000 -.area 0x2000, 0 -.include "constants.asm" +.area 0x50, 0 .include "state.asm" +.endarea + +.org 0x80402050 +.area 0x2000, 0 .include "extended_items.asm" .include "item_overrides.asm" .include "cutscenes.asm" +.include "shop.asm" .include "every_frame.asm" .include "menu.asm" .include "time_travel.asm" .include "song_fix.asm" +.include "scarecrow.asm" +.include "initial_save.asm" +.include "textbox.asm" +.endarea + +.headersize (0x80405000 - 0x034B3000) + +.org 0x80405000 +.area 0xB000, 0 +.importobj "../build/bundle.o" +FONT_TEXTURE: +.incbin("../resources/font.bin") .endarea .close diff --git a/ASM/src/config.asm b/ASM/src/config.asm index 58342eb94..5e6109f45 100755 --- a/ASM/src/config.asm +++ b/ASM/src/config.asm @@ -14,14 +14,42 @@ ; II = Override ID (base item or flag) ; NN = New item ID -.area 0x400, 0 +.area 0x800, 0 ITEM_OVERRIDES: .endarea -; 0x03481400: Special items +; 0x03481800: Initial Save Data table: +; +; This table describes what extra data should be written when a new save file is created. It must be terminated with +; four 0x00 bytes (which will happen by default as long as you don't fill the allotted space). +; +; Row format (4 bytes): +; AAAATTVV +; AAAA = Offset from the start of the save data +; TT = Type (0x00 = or value with current value, 0x01 = set the byte to the given value) +; VV = Value to write to the save + +.area 0x400, 0 +INITIAL_SAVE_DATA: +.endarea + +PLAYER_ID: +.byte 0x00 +COOP_GET_ITEM: +.byte 0x00 +PLAYER_NAME_ID: +.byte 0x00 + +.area 8*32, 0xDF +PLAYER_NAMES: +.endarea + +; 0x03481C00: Special items LIGHT_ARROW_ITEM: .byte 0x5A +FAIRY_OCARINA_ITEM: +.byte 0x3B FAIRY_ITEMS: .byte 0x5D ; Zora's Domain .byte 0x5C ; Hyrule Castle diff --git a/ASM/src/constants.asm b/ASM/src/constants.asm index 67e5789cd..919b156dc 100755 --- a/ASM/src/constants.asm +++ b/ASM/src/constants.asm @@ -1,5 +1,14 @@ ; Pointers to game state -.definelabel SAVE_CONTEXT, 0x8011A5D0 -.definelabel GLOBAL_CONTEXT, 0x801C84A0 -.definelabel PLAYER_ACTOR, 0x801DAA30 -.definelabel DUMMY_ACTOR, 0x80410000 +.definelabel SAVE_CONTEXT, 0x8011A5D0 +.definelabel GLOBAL_CONTEXT, 0x801C84A0 +.definelabel SUBSCREEN_CONTEXT, 0x801D8C00 +.definelabel PLAYER_ACTOR, 0x801DAA30 +.definelabel GET_ITEMTABLE, 0x803A9E7E + +; Extended memory map: +; Loaded code files 0x80400000 +; ASM working memory 0x80480000 +; C working memory 0x80500000 + +.definelabel DUMMY_ACTOR, 0x80480000 +.definelabel C_HEAP, 0x80500000 diff --git a/ASM/src/cutscenes.asm b/ASM/src/cutscenes.asm index 6813ccd4f..33f76a36e 100644 --- a/ASM/src/cutscenes.asm +++ b/ASM/src/cutscenes.asm @@ -60,7 +60,128 @@ override_great_fairy_cutscene: override_light_arrow_cutscene: li t0, LIGHT_ARROW_ITEM lb t0, 0x00 (t0) + b store_pending_special_item + nop + +override_fairy_ocarina_cutscene: + li t0, FAIRY_OCARINA_ITEM + lb t0, 0x00 (t0) + b store_pending_special_item + nop + +;a3 = item ID +override_ocarina_songs: + li v0, 0xFF + addi t0, a3, -0x5A + addi t0, t0, 0x61 + b store_pending_special_item + nop + +override_requiem_song: + li t0, 0x64 + b store_pending_special_item + nop + +override_epona_song: + lui at,0x8012 + addiu at,at,0xA5D0 ; v1 = 0x8012a5d0 # save context (sav) + lb t0,0x0EDE(at) ; check learned song from malon flag + ori t0,t0,0x01 ; t9 = "Invited to Sing With Child Malon" + sb t0,0x0EDE(at) + + li t0, 0x68 + b store_pending_special_item + nop + +override_suns_song: + lui at,0x8012 + addiu at,at,0xA5D0 ; v1 = 0x8012a5d0 # save context (sav) + lb t0,0x0EDE(at) ; learned song from sun's song + ori t0,t0,0x04 ; + sb t0,0x0EDE(at) + + li t0, 0x6A + b store_pending_special_item + nop + +override_song_of_time: + li a1, 3 + li t0, 0x6B + b store_pending_special_item + nop + +store_pending_special_item: +; Don't add item if it's already pending li t1, PENDING_SPECIAL_ITEM - sb t0, 0x00 (t1) + li t2, PENDING_SPECIAL_ITEM_END ; max number of entries +@@find_duplicate_loop: + lb t4, 0x00 (t1) + beq t4, t0, @@return ; item is already in list + addi t1, t1, 0x01 + bne t1, t2, @@find_duplicate_loop ; end of list + nop + +; Find free index to add item + li t1, (PENDING_SPECIAL_ITEM - 1) +@@find_empty_loop: + addi t1, t1, 0x01 + beq t1, t2, @@return ; end of list + lb t4, 0x00 (t1) + bnez t4, @@find_empty_loop ; next index + nop + + sb t0, 0x00 (t1) ; store in first free spot +@@return: + jr ra + nop + +override_saria_song_check: + move t7, v1 + lb t4, 0x0EDF(t7) + andi t6, t4, 0x80 + beqz t6, @@get_item + li v1, 5 + + jr ra + li v0, 2 + +@@get_item: + jr ra + move v0, v1 + +set_saria_song_flag: + lh v0, 0xa4(t6) ; v0 = scene + li t0, SAVE_CONTEXT + lb t1, 0x0EDF(t0) + ori t1, t1, 0x80 + sb t1, 0x0EDF(t0) + jr ra + nop + +; Injection for talking to the Altar in the Temple of Time +; Should set flag in save that it has been spoken to. +set_dungeon_knowledge: + addiu sp, sp, -0x10 + sw ra, 0x04(sp) + + ; displaced instruction + jal 0xD6218 + nop + + li t4, SAVE_CONTEXT + lh t5, 0x0F2E(t4) ; flags + lw t8, 0x0004(t4) ; age + + beqz t8, @@set_flag + li t6, 0x0001 ; adult bit + li t6, 0x0002 ; child bit + +@@set_flag: + or t5, t5, t6 + sh t5, 0x0F2E(t4) ; set the flag + + lw ra, 0x04(sp) + addiu sp, sp, 0x10 + jr ra nop diff --git a/ASM/src/debug.asm b/ASM/src/debug.asm new file mode 100644 index 000000000..a01ce662a --- /dev/null +++ b/ASM/src/debug.asm @@ -0,0 +1,40 @@ +.macro debug_print,reg + addi sp, sp, -0x20 + sw t0, 0x04(sp) + sw t1, 0x08(sp) + sw t2, 0x0C(sp) + sw t3, 0x10(sp) + sw at, 0x14(sp) + + ori t3, reg, 0 + + li t0, DebugOutput + lw t1, 0x00(t0) + + add t2, t0, t1 + sw t3, 0x04(t2) + + addi t1, t1, 4 + sw t1, 0x00(t0) + + lw t0, 0x04(sp) + lw t1, 0x08(sp) + lw t2, 0x0C(sp) + lw t3, 0x10(sp) + lw at, 0x14(sp) + addi sp, sp, 0x20 +.endmacro + +.macro debug_printi,val + addi sp, sp, -0x10 + sw at, 0x04(sp) + sw t4, 0x08(sp) + + li t4, val + debug_print t4 + + lw at, 0x04(sp) + lw t4, 0x08(sp) + addi sp, sp, 0x10 +.endmacro + diff --git a/ASM/src/every_frame.asm b/ASM/src/every_frame.asm index 195c5d929..5dd600695 100644 --- a/ASM/src/every_frame.asm +++ b/ASM/src/every_frame.asm @@ -1,19 +1,46 @@ -every_frame: - sw a0, 0x68 (sp) - sw a1, 0x6C (sp) - sw a2, 0x70 (sp) - sw a3, 0x74 (sp) +before_game_state_update: addiu sp, sp, -0x18 - sw v1, 0x10 (sp) - sw ra, 0x14 (sp) + sw ra, 0x10 (sp) + + ; Don't give pending item during cutscene. This can lead to a crash when giving an item + ; during another item cutscene. + li t2, PLAYER_ACTOR + lb t0, 0x066C (t2) ;link's state + andi t0, 0x20 ;cutscene + bnez t0, @@no_pending_item + nop + + ; Don't give an item if link's camera is not being used + ; If an item is given in this state then it will cause the + ; Walking-While-Talking glitch. + li t2, GLOBAL_CONTEXT + lw t0, 0x0794 (t2) ; Camera 2 + bnez t0, @@no_pending_item + + ; clear pending item index + li t1, PENDING_SPECIAL_ITEM_END + li t2, 0xFF + sb t2, 0x00 (t1) ; If there is a pending item, try to make the player instance receive it. If the player has ; control on this frame, they will receive the item. Otherwise nothing will happen, and ; we try again next frame. - li t0, PENDING_SPECIAL_ITEM - lb t0, 0x00 (t0) - beqz t0, @@no_pending_item + li t1, PENDING_SPECIAL_ITEM + li t2, -1 + li t4, (PENDING_SPECIAL_ITEM_END - PENDING_SPECIAL_ITEM) ; max number of entries +@@loop: + addi t2, t2, 0x01 + beq t2, t4, @@no_pending_item ; stop if end of list + add t3, t1, t2 + + lb t0, 0x00 (t3) + beqz t0, @@loop ; loop if index is empty nop + + ; Store index of pending item to be given + li t1, PENDING_SPECIAL_ITEM_END + sb t2, 0x00 (t1) + ; Disable warping when there is a pending item. Currently this code is only used in places ; where warping is allowed, so warping can always be re-enabled after the item is received. li t1, GLOBAL_CONTEXT + 0x104E4 @@ -33,15 +60,25 @@ every_frame: nop @@no_pending_item: - lw v1, 0x10 (sp) - lw ra, 0x14 (sp) + ; Displaced code + lw t9, 0x04 (s0) + or a0, s0, r0 + + lw ra, 0x10 (sp) + jr ra addiu sp, sp, 0x18 - lw a0, 0x68 (sp) - lw a1, 0x6C (sp) - lw a2, 0x70 (sp) - lw a3, 0x74 (sp) - lh t6, 0x13C4 (v1) ; Displaced code +after_game_state_update: + addiu sp, sp, -0x18 + sw ra, 0x10 (sp) - jr ra + jal c_after_game_state_update nop + + ; Displaced code + lui t6, 0x8012 + lbu t6, 0x1212 (t6) + + lw ra, 0x10 (sp) + jr ra + addiu sp, sp, 0x18 diff --git a/ASM/src/extended_items.asm b/ASM/src/extended_items.asm index 18b4279b7..6a29b7e47 100755 --- a/ASM/src/extended_items.asm +++ b/ASM/src/extended_items.asm @@ -54,75 +54,98 @@ Item_Row -1, -1, -1, -1, -1, strength_upgrade, no_effect, -1, -1 ; 0x81 = Progr Item_Row -1, -1, -1, -1, -1, bomb_bag_upgrade, no_effect, -1, -1 ; 0x82 = Progressive Bomb Bag Item_Row -1, -1, -1, -1, -1, bow_upgrade, no_effect, -1, -1 ; 0x83 = Progressive Bow Item_Row -1, -1, -1, -1, -1, slingshot_upgrade, no_effect, -1, -1 ; 0x84 = Progressive Slingshot -Item_Row -1, -1, -1, -1, -1, wallet_upgrade, no_effect, -1, -1 ; 0x85 = Progressive Wallet +Item_Row 0x53, 0x41, 0x23, 0xF8, 0x00D1, wallet_upgrade, tycoon_wallet, -1, -1 ; 0x85 = Progressive Wallet Item_Row -1, -1, -1, -1, -1, scale_upgrade, no_effect, -1, -1 ; 0x86 = Progressive Scale Item_Row -1, -1, -1, -1, -1, nut_upgrade, no_effect, -1, -1 ; 0x87 = Progressive Nut Capacity Item_Row -1, -1, -1, -1, -1, stick_upgrade, no_effect, -1, -1 ; 0x88 = Progressive Stick Capacity -Item_Row 0x53, 0x41, 0x01, 0x43, 0x00C6, no_upgrade, give_bottle, 0x15, -1 ; 0x89 = Bottle with Red Potion -Item_Row 0x53, 0x41, 0x01, 0x44, 0x00C6, no_upgrade, give_bottle, 0x16, -1 ; 0x8A = Bottle with Green Potion -Item_Row 0x53, 0x41, 0x01, 0x45, 0x00C6, no_upgrade, give_bottle, 0x17, -1 ; 0x8B = Bottle with Blue Potion -Item_Row 0x53, 0x41, 0x01, 0x46, 0x00C6, no_upgrade, give_bottle, 0x18, -1 ; 0x8C = Bottle with Fairy -Item_Row 0x53, 0x41, 0x01, 0x47, 0x00C6, no_upgrade, give_bottle, 0x19, -1 ; 0x8D = Bottle with Fish -Item_Row 0x53, 0x41, 0x01, 0x5D, 0x00C6, no_upgrade, give_bottle, 0x1C, -1 ; 0x8E = Bottle with Blue Fire -Item_Row 0x53, 0x41, 0x01, 0x7A, 0x00C6, no_upgrade, give_bottle, 0x1D, -1 ; 0x8F = Bottle with Bugs -Item_Row 0x53, 0x41, 0x01, 0xF9, 0x00C6, no_upgrade, give_bottle, 0x1E, -1 ; 0x90 = Bottle with Big Poe -Item_Row 0x53, 0x41, 0x01, 0x97, 0x00C6, no_upgrade, give_bottle, 0x20, -1 ; 0x91 = Bottle with Poe - -Item_Row 0x53, 0x41, 0x0A, 0xC7, 0x00B9, no_upgrade, give_dungeon_item, 0x01, FOREST_ID ; 0x92 = Forest Temple Boss Key -Item_Row 0x53, 0x41, 0x0A, 0xC7, 0x00B9, no_upgrade, give_dungeon_item, 0x01, FIRE_ID ; 0x93 = Fire Temple Boss Key -Item_Row 0x53, 0x41, 0x0A, 0xC7, 0x00B9, no_upgrade, give_dungeon_item, 0x01, WATER_ID ; 0x94 = Water Temple Boss Key -Item_Row 0x53, 0x41, 0x0A, 0xC7, 0x00B9, no_upgrade, give_dungeon_item, 0x01, SPIRIT_ID ; 0x95 = Spirit Temple Boss Key -Item_Row 0x53, 0x41, 0x0A, 0xC7, 0x00B9, no_upgrade, give_dungeon_item, 0x01, SHADOW_ID ; 0x96 = Shadow Temple Boss Key -Item_Row 0x53, 0x41, 0x0A, 0xC7, 0x00B9, no_upgrade, give_dungeon_item, 0x01, TOWER_ID ; 0x97 = Ganon's Castle Boss Key - -Item_Row 0x53, 0x41, 0x0B, 0x67, 0x00B8, no_upgrade, give_dungeon_item, 0x02, DEKU_ID ; 0x98 = Deku Tree Compass -Item_Row 0x53, 0x41, 0x0B, 0x67, 0x00B8, no_upgrade, give_dungeon_item, 0x02, DODONGO_ID ; 0x99 = Dodongo's Cavern Compass -Item_Row 0x53, 0x41, 0x0B, 0x67, 0x00B8, no_upgrade, give_dungeon_item, 0x02, JABU_ID ; 0x9A = Jabu Jabu Compass -Item_Row 0x53, 0x41, 0x0B, 0x67, 0x00B8, no_upgrade, give_dungeon_item, 0x02, FOREST_ID ; 0x9B = Forest Temple Compass -Item_Row 0x53, 0x41, 0x0B, 0x67, 0x00B8, no_upgrade, give_dungeon_item, 0x02, FIRE_ID ; 0x9C = Fire Temple Compass -Item_Row 0x53, 0x41, 0x0B, 0x67, 0x00B8, no_upgrade, give_dungeon_item, 0x02, WATER_ID ; 0x9D = Water Temple Compass -Item_Row 0x53, 0x41, 0x0B, 0x67, 0x00B8, no_upgrade, give_dungeon_item, 0x02, SPIRIT_ID ; 0x9E = Spirit Temple Compass -Item_Row 0x53, 0x41, 0x0B, 0x67, 0x00B8, no_upgrade, give_dungeon_item, 0x02, SHADOW_ID ; 0x9F = Shadow Temple Compass -Item_Row 0x53, 0x41, 0x0B, 0x67, 0x00B8, no_upgrade, give_dungeon_item, 0x02, BOTW_ID ; 0xA0 = Bottom of the Well Compass -Item_Row 0x53, 0x41, 0x0B, 0x67, 0x00B8, no_upgrade, give_dungeon_item, 0x02, ICE_ID ; 0xA1 = Ice Cavern Compass - -Item_Row 0x53, 0x41, 0x1C, 0x66, 0x00C8, no_upgrade, give_dungeon_item, 0x04, DEKU_ID ; 0xA2 = Deku Tree Map -Item_Row 0x53, 0x41, 0x1C, 0x66, 0x00C8, no_upgrade, give_dungeon_item, 0x04, DODONGO_ID ; 0xA3 = Dodongo's Cavern Map -Item_Row 0x53, 0x41, 0x1C, 0x66, 0x00C8, no_upgrade, give_dungeon_item, 0x04, JABU_ID ; 0xA4 = Jabu Jabu Map -Item_Row 0x53, 0x41, 0x1C, 0x66, 0x00C8, no_upgrade, give_dungeon_item, 0x04, FOREST_ID ; 0xA5 = Forest Temple Map -Item_Row 0x53, 0x41, 0x1C, 0x66, 0x00C8, no_upgrade, give_dungeon_item, 0x04, FIRE_ID ; 0xA6 = Fire Temple Map -Item_Row 0x53, 0x41, 0x1C, 0x66, 0x00C8, no_upgrade, give_dungeon_item, 0x04, WATER_ID ; 0xA7 = Water Temple Map -Item_Row 0x53, 0x41, 0x1C, 0x66, 0x00C8, no_upgrade, give_dungeon_item, 0x04, SPIRIT_ID ; 0xA8 = Spirit Temple Map -Item_Row 0x53, 0x41, 0x1C, 0x66, 0x00C8, no_upgrade, give_dungeon_item, 0x04, SHADOW_ID ; 0xA9 = Shadow Temple Map -Item_Row 0x53, 0x41, 0x1C, 0x66, 0x00C8, no_upgrade, give_dungeon_item, 0x04, BOTW_ID ; 0xAA = Bottom of the Well Map -Item_Row 0x53, 0x41, 0x1C, 0x66, 0x00C8, no_upgrade, give_dungeon_item, 0x04, ICE_ID ; 0xAB = Ice Cavern Map - -Item_Row 0x53, 0x41, 0xFE, 0x60, 0x00AA, no_upgrade, give_small_key, FOREST_ID, -1 ; 0xAC = Forest Temple Small Key -Item_Row 0x53, 0x41, 0xFE, 0x60, 0x00AA, no_upgrade, give_small_key, FIRE_ID, -1 ; 0xAD = Fire Temple Small Key -Item_Row 0x53, 0x41, 0xFE, 0x60, 0x00AA, no_upgrade, give_small_key, WATER_ID, -1 ; 0xAE = Water Temple Small Key -Item_Row 0x53, 0x41, 0xFE, 0x60, 0x00AA, no_upgrade, give_small_key, SPIRIT_ID, -1 ; 0xAF = Spirit Temple Small Key -Item_Row 0x53, 0x41, 0xFE, 0x60, 0x00AA, no_upgrade, give_small_key, SHADOW_ID, -1 ; 0xB0 = Shadow Temple Small Key -Item_Row 0x53, 0x41, 0xFE, 0x60, 0x00AA, no_upgrade, give_small_key, BOTW_ID, -1 ; 0xB1 = Bottom of the Well Small Key -Item_Row 0x53, 0x41, 0xFE, 0x60, 0x00AA, no_upgrade, give_small_key, GTG_ID, -1 ; 0xB2 = Gerudo Training Small Key -Item_Row 0x53, 0x41, 0xFE, 0x60, 0x00AA, no_upgrade, give_small_key, FORT_ID, -1 ; 0xB3 = Gerudo Fortress Small Key -Item_Row 0x53, 0x41, 0xFE, 0x60, 0x00AA, no_upgrade, give_small_key, CASTLE_ID, -1 ; 0xB4 = Ganon's Castle Small Key +Item_Row 0x53, 0x41, 0x38, 0x43, 0x00EB, no_upgrade, give_bottle, 0x15, -1 ; 0x89 = Bottle with Red Potion +Item_Row 0x53, 0x41, 0x37, 0x44, 0x00EB, no_upgrade, give_bottle, 0x16, -1 ; 0x8A = Bottle with Green Potion +Item_Row 0x53, 0x41, 0x39, 0x45, 0x00EB, no_upgrade, give_bottle, 0x17, -1 ; 0x8B = Bottle with Blue Potion +Item_Row 0x53, 0x41, 0x6B, 0x46, 0x0177, no_upgrade, give_bottle, 0x18, -1 ; 0x8C = Bottle with Fairy +Item_Row 0x53, 0x41, 0x3F, 0x47, 0x00F4, no_upgrade, give_bottle, 0x19, -1 ; 0x8D = Bottle with Fish +Item_Row 0x53, 0x41, 0x67, 0x5D, 0x0173, no_upgrade, give_bottle, 0x1C, -1 ; 0x8E = Bottle with Blue Fire +Item_Row 0x53, 0x41, 0x68, 0x7A, 0x0174, no_upgrade, give_bottle, 0x1D, -1 ; 0x8F = Bottle with Bugs +Item_Row 0x53, 0x41, 0x70, 0xF9, 0x0176, no_upgrade, give_bottle, 0x1E, -1 ; 0x90 = Bottle with Big Poe +Item_Row 0x53, 0x41, 0x6A, 0x97, 0x0176, no_upgrade, give_bottle, 0x20, -1 ; 0x91 = Bottle with Poe + +Item_Row 0x53, 0x41, 0x0A, 0x06, 0x00B9, no_upgrade, give_dungeon_item, 0x01, FOREST_ID ; 0x92 = Forest Temple Boss Key +Item_Row 0x53, 0x41, 0x0A, 0x1C, 0x00B9, no_upgrade, give_dungeon_item, 0x01, FIRE_ID ; 0x93 = Fire Temple Boss Key +Item_Row 0x53, 0x41, 0x0A, 0x1D, 0x00B9, no_upgrade, give_dungeon_item, 0x01, WATER_ID ; 0x94 = Water Temple Boss Key +Item_Row 0x53, 0x41, 0x0A, 0x1E, 0x00B9, no_upgrade, give_dungeon_item, 0x01, SPIRIT_ID ; 0x95 = Spirit Temple Boss Key +Item_Row 0x53, 0x41, 0x0A, 0x2A, 0x00B9, no_upgrade, give_dungeon_item, 0x01, SHADOW_ID ; 0x96 = Shadow Temple Boss Key +Item_Row 0x53, 0x41, 0x0A, 0x61, 0x00B9, no_upgrade, give_dungeon_item, 0x01, TOWER_ID ; 0x97 = Ganon's Castle Boss Key + +Item_Row 0x4D, 0x41, 0xF5, 0x62, 0x00B8, no_upgrade, give_dungeon_item, 0x02, DEKU_ID ; 0x98 = Deku Tree Compass +Item_Row 0x4D, 0x41, 0xF5, 0x63, 0x00B8, no_upgrade, give_dungeon_item, 0x02, DODONGO_ID ; 0x99 = Dodongo's Cavern Compass +Item_Row 0x4D, 0x41, 0xF5, 0x64, 0x00B8, no_upgrade, give_dungeon_item, 0x02, JABU_ID ; 0x9A = Jabu Jabu Compass +Item_Row 0x4D, 0x41, 0xF5, 0x65, 0x00B8, no_upgrade, give_dungeon_item, 0x02, FOREST_ID ; 0x9B = Forest Temple Compass +Item_Row 0x4D, 0x41, 0xF5, 0x7C, 0x00B8, no_upgrade, give_dungeon_item, 0x02, FIRE_ID ; 0x9C = Fire Temple Compass +Item_Row 0x4D, 0x41, 0xF5, 0x7D, 0x00B8, no_upgrade, give_dungeon_item, 0x02, WATER_ID ; 0x9D = Water Temple Compass +Item_Row 0x4D, 0x41, 0xF5, 0x7E, 0x00B8, no_upgrade, give_dungeon_item, 0x02, SPIRIT_ID ; 0x9E = Spirit Temple Compass +Item_Row 0x4D, 0x41, 0xF5, 0x7F, 0x00B8, no_upgrade, give_dungeon_item, 0x02, SHADOW_ID ; 0x9F = Shadow Temple Compass +Item_Row 0x4D, 0x41, 0xF5, 0xA2, 0x00B8, no_upgrade, give_dungeon_item, 0x02, BOTW_ID ; 0xA0 = Bottom of the Well Compass +Item_Row 0x4D, 0x41, 0xF5, 0x87, 0x00B8, no_upgrade, give_dungeon_item, 0x02, ICE_ID ; 0xA1 = Ice Cavern Compass + +Item_Row 0x4D, 0x41, 0xE4, 0x88, 0x00C8, no_upgrade, give_dungeon_item, 0x04, DEKU_ID ; 0xA2 = Deku Tree Map +Item_Row 0x4D, 0x41, 0xE4, 0x89, 0x00C8, no_upgrade, give_dungeon_item, 0x04, DODONGO_ID ; 0xA3 = Dodongo's Cavern Map +Item_Row 0x4D, 0x41, 0xE4, 0x8A, 0x00C8, no_upgrade, give_dungeon_item, 0x04, JABU_ID ; 0xA4 = Jabu Jabu Map +Item_Row 0x4D, 0x41, 0xE4, 0x8B, 0x00C8, no_upgrade, give_dungeon_item, 0x04, FOREST_ID ; 0xA5 = Forest Temple Map +Item_Row 0x4D, 0x41, 0xE4, 0x8C, 0x00C8, no_upgrade, give_dungeon_item, 0x04, FIRE_ID ; 0xA6 = Fire Temple Map +Item_Row 0x4D, 0x41, 0xE4, 0x8E, 0x00C8, no_upgrade, give_dungeon_item, 0x04, WATER_ID ; 0xA7 = Water Temple Map +Item_Row 0x4D, 0x41, 0xE4, 0x8F, 0x00C8, no_upgrade, give_dungeon_item, 0x04, SPIRIT_ID ; 0xA8 = Spirit Temple Map +Item_Row 0x4D, 0x41, 0xE4, 0xA3, 0x00C8, no_upgrade, give_dungeon_item, 0x04, SHADOW_ID ; 0xA9 = Shadow Temple Map +Item_Row 0x4D, 0x41, 0xE4, 0xA5, 0x00C8, no_upgrade, give_dungeon_item, 0x04, BOTW_ID ; 0xAA = Bottom of the Well Map +Item_Row 0x4D, 0x41, 0xE4, 0x92, 0x00C8, no_upgrade, give_dungeon_item, 0x04, ICE_ID ; 0xAB = Ice Cavern Map + +Item_Row 0x53, 0x41, 0x02, 0x93, 0x00AA, no_upgrade, give_small_key, FOREST_ID, -1 ; 0xAC = Forest Temple Small Key +Item_Row 0x53, 0x41, 0x02, 0x94, 0x00AA, no_upgrade, give_small_key, FIRE_ID, -1 ; 0xAD = Fire Temple Small Key +Item_Row 0x53, 0x41, 0x02, 0x95, 0x00AA, no_upgrade, give_small_key, WATER_ID, -1 ; 0xAE = Water Temple Small Key +Item_Row 0x53, 0x41, 0x02, 0xA6, 0x00AA, no_upgrade, give_small_key, SPIRIT_ID, -1 ; 0xAF = Spirit Temple Small Key +Item_Row 0x53, 0x41, 0x02, 0xA9, 0x00AA, no_upgrade, give_small_key, SHADOW_ID, -1 ; 0xB0 = Shadow Temple Small Key +Item_Row 0x53, 0x41, 0x02, 0x9B, 0x00AA, no_upgrade, give_small_key, BOTW_ID, -1 ; 0xB1 = Bottom of the Well Small Key +Item_Row 0x53, 0x41, 0x02, 0x9F, 0x00AA, no_upgrade, give_small_key, GTG_ID, -1 ; 0xB2 = Gerudo Training Small Key +Item_Row 0x53, 0x41, 0x02, 0xA0, 0x00AA, no_upgrade, give_small_key, FORT_ID, -1 ; 0xB3 = Gerudo Fortress Small Key +Item_Row 0x53, 0x41, 0x02, 0xA1, 0x00AA, no_upgrade, give_small_key, CASTLE_ID, -1 ; 0xB4 = Ganon's Castle Small Key Item_Row 0x53, 0x3D, 0x43, 0x0C, 0x00F8, no_upgrade, give_biggoron_sword, -1, -1 ; 0xB5 = Biggoron Sword -Item_Row 0x4D, 0x83, 0x09, 0x55, 0x00B7, no_upgrade, no_effect, -1, -1 ; 0xB6 = Recovery Heart -Item_Row 0x53, 0x92, 0xDB, 0xE6, 0x00D8, arrows_to_rupee, no_effect, -1, -1 ; 0xB7 = Arrows (5) -Item_Row 0x53, 0x93, 0xDA, 0xE6, 0x00D8, arrows_to_rupee, no_effect, -1, -1 ; 0xB8 = Arrows (10) -Item_Row 0x53, 0x94, 0xD9, 0xE6, 0x00D8, arrows_to_rupee, no_effect, -1, -1 ; 0xB9 = Arrows (30) -Item_Row 0x53, 0x8E, 0xE0, 0x32, 0x00CE, bombs_to_rupee, no_effect, -1, -1 ; 0xBA = Bombs (5) -Item_Row 0x53, 0x8F, 0xE0, 0x32, 0x00CE, bombs_to_rupee, no_effect, -1, -1 ; 0xBB = Bombs (10) -Item_Row 0x53, 0x90, 0xE0, 0x32, 0x00CE, bombs_to_rupee, no_effect, -1, -1 ; 0xBC = Bombs (20) -Item_Row 0x53, 0x8C, 0xEE, 0x34, 0x00BB, no_upgrade, no_effect, -1, -1 ; 0xBD = Deku Nuts (5) -Item_Row 0x53, 0x8D, 0xEE, 0x34, 0x00BB, no_upgrade, no_effect, -1, -1 ; 0xBE = Deku Nuts (10) - -Item_Row 0x4F, 0x41, 0x13, 0xE9, 0x00BD, no_upgrade, give_defense, -1, -1 ; 0xBF = Double Defense -Item_Row 0x4F, 0x41, 0xE2, 0xE4, 0x00CD, magic_upgrade, give_magic, -1, -1 ; 0xC0 = Progressive Magic Meter -Item_Row 0x4F, 0x41, 0xE1, 0xE8, 0x00CD, no_upgrade, double_magic, -1, -1 ; 0xC1 = Double Magic +Item_Row 0x4D, 0x83, 0xF7, 0x55, 0x00B7, no_upgrade, no_effect, -1, -1 ; 0xB6 = Recovery Heart +Item_Row 0x4D, 0x92, 0xDB, 0xE6, 0x00D8, arrows_to_rupee, no_effect, -1, -1 ; 0xB7 = Arrows (5) +Item_Row 0x4D, 0x93, 0xDA, 0xE6, 0x00D8, arrows_to_rupee, no_effect, -1, -1 ; 0xB8 = Arrows (10) +Item_Row 0x4D, 0x94, 0xD9, 0xE6, 0x00D8, arrows_to_rupee, no_effect, -1, -1 ; 0xB9 = Arrows (30) +Item_Row 0x4D, 0x8E, 0xE0, 0x32, 0x00CE, bombs_to_rupee, no_effect, -1, -1 ; 0xBA = Bombs (5) +Item_Row 0x4D, 0x8F, 0xE0, 0x32, 0x00CE, bombs_to_rupee, no_effect, -1, -1 ; 0xBB = Bombs (10) +Item_Row 0x4D, 0x90, 0xE0, 0x32, 0x00CE, bombs_to_rupee, no_effect, -1, -1 ; 0xBC = Bombs (20) +Item_Row 0x4D, 0x8C, 0xEE, 0x34, 0x00BB, no_upgrade, no_effect, -1, -1 ; 0xBD = Deku Nuts (5) +Item_Row 0x4D, 0x8D, 0xEE, 0x34, 0x00BB, no_upgrade, no_effect, -1, -1 ; 0xBE = Deku Nuts (10) + +Item_Row 0x53, 0x41, 0x13, 0xE9, 0x00BD, no_upgrade, give_defense, -1, -1 ; 0xBF = Double Defense +Item_Row 0x53, 0x41, 0x1E, 0xE4, 0x00CD, magic_upgrade, give_magic, -1, -1 ; 0xC0 = Progressive Magic Meter +Item_Row 0x53, 0x41, 0x1F, 0xE8, 0x00CD, no_upgrade, double_magic, -1, -1 ; 0xC1 = Double Magic + +Item_Row -1, -1, -1, -1, -1, bombchu_upgrade, no_effect, -1, -1 ; 0xC2 = Progressive Bombchus +Item_Row 0x53, 0x41, 0x46, 0x4A, 0x010E, ocarina_upgrade, give_fairy_ocarina, -1, -1 ; 0xC3 = Progressive Ocarina + +Item_Row 0x53, 0x41, 0x03, 0xB0, 0x00B6, no_upgrade, give_song, 6, -1 ; 0xC4 = Minuet of Forest +Item_Row 0x53, 0x41, 0x04, 0xB1, 0x00B6, no_upgrade, give_song, 7, -1 ; 0xC5 = Bolero of Fire +Item_Row 0x53, 0x41, 0x05, 0xB2, 0x00B6, no_upgrade, give_song, 8, -1 ; 0xC6 = Serenade of Water +Item_Row 0x53, 0x41, 0x06, 0xB3, 0x00B6, no_upgrade, give_song, 9, -1 ; 0xC7 = Requiem of Spirit +Item_Row 0x53, 0x41, 0x07, 0xB6, 0x00B6, no_upgrade, give_song, 10, -1 ; 0xC8 = Nocturn of Shadow +Item_Row 0x53, 0x41, 0x08, 0xB7, 0x00B6, no_upgrade, give_song, 11, -1 ; 0xC9 = Prelude of Light + +Item_Row 0x53, 0x41, 0x04, 0xB8, 0x00B6, no_upgrade, give_song, 12, -1 ; 0xCA = Zelda's Lullaby +Item_Row 0x53, 0x41, 0x06, 0xB9, 0x00B6, no_upgrade, give_song, 13, -1 ; 0xCB = Epona's Song +Item_Row 0x53, 0x41, 0x03, 0xBA, 0x00B6, no_upgrade, give_song, 14, -1 ; 0xCC = Saria's Song +Item_Row 0x53, 0x41, 0x08, 0xBB, 0x00B6, no_upgrade, give_song, 15, -1 ; 0xCD = Sun's Song +Item_Row 0x53, 0x41, 0x05, 0xBC, 0x00B6, no_upgrade, give_song, 16, -1 ; 0xCE = Song of Time +Item_Row 0x53, 0x41, 0x07, 0xBD, 0x00B6, no_upgrade, give_song, 17, -1 ; 0xCF = Song of Storms + +Item_Row 0x4D, 0x00, 0xE5, 0x37, 0x00C7, no_upgrade, no_effect, -1, -1 ; 0xD0 = Deku Sticks (1) +Item_Row 0x4D, 0x95, 0xB8, 0xDC, 0x0119, seeds_to_rupee, no_effect, -1, -1 ; 0xD1 = Deku Seeds (30) + +Item_Row 0x77, 0x3E, 0xE3, 0x4C, 0x00CB, no_upgrade, no_effect, -1, -1 ; 0xD2 = Deku Shield +Item_Row 0x77, 0x3F, 0xD4, 0x4D, 0x00DC, no_upgrade, no_effect, -1, -1 ; 0xD3 = Hylian Shield ;================================================================================================== ; Item upgrade functions @@ -227,12 +250,24 @@ wallet_upgrade: beqz t0, @@return li v0, 0x45 ; Adult's Wallet + li t1, 0x10 + beq t0, t1, @@return li v0, 0x46 ; Giant's Wallet + ori v0, a1, 0 ; Tycoon's Wallet (unchanged) + @@return: jr ra nop +tycoon_wallet: + ; a0 = save context + lbu t0, 0xA2 (a0) ; Load wallet from inventory + ori t0, t0, 0x30 ; Give lvl 3 wallet + sb t0, 0xA2 (a0) ; Store wallet to inventory + jr ra + nop + ;================================================================================================== scale_upgrade: @@ -322,6 +357,21 @@ bombs_to_rupee: jr ra nop +;================================================================================================== + +seeds_to_rupee: + lbu t0, 0xA2 (a0) ; Load seed bag from inventory + andi t0, t0, 0xC0 ; Mask bits to isolate seed bag + + beqz t0, @@return + li v0, 0x4D ; Blue Rupee + + ori v0, a1, 0 + +@@return: + jr ra + nop + ;================================================================================================== ; Item effect functions ;================================================================================================== @@ -432,3 +482,55 @@ double_magic: sb t0, 0x33 (a0) ; Fill meter jr ra nop + +;================================================================================================== + +bombchu_upgrade: + lbu t0, 0x7C (a0) ; Load bomchu from inventory + beq t0, 0xFF, @@return + li v0, 0x6B ; Bombchu 20 pack + + lbu t0, 0x94 (a0) ; Load bombchu count from inventory + sltiu t0, t0, 0x06 + beqz t0, @@return ; if + li v0, 0x6A ; Bombchu 5 Pack + + li v0, 0x03 ; Bombchu 10 Pack + +@@return: + jr ra + nop + +;================================================================================================== + +ocarina_upgrade: + lbu t0, 0x7B (a0) ; Load ocarina from inventory + + beq t0, 0xFF, @@return + ori v0, a1, 0 ; Fairy Ocarina (unchanged) + + li v0, 0x0C ; Ocarina of Time + +@@return: + jr ra + nop + +give_fairy_ocarina: + ; a0 = save context + li t0, 0x07 + sb t0, 0x7B (a0) + jr ra + nop + +;================================================================================================== + +give_song: + ; a0 = save context + ; a1 = quest bit + li t0, 1 + sllv t0, t0, a1 + lw t1, 0xA4(a0) + or t1, t1, t0 + sw t1, 0xA4(a0) + jr ra + nop diff --git a/ASM/src/hacks.asm b/ASM/src/hacks.asm index 27e31948d..82efeed07 100755 --- a/ASM/src/hacks.asm +++ b/ASM/src/hacks.asm @@ -1,9 +1,3 @@ -; Make all chest opening animations fast -; Replaces: -; lb t2, 0x0002 (t1) -.org 0xBDA2E8 ; In memory: 0x803952D8 - addiu t2, r0, -1 - ; Prevent Kokiri Sword from being added to inventory on game load ; Replaces: ; sh t9, 0x009C (v0) @@ -14,11 +8,17 @@ ; Time Travel ;================================================================================================== -; Before time travel + +; Replaces: +; jal 8006FDCC ; Give Item +.org 0xCB6874 ; Bg_Toki_Swd addr 809190F4 in func_8091902C + jal give_master_sword + ; Replaces: -; lw t6, 0x04 (s0) -.org 0xCB6860 ; Bg_Toki_Swd in func_8091902C - jal before_time_travel +; lui/addiu a1, 0x8011A5D0 +.org 0xAE5764 + j before_time_travel + nop ; After time travel ; Replaces: @@ -119,18 +119,79 @@ .org 0xBE9BDC ; In memory: 0x803A4BCC addiu at, r0, 0x8383 ; Make branch impossible + + +; Change Skulltula Token to give a different item +; Replaces +; move a0,s1 +; jal 0x0006fdcc ; call ex_06fdcc(ctx, 0x0071); VROM: 0xAE5D2C +; li a1,113 +; lw t5,44(sp) ; t5 = what was *(ctx + 0x1c44) at the start of the function +; li t4,10 ; t4 = 0x0a +; move a0,s1 +; li a1,180 ; at = 0x00b4 ("You destoryed a Gold Skulltula...") +; move a2,zero +; jal 0x000dce14 ; call ex_0dce14(ctx, 0x00b4, 0) +; sh t4,272(t5) ; *(t5 + 0x110) = 0x000a +.org 0xEC68BC +.area 0x28, 0 + lw t5,44(sp) ; original code + li t4,10 ; original code + sh t4,272(t5) ; original code + jal override_skulltula_token ; call override_skulltula_token(_, actor) + move a1,s0 +.endarea + +.org 0xEC69AC +.area 0x28, 0 + lw t5,44(sp) ; original code + li t4,10 ; original code + sh t4,272(t5) ; original code + jal override_skulltula_token ; call override_skulltula_token(_, actor) + move a1,s0 +.endarea + ;================================================================================================== -; Special item sources +; Every frame hooks ;================================================================================================== -; Runs every frame (part of player actor) +; Runs before the game state updates ; Replaces: -; sw a1, 0x006C (sp) -; lh t6, 0x13C4 (v1) -.org 0xBE5990 ; In memory: 0x803A0980 - jal every_frame +; lw t9, 0x0004 (s0) +; or a0, s0, r0 +.org 0xB16B50 ; In memory: 0x800A0BF0 + jal before_game_state_update nop +; Runs after the game state updates +; Replaces: +; lui t6, 0x8012 +; lbu t6, 0x1212 (t6) +.org 0xB16B60 ; In memory: 0x800A0C00 + jal after_game_state_update + nop + +;================================================================================================== +; File select hash +;================================================================================================== + +; Runs after the file select menu is rendered +; Replaces: code that draws the fade-out rectangle on file load +.org 0xBAF738 ; In memory: 0x803B3538 +.area 0x60, 0 + jal draw_file_select_hash + andi a0, t8, 0xFF ; a0 = alpha channel of fade-out rectangle + + lw s0, 0x18 (sp) + lw ra, 0x1C (sp) + jr ra + addiu sp, sp, 0x88 +.endarea + +;================================================================================================== +; Special item sources +;================================================================================================== + ; Override Light Arrow cutscene ; Replaces: ; addiu t8, r0, 0x0053 @@ -183,46 +244,91 @@ li t2, 1 ;================================================================================================== -; Menu hacks +; Pause menu ;================================================================================================== -; Make the "SOLD OUT" menu text blank -.org 0x8A9C00 +; Create a blank texture, overwriting a Japanese item description +.org 0x89E800 .fill 0x400, 0 -; Item Menu hooks: -; -; There are 4 removed checks for whether the cursor is allowed to move to an adjacent space, -; one for each cardinal direction. -; -; There are 4 hooks that override the item ID used to display the item description. -; One runs periodically (because the description flips between the item name and "< v > to Equip"). -; The other three run immediately when the cursor moves. +; Use a blank item description texture if the cursor is on an empty slot +; Replaces: +; sll t4, v1, 10 +; addu a1, t4, t5 +.org 0xBC088C ; In memory: 0x8039820C + jal menu_use_blank_description + nop + +;================================================================================================== +; Equipment menu +;================================================================================================== ; Left movement check ; Replaces: -; beq s4, t5, 0x8038F2B4 +; beqz t3, 0x8038D9FC ; nop -.org 0xBB77B4 ; In memory: 0x8038F134 +.org 0xBB5EAC ; In memory: 0x8038D834 nop nop -; Right movement check AND an immediate description update +; Right movement check ; Replaces: -; lbu t4, 0x0074 (t9) -; beq s4, t4, 0x8038F2B4 +; beqz t3, 0x8038D9FC +; nop +.org 0xBB5FD4 ; In memory: 0x8038D95C +nop +nop + +; Upward movement check +; Replaces: +; beqz t6, 0x8038DB90 ; nop -.org 0xBB7890 ; In memory: 0x8038F210 - jal item_menu_description_id_immediate_1 +.org 0xBB6134 ; In memory: 0x8038DABC +nop +nop + +; Downward movement check +; Replaces: +; beqz t9, 0x8038DB90 +; nop +.org 0xBB61E0 ; In memory: 0x8038DB68 +nop +nop + +; Remove "to Equip" text if the cursor is on an empty slot +; Replaces: +; lbu v1, 0x0000 (t4) +; addiu at, r0, 0x0009 +.org 0xBB6688 ; In memory: 0x8038E008 + jal equipment_menu_prevent_empty_equip + nop + +; Prevent empty slots from being equipped +; Replaces: +; addu t8, t4, v0 +; lbu v1, 0x0000 (t8) +.org 0xBB67C4 ; In memory: 0x8038E144 + jal equipment_menu_prevent_empty_equip + addu t4, t4, v0 + +;================================================================================================== +; Item menu +;================================================================================================== + +; Left movement check +; Replaces: +; beq s4, t5, 0x8038F2B4 +; nop +.org 0xBB77B4 ; In memory: 0x8038F134 nop nop -; Immediate description update +; Right movement check ; Replaces: -; lbu t6, 0x0074 (t5) -; sh t6, 0x009A (sp) -.org 0xBB7950 ; In memory: 0x8038F2D0 - jal item_menu_description_id_immediate_2 +; beq s4, t4, 0x8038F2B4 +; nop +.org 0xBB7894 ; In memory: 0x8038F214 + nop nop ; Upward movement check @@ -241,20 +347,20 @@ nop nop -; Immediate description update +; Remove "to Equip" text if the cursor is on an empty slot ; Replaces: -; lbu t7, 0x0074 (t6) -; sh t7, 0x009A (sp) -.org 0xBB7C3C ; In memory: 0x8038F5BC - jal item_menu_description_id_immediate_3 - nop +; addu s1, t6, t7 +; lbu v0, 0x0000 (s1) +.org 0xBB7C88 ; In memory: 0x8038F608 + jal item_menu_prevent_empty_equip + addu s1, t6, t7 -; Periodic description update +; Prevent empty slots from being equipped ; Replaces: -; lbu t9, 0x0074 (t8) -; sh t9, 0x009A (sp) -.org 0xBB7C58 ; In memory: 0x8038F5D8 - jal item_menu_description_id_periodic +; lbu v0, 0x0000 (s1) +; addiu at, r0, 0x0009 +.org 0xBB7D10 ; In memory: 0x8038F690 + jal item_menu_prevent_empty_equip nop ;================================================================================================== @@ -262,16 +368,244 @@ ;================================================================================================== ; Replaces: -; lw t5, 0x8AA0(t5) +; lw t5, 0x8AA0(t5) .org 0xAE5DF0 ; In memory: 8006FE90 - jal suns_song_fix + jal suns_song_fix ; Replaces: -; addu at, at, s3 +; addu at, at, s3 .org 0xB54E5C ; In memory: 800DEEFC - jal suns_song_fix_event - + jal suns_song_fix_event + ; Replaces: -; addu at, at, s3 +; addu at, at, s3 .org 0xB54B38 ; In memory: 800DEBD8 - jal warp_song_fix + jal warp_song_fix + +;================================================================================================== +; Initial save +;================================================================================================== + +; Replaces: +; sb t0, 32(s1) +; sb a1, 33(s1) +.org 0xB06C2C ; In memory: ??? + jal write_initial_save + sb t0, 32(s1) + +;================================================================================================== +; Enemy Hacks +;================================================================================================== + +; Replaces: +; beq t1, at, 0x801E51E0 +.org 0xD74964 ; In memory: 0x801E51B4 + b skip_steal_tunic ; disable like-like stealing tunic +.org 0xD74990 + skip_steal_tunic: + +;================================================================================================== +; Ocarina Song Cutscene Overrides +;================================================================================================== + +; Replaces +; addu t8,t0,t7 +; sb t6,0x74(t8) ; store to fairy ocarina slot +.org 0xAE6E48 + jal override_fairy_ocarina_cutscene + addu t8,t0,t7 + +; a3 = item ID +; Replaces +; li v0,0xFF +.org 0xAE5DF8 + jal override_ocarina_songs +; sw $t7, 0xa4($t0) +.org 0xAE5E04 + nop + +; Replaces +;lui at,0x1 +;addu at,at,s0 +.org 0xAC9ABC + jal override_requiem_song + nop + +;lw $t7, 0xa4($v1) +;lui $v0, 0x200 +;addiu $v0, $v0, 0x24a0 +;and $t8, $t6, $t7 +.org 0xE09F68 + lb t7,0x0EDE(v1) ; check learned song from sun's song +.skip 4 +.skip 4 + andi t8, t7, 0x04 +;addiu $t7, $zero, 1 +.org 0xE09FB0 + jal override_suns_song + +; lw $t7, 0xa4($s0) +; lui $t3, 0x8010 +; addiu $t3, $t3, -0x70cc +; and $t8, $t6, $t7 +.org 0xB06400 + lb t7,0x0EDE(s0) ; check learned song from ZL +.skip 4 +.skip 4 + andi t8, t7, 0x02 + +; Impa does not despawn from Zelda Escape CS +.org 0xD12F78 + li t7, 0 + +;li v1, 5 +.org 0xE29388 + j override_saria_song_check + +;lh v0, 0xa4(t6) ; v0 = scene +.org 0xE2A044 + jal set_saria_song_flag + +; li a1, 3 +.org 0xDB532C + jal override_song_of_time + +;================================================================================================== +; Fire Arrow Chest +;================================================================================================== + +; Don't require water temple +; bne t9,at,+0x0024 +.org 0xE9E1D8 + li t1, 0x4000 + +; Load chest contents +; li t0, 0x0007 +.org 0xE9E1F0 + li t0, 0x5B08 + +; Load actor type +; li a2, 0x010f +.org 0xE9E200 + li a2, 0x000A + +; Set rotation +; sw zero, 0x1C (sp) +.org 0xE9E20C + sw t1, 0x1C (sp) + +;================================================================================================== +; Epona Check Override +;================================================================================================== +.org 0xA9E838 + j Check_Has_Epona_Song + +;================================================================================================== +; Shop Injections +;================================================================================================== + +; Check sold out override +.org 0xC004EC + j Shop_Check_Sold_Out + +; Allow Shop Item ID up to 100 instead of 50 +; slti at, v1, 0x32 +.org 0xC0067C + slti at, v1, 100 + +; Set sold out override +; lh t6, 0x1c(a1) +.org 0xC018A0 + jal Shop_Set_Sold_Out + +; Only run init function if ID is in normal range +; jr t9 +.org 0xC6C7A8 + jal Shop_Keeper_Init_ID +.org 0xC6C920 + jal Shop_Keeper_Init_ID + +; Override Deku Salescrub sold out check +; addiu at, zero, 2 +; lui v1, 0x8012 +; bne v0, at, 0xd8 +; addiu v1, v1, -0x5a30 +; lhu t9, 0xef0(v1) +.org 0xEBB85C + jal Deku_Check_Sold_Out + .skip 4 + bnez v0, @Deku_Check_True + .skip 4 + b @Deku_Check_False +.org 0xEBB8B0 +@Deku_Check_True: +.org 0xEBB8C0 +@Deku_Check_False: + +; Ovveride Deku Scrub set sold out +; sh t7, 0xef0(v0) +.org 0xDF7CB0 + jal Deku_Set_Sold_Out + +;================================================================================================== +; Dungeon info display +;================================================================================================== + +; Talk to Temple of Time Altar injection +; Replaces: +; jal 0xD6218 +.org 0xE2B0B4 + jal set_dungeon_knowledge + + +;================================================================================================== +; V1.0 Scarecrow Song Bug +;================================================================================================== + +; Replaces: +; jal 0x80057030 ; copies Scarecrow Song from active space to save context +.org 0xB55A64 ; In memory 800DFB04 + jal save_scarecrow_song + +;================================================================================================== +; Override Player Name Text +;================================================================================================== + +; Replaces +; lui t2,0x8012 +; addu t2,t2,s3 +; lbu t2,-23053(t2) +.org 0xB51694 + jal get_name_char_1 + ;addi a0, s3, -1 + ;ori t2, v0, 0 + +; Replaces +; lui s0,0x8012 +; addu s0,s0,s2 +; lbu s0,-23052(s0) +.org 0xB516C4 + jal get_name_char_2 + ;ori a0, s2, 0 + ;ori s0, v0, 0 + +; Replaces +; lw s6,48(sp) +; lw s7,52(sp) +; lw s8,56(sp) +.org 0xB52784 + jal reset_player_name_id + nop + lw ra, 0x3C (sp) + +;================================================================================================== +; Text Fixes +;================================================================================================== + +; Skip text overrides for GS Token and Biggoron Sword +; Replaces +; li at, 0x0C +.org 0xB5293C + b skip_GS_BGS_text +.org 0xB529A0 +skip_GS_BGS_text: diff --git a/ASM/src/init.asm b/ASM/src/init.asm new file mode 100644 index 000000000..cd9d85b98 --- /dev/null +++ b/ASM/src/init.asm @@ -0,0 +1,25 @@ +init: + addiu sp, sp, -0x18 + sw ra, 0x10 (sp) + + ; Load second code file from ROM + li a0, 0x80405000 + li a1, 0x034B3000 + li a2, 0xB000 + jal 0x80000DF0 + nop + + jal c_init + nop + + ; Displaced code + lui v0, 0x8012 + addiu v0, v0, 0xD2A0 + addiu t6, r0, 0x0140 + lui at, 0x8010 + sw t6, 0xE500 (at) + + lw ra, 0x10 (sp) + addiu sp, sp, 0x18 + jr ra + nop diff --git a/ASM/src/initial_save.asm b/ASM/src/initial_save.asm new file mode 100644 index 000000000..893f4757f --- /dev/null +++ b/ASM/src/initial_save.asm @@ -0,0 +1,34 @@ +;=========================================== +; Writes extra data to the initial save file +;=========================================== +write_initial_save: + sb a1, 33(s1) ; this was the instruction we replaced to make room for the jump to this function + ; it is writing the Z at the end of ZELDAZ in the save file + ; s1 = pointer to the start of the save file + ; the only registers I have some confidence can be overridden here are: + ; a0, a1, a3, t2, t7, t8, t9, v0, v1, s0 + + ; loop over the save data table + li s0, (INITIAL_SAVE_DATA - 0x04) + +@@save_data_loop: + addiu s0, s0, 0x04 + lw t2, 0x00 (s0) ; t2 = override entry + beqz t2, @@return ; Reached end of save data table + nop + srl t7, t2, 16 + add t7, t7, s1 ; t7 = save data address + andi t8, t2, 0xFF00 + srl t8, t8, 8 ; t8 = write type + bnez t8, @@overwrite_type ; if type is 0, use 'or' type (set bits) otherwise use overwrite type (set byte) + andi t9, t2, 0xFF ; t9 = value to write + lb t2, 0x00 (t7) ; t2 = current saved value + or t9, t9, t2 ; t9 = given value | current saved value + +@@overwrite_type: + j @@save_data_loop + sb t9, 0x00 (t7) ; write the value into the save data + +@@return: + jr ra + nop \ No newline at end of file diff --git a/ASM/src/item_overrides.asm b/ASM/src/item_overrides.asm index 1d9628a49..0798cdf97 100755 --- a/ASM/src/item_overrides.asm +++ b/ASM/src/item_overrides.asm @@ -34,6 +34,103 @@ inventory_check: ;================================================================================================== +; a1 = pointer to the skulltula token actor + +override_skulltula_token: + addiu sp, sp, -0x20 + sw ra, 0x10 (sp) + sw s0, 0x14 (sp) + + jal lookup_override ; call lookup_override(_, actor) + ; so that v0 = index of overwritten item + nop + bgez v0, @@in_table + nop + li v0, 0x5B ; default to giving a token + +@@in_table: + ; resolve the item if it is extended + move a0, v0 + jal resolve_extended_item ; v0 = resolved item ID, v1 = ITEM_TABLE entry + nop + beqz v1, @@not_extended + sw v1, 0x1C (sp) + + ; display message + ; message id is in the extended item table + lbu a1, ITEM_ROW_TEXT_ID (v1) + move a0,s1 + jal 0x000dce14 ; call ex_0dce14(ctx, text_id, 0) + move a2,zero + lw v1, 0x1C (sp) + + ; check if item is for this player + li t0, PLAYER_OVERRIDE_DATA + lh t1, 0x02(t0) + beqz t1, @@extended_effect ; if item is pending player override + li t2, 0x01 + b @@return + sh t2, 0x00(t0) ; set override collected flag + +@@extended_effect: + ; Run effect function + li a0, SAVE_CONTEXT + lbu a1, ITEM_ROW_EFFECT_ARG1 (v1) + lbu a2, ITEM_ROW_EFFECT_ARG2 (v1) + lw t1, ITEM_ROW_EFFECT_FN (v1) + jalr t1 + nop + + ; run original action + lw v1, 0x1C (sp) + lbu a1, ITEM_ROW_ACTION_ID (v1) + jal 0x0006fdcc ; call ex_06fdcc(ctx, item) ; this gives link the item + move a0,s1 ; a0 = ctx + + b @@return + nop + +@@not_extended: + ; get the table entry in the get item table for this item + li t1, GET_ITEMTABLE ; t1 = base of get item table + li t2, 0x6 ; t2 = size of an element + mult v0, t2 ; + mflo t2 ; t2 = offset into get item table + addu s0, t1, t2 ; s0 = pointer to table entry + + ; display message + ; message id is in the get item table + move a0,s1 + lbu a1, 0x3 (s0) ; a1 = text id + jal 0x000dce14 ; call ex_0dce14(ctx, text_id, 0) + move a2,zero + + lb a1, 0x0 (s0) ; a1 = item id + ; check if item is for this player + li t0, PLAYER_OVERRIDE_DATA + lh t1, 0x02(t0) + beqz t1, @@item_effect ; if item is pending player override + li t2, 0x01 + sh t2, 0x00(t0) ; set override collected flag + li a1, 0x41 ; a1 = 0x41 (No item) + +@@item_effect: + ; give the item + jal 0x0006fdcc ; call ex_06fdcc(ctx, item); this gives link the item + move a0,s1 ; a0 = ctx + + ; message id is in the get item table + lbu a1, 0x3 (s0) ; a1 = text id + +@@return: + lw ra, 0x10 (sp) + lw s0, 0x14 (sp) + addiu sp, sp, 0x20 + jr ra + nop + +;================================================================================================== + override_object_npc: lw a2, 0x0030 (sp) lh a1, 0x0004 (a2) @@ -56,13 +153,30 @@ override_object: lhu a1, ITEM_ROW_OBJECT_ID (t2) @@return: - ; Clear any pending special item, now that it's being received - li t2, PENDING_SPECIAL_ITEM - sb r0, 0x00 (t2) ; Re-enable warping (disabled by pending item) li t2, GLOBAL_CONTEXT + 0x104E4 sh r0, 0x00 (t2) + ; get pending item index + li t1, PENDING_SPECIAL_ITEM + lb t2, (PENDING_SPECIAL_ITEM_END - PENDING_SPECIAL_ITEM) (t1) + bltz t2, @@no_pending_clear + add t1, t1, t2 + + ; if item is 0x7F, then increment recieved item count + lb t0, 0x00 (t1) ; item id + li t2, 0x7F + bne t0, t2, @@no_count_inc + nop + li t2, SAVE_CONTEXT + lh t0, 0x90(t2) + addi t0, t0, 1 + sh t0, 0x90(t2) ; item count++ + +@@no_count_inc: + sb zero, 0x00 (t1) + +@@no_pending_clear: jr ra nop @@ -108,6 +222,18 @@ override_action: lw v0, 0x24 (sp) lbu a1, 0x0000 (v0) + li t0, PLAYER_OVERRIDE_DATA + lh t1, 0x02(t0) + beqz t1, @@no_player_override ; if item is pending player override + + li t2, 0x01 + sh t2, 0x00(t0) ; set override collected flag + + b @@return + li a1, 0x41 ; set action to no action + + +@@no_player_override: li t0, EXTENDED_ITEM_DATA lw t1, ITEM_ROW_IS_EXTENDED (t0) beqz t1, @@return @@ -265,12 +391,24 @@ get_override_search_key: ; Load the current scene number li v0, GLOBAL_CONTEXT - lhu v0, 0xA4 (v0) + lhu v0, 0xA4 (v0) ; v0 = scene number li t0, 0x00 ; t0 = override type ori t1, a0, 0 ; t1 = override ID lhu t2, 0x00 (a1) ; t2 = actor ID + bne t2, 0x019C, @@not_skulltula ; if not skulltula, try for other types + nop + + li t0, 0x03 ; t0 = skulltula type + lhu t3, 0x1C (a1) ; t3 = skulltula token variable + andi t1, t3, 0x00FF ; t1 = skulltula flag (used for the lookup) + andi v0, t3, 0x1F00 ; v0 = skulltula scene (shifted) + srl v0, v0, 8 ; v0 = v0 >> 8 (skulltula scene) + b @@not_collectable ; create the id + nop + +@@not_skulltula: bne t2, 0x000A, @@not_chest nop lhu t3, 0x1C (a1) @@ -302,7 +440,18 @@ get_override_search_key: li t0, 0x02 lbu t1, 0x0141 (a1) ; t1 = collectable flag @@not_collectable: + bne t2, 0x011A, @@not_grotto_deku_scrub + nop + bne v0, 0x3E, @@not_grotto_deku_scrub + nop + ; If grotto scene and deku salescrub, then use the + ; grotto id for the scene. + li t0, 0x04 + li t3, SAVE_CONTEXT + lb v0, 0x1397(t3) ; v0 = Grotto ID + +@@not_grotto_deku_scrub: ; Construct ID used to search the override table ; v0 = (scene << 16) | (override_type << 8) | override_id sll v0, v0, 8 @@ -321,6 +470,26 @@ scan_override_table: li v0, -1 + li t0, PLAYER_ID + lbu t1, 0x00(t0) + + li t0, PLAYER_NAME_ID + sb t1, 0x00 (t0) + + ; Check if the item source ID is 0x7F which is used for Co-op items + andi t1, a0, 0x00FF ; t1 = item source ID + li at, 0x7F + bne t1, at, @@not_coop_item + nop + + ; Give co-op item override instead of from the look up table + li t0, PLAYER_ID + lbu t3, 0x00 (t0) ; t3 = player id + lbu v0, 0x01 (t0) ; v0 = override item ID + b @@lookup_item_found + nop + +@@not_coop_item: ; Look up override li t0, (ITEM_OVERRIDES - 0x04) @@lookup_loop: @@ -328,12 +497,34 @@ scan_override_table: lw t1, 0x00 (t0) ; t1 = override entry beqz t1, @@return ; Reached end of override table nop + srl t2, t1, 8 ; t2 = override key + andi t3, t2, 0xF800 + srl t3, t3, 11 ; t3 = player id + + lui t4, 0xFFFF + ori t4, t4, 0x07FF ;t4 = 0xFFFF07FF masks out the player id + and t2, t2, t4 bne t2, a0, @@lookup_loop nop andi v0, t1, 0xFF ; v0 = found item ID +@@lookup_item_found: + li t0, PLAYER_NAME_ID + sb t3, 0x00 (t0) + + li t1, PLAYER_OVERRIDE_DATA + + li t4, PLAYER_ID + lbu t4, 0x00(t4) + beq t3, t4, @@return ; correct player for the item + sh zero, 0x02(t1) ; store no player override + + sb t3, 0x02(t1) ; store player override id + sb v0, 0x03(t1) ; store item id + sw a0, 0x04(t1) ; store search key + @@return: jr ra nop diff --git a/ASM/src/malon.asm b/ASM/src/malon.asm new file mode 100644 index 000000000..cae388cba --- /dev/null +++ b/ASM/src/malon.asm @@ -0,0 +1,229 @@ +;========================================================================================================== +; Hacks to make Malon fast, and allow you to always get her item at the vines, even if you've rescued Talon +;========================================================================================================== + +; 0xD7E344 starts a function that checks if Malon should spawn +; + 0x54 is after credits and age have been checked +; at this point, we have the following: +; a0 = pointer to the save context +; a1 = pointer to the global context +; a2 = 3 +; a3 = 1 +; v0 = not sure, but it's checked to be equal to 3 in the original code, probably has to do with credits +; v1 = the current scene number +; the function has pushed nothing to the stack (so nothing needs to be restored) +; we are expected to return 1 if Malon should spawn, and 0 if she should not + +.org 0xD7E398 + ; this is the state we need for Malon to move to Lon Lon Ranch + lhu t1,0x0ed6(a0) ; this half holds both the following flags + andi t0,t1,0x10 ; t0 = "Talon has fled castle" + andi t1,t1,0x04 ; t1 = "Obtained Malon's Item" + or t0,t0,t1 ; t0 = combination of the flags + li t1,0x14 ; t1 = 0x14 which is the value if both flags are set + +@@hyrule_check: ; she should spawn at castle until Talon has fled and Item has been given + li at,0x5f ; at = 0x5f (Hyrule Castle) + bne at,v1,@@lon_lon_check ; if not in Hyrule Castle, try Lon Lon instead + nop + beq t0,t1,@@lon_lon_check ; if Talon and Item, try Lon Lon instead + nop + li v0,1 + jr ra ; return true + nop + +@@lon_lon_check: ; she should spawn at Lon Lon only once Talon has fled and Item has been given + bne a2,v0,@@return_false ; this test is in the original code, it's probably for the credits + li at,0x63 ; at = 0x63 (Lon Lon Ranch) + bne at,v1,@@return_false ; if not in Lon Lon Ranch, return false + lw t2,0x10(a0) ; t2 = is night time + bnez t2,@@return_false ; Malon does not spawn at Ranch at night + nop + bne t0,t1,@@return_false ; make sure Talon has fled and Item has been given + li v0,1 + jr ra ; return true + nop + +@@return_false: + li v0,0 + jr ra ; return false + nop + + +; 0xD7E110 starts a function that decides which text id Malon should use when spoken to +; + 0x50 is after ocarina check and song check +; at this point, we have the following: +; a0 = pointer to the global context +; v1 = pointer to the save context +; the function needs to restore the stack and return pointer before returning +; we are expected to return a text id + +.org 0xD7E160 + lh t0,0xA4(a0) ; t0 = current scene number + li at,0x63 ; at = 0x63 (Lon Lon Ranch) + bne at,t0,@@not_in_ranch ; if not in Lon Lon, she's in Hyrule Castle + li v0,0x2049 ; v0 = 0x2049 ('... Let's sing together.') + b @@return + nop + +@@not_in_ranch: + lhu t1,0x0ed6(v1) ; this half holds the following flag + andi t1,t1,0x04 ; t1 = "Obtained Malon's Item" + bnez t1,@@return ; if we haven't obtained the item, give the item + li v0,0x2044 ; v = 0x2044 'Set the egg to C to incubate it...' + li v0,0x2043 ; v = 0x2043 '... Would you mind finding my dad? ... ' + +@@return: +return_from_the_other_function: + lw ra,20(sp) + addiu sp,sp,24 ; restore stack + jr ra ; return v0 (whatever text id was chosen) + nop + + + +; 0xD7E818 is a function that sets a value in Malon's actor that makes Link get the item from her (ev0) +; + 0x78 is where the flag/scene checks take place +; at this point, we have the following: +; a0 = pointer to the Malon actor +; a2 = pointer to the global context +; t1 = current scene number +; at = 0x5f (Hyrule Castle) +; v0 = pointer to save context + +.org 0xD7E890 + nop ;bne t1,at,@@not_hyrule ; if scene is not Hyrule Castle + addiu v0,v0,0xa5d0 ; v0 = 0x8012a5d0 # save context + lhu t2,0x0ed6(v0) ; this byte holds the two flags below + andi t3,t2,0x10 ; t3 = "Talon has fled castle" + b @@safe ; skip code that may have reallocations + andi t2,t2,0x04 ; t2 = "Obtained Malon's Item" + +@@unsafe: + jal 0x00020eb4 + nop + nop + nop + lui v0,0x8012 + addiu v0,v0,0xa5d0 + +@@safe: + li t3,0x14 ; t3 = 0x14 which is the value if both flags are set + lui t6,0x8010 + or t2,t2,t3 ; t2 = combination of the flags + bne t2,t3,ev0_return ; check that both flags are true to continue this path + lh t9,472(a0) + +@@not_hyrule: + li t6,0x01 + lb t7,0x0EDE(v0) ; check learned song from malon flag + and t8,t6,t7 ; t8 = "Has Epona's Song" + bnezl t8,ev0_return ; return if we have Malon's song + +.org 0xD7E920 +ev0_return: + + +; +; ; Replaces: +; ; addiu v0,v0,0xa5d0 +; .org 0xD7E760 +; lw t8,68(sp) ; t8 = global context +; +; ; Replaces: +; ; lhu t8,3798(v0) +; .org 0xD7E76C +; lh t8,0xA4(t8) ; t8 = current scene number +; +; ; Replaces: +; ; andi t9,t8,0x10 +; ; beqz t9,ev_egg +; .org 0xD7E778 +; li t9,0x5f ; t9 = 0x5f (Hyrule Castle) +; beq t8,t9,ev_egg ; jump if the scene is Hyrule Castle +; +; ; Replace: +; ; lw t1,164(v0) +; .org 0xD7E788 +; lw t1,0xA674(v0) ; t1 = quest status +; +; .org 0xD7E7A0 +; ev_egg: + + +; This is the hook to change Malon's event ev1 +; See malon_extra.asm for description of what this is changing +; Replaces: +; lui t2,0x8012 +; lhu t2,-19290(t2) +; andi t3,t2,0x40 +; beqzl t3,@@return_block +; lw ra,28(sp) +;.org 0xD7EA48 +; lw a1,44(sp) ; a1 = pointer to the global context +; jal malon_ev1_hack ; run the extra checks +; nop ; Note that malon_ev1_hack will be able to return +; nop ; to the return address of the current function +; nop ; (fixing the stack appropriately) + + + + +; 0xD7E670 is Malon's initialization function +; the original check sets event to cb0 if Talon has fled, or Epona's Song is owned, and sets cb1 otherwise +; instead, we will check if we are in Hyrule castle, or Epona's song is owned, for event cb0 +; note that we need to be insainly careful not to change any instructions that may be reallocated, +; or else it would cause issues and other changes would need to be made + +.org 0xD7E76C + lw t8,68(sp) ; t8 = global context + lui t3,0x809f + lui t0,0x8010 + lh t8,0xA4(t8) ; t8 = current scene number + + lb t1,0x0EDE(v0) + ;lw t1,164(v0) ; t1 = quest status + + addiu t3,t3,4392 ; t3 = 0x809f1128 ( ev0 ) + + li t0,0x01 + ;lw t0,-29660(t0) ; t0 = malon's song mask + + move a0,s0 ; a0 = actor pointer to set up function call + lui t4,0x809f + addiu t4,t4,4840 ; t4 = 0x809f12e8 ( ev1 ) + and t2,t0,t1 ; t2 = "Has Malon's Song" + bnez t2,@@set_ev0 ; if "Has Malon's Song", set event to ev0 + li t9,0x5f ; t9 = 0x5f (Hyrule Castle) + bne t9,t8,set_ev1 ; otherwise if not in Hyrule Castle, set event to ev1 +@@set_ev0: + sw t3,384(s0) ; write f_9f1128 to actor + 0x180 + +.org 0xD7E7B8 +set_ev1: + + +; Replaces +; lw t6,-29660(t6) +; lw t7,164(v1) +.org 0xD7E140 + li t6,0x01 + lb t7,0x0EDE(v1) ; check learned song from malon flag + +.org 0xD7EBBC + jal override_epona_song ;bne v0,at,loc_0x00000408 ; if v0? == 7 then: Return // if preview is not done + +.org 0xD7EC1C + nop ; bne t8,at,loc_0x00000488 ; if t8 != 3 then: Return // if song not played successfully + li t1,5 ;li t1,42 ; t1 = 0x2A + + +;ctx = 0x801C84A0 +;1da2ba = 0157 = Entrance +;1da2fe = 2a -> fade swipe = white circle +; 03 -> fade swipe = white fade +;1da2b5 = 1a -> start transition + +;12B9E2 = fff1 ???? + +;#5f0 \ No newline at end of file diff --git a/ASM/src/menu.asm b/ASM/src/menu.asm index 26349b8b4..fb824f678 100755 --- a/ASM/src/menu.asm +++ b/ASM/src/menu.asm @@ -1,27 +1,91 @@ -.macro item_menu_description_id, dest_reg, base_reg - lbu dest_reg, 0x0074 (base_reg) ; Load the item ID at the selected menu slot - bne dest_reg, 0xFF, @@return ; If the slot is not empty, use default behavior - nop - li dest_reg, 0x2C ; 0x2C = "SOLD OUT" -@@return: -.endmacro +item_menu_prevent_empty_equip: + ; t1 = item under cursor + bne t1, 0xFF, @@return + lbu v0, 0x00 (s1) ; Load from usability table + + li v0, 0xFF ; Prevent equip -item_menu_description_id_periodic: - item_menu_description_id t9, t8 +@@return: jr ra - sh t9, 0x009A (sp) + li at, 9 ; Restore value expected by caller + +;================================================================================================== + +equipment_menu_prevent_empty_equip: + addiu sp, sp, -0x18 + sw v0, 0x10 (sp) + sw ra, 0x14 (sp) -item_menu_description_id_immediate_1: - item_menu_description_id t4, t9 + jal equipment_menu_slot_filled + nop + + bnez v0, @@return + lbu v1, 0x00 (t4) ; Load from usability table + + li v1, 0xFF ; Prevent equip + +@@return: + lw v0, 0x10 (sp) + lw ra, 0x14 (sp) + addiu sp, sp, 0x18 jr ra + li at, 9 ; Restore value expected by caller + +;================================================================================================== + +menu_use_blank_description: + addiu sp, sp, -0x18 + sw v0, 0x10 (sp) + sw ra, 0x14 (sp) + + lhu v0, 0x1E8 (s0) ; v0 = menu screen + bne v0, 3, @@not_equip_menu + nop + ; Check whether the equipment under the cursor has been obtained + jal equipment_menu_slot_filled + nop + bnez v0, @@return ; Use default behavior if the equipment is obtained + nop + b @@return + li v1, 0x7A ; 0x7A = index of texture that we made blank +@@not_equip_menu: + + ; Item menu: check whether the slot under the cursor is empty + ; 0x17A is an invalid texture index, used if item ID = 0xFF + bne v1, 0x17A, @@return nop + li v1, 0x7A ; 0x7A = index of texture that we made blank -item_menu_description_id_immediate_2: - item_menu_description_id t6, t5 +@@return: + ; Displaced code + sll t4, v1, 10 + addu a1, t4, t5 + + lw v0, 0x10 (sp) + lw ra, 0x14 (sp) jr ra - sh t6, 0x009A (sp) + addiu sp, sp, 0x18 + +;================================================================================================== + +equipment_menu_slot_filled: + addiu sp, sp, -0x18 + sw s0, 0x10 (sp) + sw s1, 0x14 (sp) + + li v0, SAVE_CONTEXT + lhu v0, 0x9C (v0) ; v0 = obtained equipment + li s0, SUBSCREEN_CONTEXT + lhu s1, 0x232 (s0) ; s1 = cursor vertical position + sll s1, s1, 2 ; s1 = s1 * 4 + srlv v0, v0, s1 ; shift flags for this row to least significant 4 bits + lhu s1, 0x228 (s0) ; s1 = cursor horizontal position + addiu s1, s1, -1 + li s0, 1 + sllv s1, s0, s1 ; s1 = mask for this equipment column + and v0, v0, s1 -item_menu_description_id_immediate_3: - item_menu_description_id t7, t6 + lw s0, 0x10 (sp) + lw s1, 0x14 (sp) jr ra - sh t7, 0x009A (sp) + addiu sp, sp, 0x18 diff --git a/ASM/src/scarecrow.asm b/ASM/src/scarecrow.asm new file mode 100644 index 000000000..5c6206691 --- /dev/null +++ b/ASM/src/scarecrow.asm @@ -0,0 +1,27 @@ +save_scarecrow_song: +; 80057030 +; A0 = Scarecrow Song save address (copy to) +; A1 = Scarecrow Song live location (copy from) +; A2 = 0x80 + lb t0, 0x0000(a1) + addiu t1, t0, 1 + bne t1, zero, @@copy_song ; if scarecrow song doesn't begin with a rest, copy it to the save data + nop + + addiu sp, sp, -0x18 + sw ra, 0x0014(sp) + sw a0, 0x0018(sp) + sw a1, 0x001C(sp) + + or a0, zero, a1 + addiu a1, a1, 8 + jal 0x57030 ; shift scarecrow song over by 1 note + addiu a2, a2, -8 + lw a0, 0x0018(sp) + lw a1, 0x001C(sp) + li a2, 0x80 + lw ra, 0x0014(sp) + addiu sp, sp, 0x18 +@@copy_song: + j 0x57030 + nop \ No newline at end of file diff --git a/ASM/src/shop.asm b/ASM/src/shop.asm new file mode 100644 index 000000000..db5e5007e --- /dev/null +++ b/ASM/src/shop.asm @@ -0,0 +1,146 @@ +.definelabel Shop_Item_Save_Offset, 0xD4 + (0x2C * 0x1C) + 0x10 + +Shop_Check_Sold_Out: + lh t6, 0x1c(a0) + + ; if var is under 0x32, never sell out + addi t5, t6, -0x32 + bltz t5, @@return + li v0, 0 + + ; t2 = bit mask + andi t1, t5, 0x07 + li t2, 1 + sllv t2, t2, t1 + + ; t1 = byte offset + srl t1, t5, 3 + + ; load byte from save + li t4, SAVE_CONTEXT + add t4, t4, t1 + lb t3, (Shop_Item_Save_Offset)(t4) + + ; mask out the bit flag + and t3, t3, t2 + + ; if not set then, do nothing + li v0, 0 + beqz t3, @@return + nop + + ; Else, change to sold out + li t5, 0x26 + sh t5, 0x1c(a0) ; set item to SOLD OUT + li v0, 1 ; return 1 + +@@return: + jr ra + nop + + +Shop_Set_Sold_Out: + lh t6, 0x1c(a1) + + ; if var is under 0x32, never sell out + addi t5, t6, -0x32 + bltz t5, @@return + li v0, 0 + + ; t2 = bit mask + andi t1, t5, 0x07 + li t2, 1 + sllv t2, t2, t1 + + ; t1 = byte offset + srl t1, t5, 3 + + ; load byte from save + li t4, SAVE_CONTEXT + add t4, t4, t1 + lb t3, (Shop_Item_Save_Offset)(t4) + + ; set and save the bit flag + or t3, t3, t2 + sb t3, (Shop_Item_Save_Offset)(t4) + +@@return: + jr ra + nop + + +Shop_Keeper_Init_ID: + addiu sp, sp, -0x10 + sw ra, 0x08 (sp) + + slti at, a0, 0x32 + beqz at, @@return + move v0, a0 + + jalr t9 + nop +@@return: + lw ra, 0x08 (sp) + addiu sp, sp, 0x10 + jr ra + nop + +Deku_Check_Sold_Out: + li t0, GLOBAL_CONTEXT + li t1, SAVE_CONTEXT + + lh t2, 0xA4(t0) ; current scene number + li at, 0x3E ; Grotto Scene + bne t2, at, @@continue ; If in grotto, use a free scene + + lb t3, 0x1397(t1) ; Grotto ID + addi t2, t3, 0x2D + +@@continue: + lh t3, 0x1C(s0) ; var + addi t3, t3, 1 + li t4, 1 + sllv t4, t4, t3 ; saleman item bitmask + + li at, 0x1C ; Permanant flag entry size + mult t2, at + mflo t5 ; Permanant flag entry offset + + add t6, t1, t5 + lw t7, 0xE4(t6) ; Saleman bitflag (originally unused) + + and v0, t4, t7 ; return if flag is set + + jr ra + nop + + +Deku_Set_Sold_Out: + li t0, GLOBAL_CONTEXT + li t1, SAVE_CONTEXT + + lh t2, 0xA4(t0) ; current scene number + li at, 0x3E ; Grotto Scene + bne t2, at, @@continue ; If in grotto, use a free scene + + lb t3, 0x1397(t1) ; Grotto ID + addi t2, t3, 0x2D + +@@continue: + lh t3, 0x1C(a0) ; var + addi t3, t3, 1 + li t4, 1 + sllv t4, t4, t3 ; saleman item bitmask + + li at, 0x1C ; Permanant flag entry size + mult t2, at + mflo t5 ; Permanant flag entry offset + + add t6, t1, t5 + lw t7, 0xE4(t6) ; Saleman bitflag [0xD0 (PFlag Table) + 0x10 (unused offself)] + + or t7, t4, t7 ; return if flag is set + sw t7, 0xE4(t6) + + jr ra + nop diff --git a/ASM/src/song_fix.asm b/ASM/src/song_fix.asm index 0f283b140..6d7651657 100644 --- a/ASM/src/song_fix.asm +++ b/ASM/src/song_fix.asm @@ -72,4 +72,39 @@ warp_song_fix: @@return: jr ra - nop \ No newline at end of file + nop + +;================================================================================================== +; Change Epona check for owning or being able to play the song +;================================================================================================== +Check_Has_Epona_Song: + ; If not Epona owned flag, then return result + li at, 0x18 + bne a0, at, @@return + nop + + ; If epona is owned, then return True + bnez v0, @@return + nop + + li t2, SAVE_CONTEXT + + ; Check if has Epona's Song + lb t0, 0xA6(t2) + andi t0, t0, 0x20 + beqz t0, @@return ; Return False if no song + li v0, 0 + + ; Check if has Ocarina + li v0, 1 + lb t0, 0x7B(t2) + li t1, 0x07 ; Fairy ocarina + beq t0, t1, @@return + li t2, 0x08 ; Ocarina of Time + beq t0, t2, @@return ; Return True if song & (fairy or oot) ocarina + nop + li v0, 0 ; Else False + +@@return: + jr ra + nop diff --git a/ASM/src/state.asm b/ASM/src/state.asm index 5aa1d314a..aac8c56fd 100755 --- a/ASM/src/state.asm +++ b/ASM/src/state.asm @@ -2,12 +2,20 @@ ; Global variable storage for new code ;================================================================================================== +; Stores the item and player to give to +PLAYER_OVERRIDE_DATA: +.word 0x00000000, 0x00000000 + ; Stores the ITEM_DATA row of the current extended item. EXTENDED_ITEM_DATA: .word 0x00000000, 0x00000000, 0x00000000, 0x00000000 PENDING_SPECIAL_ITEM: .byte 0x00 +.byte 0x00 +.byte 0x00 +PENDING_SPECIAL_ITEM_END: +.byte 0x00 .align 4 TIME_TRAVEL_SAVED_EQUIPS: diff --git a/ASM/src/textbox.asm b/ASM/src/textbox.asm new file mode 100644 index 000000000..6c79163e4 --- /dev/null +++ b/ASM/src/textbox.asm @@ -0,0 +1,61 @@ +get_name_char_1: + addiu sp, sp, -0x10 + sw ra, 0x08 (sp) + + jal get_name_char + addi a0, s3, -1 + + ori t2, v0, 0 + lw ra, 0x08 (sp) + addiu sp, sp, 0x10 + + +get_name_char_2: + addiu sp, sp, -0x10 + sw ra, 0x08 (sp) + + jal get_name_char + ori a0, s2, 0 + + ori s0, v0, 0 + lw ra, 0x08 (sp) + addiu sp, sp, 0x10 + + +; a0 = char index into name +get_name_char: + li t0, PLAYER_NAME_ID + lbu t0, 0x00 (t0) + + bnez t0, @@coop_player_name + nop + + li t0, SAVE_CONTEXT + add t0, t0, a0 + lbu v0, 0x24 (t0) + b @@return + nop + +@@coop_player_name: + sll t0, t0, 3 + li v0, PLAYER_NAMES + add t0, t0, v0 + add t0, t0, a0 + lbu v0, 0x00 (t0) + +@@return: + jr ra + nop + + +reset_player_name_id: + ; displaced code + lw s6,48(sp) + lw s7,52(sp) + lw s8,56(sp) + + li t0, PLAYER_NAME_ID + sb zero, 0x00 (t0) + + jr ra + nop \ No newline at end of file diff --git a/ASM/src/time_travel.asm b/ASM/src/time_travel.asm index 425e65176..11367ad89 100644 --- a/ASM/src/time_travel.asm +++ b/ASM/src/time_travel.asm @@ -1,22 +1,29 @@ +give_master_sword: ; Puts MS in Equipment Only + li t0, SAVE_CONTEXT + lh t1, 0x9C(t0) ; Equipment + ori t2, t1, 2 ; Master Sword flag + jr ra + sh t2, 0x9C(t0) + before_time_travel: - ; s0 = save context + li a1, SAVE_CONTEXT ; required by overwritten code li t0, TIME_TRAVEL_SAVED_EQUIPS ; B and C buttons - lw t1, 0x68 (s0) + lw t1, 0x68 (a1) sw t1, 0x00 (t0) ; C button indexes - lw t1, 0x6C (s0) + lw t1, 0x6C (a1) sw t1, 0x04 (t0) ; Equipment - lhu t1, 0x70 (s0) + lhu t1, 0x70 (a1) sh t1, 0x08 (t0) ; Owned equipment - lhu t1, 0x9C (s0) + lhu t1, 0x9C (a1) sh t1, 0x0A (t0) - jr ra - lw t6, 0x04 (s0) ; Displaced code + j 0x06F80C ; Swap Link Ages + nop ;================================================================================================== diff --git a/BaseClasses.py b/BaseClasses.py index 8fc895f22..9e23e0d97 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1,18 +1,18 @@ import copy from enum import Enum, unique import logging -from collections import OrderedDict +from collections import OrderedDict, Counter, defaultdict +from version import __version__ as OoTRVersion +import random class World(object): - def __init__(self, bridge, open_forest, open_door_of_time, place_dungeon_items, check_beatable_only, hints, fast_ganon, colors, healthSFX): + def __init__(self, settings): self.shuffle = 'vanilla' - self.bridge = bridge self.dungeons = [] self.regions = [] self.itempool = [] - self.seed = None self.state = CollectionState(self) self._cached_locations = None self._entrance_cache = {} @@ -20,21 +20,117 @@ def __init__(self, bridge, open_forest, open_door_of_time, place_dungeon_items, self._entrance_cache = {} self._location_cache = {} self.required_locations = [] - self.check_beatable_only = check_beatable_only - self.place_dungeon_items = place_dungeon_items - self.open_forest = open_forest - self.open_door_of_time = open_door_of_time - self.hints = hints - self.colors = colors - self.healthSFX = healthSFX - self.keysanity = False - self.fast_ganon = fast_ganon + self.shop_prices = {} + + # dump settings directly into world's namespace + # this gives the world an attribute for every setting listed in Settings.py + self.settings = settings + self.__dict__.update(settings.__dict__) + # rename a few attributes... + self.keysanity = self.shuffle_smallkeys != 'dungeon' + self.check_beatable_only = not self.all_reachable + # trials that can be skipped will be decided later + self.skipped_trials = { + 'Forest': False, + 'Fire': False, + 'Water': False, + 'Spirit': False, + 'Shadow': False, + 'Light': False + } + # dungeon forms will be decided later + self.dungeon_mq = { + 'DT': False, + 'DC': False, + 'JB': False, + 'BW': False, + 'IC': False, + 'GTG': False, + 'FoT': False, + 'FiT': False, + 'WT': False, + 'SpT': False, + 'ShT': False, + 'GC': False + } + self.can_take_damage = True - self.spoiler = Spoiler(self) + self.keys_placed = False + - def intialize_regions(self): + def copy(self): + ret = World(self.settings) + ret.skipped_trials = copy.copy(self.skipped_trials) + ret.dungeon_mq = copy.copy(self.dungeon_mq) + ret.big_poe_count = copy.copy(self.big_poe_count) + ret.can_take_damage = self.can_take_damage + ret.shop_prices = copy.copy(self.shop_prices) + ret.keys_placed = self.keys_placed + ret.id = self.id + from Regions import create_regions + from Dungeons import create_dungeons + from Rules import set_rules, set_shop_rules + create_regions(ret) + create_dungeons(ret) + set_rules(ret) + + # connect copied world + for region in self.regions: + copied_region = ret.get_region(region.name) + for entrance in region.entrances: + ret.get_entrance(entrance.name).connect(copied_region) + + # fill locations + for location in self.get_locations(): + if location.item is not None: + item = Item(location.item.name, location.item.advancement, location.item.priority, location.item.type) + item.world = location.item.world + ret.get_location(location.name).item = item + item.location = ret.get_location(location.name) + item.location.locked = location.locked + + # copy remaining itempool. No item in itempool should have an assigned location + for item in self.itempool: + new_item = Item(item.name, item.advancement, item.priority, item.type) + new_item.world = item.world + ret.itempool.append(new_item) + + # copy progress items in state + ret.state.prog_items = copy.copy(self.state.prog_items) + + set_shop_rules(ret) + + return ret + + def initialize_regions(self): for region in self.regions: region.world = self + for location in region.locations: + location.world = self + + def initialize_items(self): + for item in self.itempool: + item.world = self + for region in self.regions: + for location in region.locations: + if location.item != None: + location.item.world = self + for item in [item for dungeon in self.dungeons for item in dungeon.all_items]: + item.world = self + + def random_shop_prices(self): + shop_item_indexes = ['7', '5', '8', '6'] + self.shop_prices = {} + for region in self.regions: + if self.shopsanity == 'random': + shop_item_count = random.randint(0,4) + else: + shop_item_count = int(self.shopsanity) + + for location in region.locations: + if location.type == 'Shop': + if location.name[-1:] in shop_item_indexes[:shop_item_count]: + self.shop_prices[location.name] = int(random.betavariate(1.5, 2) * 60) * 5 def get_region(self, regionname): if isinstance(regionname, Region): @@ -74,40 +170,50 @@ def get_location(self, location): return r_location raise RuntimeError('No such location %s' % location) - def get_all_state(self, keys=False): - ret = CollectionState(self) - - def soft_collect(item): - if item.advancement or item.key: - ret.prog_items.append(item.name) - - for item in self.itempool: - soft_collect(item) - from Items import ItemFactory - if keys: - for item in ItemFactory(['Small Key (Forest Temple)'] * 5 + ['Boss Key (Forest Temple)', 'Boss Key (Fire Temple)', 'Boss Key (Water Temple)', 'Boss Key (Shadow Temple)', 'Boss Key (Spirit Temple)', 'Boss Key (Ganons Castle)'] + ['Small Key (Bottom of the Well)'] * 3 + ['Small Key (Fire Temple)'] * 8 + ['Small Key (Water Temple)'] * 6 + ['Small Key (Shadow Temple)'] * 5 + ['Small Key (Gerudo Training Grounds)'] * 9 + ['Small Key (Spirit Temple)'] * 5 + ['Small Key (Ganons Castle)'] * 2): - soft_collect(item) - ret.sweep_for_events() - ret.clear_cached_unreachable() - return ret - def get_items(self): return [loc.item for loc in self.get_filled_locations()] + self.itempool + # get a list of items that should stay in their proper dungeon + def get_restricted_dungeon_items(self): + itempool = [] + if self.shuffle_mapcompass == 'dungeon': + itempool.extend([item for dungeon in self.dungeons for item in dungeon.dungeon_items]) + if self.shuffle_smallkeys == 'dungeon': + itempool.extend([item for dungeon in self.dungeons for item in dungeon.small_keys]) + if self.shuffle_bosskeys == 'dungeon': + itempool.extend([item for dungeon in self.dungeons for item in dungeon.boss_key]) + + for item in itempool: + item.world = self + return itempool + + # get a list of items that don't have to be in their proper dungeon + def get_unrestricted_dungeon_items(self): + itempool = [] + if self.shuffle_mapcompass == 'keysanity': + itempool.extend([item for dungeon in self.dungeons for item in dungeon.dungeon_items]) + if self.shuffle_smallkeys == 'keysanity': + itempool.extend([item for dungeon in self.dungeons for item in dungeon.small_keys]) + if self.shuffle_bosskeys == 'keysanity': + itempool.extend([item for dungeon in self.dungeons for item in dungeon.boss_key]) + + for item in itempool: + item.world = self + return itempool + def find_items(self, item): return [location for location in self.get_locations() if location.item is not None and location.item.name == item] - def push_item(self, location, item, collect=True): + def push_item(self, location, item): if not isinstance(location, Location): location = self.get_location(location) + # This check should never be false normally, but is here as a sanity check if location.can_fill(self.state, item, False): location.item = item item.location = location - if collect: - self.state.collect(item, location.event, location) - logging.getLogger('').debug('Placed %s at %s', item, location) + logging.getLogger('').debug('Placed %s [World %d] at %s [World %d]', item, item.world.id if hasattr(item, 'world') else -1, location, location.world.id if hasattr(location, 'world') else -1) else: raise RuntimeError('Cannot assign item %s to location %s.' % (item, location)) @@ -137,7 +243,7 @@ def get_placeable_locations(self, state=None): def unlocks_new_location(self, item): temp_state = self.state.copy() temp_state.clear_cached_unreachable() - temp_state.collect(item, True) + temp_state.collect(item) for location in self.get_unfilled_locations(): if temp_state.can_reach(location) and not self.state.can_reach(location): @@ -146,74 +252,19 @@ def unlocks_new_location(self, item): return False def has_beaten_game(self, state): - if state.has('Triforce'): - return True - return False - - def can_beat_game(self, starting_state=None): - if starting_state: - state = starting_state.copy() - else: - state = CollectionState(self) - - if self.has_beaten_game(state): - return True - - prog_locations = [location for location in self.get_locations() if location.item is not None and (location.item.advancement or location.event) and location not in state.locations_checked] - - while prog_locations: - sphere = [] - # build up spheres of collection radius. Everything in each sphere is independent from each other in dependencies and only depends on lower spheres - for location in prog_locations: - if state.can_reach(location): - if location.item.name == 'Triforce': - return True - sphere.append(location) - - if not sphere: - # ran out of places and did not find triforce yet, quit - return False - - for location in sphere: - prog_locations.remove(location) - state.collect(location.item, True, location) - - return False - - @property - def option_identifier(self): - id_value = 0 - id_value_max = 1 - - def markbool(value): - nonlocal id_value, id_value_max - id_value += id_value_max * bool(value) - id_value_max *= 2 - def marksequence(options, value): - nonlocal id_value, id_value_max - id_value += id_value_max * options.index(value) - id_value_max *= len(options) - markbool(self.place_dungeon_items) - marksequence(['ganon', 'pedestal', 'dungeons'], self.bridge) - marksequence(['vanilla', 'simple'], self.shuffle) - markbool(self.check_beatable_only) - assert id_value_max <= 0xFFFFFFFF - return id_value + return state.has('Triforce') class CollectionState(object): def __init__(self, parent): - self.prog_items = [] + self.prog_items = Counter() self.world = parent self.region_cache = {} self.location_cache = {} self.entrance_cache = {} self.recursion_count = 0 - self.events = [] - self.path = {} - self.locations_checked = set() - + self.collected_locations = {} def clear_cached_unreachable(self): # we only need to invalidate results which were False, places we could reach before we can still reach after adding more items @@ -227,9 +278,7 @@ def copy(self): ret.region_cache = copy.copy(self.region_cache) ret.location_cache = copy.copy(self.location_cache) ret.entrance_cache = copy.copy(self.entrance_cache) - ret.events = copy.copy(self.events) - ret.path = copy.copy(self.path) - ret.locations_checked = copy.copy(self.locations_checked) + ret.collected_locations = copy.copy(self.collected_locations) return ret def can_reach(self, spot, resolution_hint=None): @@ -276,53 +325,144 @@ def can_reach(self, spot, resolution_hint=None): return can_reach return correct_cache[spot] - def sweep_for_events(self, key_only=False): - # this may need improvement - new_locations = True - checked_locations = 0 - while new_locations: - reachable_events = [location for location in self.world.get_filled_locations() if location.event and (not key_only or location.item.key) and self.can_reach(location)] - for event in reachable_events: - if event.name not in self.events: - self.events.append(event.name) - self.collect(event.item, True, event) - new_locations = len(reachable_events) > checked_locations - checked_locations = len(reachable_events) - def has(self, item, count=1): - if count == 1: - return item in self.prog_items - return self.item_count(item) >= count + return self.prog_items[item] >= count def item_count(self, item): - return len([pritem for pritem in self.prog_items if pritem == item]) + return self.prog_items[item] def is_adult(self): return self.has('Master Sword') - def can_blast(self): - return self.has('Bomb Bag') or (self.is_adult() and self.has('Hammer')) + def can_child_attack(self): + return self.has_slingshot() or \ + self.has('Boomerang') or \ + self.has_sticks() or \ + self.has_explosives() or \ + self.has('Kokiri Sword') or \ + (self.has('Dins Fire') and self.has('Magic Meter')) + + def can_stun_deku(self): + return self.is_adult() or \ + self.can_child_attack() or \ + self.has_nuts() or \ + self.has('Buy Deku Shield') + + def has_nuts(self): + return self.has('Buy Deku Nut (5)') or self.has('Buy Deku Nut (10)') or self.has('Deku Nut Drop') + + def has_sticks(self): + return self.has('Buy Deku Stick (1)') or self.has('Deku Stick Drop') + + def has_bow(self): + return self.has('Bow') + + def has_slingshot(self): + return self.has('Slingshot') + + def has_bombs(self): + return self.has('Bomb Bag') + + def has_blue_fire(self): + return self.has_bottle() and \ + (self.can_reach('Ice Cavern') + or self.can_reach('Ganons Castle Water Trial') + or self.has('Buy Blue Fire') + or (self.world.dungeon_mq['GTG'] and self.can_reach('Gerudo Training Grounds Stalfos Room'))) + + def has_ocarina(self): + return (self.has('Ocarina') or self.has("Fairy Ocarina") or self.has("Ocarina of Time")) + + def can_play(self, song): + return self.has_ocarina() and self.has(song) + + def can_use(self, item): + magic_items = ['Dins Fire', 'Farores Wind', 'Nayrus Love', 'Lens of Truth'] + adult_items = ['Bow', 'Hammer', 'Iron Boots', 'Hover Boots', 'Magic Bean'] + magic_arrows = ['Fire Arrows', 'Light Arrows'] + if item in magic_items: + return self.has(item) and self.has('Magic Meter') + elif item in adult_items: + return self.has(item) and self.is_adult() + elif item in magic_arrows: + return self.has(item) and self.is_adult() and self.has_bow() and self.has('Magic Meter') + elif item == 'Hookshot': + return self.has('Progressive Hookshot') and self.is_adult() + elif item == 'Longshot': + return self.has('Progressive Hookshot', 2) and self.is_adult() + elif item == 'Silver Gauntlets': + return self.has('Progressive Strength Upgrade', 2) and self.is_adult() + elif item == 'Golden Gauntlets': + return self.has('Progressive Strength Upgrade', 3) and self.is_adult() + elif item == 'Scarecrow': + return self.has('Progressive Hookshot') and self.is_adult() and self.has_ocarina() + elif item == 'Distant Scarecrow': + return self.has('Progressive Hookshot', 2) and self.is_adult() and self.has_ocarina() + else: + return self.has(item) + + def can_buy_bombchus(self): + return self.has('Buy Bombchu (5)') or \ + self.has('Buy Bombchu (10)') or \ + self.has('Buy Bombchu (20)') or \ + self.can_reach('Castle Town Bombchu Bowling') + + def has_bombchus(self): + return (self.world.bombchus_in_logic and \ + ((any(pritem.startswith('Bombchus') for pritem in self.prog_items) and \ + self.can_buy_bombchus()) \ + or (self.has('Progressive Wallet') and self.can_reach('Haunted Wasteland')))) \ + or (not self.world.bombchus_in_logic and self.has('Bomb Bag') and \ + self.can_buy_bombchus()) + + def has_bombchus_item(self): + return (self.world.bombchus_in_logic and \ + (any(pritem.startswith('Bombchus') for pritem in self.prog_items) \ + or (self.has('Progressive Wallet') and self.can_reach('Haunted Wasteland')))) \ + or (not self.world.bombchus_in_logic and self.has('Bomb Bag')) + + def has_explosives(self): + return self.has_bombs() or self.has_bombchus() + + def can_blast_or_smash(self): + return self.has_explosives() or (self.is_adult() and self.has('Hammer')) def can_dive(self): return self.has('Progressive Scale') - def can_lift_rocks(self): - return (self.has('Silver Gauntlets') or self.has('Gold Gauntlets')) and self.is_adult() + def can_see_with_lens(self): + return ((self.has('Magic Meter') and self.has('Lens of Truth')) or self.world.logic_lens != 'all') + + def has_projectile(self, age='either'): + if age == 'child': + return self.has_explosives() or self.has_slingshot() or self.has('Boomerang') + elif age == 'adult': + return self.has_explosives() or self.has_bow() or self.has('Progressive Hookshot') + elif age == 'both': + return self.has_explosives() or ((self.has_bow() or self.has('Progressive Hookshot')) and (self.has_slingshot() or self.has('Boomerang'))) + else: + return self.has_explosives() or ((self.has_bow() or self.has('Progressive Hookshot')) or (self.has_slingshot() or self.has('Boomerang'))) def has_GoronTunic(self): - return (self.has('Goron Tunic') or (self.has('Progressive Wallet') and (self.has('Bomb Bag') or self.has('Progressive Strength Upgrade') or self.has('Bow')))) + return (self.has('Goron Tunic') or self.has('Buy Goron Tunic')) + + def has_ZoraTunic(self): + return (self.has('Zora Tunic') or self.has('Buy Zora Tunic')) + + def can_leave_forest(self): + return self.world.open_forest or self.can_reach(self.world.get_location('Queen Gohma')) def can_finish_adult_trades(self): - zora_thawed = self.has_bottle() and self.has('Zeldas Lullaby') and (self.can_reach('Ice Cavern') or self.can_reach('Ganons Castle Water Trial') or self.has('Progressive Wallet', 2)) + zora_thawed = (self.can_play('Zeldas Lullaby') or (self.has('Hover Boots') and self.world.logic_zora_with_hovers)) and self.has_blue_fire() carpenter_access = self.has('Epona') or self.has('Progressive Hookshot', 2) - return (self.has('Claim Check') or ((self.has('Eyedrops') or self.has('Eyeball Frog') or self.has('Prescription') or self.has('Broken Sword')) and zora_thawed) or ((self.has('Poachers Saw') or self.has('Odd Mushroom') or self.has('Cojiro') or self.has('Pocket Cucco') or self.has('Pocket Egg')) and zora_thawed and carpenter_access)) + return (self.has('Claim Check') or ((self.has('Progressive Strength Upgrade') or self.can_blast_or_smash() or self.has_bow()) and (((self.has('Eyedrops') or self.has('Eyeball Frog') or self.has('Prescription') or self.has('Broken Sword')) and zora_thawed) or ((self.has('Poachers Saw') or self.has('Odd Mushroom') or self.has('Cojiro') or self.has('Pocket Cucco') or self.has('Pocket Egg')) and zora_thawed and carpenter_access)))) def has_bottle(self): - is_normal_bottle = lambda item: (item.startswith('Bottle') and item != 'Bottle with Letter') + is_normal_bottle = lambda item: (item.startswith('Bottle') and item != 'Bottle with Letter' and (item != 'Bottle with Big Poe' or self.is_adult())) return any(is_normal_bottle(pritem) for pritem in self.prog_items) def bottle_count(self): - return len([pritem for pritem in self.prog_items if pritem.startswith('Bottle')]) + return sum([pritem for pritem in self.prog_items if pritem.startswith('Bottle') and pritem != 'Bottle with Letter' and (pritem != 'Bottle with Big Poe' or self.is_adult())]) def has_hearts(self, count): # Warning: This only considers items that are marked as advancement items @@ -336,48 +476,51 @@ def heart_count(self): + 3 # starting hearts ) - def can_lift_pillars(self): - return self.has('Gold Gauntlets') and self.is_adult() - def has_fire_source(self): - return ((self.has('Dins Fire') or (self.has('Bow') and self.has('Fire Arrows') and self.is_adult())) and self.has('Magic Meter')) + return self.can_use('Dins Fire') or self.can_use('Fire Arrows') def guarantee_hint(self): - return(self.has('Stone of Agony') or not self.world.hints) - - def collect(self, item, event=False, location=None): - if location: - self.locations_checked.add(location) - changed = False - if item.name.startswith('Bottle'): - if self.bottle_count() < 4: - self.prog_items.append(item.name) - changed = True - elif event or item.advancement: - self.prog_items.append(item.name) - changed = True - - if changed: - self.clear_cached_unreachable() - if not event: - self.sweep_for_events() - self.clear_cached_unreachable() + if(self.world.hints == 'mask'): + # has the mask of truth + return self.has('Zeldas Letter') and self.can_play('Sarias Song') and self.has('Kokiri Emerald') and self.has('Goron Ruby') and self.has('Zora Sapphire') + elif(self.world.hints == 'agony'): + # has the Stone of Agony + return self.has('Stone of Agony') + return True - def remove(self, item): - if item.advancement: - to_remove = item.name + def nighttime(self): + if self.world.logic_no_night_tokens_without_suns_song: + return self.can_play('Suns Song') + return True - if to_remove is not None: - try: - self.prog_items.remove(to_remove) - except ValueError: - return + def can_finish_GerudoFortress(self): + if self.world.gerudo_fortress == 'normal': + return self.has('Small Key (Gerudo Fortress)', 4) and (self.can_use('Bow') or self.can_use('Hookshot') or self.can_use('Hover Boots') or self.world.logic_tricks) + elif self.world.gerudo_fortress == 'fast': + return self.has('Small Key (Gerudo Fortress)', 1) and self.is_adult() + else: + return self.is_adult() - # invalidate caches, nothing can be trusted anymore now - self.region_cache = {} - self.location_cache = {} - self.entrance_cache = {} - self.recursion_count = 0 + # Be careful using this function. It will not collect any + # items that may be locked behind the item, only the item itself. + def collect(self, item): + if item.advancement: + self.prog_items[item.name] += 1 + self.clear_cached_unreachable() + + # Be careful using this function. It will not uncollect any + # items that may be locked behind the item, only the item itself. + def remove(self, item): + if self.prog_items[item.name] > 0: + self.prog_items[item.name] -= 1 + if self.prog_items[item.name] <= 0: + del self.prog_items[item.name] + + # invalidate collected cache. unreachable locations are still unreachable + self.region_cache = {k: v for k, v in self.region_cache.items() if not v} + self.location_cache = {k: v for k, v in self.location_cache.items() if not v} + self.entrance_cache = {k: v for k, v in self.entrance_cache.items() if not v} + self.recursion_count = 0 def __getattr__(self, item): if item.startswith('can_reach_'): @@ -387,6 +530,114 @@ def __getattr__(self, item): raise RuntimeError('Cannot parse %s.' % item) + # This function returns a list of states that is each of the base_states + # with every item still in the itempool. It only adds items that belong + # to its respective world. See fill_restrictive + @staticmethod + def get_states_with_items(base_state_list, itempool): + new_state_list = [] + for base_state in base_state_list: + new_state = base_state.copy() + for item in itempool: + if item.world.id == base_state.world.id: # Check world + new_state.collect(item) + new_state_list.append(new_state) + CollectionState.collect_locations(new_state_list) + return new_state_list + + # This collected all item locations available in the state list given that + # the states have collected items. The purpose is that it will search for + # all new items that become accessible with a new item set + @staticmethod + def collect_locations(state_list): + # Get all item locations in the worlds + item_locations = [location for state in state_list for location in state.world.get_filled_locations() if location.item.advancement] + + # will loop if there is more items opened up in the previous iteration. Always run once + reachable_items_locations = True + while reachable_items_locations: + # get reachable new items locations + reachable_items_locations = [location for location in item_locations if location.name not in state_list[location.world.id].collected_locations and state_list[location.world.id].can_reach(location)] + for location in reachable_items_locations: + # Mark the location collected in the state world it exists in + state_list[location.world.id].collected_locations[location.name] = True + # Collect the item for the state world it is for + state_list[location.item.world.id].collect(location.item) + + # This returns True is every state is beatable. It's important to ensure + # all states beatable since items required in one world can be in another. + @staticmethod + def can_beat_game(state_list, scan_for_items=True): + if scan_for_items: + # Check if already beaten + game_beaten = True + for state in state_list: + if not state.has('Triforce'): + game_beaten = False + break + if game_beaten: + return True + + # collect all available items + new_state_list = [state.copy() for state in state_list] + CollectionState.collect_locations(new_state_list) + else: + new_state_list = state_list + + # if the every state got the Triforce, then return True + for state in new_state_list: + if not state.has('Triforce'): + return False + return True + + @staticmethod + def update_required_items(worlds): + state_list = [world.state for world in worlds] + + # get list of all of the progressive items that can appear in hints + all_locations = [location for world in worlds for location in world.get_filled_locations()] + item_locations = [location for location in all_locations + if location.item.advancement + and location.item.type != 'Event' + and location.item.type != 'Shop' + and not location.locked + and (worlds[0].shuffle_smallkeys != 'dungeon' or not location.item.smallkey) + and (worlds[0].shuffle_bosskeys != 'dungeon' or not location.item.bosskey)] + + # if the playthrough was generated, filter the list of locations to the + # locations in the playthrough. The required locations is a subset of these + # locations. Can't use the locations directly since they are location to the + # copied spoiler world, so must try to find the matching locations by name + if worlds[0].spoiler.playthrough: + spoiler_locations = defaultdict(lambda: []) + for location in [location for _,sphere in worlds[0].spoiler.playthrough.items() for location in sphere]: + spoiler_locations[location.name].append(location.world.id) + item_locations = list(filter(lambda location: location.world.id in spoiler_locations[location.name], item_locations)) + + required_locations = [] + reachable_items_locations = True + while (item_locations and reachable_items_locations): + reachable_items_locations = [location for location in all_locations if location.name not in state_list[location.world.id].collected_locations and state_list[location.world.id].can_reach(location)] + for location in reachable_items_locations: + # Try to remove items one at a time and see if the game is still beatable + if location in item_locations: + old_item = location.item + location.item = None + if not CollectionState.can_beat_game(state_list): + required_locations.append(location) + location.item = old_item + item_locations.remove(location) + state_list[location.world.id].collected_locations[location.name] = True + state_list[location.item.world.id].collect(location.item) + + # Filter the required location to only include location in the world + required_locations_dict = {} + for world in worlds: + required_locations_dict[world.id] = list(filter(lambda location: location.world.id == world.id, required_locations)) + for world in worlds: + world.spoiler.required_locations = required_locations_dict + + @unique class RegionType(Enum): Overworld = 1 @@ -400,7 +651,6 @@ def is_indoors(self): return self in (RegionType.Interior, RegionType.Dungeon, RegionType.Grotto) - class Region(object): def __init__(self, name, type): @@ -413,19 +663,25 @@ def __init__(self, name, type): self.world = None self.spot_type = 'Region' self.recursion_count = 0 + self.price = None def can_reach(self, state): for entrance in self.entrances: if state.can_reach(entrance): - if not self in state.path: - state.path[self] = (self.name, state.path.get(entrance, None)) return True return False def can_fill(self, item): - is_dungeon_item = item.key or item.map or item.compass - if is_dungeon_item: - return self.dungeon and self.dungeon.is_dungeon_item(item) + is_dungeon_restricted = False + if item.map or item.compass: + is_dungeon_restricted = self.world.shuffle_mapcompass == 'dungeon' + elif item.smallkey: + is_dungeon_restricted = self.world.shuffle_smallkeys == 'dungeon' + elif item.bosskey: + is_dungeon_restricted = self.world.shuffle_bosskeys == 'dungeon' + + if is_dungeon_restricted: + return self.dungeon and self.dungeon.is_dungeon_item(item) and item.world.id == self.world.id return True def __str__(self): @@ -450,8 +706,6 @@ def __init__(self, name='', parent=None): def can_reach(self, state): if self.access_rule(state) and state.can_reach(self.parent_region): - if not self in state.path: - state.path[self] = (self.name, state.path.get(self.parent_region, (self.parent_region.name, None))) return True return False @@ -472,16 +726,25 @@ def __unicode__(self): class Dungeon(object): - def __init__(self, name, regions, boss_key, small_keys, dungeon_items): + def __init__(self, world, name, regions, boss_key, small_keys, dungeon_items): + def to_array(obj): + if obj == None: + return [] + if isinstance(obj, list): + return obj + else: + return [obj] + + self.world = world self.name = name self.regions = regions - self.boss_key = boss_key - self.small_keys = small_keys - self.dungeon_items = dungeon_items + self.boss_key = to_array(boss_key) + self.small_keys = to_array(small_keys) + self.dungeon_items = to_array(dungeon_items) @property def keys(self): - return self.small_keys + ([self.boss_key] if self.boss_key else []) + return self.small_keys + self.boss_key @property def all_items(self): @@ -512,14 +775,17 @@ def __init__(self, name='', address=None, address2=None, default=None, type='Che self.spot_type = 'Location' self.recursion_count = 0 self.staleness_count = 0 - self.event = False self.always_allow = lambda item, state: False self.access_rule = lambda state: True self.item_rule = lambda item: True + self.locked = False + self.price = None + self.minor_only = False def can_fill(self, state, item, check_access=True): - return self.always_allow(item, self) or (self.parent_region.can_fill(item) and self.item_rule(item) and (not check_access or self.can_reach(state))) - + if self.minor_only and item.majoritem: + return False + return self.parent_region.can_fill(item) and (self.always_allow(item, state) or (self.item_rule(item) and (not check_access or state.can_reach(self)))) def can_fill_fast(self, item): return self.item_rule(item) @@ -537,7 +803,7 @@ def __unicode__(self): class Item(object): - def __init__(self, name='', advancement=False, priority=False, type=None, code=None, index=None): + def __init__(self, name='', advancement=False, priority=False, type=None, code=None, index=None, object=None, model=None): self.name = name self.advancement = advancement self.priority = priority @@ -545,11 +811,25 @@ def __init__(self, name='', advancement=False, priority=False, type=None, code=N self.code = code self.index = index self.location = None + self.object = object + self.model = model + self.price = None + + def copy(self): + return Item(self.name, self.advancement, self.priority, self.type, self.code, self.index) @property def key(self): return self.type == 'SmallKey' or self.type == 'BossKey' + @property + def smallkey(self): + return self.type == 'SmallKey' + + @property + def bosskey(self): + return self.type == 'BossKey' + @property def crystal(self): return self.type == 'Crystal' @@ -562,6 +842,27 @@ def map(self): def compass(self): return self.type == 'Compass' + @property + def dungeonitem(self): + return self.type == 'SmallKey' or self.type == 'BossKey' or self.type == 'Map' or self.type == 'Compass' + + @property + def majoritem(self): + if self.type == 'Token' or self.type == 'Event' or self.type == 'Shop' or not self.advancement: + return False + + if self.name.startswith('Bombchus') and not self.world.bombchus_in_logic: + return False + + if self.map or self.compass: + return False + if self.smallkey and self.world.shuffle_smallkeys == 'dungeon': + return False + if self.bosskey and self.world.shuffle_bosskeys == 'dungeon': + return False + + return True + def __str__(self): return str(self.__unicode__()) @@ -571,60 +872,57 @@ def __unicode__(self): class Spoiler(object): - def __init__(self, world): - self.world = world - self.entrances = [] + def __init__(self, worlds): + self.worlds = worlds self.playthrough = {} self.locations = {} - self.paths = {} self.metadata = {} - - def set_entrance(self, entrance, exit, direction): - self.entrances.append(OrderedDict([('entrance', entrance), ('exit', exit), ('direction', direction)])) + self.required_locations = [] + self.hints = {} def parse_data(self): - spoiler_locations = [] - for location in self.world.get_locations(): - if location.item.name not in ['Gold Skulltulla Token', 'Epona', 'Triforce', 'Fairy Ocarina', 'Ocarina of Time', 'Zeldas Letter', 'Master Sword', - 'Magic Bean', 'Gerudo Membership Card', 'Forest Trial Clear', 'Fire Trial Clear', 'Water Trial Clear', 'Shadow Trial Clear', 'Spirit Trial Clear', 'Light Trial Clear']: - spoiler_locations.append(location) - sort_order = {"Song": 0, "Boss": -1} - spoiler_locations.sort(key=lambda item: sort_order.get(item.type, 1)) - self.locations = {'other locations': OrderedDict([(str(location), str(location.item) if location.item is not None else 'Nothing') for location in spoiler_locations])} - from Main import __version__ as OoTRVersion - self.metadata = {'version': OoTRVersion, - 'seed': self.world.seed, - 'bridge': self.world.bridge, - 'forest': self.world.open_forest, - 'door': self.world.open_door_of_time, - 'ganon': self.world.fast_ganon, - 'completeable': not self.world.check_beatable_only, - 'dungeonitems': self.world.place_dungeon_items} + self.locations = {} + self.version = OoTRVersion + self.settings = self.worlds[0].settings + for world in self.worlds: + spoiler_locations = [location for location in world.get_locations() if not location.locked] + sort_order = {"Song": 0, "Boss": -1} + spoiler_locations.sort(key=lambda item: sort_order.get(item.type, 1)) + if self.settings.world_count > 1: + self.locations[world.id] = OrderedDict([(str(location), "%s [Player %d]" % (str(location.item), location.item.world.id + 1) if location.item is not None else 'Nothing') for location in spoiler_locations]) + else: + self.locations[world.id] = OrderedDict([(str(location), str(location.item) if location.item is not None else 'Nothing') for location in spoiler_locations]) def to_file(self, filename): self.parse_data() with open(filename, 'w') as outfile: - outfile.write('OoT Randomizer Version %s - Seed: %s\n\n' % (self.metadata['version'], self.metadata['seed'])) - outfile.write('Rainbow Bridge Requirement: %s\n' % self.metadata['bridge']) - outfile.write('Open Forest: %s\n' % ('Yes' if self.metadata['forest'] else 'No')) - outfile.write('Open Door of Time: %s\n' % ('Yes' if self.metadata['door'] else 'No')) - outfile.write('Fast Ganon\'s Castle: %s\n' % ('Yes' if self.metadata['ganon'] else 'No')) - outfile.write('All Locations Accessible: %s\n' % ('Yes' if self.metadata['completeable'] else 'No, some locations may be unreachable')) - outfile.write('Maps and Compasses in Dungeons: %s\n' % ('Yes' if self.metadata['dungeonitems'] else 'No')) - outfile.write('\n\nLocations:\n\n') - outfile.write('\n'.join(['%s: %s' % (location, item) for (location, item) in self.locations['other locations'].items()])) + outfile.write('OoT Randomizer Version %s - Seed: %s\n\n' % (self.version, self.settings.seed)) + outfile.write('Settings (%s):\n%s' % (self.settings.get_settings_string(), self.settings.get_settings_display())) + + for world in self.worlds: + if self.settings.world_count > 1: + outfile.write('\n\nLocations [World %d]:\n\n' % (world.id + 1)) + else: + outfile.write('\n\nLocations:\n\n') + outfile.write('\n'.join(['%s: %s' % (location, item) for (location, item) in self.locations[world.id].items()])) + outfile.write('\n\nPlaythrough:\n\n') - outfile.write('\n'.join(['%s: {\n%s\n}' % (sphere_nr, '\n'.join([' %s: %s' % (location, item) for (location, item) in sphere.items()])) for (sphere_nr, sphere) in self.playthrough.items()])) - outfile.write('\n\nPaths:\n\n') - - path_listings = [] - for location, path in sorted(self.paths.items()): - path_lines = [] - for region, exit in path: - if exit is not None: - path_lines.append("{} -> {}".format(region, exit)) - else: - path_lines.append(region) - path_listings.append("{}\n {}".format(location, "\n => ".join(path_lines))) + if self.settings.world_count > 1: + outfile.write('\n'.join(['%s: {\n%s\n}' % (sphere_nr, '\n'.join([' %s [World %d]: %s [Player %d]' % (location.name, location.world.id + 1, item.name, item.world.id + 1) for (location, item) in sphere.items()])) for (sphere_nr, sphere) in self.playthrough.items()])) + else: + outfile.write('\n'.join(['%s: {\n%s\n}' % (sphere_nr, '\n'.join([' %s: %s' % (location.name, item.name) for (location, item) in sphere.items()])) for (sphere_nr, sphere) in self.playthrough.items()])) - outfile.write('\n'.join(path_listings)) + if len(self.hints) > 0: + for world in self.worlds: + if self.settings.world_count > 1: + outfile.write('\n\nWay of the Hero [Player %d]:\n\n' % (world.id + 1)) + outfile.write('\n'.join(['%s: %s [Player %d]' % (location.name, location.item.name, location.item.world.id + 1) for location in self.required_locations[world.id]])) + else: + outfile.write('\n\nWay of the Hero:\n\n') + outfile.write('\n'.join(['%s: %s' % (location.name, location.item.name) for location in self.required_locations[world.id]])) + + if self.settings.world_count > 1: + outfile.write('\n\nGossip Stone Hints [Player %d]:\n\n' % self.settings.player_num) + else: + outfile.write('\n\nGossip Stone Hints:\n\n') + outfile.write('\n'.join(self.hints.values())) diff --git a/Compress/Compress b/Compress/Compress index 1386ef977..1fd48949f 100755 Binary files a/Compress/Compress and b/Compress/Compress differ diff --git a/Compress/Compress.exe b/Compress/Compress.exe index 46ab74eaa..cf12f6be4 100755 Binary files a/Compress/Compress.exe and b/Compress/Compress.exe differ diff --git a/Compress/Compress.out b/Compress/Compress.out index 66fab4b35..ec72afb09 100755 Binary files a/Compress/Compress.out and b/Compress/Compress.out differ diff --git a/Compress/Compress32.exe b/Compress/Compress32.exe new file mode 100755 index 000000000..bb1ddd929 Binary files /dev/null and b/Compress/Compress32.exe differ diff --git a/Decompress/Decompress b/Decompress/Decompress index 84f51cd5e..8c0741a91 100755 Binary files a/Decompress/Decompress and b/Decompress/Decompress differ diff --git a/Decompress/Decompress.exe b/Decompress/Decompress.exe old mode 100644 new mode 100755 diff --git a/Decompress/Decompress.out b/Decompress/Decompress.out index e8527cf0e..a57d638aa 100755 Binary files a/Decompress/Decompress.out and b/Decompress/Decompress.out differ diff --git a/Decompress/Decompress32.exe b/Decompress/Decompress32.exe new file mode 100755 index 000000000..0de1251d8 Binary files /dev/null and b/Decompress/Decompress32.exe differ diff --git a/Dungeons.py b/Dungeons.py index 81917e15a..d687cc7d6 100644 --- a/Dungeons.py +++ b/Dungeons.py @@ -1,46 +1,202 @@ -import random - -from BaseClasses import Dungeon -from Fill import fill_restrictive -from Items import ItemFactory - - -def create_dungeons(world): - def make_dungeon(name, dungeon_regions, boss_key, small_keys, dungeon_items): - dungeon = Dungeon(name, dungeon_regions, boss_key, small_keys, dungeon_items) - for region in dungeon.regions: - world.get_region(region).dungeon = dungeon - return dungeon - - DT = make_dungeon('Deku Tree', ['Deku Tree Lobby', 'Deku Tree Slingshot Room', 'Deku Tree Boss Room'], None, [], ItemFactory(['Map (Deku Tree)', 'Compass (Deku Tree)'])) - DC = make_dungeon('Dodongos Cavern', ['Dodongos Cavern Beginning', 'Dodongos Cavern Lobby', 'Dodongos Cavern Climb', 'Dodongos Cavern Far Bridge', 'Dodongos Cavern Boss Area'], None, [], ItemFactory(['Map (Dodongos Cavern)', 'Compass (Dodongos Cavern)'])) - JB = make_dungeon('Jabu Jabus Belly', ['Jabu Jabus Belly Beginning', 'Jabu Jabus Belly Main', 'Jabu Jabus Belly Depths', 'Jabu Jabus Belly Boss Area'], None, [], ItemFactory(['Map (Jabu Jabus Belly)', 'Compass (Jabu Jabus Belly)'])) - FoT = make_dungeon('Forest Temple', ['Forest Temple Lobby', 'Forest Temple NW Outdoors', 'Forest Temple NE Outdoors', 'Forest Temple Falling Room', 'Forest Temple Block Push Room', 'Forest Temple Straightened Hall', 'Forest Temple Outside Upper Ledge', 'Forest Temple Bow Region', 'Forest Temple Boss Region'], ItemFactory('Boss Key (Forest Temple)'), ItemFactory(['Small Key (Forest Temple)'] * 5), ItemFactory(['Map (Forest Temple)', 'Compass (Forest Temple)'])) - BW = make_dungeon('Bottom of the Well', ['Bottom of the Well'], None, ItemFactory(['Small Key (Bottom of the Well)'] * 3), ItemFactory(['Map (Bottom of the Well)', 'Compass (Bottom of the Well)'])) - FiT = make_dungeon('Fire Temple', ['Fire Temple Lower', 'Fire Temple Middle', 'Fire Temple Upper'], ItemFactory('Boss Key (Fire Temple)'), ItemFactory(['Small Key (Fire Temple)'] * 8), ItemFactory(['Map (Fire Temple)', 'Compass (Fire Temple)'])) - IC = make_dungeon('Ice Cavern', ['Ice Cavern'], None, [], ItemFactory(['Map (Ice Cavern)', 'Compass (Ice Cavern)'])) - WT = make_dungeon('Water Temple', ['Water Temple Lobby', 'Water Temple Middle Water Level', 'Water Temple Dark Link Region'], ItemFactory('Boss Key (Water Temple)'), ItemFactory(['Small Key (Water Temple)'] * 6), ItemFactory(['Map (Water Temple)', 'Compass (Water Temple)'])) - ShT = make_dungeon('Shadow Temple', ['Shadow Temple Beginning', 'Shadow Temple First Beamos', 'Shadow Temple Huge Pit', 'Shadow Temple Wind Tunnel', 'Shadow Temple Beyond Boat'], ItemFactory('Boss Key (Shadow Temple)'), ItemFactory(['Small Key (Shadow Temple)'] * 5), ItemFactory(['Map (Shadow Temple)', 'Compass (Shadow Temple)'])) - GTG = make_dungeon('Gerudo Training Grounds', ['Gerudo Training Grounds Lobby', 'Gerudo Training Grounds Central Maze', 'Gerudo Training Grounds Central Maze Right', 'Gerudo Training Grounds Lava Room', 'Gerudo Training Grounds Hammer Room', 'Gerudo Training Grounds Eye Statue Lower', 'Gerudo Training Grounds Eye Statue Upper', 'Gerudo Training Grounds Heavy Block Room'], None, ItemFactory(['Small Key (Gerudo Training Grounds)'] * 9), []) - SpT = make_dungeon('Spirit Temple', ['Spirit Temple Lobby', 'Child Spirit Temple', 'Early Adult Spirit Temple', 'Spirit Temple Central Chamber', 'Spirit Temple Beyond Central Locked Door', 'Spirit Temple Beyond Final Locked Door'], ItemFactory('Boss Key (Spirit Temple)'), ItemFactory(['Small Key (Spirit Temple)'] * 5), ItemFactory(['Map (Spirit Temple)', 'Compass (Spirit Temple)'])) - GC = make_dungeon('Ganons Castle', ['Ganons Castle Lobby', 'Ganons Castle Forest Trial', 'Ganons Castle Fire Trial', 'Ganons Castle Water Trial', 'Ganons Castle Shadow Trial', 'Ganons Castle Spirit Trial', 'Ganons Castle Light Trial', 'Ganons Castle Tower'], ItemFactory('Boss Key (Ganons Castle)'), ItemFactory(['Small Key (Ganons Castle)'] * 2), []) - - - world.dungeons = [DT, DC, JB, FoT, BW, FiT, IC, WT, ShT, GTG, SpT, GC] - - -def get_dungeon_item_pool(world): - return [item for dungeon in world.dungeons for item in dungeon.all_items if item.key or world.place_dungeon_items] - -def fill_dungeons_restrictive(world, shuffled_locations): - all_state_base = world.get_all_state() - - dungeon_items = get_dungeon_item_pool(world) - - # sort in the order Boss Key, Small Key, Other before placing dungeon items - sort_order = {"BossKey": 3, "SmallKey": 2} - dungeon_items.sort(key=lambda item: sort_order.get(item.type, 1)) - - fill_restrictive(world, all_state_base, shuffled_locations, dungeon_items) - - world.state.clear_cached_unreachable() \ No newline at end of file +import random + +from BaseClasses import Dungeon +from Items import ItemFactory + + +def create_dungeons(world): + def make_dungeon(name, dungeon_regions_names, boss_key, small_keys, dungeon_items): + dungeon_regions = [world.get_region(region) for region in dungeon_regions_names] + + dungeon = Dungeon(world, name, dungeon_regions, boss_key, small_keys, dungeon_items) + for region in dungeon.regions: + region.dungeon = dungeon + return dungeon + + if world.dungeon_mq['DT']: + DT = make_dungeon( + 'Deku Tree', + ['Deku Tree Lobby', 'Deku Tree Compass Room', 'Deku Tree Boss Room'], + None, [], + ItemFactory(['Map (Deku Tree)', 'Compass (Deku Tree)'])) + else: + DT = make_dungeon( + 'Deku Tree', + ['Deku Tree Lobby', 'Deku Tree Slingshot Room', 'Deku Tree Boss Room'], + None, [], + ItemFactory(['Map (Deku Tree)', 'Compass (Deku Tree)'])) + + if world.dungeon_mq['DC']: + DC = make_dungeon( + 'Dodongos Cavern', + ['Dodongos Cavern Beginning', 'Dodongos Cavern Lobby', 'Dodongos Cavern Boss Area'], + None, [], + ItemFactory(['Map (Dodongos Cavern)', 'Compass (Dodongos Cavern)'])) + else: + DC = make_dungeon( + 'Dodongos Cavern', + ['Dodongos Cavern Beginning', 'Dodongos Cavern Lobby', 'Dodongos Cavern Climb', 'Dodongos Cavern Far Bridge', + 'Dodongos Cavern Boss Area'], + None, [], + ItemFactory(['Map (Dodongos Cavern)', 'Compass (Dodongos Cavern)'])) + + if world.dungeon_mq['JB']: + JB = make_dungeon( + 'Jabu Jabus Belly', + ['Jabu Jabus Belly Beginning', 'Jabu Jabus Belly Main', 'Jabu Jabus Belly Depths', 'Jabu Jabus Belly Boss Area'], + None, [], + ItemFactory(['Map (Jabu Jabus Belly)', 'Compass (Jabu Jabus Belly)'])) + else: + JB = make_dungeon( + 'Jabu Jabus Belly', + ['Jabu Jabus Belly Beginning', 'Jabu Jabus Belly Main', 'Jabu Jabus Belly Depths', 'Jabu Jabus Belly Boss Area'], + None, [], + ItemFactory(['Map (Jabu Jabus Belly)', 'Compass (Jabu Jabus Belly)'])) + + if world.dungeon_mq['FoT']: + FoT = make_dungeon( + 'Forest Temple', + ['Forest Temple Lobby', 'Forest Temple Central Area', 'Forest Temple After Block Puzzle', 'Forest Temple NW Outdoors', + 'Forest Temple NE Outdoors', 'Forest Temple Outdoors Top Ledges', 'Forest Temple NE Outdoors Ledge', + 'Forest Temple Bow Region', 'Forest Temple Falling Room', 'Forest Temple Boss Region'], + ItemFactory('Boss Key (Forest Temple)'), + ItemFactory(['Small Key (Forest Temple)'] * 6), + ItemFactory(['Map (Forest Temple)', 'Compass (Forest Temple)'])) + else: + FoT = make_dungeon( + 'Forest Temple', + ['Forest Temple Lobby', 'Forest Temple NW Outdoors', 'Forest Temple NE Outdoors', 'Forest Temple Falling Room', + 'Forest Temple Block Push Room', 'Forest Temple Straightened Hall', 'Forest Temple Outside Upper Ledge', + 'Forest Temple Bow Region', 'Forest Temple Boss Region'], + ItemFactory('Boss Key (Forest Temple)'), + ItemFactory(['Small Key (Forest Temple)'] * 5), + ItemFactory(['Map (Forest Temple)', 'Compass (Forest Temple)'])) + + if world.dungeon_mq['BW']: + BW = make_dungeon( + 'Bottom of the Well', + ['Bottom of the Well'], + None, + ItemFactory(['Small Key (Bottom of the Well)'] * 2), + ItemFactory(['Map (Bottom of the Well)', 'Compass (Bottom of the Well)'])) + else: + BW = make_dungeon( + 'Bottom of the Well', + ['Bottom of the Well'], + None, + ItemFactory(['Small Key (Bottom of the Well)'] * 3), + ItemFactory(['Map (Bottom of the Well)', 'Compass (Bottom of the Well)'])) + + if world.dungeon_mq['FiT']: + FiT = make_dungeon( + 'Fire Temple', + ['Fire Temple Lower', 'Fire Lower Locked Door', 'Fire Big Lava Room', 'Fire Lower Maze', 'Fire Upper Maze', + 'Fire Temple Upper', 'Fire Boss Room'], + ItemFactory('Boss Key (Fire Temple)'), + ItemFactory(['Small Key (Fire Temple)'] * 5), + ItemFactory(['Map (Fire Temple)', 'Compass (Fire Temple)'])) + else: + FiT = make_dungeon( + 'Fire Temple', + ['Fire Temple Lower', 'Fire Temple Middle', 'Fire Temple Upper'], + ItemFactory('Boss Key (Fire Temple)'), + ItemFactory(['Small Key (Fire Temple)'] * 8), + ItemFactory(['Map (Fire Temple)', 'Compass (Fire Temple)'])) + + # Ice Cavern is built identically in vanilla and MQ + IC = make_dungeon( + 'Ice Cavern', + ['Ice Cavern'], + None, [], + ItemFactory(['Map (Ice Cavern)', 'Compass (Ice Cavern)'])) + + if world.dungeon_mq['WT']: + WT = make_dungeon( + 'Water Temple', + ['Water Temple Lobby', 'Water Temple Lowered Water Levels', 'Water Temple Dark Link Region', + 'Water Temple Basement Gated Areas'], + ItemFactory('Boss Key (Water Temple)'), + ItemFactory(['Small Key (Water Temple)'] * 2), + ItemFactory(['Map (Water Temple)', 'Compass (Water Temple)'])) + else: + WT = make_dungeon( + 'Water Temple', + ['Water Temple Lobby', 'Water Temple Middle Water Level', 'Water Temple Dark Link Region'], + ItemFactory('Boss Key (Water Temple)'), + ItemFactory(['Small Key (Water Temple)'] * 6), + ItemFactory(['Map (Water Temple)', 'Compass (Water Temple)'])) + + if world.dungeon_mq['ShT']: + ShT = make_dungeon( + 'Shadow Temple', + ['Shadow Temple Beginning', 'Shadow Temple Dead Hand Area', 'Shadow Temple First Beamos', 'Shadow Temple Huge Pit', + 'Shadow Temple Wind Tunnel', 'Shadow Temple Beyond Boat', 'Shadow Temple Invisible Maze'], + ItemFactory('Boss Key (Shadow Temple)'), + ItemFactory(['Small Key (Shadow Temple)'] * 6), + ItemFactory(['Map (Shadow Temple)', 'Compass (Shadow Temple)'])) + else: + ShT = make_dungeon( + 'Shadow Temple', + ['Shadow Temple Beginning', 'Shadow Temple First Beamos', 'Shadow Temple Huge Pit', 'Shadow Temple Wind Tunnel', + 'Shadow Temple Beyond Boat'], + ItemFactory('Boss Key (Shadow Temple)'), + ItemFactory(['Small Key (Shadow Temple)'] * 5), + ItemFactory(['Map (Shadow Temple)', 'Compass (Shadow Temple)'])) + + if world.dungeon_mq['GTG']: + GTG = make_dungeon( + 'Gerudo Training Grounds', + ['Gerudo Training Grounds Lobby', 'Gerudo Training Grounds Right Side', + 'Gerudo Training Grounds Left Side', 'Gerudo Training Grounds Stalfos Room', + 'Gerudo Training Grounds Back Areas', 'Gerudo Training Grounds Central Maze Right'], + None, + ItemFactory(['Small Key (Gerudo Training Grounds)'] * 3), + []) + else: + GTG = make_dungeon( + 'Gerudo Training Grounds', + ['Gerudo Training Grounds Lobby', 'Gerudo Training Grounds Central Maze', + 'Gerudo Training Grounds Central Maze Right', 'Gerudo Training Grounds Lava Room', + 'Gerudo Training Grounds Hammer Room', 'Gerudo Training Grounds Eye Statue Lower', + 'Gerudo Training Grounds Eye Statue Upper', 'Gerudo Training Grounds Heavy Block Room'], + None, + ItemFactory(['Small Key (Gerudo Training Grounds)'] * 9), + []) + + if world.dungeon_mq['SpT']: + SpT = make_dungeon( + 'Spirit Temple', + ['Spirit Temple Lobby', 'Child Spirit Temple', 'Adult Spirit Temple', 'Spirit Temple Shared', + 'Lower Adult Spirit Temple', 'Spirit Temple Boss Area'], + ItemFactory('Boss Key (Spirit Temple)'), + ItemFactory(['Small Key (Spirit Temple)'] * 7), + ItemFactory(['Map (Spirit Temple)', 'Compass (Spirit Temple)'])) + else: + SpT = make_dungeon( + 'Spirit Temple', + ['Spirit Temple Lobby', 'Child Spirit Temple', 'Child Spirit Temple Climb', 'Early Adult Spirit Temple', + 'Spirit Temple Central Chamber', 'Spirit Temple Beyond Central Locked Door', 'Spirit Temple Beyond Final Locked Door'], + ItemFactory('Boss Key (Spirit Temple)'), + ItemFactory(['Small Key (Spirit Temple)'] * 5), + ItemFactory(['Map (Spirit Temple)', 'Compass (Spirit Temple)'])) + + if world.dungeon_mq['GC']: + GC = make_dungeon( + 'Ganons Castle', + ['Ganons Castle Lobby', 'Ganons Castle Forest Trial', 'Ganons Castle Fire Trial', 'Ganons Castle Water Trial', + 'Ganons Castle Shadow Trial', 'Ganons Castle Spirit Trial', 'Ganons Castle Light Trial', 'Ganons Castle Tower', + 'Ganons Castle Deku Scrubs'], + ItemFactory('Boss Key (Ganons Castle)'), + ItemFactory(['Small Key (Ganons Castle)'] * 3), + []) + else: + GC = make_dungeon( + 'Ganons Castle', + ['Ganons Castle Lobby', 'Ganons Castle Forest Trial', 'Ganons Castle Fire Trial', 'Ganons Castle Water Trial', + 'Ganons Castle Shadow Trial', 'Ganons Castle Spirit Trial', 'Ganons Castle Light Trial', 'Ganons Castle Tower', + 'Ganons Castle Deku Scrubs'], + ItemFactory('Boss Key (Ganons Castle)'), + ItemFactory(['Small Key (Ganons Castle)'] * 2), + []) + + world.dungeons = [DT, DC, JB, FoT, BW, FiT, IC, WT, ShT, GTG, SpT, GC] diff --git a/EntranceShuffle.py b/EntranceShuffle.py index b1f86c8e6..c117ba20b 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -1,329 +1,488 @@ -import random - -def link_entrances(world): - - # setup mandatory connections - for exitname, regionname in mandatory_connections: - connect_simple(world, exitname, regionname) - - # if we do not shuffle, set default connections - if world.shuffle == 'vanilla': - for exitname, regionname in default_connections: - connect_simple(world, exitname, regionname) - for exitname, regionname in default_dungeon_connections: - connect_simple(world, exitname, regionname) - else: - raise NotImplementedError('Shuffling not supported yet') - - -def connect_simple(world, exitname, regionname): - world.get_entrance(exitname).connect(world.get_region(regionname)) - -def connect_entrance(world, entrancename, exitname): - entrance = world.get_entrance(entrancename) - # check if we got an entrance or a region to connect to - try: - region = world.get_region(exitname) - exit = None - except RuntimeError: - exit = world.get_entrance(exitname) - region = exit.parent_region - - # if this was already connected somewhere, remove the backreference - if entrance.connected_region is not None: - entrance.connected_region.entrances.remove(entrance) - - target = exit_ids[exit.name][0] if exit is not None else exit_ids.get(region.name, None) - addresses = door_addresses[entrance.name][0] - - entrance.connect(region, addresses, target) - world.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance') - - -def connect_exit(world, exitname, entrancename): - entrance = world.get_entrance(entrancename) - exit = world.get_entrance(exitname) - - # if this was already connected somewhere, remove the backreference - if exit.connected_region is not None: - exit.connected_region.entrances.remove(exit) - - exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1]) - world.spoiler.set_entrance(entrance.name, exit.name, 'exit') - - -def connect_random(world, exitlist, targetlist, two_way=False): - targetlist = list(targetlist) - random.shuffle(targetlist) - - for exit, target in zip(exitlist, targetlist): - if two_way: - connect_two_way(world, exit, target) - else: - connect_entrance(world, exit, target) - - -def connect_doors(world, doors, targets): - """This works inplace""" - random.shuffle(doors) - random.shuffle(targets) - while doors: - door = doors.pop() - target = targets.pop() - connect_entrance(world, door, target) - -# these are connections that cannot be shuffled and always exist. They link together separate parts of the world we need to divide into regions -mandatory_connections = [('Adult Forest Warp Pad', 'Forest Temple Entry Area'), - ('Child Forest Warp Pad', 'Sacred Forest Meadow'), - ('Temple Warp Pad', 'Temple of Time'), - ('Crater Warp Pad', 'Death Mountain Crater Central'), - ('Lake Warp Pad', 'Lake Hylia'), - ('Graveyard Warp Pad', 'Shadow Temple Warp Region'), - ('Colossus Warp Pad', 'Desert Colossus'), - ('Lost Woods', 'Lost Woods'), - ('Lost Woods Front', 'Kokiri Forest'), - ('Woods to Goron City', 'Goron City Woods Warp'), - ('Goron City to Woods', 'Lost Woods'), - ('Goron City from Woods', 'Goron City'), - ('Goron City Bomb Wall', 'Goron City Woods Warp'), - ('Lost Woods Dive Warp', 'Zora River Top'), - ('Zora River Dive Warp', 'Lost Woods'), - ('Meadow Entrance', 'Sacred Forest Meadow Entryway'), - ('Meadow Exit', 'Lost Woods'), - ('Meadow Gate', 'Sacred Forest Meadow'), - ('Meadow Gate Exit', 'Sacred Forest Meadow Entryway'), - ('Adult Meadow Access', 'Forest Temple Entry Area'), - ('Adult Meadow Exit', 'Lost Woods'), - ('Lost Woods Bridge', 'Lost Woods Bridge'), - ('Kokiri Forest Entrance', 'Kokiri Forest'), - ('Field to Forest', 'Lost Woods Bridge'), - ('Forest Exit', 'Hyrule Field'), - ('Field to Lake', 'Lake Hylia'), - ('Lake Hylia Dive Warp', 'Zoras Domain'), - ('Zoras Domain Dive Warp', 'Lake Hylia'), - ('Lake Exit', 'Hyrule Field'), - ('Field to Valley', 'Gerudo Valley'), - ('Valley Exit', 'Hyrule Field'), - ('Valley River', 'Lake Hylia'), - ('Bridge Crossing', 'Gerudo Valley Far Side'), - ('Fortress Entrance', 'Gerudo Fortress'), - ('Haunted Wasteland Entrance', 'Haunted Wasteland'), - ('Haunted Wasteland Crossing', 'Desert Colossus'), - ('Field to Castle Town', 'Castle Town'), - ('Castle Town Exit', 'Hyrule Field'), - ('Hyrule Castle Grounds', 'Hyrule Castle Grounds'), - ('Hyrule Castle Grounds Exit', 'Castle Town'), - ('Hyrule Castle Garden', 'Hyrule Castle Garden'), - ('Hyrule Castle Garden Exit', 'Hyrule Castle Grounds'), - ('Ganons Castle Grounds', 'Ganons Castle Grounds'), - ('Ganons Castle Grounds Exit', 'Castle Town'), - ('Field to Kakariko', 'Kakariko Village'), - ('Kakariko Exit', 'Hyrule Field'), - ('Graveyard Entrance', 'Graveyard'), - ('Graveyard Exit', 'Kakariko Village'), - ('Drop to Graveyard', 'Graveyard'), - ('Death Mountain Entrance', 'Death Mountain'), - ('Death Mountain Exit', 'Kakariko Village'), - ('Goron City Entrance', 'Goron City'), - ('Goron City Exit', 'Death Mountain'), - ('Darunias Chamber', 'Darunias Chamber'), - ('Darunias Chamber Exit', 'Goron City'), - ('Mountain Crater Entrance', 'Death Mountain Crater Upper'), - ('Crater Exit', 'Death Mountain'), - ('Crater Hover Boots', 'Death Mountain Crater Lower'), - ('Crater Ascent', 'Death Mountain Crater Upper'), - ('Crater Scarecrow', 'Death Mountain Crater Central'), - ('Crater Bridge', 'Death Mountain Crater Central'), - ('Crater Bridge Reverse', 'Death Mountain Crater Lower'), - ('Crater to City', 'Goron City'), - ('Crater Access', 'Death Mountain Crater Lower'), - ('Dodongos Cavern Rocks', 'Dodongos Cavern Entryway'), - ('Mountain Access from Behind Rock', 'Death Mountain'), - ('Field to Zora River', 'Zora River Bottom'), - ('Zora River Exit', 'Hyrule Field'), - ('Zora River Rocks', 'Zora River Top'), - ('Zora River Downstream', 'Zora River Bottom'), - ('Zora River Waterfall', 'Zoras Domain'), - ('Zoras Domain Exit', 'Zora River Top'), - ('Behind King Zora', 'Zoras Fountain'), - ('Zoras Fountain Exit', 'Zoras Domain'), - ('Zora River Adult', 'Zora River Adult'), - ('Zoras Domain Adult Access', 'Zoras Domain Frozen'), - ('Zoras Fountain Adult Access', 'Outside Ice Cavern'), - ('Lon Lon Rance Entrance', 'Lon Lon Ranch'), - ('Lon Lon Exit', 'Hyrule Field'), - ('Deku Tree Slingshot Passage', 'Deku Tree Slingshot Room'), - ('Deku Tree Slingshot Exit', 'Deku Tree Lobby'), - ('Deku Tree Basement Path', 'Deku Tree Boss Room'), - ('Deku Tree Basement Vines', 'Deku Tree Lobby'), - ('Dodongos Cavern Lobby', 'Dodongos Cavern Lobby'), - ('Dodongos Cavern Retreat', 'Dodongos Cavern Beginning'), - ('Dodongos Cavern Left Door', 'Dodongos Cavern Climb'), - ('Dodongos Cavern Bridge Fall', 'Dodongos Cavern Lobby'), - ('Dodongos Cavern Slingshot Target', 'Dodongos Cavern Far Bridge'), - ('Dodongos Cavern Bridge Fall 2', 'Dodongos Cavern Lobby'), - ('Dodongos Cavern Bomb Drop', 'Dodongos Cavern Boss Area'), - ('Dodongos Cavern Exit Skull', 'Dodongos Cavern Lobby'), - ('Jabu Jabus Belly Ceiling Switch', 'Jabu Jabus Belly Main'), - ('Jabu Jabus Belly Retreat', 'Jabu Jabus Belly Beginning'), - ('Jabu Jabus Belly Tentacles', 'Jabu Jabus Belly Depths'), - ('Jabu Jabus Belly Elevator', 'Jabu Jabus Belly Main'), - ('Jabu Jabus Belly Octopus', 'Jabu Jabus Belly Boss Area'), - ('Jabu Jabus Belly Final Backtrack', 'Jabu Jabus Belly Main'), - ('Forest Temple Song of Time Block', 'Forest Temple NW Outdoors'), - ('Forest Temple Lobby Eyeball Switch', 'Forest Temple NE Outdoors'), - ('Forest Temple Lobby Locked Door', 'Forest Temple Block Push Room'), - ('Forest Temple Through Map Room', 'Forest Temple NE Outdoors'), - ('Forest Temple Well Connection', 'Forest Temple NW Outdoors'), - ('Forest Temple Outside to Lobby', 'Forest Temple Lobby'), - ('Forest Temple Scarecrows Song', 'Forest Temple Falling Room'), - ('Forest Temple Falling Room Exit', 'Forest Temple NE Outdoors'), - ('Forest Temple Elevator', 'Forest Temple Boss Region'), - ('Forest Temple Outside Backdoor', 'Forest Temple Outside Upper Ledge'), - ('Forest Temple Twisted Hall', 'Forest Temple Bow Region'), - ('Forest Temple Straightened Hall', 'Forest Temple Straightened Hall'), - ('Forest Temple Boss Key Chest Drop', 'Forest Temple Outside Upper Ledge'), - ('Forest Temple Outside Ledge Drop', 'Forest Temple NW Outdoors'), - ('Forest Temple Drop to Falling Room', 'Forest Temple Falling Room'), - ('Fire Temple Early Climb', 'Fire Temple Middle'), - ('Fire Temple Fire Maze Escape', 'Fire Temple Upper'), - ('Water Temple Central Pillar', 'Water Temple Middle Water Level'), - ('Water Temple Upper Locked Door', 'Water Temple Dark Link Region'), - ('Shadow Temple First Pit', 'Shadow Temple First Beamos'), - ('Shadow Temple Bomb Wall', 'Shadow Temple Huge Pit'), - ('Shadow Temple Hookshot Target', 'Shadow Temple Wind Tunnel'), - ('Shadow Temple Boat', 'Shadow Temple Beyond Boat'), - ('Gerudo Training Ground Left Silver Rupees', 'Gerudo Training Grounds Heavy Block Room'), - ('Gerudo Training Ground Beamos', 'Gerudo Training Grounds Lava Room'), - ('Gerudo Training Ground Central Door', 'Gerudo Training Grounds Central Maze'), - ('Gerudo Training Grounds Right Locked Doors', 'Gerudo Training Grounds Central Maze Right'), - ('Gerudo Training Grounds Maze Exit', 'Gerudo Training Grounds Lava Room'), - ('Gerudo Training Grounds Maze Ledge', 'Gerudo Training Grounds Central Maze Right'), - ('Gerudo Training Grounds Right Hookshot Target', 'Gerudo Training Grounds Hammer Room'), - ('Gerudo Training Grounds Hammer Target', 'Gerudo Training Grounds Eye Statue Lower'), - ('Gerudo Training Grounds Hammer Room Clear', 'Gerudo Training Grounds Lava Room'), - ('Gerudo Training Grounds Eye Statue Exit', 'Gerudo Training Grounds Hammer Room'), - ('Gerudo Training Grounds Eye Statue Drop', 'Gerudo Training Grounds Eye Statue Lower'), - ('Gerudo Training Grounds Hidden Hookshot Target', 'Gerudo Training Grounds Eye Statue Upper'), - ('Spirit Temple Crawl Passage', 'Child Spirit Temple'), - ('Spirit Temple Silver Block', 'Early Adult Spirit Temple'), - ('Child Spirit Temple Passthrough', 'Spirit Temple Central Chamber'), - ('Adult Spirit Temple Passthrough', 'Spirit Temple Central Chamber'), - ('Spirit Temple to Hands', 'Spirit Temple Outdoor Hands'), - ('Spirit Temple Central Locked Door', 'Spirit Temple Beyond Central Locked Door'), - ('Spirit Temple Final Locked Door', 'Spirit Temple Beyond Final Locked Door'), - ('Ganons Castle Forest Trial', 'Ganons Castle Forest Trial'), - ('Ganons Castle Fire Trial', 'Ganons Castle Fire Trial'), - ('Ganons Castle Water Trial', 'Ganons Castle Water Trial'), - ('Ganons Castle Shadow Trial', 'Ganons Castle Shadow Trial'), - ('Ganons Castle Spirit Trial', 'Ganons Castle Spirit Trial'), - ('Ganons Castle Light Trial', 'Ganons Castle Light Trial'), - ('Ganons Castle Tower', 'Ganons Castle Tower') - ] - -# non-shuffled entrance links -default_connections = [('Links House Exit', 'Kokiri Forest'), - ('Links House', 'Links House'), - ('Mido House Exit', 'Kokiri Forest'), - ('Mido House', 'Mido House'), - ('Saria House Exit', 'Kokiri Forest'), - ('Saria House', 'Saria House'), - ('House of Twins Exit', 'Kokiri Forest'), - ('House of Twins', 'House of Twins'), - ('Know It All House Exit', 'Kokiri Forest'), - ('Know It All House', 'Know It All House'), - ('Kokiri Shop Exit', 'Kokiri Forest'), - ('Kokiri Shop', 'Kokiri Shop'), - ('Lake Hylia Lab', 'Lake Hylia Lab'), - ('Fishing Hole', 'Fishing Hole'), - ('Colossus Fairy', 'Colossus Fairy'), - ('Temple of Time', 'Temple of Time'), - ('Temple of Time Exit', 'Castle Town'), - ('Door of Time', 'Beyond Door of Time'), - ('Emerge as Adult', 'Temple of Time'), - ('Hyrule Castle Fairy', 'Hyrule Castle Fairy'), - ('Ganons Castle Fairy', 'Ganons Castle Fairy'), - ('Castle Town Rupee Room', 'Castle Town Rupee Room'), - ('Castle Town Bazaar', 'Castle Town Bazaar'), - ('Castle Town Mask Shop', 'Castle Town Mask Shop'), - ('Castle Town Shooting Gallery', 'Castle Town Shooting Gallery'), - ('Castle Town Bombchu Bowling', 'Castle Town Bombchu Bowling'), - ('Castle Town Potion Shop', 'Castle Town Potion Shop'), - ('Castle Town Treasure Chest Game', 'Castle Town Treasure Chest Game'), - ('Castle Town Bombchu Shop', 'Castle Town Bombchu Shop'), - ('Castle Town Dog Lady', 'Castle Town Dog Lady'), - ('Castle Town Man in Green House', 'Castle Town Man in Green House'), - ('Carpenter Boss House', 'Carpenter Boss House'), - ('House of Skulltulla', 'House of Skulltulla'), - ('Impas House', 'Impas House'), - ('Impas House Back', 'Impas House Back'), - ('Windmill', 'Windmill'), - ('Kakariko Bazaar', 'Kakariko Bazaar'), - ('Kakariko Shooting Gallery', 'Kakariko Shooting Gallery'), - ('Kakariko Potion Shop Front', 'Kakariko Potion Shop Front'), - ('Kakariko Potion Shop Back', 'Kakariko Potion Shop Back'), - ('Odd Medicine Building', 'Odd Medicine Building'), - ('Shield Grave', 'Shield Grave'), - ('Heart Piece Grave', 'Heart Piece Grave'), - ('Composer Grave', 'Composer Grave'), - ('Dampes Grave', 'Dampes Grave'), - ('Crater Fairy', 'Crater Fairy'), - ('Mountain Summit Fairy', 'Mountain Summit Fairy'), - ('Dampes House', 'Dampes House'), - ('Talon House', 'Talon House'), - ('Ingo Barn', 'Ingo Barn'), - ('Lon Lon Corner Tower', 'Lon Lon Corner Tower'), - ('Zora Shop', 'Zora Shop'), - ('Zoras Fountain Fairy', 'Zoras Fountain Fairy'), - ('Kokiri Forest Storms Grotto', 'Kokiri Forest Storms Grotto'), - ('Lost Woods Generic Grotto', 'Lost Woods Generic Grotto'), - ('Deku Theater', 'Deku Theater'), - ('Lost Woods Sales Grotto', 'Lost Woods Sales Grotto'), - ('Meadow Fairy Grotto', 'Meadow Fairy Grotto'), - ('Front of Meadow Grotto', 'Front of Meadow Grotto'), - ('Lon Lon Grotto', 'Lon Lon Grotto'), - ('Remote Southern Grotto', 'Remote Southern Grotto'), - ('Field Near Lake Outside Fence Grotto', 'Field Near Lake Outside Fence Grotto'), - ('Field Near Lake Inside Fence Grotto', 'Field Near Lake Inside Fence Grotto'), - ('Field Valley Grotto', 'Field Valley Grotto'), - ('Field West Castle Town Grotto', 'Field West Castle Town Grotto'), - ('Field Far West Castle Town Grotto', 'Field Far West Castle Town Grotto'), - ('Field Kakariko Grotto', 'Field Kakariko Grotto'), - ('Kakariko Bombable Grotto', 'Kakariko Bombable Grotto'), - ('Kakariko Back Grotto', 'Kakariko Back Grotto'), - ('Mountain Bombable Grotto', 'Mountain Bombable Grotto'), - ('Mountain Storms Grotto', 'Mountain Storms Grotto'), - ('Top of Crater Grotto', 'Top of Crater Grotto'), - ('Field North Lon Lon Grotto', 'Field North Lon Lon Grotto'), - ('Castle Storms Grotto', 'Castle Storms Grotto'), - ('Zora River Plateau Open Grotto', 'Zora River Plateau Open Grotto'), - ('Zora River Plateau Bombable Grotto', 'Zora River Plateau Bombable Grotto'), - ('Lake Hylia Grotto', 'Lake Hylia Grotto') - ] - -# non shuffled dungeons -default_dungeon_connections = [('Deku Tree', 'Deku Tree Lobby'), - ('Deku Tree Exit', 'Kokiri Forest'), - ('Dodongos Cavern', 'Dodongos Cavern Beginning'), - ('Dodongos Cavern Exit', 'Dodongos Cavern Entryway'), - ('Jabu Jabus Belly', 'Jabu Jabus Belly Beginning'), - ('Jabu Jabus Belly Exit', 'Zoras Fountain'), - ('Forest Temple Entrance', 'Forest Temple Lobby'), - ('Forest Temple Exit', 'Forest Temple Entry Area'), - ('Bottom of the Well', 'Bottom of the Well'), - ('Bottom of the Well Exit', 'Kakariko Village'), - ('Fire Temple Entrance', 'Fire Temple Lower'), - ('Fire Temple Exit', 'Death Mountain Crater Central'), - ('Ice Cavern Entrance', 'Ice Cavern'), - ('Ice Cavern Exit', 'Outside Ice Cavern'), - ('Water Temple Entrance', 'Water Temple Lobby'), - ('Water Temple Exit', 'Lake Hylia'), - ('Shadow Temple Entrance', 'Shadow Temple Beginning'), - ('Shadow Temple Exit', 'Shadow Temple Warp Region'), - ('Gerudo Training Grounds Entrance', 'Gerudo Training Grounds Lobby'), - ('Gerudo Training Grounds Exit', 'Gerudo Fortress'), - ('Spirit Temple Entrance', 'Spirit Temple Lobby'), - ('Spirit Temple Exit', 'Desert Colossus'), - ('Rainbow Bridge', 'Ganons Castle Lobby'), - ('Ganons Castle Exit', 'Ganons Castle Grounds') - ] +import random + +def link_entrances(world): + + # setup mandatory connections + for exitname, regionname in mandatory_connections: + connect_simple(world, exitname, regionname) + if world.dungeon_mq['DT']: + for exitname, regionname in DT_MQ_connections: + connect_simple(world, exitname, regionname) + else: + for exitname, regionname in DT_vanilla_connections: + connect_simple(world, exitname, regionname) + if world.dungeon_mq['DC']: + for exitname, regionname in DC_MQ_connections: + connect_simple(world, exitname, regionname) + else: + for exitname, regionname in DC_vanilla_connections: + connect_simple(world, exitname, regionname) + if world.dungeon_mq['JB']: + for exitname, regionname in JB_MQ_connections: + connect_simple(world, exitname, regionname) + else: + for exitname, regionname in JB_vanilla_connections: + connect_simple(world, exitname, regionname) + if world.dungeon_mq['FoT']: + for exitname, regionname in FoT_MQ_connections: + connect_simple(world, exitname, regionname) + else: + for exitname, regionname in FoT_vanilla_connections: + connect_simple(world, exitname, regionname) + if world.dungeon_mq['FiT']: + for exitname, regionname in FiT_MQ_connections: + connect_simple(world, exitname, regionname) + else: + for exitname, regionname in FiT_vanilla_connections: + connect_simple(world, exitname, regionname) + if world.dungeon_mq['WT']: + for exitname, regionname in WT_MQ_connections: + connect_simple(world, exitname, regionname) + else: + for exitname, regionname in WT_vanilla_connections: + connect_simple(world, exitname, regionname) + if world.dungeon_mq['GTG']: + for exitname, regionname in GTG_MQ_connections: + connect_simple(world, exitname, regionname) + else: + for exitname, regionname in GTG_vanilla_connections: + connect_simple(world, exitname, regionname) + if world.dungeon_mq['SpT']: + for exitname, regionname in SpT_MQ_connections: + connect_simple(world, exitname, regionname) + else: + for exitname, regionname in SpT_vanilla_connections: + connect_simple(world, exitname, regionname) + if world.dungeon_mq['ShT']: + for exitname, regionname in ShT_MQ_connections: + connect_simple(world, exitname, regionname) + else: + for exitname, regionname in ShT_vanilla_connections: + connect_simple(world, exitname, regionname) + # if we do not shuffle, set default connections + if world.shuffle == 'vanilla': + for exitname, regionname in default_connections: + connect_simple(world, exitname, regionname) + for exitname, regionname in default_dungeon_connections: + connect_simple(world, exitname, regionname) + else: + raise NotImplementedError('Shuffling not supported yet') + + +def connect_simple(world, exitname, regionname): + world.get_entrance(exitname).connect(world.get_region(regionname)) + +def connect_entrance(world, entrancename, exitname): + entrance = world.get_entrance(entrancename) + # check if we got an entrance or a region to connect to + try: + region = world.get_region(exitname) + exit = None + except RuntimeError: + exit = world.get_entrance(exitname) + region = exit.parent_region + + # if this was already connected somewhere, remove the backreference + if entrance.connected_region is not None: + entrance.connected_region.entrances.remove(entrance) + + target = exit_ids[exit.name][0] if exit is not None else exit_ids.get(region.name, None) + addresses = door_addresses[entrance.name][0] + + entrance.connect(region, addresses, target) + + +def connect_exit(world, exitname, entrancename): + entrance = world.get_entrance(entrancename) + exit = world.get_entrance(exitname) + + # if this was already connected somewhere, remove the backreference + if exit.connected_region is not None: + exit.connected_region.entrances.remove(exit) + + exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1]) + + +def connect_random(world, exitlist, targetlist, two_way=False): + targetlist = list(targetlist) + random.shuffle(targetlist) + + for exit, target in zip(exitlist, targetlist): + if two_way: + connect_two_way(world, exit, target) + else: + connect_entrance(world, exit, target) + + +def connect_doors(world, doors, targets): + """This works inplace""" + random.shuffle(doors) + random.shuffle(targets) + while doors: + door = doors.pop() + target = targets.pop() + connect_entrance(world, door, target) + +# these are connections that cannot be shuffled and always exist. They link together separate parts of the world we need to divide into regions +mandatory_connections = [('Adult Forest Warp Pad', 'Forest Temple Entry Area'), + ('Child Forest Warp Pad', 'Sacred Forest Meadow'), + ('Temple Warp Pad', 'Temple of Time'), + ('Crater Warp Pad', 'Death Mountain Crater Central'), + ('Lake Warp Pad', 'Lake Hylia'), + ('Graveyard Warp Pad', 'Shadow Temple Warp Region'), + ('Colossus Warp Pad', 'Desert Colossus'), + ('Lost Woods', 'Lost Woods'), + ('Lost Woods Front', 'Kokiri Forest'), + ('Woods to Goron City', 'Goron City Woods Warp'), + ('Goron City to Woods', 'Lost Woods'), + ('Goron City from Woods', 'Goron City'), + ('Goron City Bomb Wall', 'Goron City Woods Warp'), + ('Lost Woods Dive Warp', 'Zora River Child'), + ('Zora River Dive Warp', 'Lost Woods'), + ('Meadow Entrance', 'Sacred Forest Meadow Entryway'), + ('Meadow Exit', 'Lost Woods'), + ('Meadow Gate', 'Sacred Forest Meadow'), + ('Meadow Gate Exit', 'Sacred Forest Meadow Entryway'), + ('Adult Meadow Access', 'Forest Temple Entry Area'), + ('Adult Meadow Exit', 'Lost Woods'), + ('Lost Woods Bridge', 'Lost Woods Bridge'), + ('Kokiri Forest Entrance', 'Kokiri Forest'), + ('Field to Forest', 'Lost Woods Bridge'), + ('Forest Exit', 'Hyrule Field'), + ('Field to Lake', 'Lake Hylia'), + ('Lake Hylia Dive Warp', 'Zoras Domain'), + ('Zoras Domain Dive Warp', 'Lake Hylia'), + ('Lake Exit', 'Hyrule Field'), + ('Field to Valley', 'Gerudo Valley'), + ('Valley Exit', 'Hyrule Field'), + ('Valley River', 'Lake Hylia'), + ('Bridge Crossing', 'Gerudo Valley Far Side'), + ('Fortress Entrance', 'Gerudo Fortress'), + ('Haunted Wasteland Entrance', 'Haunted Wasteland'), + ('Haunted Wasteland Crossing', 'Desert Colossus'), + ('Field to Castle Town', 'Castle Town'), + ('Castle Town Exit', 'Hyrule Field'), + ('Hyrule Castle Grounds', 'Hyrule Castle Grounds'), + ('Hyrule Castle Grounds Exit', 'Castle Town'), + ('Hyrule Castle Garden', 'Hyrule Castle Garden'), + ('Hyrule Castle Garden Exit', 'Hyrule Castle Grounds'), + ('Ganons Castle Grounds', 'Ganons Castle Grounds'), + ('Ganons Castle Grounds Exit', 'Castle Town'), + ('Field to Kakariko', 'Kakariko Village'), + ('Kakariko Exit', 'Hyrule Field'), + ('Graveyard Entrance', 'Graveyard'), + ('Graveyard Exit', 'Kakariko Village'), + ('Drop to Graveyard', 'Graveyard'), + ('Death Mountain Entrance', 'Death Mountain'), + ('Death Mountain Exit', 'Kakariko Village'), + ('Goron City Entrance', 'Goron City'), + ('Goron City Exit', 'Death Mountain'), + ('Darunias Chamber', 'Darunias Chamber'), + ('Darunias Chamber Exit', 'Goron City'), + ('Mountain Crater Entrance', 'Death Mountain Crater Upper'), + ('Crater Exit', 'Death Mountain'), + ('Crater Hover Boots', 'Death Mountain Crater Lower'), + ('Crater Ascent', 'Death Mountain Crater Upper'), + ('Crater Scarecrow', 'Death Mountain Crater Central'), + ('Crater Bridge', 'Death Mountain Crater Central'), + ('Crater Bridge Reverse', 'Death Mountain Crater Lower'), + ('Crater to City', 'Goron City'), + ('Crater Access', 'Death Mountain Crater Lower'), + ('Dodongos Cavern Rocks', 'Dodongos Cavern Entryway'), + ('Mountain Access from Behind Rock', 'Death Mountain'), + ('Field to Zora River', 'Zora River Front'), + ('Zora River Exit', 'Hyrule Field'), + ('Zora River Rocks', 'Zora River Child'), + ('Zora River Downstream', 'Zora River Front'), + ('Zora River Child to Shared', 'Zora River Shared'), + ('Zora River Adult to Shared', 'Zora River Shared'), + ('Zora River Waterfall', 'Zoras Domain'), + ('Zoras Domain Exit', 'Zora River Child'), + ('Behind King Zora', 'Zoras Fountain'), + ('Zoras Fountain Exit', 'Zoras Domain'), + ('Zora River Adult', 'Zora River Adult'), + ('Zoras Domain Adult Access', 'Zoras Domain Frozen'), + ('Zoras Fountain Adult Access', 'Outside Ice Cavern'), + ('Lon Lon Rance Entrance', 'Lon Lon Ranch'), + ('Lon Lon Exit', 'Hyrule Field'), + ('Ganons Castle Deku Scrubs', 'Ganons Castle Deku Scrubs'), + ('Ganons Castle Forest Trial', 'Ganons Castle Forest Trial'), + ('Ganons Castle Fire Trial', 'Ganons Castle Fire Trial'), + ('Ganons Castle Water Trial', 'Ganons Castle Water Trial'), + ('Ganons Castle Shadow Trial', 'Ganons Castle Shadow Trial'), + ('Ganons Castle Spirit Trial', 'Ganons Castle Spirit Trial'), + ('Ganons Castle Light Trial', 'Ganons Castle Light Trial'), + ('Ganons Castle Tower', 'Ganons Castle Tower') + ] + +DT_vanilla_connections = [('Deku Tree Slingshot Passage', 'Deku Tree Slingshot Room'), + ('Deku Tree Slingshot Exit', 'Deku Tree Lobby'), + ('Deku Tree Basement Path', 'Deku Tree Boss Room'), + ('Deku Tree Basement Vines', 'Deku Tree Lobby') + ] + +DT_MQ_connections = [('Deku Tree Compass Passage', 'Deku Tree Compass Room'), + ('Deku Tree Compass Exit', 'Deku Tree Lobby'), + ('Deku Tree Basement Path', 'Deku Tree Boss Room'), + ('Deku Tree Basement Vines', 'Deku Tree Lobby') + ] + +DC_vanilla_connections = [('Dodongos Cavern Lobby', 'Dodongos Cavern Lobby'), + ('Dodongos Cavern Retreat', 'Dodongos Cavern Beginning'), + ('Dodongos Cavern Left Door', 'Dodongos Cavern Climb'), + ('Dodongos Cavern Bridge Fall', 'Dodongos Cavern Lobby'), + ('Dodongos Cavern Slingshot Target', 'Dodongos Cavern Far Bridge'), + ('Dodongos Cavern Bridge Fall 2', 'Dodongos Cavern Lobby'), + ('Dodongos Cavern Bomb Drop', 'Dodongos Cavern Boss Area'), + ('Dodongos Cavern Exit Skull', 'Dodongos Cavern Lobby') + ] + +DC_MQ_connections = [('Dodongos Cavern Lobby', 'Dodongos Cavern Lobby'), + ('Dodongos Cavern Bomb Drop', 'Dodongos Cavern Boss Area') + ] + +JB_vanilla_connections = [('Jabu Jabus Belly Ceiling Switch', 'Jabu Jabus Belly Main'), + ('Jabu Jabus Belly Retreat', 'Jabu Jabus Belly Beginning'), + ('Jabu Jabus Belly Tentacles', 'Jabu Jabus Belly Depths'), + ('Jabu Jabus Belly Elevator', 'Jabu Jabus Belly Main'), + ('Jabu Jabus Belly Octopus', 'Jabu Jabus Belly Boss Area'), + ('Jabu Jabus Belly Final Backtrack', 'Jabu Jabus Belly Main') + ] + +JB_MQ_connections = [('Jabu Jabus Belly Cow Switch', 'Jabu Jabus Belly Main'), + ('Jabu Jabus Belly Retreat', 'Jabu Jabus Belly Beginning'), + ('Jabu Jabus Belly Tentacle Access', 'Jabu Jabus Belly Depths'), + ('Jabu Jabus Belly Elevator', 'Jabu Jabus Belly Main'), + ('Jabu Jabus Belly Octopus', 'Jabu Jabus Belly Boss Area'), + ('Jabu Jabus Belly Final Backtrack', 'Jabu Jabus Belly Main') + ] + +FoT_vanilla_connections = [('Forest Temple Song of Time Block', 'Forest Temple NW Outdoors'), + ('Forest Temple Lobby Eyeball Switch', 'Forest Temple NE Outdoors'), + ('Forest Temple Lobby Locked Door', 'Forest Temple Block Push Room'), + ('Forest Temple Through Map Room', 'Forest Temple NE Outdoors'), + ('Forest Temple Well Connection', 'Forest Temple NW Outdoors'), + ('Forest Temple Outside to Lobby', 'Forest Temple Lobby'), + ('Forest Temple Scarecrows Song', 'Forest Temple Falling Room'), + ('Forest Temple Falling Room Exit', 'Forest Temple NE Outdoors'), + ('Forest Temple Elevator', 'Forest Temple Boss Region'), + ('Forest Temple Outside Backdoor', 'Forest Temple Outside Upper Ledge'), + ('Forest Temple Twisted Hall', 'Forest Temple Bow Region'), + ('Forest Temple Straightened Hall', 'Forest Temple Straightened Hall'), + ('Forest Temple Boss Key Chest Drop', 'Forest Temple Outside Upper Ledge'), + ('Forest Temple Outside Ledge Drop', 'Forest Temple NW Outdoors'), + ('Forest Temple Drop to Falling Room', 'Forest Temple Falling Room') + ] + +FoT_MQ_connections = [('Forest Temple Lobby Locked Door', 'Forest Temple Central Area'), + ('Forest Temple West Eye Switch', 'Forest Temple NW Outdoors'), + ('Forest Temple East Eye Switch', 'Forest Temple NE Outdoors'), + ('Forest Temple Block Puzzle Solve', 'Forest Temple After Block Puzzle'), + ('Forest Temple Crystal Switch Jump', 'Forest Temple Outdoor Ledge'), + ('Forest Temple Drop to NW Outdoors', 'Forest Temple NW Outdoors'), + ('Forest Temple Well Connection', 'Forest Temple NE Outdoors'), + ('Forest Temple Webs', 'Forest Temple Outdoors Top Ledges'), + ('Forest Temple Climb to Top Ledges', 'Forest Temple Outdoors Top Ledges'), + ('Forest Temple Longshot to NE Outdoors Ledge', 'Forest Temple NE Outdoors Ledge'), + ('Forest Temple Top Drop to NE Outdoors', 'Forest Temple NE Outdoors'), + ('Forest Temple Drop to NE Outdoors', 'Forest Temple NE Outdoors'), + ('Forest Temple Song of Time Block Climb', 'Forest Temple Falling Room'), + ('Forest Temple Twisted Hall', 'Forest Temple Bow Region'), + ('Forest Temple Drop to Falling Room', 'Forest Temple Falling Room'), + ('Forest Temple Falling Room Exit', 'Forest Temple NE Outdoors Ledge'), + ('Forest Temple Elevator', 'Forest Temple Boss Region') + ] + +FiT_vanilla_connections = [('Fire Temple Early Climb', 'Fire Temple Middle'), + ('Fire Temple Fire Maze Escape', 'Fire Temple Upper') + ] + +FiT_MQ_connections = [('Fire Temple Boss Door', 'Fire Boss Room'), + ('Fire Temple Lower Locked Door', 'Fire Lower Locked Door'), + ('Fire Temple Hammer Statue', 'Fire Big Lava Room'), + ('Fire Temple Early Climb', 'Fire Lower Maze'), + ('Fire Temple Maze Climb', 'Fire Upper Maze'), + ('Fire Temple Maze Escape', 'Fire Temple Upper') + ] + +WT_vanilla_connections = [('Water Temple Central Pillar', 'Water Temple Middle Water Level'), + ('Water Temple Upper Locked Door', 'Water Temple Dark Link Region') + ] + +WT_MQ_connections = [('Water Temple Water Level Switch', 'Water Temple Lowered Water Levels'), + ('Water Temple Locked Door', 'Water Temple Dark Link Region'), + ('Water Temple Basement Gates Switch', 'Water Temple Basement Gated Areas') + ] + +GTG_vanilla_connections = [('Gerudo Training Ground Left Silver Rupees', 'Gerudo Training Grounds Heavy Block Room'), + ('Gerudo Training Ground Beamos', 'Gerudo Training Grounds Lava Room'), + ('Gerudo Training Ground Central Door', 'Gerudo Training Grounds Central Maze'), + ('Gerudo Training Grounds Right Locked Doors', 'Gerudo Training Grounds Central Maze Right'), + ('Gerudo Training Grounds Maze Exit', 'Gerudo Training Grounds Lava Room'), + ('Gerudo Training Grounds Maze Ledge', 'Gerudo Training Grounds Central Maze Right'), + ('Gerudo Training Grounds Right Hookshot Target', 'Gerudo Training Grounds Hammer Room'), + ('Gerudo Training Grounds Hammer Target', 'Gerudo Training Grounds Eye Statue Lower'), + ('Gerudo Training Grounds Hammer Room Clear', 'Gerudo Training Grounds Lava Room'), + ('Gerudo Training Grounds Eye Statue Exit', 'Gerudo Training Grounds Hammer Room'), + ('Gerudo Training Grounds Eye Statue Drop', 'Gerudo Training Grounds Eye Statue Lower'), + ('Gerudo Training Grounds Hidden Hookshot Target', 'Gerudo Training Grounds Eye Statue Upper') + ] + +GTG_MQ_connections = [('Gerudo Training Grounds Left Door', 'Gerudo Training Grounds Left Side'), + ('Gerudo Training Grounds Right Door', 'Gerudo Training Grounds Right Side'), + ('Gerudo Training Grounds Longshot Target', 'Gerudo Training Grounds Stalfos Room'), + ('Gerudo Training Grounds Song of Time Block', 'Gerudo Training Grounds Back Areas'), + ('Gerudo Training Grounds Rusted Switch', 'Gerudo Training Grounds Central Maze Right'), + ('Gerudo Training Grounds Loop Around', 'Gerudo Training Grounds Right Side') + ] + +SpT_vanilla_connections = [('Spirit Temple Crawl Passage', 'Child Spirit Temple'), + ('Spirit Temple Silver Block', 'Early Adult Spirit Temple'), + ('Child Spirit Temple Climb', 'Child Spirit Temple Climb'), + ('Child Spirit Temple Passthrough', 'Spirit Temple Central Chamber'), + ('Adult Spirit Temple Passthrough', 'Spirit Temple Central Chamber'), + ('Spirit Temple Middle Child Door', 'Child Spirit Temple Climb'), + ('Spirit Temple to Hands', 'Spirit Temple Outdoor Hands'), + ('Spirit Temple Central Locked Door', 'Spirit Temple Beyond Central Locked Door'), + ('Spirit Temple Final Locked Door', 'Spirit Temple Beyond Final Locked Door'), + ] + +SpT_MQ_connections = [('Spirit Temple Crawl Passage', 'Child Spirit Temple'), + ('Spirit Temple Ceiling Passage', 'Adult Spirit Temple'), + ('Child Spirit Temple to Shared', 'Spirit Temple Shared'), + ('Adult Spirit Temple to Shared', 'Spirit Temple Shared'), + ('Adult Spirit Temple Descent', 'Lower Adult Spirit Temple'), + ('Spirit Temple Climbable Wall', 'Spirit Temple Boss Area'), + ('Mirror Shield Exit', 'Mirror Shield Hand'), + ('Silver Gauntlets Exit', 'Silver Gauntlets Hand') + ] + +ShT_vanilla_connections = [('Shadow Temple First Pit', 'Shadow Temple First Beamos'), + ('Shadow Temple Bomb Wall', 'Shadow Temple Huge Pit'), + ('Shadow Temple Hookshot Target', 'Shadow Temple Wind Tunnel'), + ('Shadow Temple Boat', 'Shadow Temple Beyond Boat') + ] + +ShT_MQ_connections = [('Shadow Temple First Pit', 'Shadow Temple First Beamos'), + ('Shadow Temple Beginning Locked Door', 'Shadow Temple Dead Hand Area'), + ('Shadow Temple Bomb Wall', 'Shadow Temple Huge Pit'), + ('Shadow Temple Hookshot Target', 'Shadow Temple Wind Tunnel'), + ('Shadow Temple Boat', 'Shadow Temple Beyond Boat'), + ('Shadow Temple Longshot Target', 'Shadow Temple Invisible Maze') + ] + +# non-shuffled entrance links +default_connections = [('Links House Exit', 'Kokiri Forest'), + ('Links House', 'Links House'), + ('Mido House Exit', 'Kokiri Forest'), + ('Mido House', 'Mido House'), + ('Saria House Exit', 'Kokiri Forest'), + ('Saria House', 'Saria House'), + ('House of Twins Exit', 'Kokiri Forest'), + ('House of Twins', 'House of Twins'), + ('Know It All House Exit', 'Kokiri Forest'), + ('Know It All House', 'Know It All House'), + ('Kokiri Shop Exit', 'Kokiri Forest'), + ('Kokiri Shop', 'Kokiri Shop'), + ('Lake Hylia Lab', 'Lake Hylia Lab'), + ('Fishing Hole', 'Fishing Hole'), + ('Colossus Fairy', 'Colossus Fairy'), + ('Temple of Time', 'Temple of Time'), + ('Temple of Time Exit', 'Castle Town'), + ('Door of Time', 'Beyond Door of Time'), + ('Emerge as Adult', 'Temple of Time'), + ('Hyrule Castle Fairy', 'Hyrule Castle Fairy'), + ('Ganons Castle Fairy', 'Ganons Castle Fairy'), + ('Castle Town Rupee Room', 'Castle Town Rupee Room'), + ('Castle Town Bazaar', 'Castle Town Bazaar'), + ('Castle Town Mask Shop', 'Castle Town Mask Shop'), + ('Castle Town Shooting Gallery', 'Castle Town Shooting Gallery'), + ('Castle Town Bombchu Bowling', 'Castle Town Bombchu Bowling'), + ('Castle Town Potion Shop', 'Castle Town Potion Shop'), + ('Castle Town Treasure Chest Game', 'Castle Town Treasure Chest Game'), + ('Castle Town Bombchu Shop', 'Castle Town Bombchu Shop'), + ('Castle Town Dog Lady', 'Castle Town Dog Lady'), + ('Castle Town Man in Green House', 'Castle Town Man in Green House'), + ('Carpenter Boss House', 'Carpenter Boss House'), + ('House of Skulltula', 'House of Skulltula'), + ('Impas House', 'Impas House'), + ('Impas House Back', 'Impas House Back'), + ('Windmill', 'Windmill'), + ('Kakariko Bazaar', 'Kakariko Bazaar'), + ('Kakariko Shooting Gallery', 'Kakariko Shooting Gallery'), + ('Kakariko Potion Shop Front', 'Kakariko Potion Shop Front'), + ('Kakariko Potion Shop Back', 'Kakariko Potion Shop Back'), + ('Odd Medicine Building', 'Odd Medicine Building'), + ('Shield Grave', 'Shield Grave'), + ('Heart Piece Grave', 'Heart Piece Grave'), + ('Composer Grave', 'Composer Grave'), + ('Dampes Grave', 'Dampes Grave'), + ('Crater Fairy', 'Crater Fairy'), + ('Mountain Summit Fairy', 'Mountain Summit Fairy'), + ('Dampes House', 'Dampes House'), + ('Talon House', 'Talon House'), + ('Ingo Barn', 'Ingo Barn'), + ('Lon Lon Corner Tower', 'Lon Lon Corner Tower'), + ('Zora Shop Child Access', 'Zora Shop'), + ('Goron Shop', 'Goron Shop'), + ('Zoras Fountain Fairy', 'Zoras Fountain Fairy'), + ('Kokiri Forest Storms Grotto', 'Kokiri Forest Storms Grotto'), + ('Lost Woods Generic Grotto', 'Lost Woods Generic Grotto'), + ('Deku Theater', 'Deku Theater'), + ('Lost Woods Sales Grotto', 'Lost Woods Sales Grotto'), + ('Meadow Fairy Grotto', 'Meadow Fairy Grotto'), + ('Front of Meadow Grotto', 'Front of Meadow Grotto'), + ('Lon Lon Grotto', 'Lon Lon Grotto'), + ('Remote Southern Grotto', 'Remote Southern Grotto'), + ('Field Near Lake Outside Fence Grotto', 'Field Near Lake Outside Fence Grotto'), + ('Field Near Lake Inside Fence Grotto', 'Field Near Lake Inside Fence Grotto'), + ('Field Valley Grotto', 'Field Valley Grotto'), + ('Field West Castle Town Grotto', 'Field West Castle Town Grotto'), + ('Field Far West Castle Town Grotto', 'Field Far West Castle Town Grotto'), + ('Field Kakariko Grotto', 'Field Kakariko Grotto'), + ('Kakariko Bombable Grotto', 'Kakariko Bombable Grotto'), + ('Kakariko Back Grotto', 'Kakariko Back Grotto'), + ('Mountain Bombable Grotto', 'Mountain Bombable Grotto'), + ('Mountain Storms Grotto', 'Mountain Storms Grotto'), + ('Top of Crater Grotto', 'Top of Crater Grotto'), + ('Field North Lon Lon Grotto', 'Field North Lon Lon Grotto'), + ('Castle Storms Grotto', 'Castle Storms Grotto'), + ('Zora River Plateau Open Grotto', 'Zora River Plateau Open Grotto'), + ('Zora River Plateau Bombable Grotto', 'Zora River Plateau Bombable Grotto'), + ('Lake Hylia Grotto', 'Lake Hylia Grotto'), + ('Meadow Storms Grotto Child Access', 'Meadow Storms Grotto'), + ('Meadow Storms Grotto Adult Access', 'Meadow Storms Grotto'), + ('Gerudo Valley Storms Grotto','Gerudo Valley Storms Grotto'), + ('Desert Colossus Grotto','Desert Colossus Grotto'), + ('Goron City Grotto', 'Goron City Grotto'), + ('DMC Hammer Grotto', 'DMC Hammer Grotto'), + ('Zora River Storms Grotto', 'Zora River Storms Grotto'), + ('Zora Shop Adult Access', 'Zora Shop'), + ] + +# non shuffled dungeons +default_dungeon_connections = [('Deku Tree', 'Deku Tree Lobby'), + ('Deku Tree Exit', 'Kokiri Forest'), + ('Dodongos Cavern', 'Dodongos Cavern Beginning'), + ('Dodongos Cavern Exit', 'Dodongos Cavern Entryway'), + ('Jabu Jabus Belly', 'Jabu Jabus Belly Beginning'), + ('Jabu Jabus Belly Exit', 'Zoras Fountain'), + ('Forest Temple Entrance', 'Forest Temple Lobby'), + ('Forest Temple Exit', 'Forest Temple Entry Area'), + ('Bottom of the Well', 'Bottom of the Well'), + ('Bottom of the Well Exit', 'Kakariko Village'), + ('Fire Temple Entrance', 'Fire Temple Lower'), + ('Fire Temple Exit', 'Death Mountain Crater Central'), + ('Ice Cavern Entrance', 'Ice Cavern'), + ('Ice Cavern Exit', 'Outside Ice Cavern'), + ('Water Temple Entrance', 'Water Temple Lobby'), + ('Water Temple Exit', 'Lake Hylia'), + ('Shadow Temple Entrance', 'Shadow Temple Beginning'), + ('Shadow Temple Exit', 'Shadow Temple Warp Region'), + ('Gerudo Training Grounds Entrance', 'Gerudo Training Grounds Lobby'), + ('Gerudo Training Grounds Exit', 'Gerudo Fortress'), + ('Spirit Temple Entrance', 'Spirit Temple Lobby'), + ('Spirit Temple Exit', 'Desert Colossus'), + ('Rainbow Bridge', 'Ganons Castle Lobby'), + ('Ganons Castle Exit', 'Ganons Castle Grounds') + ] diff --git a/Fill.py b/Fill.py index c00824bfd..434da6f43 100644 --- a/Fill.py +++ b/Fill.py @@ -1,103 +1,365 @@ import random import logging +from BaseClasses import CollectionState +from Rules import set_shop_rules class FillError(RuntimeError): pass -def fill_restrictive(world, base_state, locations, itempool): - def sweep_from_pool(): - new_state = base_state.copy() - for item in itempool: - new_state.collect(item, True) - new_state.sweep_for_events() - return new_state +# Places all items into the world +def distribute_items_restrictive(window, worlds, fill_locations=None): + song_locations = [world.get_location(location) for world in worlds for location in + ['Song from Composer Grave', 'Impa at Castle', 'Song from Malon', 'Song from Saria', + 'Song from Ocarina of Time', 'Song at Windmill', 'Sheik Forest Song', 'Sheik at Temple', + 'Sheik in Crater', 'Sheik in Ice Cavern', 'Sheik in Kakariko', 'Sheik at Colossus']] - while itempool and locations: - item_to_place = itempool.pop() - maximum_exploration_state = sweep_from_pool() + shop_locations = [location for world in worlds for location in world.get_unfilled_locations() if location.type == 'Shop' and location.price == None] - perform_access_check = True - if world.check_beatable_only: - perform_access_check = not world.has_beaten_game(maximum_exploration_state) + # If not passed in, then get a shuffled list of locations to fill in + if not fill_locations: + fill_locations = [location for world in worlds for location in world.get_unfilled_locations() if location not in song_locations and location not in shop_locations] + world_states = [world.state for world in worlds] + window.locationcount = len(fill_locations) + len(song_locations) + window.fillcount = 0 - spot_to_fill = None - for location in locations: - if location.can_fill(maximum_exploration_state, item_to_place, perform_access_check): - spot_to_fill = location - break - - if spot_to_fill is None: - # we filled all reachable spots. Maybe the game can be beaten anyway? - if world.can_beat_game(): - if not world.check_beatable_only: - logging.getLogger('').warning('Not all items placed. Game beatable anyway.') - break - raise FillError('No more spots to place %s' % item_to_place) + # Generate the itempools + shopitempool = [item for world in worlds for item in world.itempool if item.type == 'Shop'] + songitempool = [item for world in worlds for item in world.itempool if item.type == 'Song'] + itempool = [item for world in worlds for item in world.itempool if item.type != 'Shop' and item.type != 'Song'] + if worlds[0].shuffle_song_items: + itempool.extend(songitempool) + fill_locations.extend(song_locations) - world.push_item(spot_to_fill, item_to_place, False) - locations.remove(spot_to_fill) - spot_to_fill.event = True + # add unrestricted dungeon items to main item pool + itempool.extend([item for world in worlds for item in world.get_unrestricted_dungeon_items()]) + dungeon_items = [item for world in worlds for item in world.get_restricted_dungeon_items()] + random.shuffle(itempool) # randomize item placement order. this ordering can greatly affect the location accessibility bias + progitempool = [item for item in itempool if item.advancement] + prioitempool = [item for item in itempool if not item.advancement and item.priority] + restitempool = [item for item in itempool if not item.advancement and not item.priority] -def distribute_items_restrictive(world, fill_locations=None): - # If not passed in, then get a shuffled list of locations to fill in - if not fill_locations: - fill_locations = world.get_unfilled_locations() - random.shuffle(fill_locations) - # get items to distribute - random.shuffle(world.itempool) - progitempool = [item for item in world.itempool if item.advancement] - prioitempool = [item for item in world.itempool if not item.advancement and item.priority] - restitempool = [item for item in world.itempool if not item.advancement and not item.priority] + # We place all the shop items first. Like songs, they have a more limited + # set of locations that they can be placed in, so placing them first will + # reduce the odds of creating unbeatable seeds. This also avoids needing + # to create item rules for every location for whether they are a shop item + # or not. This shouldn't have much affect on item bias. + if shop_locations: + random.shuffle(shop_locations) + fill_shops(window, worlds, shop_locations, shopitempool, itempool + songitempool + dungeon_items) + # Update the shop item access rules + for world in worlds: + set_shop_rules(world) + # If there are dungeon items that are restricted to their original dungeon, + # we must place them first to make sure that there is always a location to + # place them. This could probably be replaced for more intelligent item + # placement, but will leave as is for now + random.shuffle(fill_locations) + fill_dungeons_restrictive(window, worlds, fill_locations, dungeon_items, itempool + songitempool) + for world in worlds: + world.keys_placed = True + + # I have no idea why the locations are reversed but this is how it was, + # so whatever. It can't hurt I guess random.shuffle(fill_locations) fill_locations.reverse() - fill_restrictive(world, world.state, fill_locations, progitempool) + # places the songs into the world + # Currently places songs only at song locations. if there's an option + # to allow at other locations then they should be in the main pool. + # Placing songs on their own since they have a relatively high chance + # of failing compared to other item type. So this way we only have retry + # the song locations only. + if not worlds[0].shuffle_song_items: + fill_songs(window, worlds, song_locations, songitempool, progitempool) + # Put one item in every dungeon, needs to be done before other items are + # placed to ensure there is a spot available for them + if worlds[0].one_item_per_dungeon: + fill_dungeon_unique_item(window, worlds, fill_locations, progitempool) + + # Place all progression items. This will include keys in keysanity. + # Items in this group will check for reachability and will be placed + # such that the game is guaranteed beatable. random.shuffle(fill_locations) + fill_restrictive(window, worlds, [world.state for world in worlds], fill_locations, progitempool) - fill_restrictive_fast(world, world.state, fill_locations, prioitempool) + # Place all priority items. + # These items are items that only check if the item is allowed to be + # placed in the location, not checking reachability. This is important + # for things like Ice Traps that can't be found at some locations + random.shuffle(fill_locations) + fill_restrictive_fast(window, worlds, fill_locations, prioitempool) + # Place the rest of the items. + # No restrictions at all. Places them completely randomly. Since they + # cannot affect the beatability, we don't need to check them random.shuffle(fill_locations) + fast_fill(window, fill_locations, restitempool) + + # Log unplaced item/location warnings + for item in progitempool + prioitempool + restitempool: + logging.getLogger('').debug('Unplaced Items: %s [World %d]' % (item.name, item.world.id)) + if progitempool + prioitempool + restitempool: + for item in progitempool + prioitempool + restitempool: + print('Unplaced Items: %s [World %d]' % (item.name, item.world.id)) + + raise FillError('Not all items are placed.') + + if fill_locations: + for location in fill_locations: + logging.getLogger('').debug('Unfilled Locations: %s [World %d]' % (location.name, location.world.id)) + raise FillError('Not all locations have an item.') + + +# Places restricted dungeon items into the worlds. To ensure there is room for them. +# they are placed first so it will assume all other items are reachable +def fill_dungeons_restrictive(window, worlds, shuffled_locations, dungeon_items, itempool): + # List of states with all non-key items + all_state_base_list = CollectionState.get_states_with_items([world.state for world in worlds], itempool) + + # shuffle this list to avoid placement bias + random.shuffle(dungeon_items) + + # sort in the order Boss Key, Small Key, Other before placing dungeon items + # python sort is stable, so the ordering is still random within groups + sort_order = {"BossKey": 3, "SmallKey": 2} + dungeon_items.sort(key=lambda item: sort_order.get(item.type, 1)) - fast_fill(world, restitempool, fill_locations) + # place dungeon items + fill_restrictive(window, worlds, all_state_base_list, shuffled_locations, dungeon_items) - logging.getLogger('').debug('Unplaced items: %s - Unfilled Locations: %s', [item.name for item in progitempool + prioitempool + restitempool], [location.name for location in fill_locations]) + for world in worlds: + world.state.clear_cached_unreachable() -def fast_fill(world, item_pool, fill_locations): - while item_pool and fill_locations: - spot_to_fill = fill_locations.pop() - item_to_place = item_pool.pop() - world.push_item(spot_to_fill, item_to_place, False) +# Places items into dungeon locations. This is used when there should be exactly +# one progression item per dungeon. This should be ran before all the progression +# items are places to ensure there is space to place them. +def fill_dungeon_unique_item(window, worlds, fill_locations, itempool): + # We should make sure that we don't count event items, shop items, + # token items, or dungeon items as a major item. itempool at this + # point should only be able to have tokens of those restrictions + # since the rest are already placed. + major_items = [item for item in itempool if item.majoritem] + minor_items = [item for item in itempool if not item.majoritem] -def fill_restrictive_fast(world, base_state, locations, itempool): - def sweep_from_pool(): - new_state = base_state.copy() + dungeons = [dungeon for world in worlds for dungeon in world.dungeons] + double_dungeons = [] + for dungeon in dungeons: + # we will count spirit temple twice so that it gets 2 items to match vanilla + if dungeon.name == 'Spirit Temple': + double_dungeons.append(dungeon) + dungeons.extend(double_dungeons) + + random.shuffle(dungeons) + random.shuffle(itempool) + + all_other_item_state = CollectionState.get_states_with_items([world.state for world in worlds], minor_items) + all_dungeon_locations = [] + + # iterate of all the dungeons in a random order, placing the item there + for dungeon in dungeons: + dungeon_locations = [location for region in dungeon.regions for location in region.locations if location in fill_locations] + if dungeon.name == 'Spirit Temple': + # spirit temple is weird and includes a couple locations outside of the dungeon + dungeon_locations.extend(filter(lambda location: location in fill_locations, [dungeon.world.get_location(location) for location in ['Mirror Shield Chest', 'Silver Gauntlets Chest']])) + + # cache this list to flag afterwards + all_dungeon_locations.extend(dungeon_locations) + + # place 1 item into the dungeon + random.shuffle(dungeon_locations) + fill_restrictive(window, worlds, all_other_item_state, dungeon_locations, major_items, 1) + + # update the location and item pool, removing any placed items and filled locations + # the fact that you can remove items from a list you're iterating over is python magic for item in itempool: - new_state.collect(item, True) - new_state.sweep_for_events() - return new_state + if item.location != None: + fill_locations.remove(item.location) + itempool.remove(item) + + # flag locations to not place further major items. it's important we do it on the + # locations instead of the dungeon because some locations are not in the dungeon + for location in all_dungeon_locations: + location.minor_only = True + + logging.getLogger('').info("Unique dungeon items placed") + +# Places the shop items into the world at the Shop locations +def fill_shops(window, worlds, locations, shoppool, itempool, attempts=15): + # List of states with all items + all_state_base_list = CollectionState.get_states_with_items([world.state for world in worlds], itempool) + + while attempts: + attempts -= 1 + try: + prizepool = list(shoppool) + prize_locs = list(locations) + random.shuffle(prizepool) + random.shuffle(prize_locs) + fill_restrictive(window, worlds, all_state_base_list, prize_locs, prizepool) + logging.getLogger('').info("Shop items placed") + except FillError as e: + logging.getLogger('').info("Failed to place shop items. Will retry %s more times", attempts) + for location in locations: + location.item = None + logging.getLogger('').info('\t%s' % str(e)) + continue + break + else: + raise FillError('Unable to place shops') + + +# Places the songs into the world at the Song locations +def fill_songs(window, worlds, locations, songpool, itempool, attempts=15): + # get the song locations for each world + + # look for preplaced items + placed_prizes = [loc.item.name for loc in locations if loc.item is not None] + unplaced_prizes = [song for song in songpool if song.name not in placed_prizes] + empty_song_locations = [loc for loc in locations if loc.item is None] + + # List of states with all items + all_state_base_list = CollectionState.get_states_with_items([world.state for world in worlds], itempool) + + while attempts: + attempts -= 1 + try: + prizepool = list(unplaced_prizes) + prize_locs = list(empty_song_locations) + random.shuffle(prizepool) + random.shuffle(prize_locs) + fill_restrictive(window, worlds, all_state_base_list, prize_locs, prizepool) + logging.getLogger('').info("Songs placed") + except FillError as e: + logging.getLogger('').info("Failed to place songs. Will retry %s more times", attempts) + for location in empty_song_locations: + location.item = None + logging.getLogger('').info('\t%s' % str(e)) + continue + break + else: + raise FillError('Unable to place songs') + + +# Places items in the itempool into locations. +# worlds is a list of worlds and is redundant of the worlds in the base_state_list +# base_state_list is a list of world states prior to placing items in the item pool +# items and locations have pointers to the world that they belong to +# +# The algorithm places items in the world in reverse. +# This means we first assume we have every item in the item pool and +# remove an item and try to place it somewhere that is still reachable +# This method helps distribution of items locked behind many requirements +# +# count is the number of items to place. If count is negative, then it will place +# every item. Raises an error if specified count of items are not placed. +# +# This function will modify the location and itempool arguments. placed items and +# filled locations will be removed. If this returns and error, then the state of +# those two lists cannot be guaranteed. +def fill_restrictive(window, worlds, base_state_list, locations, itempool, count=-1): + unplaced_items = [] + + # loop until there are no items or locations while itempool and locations: + # if remaining count is 0, return. Negative means unbounded. + if count == 0: + break + + # get and item and remove it from the itempool item_to_place = itempool.pop() + # generate the max states that include every remaining item + # this will allow us to place this item in a reachable location + maximum_exploration_state_list = CollectionState.get_states_with_items(base_state_list, itempool + unplaced_items) + + # perform_access_check checks location reachability + perform_access_check = True + if worlds[0].check_beatable_only: + # if any world can not longer be beatable with the remaining items + # then we must check for reachability no matter what. + # This way the reachability test is monotonic. If we were to later + # stop checking, then we could place an item needed in one world + # in an unreachable place in another world + perform_access_check = not CollectionState.can_beat_game(maximum_exploration_state_list) + + # find a location that the item can be places. It must be a valid location + # in the world we are placing it (possibly checking for reachability) spot_to_fill = None for location in locations: - if location.can_fill_fast(item_to_place): + if location.can_fill(maximum_exploration_state_list[location.world.id], item_to_place, perform_access_check): spot_to_fill = location break + # if we failed to find a suitable location if spot_to_fill is None: - # we filled all reachable spots. Maybe the game can be beaten anyway? - if world.can_beat_game(): - logging.getLogger('').warning('Not all items placed. Game beatable anyway.') + # if we specify a count, then we only want to place a subset, so a miss might be ok + if count > 0: + # don't decrement count, we didn't place anything + unplaced_items.append(item_to_place) + continue + else: + # we expect all items to be placed + raise FillError('Game unbeatable: No more spots to place %s [World %d]' % (item_to_place, item_to_place.world.id)) + + # Place the item in the world and continue + spot_to_fill.world.push_item(spot_to_fill, item_to_place) + locations.remove(spot_to_fill) + window.fillcount += 1 + window.update_progress(5 + ((window.fillcount / window.locationcount) * 30)) + + # decrement count + count -= 1 + + # assert that the specified number of items were placed + if count > 0: + raise FillError('Could not place the specified number of item. %d remaining to be placed.' % count) + # re-add unplaced items that were skipped + itempool.extend(unplaced_items) + + +# This places items in the itempool into the locations +# It does not check for reachability, only that the item is +# allowed in the location +def fill_restrictive_fast(window, worlds, locations, itempool): + while itempool and locations: + item_to_place = itempool.pop() + + # get location that allows this item + spot_to_fill = None + for location in locations: + if location.can_fill_fast(item_to_place): + spot_to_fill = location break - raise FillError('No more spots to place %s' % item_to_place) - world.push_item(spot_to_fill, item_to_place, False) + # if we failed to find a suitable location, then stop placing items + # we don't need to check beatability since world must be beatable + # at this point + if spot_to_fill is None: + if not worlds[0].check_beatable_only: + logging.getLogger('').debug('Not all items placed. Game beatable anyway.') + break + + # Place the item in the world and continue + spot_to_fill.world.push_item(spot_to_fill, item_to_place) locations.remove(spot_to_fill) - spot_to_fill.event = True \ No newline at end of file + window.fillcount += 1 + window.update_progress(5 + ((window.fillcount / window.locationcount) * 30)) + + +# this places item in item_pool completely randomly into +# fill_locations. There is no checks for validity since +# there should be none for these remaining items +def fast_fill(window, locations, itempool): + while itempool and locations: + spot_to_fill = locations.pop() + item_to_place = itempool.pop() + spot_to_fill.world.push_item(spot_to_fill, item_to_place) + window.fillcount += 1 + window.update_progress(5 + ((window.fillcount / window.locationcount) * 30)) diff --git a/Gui.py b/Gui.py old mode 100644 new mode 100755 index 87127a880..323f0e31e --- a/Gui.py +++ b/Gui.py @@ -3,235 +3,485 @@ from glob import glob import json import random +import re import os import shutil -from tkinter import Checkbutton, OptionMenu, Toplevel, LabelFrame, PhotoImage, Tk, LEFT, RIGHT, BOTTOM, TOP, StringVar, IntVar, Frame, Label, W, E, X, Entry, Spinbox, Button, filedialog, messagebox, ttk +from tkinter import Scale, Checkbutton, OptionMenu, Toplevel, LabelFrame, Radiobutton, PhotoImage, Tk, BOTH, LEFT, RIGHT, BOTTOM, TOP, StringVar, IntVar, Frame, Label, W, E, X, N, S, NW, Entry, Spinbox, Button, filedialog, messagebox, ttk, HORIZONTAL, Toplevel +from tkinter.colorchooser import * from urllib.parse import urlparse from urllib.request import urlopen -from GuiUtils import ToolTips, set_icon, BackgroundTaskProgress -from Main import main, __version__ as ESVersion -from Utils import is_bundled, local_path, output_path, open_file +from GuiUtils import ToolTips, set_icon, BackgroundTask, BackgroundTaskProgress, Dialog +from Main import main +from Utils import is_bundled, local_path, default_output_path, open_file, check_version +from Patches import get_tunic_color_options, get_navi_color_options +from Settings import Settings, setting_infos +from version import __version__ as ESVersion +import webbrowser + +def settings_to_guivars(settings, guivars): + for info in setting_infos: + name = info.name + if name not in guivars: + continue + guivar = guivars[name] + value = settings.__dict__[name] + # checkbox + if info.type == bool: + guivar.set( int(value) ) + # dropdown/radiobox + if info.type == str: + if value is None: + guivar.set( "" ) + else: + if info.gui_params and 'options' in info.gui_params: + if 'Custom Color' in info.gui_params['options'] and re.match(r'^[A-Fa-f0-9]{6}$', value): + guivar.set('Custom (#' + value + ')') + else: + for gui_text,gui_value in info.gui_params['options'].items(): + if gui_value == value: + guivar.set( gui_text ) + else: + guivar.set( value ) + # text field for a number... + if info.type == int: + if value is None: + guivar.set( str(1) ) + else: + guivar.set( str(value) ) + +def guivars_to_settings(guivars): + result = {} + for info in setting_infos: + name = info.name + if name not in guivars: + result[name] = None + continue + guivar = guivars[name] + # checkbox + if info.type == bool: + result[name] = bool(guivar.get()) + # dropdown/radiobox + if info.type == str: + # set guivar to hexcode if custom color + if re.match(r'^Custom \(#[A-Fa-f0-9]{6}\)$', guivar.get()): + result[name] = re.findall(r'[A-Fa-f0-9]{6}', guivar.get())[0] + elif info.gui_params and 'options' in info.gui_params: + result[name] = info.gui_params['options'][guivar.get()] + else: + result[name] = guivar.get() + # text field for a number... + if info.type == int: + result[name] = int( guivar.get() ) + if result['seed'] == "": + result['seed'] = None + if result['count'] == 1: + result['count'] = None + return Settings(result) + +def guiMain(settings=None): + frames = {} -def guiMain(args=None): mainWindow = Tk() mainWindow.wm_title("OoT Randomizer %s" % ESVersion) + mainWindow.resizable(False, False) set_icon(mainWindow) notebook = ttk.Notebook(mainWindow) - randomizerWindow = ttk.Frame(notebook) + frames['rom_tab'] = ttk.Frame(notebook) + frames['rules_tab'] = ttk.Frame(notebook) + frames['logic_tab'] = ttk.Frame(notebook) + frames['other_tab'] = ttk.Frame(notebook) + frames['aesthetic_tab'] = ttk.Frame(notebook) + frames['aesthetic_tab_left'] = Frame(frames['aesthetic_tab']) + frames['aesthetic_tab_right'] = Frame(frames['aesthetic_tab']) adjustWindow = ttk.Frame(notebook) customWindow = ttk.Frame(notebook) - notebook.add(randomizerWindow, text='Randomize') - notebook.pack() + notebook.add(frames['rom_tab'], text='ROM Options') + notebook.add(frames['rules_tab'], text='Main Rules') + notebook.add(frames['logic_tab'], text='Detailed Logic') + notebook.add(frames['other_tab'], text='Other') + notebook.add(frames['aesthetic_tab'], text='Cosmetics') + + ####################### + # randomizer controls # + ####################### + + # hold the results of the user's decisions here + guivars = {} + + # hierarchy + ############ + + #Rules Tab + frames['open'] = LabelFrame(frames['rules_tab'], text='Open', labelanchor=NW) + frames['world'] = LabelFrame(frames['rules_tab'], text='World', labelanchor=NW) + frames['logic'] = LabelFrame(frames['rules_tab'], text='Shuffle', labelanchor=NW) + + # Logic tab + frames['rewards'] = LabelFrame(frames['logic_tab'], text='Remove Specific Locations', labelanchor=NW) + frames['tricks'] = LabelFrame(frames['logic_tab'], text='Specific Expected Tricks', labelanchor=NW) + + #Other Tab + frames['convenience'] = LabelFrame(frames['other_tab'], text='Speed Ups', labelanchor=NW) + frames['other'] = LabelFrame(frames['other_tab'], text='Misc', labelanchor=NW) + + #Aesthetics tab + frames['cosmetics'] = LabelFrame(frames['aesthetic_tab'], text='General', labelanchor=NW) + frames['tuniccolor'] = LabelFrame(frames['aesthetic_tab_left'], text='Tunic Color', labelanchor=NW) + frames['navicolor'] = LabelFrame(frames['aesthetic_tab_right'], text='Navi Color', labelanchor=NW) + frames['lowhp'] = LabelFrame(frames['aesthetic_tab_left'], text='Low HP SFX', labelanchor=NW) + frames['navihint'] = LabelFrame(frames['aesthetic_tab_right'], text='Navi SFX', labelanchor=NW) + + + # shared + settingsFrame = Frame(mainWindow) + settings_string_var = StringVar() + settingsEntry = Entry(settingsFrame, textvariable=settings_string_var, width=25) + + def show_settings(event=None): + settings = guivars_to_settings(guivars) + settings_string_var.set( settings.get_settings_string() ) + + # Update any dependencies + for info in setting_infos: + if info.gui_params and 'dependency' in info.gui_params: + dep_met = info.gui_params['dependency'](guivars) + + if widgets[info.name].winfo_class() == 'Frame': + for child in widgets[info.name].winfo_children(): + if child.winfo_class() == 'TCombobox': + child.configure(state= 'readonly' if dep_met else 'disabled') + else: + child.configure(state= 'normal' if dep_met else 'disabled') + + if child.winfo_class() == 'Scale': + child.configure(fg='Black'if dep_met else 'Grey') + else: + if widgets[info.name].winfo_class() == 'TCombobox': + widgets[info.name].configure(state= 'readonly' if dep_met else 'disabled') + else: + widgets[info.name].configure(state= 'normal' if dep_met else 'disabled') + + if widgets[info.name].winfo_class() == 'Scale': + widgets[info.name].configure(fg='Black'if dep_met else 'Grey') + + + if info.name in guivars and guivars[info.name].get() == 'Custom Color': + color = askcolor() + if color == (None, None): + color = ((0,0,0),'#000000') + guivars[info.name].set('Custom (' + color[1] + ')') + + def update_logic_tricks(event=None): + for info in setting_infos: + if info.gui_params \ + and info.gui_params['widget'] == 'Checkbutton' \ + and info.gui_params['group'] == 'tricks': + if guivars['all_logic_tricks'].get(): + widgets[info.name].select() + else: + widgets[info.name].deselect() + + settings = guivars_to_settings(guivars) + settings_string_var.set( settings.get_settings_string() ) + + + + def import_settings(event=None): + try: + settings = guivars_to_settings(guivars) + text = settings_string_var.get().upper() + settings.seed = guivars['seed'].get() + settings.update_with_settings_string(text) + settings_to_guivars(settings, guivars) + except Exception as e: + messagebox.showerror(title="Error", message="Invalid settings string") - # Shared Controls + label = Label(settingsFrame, text="Settings String") + importSettingsButton = Button(settingsFrame, text='Import Settings String', command=import_settings) + label.pack(side=LEFT, anchor=W, padx=5) + settingsEntry.pack(side=LEFT, anchor=W) + importSettingsButton.pack(side=LEFT, anchor=W, padx=5) - farBottomFrame = Frame(mainWindow) - def open_output(): - open_file(output_path('')) - openOutputButton = Button(farBottomFrame, text='Open Output Directory', command=open_output) - - if os.path.exists(local_path('README.html')): - def open_readme(): - open_file(local_path('README.html')) - openReadmeButton = Button(farBottomFrame, text='Open Documentation', command=open_readme) - openReadmeButton.pack(side=LEFT) - - farBottomFrame.pack(side=BOTTOM, fill=X, padx=5, pady=5) - - # randomizer controls - - topFrame = Frame(randomizerWindow) - rightHalfFrame = Frame(topFrame) - checkBoxFrame = Frame(rightHalfFrame) - - createSpoilerVar = IntVar() - createSpoilerCheckbutton = Checkbutton(checkBoxFrame, text="Create Spoiler Log (affects item layout)", variable=createSpoilerVar) - suppressRomVar = IntVar() - suppressRomCheckbutton = Checkbutton(checkBoxFrame, text="Do not create patched Rom", variable=suppressRomVar) - compressRomVar = IntVar() - compressRomCheckbutton = Checkbutton(checkBoxFrame, text="Compress patched Rom", variable=compressRomVar) - openForestVar = IntVar() - openForestCheckbutton = Checkbutton(checkBoxFrame, text="Open Forest", variable=openForestVar) - openDoorVar = IntVar() - openDoorCheckbutton = Checkbutton(checkBoxFrame, text="Open Door of Time", variable=openDoorVar) - fastGanonVar = IntVar() - fastGanonCheckbutton = Checkbutton(checkBoxFrame, text="Skip most of Ganon's Castle", variable=fastGanonVar) - dungeonItemsVar = IntVar() - dungeonItemsCheckbutton = Checkbutton(checkBoxFrame, text="Place Dungeon Items (Compasses/Maps)", onvalue=0, offvalue=1, variable=dungeonItemsVar) - beatableOnlyVar = IntVar() - beatableOnlyCheckbutton = Checkbutton(checkBoxFrame, text="Only ensure seed is beatable, not all items must be reachable", variable=beatableOnlyVar) - hintsVar = IntVar() - hintsCheckbutton = Checkbutton(checkBoxFrame, text="Gossip Stone Hints with Stone of Agony", variable=hintsVar) - - createSpoilerCheckbutton.pack(expand=True, anchor=W) - suppressRomCheckbutton.pack(expand=True, anchor=W) - compressRomCheckbutton.pack(expand=True, anchor=W) - openForestCheckbutton.pack(expand=True, anchor=W) - openDoorCheckbutton.pack(expand=True, anchor=W) - fastGanonCheckbutton.pack(expand=True, anchor=W) - dungeonItemsCheckbutton.pack(expand=True, anchor=W) - beatableOnlyCheckbutton.pack(expand=True, anchor=W) - hintsCheckbutton.pack(expand=True, anchor=W) - - fileDialogFrame = Frame(rightHalfFrame) + fileDialogFrame = Frame(frames['rom_tab']) romDialogFrame = Frame(fileDialogFrame) - baseRomLabel = Label(romDialogFrame, text='Base Rom') - romVar = StringVar() - romEntry = Entry(romDialogFrame, textvariable=romVar) + baseRomLabel = Label(romDialogFrame, text='Base ROM') + guivars['rom'] = StringVar(value='ZOOTDEC.z64') + romEntry = Entry(romDialogFrame, textvariable=guivars['rom'], width=40) def RomSelect(): - rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".z64", ".n64")), ("All Files", "*")]) - romVar.set(rom) - romSelectButton = Button(romDialogFrame, text='Select Rom', command=RomSelect) + rom = filedialog.askopenfilename(filetypes=[("ROM Files", (".z64", ".n64")), ("All Files", "*")]) + if rom != '': + guivars['rom'].set(rom) + romSelectButton = Button(romDialogFrame, text='Select ROM', command=RomSelect, width=10) - baseRomLabel.pack(side=LEFT) - romEntry.pack(side=LEFT) + baseRomLabel.pack(side=LEFT, padx=(38,0)) + romEntry.pack(side=LEFT, padx=3) romSelectButton.pack(side=LEFT) romDialogFrame.pack() - checkBoxFrame.pack() - fileDialogFrame.pack() - - dropDownFrame = Frame(topFrame) - - - bridgeFrame = Frame(dropDownFrame) - bridgeVar = StringVar() - bridgeVar.set('medallions') - bridgeOptionMenu = OptionMenu(bridgeFrame, bridgeVar, 'medallions', 'vanilla', 'dungeons', 'open') - bridgeOptionMenu.pack(side=RIGHT) - bridgeLabel = Label(bridgeFrame, text='Rainbow Bridge Requirement') - bridgeLabel.pack(side=LEFT) - - colorVars = [] - colorVars.append(StringVar()) - colorVars.append(StringVar()) - colorVars.append(StringVar()) - colorVars[0].set('Kokiri Green') - colorVars[1].set('Goron Red') - colorVars[2].set('Zora Blue') - - kokiriFrame = Frame(dropDownFrame) - kokiriOptionMenu = OptionMenu(kokiriFrame, colorVars[0], 'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green', 'Random', 'True Random') - kokiriOptionMenu.pack(side=RIGHT) - kokiriLabel = Label(kokiriFrame, text='Kokiri Tunic Color') - kokiriLabel.pack(side=LEFT) - - goronFrame = Frame(dropDownFrame) - goronOptionMenu = OptionMenu(goronFrame, colorVars[1], 'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green', 'Random', 'True Random') - goronOptionMenu.pack(side=RIGHT) - goronLabel = Label(goronFrame, text='Goron Tunic Color') - goronLabel.pack(side=LEFT) - - zoraFrame = Frame(dropDownFrame) - zoraOptionMenu = OptionMenu(zoraFrame, colorVars[2], 'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green', 'Random', 'True Random') - zoraOptionMenu.pack(side=RIGHT) - zoraLabel = Label(zoraFrame, text='Zora Tunic Color') - zoraLabel.pack(side=LEFT) - - lowHealthSFXVar = StringVar() - lowHealthSFXVar.set('Default') + fileDialogFrame.pack(side=TOP, anchor=W, padx=5, pady=(5,1)) + + def open_output(): + open_file(output_path('')) - lowHealthSFXFrame = Frame(dropDownFrame) - lowHealthSFXOptionMenu = OptionMenu(lowHealthSFXFrame, lowHealthSFXVar, 'Default', 'Softer Beep', 'Rupee', 'Timer', 'Tamborine', 'Recovery Heart', 'Carrot Refill', 'Navi - Hey!', 'Zelda - Gasp', 'Cluck', 'Mweep!', 'Random', 'None') - lowHealthSFXOptionMenu.pack(side=RIGHT) - lowHealthSFXLabel = Label(lowHealthSFXFrame, text='Low Health SFX') - lowHealthSFXLabel.pack(side=LEFT) + def output_dir_select(): + rom = filedialog.askdirectory(initialdir = default_output_path(guivars['output_dir'].get())) + if rom != '': + guivars['output_dir'].set(rom) + + outputDialogFrame = Frame(frames['rom_tab']) + outputDirLabel = Label(outputDialogFrame, text='Output Directory') + guivars['output_dir'] = StringVar(value='') + outputDirEntry = Entry(outputDialogFrame, textvariable=guivars['output_dir'], width=40) + outputDirButton = Button(outputDialogFrame, text='Select Dir', command=output_dir_select, width=10) + outputDirLabel.pack(side=LEFT, padx=(3,0)) + outputDirEntry.pack(side=LEFT, padx=3) + outputDirButton.pack(side=LEFT) + outputDialogFrame.pack(side=TOP, anchor=W, pady=3) + + countDialogFrame = Frame(frames['rom_tab']) + countLabel = Label(countDialogFrame, text='Generation Count') + guivars['count'] = StringVar() + countSpinbox = Spinbox(countDialogFrame, from_=1, to=100, textvariable=guivars['count'], width=3) + + if os.path.exists(local_path('README.html')): + def open_readme(): + open_file(local_path('README.html')) + openReadmeButton = Button(countDialogFrame, text='Open Documentation', command=open_readme) + openReadmeButton.pack(side=RIGHT, padx=5) + + countLabel.pack(side=LEFT) + countSpinbox.pack(side=LEFT, padx=2) + countDialogFrame.pack(side=TOP, anchor=W, padx=5, pady=(1,1)) + + + # build gui + ############ + + widgets = {} + + # Add special checkbox to toggle all logic tricks + guivars['all_logic_tricks'] = IntVar(value=0) + widgets['all_logic_tricks'] = Checkbutton(frames['tricks'], text="Enable All Tricks", variable=guivars['all_logic_tricks'], justify=LEFT, wraplength=190, command=update_logic_tricks) + widgets['all_logic_tricks'].pack(expand=False, anchor=W) + + for info in setting_infos: + if info.gui_params: + if info.gui_params['widget'] == 'Checkbutton': + # determine the initial value of the checkbox + default_value = 1 if info.gui_params['default'] == "checked" else 0 + # create a variable to access the box's state + guivars[info.name] = IntVar(value=default_value) + # create the checkbox + widgets[info.name] = Checkbutton(frames[info.gui_params['group']], text=info.gui_params['text'], variable=guivars[info.name], justify=LEFT, wraplength=190, command=show_settings) + widgets[info.name].pack(expand=False, anchor=W) + elif info.gui_params['widget'] == 'Combobox': + # create the variable to store the user's decision + guivars[info.name] = StringVar(value=info.gui_params['default']) + # create the option menu + widgets[info.name] = Frame(frames[info.gui_params['group']]) + # dropdown = OptionMenu(widgets[info.name], guivars[info.name], *(info['options'])) + if isinstance(info.gui_params['options'], list): + info.gui_params['options'] = dict(zip(info.gui_params['options'], info.gui_params['options'])) + dropdown = ttk.Combobox(widgets[info.name], textvariable=guivars[info.name], values=list(info.gui_params['options'].keys()), state='readonly', width=30) + dropdown.bind("<>", show_settings) + dropdown.pack(side=BOTTOM, anchor=W) + # label the option + if 'text' in info.gui_params: + label = Label(widgets[info.name], text=info.gui_params['text']) + label.pack(side=LEFT, anchor=W, padx=5) + # pack the frame + widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) + elif info.gui_params['widget'] == 'Radiobutton': + # create the variable to store the user's decision + guivars[info.name] = StringVar(value=info.gui_params['default']) + # create the option menu + widgets[info.name] = LabelFrame(frames[info.gui_params['group']], text=info.gui_params['text'] if 'text' in info.gui_params else info["name"], labelanchor=NW) + if isinstance(info.gui_params['options'], list): + info.gui_params['options'] = dict(zip(info.gui_params['options'], info.gui_params['options'])) + # setup orientation + side = TOP + anchor = W + if "horizontal" in info.gui_params and info.gui_params["horizontal"]: + side = LEFT + anchor = N + # add the radio buttons + for option in info.gui_params["options"]: + radio_button = Radiobutton(widgets[info.name], text=option, value=option, variable=guivars[info.name], justify=LEFT, wraplength=190, indicatoron=False, command=show_settings) + radio_button.pack(expand=True, side=side, anchor=anchor) + # pack the frame + widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) + elif info.gui_params['widget'] == 'Scale': + # create the variable to store the user's decision + guivars[info.name] = IntVar(value=info.gui_params['default']) + # create the option menu + widgets[info.name] = Frame(frames[info.gui_params['group']]) + # dropdown = OptionMenu(widgets[info.name], guivars[info.name], *(info['options'])) + minval = 'min' in info.gui_params and info.gui_params['min'] or 0 + maxval = 'max' in info.gui_params and info.gui_params['max'] or 100 + stepval = 'step' in info.gui_params and info.gui_params['step'] or 1 + scale = Scale(widgets[info.name], variable=guivars[info.name], from_=minval, to=maxval, tickinterval=stepval, resolution=stepval, showvalue=0, orient=HORIZONTAL, sliderlength=15, length=200, command=show_settings) + scale.pack(side=BOTTOM, anchor=W) + # label the option + if 'text' in info.gui_params: + label = Label(widgets[info.name], text=info.gui_params['text']) + label.pack(side=LEFT, anchor=W, padx=5) + # pack the frame + widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) + elif info.gui_params['widget'] == 'Entry': + # create the variable to store the user's decision + guivars[info.name] = StringVar(value=info.gui_params['default']) + # create the option menu + widgets[info.name] = Frame(frames[info.gui_params['group']]) + + entry = Entry(widgets[info.name], textvariable=guivars[info.name], width=30) + entry.pack(side=BOTTOM, anchor=W) + # label the option + if 'text' in info.gui_params: + label = Label(widgets[info.name], text=info.gui_params['text']) + label.pack(side=LEFT, anchor=W, padx=5) + # pack the frame + widgets[info.name].pack(expand=False, side=TOP, anchor=W, padx=3, pady=3) + + if 'tooltip' in info.gui_params: + ToolTips.register(widgets[info.name], info.gui_params['tooltip']) + + + # pack the hierarchy + + frames['logic'].pack( fill=BOTH, expand=True, anchor=N, side=RIGHT, pady=(5,1) ) + frames['open'].pack( fill=BOTH, expand=True, anchor=W, side=TOP, pady=(5,1) ) + frames['world'].pack( fill=BOTH, expand=True, anchor=W, side=BOTTOM, pady=(5,1) ) + + # Logic tab + frames['rewards'].pack(fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1) ) + frames['tricks'].pack( fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1) ) + + #Other Tab + frames['convenience'].pack(fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1) ) + frames['other'].pack( fill=BOTH, expand=True, anchor=N, side=LEFT, pady=(5,1) ) + + #Aesthetics tab + frames['cosmetics'].pack(fill=BOTH, expand=True, anchor=W, side=TOP) + frames['aesthetic_tab_left'].pack( fill=BOTH, expand=True, anchor=W, side=LEFT) + frames['aesthetic_tab_right'].pack(fill=BOTH, expand=True, anchor=W, side=RIGHT) + + #Aesthetics tab - Left Side + frames['tuniccolor'].pack(fill=BOTH, expand=True, anchor=W, side=TOP, pady=(5,1) ) + frames['lowhp'].pack( fill=BOTH, expand=True, anchor=W, side=TOP, pady=(5,1) ) + + #Aesthetics tab - Right Side + frames['navicolor'].pack( fill=BOTH, expand=True, anchor=W, side=TOP, pady=(5,1) ) + frames['navihint'].pack( fill=BOTH, expand=True, anchor=W, side=TOP, pady=(5,1) ) + - bridgeFrame.pack(expand=True, anchor=E) - kokiriFrame.pack(expand=True, anchor=E) - goronFrame.pack(expand=True, anchor=E) - zoraFrame.pack(expand=True, anchor=E) - lowHealthSFXFrame.pack(expand=True, anchor=E) + notebook.pack(fill=BOTH, expand=True, padx=5, pady=5) + + multiworldFrame = LabelFrame(frames['rom_tab'], text='Multi-World Generation') + countLabel = Label(multiworldFrame, wraplength=350, justify=LEFT, text='This is used for co-op generations. Increasing Player Count will drastically increase the generation time. For more information see:') + hyperLabel = Label(multiworldFrame, wraplength=350, justify=LEFT, text='https://github.com/TestRunnerSRL/bizhawk-co-op', fg='blue', cursor='hand2') + hyperLabel.bind("", lambda event: webbrowser.open_new(r"https://github.com/TestRunnerSRL/bizhawk-co-op")) + countLabel.pack(side=TOP, anchor=W, padx=5, pady=0) + hyperLabel.pack(side=TOP, anchor=W, padx=5, pady=0) + + + worldCountFrame = Frame(multiworldFrame) + countLabel = Label(worldCountFrame, text='Player Count') + guivars['world_count'] = StringVar() + countSpinbox = Spinbox(worldCountFrame, from_=1, to=31, textvariable=guivars['world_count'], width=3) + + countLabel.pack(side=LEFT) + countSpinbox.pack(side=LEFT, padx=2) + worldCountFrame.pack(side=LEFT, anchor=N, padx=10, pady=(1,5)) + + playerNumFrame = Frame(multiworldFrame) + countLabel = Label(playerNumFrame, text='Player ID') + guivars['player_num'] = StringVar() + countSpinbox = Spinbox(playerNumFrame, from_=1, to=31, textvariable=guivars['player_num'], width=3) + + countLabel.pack(side=LEFT) + countSpinbox.pack(side=LEFT, padx=2) + playerNumFrame.pack(side=LEFT, anchor=N, padx=10, pady=(1,5)) + multiworldFrame.pack(side=TOP, anchor=W, padx=5, pady=(1,1)) + + + # didn't refactor the rest, sorry - bottomFrame = Frame(randomizerWindow) - seedLabel = Label(bottomFrame, text='Seed #') - seedVar = StringVar() - seedEntry = Entry(bottomFrame, textvariable=seedVar) - countLabel = Label(bottomFrame, text='Count') - countVar = StringVar() - countSpinbox = Spinbox(bottomFrame, from_=1, to=100, textvariable=countVar) + # create the option menu + + settingsFrame.pack(fill=BOTH, anchor=W, padx=5, pady=(10,0)) + + def multiple_run(settings, window): + orig_seed = settings.seed + for i in range(settings.count): + settings.update_seed(orig_seed + '-' + str(i)) + window.update_title("Generating Seed %s...%d/%d" % (settings.seed, i+1, settings.count)) + main(settings, window) def generateRom(): - guiargs = Namespace - guiargs.seed = int(seedVar.get()) if seedVar.get() else None - guiargs.count = int(countVar.get()) if countVar.get() != '1' else None - guiargs.bridge = bridgeVar.get() - guiargs.kokiricolor = colorVars[0].get() - guiargs.goroncolor = colorVars[1].get() - guiargs.zoracolor = colorVars[2].get() - guiargs.healthSFX = lowHealthSFXVar.get() - guiargs.create_spoiler = bool(createSpoilerVar.get()) - guiargs.suppress_rom = bool(suppressRomVar.get()) - guiargs.compress_rom = bool(compressRomVar.get()) - guiargs.open_forest = bool(openForestVar.get()) - guiargs.open_door_of_time = bool(openDoorVar.get()) - guiargs.fast_ganon = bool(fastGanonVar.get()) - guiargs.nodungeonitems = bool(dungeonItemsVar.get()) - guiargs.beatableonly = bool(beatableOnlyVar.get()) - guiargs.hints = bool(hintsVar.get()) - guiargs.rom = romVar.get() - try: - if guiargs.count is not None: - seed = guiargs.seed - for _ in range(guiargs.count): - main(seed=seed, args=guiargs) - seed = random.randint(0, 999999999) - else: - main(seed=guiargs.seed, args=guiargs) - except Exception as e: - messagebox.showerror(title="Error while creating seed", message=str(e)) + settings = guivars_to_settings(guivars) + if settings.count is not None: + BackgroundTaskProgress(mainWindow, "Generating Seed %s..." % settings.seed, multiple_run, settings) else: - messagebox.showinfo(title="Success", message="Rom patched successfully") + BackgroundTaskProgress(mainWindow, "Generating Seed %s..." % settings.seed, main, settings) - generateButton = Button(bottomFrame, text='Generate Patched Rom', command=generateRom) + generateSeedFrame = Frame(mainWindow) + generateButton = Button(generateSeedFrame, text='Generate Patched ROM', command=generateRom) - seedLabel.pack(side=LEFT) + seedLabel = Label(generateSeedFrame, text='Seed') + guivars['seed'] = StringVar() + seedEntry = Entry(generateSeedFrame, textvariable=guivars['seed'], width=25) + seedLabel.pack(side=LEFT, padx=(55, 5)) seedEntry.pack(side=LEFT) - countLabel.pack(side=LEFT, padx=(5, 0)) - countSpinbox.pack(side=LEFT) generateButton.pack(side=LEFT, padx=(5, 0)) - openOutputButton.pack(side=RIGHT) + generateSeedFrame.pack(side=BOTTOM, anchor=W, padx=5, pady=10) - dropDownFrame.pack(side=LEFT) - rightHalfFrame.pack(side=RIGHT) - topFrame.pack(side=TOP) - bottomFrame.pack(side=BOTTOM) + guivars['checked_version'] = StringVar() - if args is not None: + if settings is not None: # load values from commandline args - createSpoilerVar.set(int(args.create_spoiler)) - suppressRomVar.set(int(args.suppress_rom)) - compressRomVar.set(int(args.compress_rom)) - if args.nodungeonitems: - dungeonItemsVar.set(int(not args.nodungeonitems)) - openForestVar.set(int(args.open_forest)) - openDoorVar.set(int(args.open_door_of_time)) - fastGanonVar.set(int(args.fast_ganon)) - beatableOnlyVar.set(int(args.beatableonly)) - hintsVar.set(int(args.hints)) - if args.count: - countVar.set(str(args.count)) - if args.seed: - seedVar.set(str(args.seed)) - bridgeVar.set(args.bridge) - colorVars[0].set(args.kokiricolor) - colorVars[1].set(args.goroncolor) - colorVars[2].set(args.zoracolor) - lowHealthSFXVar.set(args.healthSFX) - romVar.set(args.rom) - + settings_to_guivars(settings, guivars) + else: + # try to load saved settings + try: + settingsFile = local_path('settings.sav') + with open(settingsFile) as f: + settings = Settings( json.load(f) ) + settings.update_seed("") + settings_to_guivars(settings, guivars) + except: + pass + + show_settings() + + def gui_check_version(): + task = BackgroundTask(mainWindow, check_version, guivars['checked_version'].get()) + while task.running: + mainWindow.update() + + if task.status: + dialog = Dialog(mainWindow, title="Version Error", question=task.status, oktext='Don\'t show again', canceltext='OK') + if dialog.result: + guivars['checked_version'].set(ESVersion) + + mainWindow.after(1000, gui_check_version) mainWindow.mainloop() + # save settings on close + with open('settings.sav', 'w') as outfile: + settings = guivars_to_settings(guivars) + json.dump(settings.__dict__, outfile) + + if __name__ == '__main__': guiMain() diff --git a/GuiUtils.py b/GuiUtils.py index e93616328..5b2782484 100644 --- a/GuiUtils.py +++ b/GuiUtils.py @@ -1,26 +1,41 @@ import queue import threading import tkinter as tk +import traceback -from Utils import local_path +from Utils import data_path, is_bundled def set_icon(window): - er16 = tk.PhotoImage(file=local_path('data/ER16.gif')) - er32 = tk.PhotoImage(file=local_path('data/ER32.gif')) - er48 = tk.PhotoImage(file=local_path('data/ER32.gif')) + er16 = tk.PhotoImage(file=data_path('ER16.gif')) + er32 = tk.PhotoImage(file=data_path('ER32.gif')) + er48 = tk.PhotoImage(file=data_path('ER48.gif')) window.tk.call('wm', 'iconphoto', window._w, er16, er32, er48) # pylint: disable=protected-access + # Although tkinter is intended to be thread safe, there are many reports of issues # some which may be platform specific, or depend on if the TCL library was compiled without # multithreading support. Therefore I will assume it is not thread safe to avoid any possible problems class BackgroundTask(object): - def __init__(self, window, code_to_run): + def __init__(self, window, code_to_run, *code_arg): self.window = window + self.status = None self.queue = queue.Queue() self.running = True - self.process_queue() - self.task = threading.Thread(target=code_to_run, args=(self,)) + self.task = threading.Thread(target=self.try_run, args=(code_to_run, *code_arg)) self.task.start() + self.process_queue() + + def try_run(self, code_to_run, *code_arg): + try: + code_to_run(*code_arg) + except Exception as e: + self.update_status('Error: ' + str(e)) + if not is_bundled(): + traceback.print_exc() + self.queue_event(self.stop) + + def update_status(self, text): + self.status = text def stop(self): self.running = False @@ -44,8 +59,9 @@ def process_queue(self): if self.running: self.window.after(100, self.process_queue) + class BackgroundTaskProgress(BackgroundTask): - def __init__(self, parent, code_to_run, title): + def __init__(self, parent, title, code_to_run, *code_arg): self.parent = parent self.window = tk.Toplevel(parent) self.window['padx'] = 5 @@ -56,26 +72,107 @@ def __init__(self, parent, code_to_run, title): except tk.TclError: pass - self.window.wm_title(title) - self.label_var = tk.StringVar() - self.label_var.set("") - self.label = tk.Label(self.window, textvariable=self.label_var, width=50) + self.window.title(title) + + self.lastpercent = 0 + self.progress_var = tk.DoubleVar() + self.progress = tk.ttk.Progressbar(self.window, variable=self.progress_var, length=300) + self.progress.pack() + + self.label_var = tk.StringVar(value="") + self.label = tk.Label(self.window, textvariable=self.label_var, width=50, wrap=300) self.label.pack() - self.window.resizable(width=False, height=False) + self.button_var = tk.StringVar(value="Please wait...") + self.button = tk.Button(self.window, textvariable=self.button_var, width=10, height=2, state='disabled', command=self.close) + self.button.pack() + + self.window.resizable(width=False, height=False) set_icon(self.window) - self.window.focus() - super().__init__(self.window, code_to_run) + + self.window.transient(parent) + self.window.protocol("WM_DELETE_WINDOW", self.close_pass) + self.window.grab_set() + self.window.geometry("+%d+%d" % (parent.winfo_rootx()+50, parent.winfo_rooty()+150)) + self.window.focus_set() + + super().__init__(self.window, code_to_run, *tuple(list(code_arg) + [self])) + + self.parent.wait_window(self.window) + + def close_pass(self): + pass #safe to call from worker thread def update_status(self, text): self.queue_event(lambda: self.label_var.set(text)) - # only call this in an event callback - def close_window(self): - self.stop() + def update_progress(self, val): + if int(val) != self.lastpercent: + self.lastpercent = int(val) + self.queue_event(lambda: self.progress_var.set(val)) + + def update_title(self, text): + self.queue_event(lambda: self.window.title(text)) + + def close(self): + self.running = False self.window.destroy() + def stop(self): + self.running = False + self.progress_var.set(100) + self.window.bell() + self.button.configure(state='normal') + self.button_var.set("OK") + + +class Dialog(tk.Toplevel): + def __init__(self, parent, title=None, question=None, oktext=None, canceltext=None): + tk.Toplevel.__init__(self, parent) + self.transient(parent) + if title: + self.title(title) + self.parent = parent + self.result = False + + if question: + body = tk.Frame(self) + label = tk.Label(body, text=question, width=50, wrap=200) + label.pack() + body.pack(padx=5, pady=5) + + box = tk.Frame(self) + + w = tk.Button(box, text=oktext if oktext else "OK", width=20, command=self.ok, default=tk.ACTIVE) + w.pack(side=tk.LEFT, padx=5, pady=5) + w = tk.Button(box, text=canceltext if canceltext else "Cancel", width=20, command=self.cancel) + w.pack(side=tk.LEFT, padx=5, pady=5) + + self.bind("", self.ok) + self.bind("", self.cancel) + + box.pack() + + self.grab_set() + self.protocol("WM_DELETE_WINDOW", self.cancel) + self.geometry("+%d+%d" % (parent.winfo_rootx()+50, + parent.winfo_rooty()+150)) + + self.wait_window(self) + + # + # standard button semantics + def ok(self, event=None): + self.result = True + self.withdraw() + self.update_idletasks() + self.cancel() + + def cancel(self, event=None): + # put focus back to the parent window + self.parent.focus_set() + self.destroy() class ToolTips(object): @@ -135,6 +232,7 @@ def getcontroller(cls, widget): @classmethod def register(cls, widget, text): + text = '\n'.join([line.strip() for line in text.splitlines()]).strip() widget.ui_tooltip_text = text tags = list(widget.bindtags()) tags.append(cls.getcontroller(widget)) @@ -156,7 +254,7 @@ def enter(cls, event): cls.popup.overrideredirect(1) cls.popup.withdraw() cls.label = tk.Label( - cls.popup, fg=cls.fg, bg=cls.bg, bd=0, padx=2, justify=tk.LEFT + cls.popup, fg=cls.fg, bg=cls.bg, bd=0, padx=2, justify=tk.LEFT, wrap=400 ) cls.label.pack() cls.active = 0 diff --git a/HintList.py b/HintList.py index 0da6c6ca8..7d0a73078 100644 --- a/HintList.py +++ b/HintList.py @@ -1,245 +1,383 @@ +import random + class Hint(object): name = "" text = "" type = "" - def __init__(self, name, text, type): + def __init__(self, name, text, type, choice=None): self.name = name - self.text = text self.type = type -def getHint(string): - ret = Hint - for hint in hintTable: - if string == hint: - text, type = hintTable[hint] - ret = Hint(hint, text, type) - break + if isinstance(text, str): + self.text = text else: - text, type = hintTable['useless'] - ret = Hint(hint, text, type) - return ret + if choice == None: + self.text = random.choice(text) + else: + self.text = text[choice] + + +def getHint(name, clearer_hint=False): + hint = name + if name not in hintTable: + hint = 'KeyError' + + textOptions, clearText, type = hintTable[hint] + if clearer_hint: + if clearText == None: + return Hint(name, textOptions, type, 0) + return Hint(name, clearText, type) + else: + return Hint(name, textOptions, type) + -def getHintGroup(string): +def getHintGroup(group, world): ret = [] - for hint in hintTable: - text, type = hintTable[hint] - if type == string: - ret.append(Hint(hint, text, type)) + for name in hintTable: + hint = getHint(name, world.clearer_hints) + if hint.type == group and not (name in hintExclusions(world)): + ret.append(hint) return ret -#table of hints, format is (name, hint text, type of hint) there are special characters that are read for certain in game commands: + +#table of hints, format is (name, hint text, clear hint text, type of hint) there are special characters that are read for certain in game commands: # ^ is a box break # & is a new line # @ will print the player name # # sets color to white (currently only used for dungeon reward hints). -hintTable = {'Hammer': (" the dragon smasher.", 'item'), - 'Magic Meter': (" pixie dust.", 'item'), - 'Double Defense': (" a white outline", 'item'), - 'Progressive Hookshot': (" Dampe's Keepsake.", 'item'), - 'Progressive Strength Upgrade': (" power gloves.", 'item'), - 'Hover Boots': (" butter boots.", 'item'), - 'Master Sword': (" evil's bane.", 'item'), - 'Mirror Shield': (" the reflective rampart.", 'item'), - 'Farores Wind': (" teleportation.", 'item'), - 'Nayrus Love': (" a safe space.", 'item'), - 'Ice Arrows': (" the refrigerator rocket.", 'item'), - 'Lens of Truth': (" the perjurless porthole.", 'item'), - 'Dins Fire': (" an inferno.", 'item'), - 'Fairy Ocarina': (" a brown flute.", 'item'), - 'Goron Tunic': (" ruby robes.", 'item'), - 'Zora Tunic': (" a sapphire suit.", 'item'), - 'Iron Boots': (" sink shoes.", 'item'), - 'Zeldas Letter': (" a signed banana.", 'item'), - 'Zeldas Lullaby': (" a song of royal slumber.", 'item'), - 'Nocturne of Shadow': (" a song of spooky spirits.", 'item'), - 'Bow': (" an archery enabler.", 'item'), - 'Bomb Bag': (" an explosive container.", 'item'), - 'Sarias Song': (" a song of dancing gorons.", 'item'), - 'Song of Time': (" a song 7 years long.", 'item'), - 'Song of Storms': (" Rain Dance.", 'item'), - 'Minuet of Forest': (" the song of tall trees.", 'item'), - 'Requiem of Spirit': (" a song of sandy statues.", 'item'), - 'Slingshot': (" a seed shooter.", 'item'), - 'Boomerang': (" a banana.", 'item'), - 'Fire Arrows': (" the furnace firearm.", 'item'), - 'Ocarina of Time': (" blue flute.", 'item'), - 'Bottle': (" a fairy prison.", 'item'), - 'Bottle with Letter': (" a call for help.", 'item'), - 'Bottle with Milk': (" cow juice.", 'item'), - 'Bottle with Red Potion': (" a vitality vial.", 'item'), - 'Bottle with Green Potion': (" a magic mixture.", 'item'), - 'Bottle with Blue Potion': (" an all-cure antidote.", 'item'), - 'Bottle with Fairy': (" an imprisoned fairy.", 'item'), - 'Bottle with Fish': (" an aquarium.", 'item'), - 'Bottle with Blue Fire': (" a conflagration canteen.", 'item'), - 'Bottle with Bugs': (" a terrarium.", 'item'), - 'Bottle with Poe': (" a spooky ghost.", 'item'), - 'Progressive Scale': (" Zora Flippers.", 'item'), - 'Stone of Agony': (" an empty chest.", 'item'), - 'Eponas Song': (" an equestrian etude.", 'item'), - 'Epona': (" a horse.", 'item'), - 'Gerudo Membership Card': (" a GT subscription.", 'item'), - 'Progressive Wallet': (" a mo' money holder.", 'item'), - 'Bolero of Fire': (" a song of lethal lava.", 'item'), - 'Suns Song': (" Sunny Day.", 'item'), - 'Deku Shield': (" a wooden ward.", 'item'), - 'Hylian Shield': (" a steel safeguard.", 'item'), - 'Deku Stick Capacity': (" a bundle of sticks.", 'item'), - 'Deku Nut Capacity': (" more nuts.", 'item'), - 'Prelude of Light': (" a luminous prologue melody.", 'item'), - 'Serenade of Water': (" a song of a damp ditch.", 'item'), - 'Heart Container': (" a lot of love.", 'item'), - 'Piece of Heart': (" love.", 'item'), - 'Piece of Heart (Treasure Chest Game)': (" WINNER!", 'item'), - 'Recovery Heart': (" a free heal.", 'item'), - 'Rupee (1)': (" rare riches.", 'item'), - 'Rupees (5)': (" a common coin.", 'item'), - 'Rupees (20)': (" couch cash.", 'item'), - 'Rupees (50)': (" big bucks.", 'item'), - 'Rupees (200)': (" a juicy jackpot.", 'item'), - 'Light Arrows': (" the shining shot.", 'item'), - 'Kokiri Sword': (" a butter knife.", 'item'), - 'Biggoron Sword': (" a shield disabler.", 'item'), - 'Pocket Egg': (" a cucco container.", 'item'), - 'Pocket Cucco': (" a little clucker.", 'item'), - 'Cojiro': (" a cerulean capon.", 'item'), - 'Odd Mushroom': (" a powder ingredient.", 'item'), - 'Odd Potion': (" granny's goodies.", 'item'), - 'Poachers Saw': (" a tree killer.", 'item'), - 'Broken Sword': (" a shattered slicer.", 'item'), - 'Prescription': (" a pill pamphlet", 'item'), - 'Eyeball Frog': (" a perceiving polliwog.", 'item'), - 'Eyedrops': (" a vision vial.", 'item'), - 'Claim Check': (" a three day wait.", 'item'), - 'Map': (" a dungeon atlas.", 'item'), - 'Compass': (" a treasure tracker.", 'item'), - 'BossKey': (" a master of unlocking.", 'item'), - 'SmallKey': (" a tool for unlocking.", 'item'), - 'useless': (" something worthless.", 'item'), - 'Arrows (5)': (" danger darts.", 'item'), - 'Arrows (10)': (" danger darts.", 'item'), - 'Arrows (30)': (" danger darts.", 'item'), - 'Bombs (5)': (" explosives.", 'item'), - 'Bombs (10)': (" explosives.", 'item'), - 'Bombs (20)': (" lots-o-explosives.", 'item'), - 'Ice Trap': (" a gift from Ganon.", 'item'), - 'Magic Bean': (" wizardly legumes.", 'item'), - 'Bombchus (5)': (" mice bombs.", 'item'), - 'Bombchus (10)': (" mice bombs.", 'item'), - 'Bombchus (20)': (" mice bombs.", 'item'), - 'Deku Nuts (5)': (" some nuts.", 'item'), - 'Deku Nuts (10)': (" lots-o-nuts.", 'item'), - #xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx handy marker for how long one line should be in a text box - '10 Big Poes': ("They say that 10 Big Poes leads&to", 'alwaysLocation'), - 'Deku Theater Mask of Truth': ("They say that the Mask of Truth&yields", 'alwaysLocation'), - '30 Gold Skulltulla Reward': ("They say that slaying&30 Gold Skulltullas&reveals", 'alwaysLocation'), - '40 Gold Skulltulla Reward': ("They say that slaying&40 Gold Skulltullas&reveals", 'alwaysLocation'), - '50 Gold Skulltulla Reward': ("They say that slaying&50 Gold Skulltullas&reveals", 'alwaysLocation'), - 'Song from Ocarina of Time': ("They say the Ocarina of Time&teaches", 'alwaysLocation'), - 'Biggoron': ("They say that Biggoron&crafts", 'alwaysLocation'), - 'Child Fishing': ("They say that fishing in youth&bestows", 'location'), - 'Adult Fishing': ("They say that fishing in maturity&bestows", 'location'), - '20 Gold Skulltulla Reward': ("They say that slaying&20 Gold Skulltullas&reveals", 'location'), - 'Treasure Chest Game': ("They say that gambling&grants", 'location'), - 'Darunias Joy': ("They say that Darunia's dance leads&to", 'location'), - 'Frog Ocarina Game': ("They say The Frogs of Zora River&hold", 'location'), - 'Horseback Archery 1500 Points': ("They say that mastery of horseback&archery grants", 'location'), - 'Lake Hylia Sun': ("They say staring into the sun&grants", 'location'), - 'Heart Piece Grave Chest': ("They say there's a hidden location&where the Sun's Song&spawns", 'location'), - 'Goron City Leftmost Maze Chest': ("They say in Goron City the hammer&unlocks", 'location'), - 'Chest Above King Dodongo': ("They say that the chest above the&Infernal Dinosaur&contains", 'location'), - 'Forest Temple Floormaster Chest': ("Deep in the forest, shadows guard a&chest containing", 'location'), - 'Fire Temple Scarecrow Chest': ("They say high in the Fire Temple,&Pierre hid", 'location'), - 'Fire Temple Megaton Hammer Chest': ("They say that the highest&chest in the crater&holds", 'location'), - 'Water Temple River Chest': ("They say deep under the lake&beyond the currents&hides", 'location'), - 'Water Temple Boss Key Chest': ("Deep under the lake,&the gilded chest&contains", 'location'), - 'Gerudo Training Grounds Underwater Silver Rupee Chest': ("They say those who seek&sunken silver rupees will&find", 'location'), - 'Gerudo Training Grounds Maze Path Final Chest': ("They say that past all the locked&doors is", 'location'), - 'Bottom of the Well Defeat Boss': ("They say that Dead Hand&holds", 'location'), - 'Silver Gauntlets Chest': ("They say that upon&the Colossus's southern edge&is", 'location'), - 'Mirror Shield Chest': ("They say that upon&the Colossus's northern edge&is", 'location'), - 'Shadow Temple Hidden Floormaster Chest': ("They say in a maze&guarded by shadows&hides", 'location'), - 'Haunted Wasteland Structure Chest': ("They say that deep in the Wasteland&is", 'location'), - 'Composer Grave Chest': ("They say that the Composer Brothers&hid", 'location'), - 'Song from Composer Grave': ("They say that the Composer Brothers&wrote", 'location'), - 'Song at Windmill': ("They say that Guru-guru is driven&mad by", 'location'), - 'Sheik Forest Song': ("They say that deep&in the forest Sheik&teaches", 'location'), - 'Sheik at Temple': ("They say that Sheik&waits at a monument to time to&teach", 'location'), - 'Sheik in Crater': ("They say that the craters melody&is", 'location'), - 'Sheik in Ice Cavern': ("They say that the&frozen cavern echoes&with", 'location'), - 'Sheik in Kakariko': ("They say that a&ravaged village mourns&with", 'location'), - 'Sheik at Colossus': ("They say that a hero ventures&beyond the Wasteland to&learn", 'location'), - 'Zoras Fountain Bottom Freestanding PoH': ("They say under the icy waters&lies", 'location'), - 'Colossus Freestanding PoH': ("They say that riding a&beanstalk in the desert&leads to", 'location'), - 'DM Crater Volcano Freestanding PoH': ("They say that riding a&beanstalk in the crater&leads to", 'location'), - 'Goron City Pot Freestanding PoH': ("They say that spinning&Goron pottery&contains", 'location'), - #xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx handy marker for how long one line should be in a text box - '1001': ("Ganondorf 2020!", 'junkHint'), - '1002': ("They say that monarchy is a&terrible system of governance.", 'junkHint'), - '1003': ("They say that Zelda is a poor&leader.", 'junkHint'), - '1004': ("These hints can be quite useful.&This is an exception.", 'junkHint'), - '1005': ("The Stone of Agony is in your&inventory.", 'junkHint'), - '1006': ("They say that all the Zora drowned&in Wind Waker.", 'junkHint'), - '1007': ("They say that PJ64 is a terrible&emulator.", 'junkHint'), - '1008': ("'Member when Ganon was a blue pig?^I 'member.", 'junkHint'), - '1009': ("One who does not have Triforce&can't go in.", 'junkHint'), - '1010': ("Save your future,&end the Happy Mask Salesmen.", 'junkHint'), - '1011': ("Early Agony equals likely&troll seed.", 'junkHint'), - '1012': ("I'm stoned. Get it?", 'junkHint'), - '1013': ("Hoot! Hoot! Would you like me to&repeat that?", 'junkHint'), - '1014': ("Gorons are stupid.&They eat rocks.", 'junkHint'), - '1015': ("They say that Lon Lon Ranch&prospered under Ingo.", 'junkHint'), - '1016': ("The single rupee is a&unique item.", 'junkHint'), - '1017': ("Without the Lens of Truth, the&Treasure Chest Mini-Game&is a 1 out of 32 chance.^Good luck!", 'junkHint'), - '1018': ("Use bombs wisely.", 'junkHint'), - '1019': ("Bomchus are not considered&in logic.", 'junkHint'), - '1021': ("I found you faker!", 'junkHint'), - '1022': ("You're comparing&yourself to me?^Ha! You're not even good&enough to be my fake.", 'junkHint'), - '1023': ("I'll make you eat those words.", 'junkHint'), - '1024': ("What happened to Sheik?", 'junkHint'), - '1025': ("L2P @.", 'junkHint'), - '1026': ("I heard @ isn't&very good at Zelda.", 'junkHint'), - '1027': ("I'm Lunk from Pennsylvania.", 'junkHint'), - '1028': ("I bet you'd like to&have more bombs.", 'junkHint'), - '1029': ("When all else fails&use Fire.", 'junkHint'), - '1030': ("Here's a hint @.&Don't be bad.", 'junkHint'), - '1031': ("Game Over.&Return of Ganon.", 'junkHint'), - '1032': ("May the way of the Hero&lead to the Triforce.", 'junkHint'), - '1033': ("Can't find an item?&Scan an Amiibo.", 'junkHint'), - '1034': ("They say this game has&just a few glitches.", 'junkHint'), - '1035': ("BRRING BRRING This is Ulrira.&Wrong number?", 'junkHint'), - '1036': ("Tingle Tingle Kooloo Limpah", 'junkHint'), - '1037': ("L is real 2041", 'junkHint'), - '1038': ("They say that Ganondorf will&appear in the next Mario Tennis.", 'junkHint'), - '1039': ("Medigoron sells the earliest&Breath of the Wild demo.", 'junkHint'), - '1040': ("There's a reason why I am special&inquisitor!", 'junkHint'), - '1041': ("You were almost a @&sandwich.", 'junkHint'), - '1042': ("I'm a helpful hint Gossip Stone!^See I'm helping.", 'junkHint'), - #xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx handy marker for how long one line should be in a text box - 'Queen Gohma': ("One inside an #ancient tree#...^", 'boss'), - 'King Dodongo': ("One within an #immense cavern#...^", 'boss'), - 'Barinade': ("One in the #belly of a deity#...^", 'boss'), - 'Phantom Ganon': ("One in a #deep forest#...^", 'boss'), - 'Volvagia': ("One on a #high mountain#...^", 'boss'), - 'Morpha': ("One under a #vast lake#...^", 'boss'), - 'Bongo Bongo': ("One within the #house of the dead#...^", 'boss'), - 'Twinrova': ("One inside a #goddess of the sand#...^", 'boss'), - 'Links Pocket': ("One in #@'s pocket#...^", 'boss'), - 'Spiritual Stone Text Start': ("Ye who owns 3 Spiritual Stones...^", 'boss'), - 'Spiritual Stone Text End': ("Stand with the Ocarina of Time&and play the Song of Time.", 'boss'), - 'Medallion Text End': ("Together with the Hero of Time,&the awakened ones will bind the&evil and return the light of peace&to the world.", 'boss'), - #xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx handy marker for how long one line should be in a text box - 'Validation Line': ("Hmph... Since you made it this far&I'll let you know what glorious&prize of Ganon's you likely&missed out on in my tower.^Behold...^", 'validation line'), - 'Light Arrow Location': ("Ha ha ha... You'll never beat me by&reflecting my lightning bolts&and unleashing the arrows from&", 'Light Arrow Location'), - '2001': ("Oh! It's @.&I was expecting someone called&Sheik. Do you know what&happened to them?", 'ganonLine'), - '2002': ("I knew I shouldn't have put the key&on the other side of my door.", 'ganonLine'), - '2003': ("Looks like it's time for a&round of tennis.", 'ganonLine'), - '2004': ("You'll never deflect my bolts of&energy with your sword,&then shot me with those Light&Arrows you happen to have.", 'ganonLine'), - '2005': ("Why did I leave my trident&back in the desert?", 'ganonLine'), - '2006': ("Zelda is probably going to do&something stupid, like send you&back to your own timeline.^So this is quite meaningless.&Do you really want&to save this moron?", 'ganonLine'), - '2007': ("What about Zelda makes you think&she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the hungry,&and my castle floats.", 'ganonLine'), - '2008': ("I've learned this spell,&it's really neat,&I'll keep it later&for your treat!", 'ganonLine'), - '2009': ("Many tricks are up my sleeve,&to save yourself&you'd better leave!", 'ganonLine'), - '2010': ("After what you did to&Koholint Island how can&you call me the bad guy?", 'ganonLine'), - '2011': ("Today let's begin down&'The Hero is Defeated' timeline.", 'ganonLine')} +hintTable = { + 'Magic Meter': (["mystic training", "pixie dust", "a green rectangle"], "a Magic Meter", 'item'), + 'Double Defense': (["a white outline", "damage decrease", "strengthened love"], "Double Defense", 'item'), + 'Slingshot': (["a seed shooter", "a rubberband", "a child's catapult"], "a Slingshot", 'item'), + 'Boomerang': (["a banana", "a stun stick"], "the Boomerang", 'item'), + 'Bow': (["an archery enabler", "a danger dart launcher"], "a Bow", 'item'), + 'Bomb Bag': (["an explosive container", "a blast bag"], "a Bomb Bag", 'item'), + 'Progressive Hookshot': (["Dampe's keepsake", "the Grapple Beam", "the BOING! chain"], "a Hookshot", 'item'), + 'Progressive Strength Upgrade': (["power gloves", "metal mittens", "the heavy lifty"], "a Strength Upgrade", 'item'), + 'Progressive Scale': (["a deeper dive", "a piece of Zora"], "a Zora Scale", 'item'), + 'Hammer': (["the dragon smasher", "the metal mallet", "the heavy hitter"], "the Megaton Hammer", 'item'), + 'Iron Boots': (["sink shoes", "clank cleats"], "the Iron Boots", 'item'), + 'Hover Boots': (["butter boots", "sacred slippers", "spacewalkers"], "the Hover Boots", 'item'), + 'Kokiri Sword': (["a butter knife", "a starter slasher", "a switchblade"], "the Kokiri Sword", 'item'), + 'Biggoron Sword': (["the biggest blade", "a colossal cleaver"], "the Biggoron Sword", 'item'), + 'Master Sword': (["evil's bane"], "the Master Sword", 'item'), + 'Deku Shield': (["a wooden ward", "a burnable barrier"], "a Deku Shield", 'item'), + 'Hylian Shield': (["a steel safeguard", "Like Like's metal meal"], "a Hylian Shield", 'item'), + 'Mirror Shield': (["the reflective rampart", "Medusa's weakness", "a silvered surface"], "the Mirror Shield", 'item'), + 'Farores Wind': (["teleportation", "a relocation rune", "a green ball", "a green gust"], "Farore's Wind", 'item'), + 'Nayrus Love': (["a safe space", "an impregnable aura", "a blue barrier", "a blue crystal"], "Nayru's Love", 'item'), + 'Dins Fire': (["an inferno", "a heat wave", "a red ball"], "Din's Fire", 'item'), + 'Fire Arrows': (["the furnace firearm", "the burning bolts", "a magma missile"], "the Fire Arrows", 'item'), + 'Ice Arrows': (["the refrigerator rocket", "the frostbite bolts", "an iceberg maker"], "the Ice Arrows", 'item'), + 'Light Arrows': (["the shining shot", "the luminous launcher", "Ganondorf's bane", "the lighting bolts"], "the Light Arrows", 'item'), + 'Lens of Truth': (["a lie detector", "a ghost tracker", "true sight", "a detective's tool"], "the Lens of Truth", 'item'), + 'Ocarina': (["a flute", "a music maker"], "an Ocarina", 'item'), + 'Fairy Ocarina': (["a brown flute", "a forest instrument"], "the Fairy Ocarina", 'item'), + 'Ocarina of Time': (["a blue flute", "a royal instrument"], "the Ocarina of Time", 'item'), + 'Goron Tunic': (["ruby robes", "fireproof fabric", "cooking clothes"], "a Goron Tunic", 'item'), + 'Zora Tunic': (["a sapphire suit", "scuba gear", "a swimsuit"], "a Zora Tunic", 'item'), + 'Epona': (["a horse", "a four legged friend"], "Epona", 'item'), + 'Zeldas Lullaby': (["a song of royal slumber", "a triforce tune"], "Zelda's Lullaby", 'item'), + 'Eponas Song': (["an equestrian etude", "Malon's melody", "a ranch song"], "Epona's Song", 'item'), + 'Sarias Song': (["a song of dancing Gorons", "Saria's phone number"], "Saria's Song", 'item'), + 'Suns Song': (["Sunny Day", "the ReDead's bane", "the Gibdo's bane"], "the Sun's Song", 'item'), + 'Song of Time': (["a song 7 years long", "the tune of ages"], "the Song of Time", 'item'), + 'Song of Storms': (["Rain Dance", "a thunderstorm tune", "windmill acceleration"], "the Song of Storms", 'item'), + 'Minuet of Forest': (["the song of tall trees", "an arboreal anthem", "a green spark trail"], "the Minuet of Forest", 'item'), + 'Bolero of Fire': (["a song of lethal lava", "a red spark trail", "a volcanic verse"], "the Bolero of Fire", 'item'), + 'Serenade of Water': (["a song of a damp ditch", "a blue spark trail", "the lake's lyric"], "the Serenade of Water", 'item'), + 'Requiem of Spirit': (["a song of sandy statues", "an orange spark trail", "the desert ditty"], "the Requiem of Spirit", 'item'), + 'Nocturne of Shadow': (["a song of spooky spirits", "a graveyard boogie", "a haunted hymn", "a purple spark trail"], "the Nocturne of Shadow", 'item'), + 'Prelude of Light': (["a luminous prologue melody", "a yellow spark trail", "the temple traveler"], "the Prelude of Light", 'item'), + 'Bottle': (["a glass container", "an empty jar", "encased air"], "a Bottle", 'item'), + 'Bottle with Letter': (["a call for help", "the note that Mweeps", "an SOS call", "a fishy stationery"], "Ruto's Letter", 'item'), + 'Bottle with Milk': (["cow juice", "a white liquid", "a baby's breakfast"], "a Milk Bottle", 'item'), + 'Bottle with Red Potion': (["a vitality vial", "a red liquid"], "a Red Potion Bottle", 'item'), + 'Bottle with Green Potion': (["a magic mixture", "a green liquid"], "a Green Potion Bottle", 'item'), + 'Bottle with Blue Potion': (["an ailment antidote", "a blue liquid"], "a Blue Potion Bottle", 'item'), + 'Bottle with Fairy': (["an imprisoned fairy", "an extra life", "Navi's cousin"], "a Fairy Bottle", 'item'), + 'Bottle with Fish': (["an aquarium", "a deity's snack"], "a Fish Bottle", 'item'), + 'Bottle with Blue Fire': (["a conflagration canteen", "an icemelt jar"], "a Blue Fire Bottle", 'item'), + 'Bottle with Bugs': (["an insectarium", "Skulltula finders"], "a Bug Bottle", 'item'), + 'Bottle with Poe': (["a spooky ghost", "a face in the jar"], "a Poe Bottle", 'item'), + 'Bottle with Big Poe': (["the spookiest ghost", "a sidequest spirit"], "a Big Poe Bottle", 'item'), + 'Stone of Agony': (["the shake stone", "the Rumble Pak (TM)"], "the Stone of Agony", 'item'), + 'Gerudo Membership Card': (["a girl club membership", "a desert tribe's pass"], "the Gerudo Card", 'item'), + 'Progressive Wallet': (["a mo' money holder", "a gem purse", "a portable bank"], "a Wallet", 'item'), + 'Deku Stick Capacity': (["a lumber rack", "more flammable twigs"], "Deku Stick Capacity", 'item'), + 'Deku Nut Capacity': (["more nuts", "flashbang storage"], "Deku Nut Capacity", 'item'), + 'Heart Container': (["a lot of love", "a Valentine's gift", "a boss's organ"], "a Heart Container", 'item'), + 'Piece of Heart': (["a little love", "a broken heart"], "a Piece of Heart", 'item'), + 'Piece of Heart (Treasure Chest Game)': ("a victory valentine", "a Piece of Heart", 'item'), + 'Recovery Heart': (["a free heal", "a hearty meal", "a Band-Aid"], "a Recovery Heart", 'item'), + 'Rupee (Treasure Chest Game)': ("the dollar of defeat", 'a Green Rupee', 'item'), + 'Deku Stick (1)': ("a breakable branch", 'a Deku Stick', 'item'), + 'Rupee (1)': (["a unique coin", "a penny", "a green gem"], "a Green Rupee", 'item'), + 'Rupees (5)': (["a common coin", "a blue gem"], "a Blue Rupee", 'item'), + 'Rupees (20)': (["couch cash", "a red gem"], "a Red Rupees", 'item'), + 'Rupees (50)': (["big bucks", "a purple gem", "wealth"], "a Purple Rupee", 'item'), + 'Rupees (200)': (["a juicy jackpot", "a yellow gem", "a giant gem", "great wealth"], "a Huge Rupee", 'item'), + 'Weird Egg': (["a chicken dilemma"], "the Weird Egg", 'item'), + 'Zeldas Letter': (["an autograph", "royal stationery", "royal snail mail"], "Zelda's Letter", 'item'), + 'Pocket Egg': (["a Cucco container", "a Cucco, eventually", "a fowl youth"], "the Pocket Egg", 'item'), + 'Pocket Cucco': (["a little clucker"], "the Pocket Cucco", 'item'), + 'Cojiro': (["a cerulean capon"], "Cojiro", 'item'), + 'Odd Mushroom': (["a powder ingredient"], "an Odd Mushroom", 'item'), + 'Odd Potion': (["Granny's goodies"], "an Odd Potion", 'item'), + 'Poachers Saw': (["a tree killer"], "the Poacher's Saw", 'item'), + 'Broken Sword': (["a shattered slicer"], "the Broken Sword", 'item'), + 'Prescription': (["a pill pamphlet", "a doctor's note"], "the Prescription", 'item'), + 'Eyeball Frog': (["a perceiving polliwog"], "the Eyeball Frog", 'item'), + 'Eyedrops': (["a vision vial"], "the Eyedrops", 'item'), + 'Claim Check': (["a three day wait"], "the Claim Check", 'item'), + 'Map': (["a dungeon atlas", "blueprints"], "a Map", 'item'), + 'Compass': (["a treasure tracker", "a magnetic needle"], "a Compass", 'item'), + 'BossKey': (["a master of unlocking", "a dungeon's master pass"], "a Boss Key", 'item'), + 'SmallKey': (["a tool for unlocking", "a dungeon pass", "a lock remover", "a lockpick"], "a Small Key", 'item'), + 'FortressSmallKey': (["a get out of jail free card"], "a Jail Key", 'item'), + 'KeyError': (["something mysterious", "an unknown treasure"], "An Error (Please Report This)", 'item'), + 'Arrows (5)': (["a few danger darts", "a few sharp shafts"], "Arrows (5 pieces)", 'item'), + 'Arrows (10)': (["some danger darts", "some sharp shafts"], "Arrows (10 pieces)", 'item'), + 'Arrows (30)': (["plenty of danger darts", "plenty of sharp shafts"], "Arrows (30 pieces)", 'item'), + 'Bombs (5)': (["a few explosives", "a few blast balls"], "Bombs (5 pieces)", 'item'), + 'Bombs (10)': (["some explosives", "some blast balls"], "Bombs (10 pieces)", 'item'), + 'Bombs (20)': (["lots-o-explosives", "plenty of blast balls"], "Bombs (20 pieces)", 'item'), + 'Ice Trap': (["a gift from Ganon", "a chilling discovery", "frosty fun"], "an Ice Trap", 'item'), + 'Magic Bean': (["wizardly legumes"], "a Magic Bean", 'item'), + 'Bombchus': (["mice bombs", "proximity mice", "wall crawlers", "trail blazers"], "Bombchus", 'item'), + 'Bombchus (5)': (["a few mice bombs", "a few proximity mice", "a few wall crawlers", "a few trail blazers"], "Bombchus (5 pieces)", 'item'), + 'Bombchus (10)': (["some mice bombs", "some proximity mice", "some wall crawlers", "some trail blazers"], "Bombchus (10 pieces)", 'item'), + 'Bombchus (20)': (["plenty of mice bombs", "plenty of proximity mice", "plenty of wall crawlers", "plenty of trail blazers"], "Bombchus (20 pieces)", 'item'), + 'Deku Nuts (5)': (["some nuts", "some flashbangs", "some scrub spit"], "Deku Nuts (5 pieces)", 'item'), + 'Deku Nuts (10)': (["lots-o-nuts", "plenty of flashbangs", "plenty of scrub spit"], "Deku Nuts (10 pieces)", 'item'), + 'Deku Seeds (30)': (["catapult ammo", "lots-o-seeds"], "Deku Seeds (30 pieces)", 'item'), + 'Gold Skulltula Token': (["proof of destruction", "an arachnid chip", "spider remains", "one percent of a curse"], "a Gold Skulltula Token", 'item'), + + '10 Big Poes': (["#Big Poes# leads to", "#ghost hunters# will be rewarded with"], None, 'alwaysLocation'), + 'Deku Theater Mask of Truth': ("the #Mask of Truth# yields", None, 'alwaysLocation'), + '20 Gold Skulltula Reward': ("slaying #20 Gold Skulltulas# reveals", None, 'location'), + '30 Gold Skulltula Reward': ("slaying #30 Gold Skulltulas# reveals", None, 'alwaysLocation'), + '40 Gold Skulltula Reward': ("slaying #40 Gold Skulltulas# reveals", None, 'alwaysLocation'), + '50 Gold Skulltula Reward': ("slaying #50 Gold Skulltulas# reveals", None, 'alwaysLocation'), + 'Ocarina of Time': ("They say the #treasure thrown by Princess Zelda# is", None, 'alwaysLocation'), + 'Song from Ocarina of Time': ("the #Ocarina of Time# teaches", None, 'alwaysLocation'), + 'Biggoron': ("#Biggoron# crafts", None, 'alwaysLocation'), + 'Child Fishing': ("#fishing in youth# bestows", None, 'location'), + 'Adult Fishing': ("#fishing in maturity# bestows", None, 'location'), + 'Treasure Chest Game': (["#gambling# grants", "there is a #1/32 chance# to win"], "the #treasure chest game# grants", 'location'), + 'Darunias Joy': ("#Darunia's dance# leads to", None, 'location'), + 'Frog Ocarina Game': (["The #Frogs of Zora River# hold", "the #musical amphibians# have found"], None, 'location'), + 'Horseback Archery 1500 Points': ("mastery of #horseback archery# grants", "scoring 1500 in #horseback archery# grants", 'location'), + 'Lake Hylia Sun': ("staring into #the sun# grants", "shooting #the sun# grants", 'location'), + 'Heart Piece Grave Chest': ("playing #Sun's Song# in a grave spawns", None, 'location'), + 'Goron City Leftmost Maze Chest': ("in #Goron City# the hammer unlocks", None, 'location'), + 'GS Hyrule Castle Grotto': ("a #storm near the castle# reveals", None, 'location'), + 'GS Hyrule Field Near Gerudo Valley': ("buried near #the valley# a spider holds", None, 'location'), + 'GS Zora\'s Fountain Hidden Cave': ("a spider high above the #icy waters# holds", None, 'location'), + 'Forest Temple Floormaster Chest': ("deep in #the forest#, shadows guard a chest containing", "a Floormaster in #Forest Temple# guards", 'location'), + 'Fire Temple Scarecrow Chest': ("high in the #Fire Temple#, Pierre hid", None, 'location'), + 'Fire Temple Megaton Hammer Chest': ("high in the #Fire Temple#, Flare Dancers hid", None, 'location'), + 'Fire Temple MQ West Tower Top Chest': ("high in the #Fire Temple#, Flare Dancers hid", None, 'location'), + 'Water Temple River Chest': ("deep under #the lake#, beyond the currents, hides", "the #Water Temple River Chest# holds", 'location'), + 'Water Temple Boss Key Chest': ("deep under #the lake#, the gilded chest contains", "the #Water Temple Gilded Chest# holds", 'location'), + 'Water Temple MQ Boss Key Chest': ("deep under #the lake#, the gilded chest contains", "the #Water Temple Gilded Chest# holds", 'location'), + 'Water Temple MQ Freestanding Key': ("deep under #the lake#, the apparent key is really", None, 'location'), + 'GS Water Temple MQ North Basement': ("deep under #the lake#, the locked spider holds", None, 'location'), + 'Gerudo Training Grounds Underwater Silver Rupee Chest': ("those who seek #sunken silver rupees# will find", None, 'location'), + 'Gerudo Training Grounds MQ Underwater Silver Rupee Chest': ("those who seek #sunken silver rupees# will find", None, 'location'), + 'Gerudo Training Grounds Maze Path Final Chest': ("the final prize of #the thieves\' training# is", None, 'location'), + 'Gerudo Training Grounds MQ Ice Arrows Chest': ("the final prize of #the thieves\' training# is", None, 'location'), + 'Bottom of the Well Defeat Boss': ("#Dead Hand# holds", "#Dead Hand# in the well holds", 'location'), + 'Bottom of the Well MQ Compass Chest': ("#Dead Hand# holds", "#Dead Hand# in the well holds", 'location'), + 'Silver Gauntlets Chest': ("upon the #Colossus's right hand# is", None, 'location'), + 'Mirror Shield Chest': ("upon the #Colossus's left hand# is", None, 'location'), + 'Spirit Temple MQ Child Center Chest': ("within #the Colossus# a temporal paradox yields", None, 'location'), + 'Spirit Temple MQ Lower Adult Right Chest': ("within #the Colossus# a symphony yields", None, 'location'), + 'GS Spirit Temple MQ Lower Adult Right': ("within #the Colossus# a spider's symphony yields", None, 'location'), + 'Shadow Temple Hidden Floormaster Chest': (["shadows in an #invisible maze# guard", "after a free #boat ride# comes"], None, 'location'), + 'Shadow Temple MQ Bomb Flower Chest': (["shadows in an #invisible maze# guard", "after a free #boat ride# comes"], None, 'location'), + 'Haunted Wasteland Structure Chest': (["deep in the #Wasteland# is", "beneath #the sands#, flames reveal"], None, 'location'), + 'Composer Grave Chest': (["in the #Composers' Grave#, darkness hides", "the #Composer Brothers# hid"], None, 'location'), + 'Song from Composer Grave': (["in the #Composers' Grave#, ReDead guard", "the #Composer Brothers# wrote"], None, 'location'), + 'Sheik Forest Song': ("deep in #the forest# Sheik teaches", None, 'location'), + 'Sheik at Temple': ("Sheik waits at a #monument to time# to teach", None, 'location'), + 'Sheik in Crater': ("the #crater's melody# is", None, 'location'), + 'Sheik in Ice Cavern': ("the #frozen cavern# echoes with", None, 'location'), + 'Sheik in Kakariko': ("a #ravaged village# mourns with", None, 'location'), + 'Sheik at Colossus': ("a hero ventures beyond #the Wasteland# to learn", None, 'location'), + 'Zoras Fountain Bottom Freestanding PoH': ("under the #icy waters# lies", None, 'location'), + 'Colossus Freestanding PoH': ("riding a #beanstalk in the desert# leads to", None, 'location'), + 'DM Crater Volcano Freestanding PoH': ("riding a #beanstalk in the crater# leads to", None, 'location'), + 'Goron City Pot Freestanding PoH': ("spinning #Goron pottery# contains", None, 'location'), + 'Deku Tree MQ After Spinning Log Chest': ("within #a tree#, a temporal stone contains", None, 'location'), + 'GS Jabu Jabu MQ Invisible Enemies Room': ("in the #belly of a deity#, a spider surrounded by shadows holds", None, 'location'), + + '1001': ("Ganondorf 2020!", None, 'junkHint'), + '1002': ("They say that monarchy is a terrible system of governance.", None, 'junkHint'), + '1003': ("They say that Zelda is a poor leader.", None, 'junkHint'), + '1004': ("These hints can be quite useful. This is an exception.", None, 'junkHint'), + '1006': ("They say that all the Zora drowned in Wind Waker.", None, 'junkHint'), + '1007': ("They say that PJ64 is a terrible emulator.", None, 'junkHint'), + '1008': ("'Member when Ganon was a blue pig?^I 'member.", None, 'junkHint'), + '1009': ("One who does not have Triforce can't go in.", None, 'junkHint'), + '1010': ("Save your future, end the Happy Mask Salesman.", None, 'junkHint'), + '1012': ("I'm stoned. Get it?", None, 'junkHint'), + '1013': ("Hoot! Hoot! Would you like me to repeat that?", None, 'junkHint'), + '1014': ("Gorons are stupid. They eat rocks.", None, 'junkHint'), + '1015': ("They say that Lon Lon Ranch prospered under Ingo.", None, 'junkHint'), + '1016': ("The single rupee is a unique item.", None, 'junkHint'), + '1017': ("Without the Lens of Truth, the Treasure Chest Mini-Game is a 1 out of 32 chance.^Good luck!", None, 'junkHint'), + '1018': ("Use bombs wisely.", None, 'junkHint'), + '1021': ("I found you, faker!", None, 'junkHint'), + '1022': ("You're comparing yourself to me?^Ha! You're not even good enough to be my fake.", None, 'junkHint'), + '1023': ("I'll make you eat those words.", None, 'junkHint'), + '1024': ("What happened to Sheik?", None, 'junkHint'), + '1025': ("L2P @.", None, 'junkHint'), + '1026': ("I heard @ isn't very good at Zelda.", None, 'junkHint'), + '1027': ("I'm Lonk from Pennsylvania.", None, 'junkHint'), + '1028': ("I bet you'd like to have more bombs.", None, 'junkHint'), + '1029': ("When all else fails, use Fire.", None, 'junkHint'), + '1030': ("Here's a hint, @. Don't be bad.", None, 'junkHint'), + '1031': ("Game Over. Return of Ganon.", None, 'junkHint'), + '1032': ("May the way of the Hero lead to the Triforce.", None, 'junkHint'), + '1033': ("Can't find an item? Scan an Amiibo.", None, 'junkHint'), + '1034': ("They say this game has just a few glitches.", None, 'junkHint'), + '1035': ("BRRING BRRING This is Ulrira. Wrong number?", None, 'junkHint'), + '1036': ("Tingle Tingle Kooloo Limpah", None, 'junkHint'), + '1037': ("L is real 2041", None, 'junkHint'), + '1038': ("They say that Ganondorf will appear in the next Mario Tennis.", None, 'junkHint'), + '1039': ("Medigoron sells the earliest Breath of the Wild demo.", None, 'junkHint'), + '1040': ("There's a reason why I am special inquisitor!", None, 'junkHint'), + '1041': ("You were almost a @ sandwich.", None, 'junkHint'), + '1042': ("I'm a helpful hint Gossip Stone!^See, I'm helping.", None, 'junkHint'), + '1043': ("Dear @, please come to the castle. I've baked a cake for you.&&Yours truly, princess Zelda.", None, 'junkHint'), + '1044': ("They say all toasters toast toast.", None, 'junkHint'), + '1045': ("They say that Okami is the best Zelda game.", None, 'junkHint'), + '1046': ("They say that quest guidance can be found at a talking rock.", None, 'junkHint'), + '1047': ("They say that the final item you're looking for can be found somewhere in Hyrule", None, 'junkHint'), + '1048': ("Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.", None, 'junkHint'), + '1049': ("They say that Barinade fears Deku Nuts.", None, 'junkHint'), + '1050': ("They say that Flare Dancers do not fear Goron-crafted blades.", None, 'junkHint'), + '1051': ("They say that Morpha is easily trapped in a corner.", None, 'junkHint'), + '1052': ("They say that Bongo Bongo really hates the cold.", None, 'junkHint'), + '1053': ("They say that crouch stabs mimic the effects of your last attack.", None, 'junkHint'), + '1054': ("They say that bombing the hole Volvagia last flew into can be rewarding.", None, 'junkHint'), + '1055': ("They say that invisible ghosts can be exposed with Deku Nuts.", None, 'junkHint'), + '1056': ("They say that the real Phantom Ganon is bright and loud.", None, 'junkHint'), + '1057': ("They say that walking backwards is very fast.", None, 'junkHint'), + '1058': ("They say that leaping above the Castle Town entrance enriches most children.", None, 'junkHint'), + #xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx handy marker for how long one line should be in a text box + 'Deku Tree': ("an ancient tree", "Deku Tree", 'dungeon'), + 'Dodongos Cavern': ("an immense cavern", "Dodongo's Cavern", 'dungeon'), + 'Jabu Jabus Belly': ("the belly of a deity", "Jabu Jabu's Belly", 'dungeon'), + 'Forest Temple': ("a deep forest", "Forest Temple", 'dungeon'), + 'Fire Temple': ("a high mountain", "Fire Temple", 'dungeon'), + 'Water Temple': ("a vast lake", "Water Temple", 'dungeon'), + 'Shadow Temple': ("the house of the dead", "Shadow Temple", 'dungeon'), + 'Spirit Temple': ("the goddess of the sand", "Spirit Temple", 'dungeon'), + 'Ice Cavern': ("a frozen maze", "Ice Cavern", 'dungeon'), + 'Bottom of the Well': ("a shadow\'s prison", "Bottom of the Well", 'dungeon'), + 'Gerudo Training Grounds': ("the test of thieves", "Gerudo Training Grounds", 'dungeon'), + 'Ganons Castle': ("a conquered citadel", "Ganon's Castle", 'dungeon'), + #xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx handy marker for how long one line should be in a text box + 'Queen Gohma': ("One inside an #ancient tree#...^", "One in the #Deku Tree#...^", 'boss'), + 'King Dodongo': ("One within an #immense cavern#...^", "One in #Dodongo's Cavern#...^", 'boss'), + 'Barinade': ("One in the #belly of a deity#...^", "One in #Jabu Jabu's Belly#...^", 'boss'), + 'Phantom Ganon': ("One in a #deep forest#...^", "One in the #Forest Temple#...^", 'boss'), + 'Volvagia': ("One on a #high mountain#...^", "One in the #Fire Temple#...^", 'boss'), + 'Morpha': ("One under a #vast lake#...^", "One in the #Water Temple#...^", 'boss'), + 'Bongo Bongo': ("One within the #house of the dead#...^", "One in the #Shadow Temple#...^", 'boss'), + 'Twinrova': ("One inside a #goddess of the sand#...^", "One in the #Spirit Temple#...^", 'boss'), + 'Links Pocket': ("One in #@'s pocket#...^", "One #@ already has#...^", 'boss'), + 'Spiritual Stone Text Start': ("Ye who owns 3 Spiritual Stones...^", None, 'boss'), + 'Spiritual Stone Text End': ("Stand with the Ocarina of Time&and play the Song of Time.", None, 'boss'), + 'Medallion Text End': ("Together with the Hero of Time,&the awakened ones will bind the&evil and return the light of peace&to the world.", None, 'boss'), + #xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx handy marker for how long one line should be in a text box + 'Validation Line': ("Hmph... Since you made it this far,&I'll let you know what glorious&prize of Ganon's you likely&missed out on in my tower.^Behold...^", None, 'validation line'), + 'Light Arrow Location': ("Ha ha ha... You'll never beat me by&reflecting my lightning bolts&and unleashing the arrows from&", None, 'Light Arrow Location'), + '2001': ("Oh! It's @.&I was expecting someone called&Sheik. Do you know what&happened to them?", None, 'ganonLine'), + '2002': ("I knew I shouldn't have put the key&on the other side of my door.", None, 'ganonLine'), + '2003': ("Looks like it's time for a&round of tennis.", None, 'ganonLine'), + '2004': ("You'll never deflect my bolts of&energy with your sword,&then shoot me with those Light&Arrows you happen to have.", None, 'ganonLine'), + '2005': ("Why did I leave my trident&back in the desert?", None, 'ganonLine'), + '2006': ("Zelda is probably going to do&something stupid, like send you&back to your own timeline.^So this is quite meaningless.&Do you really want&to save this moron?", None, 'ganonLine'), + '2007': ("What about Zelda makes you think&she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the hungry,&and my castle floats.", None, 'ganonLine'), + '2008': ("I've learned this spell,&it's really neat,&I'll keep it later&for your treat!", None, 'ganonLine'), + '2009': ("Many tricks are up my sleeve,&to save yourself&you'd better leave!", None, 'ganonLine'), + '2010': ("After what you did to&Koholint Island, how can&you call me the bad guy?", None, 'ganonLine'), + '2011': ("Today, let's begin down&'The Hero is Defeated' timeline.", None, 'ganonLine'), +} + +# This specifies which hints will never appear due to either having known or known useless contents or due to the locations not existing. + +def hintExclusions(world): + expected_skulltulas = world.logic_skulltulas + exclusions = [] + if world.logic_no_trade_skull_mask: + exclusions.append('Deku Theater Skull Mask') + if world.logic_no_trade_mask_of_truth: + exclusions.append('Deku Theater Mask of Truth') + if world.logic_no_trade_biggoron: + exclusions.append('Biggoron') + if world.logic_no_child_fishing: + exclusions.append('Child Fishing') + if world.logic_no_adult_fishing: + exclusions.append('Adult Fishing') + if world.logic_no_big_poes: + exclusions.append('10 Big Poes') + if expected_skulltulas < 50: + exclusions.append('50 Gold Skulltula Reward') + if expected_skulltulas < 40: + exclusions.append('40 Gold Skulltula Reward') + if expected_skulltulas < 30: + exclusions.append('30 Gold Skulltula Reward') + if expected_skulltulas < 20: + exclusions.append('20 Gold Skulltula Reward') + if expected_skulltulas < 10: + exclusions.append('10 Gold Skulltula Reward') + if not world.shuffle_ocarinas: + exclusions.append('Ocarina of Time') + if world.tokensanity != 'all': + exclusions.append('GS Hyrule Castle Grotto') + exclusions.append('GS Hyrule Field Near Gerudo Valley') + exclusions.append('GS Zora\'s Fountain Hidden Cave') + if not world.dungeon_mq['DT']: + exclusions.append('Deku Tree MQ After Spinning Log Chest') + if world.tokensanity == 'off' or not world.dungeon_mq['JB']: + exclusions.append('GS Jabu Jabu MQ Invisible Enemies Room') + if world.dungeon_mq['FoT']: + exclusions.append('Forest Temple Floormaster Chest') + if world.dungeon_mq['FiT']: + exclusions.append('Fire Temple Scarecrow Chest') + exclusions.append('Fire Temple Megaton Hammer Chest') + else: + exclusions.append('Fire Temple MQ West Tower Top Chest') + if world.dungeon_mq['WT']: + exclusions.append('Water Temple River Chest') + exclusions.append('Water Temple Boss Key Chest') + else: + exclusions.append('Water Temple MQ Boss Key Chest') + exclusions.append('Water Temple MQ Freestanding Key') + if world.tokensanity == 'off' or not world.dungeon_mq['WT']: + exclusions.append('GS Water Temple MQ North Basement') + if world.dungeon_mq['GTG']: + exclusions.append('Gerudo Training Grounds Underwater Silver Rupee Chest') + exclusions.append('Gerudo Training Grounds Maze Path Final Chest') + else: + exclusions.append('Gerudo Training Grounds MQ Underwater Silver Rupee Chest') + exclusions.append('Gerudo Training Grounds MQ Ice Arrows Chest') + if world.dungeon_mq['BW']: + exclusions.append('Bottom of the Well Defeat Boss') + else: + exclusions.append('Bottom of the Well MQ Compass Chest') + if not world.dungeon_mq['SpT']: + exclusions.append('Spirit Temple MQ Child Center Chest') + exclusions.append('Spirit Temple MQ Lower Adult Right Chest') + if world.tokensanity == 'off' or not world.dungeon_mq['SpT']: + exclusions.append('GS Spirit Temple MQ Lower Adult Right') + if world.dungeon_mq['ShT']: + exclusions.append('Shadow Temple Hidden Floormaster Chest') + else: + exclusions.append('Shadow Temple MQ Bomb Flower Chest') + return exclusions diff --git a/Hints.py b/Hints.py index fb8dc8b4b..48d9a6f0c 100644 --- a/Hints.py +++ b/Hints.py @@ -6,181 +6,331 @@ import random from HintList import getHint, getHintGroup, Hint -from Utils import local_path +from ItemList import eventlocations +from Messages import update_message_by_id +from TextBox import lineWrap + +def buildHintString(hintString): + if len(hintString) < 77: + hintString = "They say that " + hintString + elif len(hintString) < 82: + hintString = "They say " + hintString + # captitalize the sentance + hintString = hintString[:1].upper() + hintString[1:] + + return hintString + + +def getItemGenericName(item): + if item.type == 'Map' or item.type == 'Compass' or item.type == 'BossKey' or item.type == 'SmallKey' or item.type == 'FortressSmallKey': + return item.type + else: + return item.name + + +def isDungeonItem(item): + return item.type == 'Map' or item.type == 'Compass' or item.type == 'BossKey' or item.type == 'SmallKey' + + +def add_hint(world, id, text): + world.spoiler.hints[id] = lineWrap(text) + + +def writeGossipStoneHintsHints(world, messages): + for id,text in world.spoiler.hints.items(): + update_message_by_id(messages, id, get_raw_text(text)) + +def filterTrailingSpace(text): + if text.endswith('& '): + return text[:-1] + else: + return text + +hintPrefixes = [ + 'a few ', + 'some ', + 'plenty of ', + 'a ', + 'an ', + 'the ', + '', +] + +def getSimpleHintNoPrefix(item): + hint = getHint(item.name, True).text + + for prefix in hintPrefixes: + if hint.startswith(prefix): + # return without the prefix + return hint[len(prefix):] + + # no prefex + return hint + +def colorText(text, color): + colorMap = { + 'White': '\x40', + 'Red': '\x41', + 'Green': '\x42', + 'Blue': '\x43', + 'Light Blue': '\x44', + 'Pink': '\x45', + 'Yellow': '\x46', + 'Black': '\x47', + } + + colorTags = False + while True: + splitText = text.split('#', 2) + if len(splitText) == 3: + splitText[1] = '\x05' + colorMap[color] + splitText[1] + '\x05\x40' + text = ''.join(splitText) + colorTags = True + else: + text = '#'.join(splitText) + break + + if not colorTags: + for prefix in hintPrefixes: + if text.startswith(prefix): + text = text[:len(prefix)] + '\x05' + colorMap[color] + text[len(prefix):] + '\x05\x40' + break + + return text + #builds out general hints based on location and whether an item is required or not -def buildGossipHints(world, rom): - stoneAddresses = [0x938e4c, 0x938EA8, 0x938F04, 0x938F60, 0x938FBC, 0x939018, 0x939074, 0x9390D0, 0x93912C, 0x939188, - 0x9391E4, 0x939240, 0x93929C, 0x9392F8, 0x939354, 0x9393B0, 0x93940C, 0x939468, 0x9394C4, 0x939520, - 0x93957C, 0x9395D8, 0x939634, 0x939690, 0x9396EC, 0x939748, 0x9397A4, 0x939800, 0x93985C, 0x9398B8, - 0x939914, 0x939970] #address for gossip stone text boxes, byte limit is 92 +def buildGossipHints(world): + stoneIDs = [0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, + 0x0409, 0x040A, 0x040B, 0x040C, 0x040D, 0x040E, 0x040F, 0x0410, + 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, + 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420] - alwaysLocations = getHintGroup('alwaysLocation')#These location will always have a hint somewhere in the world. - - sometimesSpace = (int((len(stoneAddresses) - len(alwaysLocations)*2)/2)) - sometimesLocations = getHintGroup('location')#A random selection of these locations will be in the hint pool. - random.shuffle(sometimesLocations) - sometimesLocations = sometimesLocations[0:sometimesSpace] - hintList = alwaysLocations - hintList.extend(alwaysLocations) - hintList.extend(sometimesLocations) - - locationData = [] - for hint in hintList: + #shuffles the stone addresses for randomization, always locations will be placed first + random.shuffle(stoneIDs) + + # Add trial hints + if world.trials < 6 and world.trials > 3: + for trial,skipped in world.skipped_trials.items(): + if skipped: + add_hint(world, stoneIDs.pop(0), buildHintString("the " + colorText(trial + " Trial", 'Yellow') + " was dispelled by Sheik.")) + elif world.trials <= 3 and world.trials > 0: + for trial,skipped in world.skipped_trials.items(): + if not skipped: + add_hint(world, stoneIDs.pop(0), buildHintString("the " + colorText(trial + " Trial", 'Pink') + " protects Ganon's Tower.")) + + # add required items locations for hints (good hints) + requiredSample = world.spoiler.required_locations[world.id] + if len(requiredSample) >= 5: + requiredSample = random.sample(requiredSample, random.randint(3,4)) + for location in requiredSample: + if location.parent_region.dungeon: + add_hint(world, stoneIDs.pop(0), buildHintString(colorText(getHint(location.parent_region.dungeon.name, world.clearer_hints).text, 'Light Blue') + \ + " is on the way of the hero.")) + else: + add_hint(world, stoneIDs.pop(0), buildHintString(colorText(location.hint, 'Light Blue') + " is on the way of the hero.")) + + # Don't repeat hints + checkedLocations = [] + + # Add required location hints + alwaysLocations = getHintGroup('alwaysLocation', world) + for hint in alwaysLocations: for locationWorld in world.get_locations(): if hint.name == locationWorld.name: - locationData.extend([locationWorld]) + checkedLocations.append(hint.name) + add_hint(world, stoneIDs.pop(0), buildHintString(colorText(getHint(locationWorld.name, world.clearer_hints).text, 'Green') + " " + \ + colorText(getHint(getItemGenericName(locationWorld.item), world.clearer_hints).text, 'Red') + ".")) + - #hopefully fixes weird VC error where the last character from a previous text box would sometimes spill over into the next box. - for address in range(stoneAddresses[0], 0x9399D8): - rom.write_byte(address, 0x08) + # Add good location hints + sometimesLocations = getHintGroup('location', world) + if sometimesLocations: + for _ in range(0, random.randint(11,12) - len(alwaysLocations)): + hint = random.choice(sometimesLocations) + # Repick if location isn't new + while hint.name in checkedLocations or hint.name in alwaysLocations: + hint = random.choice(sometimesLocations) - #shuffles the stone addresses for randomization, always locations will be placed first and twice - random.shuffle(stoneAddresses) + for locationWorld in world.get_locations(): + if hint.name == locationWorld.name: + checkedLocations.append(locationWorld.name) + add_hint(world, stoneIDs.pop(0), buildHintString(colorText(getHint(locationWorld.name, world.clearer_hints).text, 'Green') + " " + \ + colorText(getHint(getItemGenericName(locationWorld.item), world.clearer_hints).text, 'Red') + ".")) - #loops through shuffled locations and addresses and builds hint. - while locationData: - currentLoc = locationData.pop(0) - Block_code = getBytes((getHint(currentLoc.name).text)) - if currentLoc.item.type == 'Map' or currentLoc.item.type == 'Compass' or currentLoc.item.type == 'BossKey' or currentLoc.item.type == 'SmallKey': - Block_code.extend(getBytes((getHint(currentLoc.item.type).text))) + # add bad dungeon locations hints + for dungeon in random.sample(world.dungeons, random.randint(3,4)): + # Choose a randome dungeon location that is a non-dungeon item + dungeon_locations = [location for region in dungeon.regions for location in region.locations + if location.item.type != 'Event' and \ + location.item.type != 'Shop' and \ + not location.locked and \ + not isDungeonItem(location.item) and \ + (world.tokensanity != 'off' or location.item.type != 'Token') and\ + location.item.type != 'Song'] + if (len(dungeon_locations) == 0): + continue + locationWorld = random.choice(dungeon_locations) + + checkedLocations.append(locationWorld.name) + add_hint(world, stoneIDs.pop(0), buildHintString(colorText(getHint(dungeon.name, world.clearer_hints).text, 'Green') + \ + " hoards " + colorText(getHint(getItemGenericName(locationWorld.item), world.clearer_hints).text, 'Red') + ".")) + + # add bad overworld locations hints + # only choose location if it is new and a proper item from the overworld + overworldlocations = [locationWorld for locationWorld in world.get_locations() + if not locationWorld.name in checkedLocations and \ + not locationWorld.name in alwaysLocations and \ + not locationWorld.name in sometimesLocations and \ + locationWorld.item.type != 'Event' and \ + locationWorld.item.type != 'Shop' and \ + not locationWorld.locked and \ + (world.tokensanity == 'all' or locationWorld.item.type != 'Token') and \ + not locationWorld.parent_region.dungeon] + overworldSample = overworldlocations + if len(overworldSample) >= 3: + # Use this hint type to balance hints given via trials + if world.trials == 3: + overworldSample = random.sample(overworldlocations, random.randint(1,2)) + elif world.trials in [2, 4]: + overworldSample = random.sample(overworldlocations, random.randint(1,3)) + elif world.trials in [1, 5]: + overworldSample = random.sample(overworldlocations, random.randint(2,3)) + else: + overworldSample = random.sample(overworldlocations, random.randint(2,4)) + for locationWorld in overworldSample: + checkedLocations.append(locationWorld.name) + add_hint(world, stoneIDs.pop(0), buildHintString(colorText(getHint(getItemGenericName(locationWorld.item), world.clearer_hints).text, 'Red') + \ + " can be found at " + colorText(locationWorld.hint, 'Green') + ".")) + + # add good item hints + # only choose location if it is new and a good item + gooditemlocations = [locationWorld for locationWorld in world.get_locations() + if not locationWorld.name in checkedLocations and \ + locationWorld.item.advancement and \ + locationWorld.item.type != 'Event' and \ + locationWorld.item.type != 'Shop' and \ + not locationWorld.locked and \ + locationWorld.item.type != 'Token' and \ + not locationWorld.item.key] + gooditemSample = gooditemlocations + if len(gooditemSample) >= 6: + gooditemSample = random.sample(gooditemlocations, random.randint(4,6)) + for locationWorld in gooditemSample: + checkedLocations.append(locationWorld.name) + if locationWorld.parent_region.dungeon: + add_hint(world, stoneIDs.pop(0), buildHintString(colorText(getHint(locationWorld.parent_region.dungeon.name, world.clearer_hints).text, 'Green') + \ + " hoards " + colorText(getHint(getItemGenericName(locationWorld.item), world.clearer_hints).text, 'Red') + ".")) else: - Block_code.extend(getBytes((getHint(currentLoc.item.name).text))) - endText(Block_code) - - if len(Block_code) > 92: - print('Too many characters in hint') - Block_code = getBytes("I am Error.") - Block_code.extend(getBytes(currentLoc.name)) - Block_code.extend(getBytes('&')) - Block_code.extend(getBytes(currentLoc.item.name)) - - rom.write_bytes(stoneAddresses.pop(0), Block_code) - - junkHints = getHintGroup('junkHint') + add_hint(world, stoneIDs.pop(0), buildHintString(colorText(getHint(getItemGenericName(locationWorld.item), world.clearer_hints).text, 'Red') + \ + " can be found at " + colorText(locationWorld.hint, 'Green') + ".")) + + # fill the remaining hints with junk + junkHints = getHintGroup('junkHint', world) random.shuffle(junkHints) - while stoneAddresses: - junkHint = junkHints.pop() - Block_code = getBytes(junkHint.text) - endText(Block_code) - rom.write_bytes(stoneAddresses.pop(0), Block_code) - - return rom + while stoneIDs: + add_hint( world, stoneIDs.pop(0), junkHints.pop().text ) # builds boss reward text that is displayed at the temple of time altar for child and adult, pull based off of item in a fixed order. -def buildBossRewardHints(world, rom): +def buildBossRewardHints(world, messages): bossRewardsSpiritualStones = ['Kokiri Emerald', 'Goron Ruby', 'Zora Sapphire'] bossRewardsMedallions = ['Forest Medallion', 'Fire Medallion', 'Water Medallion', 'Shadow Medallion', 'Spirit Medallion', 'Light Medallion'] # text that appears at altar as a child. - Block_code = [] - Block_code = getBytes(getHint('Spiritual Stone Text Start').text) + text = '\x08' + text += get_raw_text(getHint('Spiritual Stone Text Start', world.clearer_hints).text) for reward in bossRewardsSpiritualStones: - buildBossString(Block_code, reward, world) + text += buildBossString(reward, world) + + text = setRewardColor(text) + text += get_raw_text(getHint('Spiritual Stone Text End', world.clearer_hints).text) + text += '\x0B' + + update_message_by_id(messages, 0x707a, text, 0x20) - Block_code = setRewardColor(Block_code) - Block_code.extend(getBytes(getHint('Spiritual Stone Text End').text)) - Block_code.extend([0x0B]) - endText(Block_code) - rom.write_bytes(0x95ED95, Block_code) # text that appears at altar as an adult. - Block_code = [] + start = '\x08When evil rules all, an awakening\x01voice from the Sacred Realm will\x01call those destined to be Sages,\x01who dwell in the \x05\x41five temples\x05\x40.\x04' + text = '' for reward in bossRewardsMedallions: - buildBossString(Block_code, reward, world) + text += buildBossString(reward, world) - Block_code = setRewardColor(Block_code) - Block_code.extend(getBytes(getHint('Medallion Text End').text)) - Block_code.extend([0x0B]) - endText(Block_code) - rom.write_bytes(0x95DB94, Block_code) - - return rom + text = setRewardColor(text) + text += get_raw_text(getHint('Medallion Text End', world.clearer_hints).text) + text += '\x0B' + + update_message_by_id(messages, 0x7057, start + text, 0x20) # pulls text string from hintlist for reward after sending the location to hintlist. -def buildBossString(Block_code, reward, world): +def buildBossString(reward, world): + text = '' for location in world.get_locations(): if location.item.name == reward: - Block_code.extend([0x08]) - Block_code.extend(getBytes(getHint(location.name).text)) - - return Block_code + text += '\x08' + get_raw_text(getHint(location.name, world.clearer_hints).text) + return text # alternates through color set commands in child and adult boss reward hint strings setting the colors at the start of the string to correspond with the reward found at the location. # skips over color commands at the end of stings to set color back to white. -def setRewardColor(Block_code): - rewardColors = [0x42, 0x41, 0x43, 0x45, 0x46, 0x44] +def setRewardColor(text): + rewardColors = ['\x42', '\x41', '\x43', '\x45', '\x46', '\x44'] colorWhite = True - for i, byte in enumerate(Block_code): - if byte == 0x05 and colorWhite: - Block_code[i + 1] = rewardColors.pop(0) + for i, char in enumerate(text): + if char == '\x05' and colorWhite: + text = text[:i + 1] + rewardColors.pop(0) + text[i + 2:] colorWhite = False - elif byte == 0x05 and not colorWhite: + elif char == '\x05' and not colorWhite: colorWhite = True - return Block_code + return text # fun new lines for Ganon during the final battle -def buildGanonText(world, rom): - # reorganize text header files to make space for text - rom.write_bytes(0xB884B1, [0x03, 0x41, 0xED]) - rom.write_bytes(0xB884B9, [0x03, 0x41, 0xEE]) - rom.write_bytes(0xB884C1, [0x03, 0x41, 0xEF]) - rom.write_bytes(0xB884C9, [0x03, 0x42, 0x99]) - - # clear space for new text - for address in range(0x9611EC, 0x961349): - rom.write_byte(address, 0x08) - - Block_code = [] - # lines before battle, 160 characters max - ganonLines = getHintGroup('ganonLine') +def buildGanonText(world, messages): + # empty now unused messages to make space for ganon lines + update_message_by_id(messages, 0x70C8, " ") + update_message_by_id(messages, 0x70C9, " ") + update_message_by_id(messages, 0x70CA, " ") + + # lines before battle + text = '\x08' + ganonLines = getHintGroup('ganonLine', world) random.shuffle(ganonLines) - Block_code = getBytes(ganonLines.pop().text) - endText(Block_code) - rom.write_bytes(0x9611F1, Block_code) + text = get_raw_text(ganonLines.pop().text) + update_message_by_id(messages, 0x70CB, text) - if world.fast_ganon: + # light arrow hint or validation chest item + text = '\x08' + if world.trials == 0: for location in world.get_locations(): if location.item.name == 'Light Arrows': - Block_code = getBytes(getHint('Light Arrow Location').text) - Block_code.extend(getBytes(location.hint)) - Block_code.extend(getBytes('!')) + text = get_raw_text(getHint('Light Arrow Location', world.clearer_hints).text) + location_hint = location.hint.replace('Ganon\'s Castle', 'my castle') + location_hint = location.hint.replace('Ganon\'s Tower', 'my tower') + text += get_raw_text(location_hint) + text += '!' break - endText(Block_code) else: - Block_code = getBytes(getHint('Validation Line').text) + text = get_raw_text(getHint('Validation Line', world.clearer_hints).text) for location in world.get_locations(): if location.name == 'Ganons Tower Boss Key Chest': - Block_code.extend(getBytes((getHint(location.item.name).text))) - endText(Block_code) + text += get_raw_text(getHint(getItemGenericName(location.item), world.clearer_hints).text) + text += '!' + break - rom.write_bytes(0x96129D, Block_code) - - return rom - -#sets the end of text byte in the text box. -def endText(byteArray): - return byteArray.extend([0x02]) - -# reads array of characters and converts them to an array of bytes. -def getBytes(string): - byteCode = [] + update_message_by_id(messages, 0x70CC, text) + +def get_raw_text(string): + text = '' for char in string: if char == '^': - byteCode.extend([0x04])#box break + text += '\x04' # box break elif char == '&': - byteCode.extend([0x01])#new line + text += '\x01' #new line elif char == '@': - byteCode.extend([0x0F])#print player name + text += '\x0F' #print player name elif char == '#': - byteCode.extend([0x05, 0x40]) #sets color to white + text += '\x05\x40' #sets color to white else: - char = char.encode('utf-8') - char = char.hex() - byte = int('0x' + char, 16) - byteCode.extend([byte]) - return byteCode - + text += char + return text diff --git a/ItemList.py b/ItemList.py index f75ccb1c7..bc043c4a6 100644 --- a/ItemList.py +++ b/ItemList.py @@ -3,94 +3,865 @@ import random from Items import ItemFactory -from Fill import FillError, fill_restrictive #This file sets the item pools for various modes. Timed modes and triforce hunt are enforced first, and then extra items are specified per mode to fill in the remaining space. #Some basic items that various modes require are placed here, including pendants and crystals. Medallion requirements for the two relevant entrances are also decided. -alwaysitems = (['Kokiri Sword', 'Biggoron Sword', 'Boomerang', 'Lens of Truth', 'Hammer', 'Iron Boots', 'Goron Tunic', 'Zora Tunic', 'Hover Boots', 'Mirror Shield', 'Stone of Agony', 'Fire Arrows', 'Ice Arrows', 'Light Arrows', 'Dins Fire', 'Farores Wind', 'Nayrus Love', 'Rupee (1)'] + ['Progressive Hookshot'] * 2 + ['Deku Shield'] * 4 + ['Hylian Shield'] * 2 + ['Ice Trap'] * 6 + - ['Progressive Strength Upgrade'] * 3 + ['Progressive Scale'] * 2 + ['Piece of Heart'] * 35 + ['Recovery Heart'] * 11 + ['Rupees (5)'] * 17 + ['Rupees (20)'] * 5 + ['Rupees (50)'] * 7 + ['Rupees (200)'] * 6 + ['Bow'] * 3 + ['Slingshot'] * 3 + ['Bomb Bag'] * 3 + ['Bottle with Letter'] + ['Heart Container'] * 8 + ['Piece of Heart (Treasure Chest Game)'] + - ['Bombs (5)'] * 2 + ['Bombs (10)'] * 2 + ['Bombs (20)'] * 2 + ['Bombchus (5)'] + ['Bombchus (10)'] * 3 + ['Bombchus (20)'] + ['Arrows (5)'] + ['Arrows (10)'] * 6 + ['Arrows (30)'] * 6 + ['Deku Nuts (5)'] + ['Deku Nuts (10)'] + ['Progressive Wallet'] * 2 + ['Deku Stick Capacity'] * 2 + ['Deku Nut Capacity'] * 2 + ['Magic Meter'] * 2 + ['Double Defense']) -normal_bottles = ['Bottle', 'Bottle with Milk', 'Bottle with Red Potion', 'Bottle with Green Potion', 'Bottle with Blue Potion', 'Bottle with Fairy', 'Bottle with Fish', 'Bottle with Blue Fire', 'Bottle with Bugs', 'Bottle with Poe'] +alwaysitems = ([ + 'Biggoron Sword', + 'Boomerang', + 'Lens of Truth', + 'Hammer', + 'Iron Boots', + 'Goron Tunic', + 'Zora Tunic', + 'Hover Boots', + 'Mirror Shield', + 'Stone of Agony', + 'Fire Arrows', + 'Ice Arrows', + 'Light Arrows', + 'Dins Fire', + 'Farores Wind', + 'Rupee (1)'] + + ['Progressive Hookshot'] * 2 + + ['Deku Shield'] + + ['Hylian Shield'] + + ['Progressive Strength Upgrade'] * 3 + + ['Progressive Scale'] * 2 + + ['Recovery Heart'] * 6 + + ['Bow'] + + ['Slingshot'] + + ['Bomb Bag'] + + ['Bottle with Letter'] + + ['Bombs (5)'] * 2 + + ['Bombs (10)'] + + ['Bombs (20)'] + + ['Arrows (5)'] + + ['Arrows (10)'] * 5 + + ['Progressive Wallet'] * 2 + + ['Magic Meter'] + + ['Piece of Heart (Treasure Chest Game)']) + +DT_vanilla = (['Recovery Heart'] * 2) + +DT_MQ = (['Deku Shield'] * 2 + + ['Rupees (50)']) + +DC_vanilla = (['Rupees (20)']) + +DC_MQ = (['Hylian Shield'] + + ['Rupees (5)']) + +JB_MQ = (['Deku Nuts (5)'] * 4 + + ['Recovery Heart'] + + ['Deku Shield'] + + ['Deku Stick (1)']) + +FoT_vanilla = (['Recovery Heart'] + + ['Arrows (10)'] + + ['Arrows (30)']) + +FoT_MQ = (['Arrows (5)']) + +FiT_vanilla = (['Rupees (200)']) + +FiT_MQ = (['Bombs (20)'] + + ['Hylian Shield']) + +SpT_vanilla = (['Deku Shield'] * 2 + + ['Recovery Heart'] + + ['Bombs (20)']) + +SpT_MQ = (['Rupees (50)'] * 2 + + ['Arrows (30)']) + +ShT_vanilla = (['Arrows (30)']) + +ShT_MQ = (['Arrows (5)'] * 2 + + ['Rupees (20)']) + +BW_vanilla = (['Recovery Heart'] + + ['Bombs (10)'] + + ['Rupees (200)'] + + ['Deku Nuts (5)'] + + ['Deku Nuts (10)'] + + ['Deku Shield'] + + ['Hylian Shield']) + +GTG_vanilla = (['Arrows (30)'] * 3 + + ['Rupees (200)']) + +GTG_MQ = (['Rupee (Treasure Chest Game)'] * 2 + + ['Arrows (10)'] + + ['Rupee (1)'] + + ['Rupees (50)']) + +GC_vanilla = (['Rupees (5)'] * 3 + + ['Arrows (30)']) + +GC_MQ = (['Arrows (10)'] * 2 + + ['Bombs (5)'] + + ['Rupees (20)'] + + ['Recovery Heart']) + +normal_bottles = [ + 'Bottle', + 'Bottle with Milk', + 'Bottle with Red Potion', + 'Bottle with Green Potion', + 'Bottle with Blue Potion', + 'Bottle with Fairy', + 'Bottle with Fish', + 'Bottle with Bugs', + 'Bottle with Poe', + 'Bottle with Big Poe', + 'Bottle with Blue Fire'] + normal_bottle_count = 3 -notmapcompass = ['Rupees (5)'] * 20 -rewardlist = ['Kokiri Emerald', 'Goron Ruby', 'Zora Sapphire', 'Forest Medallion', 'Fire Medallion', 'Water Medallion', 'Spirit Medallion', 'Shadow Medallion', 'Light Medallion'] -songlist = ['Zeldas Lullaby', 'Eponas Song', 'Suns Song', 'Sarias Song', 'Song of Time', 'Song of Storms', 'Minuet of Forest', 'Prelude of Light', 'Bolero of Fire', 'Serenade of Water', 'Nocturne of Shadow', 'Requiem of Spirit'] -skulltulla_locations = (['GS1', 'GS2', 'GS3', 'GS4', 'GS5', 'GS6', 'GS7', 'GS8', 'GS9', 'GS10', 'GS11', 'GS12', 'GS13', 'GS14', 'GS15', 'GS16', 'GS17', 'GS18', 'GS19', 'GS20'] + - ['GS21', 'GS22', 'GS23', 'GS24', 'GS25', 'GS26', 'GS27', 'GS28', 'GS29', 'GS30', 'GS31', 'GS32', 'GS33', 'GS34', 'GS35', 'GS36', 'GS37', 'GS38', 'GS39', 'GS40'] + - ['GS41', 'GS42', 'GS43', 'GS44', 'GS45', 'GS46', 'GS47', 'GS48', 'GS49', 'GS50', 'GS51', 'GS52', 'GS53', 'GS54', 'GS55', 'GS56', 'GS57', 'GS58', 'GS59', 'GS60'] + - ['GS61', 'GS62', 'GS63', 'GS64', 'GS65', 'GS66', 'GS67', 'GS68', 'GS69', 'GS70', 'GS71', 'GS72', 'GS73', 'GS74', 'GS75', 'GS76', 'GS77', 'GS78', 'GS79', 'GS80'] + - ['GS81', 'GS82', 'GS83', 'GS84', 'GS85', 'GS86', 'GS87', 'GS88', 'GS89', 'GS90', 'GS91', 'GS92', 'GS93', 'GS94', 'GS95', 'GS96', 'GS97', 'GS98', 'GS99', 'GS100']) -tradeitems = ['Pocket Egg', 'Pocket Cucco', 'Cojiro', 'Odd Mushroom', 'Poachers Saw', 'Broken Sword', 'Prescription', 'Eyeball Frog', 'Eyedrops', 'Claim Check'] - -#total_items_to_place = 5 -def generate_itempool(world): +normal_rupees = ( + ['Rupees (5)'] * 13 + + ['Rupees (20)'] * 5 + + ['Rupees (50)'] * 7 + + ['Rupees (200)'] * 3) + +shopsanity_rupees = ( + ['Rupees (5)'] * 2 + + ['Rupees (20)'] * 10 + + ['Rupees (50)'] * 10 + + ['Rupees (200)'] * 5 + + ['Progressive Wallet']) + +vanilla_shop_items = { + 'Kokiri Shop Item 1': 'Buy Deku Shield', + 'Kokiri Shop Item 2': 'Buy Deku Nut (5)', + 'Kokiri Shop Item 3': 'Buy Deku Nut (10)', + 'Kokiri Shop Item 4': 'Buy Deku Stick (1)', + 'Kokiri Shop Item 5': 'Buy Deku Seeds (30)', + 'Kokiri Shop Item 6': 'Buy Arrows (10)', + 'Kokiri Shop Item 7': 'Buy Arrows (30)', + 'Kokiri Shop Item 8': 'Buy Heart', + 'Kakariko Potion Shop Item 1': 'Buy Deku Nut (5)', + 'Kakariko Potion Shop Item 2': 'Buy Fish', + 'Kakariko Potion Shop Item 3': 'Buy Red Potion [30]', + 'Kakariko Potion Shop Item 4': 'Buy Green Potion', + 'Kakariko Potion Shop Item 5': 'Buy Blue Fire', + 'Kakariko Potion Shop Item 6': 'Buy Bottle Bug', + 'Kakariko Potion Shop Item 7': 'Buy Poe', + 'Kakariko Potion Shop Item 8': 'Buy Fairy\'s Spirit', + 'Bombchu Shop Item 1': 'Buy Bombchu (5)', + 'Bombchu Shop Item 2': 'Buy Bombchu (10)', + 'Bombchu Shop Item 3': 'Buy Bombchu (10)', + 'Bombchu Shop Item 4': 'Buy Bombchu (10)', + 'Bombchu Shop Item 5': 'Buy Bombchu (20)', + 'Bombchu Shop Item 6': 'Buy Bombchu (20)', + 'Bombchu Shop Item 7': 'Buy Bombchu (20)', + 'Bombchu Shop Item 8': 'Buy Bombchu (20)', + 'Castle Town Potion Shop Item 1': 'Buy Green Potion', + 'Castle Town Potion Shop Item 2': 'Buy Blue Fire', + 'Castle Town Potion Shop Item 3': 'Buy Red Potion [30]', + 'Castle Town Potion Shop Item 4': 'Buy Fairy\'s Spirit', + 'Castle Town Potion Shop Item 5': 'Buy Deku Nut (5)', + 'Castle Town Potion Shop Item 6': 'Buy Bottle Bug', + 'Castle Town Potion Shop Item 7': 'Buy Poe', + 'Castle Town Potion Shop Item 8': 'Buy Fish', + 'Castle Town Bazaar Item 1': 'Buy Hylian Shield', + 'Castle Town Bazaar Item 2': 'Buy Bombs (5) [35]', + 'Castle Town Bazaar Item 3': 'Buy Deku Nut (5)', + 'Castle Town Bazaar Item 4': 'Buy Heart', + 'Castle Town Bazaar Item 5': 'Buy Arrows (10)', + 'Castle Town Bazaar Item 6': 'Buy Arrows (50)', + 'Castle Town Bazaar Item 7': 'Buy Deku Stick (1)', + 'Castle Town Bazaar Item 8': 'Buy Arrows (30)', + 'Kakariko Bazaar Item 1': 'Buy Hylian Shield', + 'Kakariko Bazaar Item 2': 'Buy Bombs (5) [35]', + 'Kakariko Bazaar Item 3': 'Buy Deku Nut (5)', + 'Kakariko Bazaar Item 4': 'Buy Heart', + 'Kakariko Bazaar Item 5': 'Buy Arrows (10)', + 'Kakariko Bazaar Item 6': 'Buy Arrows (50)', + 'Kakariko Bazaar Item 7': 'Buy Deku Stick (1)', + 'Kakariko Bazaar Item 8': 'Buy Arrows (30)', + 'Zora Shop Item 1': 'Buy Zora Tunic', + 'Zora Shop Item 2': 'Buy Arrows (10)', + 'Zora Shop Item 3': 'Buy Heart', + 'Zora Shop Item 4': 'Buy Arrows (30)', + 'Zora Shop Item 5': 'Buy Deku Nut (5)', + 'Zora Shop Item 6': 'Buy Arrows (50)', + 'Zora Shop Item 7': 'Buy Fish', + 'Zora Shop Item 8': 'Buy Red Potion [50]', + 'Goron Shop Item 1': 'Buy Bombs (5) [25]', + 'Goron Shop Item 2': 'Buy Bombs (10)', + 'Goron Shop Item 3': 'Buy Bombs (20)', + 'Goron Shop Item 4': 'Buy Bombs (30)', + 'Goron Shop Item 5': 'Buy Goron Tunic', + 'Goron Shop Item 6': 'Buy Heart', + 'Goron Shop Item 7': 'Buy Red Potion [40]', + 'Goron Shop Item 8': 'Buy Heart', +} - for location in skulltulla_locations: - world.push_item(location, ItemFactory('Gold Skulltulla Token'), False) - world.get_location(location).event = True - - world.push_item('Ganon', ItemFactory('Triforce'), False) - world.get_location('Ganon').event = True - world.push_item('Gift from Saria', ItemFactory('Fairy Ocarina'), False) - world.get_location('Gift from Saria').event = True - world.push_item('Zeldas Letter', ItemFactory('Zeldas Letter'), False) - world.get_location('Zeldas Letter').event = True - world.push_item('Magic Bean Salesman', ItemFactory('Magic Bean'), False) - world.get_location('Magic Bean Salesman').event = True - world.push_item('King Zora Moves', ItemFactory('Bottle'), False) - world.get_location('King Zora Moves').event = True - world.push_item('Ocarina of Time', ItemFactory('Ocarina of Time'), False) - world.get_location('Ocarina of Time').event = True - world.push_item('Master Sword Pedestal', ItemFactory('Master Sword'), False) - world.get_location('Master Sword Pedestal').event = True - world.push_item('Epona', ItemFactory('Epona'), False) - world.get_location('Epona').event = True - world.push_item('Gerudo Fortress Carpenter Rescue', ItemFactory('Gerudo Membership Card'), False) - world.get_location('Gerudo Fortress Carpenter Rescue').event = True - world.push_item('Ganons Castle Forest Trial Clear', ItemFactory('Forest Trial Clear'), False) - world.get_location('Ganons Castle Forest Trial Clear').event = True - world.push_item('Ganons Castle Fire Trial Clear', ItemFactory('Fire Trial Clear'), False) - world.get_location('Ganons Castle Fire Trial Clear').event = True - world.push_item('Ganons Castle Water Trial Clear', ItemFactory('Water Trial Clear'), False) - world.get_location('Ganons Castle Water Trial Clear').event = True - world.push_item('Ganons Castle Shadow Trial Clear', ItemFactory('Shadow Trial Clear'), False) - world.get_location('Ganons Castle Shadow Trial Clear').event = True - world.push_item('Ganons Castle Spirit Trial Clear', ItemFactory('Spirit Trial Clear'), False) - world.get_location('Ganons Castle Spirit Trial Clear').event = True - world.push_item('Ganons Castle Light Trial Clear', ItemFactory('Light Trial Clear'), False) - world.get_location('Ganons Castle Light Trial Clear').event = True +min_shop_items = ( + ['Buy Deku Shield'] + + ['Buy Hylian Shield'] + + ['Buy Goron Tunic'] + + ['Buy Zora Tunic'] + + ['Buy Deku Nut (5)'] * 2 + ['Buy Deku Nut (10)'] + + ['Buy Deku Stick (1)'] * 2 + + ['Buy Deku Seeds (30)'] + + ['Buy Arrows (10)'] * 2 + ['Buy Arrows (30)'] + ['Buy Arrows (50)'] + + ['Buy Bombchu (5)'] + ['Buy Bombchu (10)'] * 2 + ['Buy Bombchu (20)'] + + ['Buy Bombs (5) [25]'] + ['Buy Bombs (5) [35]'] + ['Buy Bombs (10)'] + ['Buy Bombs (20)'] + + ['Buy Green Potion'] + + ['Buy Red Potion [30]'] + + ['Buy Blue Fire'] + + ['Buy Fairy\'s Spirit'] + + ['Buy Bottle Bug'] + + ['Buy Fish']) + +vanilla_deku_scrubs = { + 'ZR Grotto Deku Scrub Red Potion': 'Buy Red Potion [30]', + 'ZR Grotto Deku Scrub Green Potion': 'Buy Green Potion', + 'SFM Grotto Deku Scrub Red Potion': 'Buy Red Potion [30]', + 'SFM Grotto Deku Scrub Green Potion': 'Buy Green Potion', + 'LH Grotto Deku Scrub Deku Nuts': 'Buy Deku Nut (5)', + 'LH Grotto Deku Scrub Bombs': 'Buy Bombs (5) [35]', + 'LH Grotto Deku Scrub Arrows': 'Buy Arrows (30)', + 'Valley Grotto Deku Scrub Red Potion': 'Buy Red Potion [30]', + 'Valley Grotto Deku Scrub Green Potion': 'Buy Green Potion', + 'LW Deku Scrub Deku Nuts': 'Buy Deku Nut (5)', + 'LW Deku Scrub Deku Sticks': 'Buy Deku Stick (1)', + 'LW Grotto Deku Scrub Arrows': 'Buy Arrows (30)', + 'Desert Grotto Deku Scrub Red Potion': 'Buy Red Potion [30]', + 'Desert Grotto Deku Scrub Green Potion': 'Buy Green Potion', + 'DMC Deku Scrub Bombs': 'Buy Bombs (5) [35]', + 'DMC Grotto Deku Scrub Deku Nuts': 'Buy Deku Nut (5)', + 'DMC Grotto Deku Scrub Bombs': 'Buy Bombs (5) [35]', + 'DMC Grotto Deku Scrub Arrows': 'Buy Arrows (30)', + 'Goron Grotto Deku Scrub Deku Nuts': 'Buy Deku Nut (5)', + 'Goron Grotto Deku Scrub Bombs': 'Buy Bombs (5) [35]', + 'Goron Grotto Deku Scrub Arrows': 'Buy Arrows (30)', + 'LLR Grotto Deku Scrub Deku Nuts': 'Buy Deku Nut (5)', + 'LLR Grotto Deku Scrub Bombs': 'Buy Bombs (5) [35]', + 'LLR Grotto Deku Scrub Arrows': 'Buy Arrows (30)', +} + +deku_scrubs_items = ( + ['Deku Nuts (5)'] * 5 + + ['Deku Stick (1)'] + + ['Bombs (5)'] * 5 + + ['Recovery Heart'] * 4 + + ['Rupees (5)'] * 4 # ['Green Potion'] +) + +rewardlist = [ + 'Kokiri Emerald', + 'Goron Ruby', + 'Zora Sapphire', + 'Forest Medallion', + 'Fire Medallion', + 'Water Medallion', + 'Spirit Medallion', + 'Shadow Medallion', + 'Light Medallion'] + +songlist = [ + 'Zeldas Lullaby', + 'Eponas Song', + 'Suns Song', + 'Sarias Song', + 'Song of Time', + 'Song of Storms', + 'Minuet of Forest', + 'Prelude of Light', + 'Bolero of Fire', + 'Serenade of Water', + 'Nocturne of Shadow', + 'Requiem of Spirit'] + +skulltula_locations = ([ + 'GS Kokiri Know It All House', + 'GS Kokiri Bean Patch', + 'GS Kokiri House of Twins', + 'GS Lost Woods Bean Patch Near Bridge', + 'GS Lost Woods Bean Patch Near Stage', + 'GS Lost Woods Above Stage', + 'GS Sacred Forest Meadow', + 'GS Hyrule Field near Kakariko', + 'GS Hyrule Field Near Gerudo Valley', + 'GS Castle Market Guard House', + 'GS Hyrule Castle Tree', + 'GS Hyrule Castle Grotto', + 'GS Outside Ganon\'s Castle', + 'GS Lon Lon Ranch Tree', + 'GS Lon Lon Ranch Rain Shed', + 'GS Lon Lon Ranch House Window', + 'GS Lon Lon Ranch Back Wall', + 'GS Kakariko House Under Construction', + 'GS Kakariko Skulltula House', + 'GS Kakariko Guard\'s House', + 'GS Kakariko Tree', + 'GS Kakariko Watchtower', + 'GS Kakariko Above Impa\'s House', + 'GS Graveyard Wall', + 'GS Graveyard Bean Patch', + 'GS Mountain Trail Bean Patch', + 'GS Mountain Trail Bomb Alcove', + 'GS Mountain Trail Path to Crater', + 'GS Mountain Trail Above Dodongo\'s Cavern', + 'GS Goron City Boulder Maze', + 'GS Goron City Center Platform', + 'GS Death Mountain Crater Crate', + 'GS Mountain Crater Bean Patch', + 'GS Zora River Ladder', + 'GS Zora River Tree', + 'GS Zora River Near Raised Grottos', + 'GS Zora River Above Bridge', + 'GS Zora\'s Domain Frozen Waterfall', + 'GS Zora\'s Fountain Tree', + 'GS Zora\'s Fountain Above the Log', + 'GS Zora\'s Fountain Hidden Cave', + 'GS Lake Hylia Bean Patch', + 'GS Lake Hylia Lab Wall', + 'GS Lake Hylia Small Island', + 'GS Lake Hylia Giant Tree', + 'GS Lab Underwater Crate', + 'GS Gerudo Valley Small Bridge', + 'GS Gerudo Valley Bean Patch', + 'GS Gerudo Valley Behind Tent', + 'GS Gerudo Valley Pillar', + 'GS Gerudo Fortress Archery Range', + 'GS Gerudo Fortress Top Floor', + 'GS Wasteland Ruins', + 'GS Desert Colossus Bean Patch', + 'GS Desert Colossus Tree', + 'GS Desert Colossus Hill']) + +tradeitems = ( + 'Pocket Egg', + 'Pocket Cucco', + 'Cojiro', + 'Odd Mushroom', + 'Poachers Saw', + 'Broken Sword', + 'Prescription', + 'Eyeball Frog', + 'Eyedrops', + 'Claim Check') + +tradeitemoptions = ( + 'pocket_egg', + 'pocket_cucco', + 'cojiro', + 'odd_mushroom', + 'poachers_saw', + 'broken_sword', + 'prescription', + 'eyeball_frog', + 'eyedrops', + 'claim_check') + + +eventlocations = { + 'Ganon': 'Triforce', + 'Zeldas Letter': 'Zeldas Letter', + 'Magic Bean Salesman': 'Magic Bean', + 'King Zora Moves': 'Bottle', + 'Master Sword Pedestal': 'Master Sword', + 'Epona': 'Epona', + 'Deku Baba Sticks': 'Deku Stick Drop', + 'Goron City Stick Pot': 'Deku Stick Drop', + 'Zoras Domain Stick Pot': 'Deku Stick Drop', + 'Deku Baba Nuts': 'Deku Nut Drop', + 'Zoras Domain Nut Pot': 'Deku Nut Drop', + 'Gerudo Fortress Carpenter Rescue': 'Carpenter Rescue', + 'Ganons Castle Forest Trial Clear': 'Forest Trial Clear', + 'Ganons Castle Fire Trial Clear': 'Fire Trial Clear', + 'Ganons Castle Water Trial Clear': 'Water Trial Clear', + 'Ganons Castle Shadow Trial Clear': 'Shadow Trial Clear', + 'Ganons Castle Spirit Trial Clear': 'Spirit Trial Clear', + 'Ganons Castle Light Trial Clear': 'Light Trial Clear' +} + +junk_pool = ( + 8 * ['Bombs (5)'] + + 2 * ['Bombs (10)'] + + 8 * ['Arrows (5)'] + + 2 * ['Arrows (10)'] + + 5 * ['Deku Stick (1)'] + + 5 * ['Deku Nuts (5)'] + + 5 * ['Deku Seeds (30)'] + + 10 * ['Rupees (5)'] + + 4 * ['Rupees (20)'] + + 1 * ['Rupees (50)']) +def get_junk_item(count=1): + ret_junk = [] + for _ in range(count): + ret_junk.append(random.choice(junk_pool)) + + return ret_junk + + +def generate_itempool(world): + for location, item in eventlocations.items(): + world.push_item(location, ItemFactory(item, world)) + world.get_location(location).locked = True # set up item pool - (pool, placed_items) = get_pool_core(world.place_dungeon_items) - world.itempool = ItemFactory(pool) - for (location, item) in placed_items: - world.push_item(location, ItemFactory(item), False) - world.get_location(location).event = True + (pool, placed_items) = get_pool_core(world) + world.itempool = ItemFactory(pool, world) + for (location, item) in placed_items.items(): + world.push_item(location, ItemFactory(item, world)) + world.get_location(location).locked = True + choose_trials(world) fill_bosses(world) - fill_songs(world) -def get_pool_core(dungeon_items): + world.initialize_items() + + +def get_pool_core(world): pool = [] - placed_items = [] + placed_items = {} + + if world.shuffle_kokiri_sword: + pool.append('Kokiri Sword') + else: + placed_items['Kokiri Sword Chest'] = 'Kokiri Sword' + + if world.shuffle_weird_egg: + pool.append('Weird Egg') + else: + placed_items['Malon Egg'] = 'Weird Egg' + + if world.shuffle_ocarinas: + pool.extend(['Ocarina'] * 2) + else: + placed_items['Gift from Saria'] = 'Ocarina' + placed_items['Ocarina of Time'] = 'Ocarina' + + if world.dungeon_mq['DT']: + skulltula_locations_final = skulltula_locations + [ + 'GS Deku Tree MQ Lobby', + 'GS Deku Tree MQ Compass Room', + 'GS Deku Tree MQ Basement Ceiling', + 'GS Deku Tree MQ Basement Back Room'] + else: + skulltula_locations_final = skulltula_locations + [ + 'GS Deku Tree Compass Room', + 'GS Deku Tree Basement Vines', + 'GS Deku Tree Basement Gate', + 'GS Deku Tree Basement Back Room'] + if world.dungeon_mq['DC']: + skulltula_locations_final.extend([ + 'GS Dodongo\'s Cavern MQ Scrub Room', + 'GS Dodongo\'s Cavern MQ Song of Time Block Room', + 'GS Dodongo\'s Cavern MQ Lizalfos Room', + 'GS Dodongo\'s Cavern MQ Larva Room', + 'GS Dodongo\'s Cavern MQ Back Area']) + else: + skulltula_locations_final.extend([ + 'GS Dodongo\'s Cavern East Side Room', + 'GS Dodongo\'s Cavern Vines Above Stairs', + 'GS Dodongo\'s Cavern Back Room', + 'GS Dodongo\'s Cavern Alcove Above Stairs', + 'GS Dodongo\'s Cavern Scarecrow']) + if world.dungeon_mq['JB']: + skulltula_locations_final.extend([ + 'GS Jabu Jabu MQ Tailpasaran Room', + 'GS Jabu Jabu MQ Invisible Enemies Room', + 'GS Jabu Jabu MQ Boomerang Room', + 'GS Jabu Jabu MQ Near Boss']) + else: + skulltula_locations_final.extend([ + 'GS Jabu Jabu Water Switch Room', + 'GS Jabu Jabu Lobby Basement Lower', + 'GS Jabu Jabu Lobby Basement Upper', + 'GS Jabu Jabu Near Boss']) + if world.dungeon_mq['FoT']: + skulltula_locations_final.extend([ + 'GS Forest Temple MQ First Hallway', + 'GS Forest Temple MQ Block Push Room', + 'GS Forest Temple MQ Outdoor East', + 'GS Forest Temple MQ Outdoor West', + 'GS Forest Temple MQ Well']) + else: + skulltula_locations_final.extend([ + 'GS Forest Temple First Room', + 'GS Forest Temple Lobby', + 'GS Forest Temple Outdoor East', + 'GS Forest Temple Outdoor West', + 'GS Forest Temple Basement']) + if world.dungeon_mq['FiT']: + skulltula_locations_final.extend([ + 'GS Fire Temple MQ Above Fire Wall Maze', + 'GS Fire Temple MQ Fire Wall Maze Center', + 'GS Fire Temple MQ Big Lava Room', + 'GS Fire Temple MQ Fire Wall Maze Side Room', + 'GS Fire Temple MQ East Tower Top']) + else: + skulltula_locations_final.extend([ + 'GS Fire Temple Song of Time Room', + 'GS Fire Temple Unmarked Bomb Wall', + 'GS Fire Temple East Tower Climb', + 'GS Fire Temple East Tower Top', + 'GS Fire Temple Basement']) + if world.dungeon_mq['WT']: + skulltula_locations_final.extend([ + 'GS Water Temple MQ Before Upper Water Switch', + 'GS Water Temple MQ North Basement', + 'GS Water Temple MQ Lizalfos Hallway', + 'GS Water Temple MQ Serpent River', + 'GS Water Temple MQ South Basement']) + else: + skulltula_locations_final.extend([ + 'GS Water Temple South Basement', + 'GS Water Temple Serpent River', + 'GS Water Temple Falling Platform Room', + 'GS Water Temple Central Room', + 'GS Water Temple Near Boss Key Chest']) + if world.dungeon_mq['SpT']: + skulltula_locations_final.extend([ + 'GS Spirit Temple MQ Lower Adult Right', + 'GS Spirit Temple MQ Lower Adult Left', + 'GS Spirit Temple MQ Iron Knuckle West', + 'GS Spirit Temple MQ Iron Knuckle North', + 'GS Spirit Temple MQ Sun Block Room']) + else: + skulltula_locations_final.extend([ + 'GS Spirit Temple Metal Fence', + 'GS Spirit Temple Bomb for Light Room', + 'GS Spirit Temple Hall to West Iron Knuckle', + 'GS Spirit Temple Boulder Room', + 'GS Spirit Temple Lobby']) + if world.dungeon_mq['ShT']: + skulltula_locations_final.extend([ + 'GS Shadow Temple MQ Crusher Room', + 'GS Shadow Temple MQ Wind Hint Room', + 'GS Shadow Temple MQ After Wind', + 'GS Shadow Temple MQ After Ship', + 'GS Shadow Temple MQ Near Boss']) + else: + skulltula_locations_final.extend([ + 'GS Shadow Temple Like Like Room', + 'GS Shadow Temple Crusher Room', + 'GS Shadow Temple Single Giant Pot', + 'GS Shadow Temple Near Ship', + 'GS Shadow Temple Triple Giant Pot']) + if world.dungeon_mq['BW']: + skulltula_locations_final.extend([ + 'GS Well MQ Basement', + 'GS Well MQ Coffin Room', + 'GS Well MQ West Inner Room']) + else: + skulltula_locations_final.extend([ + 'GS Well West Inner Room', + 'GS Well East Inner Room', + 'GS Well Like Like Cage']) + if world.dungeon_mq['IC']: + skulltula_locations_final.extend([ + 'GS Ice Cavern MQ Scarecrow', + 'GS Ice Cavern MQ Ice Block', + 'GS Ice Cavern MQ Red Ice']) + else: + skulltula_locations_final.extend([ + 'GS Ice Cavern Spinning Scythe Room', + 'GS Ice Cavern Heart Piece Room', + 'GS Ice Cavern Push Block Room']) + if world.tokensanity == 'off': + for location in skulltula_locations_final: + placed_items[location] = 'Gold Skulltula Token' + elif world.tokensanity == 'dungeons': + for location in skulltula_locations_final: + if world.get_location(location).scene >= 0x0A: + placed_items[location] = 'Gold Skulltula Token' + else: + pool.append('Gold Skulltula Token') + else: + pool.extend(['Gold Skulltula Token'] * 100) + + if world.bombchus_in_logic: + pool.extend(['Bombchus']) + if world.difficulty == 'normal': + pool.extend(['Bombchus'] * 3) + elif world.difficulty == 'hard': + pool.extend(['Bombchus'] * 2) + pool.extend(get_junk_item(1)) + else: + pool.extend(get_junk_item(3)) + if world.dungeon_mq['JB']: + if world.difficulty == 'normal': + pool.extend(['Bombchus']) + else: + pool.extend(get_junk_item(1)) + if world.dungeon_mq['SpT']: + if world.difficulty == 'normal': + pool.extend(['Bombchus'] * 2) + else: + pool.extend(get_junk_item(2)) + if not world.dungeon_mq['BW']: + if world.difficulty == 'normal': + pool.extend(['Bombchus']) + else: + pool.extend(get_junk_item(1)) + if world.dungeon_mq['GTG']: + if world.difficulty == 'normal': + pool.extend(['Bombchus']) + else: + pool.extend(get_junk_item(1)) + else: + pool.extend(['Bombchus (5)']) + if world.difficulty == 'very_hard' or world.difficulty == 'ohko': + pool.extend(get_junk_item(2)) + else: + pool.extend(['Bombchus (10)'] * 2) + if world.dungeon_mq['JB']: + if world.difficulty == 'normal': + pool.extend(['Bombchus (10)']) + else: + pool.extend(get_junk_item(1)) + if world.dungeon_mq['SpT']: + if world.difficulty == 'normal': + pool.extend(['Bombchus (10)'] * 2) + else: + pool.extend(get_junk_item(2)) + if not world.dungeon_mq['BW']: + if world.difficulty == 'normal': + pool.extend(['Bombchus (10)']) + else: + pool.extend(get_junk_item(1)) + if world.dungeon_mq['GTG']: + if world.difficulty == 'normal': + pool.extend(['Bombchus (10)']) + else: + pool.extend(get_junk_item(1)) + if world.difficulty == 'normal': + if world.dungeon_mq['GC']: + pool.extend(['Bombchus (10)']) + else: + pool.extend(['Bombchus (20)']) + else: + pool.extend(get_junk_item(1)) + + if world.difficulty == 'ohko': + pool.extend(['Recovery Heart']) + if not world.dungeon_mq['GTG']: + pool.extend(['Recovery Heart']) + if not world.dungeon_mq['GC']: + pool.extend(['Recovery Heart'] * 4) + else: + pool.extend(['Ice Trap']) + if not world.dungeon_mq['GTG']: + pool.extend(['Ice Trap']) + if not world.dungeon_mq['GC']: + pool.extend(['Ice Trap'] * 4) + + if world.difficulty == 'normal': + pool.extend(['Magic Meter', 'Double Defense', 'Deku Stick Capacity', 'Deku Nut Capacity', 'Bow', 'Slingshot', 'Bomb Bag'] + ['Heart Container'] * 8) + else: + pool.extend(get_junk_item(15)) + + if world.difficulty == 'very_hard' or world.difficulty == 'ohko': + pool.extend(get_junk_item(41)) + else: + pool.extend(['Nayrus Love', 'Deku Stick Capacity', 'Deku Nut Capacity', 'Bow', 'Slingshot', 'Bomb Bag'] + ['Piece of Heart'] * 35) + + if world.gerudo_fortress == 'open': + placed_items['Gerudo Fortress North F1 Carpenter'] = 'Recovery Heart' + placed_items['Gerudo Fortress North F2 Carpenter'] = 'Recovery Heart' + placed_items['Gerudo Fortress South F1 Carpenter'] = 'Recovery Heart' + placed_items['Gerudo Fortress South F2 Carpenter'] = 'Recovery Heart' + elif world.shuffle_smallkeys == 'keysanity': + if world.gerudo_fortress == 'fast': + pool.append('Small Key (Gerudo Fortress)') + placed_items['Gerudo Fortress North F2 Carpenter'] = 'Recovery Heart' + placed_items['Gerudo Fortress South F1 Carpenter'] = 'Recovery Heart' + placed_items['Gerudo Fortress South F2 Carpenter'] = 'Recovery Heart' + else: + pool.extend(['Small Key (Gerudo Fortress)'] * 4) + else: + if world.gerudo_fortress == 'fast': + placed_items['Gerudo Fortress North F1 Carpenter'] = 'Small Key (Gerudo Fortress)' + placed_items['Gerudo Fortress North F2 Carpenter'] = 'Recovery Heart' + placed_items['Gerudo Fortress South F1 Carpenter'] = 'Recovery Heart' + placed_items['Gerudo Fortress South F2 Carpenter'] = 'Recovery Heart' + else: + placed_items['Gerudo Fortress North F1 Carpenter'] = 'Small Key (Gerudo Fortress)' + placed_items['Gerudo Fortress North F2 Carpenter'] = 'Small Key (Gerudo Fortress)' + placed_items['Gerudo Fortress South F1 Carpenter'] = 'Small Key (Gerudo Fortress)' + placed_items['Gerudo Fortress South F2 Carpenter'] = 'Small Key (Gerudo Fortress)' + + if world.shuffle_gerudo_card and world.gerudo_fortress != 'open': + pool.append('Gerudo Membership Card') + else: + placed_items['Gerudo Fortress Membership Card'] = 'Gerudo Membership Card' + + if world.shopsanity == 'off': + placed_items.update(vanilla_shop_items) + if world.bombchus_in_logic: + placed_items['Kokiri Shop Item 8'] = 'Buy Bombchu (5)' + placed_items['Castle Town Bazaar Item 4'] = 'Buy Bombchu (5)' + placed_items['Kakariko Bazaar Item 4'] = 'Buy Bombchu (5)' + pool.extend(normal_rupees) + + else: + remain_shop_items = [item for _,item in vanilla_shop_items.items()] + pool.extend(min_shop_items) + for item in min_shop_items: + remain_shop_items.remove(item) + + shop_slots_count = len(remain_shop_items) + shop_nonitem_count = len(world.shop_prices) + shop_item_count = shop_slots_count - shop_nonitem_count + + pool.extend(random.sample(remain_shop_items, shop_item_count)) + pool.extend(get_junk_item(shop_nonitem_count)) + if world.shopsanity == '0': + pool.extend(normal_rupees) + else: + pool.extend(shopsanity_rupees) + + if world.shuffle_scrubs != 'off': + if world.dungeon_mq['DT']: + pool.append('Deku Shield') + if world.dungeon_mq['DC']: + pool.extend(['Deku Stick (1)', 'Deku Shield', 'Recovery Heart']) + else: + pool.extend(['Deku Nuts (5)', 'Deku Stick (1)', 'Deku Shield']) + if not world.dungeon_mq['JB']: + pool.append('Deku Nuts (5)') + if world.dungeon_mq['GC']: + pool.extend(['Bombs (5)', 'Recovery Heart', 'Rupees (5)', 'Deku Nuts (5)']) + else: + pool.extend(['Bombs (5)', 'Recovery Heart', 'Rupees (5)']) + pool.extend(deku_scrubs_items) + for _ in range(7): + pool.append('Arrows (30)' if random.randint(0,3) > 0 else 'Deku Seeds (30)') + + else: + if world.dungeon_mq['DT']: + placed_items['DT MQ Deku Scrub Deku Shield'] = 'Buy Deku Shield' + if world.dungeon_mq['DC']: + placed_items['DC MQ Deku Scrub Deku Sticks'] = 'Buy Deku Stick (1)' + placed_items['DC MQ Deku Scrub Deku Seeds'] = 'Buy Deku Seeds (30)' + placed_items['DC MQ Deku Scrub Deku Shield'] = 'Buy Deku Shield' + placed_items['DC MQ Deku Scrub Red Potion'] = 'Buy Red Potion [30]' + else: + placed_items['DC Deku Scrub Deku Nuts'] = 'Buy Deku Nut (5)' + placed_items['DC Deku Scrub Deku Sticks'] = 'Buy Deku Stick (1)' + placed_items['DC Deku Scrub Deku Seeds'] = 'Buy Deku Seeds (30)' + placed_items['DC Deku Scrub Deku Shield'] = 'Buy Deku Shield' + if not world.dungeon_mq['JB']: + placed_items['Jabu Deku Scrub Deku Nuts'] = 'Buy Deku Nut (5)' + if world.dungeon_mq['GC']: + placed_items['GC MQ Deku Scrub Deku Nuts'] = 'Buy Deku Nut (5)' + placed_items['GC MQ Deku Scrub Bombs'] = 'Buy Bombs (5) [35]' + placed_items['GC MQ Deku Scrub Arrows'] = 'Buy Arrows (30)' + placed_items['GC MQ Deku Scrub Red Potion'] = 'Buy Red Potion [30]' + placed_items['GC MQ Deku Scrub Green Potion'] = 'Buy Green Potion' + else: + placed_items['GC Deku Scrub Bombs'] = 'Buy Bombs (5) [35]' + placed_items['GC Deku Scrub Arrows'] = 'Buy Arrows (30)' + placed_items['GC Deku Scrub Red Potion'] = 'Buy Red Potion [30]' + placed_items['GC Deku Scrub Green Potion'] = 'Buy Green Potion' + placed_items.update(vanilla_deku_scrubs) - if not dungeon_items: - pool.extend(notmapcompass) pool.extend(alwaysitems) + if world.dungeon_mq['DT']: + pool.extend(DT_MQ) + else: + pool.extend(DT_vanilla) + if world.dungeon_mq['DC']: + pool.extend(DC_MQ) + else: + pool.extend(DC_vanilla) + if world.dungeon_mq['JB']: + pool.extend(JB_MQ) + if world.dungeon_mq['FoT']: + pool.extend(FoT_MQ) + else: + pool.extend(FoT_vanilla) + if world.dungeon_mq['FiT']: + pool.extend(FiT_MQ) + else: + pool.extend(FiT_vanilla) + if world.dungeon_mq['SpT']: + pool.extend(SpT_MQ) + else: + placed_items['Spirit Temple Nut Crate'] = 'Deku Nut Drop' + pool.extend(SpT_vanilla) + if world.dungeon_mq['ShT']: + pool.extend(ShT_MQ) + else: + pool.extend(ShT_vanilla) + if not world.dungeon_mq['BW']: + placed_items['Bottom of the Well Stick Pot'] = 'Deku Stick Drop' + pool.extend(BW_vanilla) + if world.dungeon_mq['GTG']: + pool.extend(GTG_MQ) + else: + pool.extend(GTG_vanilla) + if world.dungeon_mq['GC']: + pool.extend(GC_MQ) + else: + pool.extend(GC_vanilla) + for _ in range(normal_bottle_count): bottle = random.choice(normal_bottles) pool.append(bottle) + + if world.big_poe_count_random: + world.big_poe_count = random.randint(1, 10) + tradeitem = random.choice(tradeitems) + earliest_trade = tradeitemoptions.index(world.logic_earliest_adult_trade) + latest_trade = tradeitemoptions.index(world.logic_latest_adult_trade) + if earliest_trade > latest_trade: + earliest_trade, latest_trade = latest_trade, earliest_trade + tradeitem = random.choice(tradeitems[earliest_trade:latest_trade+1]) pool.append(tradeitem) + + pool.extend(songlist) + + if world.shuffle_mapcompass == 'remove' or world.shuffle_mapcompass == 'startwith': + for item in [item for dungeon in world.dungeons for item in dungeon.dungeon_items]: + world.state.collect(item) + pool.extend(get_junk_item()) + if world.shuffle_smallkeys == 'remove': + for item in [item for dungeon in world.dungeons for item in dungeon.small_keys]: + world.state.collect(item) + pool.extend(get_junk_item()) + if world.shuffle_bosskeys == 'remove': + for item in [item for dungeon in world.dungeons for item in dungeon.boss_key]: + world.state.collect(item) + pool.extend(get_junk_item()) + if not world.keysanity and not world.dungeon_mq['FiT']: + world.state.collect(ItemFactory('Small Key (Fire Temple)')) + return (pool, placed_items) +def choose_trials(world): + if world.trials_random: + world.trials = random.randint(0, 6) + num_trials = int(world.trials) + choosen_trials = random.sample(['Forest', 'Fire', 'Water', 'Spirit', 'Shadow', 'Light'], num_trials) + for trial in world.skipped_trials: + if trial not in choosen_trials: + world.skipped_trials[trial] = True + def fill_bosses(world, bossCount=9): - boss_rewards = ItemFactory(rewardlist) - boss_locations = [world.get_location('Queen Gohma'), world.get_location('King Dodongo'), world.get_location('Barinade'), world.get_location('Phantom Ganon'), - world.get_location('Volvagia'), world.get_location('Morpha'), world.get_location('Bongo Bongo'), world.get_location('Twinrova'), world.get_location('Links Pocket')] + boss_rewards = ItemFactory(rewardlist, world) + boss_locations = [ + world.get_location('Queen Gohma'), + world.get_location('King Dodongo'), + world.get_location('Barinade'), + world.get_location('Phantom Ganon'), + world.get_location('Volvagia'), + world.get_location('Morpha'), + world.get_location('Bongo Bongo'), + world.get_location('Twinrova'), + world.get_location('Links Pocket')] + placed_prizes = [loc.item.name for loc in boss_locations if loc.item is not None] unplaced_prizes = [item for item in boss_rewards if item.name not in placed_prizes] empty_boss_locations = [loc for loc in boss_locations if loc.item is None] @@ -103,29 +874,4 @@ def fill_bosses(world, bossCount=9): random.shuffle(prize_locs) item = prizepool.pop() loc = prize_locs.pop() - world.push_item(loc, item, False) - world.get_location(loc).event = True - -def fill_songs(world, attempts=15): - songs = ItemFactory(songlist) - song_locations = [world.get_location('Song from Composer Grave'), world.get_location('Impa at Castle'), world.get_location('Song from Malon'), world.get_location('Song from Saria'), world.get_location('Song from Ocarina of Time'), world.get_location('Song at Windmill'), world.get_location('Sheik Forest Song'), world.get_location('Sheik at Temple'), world.get_location('Sheik in Crater'), world.get_location('Sheik in Ice Cavern'), world.get_location('Sheik in Kakariko'), world.get_location('Sheik at Colossus')] - placed_prizes = [loc.item.name for loc in song_locations if loc.item is not None] - unplaced_prizes = [song for song in songs if song.name not in placed_prizes] - empty_song_locations = [loc for loc in song_locations if loc.item is None] - - while attempts: - attempts -= 1 - try: - prizepool = list(unplaced_prizes) - prize_locs = list(empty_song_locations) - random.shuffle(prizepool) - random.shuffle(prize_locs) - fill_restrictive(world, world.get_all_state(keys=True), prize_locs, prizepool) #TODO: Set keys to true once keys are properly implemented - except FillError: - logging.getLogger('').info("Failed to place songs. Will retry %s more times", attempts) - for location in empty_song_locations: - location.item = None - continue - break - else: - raise FillError('Unable to place songs') + world.push_item(loc, item) diff --git a/Items.py b/Items.py index e23b46470..3e8593d7d 100644 --- a/Items.py +++ b/Items.py @@ -3,7 +3,7 @@ from BaseClasses import Item -def ItemFactory(items): +def ItemFactory(items, world=None): ret = [] singleton = False if isinstance(items, str): @@ -11,254 +11,306 @@ def ItemFactory(items): singleton = True for item in items: if item in item_table: - advancement, priority, type, code, index = item_table[item] - ret.append(Item(item, advancement, priority, type, code, index)) + advancement, priority, type, code, index, object, model = item_table[item] + new_item = Item(item, advancement, priority, type, code, index, object, model) + if world: + new_item.world = world + ret.append(new_item) else: - logging.getLogger('').warning('Unknown Item: %s', item) - return None + raise KeyError('Unknown Item: %s', item) if singleton: return ret[0] return ret +class ShopData(object): + def __init__(self, model, gid, price): + self.model = model + self.gid = gid + self.price = price + + # Format: Name: (Advancement, Priority, Type, ItemCode, Index) -item_table = {'Bow': (True, False, None, None, 0x83), - 'Progressive Hookshot': (True, False, None, None, 0x80), - 'Hammer': (True, False, None, 0x01A0, 0x0D), - 'Slingshot': (True, False, None, None, 0x84), - 'Boomerang': (True, False, None, 0x00C0, 0x06), - 'Bomb Bag': (True, False, None, None, 0x82), - 'Lens of Truth': (True, False, None, 0x0140, 0x0A), - 'Dins Fire': (True, False, None, 0x0B80, 0x5C), - 'Farores Wind': (True, False, None, 0x0BA0, 0x5D), - 'Nayrus Love': (True, False, None, 0x0BC0, 0x5E), - 'Fire Arrows': (True, False, None, 0x0B00, 0x58), - 'Ice Arrows': (True, False, None, 0x0B20, 0x59), - 'Light Arrows': (True, False, None, 0x0B40, 0x5A), - 'Fairy Ocarina': (True, False, None, 0x0760, 0x3B), - 'Ocarina of Time': (True, False, None, 0x0180, 0x0C), - 'Bottle': (True, False, None, 0x01E0, 0x0F), - 'Bottle with Letter': (True, False, None, 0x02A0, 0x15), - 'Bottle with Milk': (True, False, None, 0x0280, 0x14), - 'Bottle with Red Potion': (True, False, None, None, 0x89), - 'Bottle with Green Potion': (True, False, None, None, 0x8A), - 'Bottle with Blue Potion': (True, False, None, None, 0x8B), - 'Bottle with Fairy': (True, False, None, None, 0x8C), - 'Bottle with Fish': (True, False, None, None, 0x8D), - 'Bottle with Blue Fire': (True, False, None, None, 0x8E), - 'Bottle with Bugs': (True, False, None, None, 0x8F), - 'Bottle with Poe': (True, False, None, None, 0x91), - 'Pocket Egg': (True, False, None, 0x03A0, 0x1D), - 'Pocket Cucco': (True, False, None, 0x03C0, 0x1E), - 'Cojiro': (True, False, None, 0x01C0, 0x0E), - 'Odd Mushroom': (True, False, None, 0x03E0, 0x1F), - 'Odd Potion': (True, False, None, 0x0400, 0x20), - 'Poachers Saw': (True, False, None, 0x0420, 0x21), - 'Broken Sword': (True, False, None, 0x0440, 0x22), - 'Prescription': (True, False, None, 0x0460, 0x23), - 'Eyeball Frog': (True, False, None, 0x0480, 0x24), - 'Eyedrops': (True, False, None, 0x04A0, 0x25), - 'Claim Check': (True, False, None, 0x04C0, 0x26), - 'Kokiri Sword': (True, False, None, 0x04E0, 0x27), - 'Master Sword': (True, False, None, None, None), - 'Biggoron Sword': (True, False, None, None, 0xB5), - 'Deku Shield': (False, False, None, 0x0520, 0x29), - 'Hylian Shield': (False, False, None, 0x0540, 0x2A), - 'Mirror Shield': (True, False, None, 0x0560, 0x2B), - 'Goron Tunic': (True, False, None, 0x0580, 0x2C), - 'Zora Tunic': (True, False, None, 0x05A0, 0x2D), - 'Iron Boots': (True, False, None, 0x05C0, 0x2E), - 'Hover Boots': (True, False, None, 0x05E0, 0x2F), - 'Progressive Strength Upgrade': (True, False, None, None, 0x81), - 'Progressive Scale': (True, False, None, None, 0x86), - 'Progressive Wallet': (True, False, None, None, 0x85), - 'Deku Stick Capacity': (False, False, None, None, 0x88), - 'Deku Nut Capacity': (False, False, None, None, 0x87), - 'Magic Meter': (True, False, None, None, 0xC0), - 'Double Defense': (False, False, None, None, 0xBF), - 'Stone of Agony': (True, False, None, 0x0720, 0x39), - 'Piece of Heart': (False, False, None, 0x07C0, 0x3E), - 'Heart Container': (False, False, None, 0x07A0, 0x3D), - 'Piece of Heart (Treasure Chest Game)': (False, False, None, None, 0x76), - 'Heart Container (Boss)': (False, False, None, None, 0x4F), - 'Recovery Heart': (False, False, None, None, 0xB6), - 'Arrows (5)': (False, False, None, None, 0xB7), - 'Arrows (10)': (False, False, None, None, 0xB8), - 'Arrows (30)': (False, False, None, None, 0xB9), - 'Bombs (5)': (False, False, None, None, 0xBA), - 'Bombs (10)': (False, False, None, None, 0xBB), - 'Bombs (20)': (False, False, None, None, 0xBC), - 'Bombchus (5)': (False, False, None, 0x0D40, 0x6A), - 'Bombchus (10)': (False, False, None, 0x0060, 0x03), - 'Bombchus (20)': (False, False, None, 0x0D60, 0x6B), - 'Deku Nuts (5)': (False, False, None, None, 0xBD), - 'Deku Nuts (10)': (False, False, None, None, 0xBE), - 'Rupee (1)': (False, False, None, 0x0980, 0x4C), - 'Rupees (5)': (False, False, None, 0x09A0, 0x4D), - 'Rupees (20)': (False, False, None, 0x09C0, 0x4E), - 'Rupees (50)': (False, False, None, 0x0AA0, 0x55), - 'Rupees (200)': (False, False, None, 0x0AC0, 0x56), - 'Skull Mask': (False, False, None, 0x02E0, 0x17), - 'Spooky Mask': (False, False, None, 0x0300, 0x18), - 'Keaton Mask': (False, False, None, 0x0340, 0x1A), - 'Bunny Hood': (False, False, None, 0x0360, 0x1B), - 'Mask of Truth': (False, False, None, 0x0380, 0x1C), - 'Goron Mask': (False, False, None, 0x0A20, 0x51), - 'Zora Mask': (False, False, None, 0x0A40, 0x52), - 'Gerudo Mask': (False, False, None, 0x0A60, 0x53), - 'Ice Trap': (False, True, None, 0x0F80, 0x7C), - 'Magic Bean': (True, False, None, 0x02C0, 0x16), - 'Map': (False, False, 'Map', 0x0820, 0x41), - 'Compass': (False, False, 'Compass', 0x0800, 0x40), - 'Boss Key': (False, False, 'BossKey', 0x07E0, 0x3F), - 'Small Key': (False, False, 'SmallKey', 0x0840, 0x42), - 'Boss Key (Forest Temple)': (False, False, 'BossKey', None, 0x92), - 'Boss Key (Fire Temple)': (False, False, 'BossKey', None, 0x93), - 'Boss Key (Water Temple)': (False, False, 'BossKey', None, 0x94), - 'Boss Key (Spirit Temple)': (False, False, 'BossKey', None, 0x95), - 'Boss Key (Shadow Temple)': (False, False, 'BossKey', None, 0x96), - 'Boss Key (Ganons Castle)': (False, False, 'BossKey', None, 0x97), - 'Compass (Deku Tree)': (False, False, 'Compass', None, 0x98), - 'Compass (Dodongos Cavern)': (False, False, 'Compass', None, 0x99), - 'Compass (Jabu Jabus Belly)': (False, False, 'Compass', None, 0x9A), - 'Compass (Forest Temple)': (False, False, 'Compass', None, 0x9B), - 'Compass (Fire Temple)': (False, False, 'Compass', None, 0x9C), - 'Compass (Water Temple)': (False, False, 'Compass', None, 0x9D), - 'Compass (Spirit Temple)': (False, False, 'Compass', None, 0x9E), - 'Compass (Shadow Temple)': (False, False, 'Compass', None, 0x9F), - 'Compass (Bottom of the Well)': (False, False, 'Compass', None, 0xA0), - 'Compass (Ice Cavern)': (False, False, 'Compass', None, 0xA1), - 'Map (Deku Tree)': (False, False, 'Map', None, 0xA2), - 'Map (Dodongos Cavern)': (False, False, 'Map', None, 0xA3), - 'Map (Jabu Jabus Belly)': (False, False, 'Map', None, 0xA4), - 'Map (Forest Temple)': (False, False, 'Map', None, 0xA5), - 'Map (Fire Temple)': (False, False, 'Map', None, 0xA6), - 'Map (Water Temple)': (False, False, 'Map', None, 0xA7), - 'Map (Spirit Temple)': (False, False, 'Map', None, 0xA8), - 'Map (Shadow Temple)': (False, False, 'Map', None, 0xA9), - 'Map (Bottom of the Well)': (False, False, 'Map', None, 0xAA), - 'Map (Ice Cavern)': (False, False, 'Map', None, 0xAB), - 'Small Key (Forest Temple)': (False, False, 'SmallKey', None, 0xAC), - 'Small Key (Fire Temple)': (False, False, 'SmallKey', None, 0xAD), - 'Small Key (Water Temple)': (False, False, 'SmallKey', None, 0xAE), - 'Small Key (Spirit Temple)': (False, False, 'SmallKey', None, 0xAF), - 'Small Key (Shadow Temple)': (False, False, 'SmallKey', None, 0xB0), - 'Small Key (Bottom of the Well)': (False, False, 'SmallKey', None, 0xB1), - 'Small Key (Gerudo Training Grounds)': (False, False, 'SmallKey', None, 0xB2), - 'Small Key (Gerudo Fortress)': (False, False, 'SmallKey', None, 0xB3), - 'Small Key (Ganons Castle)': (False, False, 'SmallKey', None, 0xB4), - 'Zeldas Letter': (True, False, None, None, None), - 'Zeldas Lullaby': (True, False, 'Song', 0x0A, 0x5), - 'Eponas Song': (True, False, 'Song', 0x09, 0x4), - 'Suns Song': (True, False, 'Song', 0x0B, 0x2), - 'Sarias Song': (True, False, 'Song', 0x08, 0x3), - 'Song of Time': (True, False, 'Song', 0x0C, 0x1), - 'Song of Storms': (True, False, 'Song', 0x0D, 0x0), - 'Minuet of Forest': (True, False, 'Song', 0x02, 0xB), - 'Prelude of Light': (True, False, 'Song', 0x07, 0x6), - 'Bolero of Fire': (True, False, 'Song', 0x03, 0xA), - 'Serenade of Water': (True, False, 'Song', 0x04, 0x9), - 'Nocturne of Shadow': (True, False, 'Song', 0x06, 0x7), - 'Requiem of Spirit': (True, False, 'Song', 0x05, 0x8), - 'Epona': (True, False, 'Event', None, None), - 'Gerudo Membership Card': (True, False, 'Event', 0x0740, 0x3A), - 'Gold Skulltulla Token': (True, False, 'Event', None, None), - 'Kokiri Emerald': (True, False, 'Event', 0x6C, None), - 'Goron Ruby': (True, False, 'Event', 0x6D, None), - 'Zora Sapphire': (True, False, 'Event', 0x6E, None), - 'Forest Medallion': (True, False, 'Event', 0x66, None), - 'Fire Medallion': (True, False, 'Event', 0x67, None), - 'Water Medallion': (True, False, 'Event', 0x68, None), - 'Spirit Medallion': (True, False, 'Event', 0x69, None), - 'Shadow Medallion': (True, False, 'Event', 0x6A, None), - 'Light Medallion': (True, False, 'Event', 0x6B, None), - 'Forest Trial Clear': (True, False, 'Event', None, None), - 'Fire Trial Clear': (True, False, 'Event', None, None), - 'Water Trial Clear': (True, False, 'Event', None, None), - 'Shadow Trial Clear': (True, False, 'Event', None, None), - 'Spirit Trial Clear': (True, False, 'Event', None, None), - 'Light Trial Clear': (True, False, 'Event', None, None), - 'Triforce': (True, False, 'Event', None, None)} +item_table = { + 'Bow': (True, False, None, None, 0x83, 0x00E9, 0x35), + 'Progressive Hookshot': (True, False, None, None, 0x80, 0x00DD, 0x2D), + 'Hammer': (True, False, None, 0x01A0, 0x0D, 0x00F6, 0x41), + 'Slingshot': (True, False, None, None, 0x84, 0x00E7, 0x33), + 'Boomerang': (True, False, None, 0x00C0, 0x06, 0x00E8, 0x34), + 'Bomb Bag': (True, False, None, None, 0x82, 0x00BF, 0x18), + 'Lens of Truth': (True, False, None, 0x0140, 0x0A, 0x00EA, 0x36), + 'Dins Fire': (True, False, None, 0x0B80, 0x5C, 0x015D, 0x64), + 'Farores Wind': (True, False, None, 0x0BA0, 0x5D, 0x015D, 0x65), + 'Nayrus Love': (True, False, None, 0x0BC0, 0x5E, 0x015D, 0x66), + 'Fire Arrows': (True, False, None, 0x0B00, 0x58, 0x0158, 0x60), + 'Ice Arrows': (True, False, None, 0x0B20, 0x59, 0x0158, 0x61), + 'Light Arrows': (True, False, None, 0x0B40, 0x5A, 0x0158, 0x62), + 'Fairy Ocarina': (True, False, None, 0x0760, 0x3B, 0x010E, 0x46), + 'Ocarina of Time': (True, False, None, 0x0180, 0x0C, 0x00DE, 0x2F), + 'Ocarina': (True, False, None, 0x0180, 0xC3, 0x00DE, 0x2F), + 'Bottle': (True, False, None, 0x01E0, 0x0F, 0x00C6, 0x01), + 'Bottle with Letter': (True, False, None, 0x02A0, 0x15, 0x010B, 0x45), + 'Bottle with Milk': (True, False, None, 0x0280, 0x14, 0x00DF, 0x30), + 'Bottle with Red Potion': (True, False, None, None, 0x89, 0x00C6, 0x01), + 'Bottle with Green Potion': (True, False, None, None, 0x8A, 0x00C6, 0x01), + 'Bottle with Blue Potion': (True, False, None, None, 0x8B, 0x00C6, 0x01), + 'Bottle with Fairy': (True, False, None, None, 0x8C, 0x00C6, 0x01), + 'Bottle with Fish': (True, False, None, None, 0x8D, 0x00C6, 0x01), + 'Bottle with Blue Fire': (True, False, None, None, 0x8E, 0x00C6, 0x01), + 'Bottle with Bugs': (True, False, None, None, 0x8F, 0x00C6, 0x01), + 'Bottle with Big Poe': (True, False, None, None, 0x90, 0x00C6, 0x01), + 'Bottle with Poe': (True, False, None, None, 0x91, 0x00C6, 0x01), + 'Weird Egg': (True, False, None, 0x08E0, 0x47, 0x00DA, 0x29), + 'Pocket Egg': (True, False, None, 0x03A0, 0x1D, 0x00DA, 0x29), + 'Pocket Cucco': (True, False, None, 0x03C0, 0x1E, 0x0109, 0x44), + 'Cojiro': (True, False, None, 0x01C0, 0x0E, 0x0109, 0x5E), + 'Odd Mushroom': (True, False, None, 0x03E0, 0x1F, 0x0141, 0x54), + 'Odd Potion': (True, False, None, 0x0400, 0x20, 0x0140, 0x53), + 'Poachers Saw': (True, False, None, 0x0420, 0x21, 0x00F5, 0x40), + 'Broken Sword': (True, False, None, 0x0440, 0x22, 0x0143, 0x56), + 'Prescription': (True, False, None, 0x0460, 0x23, 0x0146, 0x57), + 'Eyeball Frog': (True, False, None, 0x0480, 0x24, 0x0149, 0x5A), + 'Eyedrops': (True, False, None, 0x04A0, 0x25, 0x013F, 0x52), + 'Claim Check': (True, False, None, 0x04C0, 0x26, 0x0142, 0x55), + 'Kokiri Sword': (True, False, None, 0x04E0, 0x27, 0x018D, 0x74), + 'Master Sword': (True, False, None, None, None, None, None), + 'Biggoron Sword': (True, False, None, None, 0xB5, 0x00F8, 0x43), + 'Deku Shield': (False, False, None, 0x0520, 0xD2, 0x00CB, 0x1D), + 'Hylian Shield': (False, False, None, 0x0540, 0xD3, 0x00DC, 0x2C), + 'Mirror Shield': (True, False, None, 0x0560, 0x2B, 0x00EE, 0x3A), + 'Goron Tunic': (True, False, None, 0x0580, 0x2C, 0x00F2, 0x3C), + 'Zora Tunic': (True, False, None, 0x05A0, 0x2D, 0x00F2, 0x3D), + 'Iron Boots': (True, False, None, 0x05C0, 0x2E, 0x0118, 0x47), + 'Hover Boots': (True, False, None, 0x05E0, 0x2F, 0x0157, 0x5F), + 'Progressive Strength Upgrade': (True, False, None, None, 0x81, 0x0147, 0x58), + 'Progressive Scale': (True, False, None, None, 0x86, 0x00DB, 0x2A), + 'Progressive Wallet': (True, False, None, None, 0x85, 0x00D1, 0x22), + 'Deku Stick Capacity': (False, False, None, None, 0x88, 0x00C7, 0x1B), + 'Deku Nut Capacity': (False, False, None, None, 0x87, 0x00BB, 0x12), + 'Magic Meter': (True, False, None, None, 0xC0, 0x00CD, 0x1E), + 'Double Defense': (True, False, None, None, 0xBF, 0x00BD, 0x13), + 'Stone of Agony': (True, False, None, 0x0720, 0x39, 0x00C8, 0x21), + 'Piece of Heart': (False, False, None, 0x07C0, 0x3E, 0x00BD, 0x14), + 'Heart Container': (False, False, None, 0x07A0, 0x3D, 0x00BD, 0x13), + 'Piece of Heart (Treasure Chest Game)': (False, False, None, None, 0x76, 0x00BD, 0x14), + 'Heart Container (Boss)': (False, False, None, None, 0x4F, 0x00BD, 0x13), + 'Recovery Heart': (False, False, None, None, 0xB6, 0x00B7, 0x09), + 'Arrows (5)': (False, False, None, None, 0xB7, 0x00D8, 0x25), + 'Arrows (10)': (False, False, None, None, 0xB8, 0x00D8, 0x26), + 'Arrows (30)': (False, False, None, None, 0xB9, 0x00D8, 0x27), + 'Bombs (5)': (False, False, None, None, 0xBA, 0x00CE, 0x20), + 'Bombs (10)': (False, False, None, None, 0xBB, 0x00CE, 0x20), + 'Bombs (20)': (False, False, None, None, 0xBC, 0x00CE, 0x20), + 'Bombchus (5)': (True, False, None, 0x0D40, 0x6A, 0x00D9, 0x28), + 'Bombchus (10)': (True, False, None, 0x0060, 0x03, 0x00D9, 0x28), + 'Bombchus (20)': (True, False, None, 0x0D60, 0x6B, 0x00D9, 0x28), + 'Bombchus': (True, False, None, None, 0xC2, 0x00D9, 0x28), + 'Deku Nuts (5)': (False, False, None, None, 0xBD, 0x00BB, 0x12), + 'Deku Nuts (10)': (False, False, None, None, 0xBE, 0x00BB, 0x12), + 'Deku Stick (1)': (False, False, None, 0x00E0, 0xD0, 0x00C7, 0x1B), + 'Deku Seeds (30)': (False, False, None, 0x00E0, 0xD1, 0x0119, 0x48), + 'Rupee (Treasure Chest Game)': (False, False, None, 0x0E40, 0x72, 0x017F, 0x6D), + 'Rupee (1)': (False, False, None, 0x0980, 0x4C, 0x017F, 0x6D), + 'Rupees (5)': (False, False, None, 0x09A0, 0x4D, 0x017F, 0x6E), + 'Rupees (20)': (False, False, None, 0x09C0, 0x4E, 0x017F, 0x6F), + 'Rupees (50)': (False, False, None, 0x0AA0, 0x55, 0x017F, 0x71), + 'Rupees (200)': (False, False, None, 0x0AC0, 0x56, 0x017F, 0x72), + 'Skull Mask': (False, False, None, 0x02E0, 0x17, 0x0136, 0x4F), + 'Spooky Mask': (False, False, None, 0x0300, 0x18, 0x0135, 0x32), + 'Keaton Mask': (False, False, None, 0x0340, 0x1A, 0x0134, 0x31), + 'Bunny Hood': (False, False, None, 0x0360, 0x1B, 0x0137, 0x50), + 'Mask of Truth': (False, False, None, 0x0380, 0x1C, 0x0138, 0x51), + 'Goron Mask': (False, False, None, 0x0A20, 0x51, 0x0150, 0x5B), + 'Zora Mask': (False, False, None, 0x0A40, 0x52, 0x0151, 0x5C), + 'Gerudo Mask': (False, False, None, 0x0A60, 0x53, 0x0152, 0x5D), + 'Ice Trap': (False, True, None, 0x0F80, 0x7C, None, None), + 'Magic Bean': (True, False, None, 0x02C0, 0x16, 0x00F3, 0x3E), + 'Map': (False, False, 'Map', 0x0820, 0x41, 0x00C8, 0x1C), + 'Compass': (False, False, 'Compass', 0x0800, 0x40, 0x00B8, 0x0B), + 'Boss Key': (True, False, 'BossKey', 0x07E0, 0x3F, 0x00B9, 0x0A), + 'Small Key': (True, False, 'SmallKey', 0x0840, 0x42, 0x00AA, 0x02), + 'Boss Key (Forest Temple)': (True, False, 'BossKey', None, 0x92, 0x00B9, 0x0A), + 'Boss Key (Fire Temple)': (True, False, 'BossKey', None, 0x93, 0x00B9, 0x0A), + 'Boss Key (Water Temple)': (True, False, 'BossKey', None, 0x94, 0x00B9, 0x0A), + 'Boss Key (Spirit Temple)': (True, False, 'BossKey', None, 0x95, 0x00B9, 0x0A), + 'Boss Key (Shadow Temple)': (True, False, 'BossKey', None, 0x96, 0x00B9, 0x0A), + 'Boss Key (Ganons Castle)': (True, False, 'BossKey', None, 0x97, 0x00B9, 0x0A), + 'Compass (Deku Tree)': (False, False, 'Compass', None, 0x98, 0x00B8, 0x0B), + 'Compass (Dodongos Cavern)': (False, False, 'Compass', None, 0x99, 0x00B8, 0x0B), + 'Compass (Jabu Jabus Belly)': (False, False, 'Compass', None, 0x9A, 0x00B8, 0x0B), + 'Compass (Forest Temple)': (False, False, 'Compass', None, 0x9B, 0x00B8, 0x0B), + 'Compass (Fire Temple)': (False, False, 'Compass', None, 0x9C, 0x00B8, 0x0B), + 'Compass (Water Temple)': (False, False, 'Compass', None, 0x9D, 0x00B8, 0x0B), + 'Compass (Spirit Temple)': (False, False, 'Compass', None, 0x9E, 0x00B8, 0x0B), + 'Compass (Shadow Temple)': (False, False, 'Compass', None, 0x9F, 0x00B8, 0x0B), + 'Compass (Bottom of the Well)': (False, False, 'Compass', None, 0xA0, 0x00B8, 0x0B), + 'Compass (Ice Cavern)': (False, False, 'Compass', None, 0xA1, 0x00B8, 0x0B), + 'Map (Deku Tree)': (False, False, 'Map', None, 0xA2, 0x00C8, 0x1C), + 'Map (Dodongos Cavern)': (False, False, 'Map', None, 0xA3, 0x00C8, 0x1C), + 'Map (Jabu Jabus Belly)': (False, False, 'Map', None, 0xA4, 0x00C8, 0x1C), + 'Map (Forest Temple)': (False, False, 'Map', None, 0xA5, 0x00C8, 0x1C), + 'Map (Fire Temple)': (False, False, 'Map', None, 0xA6, 0x00C8, 0x1C), + 'Map (Water Temple)': (False, False, 'Map', None, 0xA7, 0x00C8, 0x1C), + 'Map (Spirit Temple)': (False, False, 'Map', None, 0xA8, 0x00C8, 0x1C), + 'Map (Shadow Temple)': (False, False, 'Map', None, 0xA9, 0x00C8, 0x1C), + 'Map (Bottom of the Well)': (False, False, 'Map', None, 0xAA, 0x00C8, 0x1C), + 'Map (Ice Cavern)': (False, False, 'Map', None, 0xAB, 0x00C8, 0x1C), + 'Small Key (Forest Temple)': (True, False, 'SmallKey', None, 0xAC, 0x00AA, 0x02), + 'Small Key (Fire Temple)': (True, False, 'SmallKey', None, 0xAD, 0x00AA, 0x02), + 'Small Key (Water Temple)': (True, False, 'SmallKey', None, 0xAE, 0x00AA, 0x02), + 'Small Key (Spirit Temple)': (True, False, 'SmallKey', None, 0xAF, 0x00AA, 0x02), + 'Small Key (Shadow Temple)': (True, False, 'SmallKey', None, 0xB0, 0x00AA, 0x02), + 'Small Key (Bottom of the Well)': (True, False, 'SmallKey', None, 0xB1, 0x00AA, 0x02), + 'Small Key (Gerudo Training Grounds)': (True, False, 'SmallKey', None, 0xB2, 0x00AA, 0x02), + 'Small Key (Gerudo Fortress)': (True, False, 'FortressSmallKey', None, 0xB3, 0x00AA, 0x02), + 'Small Key (Ganons Castle)': (True, False, 'SmallKey', None, 0xB4, 0x00AA, 0x02), + 'Zeldas Letter': (True, False, None, None, None, None, None), + 'Zeldas Lullaby': (True, False, 'Song', [0x0A, 0x5], 0xCA, 0x00B6, 0x04), + 'Eponas Song': (True, False, 'Song', [0x09, 0x4], 0xCB, 0x00B6, 0x06), + 'Suns Song': (True, False, 'Song', [0x0B, 0x2], 0xCD, 0x00B6, 0x08), + 'Sarias Song': (True, False, 'Song', [0x08, 0x3], 0xCC, 0x00B6, 0x03), + 'Song of Time': (True, False, 'Song', [0x0C, 0x1], 0xCE, 0x00B6, 0x05), + 'Song of Storms': (True, False, 'Song', [0x0D, 0x0], 0xCF, 0x00B6, 0x07), + 'Minuet of Forest': (True, False, 'Song', [0x02, 0xB], 0xC4, 0x00B6, 0x03), + 'Prelude of Light': (True, False, 'Song', [0x07, 0x6], 0xC9, 0x00B6, 0x08), + 'Bolero of Fire': (True, False, 'Song', [0x03, 0xA], 0xC5, 0x00B6, 0x04), + 'Serenade of Water': (True, False, 'Song', [0x04, 0x9], 0xC6, 0x00B6, 0x05), + 'Nocturne of Shadow': (True, False, 'Song', [0x06, 0x7], 0xC8, 0x00B6, 0x07), + 'Requiem of Spirit': (True, False, 'Song', [0x05, 0x8], 0xC7, 0x00B6, 0x08), + 'Gold Skulltula Token': (True, False, 'Token', None, 0x5B, 0x015C, 0x63), + 'Epona': (True, False, 'Event', None, None, None, None), + 'Deku Stick Drop': (True, False, 'Event', None, None, None, None), + 'Deku Nut Drop': (True, False, 'Event', None, None, None, None), + 'Carpenter Rescue': (True, False, 'Event', None, None, None, None), + 'Gerudo Membership Card': (True, False, None, 0x0740, 0x3A, 0x00D7, 0x24), + 'Kokiri Emerald': (True, False, 'Event', 0x6C, None, None, None), + 'Goron Ruby': (True, False, 'Event', 0x6D, None, None, None), + 'Zora Sapphire': (True, False, 'Event', 0x6E, None, None, None), + 'Forest Medallion': (True, False, 'Event', 0x66, None, None, None), + 'Fire Medallion': (True, False, 'Event', 0x67, None, None, None), + 'Water Medallion': (True, False, 'Event', 0x68, None, None, None), + 'Spirit Medallion': (True, False, 'Event', 0x69, None, None, None), + 'Shadow Medallion': (True, False, 'Event', 0x6A, None, None, None), + 'Light Medallion': (True, False, 'Event', 0x6B, None, None, None), + 'Forest Trial Clear': (True, False, 'Event', None, None, None, None), + 'Fire Trial Clear': (True, False, 'Event', None, None, None, None), + 'Water Trial Clear': (True, False, 'Event', None, None, None, None), + 'Shadow Trial Clear': (True, False, 'Event', None, None, None, None), + 'Spirit Trial Clear': (True, False, 'Event', None, None, None, None), + 'Light Trial Clear': (True, False, 'Event', None, None, None, None), + 'Triforce': (True, False, 'Event', None, None, None, None), + 'Buy Deku Nut (5)': (True, False, 'Shop', None, 0x00, 0x00BB, 0x12), + 'Buy Arrows (30)': (False, True, 'Shop', None, 0x01, 0x00D8, 0x26), + 'Buy Arrows (50)': (False, True, 'Shop', None, 0x02, 0x00D8, 0x27), + 'Buy Bombs (5) [25]': (False, True, 'Shop', None, 0x03, 0x00CE, 0x20), + 'Buy Deku Nut (10)': (True, False, 'Shop', None, 0x04, 0x00BB, 0x12), + 'Buy Deku Stick (1)': (True, False, 'Shop', None, 0x05, 0x00C7, 0x1B), + 'Buy Bombs (10)': (False, True, 'Shop', None, 0x06, 0x00CE, 0x20), + 'Buy Fish': (False, True, 'Shop', None, 0x07, 0x00F4, 0x3F), + 'Buy Red Potion [30]': (False, True, 'Shop', None, 0x08, 0x00EB, 0x38), + 'Buy Green Potion': (False, True, 'Shop', None, 0x09, 0x00EB, 0x37), + 'Buy Blue Potion': (False, True, 'Shop', None, 0x0A, 0x00EB, 0x39), + 'Buy Hylian Shield': (False, True, 'Shop', None, 0x0C, 0x00DC, 0x2C), + 'Buy Deku Shield': (True, False, 'Shop', None, 0x0D, 0x00CB, 0x1D), + 'Buy Goron Tunic': (True, False, 'Shop', None, 0x0E, 0x00F2, 0x3C), + 'Buy Zora Tunic': (True, False, 'Shop', None, 0x0F, 0x00F2, 0x3D), + 'Buy Heart': (False, True, 'Shop', None, 0x10, 0x00B7, 0x09), + 'Buy Bombchu (10)': (True, False, 'Shop', None, 0x15, 0x00D9, 0x28), + 'Buy Bombchu (20)': (True, False, 'Shop', None, 0x16, 0x00D9, 0x28), + 'Buy Bombchu (5)': (True, False, 'Shop', None, 0x18, 0x00D9, 0x28), + 'Buy Deku Seeds (30)': (False, True, 'Shop', None, 0x1D, 0x0119, 0x48), + 'Sold Out': (False, True, 'Shop', None, 0x26, 0x0148, 0x59), + 'Buy Blue Fire': (True, False, 'Shop', None, 0x27, 0x0173, 0x67), + 'Buy Bottle Bug': (True, False, 'Shop', None, 0x28, 0x0174, 0x68), + 'Buy Poe': (False, True, 'Shop', None, 0x2A, 0x0176, 0x6A), + 'Buy Fairy\'s Spirit': (False, True, 'Shop', None, 0x2B, 0x0177, 0x6B), + 'Buy Arrows (10)': (False, True, 'Shop', None, 0x2C, 0x00D8, 0x25), + 'Buy Bombs (20)': (False, True, 'Shop', None, 0x2D, 0x00CE, 0x20), + 'Buy Bombs (30)': (False, True, 'Shop', None, 0x2E, 0x00CE, 0x20), + 'Buy Bombs (5) [35]': (False, True, 'Shop', None, 0x2F, 0x00CE, 0x20), + 'Buy Red Potion [40]': (False, True, 'Shop', None, 0x30, 0x00EB, 0x38), + 'Buy Red Potion [50]': (False, True, 'Shop', None, 0x31, 0x00EB, 0x38), +} item_data = { - 'Hammer': [0x11, 0x80, 0x41, 0x38, 0x00, 0xF6], - 'Boomerang': [0x0E, 0x80, 0x34, 0x35, 0x00, 0xE8], - 'Lens of Truth': [0x0F, 0x80, 0x36, 0x39, 0x00, 0xEA], - 'Dins Fire': [0x05, 0x80, 0x64, 0xAD, 0x01, 0x5D], - 'Farores Wind': [0x0D, 0x80, 0x65, 0xAE, 0x01, 0x5D], - 'Nayrus Love': [0x13, 0x80, 0x66, 0xAF, 0x01, 0x5D], - 'Fire Arrows': [0x04, 0x80, 0x60, 0x70, 0x01, 0x58], - 'Ice Arrows': [0x0C, 0x80, 0x61, 0x71, 0x01, 0x58], - 'Light Arrows': [0x12, 0x80, 0x62, 0x72, 0x01, 0x58], - 'Bottle': [0x14, 0x80, 0x01, 0x42, 0x00, 0xC6], - 'Bottle with Letter': [0x1B, 0x80, 0x45, 0x99, 0x01, 0x0B], - 'Bottle with Milk': [0x1A, 0x80, 0x30, 0x98, 0x00, 0xDF], - 'Pocket Egg': [0x2D, 0x80, 0x29, 0x01, 0x00, 0xDA], - 'Pocket Cucco': [0x2E, 0x80, 0x44, 0x0B, 0x01, 0x09], - 'Cojiro': [0x2F, 0x80, 0x5E, 0x02, 0x01, 0x09], - 'Odd Mushroom': [0x30, 0x80, 0x54, 0x03, 0x01, 0x41], - 'Odd Potion': [0x31, 0x80, 0x53, 0x04, 0x01, 0x40], - 'Poachers Saw': [0x32, 0x80, 0x40, 0x05, 0x00, 0xF5], - 'Broken Sword': [0x33, 0x80, 0x56, 0x08, 0x01, 0x43], - 'Prescription': [0x34, 0x80, 0x57, 0x09, 0x01, 0x46], - 'Eyeball Frog': [0x35, 0x80, 0x5A, 0x0D, 0x01, 0x49], - 'Eyedrops': [0x36, 0x80, 0x52, 0x0E, 0x01, 0x3F], - 'Claim Check': [0x37, 0x80, 0x55, 0xA4, 0x01, 0x8D], - 'Kokiri Sword': [0x3B, 0x80, 0x74, 0xA4, 0x01, 0x8D], - 'Deku Shield': [0x3E, 0xA0, 0xE3, 0x4C, 0x00, 0xCB], - 'Hylian Shield': [0x3F, 0xA0, 0xD4, 0x4D, 0x00, 0xDC], - 'Mirror Shield': [0x40, 0x80, 0x3A, 0x4E, 0x00, 0xEE], - 'Goron Tunic': [0x42, 0xA0, 0x3C, 0x50, 0x00, 0xF2], - 'Zora Tunic': [0x43, 0xA0, 0x3D, 0x51, 0x00, 0xF2], - 'Iron Boots': [0x45, 0x80, 0x47, 0x53, 0x01, 0x18], - 'Hover Boots': [0x46, 0x80, 0x5F, 0x54, 0x01, 0x57], - 'Stone of Agony': [0x6F, 0x80, 0x21, 0x68, 0x00, 0xC8], - 'Piece of Heart': [0x7A, 0x80, 0x14, 0xC2, 0x00, 0xBD], - 'Recovery Heart': [0x83, 0x80, 0x09, 0x55, 0x00, 0xB7], - 'Arrows (5)': [0x92, 0x48, 0xDB, 0xE6, 0x00, 0xD8], - 'Arrows (10)': [0x93, 0x4A, 0xDA, 0xE6, 0x00, 0xD8], - 'Arrows (30)': [0x94, 0x4A, 0xD9, 0xE6, 0x00, 0xD8], - 'Bombs (5)': [0x8E, 0x59, 0xE0, 0x32, 0x00, 0xCE], - 'Bombs (10)': [0x8F, 0x59, 0xE0, 0x32, 0x00, 0xCE], - 'Bombs (20)': [0x90, 0x59, 0xE0, 0x32, 0x00, 0xCE], - 'Bombchus (5)': [0x96, 0x80, 0xD8, 0x33, 0x00, 0xD9], - 'Bombchus (10)': [0x09, 0x80, 0xD8, 0x33, 0x00, 0xD9], - 'Bombchus (20)': [0x97, 0x80, 0xD8, 0x33, 0x00, 0xD9], - 'Deku Nuts (5)': [0x8C, 0x0C, 0xEE, 0x34, 0x00, 0xBB], - 'Deku Nuts (10)': [0x8D, 0x0C, 0xEE, 0x34, 0x00, 0xBB], - 'Rupee (1)': [0x84, 0x00, 0x93, 0x6F, 0x01, 0x7F], - 'Rupees (5)': [0x85, 0x01, 0x92, 0xCC, 0x01, 0x7F], - 'Rupees (20)': [0x86, 0x02, 0x91, 0xF0, 0x01, 0x7F], - 'Rupees (50)': [0x87, 0x14, 0x8F, 0xF1, 0x01, 0x7F], - 'Rupees (200)': [0x88, 0x13, 0x8E, 0xF2, 0x01, 0x7F], - 'Skull Mask': [0x25, 0x80, 0x4F, 0x10, 0x01, 0x36 ], - 'Spooky Mask': [0x26, 0x80, 0x32, 0x11, 0x01, 0x35], - 'Keaton Mask': [0x24, 0x80, 0x31, 0x12, 0x01, 0x34], - 'Bunny Hood': [0x27, 0x80, 0x50, 0x13, 0x01, 0x37], - 'Mask of Truth': [0x2B, 0x80, 0x51, 0x17, 0x01, 0x38], - 'Goron Mask': [0x28, 0x80, 0x5B, 0x14, 0x01, 0x50], - 'Zora Mask': [0x29, 0x80, 0x5C, 0x15, 0x01, 0x51 ], - 'Gerudo Mask': [0x2A, 0x80, 0x5D, 0x16, 0x01, 0x52], - 'Ice Trap': [0x85, 0x01, 0x92, 0xCC, 0x01, 0x7F], # Ice Trap in special spots will become a blue rupee. - 'Zeldas Lullaby': 0xD4, - 'Eponas Song': 0xD2, - 'Suns Song': 0xD3, - 'Sarias Song': 0xD1, - 'Song of Time': 0xD5, - 'Song of Storms': 0xD6, - 'Minuet of Forest': 0x73, - 'Bolero of Fire': 0x74, - 'Serenade of Water': 0x75, - 'Nocturne of Shadow': 0x77, - 'Requiem of Spirit': 0x76, - 'Prelude of Light': 0x78, - 'Kokiri Emerald': [0x04, 0xA5, 0x80, [0x00, 0x04, 0x00, 0x00]], - 'Goron Ruby': [0x08, 0xA5, 0x81, [0x00, 0x08, 0x00, 0x00]], - 'Zora Sapphire': [0x10, 0xA5, 0x82, [0x00, 0x10, 0x00, 0x00]], - 'Forest Medallion': [0x01, 0xA7, 0x3E, [0x00, 0x00, 0x00, 0x01]], - 'Fire Medallion': [0x02, 0xA7, 0x3C, [0x00, 0x00, 0x00, 0x02]], - 'Water Medallion': [0x04, 0xA7, 0x3D, [0x00, 0x00, 0x00, 0x04]], - 'Spirit Medallion': [0x08, 0xA7, 0x3F, [0x00, 0x00, 0x00, 0x08]], - 'Shadow Medallion': [0x10, 0xA7, 0x41, [0x00, 0x00, 0x00, 0x10]], - 'Light Medallion': [0x20, 0xA7, 0x40, [0x00, 0x00, 0x00, 0x20]]} + 'Hammer': [0x11, 0x80, 0x41, 0x38, 0x00, 0xF6], + 'Boomerang': [0x0E, 0x80, 0x34, 0x35, 0x00, 0xE8], + 'Lens of Truth': [0x0F, 0x80, 0x36, 0x39, 0x00, 0xEA], + 'Dins Fire': [0x05, 0x80, 0x64, 0xAD, 0x01, 0x5D], + 'Farores Wind': [0x0D, 0x80, 0x65, 0xAE, 0x01, 0x5D], + 'Nayrus Love': [0x13, 0x80, 0x66, 0xAF, 0x01, 0x5D], + 'Fire Arrows': [0x04, 0x80, 0x60, 0x70, 0x01, 0x58], + 'Ice Arrows': [0x0C, 0x80, 0x61, 0x71, 0x01, 0x58], + 'Light Arrows': [0x12, 0x80, 0x62, 0x72, 0x01, 0x58], + 'Bottle': [0x14, 0x80, 0x01, 0x42, 0x00, 0xC6], + 'Bottle with Letter': [0x1B, 0x80, 0x45, 0x99, 0x01, 0x0B], + 'Bottle with Milk': [0x1A, 0x80, 0x30, 0x98, 0x00, 0xDF], + 'Pocket Egg': [0x2D, 0x80, 0x29, 0x01, 0x00, 0xDA], + 'Pocket Cucco': [0x2E, 0x80, 0x44, 0x0B, 0x01, 0x09], + 'Cojiro': [0x2F, 0x80, 0x5E, 0x02, 0x01, 0x09], + 'Odd Mushroom': [0x30, 0x80, 0x54, 0x03, 0x01, 0x41], + 'Odd Potion': [0x31, 0x80, 0x53, 0x04, 0x01, 0x40], + 'Poachers Saw': [0x32, 0x80, 0x40, 0x05, 0x00, 0xF5], + 'Broken Sword': [0x33, 0x80, 0x56, 0x08, 0x01, 0x43], + 'Prescription': [0x34, 0x80, 0x57, 0x09, 0x01, 0x46], + 'Eyeball Frog': [0x35, 0x80, 0x5A, 0x0D, 0x01, 0x49], + 'Eyedrops': [0x36, 0x80, 0x52, 0x0E, 0x01, 0x3F], + 'Claim Check': [0x37, 0x80, 0x55, 0xA4, 0x01, 0x8D], + 'Kokiri Sword': [0x3B, 0x80, 0x74, 0xA4, 0x01, 0x8D], + 'Deku Shield': [0x3E, 0xA0, 0xE3, 0x4C, 0x00, 0xCB], + 'Hylian Shield': [0x3F, 0xA0, 0xD4, 0x4D, 0x00, 0xDC], + 'Mirror Shield': [0x40, 0x80, 0x3A, 0x4E, 0x00, 0xEE], + 'Goron Tunic': [0x42, 0xA0, 0x3C, 0x50, 0x00, 0xF2], + 'Zora Tunic': [0x43, 0xA0, 0x3D, 0x51, 0x00, 0xF2], + 'Iron Boots': [0x45, 0x80, 0x47, 0x53, 0x01, 0x18], + 'Hover Boots': [0x46, 0x80, 0x5F, 0x54, 0x01, 0x57], + 'Stone of Agony': [0x6F, 0x80, 0x21, 0x68, 0x00, 0xC8], + 'Piece of Heart': [0x7A, 0x80, 0x14, 0xC2, 0x00, 0xBD], + 'Recovery Heart': [0x83, 0x80, 0x09, 0x55, 0x00, 0xB7], + 'Arrows (5)': [0x92, 0x48, 0xDB, 0xE6, 0x00, 0xD8], + 'Arrows (10)': [0x93, 0x4A, 0xDA, 0xE6, 0x00, 0xD8], + 'Arrows (30)': [0x94, 0x4A, 0xD9, 0xE6, 0x00, 0xD8], + 'Bombs (5)': [0x8E, 0x59, 0xE0, 0x32, 0x00, 0xCE], + 'Bombs (10)': [0x8F, 0x59, 0xE0, 0x32, 0x00, 0xCE], + 'Bombs (20)': [0x90, 0x59, 0xE0, 0x32, 0x00, 0xCE], + 'Bombchus (5)': [0x96, 0x80, 0xD8, 0x33, 0x00, 0xD9], + 'Bombchus (10)': [0x09, 0x80, 0xD8, 0x33, 0x00, 0xD9], + 'Bombchus (20)': [0x97, 0x80, 0xD8, 0x33, 0x00, 0xD9], + 'Deku Nuts (5)': [0x8C, 0x0C, 0xEE, 0x34, 0x00, 0xBB], + 'Deku Nuts (10)': [0x8D, 0x0C, 0xEE, 0x34, 0x00, 0xBB], + 'Rupee (1)': [0x84, 0x00, 0x93, 0x6F, 0x01, 0x7F], + 'Rupees (5)': [0x85, 0x01, 0x92, 0xCC, 0x01, 0x7F], + 'Rupees (20)': [0x86, 0x02, 0x91, 0xF0, 0x01, 0x7F], + 'Rupees (50)': [0x87, 0x14, 0x8F, 0xF1, 0x01, 0x7F], + 'Rupees (200)': [0x88, 0x13, 0x8E, 0xF2, 0x01, 0x7F], + 'Skull Mask': [0x25, 0x80, 0x4F, 0x10, 0x01, 0x36 ], + 'Spooky Mask': [0x26, 0x80, 0x32, 0x11, 0x01, 0x35], + 'Keaton Mask': [0x24, 0x80, 0x31, 0x12, 0x01, 0x34], + 'Bunny Hood': [0x27, 0x80, 0x50, 0x13, 0x01, 0x37], + 'Mask of Truth': [0x2B, 0x80, 0x51, 0x17, 0x01, 0x38], + 'Goron Mask': [0x28, 0x80, 0x5B, 0x14, 0x01, 0x50], + 'Zora Mask': [0x29, 0x80, 0x5C, 0x15, 0x01, 0x51 ], + 'Gerudo Mask': [0x2A, 0x80, 0x5D, 0x16, 0x01, 0x52], + 'Ice Trap': [0x85, 0x01, 0x92, 0xCC, 0x01, 0x7F], # Ice Trap in special spots will become a blue rupee. + 'Zeldas Lullaby': 0xD4, + 'Eponas Song': 0xD2, + 'Suns Song': 0xD3, + 'Sarias Song': 0xD1, + 'Song of Time': 0xD5, + 'Song of Storms': 0xD6, + 'Minuet of Forest': 0x73, + 'Bolero of Fire': 0x74, + 'Serenade of Water': 0x75, + 'Nocturne of Shadow': 0x77, + 'Requiem of Spirit': 0x76, + 'Prelude of Light': 0x78, + 'Kokiri Emerald': [0x04, 0xA5, 0x80, [0x00, 0x04, 0x00, 0x00]], + 'Goron Ruby': [0x08, 0xA5, 0x81, [0x00, 0x08, 0x00, 0x00]], + 'Zora Sapphire': [0x10, 0xA5, 0x82, [0x00, 0x10, 0x00, 0x00]], + 'Forest Medallion': [0x01, 0xA7, 0x3E, [0x00, 0x00, 0x00, 0x01]], + 'Fire Medallion': [0x02, 0xA7, 0x3C, [0x00, 0x00, 0x00, 0x02]], + 'Water Medallion': [0x04, 0xA7, 0x3D, [0x00, 0x00, 0x00, 0x04]], + 'Spirit Medallion': [0x08, 0xA7, 0x3F, [0x00, 0x00, 0x00, 0x08]], + 'Shadow Medallion': [0x10, 0xA7, 0x41, [0x00, 0x00, 0x00, 0x10]], + 'Light Medallion': [0x20, 0xA7, 0x40, [0x00, 0x00, 0x00, 0x20]]} diff --git a/MQ.py b/MQ.py new file mode 100644 index 000000000..ffecbf415 --- /dev/null +++ b/MQ.py @@ -0,0 +1,724 @@ +# mzxrules 2018 +# In order to patch MQ to the existing data... +# +# Scenes: +# +# Ice Cavern (Scene 9) needs to have it's header altered to support MQ's path list. This +# expansion will delete the otherwise unused alternate headers command +# +# Transition actors will be patched over the old data, as the number of records is the same +# Path data will be appended to the end of the scene file. +# +# The size of a single path on file is NUM_POINTS * 6, rounded up to the nearest 4 byte boundary +# The total size consumed by the path data is NUM_PATHS * 8, plus the sum of all path file sizes +# padded to the nearest 0x10 bytes +# +# Collision: +# OoT's collision data consists of these elements: vertices, surface types, water boxes, +# camera behavior data, and polys. MQ's vertice and polygon geometry data is identical. +# However, the surface types and the collision exclusion flags bound to the polys have changed +# for some polygons, as well as the number of surface type records and camera type records. +# +# To patch collision, a flag denotes whether collision data cannot be written in place without +# expanding the size of the scene file. If true, the camera data is relocated to the end +# of the scene file, and the surface types are shifted down into where the camera types +# were situated. If false, the camera data isn't moved, but rather the surface type list +# will be shifted to the end of the camera data +# +# Rooms: +# +# Object file initialization data will be appended to the end of the room file. +# The total size consumed by the object file data is NUM_OBJECTS * 0x02, aligned to +# the nearest 0x04 bytes +# +# Actor spawn data will be appended to the end of the room file, after the objects. +# The total size consumed by the actor spawn data is NUM_ACTORS * 0x10 +# +# Finally: +# +# Scene and room files will be padded to the nearest 0x10 bytes +# +# Maps: +# Jabu Jabu's B1 map contains no chests in the vanilla layout. Because of this, +# the floor map data is missing a vertex pointer that would point within kaleido_scope. +# As such, if the file moves, the patch will break. + +from Utils import data_path +from Rom import LocalRom +import json +from struct import pack, unpack + +SCENE_TABLE = 0xB71440 + + +class File(object): + def __init__(self, file): + self.name = file['Name'] + self.start = int(file['Start'], 16) + self.end = int(file['End'], 16) + self.remap = file['RemapStart'] + + # used to update the file's associated dmadata record + self.dma_key = self.start + + if self.remap is not None: + self.remap = int(self.remap, 16) + + def __repr__(self): + remap = "None" + if self.remap is not None: + remap = "{0:x}".format(self.remap) + return "{0}: {1:x} {2:x}, remap {3}".format(self.name, self.start, self.end, remap) + + def relocate(self, rom:LocalRom): + if self.remap is None: + return + + new_start = self.remap + + offset = new_start - self.start + new_end = self.end + offset + + rom.buffer[new_start:new_end] = rom.buffer[self.start:self.end] + self.start = new_start + self.end = new_end + + +class CollisionMesh(object): + def __init__(self, rom:LocalRom, start, offset): + self.offset = offset + self.poly_addr = rom.read_int32(start + offset + 0x18) + self.polytypes_addr = rom.read_int32(start + offset + 0x1C) + self.camera_data_addr = rom.read_int32(start + offset + 0x20) + self.polytypes = (self.poly_addr - self.polytypes_addr) // 8 + + def write_to_scene(self, rom:LocalRom, start): + addr = start + self.offset + 0x18 + rom.write_int32s(addr, [self.poly_addr, self.polytypes_addr, self.camera_data_addr]) + + +class ColDelta(object): + def __init__(self, delta): + self.is_larger = delta['IsLarger'] + self.polys = delta['Polys'] + self.polytypes = delta['PolyTypes'] + self.cams = delta['Cams'] + + +class Icon(object): + def __init__(self, data): + self.icon = data["Icon"]; + self.count = data["Count"]; + self.points = [IconPoint(x) for x in data["IconPoints"]] + + def write_to_minimap(self, rom:LocalRom, addr): + rom.write_sbyte(addr, self.icon) + rom.write_byte(addr + 1, self.count) + cur = 2 + for p in self.points: + p.write_to_minimap(rom, addr + cur) + cur += 0x03 + + def write_to_floormap(self, rom:LocalRom, addr): + rom.write_int16(addr, self.icon) + rom.write_int32(addr + 0x10, self.count) + + cur = 0x14 + for p in self.points: + p.write_to_floormap(rom, addr + cur) + cur += 0x0C + + +class IconPoint(object): + def __init__(self, point): + self.flag = point["Flag"] + self.x = point["x"] + self.y = point["y"] + + def write_to_minimap(self, rom:LocalRom, addr): + rom.write_sbyte(addr, self.flag) + rom.write_byte(addr+1, self.x) + rom.write_byte(addr+2, self.y) + + def write_to_floormap(self, rom:LocalRom, addr): + rom.write_int16(addr, self.flag) + rom.write_f32(addr + 4, float(self.x)) + rom.write_f32(addr + 8, float(self.y)) + + +class Scene(object): + def __init__(self, scene): + self.file = File(scene['File']) + self.id = scene['Id'] + self.transition_actors = [convert_actor_data(x) for x in scene['TActors']] + self.rooms = [Room(x) for x in scene['Rooms']] + self.paths = [] + self.coldelta = ColDelta(scene["ColDelta"]) + self.minimaps = [[Icon(icon) for icon in minimap['Icons']] for minimap in scene['Minimaps']] + self.floormaps = [[Icon(icon) for icon in floormap['Icons']] for floormap in scene['Floormaps']] + temp_paths = scene['Paths'] + for item in temp_paths: + self.paths.append(item['Points']) + + + def write_data(self, rom:LocalRom): + + # write floormap and minimap data + self.write_map_data(rom) + + # move file to remap address + self.file.relocate(rom) + + start = self.file.start + headcur = self.file.start + + room_list_offset = 0 + + code = rom.read_byte(headcur) + loop = 0x20 + while loop > 0 and code != 0x14: #terminator + loop -= 1 + + if code == 0x03: #collision + col_mesh_offset = rom.read_int24(headcur + 5) + col_mesh = CollisionMesh(rom, start, col_mesh_offset) + self.patch_mesh(rom, col_mesh); + + elif code == 0x04: #rooms + room_list_offset = rom.read_int24(headcur + 5) + + elif code == 0x0D: #paths + path_offset = self.append_path_data(rom) + rom.write_int32(headcur + 4, path_offset) + + elif code == 0x0E: #transition actors + t_offset = rom.read_int24(headcur + 5) + addr = self.file.start + t_offset + write_actor_data(rom, addr, self.transition_actors) + + headcur += 8 + code = rom.read_byte(headcur) + + # update file references + self.file.end = align16(self.file.end) + update_dmadata(rom, self.file) + update_scene_table(rom, self.id, self.file.start, self.file.end) + + # write room file data + for room in self.rooms: + room.write_data(rom) + if self.id == 6 and room.id == 6: + patch_spirit_temple_mq_room_6(rom, room.file.start) + + cur = self.file.start + room_list_offset + for room in self.rooms: + rom.write_int32s(cur, [room.file.start, room.file.end]) + cur += 0x08 + + + def write_map_data(self, rom:LocalRom): + if self.id >= 10: + return + + # write floormap + floormap_indices = 0xB6C934 + floormap_vrom = 0xBC7E00 + floormap_index = rom.read_int16(floormap_indices + (self.id * 2)) + floormap_index //= 2 # game uses texture index, where two textures are used per floor + + cur = floormap_vrom + (floormap_index * 0x1EC) + for floormap in self.floormaps: + for icon in floormap: + Icon.write_to_floormap(icon, rom, cur) + cur += 0xA4 + + + # fixes jabu jabu floor B1 having no chest data + if self.id == 2: + cur = floormap_vrom + (0x08 * 0x1EC + 4) + kaleido_scope_chest_verts = 0x803A3DA0 # hax, should be vram 0x8082EA00 + rom.write_int32s(cur, [0x17, kaleido_scope_chest_verts, 0x04]) + + # write minimaps + map_mark_vrom = 0xBF40D0 + map_mark_vram = 0x808567F0 + map_mark_array_vram = 0x8085D2DC # ptr array in map_mark_data to minimap "marks" + + array_vrom = map_mark_array_vram - map_mark_vram + map_mark_vrom + map_mark_scene_vram = rom.read_int32(self.id * 4 + array_vrom) + mark_vrom = map_mark_scene_vram - map_mark_vram + map_mark_vrom + + cur = mark_vrom + for minimap in self.minimaps: + for icon in minimap: + Icon.write_to_minimap(icon, rom, cur) + cur += 0x26 + + + def patch_mesh(self, rom:LocalRom, mesh:CollisionMesh): + start = self.file.start + + final_cams = [] + + # build final camera data + for cam in self.coldelta.cams: + data = cam['Data'] + pos = cam['PositionIndex'] + if pos < 0: + final_cams.append((data, 0)) + else: + addr = start + (mesh.camera_data_addr & 0xFFFFFF) + seg_off = rom.read_int32(addr + (pos * 8) + 4) + final_cams.append((data, seg_off)) + + types_move_addr = 0 + + # if data can't fit within the old mesh space, append camera data + if self.coldelta.is_larger: + types_move_addr = mesh.camera_data_addr + + # append to end of file + self.write_cam_data(rom, self.file.end, final_cams) + mesh.camera_data_addr = get_segment_address(2, self.file.end - self.file.start) + self.file.end += len(final_cams) * 8 + + else: + types_move_addr = mesh.camera_data_addr + (len(final_cams) * 8) + + # append in place + addr = self.file.start + (mesh.camera_data_addr & 0xFFFFFF) + self.write_cam_data(rom, addr, final_cams) + + # if polytypes needs to be moved, do so + if (types_move_addr != mesh.polytypes_addr): + a_start = self.file.start + (mesh.polytypes_addr & 0xFFFFFF) + b_start = self.file.start + (types_move_addr & 0xFFFFFF) + size = mesh.polytypes * 8 + + rom.buffer[b_start:b_start + size] = rom.buffer[a_start:a_start + size] + mesh.polytypes_addr = types_move_addr + + # patch polytypes + for item in self.coldelta.polytypes: + id = item['Id'] + high = item['High'] + low = item['Low'] + addr = self.file.start + (mesh.polytypes_addr & 0xFFFFFF) + (id * 8) + rom.write_int32s(addr, [high, low]) + + # patch poly data + for item in self.coldelta.polys: + id = item['Id'] + t = item['Type'] + flags = item['Flags'] + + addr = self.file.start + (mesh.poly_addr & 0xFFFFFF) + (id * 0x10) + vert_bit = rom.read_byte(addr + 0x02) & 0x1F # VertexA id data + rom.write_int16(addr, t) + rom.write_byte(addr + 0x02, (flags << 5) + vert_bit) + + # Write Mesh to Scene + mesh.write_to_scene(rom, self.file.start) + + + def write_cam_data(self, rom:LocalRom, addr, cam_data): + + for item in cam_data: + data, pos = item + rom.write_int32s(addr, [data, pos]) + addr += 8 + + + # appends path data to the end of the rom + # returns segment address to path data + def append_path_data(self, rom:LocalRom): + start = self.file.start + cur = self.file.end + records = [] + + for path in self.paths: + nodes = len(path) + offset = get_segment_address(2, cur - start) + records.append((nodes, offset)) + + #flatten + points = [x for points in path for x in points] + rom.write_int16s(cur, points) + path_size = align4(len(path) * 6) + cur += path_size + + records_offset = get_segment_address(2, cur - start) + for node, offset in records: + rom.write_byte(cur, node) + rom.write_int32(cur + 4, offset) + cur += 8 + + self.file.end = cur + return records_offset + + +class Room(object): + def __init__(self, room): + self.file = File(room['File']) + self.id = room['Id'] + self.objects = [int(x, 16) for x in room['Objects']] + self.actors = [convert_actor_data(x) for x in room['Actors']] + + def write_data(self, rom:LocalRom): + + # move file to remap address + self.file.relocate(rom) + + headcur = self.file.start + + code = rom.read_byte(headcur) + loop = 0x20 + while loop != 0 and code != 0x14: #terminator + loop -= 1 + + if code == 0x01: # actors + offset = self.file.end - self.file.start + write_actor_data(rom, self.file.end, self.actors) + self.file.end += len(self.actors) * 0x10 + + rom.write_byte(headcur + 1, len(self.actors)) + rom.write_int32(headcur + 4, get_segment_address(3, offset)) + + elif code == 0x0B: # objects + offset = self.append_object_data(rom, self.objects) + + rom.write_byte(headcur + 1, len(self.objects)) + rom.write_int32(headcur + 4, get_segment_address(3, offset)) + + headcur += 8 + code = rom.read_byte(headcur) + + # update file reference + self.file.end = align16(self.file.end) + update_dmadata(rom, self.file) + + + def append_object_data(self, rom:LocalRom, objects): + offset = self.file.end - self.file.start + cur = self.file.end + rom.write_int16s(cur, objects) + + objects_size = align4(len(objects) * 2) + self.file.end += objects_size + return offset + + +def patch_files(rom:LocalRom, mq_scenes:list): + + data = get_json() + scenes = [Scene(x) for x in data] + for scene in scenes: + if scene.id in mq_scenes: + if scene.id == 9: + patch_ice_cavern_scene_header(rom) + scene.write_data(rom) + + + +def get_json(): + with open(data_path('mqu.json'), 'r') as stream: + data = json.load(stream) + return data + + +def convert_actor_data(str): + spawn_args = str.split(" ") + return [ int(x,16) for x in spawn_args ] + + +def get_segment_address(base, offset): + offset &= 0xFFFFFF + base *= 0x01000000 + return base + offset + + +def patch_ice_cavern_scene_header(rom): + rom.buffer[0x2BEB000:0x2BEB038] = rom.buffer[0x2BEB008:0x2BEB040] + rom.write_int32s(0x2BEB038, [0x0D000000, 0x02000000]) + + +def patch_spirit_temple_mq_room_6(rom:LocalRom, room_addr): + cur = room_addr + + actor_list_addr = 0 + cmd_actors_offset = 0 + + # scan for actor list and header end + code = rom.read_byte(cur) + while code != 0x14: #terminator + if code == 0x01: # actors + actor_list_addr = rom.read_int32(cur + 4) + cmd_actors_offset = cur - room_addr + + cur += 8 + code = rom.read_byte(cur) + + cur += 8 + + # original header size + header_size = cur - room_addr + + # set alternate header data location + alt_data_off = header_size + 8 + + # set new alternate header offset + alt_header_off = align16(alt_data_off + (4 * 3)) # alt header record size * num records + + # write alternate header data + # the first 3 words are mandatory. the last 3 are just to make the binary + # cleaner to read + rom.write_int32s(room_addr + alt_data_off, + [0, get_segment_address(3, alt_header_off), 0, 0, 0, 0]) + + # clone header + a_start = room_addr + a_end = a_start + header_size + b_start = room_addr + alt_header_off + b_end = b_start + header_size + + rom.buffer[b_start:b_end] = rom.buffer[a_start:a_end] + + # make the child header skip the first actor, + # which avoids the spawning of the block while in the hole + cmd_addr = room_addr + cmd_actors_offset + actor_list_addr += 0x10 + actors = rom.read_byte(cmd_addr + 1) + rom.write_byte(cmd_addr+1, actors - 1) + rom.write_int32(cmd_addr + 4, actor_list_addr) + + # move header + rom.buffer[a_start + 8:a_end + 8] = rom.buffer[a_start:a_end] + + # write alternate header command + seg = get_segment_address(3, alt_data_off) + rom.write_int32s(room_addr, [0x18000000, seg]) + + +def verify_remap(scenes): + def test_remap(file:File): + if file.remap is not None: + if file.start < file.remap: + return False + return True + print("test code: verify remap won't corrupt data") + + for scene in scenes: + file = scene.file + result = test_remap(file) + print("{0} - {1}".format(result, file)) + + for room in scene.rooms: + file = room.file + result = test_remap(file) + print("{0} - {1}".format(result, file)) + + +def update_dmadata(rom:LocalRom, file:File): + key, start, end = file.dma_key, file.start, file.end + rom.update_dmadata_record(key, start, end) + +def update_scene_table(rom:LocalRom, sceneId, start, end): + cur = sceneId * 0x14 + SCENE_TABLE + rom.write_int32s(cur, [start, end]) + + +def write_actor_data(rom:LocalRom, cur, actors): + for actor in actors: + rom.write_int16s(cur, actor) + cur += 0x10 + +def align4(value): + return ((value + 3) // 4) * 4 + +def align16(value): + return ((value + 0xF) // 0x10) * 0x10 + +# This function inserts space in a ovl section at the section's offset +# The section size is expanded +# Every relocation entry in the section after the offet is moved accordingly +# Every relocation value that is after the inserted space is increased accordingly +def insert_space(rom, file, vram_start, insert_section, insert_offset, insert_size): + sections = [] + val_hi = {} + adr_hi = {} + + # get the ovl header + cur = file.end - rom.read_int32(file.end - 4) + section_total = 0 + for i in range(0, 4): + # build the section offsets + section_size = rom.read_int32(cur) + sections.append(section_total) + section_total += section_size + + # increase the section to be expanded + if insert_section == i: + rom.write_int32(cur, section_size + insert_size) + + cur += 4 + + # calculate the insert address in vram + insert_vram = sections[insert_section] + insert_offset + vram_start + insert_rom = sections[insert_section] + insert_offset + file.start + + # iterate over the relocation table + relocate_count = rom.read_int32(cur) + cur += 4 + for i in range(0, relocate_count): + entry = rom.read_int32(cur) + + # parse relocation entry + section = ((entry & 0xC0000000) >> 30) - 1 + type = (entry & 0x3F000000) >> 24 + offset = entry & 0x00FFFFFF + + # calculate relocation address in rom + address = file.start + sections[section] + offset + + # move relocation if section is increased and it's after the insert + if insert_section == section and offset >= insert_offset: + # rebuild new relocation entry + rom.write_int32(cur, + ((section + 1) << 30) | + (type << 24) | + (offset + insert_size)) + + # value contains the vram address + value = rom.read_int32(address) + raw_value = value + if type == 2: + # Data entry: value is the raw vram address + pass + elif type == 4: + # Jump OP: Get the address from a Jump instruction + value = 0x80000000 | (value & 0x03FFFFFF) << 2 + elif type == 5: + # Load High: Upper half of an address load + reg = (value >> 16) & 0x1F + val_hi[reg] = (value & 0x0000FFFF) << 16 + adr_hi[reg] = address + # Do not process, wait until the lower half is read + value = None + elif type == 6: + # Load Low: Lower half of the address load + reg = (value >> 21) & 0x1F + val_low = value & 0x0000FFFF + val_low = unpack('h', pack('H', val_low))[0] + # combine with previous load high + value = val_hi[reg] + val_low + else: + # unknown. OoT does not use any other types + value = None + + # update the vram values if it's been moved + if value != None and value >= insert_vram: + # value = new vram address + new_value = value + insert_size + + if type == 2: + # Data entry: value is the raw vram address + rom.write_int32(address, new_value) + elif type == 4: + # Jump OP: Set the address in the Jump instruction + op = rom.read_int32(address) & 0xFC000000 + new_value = (new_value & 0x0FFFFFFC) >> 2 + new_value = op | new_value + rom.write_int32(address, new_value) + elif type == 6: + # Load Low: Lower half of the address load + op = rom.read_int32(address) & 0xFFFF0000 + new_val_low = new_value & 0x0000FFFF + rom.write_int32(address, op | new_val_low) + + # Load High: Upper half of an address load + op = rom.read_int32(adr_hi[reg]) & 0xFFFF0000 + new_val_hi = (new_value & 0xFFFF0000) >> 16 + if new_val_low >= 0x8000: + # add 1 if the lower part is negative for borrow + new_val_hi += 1 + rom.write_int32(adr_hi[reg], op | new_val_hi) + + cur += 4 + + # Move rom bytes + rom.buffer[(insert_rom + insert_size):(file.end + insert_size)] = rom.buffer[insert_rom:file.end] + rom.buffer[insert_rom:(insert_rom + insert_size)] = [0] * insert_size + file.end += insert_size + + +def add_relocations(rom, file, addresses): + relocations = [] + sections = [] + header_size = rom.read_int32(file.end - 4) + header = file.end - header_size + cur = header + + # read section sizes and build offsets + section_total = 0 + for i in range(0, 4): + section_size = rom.read_int32(cur) + sections.append(section_total) + section_total += section_size + cur += 4 + + # get all entries in relocation table + relocate_count = rom.read_int32(cur) + cur += 4 + for i in range(0, relocate_count): + relocations.append(rom.read_int32(cur)) + cur += 4 + + # create new enties + for address in addresses: + if isinstance(address, tuple): + # if type provided use it + type, address = address + else: + # Otherwise, try to infer type from value + value = rom.read_int32(address) + op = value >> 26 + type = 2 # default: data + if op == 0x02 or op == 0x03: # j or jal + type = 4 + elif op == 0x0F: # lui + type = 5 + elif op == 0x08: # addi + type = 6 + + # Calculate section and offset + address = address - file.start + section = 0 + for section_start in sections: + if address >= section_start: + section += 1 + else: + break + offset = address - sections[section - 1] + + # generate relocation entry + relocations.append((section << 30) + | (type << 24) + | (offset & 0x00FFFFFF)) + + # Rebuild Relocation Table + cur = header + 0x10 + relocations.sort(key = lambda val: val & 0xC0FFFFFF) + rom.write_int32(cur, len(relocations)) + cur += 4 + for relocation in relocations: + rom.write_int32(cur, relocation) + cur += 4 + + # Add padded 0? + rom.write_int32(cur, 0) + cur += 4 + + # Update Header and File size + new_header_size = (cur + 4) - header + rom.write_int32(cur, new_header_size) + file.end += (new_header_size - header_size) diff --git a/Main.py b/Main.py index f21de0011..decb396dc 100644 --- a/Main.py +++ b/Main.py @@ -6,231 +6,264 @@ import random import subprocess import time +import os, os.path +import sys +import struct -from BaseClasses import World, CollectionState, Item -from Regions import create_regions +from BaseClasses import World, CollectionState, Item, Spoiler from EntranceShuffle import link_entrances -from Rom import patch_rom, LocalRom +from Rom import LocalRom +from Patches import patch_rom +from Regions import create_regions +from Dungeons import create_dungeons from Rules import set_rules -from Dungeons import create_dungeons, fill_dungeons_restrictive from Fill import distribute_items_restrictive from ItemList import generate_itempool -from Utils import output_path +from Hints import buildGossipHints +from Utils import default_output_path, is_bundled, subprocess_args +from version import __version__ +from OcarinaSongs import verify_scarecrow_song_str -__version__ = '2.0.0' +class dummy_window(): + def __init__(self): + pass + def update_status(self, text): + pass + def update_progress(self, val): + pass + +def main(settings, window=dummy_window()): -def main(args, seed=None): start = time.clock() - # initialize the world - world = World(args.bridge, args.open_forest, args.open_door_of_time, not args.nodungeonitems, args.beatableonly, args.hints, args.fast_ganon, [args.kokiricolor, args.goroncolor, args.zoracolor], args.healthSFX) logger = logging.getLogger('') - if seed is None: - random.seed(None) - world.seed = random.randint(0, 999999999) - else: - world.seed = int(seed) - random.seed(world.seed) - if args.create_spoiler: # Make game different if spoiler log is generated. - for i in range (0, 10): # Generate many random numbers to increase volatility. - new_base_seed = random.randint(0, 999999999) - random.seed(new_base_seed) - - logger.info('OoT Randomizer Version %s - Seed: %s\n\n', __version__, world.seed) - - create_regions(world) - - create_dungeons(world) - - logger.info('Shuffling the World about.') - - link_entrances(world) - - logger.info('Calculating Access Rules.') - - set_rules(world) - - logger.info('Generating Item Pool.') - - generate_itempool(world) - logger.info('Placing Dungeon Items.') + # verify that the settings are valid + if settings.free_scarecrow: + verify_scarecrow_song_str(settings.scarecrow_song, settings.ocarina_songs) - shuffled_locations = None - shuffled_locations = world.get_unfilled_locations() - random.shuffle(shuffled_locations) - fill_dungeons_restrictive(world, shuffled_locations) + # initialize the world + worlds = [] + if settings.compress_rom == 'None': + settings.create_spoiler = True + settings.update() + + if not settings.world_count: + settings.world_count = 1 + if settings.world_count < 1 or settings.world_count > 31: + raise Exception('World Count must be between 1 and 31') + if settings.player_num > settings.world_count or settings.player_num < 1: + raise Exception('Player Num must be between 1 and %d' % settings.world_count) + + for i in range(0, settings.world_count): + worlds.append(World(settings)) + + random.seed(worlds[0].numeric_seed) + + logger.info('OoT Randomizer Version %s - Seed: %s\n\n', __version__, worlds[0].seed) + + # we load the rom before creating the seed so that error get caught early + if settings.compress_rom != 'None': + window.update_status('Loading ROM') + rom = LocalRom(settings) + + window.update_status('Creating the Worlds') + for id, world in enumerate(worlds): + world.id = id + logger.info('Generating World %d.' % id) + + world.spoiler = Spoiler(worlds) + + window.update_progress(0 + (((id + 1) / settings.world_count) * 1)) + logger.info('Creating Overworld') + if world.quest == 'master': + for dungeon in world.dungeon_mq: + world.dungeon_mq[dungeon] = True + elif world.quest == 'mixed': + for dungeon in world.dungeon_mq: + world.dungeon_mq[dungeon] = random.choice([True, False]) + else: + for dungeon in world.dungeon_mq: + world.dungeon_mq[dungeon] = False + create_regions(world) + + window.update_progress(0 + (((id + 1) / settings.world_count) * 2)) + logger.info('Creating Dungeons') + create_dungeons(world) + + window.update_progress(0 + (((id + 1) / settings.world_count) * 3)) + logger.info('Linking Entrances') + link_entrances(world) + + if settings.shopsanity != 'off': + world.random_shop_prices() + + window.update_progress(0 + (((id + 1) / settings.world_count) * 4)) + logger.info('Calculating Access Rules.') + set_rules(world) + + window.update_progress(0 + (((id + 1) / settings.world_count) * 5)) + logger.info('Generating Item Pool.') + generate_itempool(world) + + window.update_status('Placing the Items') logger.info('Fill the world.') + distribute_items_restrictive(window, worlds) + window.update_progress(35) + + if settings.create_spoiler: + window.update_status('Calculating Spoiler Data') + logger.info('Calculating playthrough.') + create_playthrough(worlds) + window.update_progress(50) + if settings.hints != 'none': + window.update_status('Calculating Hint Data') + CollectionState.update_required_items(worlds) + buildGossipHints(worlds[settings.player_num - 1]) + window.update_progress(55) - distribute_items_restrictive(world) + logger.info('Patching ROM.') - logger.info('Calculating playthrough.') + if settings.world_count > 1: + outfilebase = 'OoT_%s_%s_W%dP%d' % (worlds[0].settings_string, worlds[0].seed, worlds[0].world_count, worlds[0].player_num) + else: + outfilebase = 'OoT_%s_%s' % (worlds[0].settings_string, worlds[0].seed) - create_playthrough(world) + output_dir = default_output_path(settings.output_dir) - logger.info('Patching ROM.') + if settings.compress_rom != 'None': + window.update_status('Patching ROM') + patch_rom(worlds[settings.player_num - 1], rom) + window.update_progress(65) - outfilebase = 'OoT_%s%s%s%s%s_%s' % (world.bridge, "-openforest" if world.open_forest else "", "-opendoor" if world.open_door_of_time else "", "-fastganon" if world.fast_ganon else "", "-beatableonly" if world.check_beatable_only else "", world.seed) + rom_path = os.path.join(output_dir, '%s.z64' % outfilebase) - if not args.suppress_rom: - rom = LocalRom(args.rom) - patch_rom(world, rom) - rom.write_to_file(output_path('%s.z64' % outfilebase)) - if args.compress_rom: + window.update_status('Saving Uncompressed ROM') + rom.write_to_file(rom_path) + if settings.compress_rom == 'True': + window.update_status('Compressing ROM') logger.info('Compressing ROM.') + + if is_bundled(): + compressor_path = "." + else: + compressor_path = "Compress" + if platform.system() == 'Windows': - subprocess.call(["Compress\Compress.exe", (output_path('%s.z64' % outfilebase)), (output_path('%s-comp.z64' % outfilebase))]) + if 8 * struct.calcsize("P") == 64: + compressor_path += "\\Compress.exe" + else: + compressor_path += "\\Compress32.exe" elif platform.system() == 'Linux': - subprocess.call(["Compress/Compress", ('%s.z64' % outfilebase)]) + compressor_path += "/Compress" elif platform.system() == 'Darwin': - subprocess.call(["Compress/Compress.out", ('%s.z64' % outfilebase)]) + compressor_path += "/Compress.out" else: + compressor_path = "" logger.info('OS not supported for compression') - if args.create_spoiler: - world.spoiler.to_file(output_path('%s_Spoiler.txt' % outfilebase)) - - logger.info('Done. Enjoy.') - logger.debug('Total Time: %s', time.clock() - start) - - return world - -def copy_world(world): - # ToDo: Not good yet - ret = World(world.bridge, world.open_forest, world.open_door_of_time, world.place_dungeon_items, world.check_beatable_only, world.hints, world.fast_ganon, world.colors, world.healthSFX) - ret.seed = world.seed - ret.can_take_damage = world.can_take_damage - create_regions(ret) - create_dungeons(ret) - - # connect copied world - for region in world.regions: - copied_region = ret.get_region(region.name) - for entrance in region.entrances: - ret.get_entrance(entrance.name).connect(copied_region) + if compressor_path != "": + run_process(window, logger, [compressor_path, rom_path, os.path.join(output_dir, '%s-comp.z64' % outfilebase)]) + os.remove(rom_path) + window.update_progress(95) - # fill locations - for location in world.get_locations(): - if location.item is not None: - item = Item(location.item.name, location.item.advancement, location.item.priority, location.item.type) - ret.get_location(location.name).item = item - item.location = ret.get_location(location.name) - if location.event: - ret.get_location(location.name).event = True - # copy remaining itempool. No item in itempool should have an assigned location - for item in world.itempool: - ret.itempool.append(Item(item.name, item.advancement, item.priority, item.type)) + if settings.create_spoiler: + window.update_status('Creating Spoiler Log') + worlds[settings.player_num - 1].spoiler.to_file(os.path.join(output_dir, '%s_Spoiler.txt' % outfilebase)) - # copy progress items in state - ret.state.prog_items = list(world.state.prog_items) - - set_rules(ret) - - return ret + window.update_progress(100) + window.update_status('Success: Rom patched successfully') + logger.info('Done. Enjoy.') + logger.debug('Total Time: %s', time.clock() - start) -def create_playthrough(world): + return worlds[settings.player_num - 1] + + +def run_process(window, logger, args): + process = subprocess.Popen(args, **subprocess_args(True)) + filecount = None + while True: + line = process.stdout.readline() + if line != b'': + find_index = line.find(b'files remaining') + if find_index > -1: + files = int(line[:find_index].strip()) + if filecount == None: + filecount = files + window.update_progress(65 + ((1 - (files / filecount)) * 30)) + logger.info(line.decode('utf-8').strip('\n')) + else: + break + + +def create_playthrough(worlds): + if worlds[0].check_beatable_only and not CollectionState.can_beat_game([world.state for world in worlds]): + raise RuntimeError('Uncopied is broken too.') # create a copy as we will modify it - old_world = world - world = copy_world(world) + old_worlds = worlds + worlds = [world.copy() for world in worlds] # if we only check for beatable, we can do this sanity check first before writing down spheres - if world.check_beatable_only and not world.can_beat_game(): + if worlds[0].check_beatable_only and not CollectionState.can_beat_game([world.state for world in worlds]): raise RuntimeError('Cannot beat game. Something went terribly wrong here!') - # get locations containing progress items - prog_locations = [location for location in world.get_filled_locations() if location.item.advancement] - state_cache = [None] - collection_spheres = [] - state = CollectionState(world) - sphere_candidates = list(prog_locations) - logging.getLogger('').debug('Building up collection spheres.') - while sphere_candidates: - state.sweep_for_events(key_only=True) - - sphere = [] - # build up spheres of collection radius. Everything in each sphere is independent from each other in dependencies and only depends on lower spheres - for location in sphere_candidates: - if state.can_reach(location): - sphere.append(location) + state_list = [world.state for world in worlds] - for location in sphere: - sphere_candidates.remove(location) - state.collect(location.item, True, location) - - collection_spheres.append(sphere) - - state_cache.append(state.copy()) + # Get all item locations in the worlds + required_locations = [] + item_locations = [location for state in state_list for location in state.world.get_filled_locations() if location.item.advancement] - logging.getLogger('').debug('Calculated sphere %i, containing %i of %i progress items.', len(collection_spheres), len(sphere), len(prog_locations)) - if not sphere: - logging.getLogger('').debug('The following items could not be reached: %s', ['%s at %s' % (location.item.name, location.name) for location in sphere_candidates]) - if not world.check_beatable_only: - raise RuntimeError('Not all progression items reachable. Something went terribly wrong here.') - else: - break - - # in the second phase, we cull each sphere such that the game is still beatable, reducing each range of influence to the bare minimum required inside it - for num, sphere in reversed(list(enumerate(collection_spheres))): - to_delete = [] - for location in sphere: - # we remove the item at location and check if game is still beatable - logging.getLogger('').debug('Checking if %s is required to beat the game.', location.item.name) - old_item = location.item - location.item = None - state.remove(old_item) - if world.can_beat_game(state_cache[num]): - to_delete.append(location) - else: - # still required, got to keep it around - location.item = old_item - - # cull entries in spheres for spoiler walkthrough at end - for location in to_delete: - sphere.remove(location) + # in the first phase, we create the generous spheres. Collecting every item in a sphere will + # mean that every item in the next sphere is collectable. Will contain every reachable item + logging.getLogger('').debug('Building up collection spheres.') - # we are now down to just the required progress items in collection_spheres. Unfortunately - # the previous pruning stage could potentially have made certain items dependant on others - # in the same or later sphere (because the location had 2 ways to access but the item originally - # used to access it was deemed not required.) So we need to do one final sphere collection pass - # to build up the correct spheres + # will loop if there is more items opened up in the previous iteration. Always run once + reachable_items_locations = True + while reachable_items_locations: + # get reachable new items locations + reachable_items_locations = [location for location in item_locations if location.name not in state_list[location.world.id].collected_locations and state_list[location.world.id].can_reach(location)] + for location in reachable_items_locations: + # Mark the location collected in the state world it exists in + state_list[location.world.id].collected_locations[location.name] = True + # Collect the item for the state world it is for + state_list[location.item.world.id].collect(location.item) + required_locations.append(location) + + # in the second phase, we cull each sphere such that the game is still beatable, reducing each + # range of influence to the bare minimum required inside it. Effectively creates a min play + for location in reversed(required_locations): + # we remove the item at location and check if game is still beatable + logging.getLogger('').debug('Checking if %s is required to beat the game.', location.item.name) + old_item = location.item + + # Uncollect the item location. Removing it from the collected_locations + # will ensure that can_beat_game will try to collect it if it can. + # Because we search in reverse sphere order, all the later spheres will + # have their locations flagged to be re-searched. + location.item = None + state_list[old_item.world.id].remove(old_item) + del state_list[location.world.id].collected_locations[location.name] + + # remove the item from the world and test if the game is still beatable + if CollectionState.can_beat_game(state_list): + # cull entries for spoiler walkthrough at end + required_locations.remove(location) + else: + # still required, got to keep it around + location.item = old_item - required_locations = [item for sphere in collection_spheres for item in sphere] - state = CollectionState(world) + # This ensures the playthrough shows items being collected in the proper order. collection_spheres = [] while required_locations: - state.sweep_for_events(key_only=True) - - sphere = list(filter(state.can_reach, required_locations)) - + sphere = [location for location in required_locations if state_list[location.world.id].can_reach(location)] for location in sphere: required_locations.remove(location) - state.collect(location.item, True, location) - + state_list[location.item.world.id].collect(location.item) collection_spheres.append(sphere) - logging.getLogger('').debug('Calculated final sphere %i, containing %i of %i progress items.', len(collection_spheres), len(sphere), len(required_locations)) - if not sphere: - raise RuntimeError('Not all required items reachable. Something went terribly wrong here.') - - # store the required locations for statistical analysis - old_world.required_locations = [location.name for sphere in collection_spheres for location in sphere] - - def flist_to_iter(node): - while node: - value, node = node - yield value - - def get_path(state, region): - reversed_path_as_flist = state.path.get(region, (region, None)) - string_path_flat = reversed(list(map(str, flist_to_iter(reversed_path_as_flist)))) - # Now we combine the flat string list into (region, exit) pairs - pathsiter = iter(string_path_flat) - pathpairs = zip_longest(pathsiter, pathsiter) - return list(pathpairs) - - old_world.spoiler.paths = {location.name : get_path(state, location.parent_region) for sphere in collection_spheres for location in sphere} - # we can finally output our playthrough - old_world.spoiler.playthrough = OrderedDict([(str(i + 1), {str(location): str(location.item) for location in sphere}) for i, sphere in enumerate(collection_spheres)]) + for world in old_worlds: + world.spoiler.playthrough = OrderedDict([(str(i + 1), {location: location.item for location in sphere}) for i, sphere in enumerate(collection_spheres)]) + diff --git a/Messages.py b/Messages.py new file mode 100644 index 000000000..d05686ac0 --- /dev/null +++ b/Messages.py @@ -0,0 +1,796 @@ +# text details: https://wiki.cloudmodding.com/oot/Text_Format + +import random + +TABLE_START = 0xB849EC +TEXT_START = 0x92D000 + +TABLE_SIZE_LIMIT = 0x43A8 +TEXT_SIZE_LIMIT = 0x38130 + +# name of type, followed by number of additional bytes to read, follwed by a function that prints the code +CONTROL_CODES = { + 0x00: ('pad', 0, lambda _: '' ), + 0x01: ('line-break', 0, lambda _: '\n' ), + 0x02: ('end', 0, lambda _: '' ), + 0x04: ('box-break', 0, lambda _: '\nâ–¼\n' ), + 0x05: ('color', 1, lambda d: '' ), + 0x06: ('gap', 1, lambda d: '<' + str(d) + 'px gap>' ), + 0x07: ('goto', 2, lambda d: '' ), + 0x08: ('instant', 0, lambda _: '' ), + 0x09: ('un-instant', 0, lambda _: '' ), + 0x0A: ('keep-open', 0, lambda _: '' ), + 0x0B: ('event', 0, lambda _: '' ), + 0x0C: ('box-break-delay', 1, lambda d: '\nâ–¼\n' ), + 0x0E: ('fade-out', 1, lambda d: '' ), + 0x0F: ('name', 0, lambda _: '' ), + 0x10: ('ocarina', 0, lambda _: '' ), + 0x12: ('sound', 2, lambda d: '' ), + 0x13: ('icon', 1, lambda d: '' ), + 0x14: ('speed', 1, lambda d: '' ), + 0x15: ('background', 3, lambda d: '' ), + 0x16: ('marathon', 0, lambda _: '' ), + 0x17: ('race', 0, lambda _: '' ), + 0x18: ('points', 0, lambda _: '' ), + 0x19: ('skulltula', 0, lambda _: '' ), + 0x1A: ('unskippable', 0, lambda _: '' ), + 0x1B: ('two-choice', 0, lambda _: '' ), + 0x1C: ('three-choice', 0, lambda _: '' ), + 0x1D: ('fish', 0, lambda _: '' ), + 0x1E: ('high-score', 1, lambda d: '' ), + 0x1F: ('time', 0, lambda _: '' ), +} + +SPECIAL_CHARACTERS = { + 0x96: 'é', + 0x9F: '[A]', + 0xA0: '[B]', + 0xA1: '[C]', + 0xA2: '[L]', + 0xA3: '[R]', + 0xA4: '[Z]', + 0xA5: '[C Up]', + 0xA6: '[C Down]', + 0xA7: '[C Left]', + 0xA8: '[C Right]', + 0xA9: '[Triangle]', + 0xAA: '[Control Stick]', +} + +GOSSIP_STONE_MESSAGES = list( range(0x0401, 0x0421) ) # ids of the actual hints +GOSSIP_STONE_MESSAGES += [0x2053, 0x2054] # shared initial stone messages +TEMPLE_HINTS_MESSAGES = [0x7057, 0x707A] # dungeon reward hints from the temple of time pedestal +LIGHT_ARROW_HINT = [0x70CC] # ganondorf's light arrow hint line +GS_TOKEN_MESSAGES = [0x00B4, 0x00B5] # Get Gold Skulltula Token messages + +# messages for shorter item messages +ITEM_MESSAGES = { + 0x0001: "\x08\x13\x2DYou borrowed a \x05\x41Pocket Egg\x05\x40!\x01A Pocket Cucco will hatch from\x01it overnight. Be sure to give it\x01back when you are done with it.", + 0x0002: "\x08\x13\x2FYou returned the Pocket Cucco\x01and got \x05\x41Cojiro\x05\x40 in return!\x01Unlike other Cuccos, Cojiro\x01rarely crows.", + 0x0003: "\x08\x13\x30You got an \x05\x41Odd Mushroom\x05\x40!\x01A fresh mushroom like this is\x01sure to spoil quickly! Take it to\x01the Kakariko Potion Shop, quickly!", + 0x0004: "\x08\x13\x31You received an \x05\x41Odd Potion\x05\x40!\x01It may be useful for something...\x01Hurry to the Lost Woods!", + 0x0005: "\x08\x13\x32You returned the Odd Potion \x01and got the \x05\x41Poacher's Saw\x05\x40!\x01The young punk guy must have\x01left this behind.", + 0x0007: "\x08\x13\x48You got a \x01\x05\x41Deku Seeds Bullet Bag\x05\x40.\x01This bag can hold up to \x05\x4640\x05\x40\x01slingshot bullets.", + 0x0008: "\x08\x13\x33You traded the Poacher's Saw \x01for a \x05\x41Broken Goron's Sword\x05\x40!\x01Visit Biggoron to get it repaired!", + 0x0009: "\x08\x13\x34You checked in the Broken \x01Goron's Sword and received a \x01\x05\x41Prescription\x05\x40!\x01Go see King Zora!", + 0x000A: "\x08\x13\x37The Biggoron's Sword...\x01You got a \x05\x41Claim Check \x05\x40for it!\x01You can't wait for the sword\x01to be completed!", + 0x000B: "\x08\x13\x2EYou got a \x05\x41Pocket Cucco, \x05\x40one\x01of Anju's prized hens! It fits \x01in your pocket.", + 0x000C: "\x08\x13\x3DYou handed in the Claim Check\x01and got the \x05\x41Biggoron's Sword\x05\x40!\x01This blade was forged by a \x01master smith and won't break!", + 0x000D: "\x08\x13\x35You used the Prescription and\x01received an \x05\x41Eyeball Frog\x05\x40!\x01Be quick and deliver it to Lake \x01Hylia while it's cold!", + 0x000E: "\x08\x13\x36You traded the Eyeball Frog \x01for the \x05\x41World's Finest Eye Drops\x05\x40!\x01Hurry! Take them to Biggoron\x01before they go bad!", + 0x0010: "\x08\x13\x25You borrowed a \x05\x41Skull Mask\x05\x40.\x01You feel like a monster while you\x01wear this mask!", + 0x0011: "\x08\x13\x26You borrowed a \x05\x41Spooky Mask\x05\x40.\x01You can scare many people\x01with this mask!", + 0x0012: "\x08\x13\x24You borrowed a \x05\x41Keaton Mask\x05\x40.\x01You'll be a popular guy with\x01this mask on!", + 0x0013: "\x08\x13\x27You borrowed a \x05\x41Bunny Hood\x05\x40.\x01The hood's long ears are so\x01cute!", + 0x0014: "\x08\x13\x28You borrowed a \x05\x41Goron Mask\x05\x40.\x01It will make your head look\x01big, though.", + 0x0015: "\x08\x13\x29You borrowed a \x05\x41Zora Mask\x05\x40.\x01With this mask, you can\x01become one of the Zoras!", + 0x0016: "\x08\x13\x2AYou borrowed a \x05\x41Gerudo Mask\x05\x40.\x01This mask will make you look\x01like...a girl?", + 0x0017: "\x08\x13\x2BYou borrowed a \x05\x41Mask of Truth\x05\x40.\x01Show it to many people!", + 0x0030: "\x08\x13\x06You found the \x05\x41Fairy Slingshot\x05\x40!", + 0x0031: "\x08\x13\x03You found the \x05\x41Fairy Bow\x05\x40!", + 0x0032: "\x08\x13\x02You got \x05\x41Bombs\x05\x40!\x01If you see something\x01suspicious, bomb it!", + 0x0033: "\x08\x13\x09You got \x05\x41Bombchus\x05\x40!", + 0x0034: "\x08\x13\x01You got a \x05\x41Deku Nut\x05\x40!", + 0x0035: "\x08\x13\x0EYou found the \x05\x41Boomerang\x05\x40!", + 0x0036: "\x08\x13\x0AYou found the \x05\x41Hookshot\x05\x40!\x01It's a spring-loaded chain that\x01you can cast out to hook things.", + 0x0037: "\x08\x13\x00You got a \x05\x41Deku Stick\x05\x40!", + 0x0038: "\x08\x13\x11You found the \x05\x41Megaton Hammer\x05\x40!\x01It's so heavy, you need to\x01use two hands to swing it!", + 0x0039: "\x08\x13\x0FYou found the \x05\x41Lens of Truth\x05\x40!\x01Mysterious things are hidden\x01everywhere!", + 0x003A: "\x08\x13\x08You found the \x05\x41Ocarina of Time\x05\x40!\x01It glows with a mystical light...", + 0x003C: "\x08\x13\x67You received the \x05\x41Fire\x01Medallion\x05\x40!\x01Darunia awakens as a Sage and\x01adds his power to yours!", + 0x003D: "\x08\x13\x68You received the \x05\x43Water\x01Medallion\x05\x40!\x01Ruto awakens as a Sage and\x01adds her power to yours!", + 0x003E: "\x08\x13\x66You received the \x05\x42Forest\x01Medallion\x05\x40!\x01Saria awakens as a Sage and\x01adds her power to yours!", + 0x003F: "\x08\x13\x69You received the \x05\x46Spirit\x01Medallion\x05\x40!\x01Nabooru awakens as a Sage and\x01adds her power to yours!", + 0x0040: "\x08\x13\x6BYou received the \x05\x44Light\x01Medallion\x05\x40!\x01Rauru the Sage adds his power\x01to yours!", + 0x0041: "\x08\x13\x6AYou received the \x05\x45Shadow\x01Medallion\x05\x40!\x01Impa awakens as a Sage and\x01adds her power to yours!", + 0x0042: "\x08\x13\x14You got an \x05\x41Empty Bottle\x05\x40!\x01You can put something in this\x01bottle.", + 0x0043: "\x08\x13\x15You got a \x05\x41Red Potion\x05\x40!\x01It will restore your health", + 0x0044: "\x08\x13\x16You got a \x05\x42Green Potion\x05\x40!\x01It will restore your magic.", + 0x0045: "\x08\x13\x17You got a \x05\x43Blue Potion\x05\x40!\x01It will recover your health\x01and magic.", + 0x0046: "\x08\x13\x18You caught a \x05\x41Fairy\x05\x40 in a bottle!\x01It will revive you\x01the moment you run out of life \x01energy.", + 0x0047: "\x08\x13\x19You got a \x05\x41Fish\x05\x40!\x01It looks so fresh and\x01delicious!", + 0x0048: "\x08\x13\x10You got a \x05\x41Magic Bean\x05\x40!\x01Find a suitable spot for a garden\x01and plant it.", + 0x004A: "\x08\x13\x07You received the \x05\x41Fairy Ocarina\x05\x40!\x01This is a memento from Saria.", + 0x004B: "\x08\x13\x3DYou got the \x05\x42Giant's Knife\x05\x40!\x01Hold it with both hands to\x01attack! It's so long, you\x01can't use it with a \x05\x44shield\x05\x40.", + 0x004C: "\x08\x13\x3EYou got a \x05\x44Deku Shield\x05\x40!", + 0x004D: "\x08\x13\x3FYou got a \x05\x44Hylian Shield\x05\x40!", + 0x004E: "\x08\x13\x40You found the \x05\x44Mirror Shield\x05\x40!\x01The shield's polished surface can\x01reflect light or energy.", + 0x004F: "\x08\x13\x0BYou found the \x05\x41Longshot\x05\x40!\x01It's an upgraded Hookshot.\x01It extends \x05\x41twice\x05\x40 as far!", + 0x0050: "\x08\x13\x42You got a \x05\x41Goron Tunic\x05\x40!\x01Going to a hot place? No worry!", + 0x0051: "\x08\x13\x43You got a \x05\x43Zora Tunic\x05\x40!\x01Wear it, and you won't drown\x01underwater.", + 0x0052: "\x08You got a \x05\x42Magic Jar\x05\x40!\x01Your Magic Meter is filled!", + 0x0053: "\x08\x13\x45You got the \x05\x41Iron Boots\x05\x40!\x01So heavy, you can't run.\x01So heavy, you can't float.", + 0x0054: "\x08\x13\x46You got the \x05\x41Hover Boots\x05\x40!\x01With these mysterious boots\x01you can hover above the ground.", + 0x0055: "\x08You got a \x05\x45Recovery Heart\x05\x40!\x01Your life energy is recovered!", + 0x0056: "\x08\x13\x4BYou upgraded your quiver to a\x01\x05\x41Big Quiver\x05\x40!\x01Now you can carry more arrows-\x01\x05\x4640 \x05\x40in total!", + 0x0057: "\x08\x13\x4BYou upgraded your quiver to\x01the \x05\x41Biggest Quiver\x05\x40!\x01Now you can carry even more \x01arrows, to a maximum of \x05\x4650\x05\x40!", + 0x0058: "\x08\x13\x4DYou found a \x05\x41Bomb Bag\x05\x40!\x01You found \x05\x4120 Bombs\x05\x40 inside!", + 0x0059: "\x08\x13\x4EYou got a \x05\x41Big Bomb Bag\x05\x40!\x01Now you can carry more \x01Bombs, up to a maximum of \x05\x4630\x05\x40!", + 0x005A: "\x08\x13\x4FYou got the \x01\x05\x41Biggest Bomb Bag\x05\x40!\x01Now, you can carry up to \x01\x05\x4640\x05\x40 Bombs!", + 0x005B: "\x08\x13\x51You found the \x05\x43Silver Gauntlets\x05\x40!\x01You feel the power to lift\x01big things with it!", + 0x005C: "\x08\x13\x52You found the \x05\x43Golden Gauntlets\x05\x40!\x01You can feel even more power\x01coursing through your arms!", + 0x005D: "\x08\x13\x1CYou put a \x05\x44Blue Fire\x05\x40\x01into the bottle!\x01This is a cool flame you can\x01use on red ice.", + 0x005E: "\x08\x13\x56You got an \x05\x43Adult's Wallet\x05\x40!\x01Now you can hold\x01up to \x05\x46200\x05\x40 \x05\x46Rupees\x05\x40.", + 0x005F: "\x08\x13\x57You got a \x05\x43Giant's Wallet\x05\x40!\x01Now you can hold\x01up to \x05\x46500\x05\x40 \x05\x46Rupees\x05\x40.", + 0x0060: "\x08\x13\x77You found a \x05\x41Small Key\x05\x40!\x01This key will open a locked \x01door. You can use it only\x01in this dungeon.", + 0x0066: "\x08\x13\x76You found the \x05\x41Dungeon Map\x05\x40!\x01It's the map to this dungeon.", + 0x0067: "\x08\x13\x75You found the \x05\x41Compass\x05\x40!\x01Now you can see the locations\x01of many hidden things in the\x01dungeon!", + 0x0068: "\x08\x13\x6FYou obtained the \x05\x41Stone of Agony\x05\x40!\x01If you equip a \x05\x44Rumble Pak\x05\x40, it\x01will react to nearby...secrets.", + 0x0069: "\x08\x13\x23You received \x05\x41Zelda's Letter\x05\x40!\x01Wow! This letter has Princess\x01Zelda's autograph!", + 0x006C: "\x08\x13\x49Your \x05\x41Deku Seeds Bullet Bag \x01\x05\x40has become bigger!\x01This bag can hold \x05\x4650\x05\x41 \x05\x40bullets!", + 0x006F: "\x08You got a \x05\x42Green Rupee\x05\x40!\x01That's \x05\x42one Rupee\x05\x40!", + 0x0070: "\x08\x13\x04You got the \x05\x41Fire Arrow\x05\x40!\x01If you hit your target,\x01it will catch fire.", + 0x0071: "\x08\x13\x0CYou got the \x05\x43Ice Arrow\x05\x40!\x01If you hit your target,\x01it will freeze.", + 0x0072: "\x08\x13\x12You got the \x05\x44Light Arrow\x05\x40!\x01The light of justice\x01will smite evil!", + 0x0073: "\x08\x06\x28You have learned the\x01\x06\x2F\x05\x42Minuet of Forest\x05\x40!", + 0x0074: "\x08\x06\x28You have learned the\x01\x06\x37\x05\x41Bolero of Fire\x05\x40!", + 0x0075: "\x08\x06\x28You have learned the\x01\x06\x29\x05\x43Serenade of Water\x05\x40!", + 0x0076: "\x08\x06\x28You have learned the\x01\x06\x2D\x05\x46Requiem of Spirit\x05\x40!", + 0x0077: "\x08\x06\x28You have learned the\x01\x06\x28\x05\x45Nocturne of Shadow\x05\x40!", + 0x0078: "\x08\x06\x28You have learned the\x01\x06\x32\x05\x44Prelude of Light\x05\x40!", + 0x0079: "\x08\x13\x50You got the \x05\x41Goron's Bracelet\x05\x40!\x01Now you can pull up Bomb\x01Flowers.", + 0x007A: "\x08\x13\x1DYou put a \x05\x41Bug \x05\x40in the bottle!\x01This kind of bug prefers to\x01live in small holes in the ground.", + 0x007B: "\x08\x13\x70You obtained the \x05\x41Gerudo's \x01Membership Card\x05\x40!\x01You can get into the Gerudo's\x01training ground in their hideout.", + 0x0080: "\x08\x13\x6CYou got the \x05\x42Kokiri's Emerald\x05\x40!\x01This is the Spiritual Stone of \x01the Forest, now entrusted to \x01you by the Great Deku Tree.", + 0x0081: "\x08\x13\x6DYou obtained the \x05\x41Goron's Ruby\x05\x40!\x01This is the Spiritual Stone of \x01Fire passed down by the Gorons!", + 0x0082: "\x08\x13\x6EYou obtained \x05\x43Zora's Sapphire\x05\x40!\x01This is the Spiritual Stone of\x01Water passed down by the\x01Zoras!", + 0x0090: "\x08\x13\x00Now you can pick up \x01many \x05\x41Deku Sticks\x05\x40!\x01You can carry up to \x05\x4620\x05\x40 of them!", + 0x0091: "\x08\x13\x00You can now pick up \x01even more \x05\x41Deku Sticks\x05\x40!\x01You can carry up to \x05\x4630\x05\x40 of them!", + 0x0097: "\x08\x13\x20You caught a \x05\x41Poe \x05\x40in a bottle!\x01Something good might happen!", + 0x0098: "\x08\x13\x1AYou got \x05\x41Lon Lon Milk\x05\x40!\x01This milk is very nutritious!\x01There are two drinks in it.", + 0x0099: "\x08\x13\x1BYou found \x05\x41Ruto's Letter\x05\x40 in a\x01bottle! Show it to King Zora.", + 0x009A: "\x08\x13\x21You got a \x05\x41Weird Egg\x05\x40!\x01Feels like there's something\x01moving inside!", + 0x00A4: "\x08\x13\x3BYou got the \x05\x42Kokiri Sword\x05\x40!\x01This is a hidden treasure of\x01the Kokiri.", + 0x00A7: "\x08\x13\x01Now you can carry\x01many \x05\x41Deku Nuts\x05\x40!\x01You can hold up to \x05\x4630\x05\x40 nuts!", + 0x00A8: "\x08\x13\x01You can now carry even\x01more \x05\x41Deku Nuts\x05\x40! You can carry\x01up to \x05\x4640\x05\x41 \x05\x40nuts!", + 0x00AD: "\x08\x13\x05You got \x05\x41Din's Fire\x05\x40!\x01Its fireball engulfs everything!", + 0x00AE: "\x08\x13\x0DYou got \x05\x42Farore's Wind\x05\x40!\x01This is warp magic you can use!", + 0x00AF: "\x08\x13\x13You got \x05\x43Nayru's Love\x05\x40!\x01Cast this to create a powerful\x01protective barrier.", + 0x00B4: "\x08You destroyed a \x05\x41Gold Skulltula\x05\x40.\x01You got a token proving you \x01destroyed it!", + 0x00B5: "\x08You destroyed a \x05\x41Gold Skulltula\x05\x40.\x01You got a token proving you \x01destroyed it!", #Unused + 0x00C2: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01Collect four pieces total to get\x01another Heart Container.", + 0x00C3: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01So far, you've collected two \x01pieces.", + 0x00C4: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01Now you've collected three \x01pieces!", + 0x00C5: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01You've completed another Heart\x01Container!", + 0x00C6: "\x08\x13\x72You got a \x05\x41Heart Container\x05\x40!\x01Your maximum life energy is \x01increased by one heart.", + 0x00C7: "\x08\x13\x74You got the \x05\x41Boss Key\x05\x40!\x01Now you can get inside the \x01chamber where the Boss lurks.", + 0x00CC: "\x08You got a \x05\x43Blue Rupee\x05\x40!\x01That's \x05\x43five Rupees\x05\x40!", + 0x00CD: "\x08\x13\x53You got the \x05\x43Silver Scale\x05\x40!\x01You can dive deeper than you\x01could before.", + 0x00CE: "\x08\x13\x54You got the \x05\x43Golden Scale\x05\x40!\x01Now you can dive much\x01deeper than you could before!", + 0x00D1: "\x08\x06\x14You've learned \x05\x42Saria's Song\x05\x40!", + 0x00D2: "\x08\x06\x11You've learned \x05\x41Epona's Song\x05\x40!", + 0x00D3: "\x08\x06\x0BYou've learned the \x05\x46Sun's Song\x05\x40!", + 0x00D4: "\x08\x06\x15You've learned \x05\x43Zelda's Lullaby\x05\x40!", + 0x00D5: "\x08\x06\x05You've learned the \x05\x44Song of Time\x05\x40!", + 0x00D6: "\x08You've learned the \x05\x45Song of Storms\x05\x40!", + 0x00DC: "\x08\x13\x58You got \x05\x41Deku Seeds\x05\x40!\x01Use these as bullets\x01for your Slingshot.", + 0x00DD: "\x08You mastered the secret sword\x01technique of the \x05\x41Spin Attack\x05\x40!", + 0x00E4: "\x08You can now use \x05\x42Magic\x05\x40!", + 0x00E5: "\x08Your \x05\x44defensive power\x05\x40 is enhanced!", + 0x00E6: "\x08You got a \x05\x46bundle of arrows\x05\x40!", + 0x00E8: "\x08Your magic power has been \x01enhanced! Now you have twice\x01as much \x05\x41Magic Power\x05\x40!", + 0x00E9: "\x08Your defensive power has been \x01enhanced! Damage inflicted by \x01enemies will be \x05\x41reduced by half\x05\x40.", + 0x00F0: "\x08You got a \x05\x41Red Rupee\x05\x40!\x01That's \x05\x41twenty Rupees\x05\x40!", + 0x00F1: "\x08You got a \x05\x45Purple Rupee\x05\x40!\x01That's \x05\x45fifty Rupees\x05\x40!", + 0x00F2: "\x08You got a \x05\x46Huge Rupee\x05\x40!\x01This Rupee is worth a whopping\x01\x05\x46two hundred Rupees\x05\x40!", + 0x00F9: "\x08\x13\x1EYou put a \x05\x41Big Poe \x05\x40in a bottle!\x01Let's sell it at the \x05\x41Ghost Shop\x05\x40!\x01Something good might happen!", +} + + +# messages for keysanity item pickup +# ids are in the space freed up by move_shop_item_messages() +KEYSANITY_MESSAGES = { + 0x06: '\x13\x74\x08You got the \x05\x41Boss Key\x05\x40\x01for the \x05\x42Forest Temple\x05\x40!\x09', + 0x1c: '\x13\x74\x08You got the \x05\x41Boss Key\x05\x40\x01for the \x05\x41Fire Temple\x05\x40!\x09', + 0x1d: '\x13\x74\x08You got the \x05\x41Boss Key\x05\x40\x01for the \x05\x43Water Temple\x05\x40!\x09', + 0x1e: '\x13\x74\x08You got the \x05\x41Boss Key\x05\x40\x01for the \x05\x46Spirit Temple\x05\x40!\x09', + 0x2a: '\x13\x74\x08You got the \x05\x41Boss Key\x05\x40\x01for the \x05\x45Shadow Temple\x05\x40!\x09', + 0x61: '\x13\x74\x08You got the \x05\x41Boss Key\x05\x40\x01for \x05\x41Ganon\'s Castle\x05\x40!\x09', + 0x62: '\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x42Deku Tree\x05\x40!\x09', + 0x63: '\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for \x05\x41Dodongo\'s Cavern\x05\x40!\x09', + 0x64: '\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for \x05\x43Jabu Jabu\'s Belly\x05\x40!\x09', + 0x65: '\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x42Forest Temple\x05\x40!\x09', + 0x7c: '\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x41Fire Temple\x05\x40!\x09', + 0x7d: '\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x43Water Temple\x05\x40!\x09', + 0x7e: '\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x46Spirit Temple\x05\x40!\x09', + 0x7f: '\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x45Shadow Temple\x05\x40!\x09', + 0xa2: '\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x45Bottom of the Well\x05\x40!\x09', + 0x87: '\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x44Ice Cavern\x05\x40!\x09', + 0x88: '\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x42Deku Tree\x05\x40!\x09', + 0x89: '\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for \x05\x41Dodongo\'s Cavern\x05\x40!\x09', + 0x8a: '\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for \x05\x43Jabu Jabu\'s Belly\x05\x40!\x09', + 0x8b: '\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x42Forest Temple\x05\x40!\x09', + 0x8c: '\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x41Fire Temple\x05\x40!\x09', + 0x8e: '\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x43Water Temple\x05\x40!\x09', + 0x8f: '\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x46Spirit Temple\x05\x40!\x09', + 0xa3: '\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x45Shadow Temple\x05\x40!\x09', + 0xa5: '\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x45Bottom of the Well\x05\x40!\x09', + 0x92: '\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x44Ice Cavern\x05\x40!\x09', + 0x93: '\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x42Forest Temple\x05\x40!\x09', + 0x94: '\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x41Fire Temple\x05\x40!\x09', + 0x95: '\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x43Water Temple\x05\x40!\x09', + 0xa6: '\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x46Spirit Temple\x05\x40!\x09', + 0xa9: '\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x45Shadow Temple\x05\x40!\x09', + 0x9b: '\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x45Bottom of the Well\x05\x40!\x09', + 0x9f: '\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x46Gerudo Training\x01Grounds\x05\x40!\x09', + 0xa0: '\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x46Gerudo Fortress\x05\x40!\x09', + 0xa1: '\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for \x05\x41Ganon\'s Castle\x05\x40!\x09', +} + + +# messages for song items +SONG_MESSAGES = { + 0x00B0: "\x08\x06\x28You have learned the\x01\x06\x2F\x05\x42Minuet of Forest\x05\x40!", + 0x00B1: "\x08\x06\x28You have learned the\x01\x06\x37\x05\x41Bolero of Fire\x05\x40!", + 0x00B2: "\x08\x06\x28You have learned the\x01\x06\x29\x05\x43Serenade of Water\x05\x40!", + 0x00B3: "\x08\x06\x28You have learned the\x01\x06\x2D\x05\x46Requiem of Spirit\x05\x40!", + 0x00B6: "\x08\x06\x28You have learned the\x01\x06\x28\x05\x45Nocturne of Shadow\x05\x40!", + 0x00B7: "\x08\x06\x28You have learned the\x01\x06\x32\x05\x44Prelude of Light\x05\x40!", + 0x00B8: "\x08\x06\x15You've learned \x05\x43Zelda's Lullaby\x05\x40!", + 0x00B9: "\x08\x06\x11You've learned \x05\x41Epona's Song\x05\x40!", + 0x00BA: "\x08\x06\x14You've learned \x05\x42Saria's Song\x05\x40!", + 0x00BB: "\x08\x06\x0BYou've learned the \x05\x46Sun's Song\x05\x40!", + 0x00BC: "\x08\x06\x05You've learned the \x05\x44Song of Time\x05\x40!", + 0x00BD: "\x08You've learned the \x05\x45Song of Storms\x05\x40!", +} + + +# convert byte array to an integer +def bytes_to_int(bytes, signed=False): + return int.from_bytes(bytes, byteorder='big', signed=signed) + +# convert int to an array of bytes of the given width +def int_to_bytes(num, width, signed=False): + return int.to_bytes(num, width, byteorder='big', signed=signed) + +def display_code_list(codes): + message = "" + for code in codes: + message += str(code) + return message + +# holds a single character or control code of a string +class Text_Code(): + + def display(self): + if self.code in CONTROL_CODES: + return CONTROL_CODES[self.code][2](self.data) + elif self.code in SPECIAL_CHARACTERS: + return SPECIAL_CHARACTERS[self.code] + elif self.code >= 0x7F: + return '?' + else: + return chr(self.code) + + def get_python_string(self): + if self.code in CONTROL_CODES: + ret = '' + subdata = self.data + for _ in range(0, CONTROL_CODES[self.code][1]): + ret = ('\\x%02X' % (subdata & 0xFF)) + ret + subdata = subdata >> 8 + ret = '\\x%02X' % self.code + ret + return ret + elif self.code in SPECIAL_CHARACTERS: + return '\\x%02X' % self.code + elif self.code >= 0x7F: + return '?' + else: + return chr(self.code) + + # writes the code to the given offset, and returns the offset of the next byte + def write(self, rom, offset): + rom.write_byte(TEXT_START + offset, self.code) + + extra_bytes = 0 + if self.code in CONTROL_CODES: + extra_bytes = CONTROL_CODES[self.code][1] + bytes_to_write = int_to_bytes(self.data, extra_bytes) + rom.write_bytes(TEXT_START + offset + 1, bytes_to_write) + + return offset + 1 + extra_bytes + + def __init__(self, code, data): + self.code = code + if code in CONTROL_CODES: + self.type = CONTROL_CODES[code][0] + else: + self.type = 'character' + self.data = data + + __str__ = __repr__ = display + +# holds a single message, and all its data +class Message(): + + def display(self): + meta_data = ["#" + str(self.index), + "ID: 0x" + "{:04x}".format(self.id), + "Offset: 0x" + "{:06x}".format(self.offset), + "Length: 0x" + "{:04x}".format(self.unpadded_length) + "/0x" + "{:04x}".format(self.length), + "Box Type: " + str(self.box_type), + "Postion: " + str(self.position)] + return ', '.join(meta_data) + '\n' + self.text + + def get_python_string(self): + ret = '' + for code in self.text_codes: + ret = ret + code.get_python_string() + return ret + + # check if this is an unused message that just contains it's own id as text + def is_id_message(self): + if self.unpadded_length == 5: + for i in range(4): + code = self.text_codes[i].code + if not (code in range(ord('0'),ord('9')+1) or code in range(ord('A'),ord('F')+1) or code in range(ord('a'),ord('f')+1) ): + return False + return True + return False + + def parse_text(self): + self.text_codes = [] + + index = 0 + while index < self.length: + next_char = self.raw_text[index] + data = 0 + index += 1 + if next_char in CONTROL_CODES: + extra_bytes = CONTROL_CODES[next_char][1] + if extra_bytes > 0: + data = bytes_to_int(self.raw_text[index : index + extra_bytes]) + index += extra_bytes + text_code = Text_Code(next_char, data) + self.text_codes.append(text_code) + if next_char == 0x02: # message end code + break + if next_char == 0x07: # goto + self.has_goto = True + self.ending = text_code + if next_char == 0x0A: # keep-open + self.has_keep_open = True + self.ending = text_code + if next_char == 0x0B: # event + self.has_event = True + self.ending = text_code + if next_char == 0x0E: # fade out + self.has_fade = True + self.ending = text_code + if next_char == 0x10: # ocarina + self.has_ocarina = True + self.ending = text_code + if next_char == 0x1B: # two choice + self.has_two_choice = True + if next_char == 0x1C: # three choice + self.has_three_choice = True + self.text = display_code_list(self.text_codes) + self.unpadded_length = index + + def is_basic(self): + return not (self.has_goto or self.has_keep_open or self.has_event or self.has_fade or self.has_ocarina or self.has_two_choice or self.has_three_choice) + + # writes a Message back into the rom, using the given index and offset to update the table + # returns the offset of the next message + def write(self, rom, index, offset, replace_ending=False, ending=None, always_allow_skip=True, speed_up_text=True): + + # construct the table entry + id_bytes = int_to_bytes(self.id, 2) + offset_bytes = int_to_bytes(offset, 3) + entry = id_bytes + bytes([self.opts, 0x00, 0x07]) + offset_bytes + # write it back + entry_offset = TABLE_START + 8 * index + rom.write_bytes(entry_offset, entry) + + ending_codes = [0x02, 0x07, 0x0A, 0x0B, 0x0E, 0x10] + box_breaks = [0x04, 0x0C] + slows_text = [0x08, 0x09, 0x14] + + # # speed the text + if speed_up_text: + offset = Text_Code(0x08, 0).write(rom, offset) # allow instant + + # write the message + for code in self.text_codes: + # ignore ending codes if it's going to be replaced + if replace_ending and code.code in ending_codes: + pass + # ignore the "make unskippable flag" + elif always_allow_skip and code.code == 0x1A: + pass + # ignore anything that slows down text + elif speed_up_text and code.code in slows_text: + pass + elif speed_up_text and code.code in box_breaks: + offset = Text_Code(0x04, 0).write(rom, offset) # un-delayed break + offset = Text_Code(0x08, 0).write(rom, offset) # allow instant + else: + offset = code.write(rom, offset) + + if replace_ending: + if ending: + if speed_up_text and ending.code == 0x10: # ocarina + offset = Text_Code(0x09, 0).write(rom, offset) # disallow instant text + offset = ending.write(rom, offset) # write special ending + offset = Text_Code(0x02, 0).write(rom, offset) # write end code + + + while offset % 4 > 0: + offset = Text_Code(0x00, 0).write(rom, offset) # pad to 4 byte align + + return offset + + def __init__(self, raw_text, index, id, opts, offset, length): + + self.raw_text = raw_text + + self.index = index + self.id = id + self.opts = opts + self.box_type = (self.opts & 0xF0) >> 4 + self.position = (self.opts & 0x0F) + self.offset = offset + self.length = length + + self.has_goto = False + self.has_keep_open = False + self.has_event = False + self.has_fade = False + self.has_ocarina = False + self.has_two_choice = False + self.has_three_choice = False + self.ending = None + + self.parse_text() + + # read a single message from rom + @classmethod + def from_rom(cls, rom, index): + + entry_offset = TABLE_START + 8 * index + entry = rom.read_bytes(entry_offset, 8) + next = rom.read_bytes(entry_offset + 8, 8) + + id = bytes_to_int(entry[0:2]) + opts = entry[2] + offset = bytes_to_int(entry[5:8]) + length = bytes_to_int(next[5:8]) - offset + + raw_text = rom.read_bytes(TEXT_START + offset, length) + + return cls(raw_text, index, id, opts, offset, length) + + @classmethod + def from_string(cls, text, id=0, opts=0x00): + bytes = list(text.encode('utf-8')) + [0x02] + + return cls(bytes, 0, id, opts, 0, len(bytes) + 1) + + __str__ = __repr__ = display + +# wrapper for updating the text of a message, given its message id +# if the id does not exist in the list, then it will add it +def update_message_by_id(messages, id, text, opts=None): + # get the message index + index = next( (m.index for m in messages if m.id == id), -1) + # update if it was found + if index >= 0: + update_message_by_index(messages, index, text, opts) + else: + add_message(messages, text, id, opts) + +# Gets the message by its ID. Returns None if the index does not exist +def get_message_by_id(messages, id): + # get the message index + index = next( (m.index for m in messages if m.id == id), -1) + if index >= 0: + return messages[index] + else: + return None + +# wrapper for updating the text of a message, given its index in the list +def update_message_by_index(messages, index, text, opts=None): + if opts is None: + opts = messages[index].opts + messages[index] = Message.from_string(text, messages[index].id, opts) + messages[index].index = index + +# wrapper for adding a string message to a list of messages +def add_message(messages, text, id=0, opts=0x00): + messages.append( Message.from_string(text, id, opts) ) + messages[-1].index = len(messages) - 1 + +# holds a row in the shop item table (which contains pointers to the description and purchase messages) +class Shop_Item(): + + def display(self): + meta_data = ["#" + str(self.index), + "Item: 0x" + "{:04x}".format(self.get_item_id), + "Price: " + str(self.price), + "Amount: " + str(self.pieces), + "Object: 0x" + "{:04x}".format(self.object), + "Model: 0x" + "{:04x}".format(self.model), + "Description: 0x" + "{:04x}".format(self.description_message), + "Purchase: 0x" + "{:04x}".format(self.purchase_message),] + func_data = [ + "func1: 0x" + "{:08x}".format(self.func1), + "func2: 0x" + "{:08x}".format(self.func2), + "func3: 0x" + "{:08x}".format(self.func3), + "func4: 0x" + "{:08x}".format(self.func4),] + return ', '.join(meta_data) + '\n' + ', '.join(func_data) + + # write the shop item back + def write(self, rom, shop_table_address, index): + + entry_offset = shop_table_address + 0x20 * index + + bytes = [] + bytes += int_to_bytes(self.object, 2) + bytes += int_to_bytes(self.model, 2) + bytes += int_to_bytes(self.func1, 4) + bytes += int_to_bytes(self.price, 2) + bytes += int_to_bytes(self.pieces, 2) + bytes += int_to_bytes(self.description_message, 2) + bytes += int_to_bytes(self.purchase_message, 2) + bytes += [0x00, 0x00] + bytes += int_to_bytes(self.get_item_id, 2) + bytes += int_to_bytes(self.func2, 4) + bytes += int_to_bytes(self.func3, 4) + bytes += int_to_bytes(self.func4, 4) + + rom.write_bytes(entry_offset, bytes) + + # read a single message + def __init__(self, rom, shop_table_address, index): + + entry_offset = shop_table_address + 0x20 * index + entry = rom.read_bytes(entry_offset, 0x20) + + self.index = index + self.object = bytes_to_int(entry[0x00:0x02]) + self.model = bytes_to_int(entry[0x02:0x04]) + self.func1 = bytes_to_int(entry[0x04:0x08]) + self.price = bytes_to_int(entry[0x08:0x0A]) + self.pieces = bytes_to_int(entry[0x0A:0x0C]) + self.description_message = bytes_to_int(entry[0x0C:0x0E]) + self.purchase_message = bytes_to_int(entry[0x0E:0x10]) + # 0x10-0x11 is always 0000 padded apparently + self.get_item_id = bytes_to_int(entry[0x12:0x14]) + self.func2 = bytes_to_int(entry[0x14:0x18]) + self.func3 = bytes_to_int(entry[0x18:0x1C]) + self.func4 = bytes_to_int(entry[0x1C:0x20]) + + __str__ = __repr__ = display + +# reads each of the shop items +def read_shop_items(rom, shop_table_address): + shop_items = [] + + for index in range(0, 100): + shop_items.append( Shop_Item(rom, shop_table_address, index) ) + + return shop_items + +# writes each of the shop item back into rom +def write_shop_items(rom, shop_table_address, shop_items): + for s in shop_items: + s.write(rom, shop_table_address, s.index) + +# these are unused shop items, and contain text ids that are used elsewhere, and should not be moved +SHOP_ITEM_EXCEPTIONS = [0x0A, 0x0B, 0x11, 0x12, 0x13, 0x14, 0x29] + +# returns a set of all message ids used for shop items +def get_shop_message_id_set(shop_items): + ids = set() + for shop in shop_items: + if shop.index not in SHOP_ITEM_EXCEPTIONS: + ids.add(shop.description_message) + ids.add(shop.purchase_message) + return ids + +# remove all messages that easy to tell are unused to create space in the message index table +def remove_unused_messages(messages): + messages[:] = [m for m in messages if not m.is_id_message()] + for index, m in enumerate(messages): + m.index = index + +# takes all messages used for shop items, and moves messages from the 00xx range into the unused 80xx range +def move_shop_item_messages(messages, shop_items): + # checks if a message id is in the item message range + def is_in_item_range(id): + bytes = int_to_bytes(id, 2) + return bytes[0] == 0x00 + # get the ids we want to move + ids = set( id for id in get_shop_message_id_set(shop_items) if is_in_item_range(id) ) + # update them in the message list + for id in ids: + # should be a singleton list, but in case something funky is going on, handle it as a list regardless + relevant_messages = [message for message in messages if message.id == id] + for message in relevant_messages: + message.id |= 0x8000 + # update them in the shop item list + for shop in shop_items: + if is_in_item_range(shop.description_message): + shop.description_message |= 0x8000 + if is_in_item_range(shop.purchase_message): + shop.purchase_message |= 0x8000 + +def make_player_message(text): + player_text_U = '\x05\x42\x0F\x05\x40' + player_text_L = '\x05\x42\x0F\x05\x40' + pronoun_mapping = { + 'You have ': player_text_U + ' ', + 'You\'ve ': player_text_U + ' ', + 'Your ': player_text_U + '\'s ', + 'You ': player_text_U + ' ', + + 'you have ': player_text_L + ' ', + 'you\'ve ': player_text_L + ' ', + 'your ': player_text_L + '\'s ', + 'you ': player_text_L + ' ', + } + + verb_mapping = { + 'obtained ': 'got ', + 'received ': 'got ', + 'learned ': 'got ', + 'borrowed ': 'got ', + 'found ': 'got ', + } + + new_text = text + for find_text, replace_text in pronoun_mapping.items(): + if find_text in text: + new_text = new_text.replace(find_text, replace_text, 1) + break + for find_text, replace_text in verb_mapping.items(): + new_text = new_text.replace(find_text, replace_text) + return new_text + + + + +# add the keysanity messages +# make sure to call this AFTER move_shop_item_messages() +def add_keysanity_messages(messages, world): + for id, text in KEYSANITY_MESSAGES.items(): + if world.world_count > 1: + update_message_by_id(messages, id, make_player_message(text), 0x23) + else: + update_message_by_id(messages, id, text, 0x23) + +# add the song messages +# make sure to call this AFTER move_shop_item_messages() +def add_song_messages(messages, world): + for id, text in SONG_MESSAGES.items(): + if world.world_count > 1: + update_message_by_id(messages, id, make_player_message(text), 0x23) + else: + update_message_by_id(messages, id, text, 0x23) + +# reduce item message sizes +def update_item_messages(messages, world): + for id, text in ITEM_MESSAGES.items(): + if world.world_count > 1: + update_message_by_id(messages, id, make_player_message(text), 0x23) + + else: + update_message_by_id(messages, id, text) + +# run all keysanity related patching to add messages for dungeon specific items +def message_patch_for_dungeon_items(messages, shop_items, world): + move_shop_item_messages(messages, shop_items) + add_keysanity_messages(messages, world) + +# reads each of the game's messages into a list of Message objects +def read_messages(rom): + + table_offset = TABLE_START + index = 0 + messages = [] + while True: + entry = rom.read_bytes(table_offset, 8) + id = bytes_to_int(entry[0:2]) + + if id == 0xFFFD: + table_offset += 8 + continue # this is only here to give an ending offset + if id == 0xFFFF: + break # this marks the end of the table + + messages.append( Message.from_rom(rom, index) ) + + index += 1 + table_offset += 8 + + return messages + +# wrtie the messages back +def repack_messages(rom, messages, permutation=None, always_allow_skip=True, speed_up_text=True): + + if permutation is None: + permutation = range(len(messages)) + + # repack messages + offset = 0 + for old_index, new_index in enumerate(permutation): + old_message = messages[old_index] + new_message = messages[new_index] + remember_id = new_message.id + new_message.id = old_message.id + offset = new_message.write(rom, old_index, offset, True, old_message.ending, always_allow_skip, speed_up_text) + new_message.id = remember_id + + if offset > TEXT_SIZE_LIMIT: + raise(TypeError("Message Text table is too large: 0x" + "{:x}".format(offset) + " written / 0x" + "{:x}".format(TEXT_SIZE_LIMIT) + " allowed.")) + + # end the table + table_index = len(messages) + entry = bytes([0xFF, 0xFD, 0x00, 0x00, 0x07]) + int_to_bytes(offset, 3) + entry_offset = TABLE_START + 8 * table_index + rom.write_bytes(entry_offset, entry) + table_index += 1 + entry_offset = TABLE_START + 8 * table_index + if 8 * (table_index + 1) > TABLE_SIZE_LIMIT: + raise(TypeError("Message ID table is too large: 0x" + "{:x}".format(8 * (table_index + 1)) + " written / 0x" + "{:x}".format(TABLE_SIZE_LIMIT) + " allowed.")) + rom.write_bytes(entry_offset, [0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + +# shuffles the messages in the game, making sure to keep various message types in their own group +def shuffle_messages(rom, except_hints=True, always_allow_skip=True): + + messages = read_messages(rom) + + permutation = [i for i, _ in enumerate(messages)] + + def is_not_exempt(m): + exempt_as_id = m.is_id_message() + exempt_as_hint = ( except_hints and m.id in (GOSSIP_STONE_MESSAGES + TEMPLE_HINTS_MESSAGES + LIGHT_ARROW_HINT + list(KEYSANITY_MESSAGES.keys()) + shuffle_messages.shop_item_messages ) ) + return not ( exempt_as_id or exempt_as_hint ) + + have_goto = list( filter( lambda m: is_not_exempt(m) and m.has_goto, messages) ) + have_keep_open = list( filter( lambda m: is_not_exempt(m) and m.has_keep_open, messages) ) + have_event = list( filter( lambda m: is_not_exempt(m) and m.has_event, messages) ) + have_fade = list( filter( lambda m: is_not_exempt(m) and m.has_fade, messages) ) + have_ocarina = list( filter( lambda m: is_not_exempt(m) and m.has_ocarina, messages) ) + have_two_choice = list( filter( lambda m: is_not_exempt(m) and m.has_two_choice, messages) ) + have_three_choice = list( filter( lambda m: is_not_exempt(m) and m.has_three_choice, messages) ) + basic_messages = list( filter( lambda m: is_not_exempt(m) and m.is_basic(), messages) ) + + + def shuffle_group(group): + group_permutation = [i for i, _ in enumerate(group)] + random.shuffle(group_permutation) + + for index_from, index_to in enumerate(group_permutation): + permutation[group[index_to].index] = group[index_from].index + + # need to use 'list' to force 'map' to actually run through + list( map( shuffle_group, [ + have_goto + have_keep_open + have_event + have_fade + basic_messages, + have_ocarina, + have_two_choice, + have_three_choice, + ])) + + # write the messages back + repack_messages(rom, messages, permutation, always_allow_skip, False) diff --git a/Notes/shop item notes.txt b/Notes/shop item notes.txt new file mode 100644 index 000000000..a348e5756 --- /dev/null +++ b/Notes/shop item notes.txt @@ -0,0 +1,2486 @@ +scene shop item object loads +[scene] address: object +[0x2C] 0x028E4044: 0x00D8 +[0x2C] 0x028E4046: 0x00B7 +[0x2C] 0x028E4048: 0x00C7 +[0x2C] 0x028E404A: 0x00DC +[0x2C] 0x028E404C: 0x00BB +[0x2C] 0x028E404E: 0x00CE + +[0x2D] 0x02587042: 0x00D8 +[0x2D] 0x02587044: 0x00B7 +[0x2D] 0x02587046: 0x00CB +[0x2D] 0x02587048: 0x00BB +[0x2D] 0x0258704A: 0x00C7 +[0x2D] 0x0258704E: 0x0119 + +[0x2E] 0x02D33042: 0x00B7 +[0x2E] 0x02D33044: 0x00C7 +[0x2E] 0x02D33046: 0x00CE +[0x2E] 0x02D3304A: 0x00EB +[0x2E] 0x02D3304C: 0x00F2 +[0x2E] 0x02D3304E: 0x00F8 + +[0x2F] 0x02D5B044: 0x00B7 +[0x2F] 0x02D5B046: 0x00BB +[0x2F] 0x02D5B048: 0x00D8 +[0x2F] 0x02D5B04A: 0x00EB +[0x2F] 0x02D5B04C: 0x00F4 +[0x2F] 0x02D5B04E: 0x00F2 + +[0x30] 0x02D83044: 0x00EB +[0x30] 0x02D83046: 0x0173 +[0x30] 0x02D83048: 0x0174 +[0x30] 0x02D8304C: 0x00F4 +[0x30] 0x02D8304E: 0x0176 +[0x30] 0x02D83050: 0x0177 +[0x30] 0x02D83054: 0x00BB + +[0x31] 0x02DB0044: 0x00EB +[0x31] 0x02DB0046: 0x0173 +[0x31] 0x02DB0048: 0x0174 +[0x31] 0x02DB004C: 0x00F4 +[0x31] 0x02DB004E: 0x0176 +[0x31] 0x02DB0050: 0x0177 +[0x31] 0x02DB0058: 0x00BB + +[0x32] 0x02DD8044: 0x0148 +[0x32] 0x02DD8046: 0x00D9 + +[0x33] 0x0340A044: 0x0134 +[0x33] 0x0340A046: 0x0135 +[0x33] 0x0340A048: 0x0136 +[0x33] 0x0340A04A: 0x0137 +[0x33] 0x0340A04C: 0x0138 +[0x33] 0x0340A04E: 0x0150 +[0x33] 0x0340A050: 0x0151 +[0x33] 0x0340A052: 0x0152 + +.org 0xC022CC +scene shop item table +0 Deku Nut, x5, 15 00BB 0011 80022554 000F 0005 00B2 007F 00000063 80862FDC 80863B4C 80863FB4 +1 Arrows (2), x30, 60 00D8 0025 80022438 003C 001E 00C1 009B 0000004A 80862E8C 80863A64 80863FB4 +2 Arrows (3), x50, 90 00D8 0026 80022438 005A 0032 00B0 007D 0000004B 80862E8C 80863A64 80863FB4 +3 Bombs, x5, 25 00CE 001F 80022438 0019 0005 00A3 008B 00000001 80862F3C 80863AAC 80863FB4 +4 Deku Nut, x10, 30 00BB 0011 80022554 001E 000A 00A2 0087 00000064 80862FDC 80863B4C 80863FB4 +5 Deku Stick, x1, 10 00C7 001A 00000000 000A 0001 00A1 0088 00000007 80863094 80863BBC 80863FB4 +6 Bombs, x10, 50 00CE 001F 80022438 0032 000A 00B1 007C 00000066 80862F3C 80863AAC 80863FB4 +7 Fish, x1, 200 00F4 003E 80022554 00C8 0001 00B3 007E 0000006C 8086314C 00000000 80863FB4 +8 Red Potion, x1, 30 00EB 0037 80022438 001E 0001 00A5 008E 00000010 808631C4 80863E84 80863FB4 +9 Green Potion, x1, 30 00EB 0036 80022438 001E 0001 00A6 008F 00000011 8086323C 80863E84 80863FB4 +10 Blue Potion, x1, 60 00EB 0038 80022438 003C 0001 00A7 0090 00000012 808632B4 80863E84 80863FB4 +11 Giant's Knife, x1, 00F8 0042 80022438 03E8 0001 00A8 0091 00000028 8086332C 80863BF8 80863FB4 +12 Hylian Shield, x1, 80 00DC 002B 80022438 0050 0001 00A9 0092 0000002A 808633C0 80863C40 80863FB4 +13 Deku Shield, x1, 40 00CB 001C 80022438 0028 0001 009F 0089 00000029 80863440 80863C7C 80863FB4 +14 Goron Tunic, x1, 200 00F2 003B 00000000 00C8 0001 00AA 0093 0000002C 808634C0 80863CB8 80864054 +15 Zora Tunic, x1, 300 00F2 003C 00000000 012C 0001 00AB 0094 0000002D 80863568 80863CF4 80864084 +16 Heart, x16, 10 00B7 0008 00000000 000A 0010 00AC 0095 00000048 80863610 80863D30 80863FB4 +17 Milk Bottle (U) 00DF 002F 808648CC 0064 0001 00AD 0097 00000014 8086365C 80863D70 80863FB4 +18 Weird Egg (U) 00DA 0028 80022438 0064 0001 00AE 0099 00000047 808636B8 80863DAC 80863FB4 +19 Milk Bottle (U) 00DF 002F 808648CC 2710 0001 00B4 0085 00000000 80863714 80863DE8 80863FB4 +20 Weird Egg (U) 00DA 0028 80022438 2710 0001 00B5 0085 00000000 80863728 80863E18 80863FB4 +21 Bombchu, x10, 100 00D9 0027 80022438 0064 000A 00BC 008C 00000003 8086373C 00000000 808640B4 +22 Bombchu, x20, 180 00D9 0027 80022438 00B4 0014 0061 002A 0000006B 8086373C 00000000 808640B4 +23 Bombchu, x20, 180 00D9 0027 80022438 00B4 0014 0061 002A 0000006B 8086373C 00000000 808640B4 +24 Bombchu, x10, 100 00D9 0027 80022438 0064 000A 00BC 008C 00000003 8086373C 00000000 808640B4 +25 Bombchu, x10, 100 00D9 0027 80022438 0064 000A 00BC 008C 00000003 8086373C 00000000 808640B4 +26 Bombchu, x20, 180 00D9 0027 80022438 00B4 0014 0061 002A 0000006B 8086373C 00000000 808640B4 +27 Bombchu, x20, 180 00D9 0027 80022438 00B4 0014 0061 002A 0000006B 8086373C 00000000 808640B4 +28 Bombchu, x10, 100 00D9 0027 80022438 0064 000A 00BC 008C 00000003 8086373C 00000000 808640B4 +29 Deku Seeds, x30, 30 0119 0047 80022438 001E 001E 00DF 00DE 00000069 808637C0 80863E48 80863FB4 +30 Keaton Mask, x1, 0 0134 0030 80022438 0000 0001 70B2 70BE 0000001A 808637C0 80863E48 80863FB4 +31 Spooky Mask, x1, 0 0135 0031 80022438 0000 0001 70B1 70BD 00000018 808637C0 80863E48 80863FB4 +32 Skull Mask, x1, 0 0136 004E 80022438 0000 0001 70B0 70BC 00000017 808637C0 80863E48 80863FB4 +33 Bunny Hood, x1, 0 0137 004F 80022438 0000 0001 70B3 70BF 0000001B 808637C0 80863E48 80863FB4 +34 Mask of Truth, x1, 0 0138 0050 808648CC 0000 0001 70AF 70C3 0000001C 808637C0 80863E48 80863FB4 +35 Zora Mask, x1, 0 0151 005B 00000000 0000 0001 70B9 70C1 00000052 808637C0 80863E48 80863FB4 +36 Goron Mask, x1, 0 0150 005A 00000000 0000 0001 70B8 70C0 00000051 808637C0 80863E48 80863FB4 +37 Gerudo Mask, x1, 0 0152 005C 00000000 0000 0001 70BA 70C2 00000053 808637C0 80863E48 80863FB4 +38 Sold Out, x0, 0 0148 0058 80022438 0000 0000 00BD 70C2 00000053 80863870 00000000 00000000 +39 Blue Fire, x1, 300 0173 0066 80022438 012C 0001 00B9 00B8 0000006E 80863884 80863E84 80863FB4 +40 Bottle Bug, x1, 50 0174 0067 808648CC 0032 0001 00BB 00BA 0000006D 808638FC 80863E84 80863FB4 +41 Big Poe (U), x1, 50 0176 006F 808648CC 0032 0001 506F 5070 00000070 80863974 80863E84 80863FB4 +42 Poe, x1, 30 0176 0069 808648CC 001E 0001 506D 506E 0000006F 80863974 80863E84 80863FB4 +43 Fairy's Spirit, x1, 50 0177 006A 808648CC 0032 0001 00B7 00B6 00000013 808639EC 80863E84 80863FB4 +44 Arrow (1), x10, 20 00D8 0024 80022438 0014 000A 00A0 008A 00000049 80862E8C 80863A64 80863FB4 +45 Bombs, x20, 80 00CE 001F 80022438 0050 0014 001C 0006 00000067 80862F3C 80863AAC 80863FB4 +46 Bombs, x30, 120 00CE 001F 80022438 0078 001E 001D 001E 00000068 80862F3C 80863AAC 80863FB4 +47 Bombs, x5, 35 00CE 001F 80022438 0023 0005 00CB 00CA 00000001 80862F3C 80863AAC 80863FB4 +48 Red Potion, x1, 40 00EB 0037 80022438 0028 0001 0064 0062 00000010 808631C4 80863E84 80863FB4 +49 Red Potion, x1, 50 00EB 0037 80022438 0032 0001 0065 0063 00000010 808631C4 80863E84 80863FB4 + + +00BB 0011 80022554 000F 0005 80B2807F 00000063 801EEEAC 801EFA1C 801EFE84 + +0x1f17a0 + +1ebb50 +00D9 0027 80022438 003C 0005 80FE80FF 0000006A 801E9B7C 00000000 801EA4F4 + + +1f08bc + +0x17, 0x19, 0x1A, 0x1B, 0x1C, + +0xC022CC + (id * 0x20) + 0x1C + + +[0x11, 0x12, 0x13, 0x14, 0x17, 0x19, 0x1A, 0x1B, 0x1C, 0x29, 0x2A, 0x2F, 0x30, 0x31] + Function_1, Function_2, Function_3, Function_4 + ---------------------------------------------- + ["Deku Nut, x5, 15 ", 0x00A984B4, 0x00C008BC, 0x00C0142C, 0x00C01894], + ["Arrows (2), x30, 60 ", 0x00A98398, 0x00C0076C, 0x00C01344, 0x00C01894], + ["Arrows (3), x50, 90 ", 0x00A98398, 0x00C0076C, 0x00C01344, 0x00C01894], X + ["Bombs, x5, 25 ", 0x00A98398, 0x00C0081C, 0x00C0138C, 0x00C01894], + ["Deku Nut, x10, 30 ", 0x00A984B4, 0x00C008BC, 0x00C0142C, 0x00C01894], + ["Deku Stick, x1, 10 ", , 0x00C00974, 0x00C0149C, 0x00C01894], + ["Bombs, x10, 50 ", 0x00A98398, 0x00C0081C, 0x00C0138C, 0x00C01894], + ["Fish, x1, 200 ", 0x00A984B4, 0x00C00A2C, , 0x00C01894], X + ["Red Potion, x1, 30 ", 0x00A98398, 0x00C00AA4, 0x00C01764, 0x00C01894], + ["Green Potion, x1, 30 ", 0x00A98398, 0x00C00B1C, 0x00C01764, 0x00C01894], + ["Blue Potion, x1, 60 ", 0x00A98398, 0x00C00B94, 0x00C01764, 0x00C01894], + ["Giant's Knife, x1, ", 0x00A98398, 0x00C00C0C, 0x00C014D8, 0x00C01894], X + ["Hylian Shield, x1, 80 ", 0x00A98398, 0x00C00CA0, 0x00C01520, 0x00C01894], + ["Deku Shield, x1, 40 ", 0x00A98398, 0x00C00D20, 0x00C0155C, 0x00C01894], + ["Goron Tunic, x1, 200 ", , 0x00C00DA0, 0x00C01598, 0x00C01934], + ["Zora Tunic, x1, 300 ", , 0x00C00E48, 0x00C015D4, 0x00C01964], + ["Heart, x16, 10 ", , 0x00C00EF0, 0x00C01610, 0x00C01894], + ["Milk Bottle (U) ", 0x00C021AC, 0x00C00F3C, 0x00C01650, 0x00C01894], X + ["Weird Egg (U) ", 0x00A98398, 0x00C00F98, 0x00C0168C, 0x00C01894], X + ["Milk Bottle (U) ", 0x00C021AC, 0x00C00FF4, 0x00C016C8, 0x00C01894], X + ["Weird Egg (U) ", 0x00A98398, 0x00C01008, 0x00C016F8, 0x00C01894], X + ["Bombchu, x10, 100 ", 0x00A98398, 0x00C0101C, , 0x00C01994], + ["Bombchu, x20, 180 ", 0x00A98398, 0x00C0101C, , 0x00C01994], + ["Bombchu, x20, 180 ", 0x00A98398, 0x00C0101C, , 0x00C01994], + ["Bombchu, x10, 100 ", 0x00A98398, 0x00C0101C, , 0x00C01994], X + ["Bombchu, x10, 100 ", 0x00A98398, 0x00C0101C, , 0x00C01994], X + ["Bombchu, x20, 180 ", 0x00A98398, 0x00C0101C, , 0x00C01994], X + ["Bombchu, x20, 180 ", 0x00A98398, 0x00C0101C, , 0x00C01994], X + ["Bombchu, x10, 100 ", 0x00A98398, 0x00C0101C, , 0x00C01994], X + ["Deku Seeds, x30, 30 ", 0x00A98398, 0x00C010A0, 0x00C01728, 0x00C01894], + ["Keaton Mask, x1, 0 ", 0x00A98398, 0x00C010A0, 0x00C01728, 0x00C01894], + ["Spooky Mask, x1, 0 ", 0x00A98398, 0x00C010A0, 0x00C01728, 0x00C01894], + ["Skull Mask, x1, 0 ", 0x00A98398, 0x00C010A0, 0x00C01728, 0x00C01894], + ["Bunny Hood, x1, 0 ", 0x00A98398, 0x00C010A0, 0x00C01728, 0x00C01894], + ["Mask of Truth, x1, 0 ", 0x00C021AC, 0x00C010A0, 0x00C01728, 0x00C01894], + ["Zora Mask, x1, 0 ", , 0x00C010A0, 0x00C01728, 0x00C01894], + ["Goron Mask, x1, 0 ", , 0x00C010A0, 0x00C01728, 0x00C01894], + ["Gerudo Mask, x1, 0 ", , 0x00C010A0, 0x00C01728, 0x00C01894], + ["Sold Out, x0, 0 ", 0x00A98398, 0x00C01150, , ], + ["Blue Fire, x1, 300 ", 0x00A98398, 0x00C01164, 0x00C01764, 0x00C01894], + ["Bottle Bug, x1, 50 ", 0x00C021AC, 0x00C011DC, 0x00C01764, 0x00C01894], + ["Big Poe (U), x1, 50 ", 0x00C021AC, 0x00C01254, 0x00C01764, 0x00C01894], X + ["Poe, x1, 30 ", 0x00C021AC, 0x00C01254, 0x00C01764, 0x00C01894], X + ["Fairy's Spirit, x1, 50 ", 0x00C021AC, 0x00C012CC, 0x00C01764, 0x00C01894], + ["Arrow (1), x10, 20 ", 0x00A98398, 0x00C0076C, 0x00C01344, 0x00C01894], + ["Bombs, x20, 80 ", 0x00A98398, 0x00C0081C, 0x00C0138C, 0x00C01894], + ["Bombs, x30, 120 ", 0x00A98398, 0x00C0081C, 0x00C0138C, 0x00C01894], X + ["Bombs, x5, 35 ", 0x00A98398, 0x00C0081C, 0x00C0138C, 0x00C01894], X + ["Red Potion, x1, 40 ", 0x00A98398, 0x00C00AA4, 0x00C01764, 0x00C01894], X + ["Red Potion, x1, 50 ", 0x00A98398, 0x00C00AA4, 0x00C01764, 0x00C01894], X + + +shop actor item list [shop item id, X, Y ,Z] * 8 +.org 0xC71ED0 +-----------------------------------RIGHT SIDE------------------------------------- ---------------------------------LEFT SIDE---------------------------------------- +bottom left top left bottom right top right bottom right top right bottom left top left +000D 0032 0034 FFEC, 0000 0032 004C FFEC, 0004 0050 0034 FFFD, 0005 0050 004C FFFD, 001D FFCE 0034 FFEC, 002C FFCE 004C FFEC, 0001 FFB0 0034 FFFD, 0010 FFB0 004C FFFD, +0009 0032 0034 FFEC, 0027 0032 004C FFEC, 0008 0050 0034 FFFD, 002B 0050 004C FFFD, 0000 FFCE 0034 FFEC, 0028 FFCE 004C FFEC, 002A FFB0 0034 FFFD, 0007 FFB0 004C FFFD, +0018 0032 0034 FFEC, 001C 0032 004C FFEC, 0019 0050 0034 FFFD, 0015 0050 004C FFFD, 001A FFCE 0034 FFEC, 0016 FFCE 004C FFEC, 001B FFB0 0034 FFFD, 0017 FFB0 004C FFFD, +0009 0032 0034 FFEC, 0027 0032 004C FFEC, 0008 0050 0034 FFFD, 002B 0050 004C FFFD, 0000 FFCE 0034 FFEC, 0028 FFCE 004C FFEC, 002A FFB0 0034 FFFD, 0007 FFB0 004C FFFD, +000C 0032 0034 FFEC, 002F 0032 004C FFEC, 0000 0050 0034 FFFD, 0010 0050 004C FFFD, 002C FFCE 0034 FFEC, 0002 FFCE 004C FFEC, 0005 FFB0 0034 FFFD, 0001 FFB0 004C FFFD, +000C 0032 0034 FFEC, 0003 0032 004C FFEC, 0000 0050 0034 FFFD, 0010 0050 004C FFFD, 002C FFCE 0034 FFEC, 0002 FFCE 004C FFEC, 0005 FFB0 0034 FFFD, 0001 FFB0 004C FFFD, +0011 0032 0034 FFEC, 0000 0032 004C FFEC, 0004 0050 0034 FFFD, 0010 0050 004C FFFD, 0012 FFCE 0034 FFEC, 0005 FFCE 004C FFEC, 0010 FFB0 0034 FFFD, 0010 FFB0 004C FFFD, +000F 0032 0034 FFEC, 002C 0032 004C FFEC, 0010 0050 0034 FFFD, 0001 0050 004C FFFD, 0000 FFCE 0034 FFEC, 0002 FFCE 004C FFEC, 0007 FFB0 0034 FFFD, 0031 FFB0 004C FFFD, +0003 0032 0034 FFEC, 0006 0032 004C FFEC, 002D 0050 0034 FFFD, 002E 0050 004C FFFD, 000E FFCE 0034 FFEC, 0010 FFCE 004C FFEC, 0030 FFB0 0034 FFFD, 0010 FFB0 004C FFFD, +0013 0032 0034 FFEC, 0013 0032 004C FFEC, 0013 0050 0034 FFFD, 0013 0050 004C FFFD, 0014 FFCE 0034 FFEC, 0014 FFCE 004C FFEC, 0014 FFB0 0034 FFFD, 0014 FFB0 004C FFFD, +0025 0032 0034 FFEC, 0023 0032 004C FFEC, 0022 0050 0034 FFFD, 0024 0050 004C FFFD, 0020 FFCE 0034 FFEC, 001E FFCE 004C FFEC, 0021 FFB0 0034 FFFD, 001F FFB0 004C FFFD, + + + + +init = 808649B0 = +id 0004 +type 06 +room 00 +flags 00000019 +objectid 0001 +0000 +size 000001C4 +init 80862E28 - C00708 +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a0, 0x18($sp) +0x0000000c: sw $a1, 0x1c($sp) +0x00000010: jal 0x862c0c ; c004ec +0x00000014: lw $a0, 0x18($sp) +0x00000018: lw $a0, 0x18($sp) +0x0000001c: jal 0x862d84 ; +0x00000020: lw $a1, 0x1c($sp) +0x00000024: lw $ra, 0x14($sp) +0x00000028: addiu $sp, $sp, 0x18 +0x0000002c: jr $ra +0x00000030: nop + + .word data_80A3A780 + .word data_80A3A8C4 + .word data_80A3A8C4 + .word data_80A3A8C4 + .word data_80A3A858 + .word data_80A3A87C + .word data_80A3A8A0 + .word data_80A3A7A4 + .word data_80A3A7C8 + .word data_80A3A7EC + .word data_80A3A810 + .word data_80A3A834 + +func_0x862c0c_C004EC: +0x00000000: lh $t6, 0x1c($a0) ; t6 = var +0x00000004: addiu $t7, $t6, -0x11 ; t7 = var - 0x11 +0x00000008: sltiu $at, $t7, 0xc +0x0000000c: beqz $at, 0x16c ; if not 0x11 < var < 0x1D, return +0x00000010: sll $t7, $t7, 2 ; t7 = t7 << 2 +0x00000014: lui $at, 0x8086 +0x00000018: addu $at, $at, $t7 +0x0000001c: lw $t7, 0x5040($at) ; t7 = (?? + t7) +0x00000020: jr $t7 +0x00000024: nop + +0x00000028: lui $t8, 0x8012 +0x0000002c: lhu $t8, -0x4b40($t8) +0x00000030: addiu $t0, $zero, 0x10 +0x00000034: addiu $v0, $zero, 1 +0x00000038: andi $t9, $t8, 4 +0x0000003c: beql $t9, $zero, 0x170 +0x00000040: move $v0, $zero +0x00000044: jr $ra +0x00000048: sh $t0, 0x1c($a0) + +0x0000004c: lui $t1, 0x8012 +0x00000050: lhu $t1, -0x4b40($t1) +0x00000054: addiu $t3, $zero, 0x26 +0x00000058: addiu $v0, $zero, 1 +0x0000005c: andi $t2, $t1, 0x40 +0x00000060: beql $t2, $zero, 0x170 +0x00000064: move $v0, $zero +0x00000068: jr $ra +0x0000006c: sh $t3, 0x1c($a0) + +0x00000070: lui $t4, 0x8012 +0x00000074: lhu $t4, -0x4b40($t4) +0x00000078: addiu $t6, $zero, 0x26 +0x0000007c: addiu $v0, $zero, 1 +0x00000080: andi $t5, $t4, 0x80 +0x00000084: beql $t5, $zero, 0x170 +0x00000088: move $v0, $zero +0x0000008c: jr $ra +0x00000090: sh $t6, 0x1c($a0) + +0x00000094: lui $t7, 0x8012 +0x00000098: lhu $t7, -0x4b40($t7) +0x0000009c: addiu $t9, $zero, 0x26 +0x000000a0: addiu $v0, $zero, 1 +0x000000a4: andi $t8, $t7, 0x100 +0x000000a8: beql $t8, $zero, 0x170 +0x000000ac: move $v0, $zero +0x000000b0: jr $ra +0x000000b4: sh $t9, 0x1c($a0) + +0x000000b8: lui $t0, 0x8012 +0x000000bc: lhu $t0, -0x4b40($t0) +0x000000c0: addiu $t2, $zero, 0x26 +0x000000c4: addiu $v0, $zero, 1 +0x000000c8: andi $t1, $t0, 0x200 +0x000000cc: beql $t1, $zero, 0x170 +0x000000d0: move $v0, $zero +0x000000d4: jr $ra +0x000000d8: sh $t2, 0x1c($a0) + +0x000000dc: lui $t3, 0x8012 +0x000000e0: lhu $t3, -0x4b40($t3) +0x000000e4: addiu $t5, $zero, 0x26 +0x000000e8: addiu $v0, $zero, 1 +0x000000ec: andi $t4, $t3, 0x400 +0x000000f0: beql $t4, $zero, 0x170 +0x000000f4: move $v0, $zero +0x000000f8: jr $ra +0x000000fc: sh $t5, 0x1c($a0) + +0x00000100: lui $t6, 0x8012 +0x00000104: lhu $t6, -0x4b40($t6) +0x00000108: addiu $t8, $zero, 0x26 +0x0000010c: addiu $v0, $zero, 1 +0x00000110: andi $t7, $t6, 8 +0x00000114: beql $t7, $zero, 0x170 +0x00000118: move $v0, $zero +0x0000011c: jr $ra +0x00000120: sh $t8, 0x1c($a0) + +0x00000124: lui $t9, 0x8012 +0x00000128: lhu $t9, -0x4b40($t9) +0x0000012c: addiu $t1, $zero, 0x26 +0x00000130: addiu $v0, $zero, 1 +0x00000134: andi $t0, $t9, 0x10 +0x00000138: beql $t0, $zero, 0x170 +0x0000013c: move $v0, $zero +0x00000140: jr $ra +0x00000144: sh $t1, 0x1c($a0) + +0x00000148: lui $t2, 0x8012 +0x0000014c: lhu $t2, -0x4b40($t2) +0x00000150: addiu $t4, $zero, 0x26 +0x00000154: addiu $v0, $zero, 1 +0x00000158: andi $t3, $t2, 0x20 +0x0000015c: beql $t3, $zero, 0x170 +0x00000160: move $v0, $zero +0x00000164: jr $ra +0x00000168: sh $t4, 0x1c($a0) + +0x0000016c: move $v0, $zero +0x00000170: jr $ra +0x00000174: nop + + +func_0x862d84_c00664: +0x00000000: addiu $sp, $sp, -0x20 +0x00000004: sw $ra, 0x14($sp) +0x00000008: move $a2, $a0 ; a0 = a2 = actor +0x0000000c: move $a3, $a1 +0x00000010: lh $v1, 0x1c($a2) ; v1 = variable +0x00000014: lui $a1, 0x8086 +0x00000018: slti $at, $v1, 0x32 +0x0000001c: bnez $at, 0x3c +0x00000020: sll $t6, $v1, 5 ; t6 = variable << 5 (row offset) +0x00000024: bgezl $v1, 0x40 ; if variable not between 0-0x32 +0x00000028: lui $at, 1 + + ; shop item id not valid range + 0x0000002c: jal 0x20eb4 + 0x00000030: move $a0, $a2 + 0x00000034: b 0x98 + 0x00000038: lw $ra, 0x14($sp) + +; shop item id valid range +0x0000003c: lui $at, 1 +0x00000040: ori $at, $at, 0x17a4 ; at = 0x117A4 +0x00000044: addu $a1, $a1, $t6 ; a1 = partial address + row offset +0x00000048: lh $a1, 0x49ec($a1) ; a1 = (shop item table + row offset)[0] = model +0x0000004c: addu $a0, $a3, $at ; a0 = ctx + 0x117A4 +0x00000050: sh $v1, 0x1e($sp) +0x00000054: jal 0x81628 +0x00000058: sw $a2, 0x20($sp) +0x0000005c: lw $a2, 0x20($sp) +0x00000060: lh $v1, 0x1e($sp) +0x00000064: lui $t8, 0x8086 ; t8 = state1_8086443c_c01d1c +0x00000068: sb $v0, 0x184($a2) +0x0000006c: lb $t7, 0x184($a2) +0x00000070: addiu $t8, $t8, 0x443c +0x00000074: bgezl $t7, 0x90 +0x00000078: sh $v1, 0x1c($a2) + +0x0000007c: jal 0x20eb4 +0x00000080: move $a0, $a2 +0x00000084: b 0x98 +0x00000088: lw $ra, 0x14($sp) + +0x0000008c: sh $v1, 0x1c($a2) +0x00000090: sw $t8, 0x188($a2) + +0x00000094: lw $ra, 0x14($sp) +0x00000098: addiu $sp, $sp, 0x20 +0x0000009c: jr $ra +0x000000a0: nop + + +dest 80862E5C_c0073c +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: move $a2, $a0 +0x0000000c: lw $t6, 0x18c($a2) +0x00000010: beql $t6, $zero, 0x24 +0x00000014: lw $ra, 0x14($sp) +0x00000018: jal 0x8d6d0 +0x0000001c: addiu $a0, $a2, 0x13c +0x00000020: lw $ra, 0x14($sp) +0x00000024: addiu $sp, $sp, 0x18 +0x00000028: jr $ra +0x0000002c: nop + +main 808648A8 - C02188 +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: lw $t9, 0x188($a0) +0x0000000c: jalr $t9 +0x00000010: nop +0x00000014: lw $ra, 0x14($sp) +0x00000018: addiu $sp, $sp, 0x18 +0x0000001c: jr $ra +0x00000020: nop + +draw 00000000 + + + + + + + + + + +------------------------------------------------------------------------------------------------------------ +Function_1 +------------------------------------------------------------------------------------------------------------ +func_0x00A984B4: +0x00000000: addiu $sp, $sp, -0x58 +0x00000004: sw $s0, 0x18($sp) +0x00000008: move $s0, $a1 +0x0000000c: sw $ra, 0x1c($sp) +0x00000010: sw $a0, 0x58($sp) +0x00000014: sw $a2, 0x60($sp) +0x00000018: lui $at, 1 +0x0000001c: addu $v0, $s0, $at +0x00000020: lb $t6, 0xa4e($v0) +0x00000024: lw $a0, 0x58($sp) +0x00000028: addiu $a1, $s0, 0xe0 +0x0000002c: mtc1 $t6, $f4 +0x00000030: addiu $a2, $sp, 0x48 +0x00000034: addiu $a0, $a0, 0x24 +0x00000038: cvt.s.w $f6, $f4 +0x0000003c: swc1 $f6, 0x48($sp) +0x00000040: lb $t7, 0xa4f($v0) +0x00000044: mtc1 $t7, $f8 +0x00000048: nop +0x0000004c: cvt.s.w $f10, $f8 +0x00000050: swc1 $f10, 0x4c($sp) +0x00000054: lb $t8, 0xa50($v0) +0x00000058: mtc1 $t8, $f16 +0x0000005c: nop +0x00000060: cvt.s.w $f18, $f16 +0x00000064: swc1 $f18, 0x50($sp) +0x00000068: jal 0x22400 +0x0000006c: lw $a3, ($s0) +0x00000070: lw $t9, 0x60($sp) +0x00000074: lui $t0, 0xdf00 +0x00000078: beql $t9, $zero, 0x10c +0x0000007c: lw $ra, 0x1c($sp) +0x00000080: lw $a0, ($s0) +0x00000084: lw $v1, 0x2c4($a0) +0x00000088: addiu $v1, $v1, -0x10 +0x0000008c: sw $v1, 0x2c4($a0) +0x00000090: lw $a1, ($s0) +0x00000094: lw $t1, ($v0) +0x00000098: lw $t6, 4($v0) +0x0000009c: lui $at, 0xf200 +0x000000a0: andi $t2, $t1, 0xfff +0x000000a4: sll $t3, $t2, 0xc +0x000000a8: or $t4, $t3, $at +0x000000ac: andi $t7, $t6, 0xfff +0x000000b0: or $t8, $t4, $t7 +0x000000b4: sw $t8, ($v1) +0x000000b8: lw $t9, ($v0) +0x000000bc: lw $t6, 4($v0) +0x000000c0: lui $at, 0x100 +0x000000c4: addiu $t1, $t9, 0x3c +0x000000c8: andi $t2, $t1, 0xfff +0x000000cc: sll $t3, $t2, 0xc +0x000000d0: addiu $t7, $t6, 0x3c +0x000000d4: andi $t8, $t7, 0xfff +0x000000d8: or $t5, $t3, $at +0x000000dc: or $t9, $t5, $t8 +0x000000e0: sw $t9, 4($v1) +0x000000e4: sw $t0, 8($v1) +0x000000e8: sw $zero, 0xc($v1) +0x000000ec: lw $a3, 0x2d0($a1) +0x000000f0: lui $t2, 0xdb06 +0x000000f4: ori $t2, $t2, 0x1c +0x000000f8: addiu $t1, $a3, 8 +0x000000fc: sw $t1, 0x2d0($a1) +0x00000100: sw $v1, 4($a3) +0x00000104: sw $t2, ($a3) +0x00000108: lw $ra, 0x1c($sp) +0x0000010c: lw $s0, 0x18($sp) +0x00000110: addiu $sp, $sp, 0x58 +0x00000114: jr $ra +0x00000118: nop + + +func_0x00A98398: +0x00000000: addiu $sp, $sp, -0x58 +0x00000004: sw $s0, 0x18($sp) +0x00000008: move $s0, $a1 +0x0000000c: sw $ra, 0x1c($sp) +0x00000010: sw $a0, 0x58($sp) +0x00000014: sw $a2, 0x60($sp) +0x00000018: lui $at, 1 +0x0000001c: addu $v0, $s0, $at +0x00000020: lb $t6, 0xa4e($v0) +0x00000024: lw $a0, 0x58($sp) +0x00000028: addiu $a1, $s0, 0xe0 +0x0000002c: mtc1 $t6, $f4 +0x00000030: addiu $a2, $sp, 0x48 +0x00000034: addiu $a0, $a0, 0x24 +0x00000038: cvt.s.w $f6, $f4 +0x0000003c: swc1 $f6, 0x48($sp) +0x00000040: lb $t7, 0xa4f($v0) +0x00000044: mtc1 $t7, $f8 +0x00000048: nop +0x0000004c: cvt.s.w $f10, $f8 +0x00000050: swc1 $f10, 0x4c($sp) +0x00000054: lb $t8, 0xa50($v0) +0x00000058: mtc1 $t8, $f16 +0x0000005c: nop +0x00000060: cvt.s.w $f18, $f16 +0x00000064: swc1 $f18, 0x50($sp) +0x00000068: jal 0x223c8 +0x0000006c: lw $a3, ($s0) +0x00000070: lw $t9, 0x60($sp) +0x00000074: lui $t0, 0xdf00 +0x00000078: beql $t9, $zero, 0x10c +0x0000007c: lw $ra, 0x1c($sp) +0x00000080: lw $a0, ($s0) +0x00000084: lw $v1, 0x2c4($a0) +0x00000088: addiu $v1, $v1, -0x10 +0x0000008c: sw $v1, 0x2c4($a0) +0x00000090: lw $a1, ($s0) +0x00000094: lw $t1, ($v0) +0x00000098: lw $t6, 4($v0) +0x0000009c: lui $at, 0xf200 +0x000000a0: andi $t2, $t1, 0xfff +0x000000a4: sll $t3, $t2, 0xc +0x000000a8: or $t4, $t3, $at +0x000000ac: andi $t7, $t6, 0xfff +0x000000b0: or $t8, $t4, $t7 +0x000000b4: sw $t8, ($v1) +0x000000b8: lw $t9, ($v0) +0x000000bc: lw $t6, 4($v0) +0x000000c0: lui $at, 0x100 +0x000000c4: addiu $t1, $t9, 0x3c +0x000000c8: andi $t2, $t1, 0xfff +0x000000cc: sll $t3, $t2, 0xc +0x000000d0: addiu $t7, $t6, 0x3c +0x000000d4: andi $t8, $t7, 0xfff +0x000000d8: or $t5, $t3, $at +0x000000dc: or $t9, $t5, $t8 +0x000000e0: sw $t9, 4($v1) +0x000000e4: sw $t0, 8($v1) +0x000000e8: sw $zero, 0xc($v1) +0x000000ec: lw $a3, 0x2c0($a1) +0x000000f0: lui $t2, 0xdb06 +0x000000f4: ori $t2, $t2, 0x1c +0x000000f8: addiu $t1, $a3, 8 +0x000000fc: sw $t1, 0x2c0($a1) +0x00000100: sw $v1, 4($a3) +0x00000104: sw $t2, ($a3) +0x00000108: lw $ra, 0x1c($sp) +0x0000010c: lw $s0, 0x18($sp) +0x00000110: addiu $sp, $sp, 0x58 +0x00000114: jr $ra +0x00000118: nop + + +func_0x00C021AC: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a0, 0x18($sp) +0x0000000c: sw $a1, 0x1c($sp) +0x00000010: sw $a2, 0x20($sp) +0x00000014: lw $a0, 0x18($sp) +0x00000018: lw $a1, 0x1c($sp) +0x0000001c: jal 0x22438 +0x00000020: move $a2, $zero +0x00000024: lw $a0, 0x18($sp) +0x00000028: lw $a1, 0x1c($sp) +0x0000002c: jal 0x22554 +0x00000030: move $a2, $zero +0x00000034: lw $ra, 0x14($sp) +0x00000038: addiu $sp, $sp, 0x18 +0x0000003c: jr $ra +0x00000040: nop + + + + + + + +------------------------------------------------------------------------------------------------------------ +Function_2 +------------------------------------------------------------------------------------------------------------ +;a0 = ??? +;a1 = actor +;-------- +; +ext_func_0x71420_AE7370: +0x00000000: sw $a0, ($sp) +0x00000004: lui $a2, 0x8010 +0x00000008: addiu $a2, $a2, -0x70cc ; a2 = ?? +0x0000000c: andi $a0, $a0, 0xff ; a0 = a0 & 0xff +0x00000010: addu $t6, $a2, $a0 ; t6 = a2 + item id +0x00000014: lbu $v1, ($t6) ; v1 = ??? +0x00000018: slti $at, $a0, 0x8a ; at = item id < 0x8A ? +0x0000001c: move $v0, $a0 ; v0 = item id +0x00000020: sll $a1, $v1, 0x10 +0x00000024: bnez $at, 0x44 ; if item id < 0x8A +0x00000028: sra $a1, $a1, 0x10 ; a1 = v1 & 0x0000FFFF + 0x0000002c: sll $t7, $v0, 1 ; t7 = item id << 1 + 0x00000030: lui $t8, 0x800f + 0x00000034: addu $t8, $t8, $t7 + 0x00000038: lh $t8, 0x7400($t8) ; t8 = *(??? + item id) + 0x0000003c: addu $t9, $a2, $t8 ; t9 = a2 + t8 + 0x00000040: lbu $a1, ($t9) ; a1 = (t9) + +0x00000044: slti $at, $v0, 0x66 +0x00000048: bnez $at, 0x60 ; if item id >= 0x66 +0x0000004c: slti $at, $v0, 0x6c +0x00000050: beql $at, $zero, 0x64 ; if item id < 0x6C +0x00000054: slti $at, $v0, 0x6c + 0x00000058: jr $ra + 0x0000005c: addiu $v0, $zero, 0xff ; return FF if medallion + +0x00000060: slti $at, $v0, 0x6c +0x00000064: bnez $at, 0x7c ; if item id >= 0x6C +0x00000068: slti $at, $v0, 0x72 +0x0000006c: beql $at, $zero, 0x80 ; if item id < 0x80 +0x00000070: slti $at, $v0, 0x3b + 0x00000074: jr $ra + 0x00000078: addiu $v0, $zero, 0xff ; return if more junk... + +0x0000007c: slti $at, $v0, 0x3b +0x00000080: bnez $at, 0xdc ; if item id >= 0x3B +0x00000084: slti $at, $v0, 0x3e +0x00000088: beqz $at, 0xdc ; if item id < 0x3E +0x0000008c: addiu $at, $zero, 0x3d + 0x00000090: bne $v0, $at, 0xa0 ; if item id == 0x3D + 0x00000094: sll $t0, $v0, 2 ; t0 = item id << 2 + 0x00000098: jr $ra + 0x0000009c: addiu $v0, $zero, 0xff ; return FF if biggoron sword + ; if swords + 0x000000a0: lui $t1, 0x8010 + 0x000000a4: addu $t1, $t1, $t0 + 0x000000a8: lui $t2, 0x8010 + 0x000000ac: lbu $t2, -0x7340($t2); t2 = ??? + 0x000000b0: lw $t1, -0x74fc($t1) ; t1 = (??? + item id) + 0x000000b4: lui $t4, 0x8012 + 0x000000b8: lhu $t4, -0x5994($t4); t4 = ??? + 0x000000bc: sllv $t3, $t1, $t2 ; t3 = t1 << t2 + 0x000000c0: and $t5, $t3, $t4 ; t5 = t3 & t4 + 0x000000c4: beqz $t5, 0xd4 ; if t5 is found + 0x000000c8: nop + 0x000000cc: jr $ra + 0x000000d0: move $v0, $a0 ; return item if found + 0x000000d4: jr $ra + 0x000000d8: addiu $v0, $zero, 0xff ; return ff + +0x000000dc: slti $at, $v0, 0x3e +0x000000e0: bnez $at, 0x12c ; if item id >= 0x3E +0x000000e4: slti $at, $v0, 0x41 +0x000000e8: beqz $at, 0x12c ; if item id < 0x41 +0x000000ec: sll $t6, $v0, 2 + ; if shields + 0x000000f0: lui $t7, 0x8010 + 0x000000f4: addu $t7, $t7, $t6 + 0x000000f8: lui $t8, 0x8010 + 0x000000fc: lbu $t8, -0x733f($t8) + 0x00000100: lw $t7, -0x7508($t7) + 0x00000104: lui $t0, 0x8012 + 0x00000108: lhu $t0, -0x5994($t0) + 0x0000010c: sllv $t9, $t7, $t8 + 0x00000110: and $t1, $t9, $t0 + 0x00000114: beqz $t1, 0x124 + 0x00000118: nop + 0x0000011c: jr $ra + 0x00000120: move $v0, $a0 + 0x00000124: jr $ra + 0x00000128: addiu $v0, $zero, 0xff + +0x0000012c: slti $at, $v0, 0x41 +0x00000130: bnez $at, 0x17c ; if item id >= 0x41 +0x00000134: slti $at, $v0, 0x44 +0x00000138: beqz $at, 0x17c ; if item id < 0x44 +0x0000013c: sll $t2, $v0, 2 + ; tunics + 0x00000140: lui $t3, 0x8010 + 0x00000144: addu $t3, $t3, $t2 + 0x00000148: lui $t4, 0x8010 + 0x0000014c: lbu $t4, -0x733e($t4) + 0x00000150: lw $t3, -0x7514($t3) + 0x00000154: lui $t6, 0x8012 + 0x00000158: lhu $t6, -0x5994($t6) + 0x0000015c: sllv $t5, $t3, $t4 + 0x00000160: and $t7, $t5, $t6 + 0x00000164: beqz $t7, 0x174 + 0x00000168: nop + 0x0000016c: jr $ra + 0x00000170: move $v0, $a0 + 0x00000174: jr $ra + 0x00000178: addiu $v0, $zero, 0xff + +0x0000017c: slti $at, $v0, 0x44 +0x00000180: bnez $at, 0x1cc ; if item id >= 0x44 +0x00000184: slti $at, $v0, 0x47 +0x00000188: beqz $at, 0x1cc ; if item id < 0x47 +0x0000018c: sll $t8, $v0, 2 + ; if boots + 0x00000190: lui $t9, 0x8010 + 0x00000194: addu $t9, $t9, $t8 + 0x00000198: lui $t0, 0x8010 + 0x0000019c: lbu $t0, -0x733d($t0) + 0x000001a0: lw $t9, -0x7520($t9) + 0x000001a4: lui $t2, 0x8012 + 0x000001a8: lhu $t2, -0x5994($t2) + 0x000001ac: sllv $t1, $t9, $t0 + 0x000001b0: and $t3, $t1, $t2 + 0x000001b4: beqz $t3, 0x1c4 + 0x000001b8: nop + 0x000001bc: jr $ra + 0x000001c0: move $v0, $a0 + 0x000001c4: jr $ra + 0x000001c8: addiu $v0, $zero, 0xff + +0x000001cc: addiu $at, $zero, 0x74 +0x000001d0: beq $v0, $at, 0x1e8 ; if item id == 0x74 ;boss key +0x000001d4: addiu $at, $zero, 0x75 +0x000001d8: beq $v0, $at, 0x1e8 ; if item id == 0x75 ;compass +0x000001dc: addiu $at, $zero, 0x76 +0x000001e0: bnel $v0, $at, 0x1f4 ; if item id == 0x76 ;map +0x000001e4: addiu $at, $zero, 0x77 + 0x000001e8: jr $ra + 0x000001ec: addiu $v0, $zero, 0xff ; return ff + +0x000001f0: addiu $at, $zero, 0x77 +0x000001f4: bnel $v0, $at, 0x208 ; if item id == 0x77 ;key +0x000001f8: slti $at, $v0, 6 + 0x000001fc: jr $ra + 0x00000200: addiu $v0, $zero, 0xff ; return ff + +0x00000204: slti $at, $v0, 6 +0x00000208: bnez $at, 0x220 ; if item id >= 0x06 +0x0000020c: slti $at, $v0, 0xa +0x00000210: beql $at, $zero, 0x224 ; if item id < 0x0A +0x00000214: addiu $at, $zero, 0x96 + ; slingshot, ocarina, bombchu, hookshot = FF + 0x00000218: jr $ra + 0x0000021c: addiu $v0, $zero, 0xff + +0x00000220: addiu $at, $zero, 0x96 +0x00000224: beq $v0, $at, 0x234 ; if item id == 0x96 ; bombchu 5 +0x00000228: addiu $at, $zero, 0x97 +0x0000022c: bnel $v0, $at, 0x240 ; if item id == 0x97 ; bombchu 20 +0x00000230: addiu $at, $zero, 0x4a + ; bombchus (5/20) = FF + 0x00000234: jr $ra + 0x00000238: addiu $v0, $zero, 0xff + +0x0000023c: addiu $at, $zero, 0x4a +0x00000240: beq $v0, $at, 0x250 ; if item id == 0x4A ; quiver 30 +0x00000244: lui $t4, 0x8012 +0x00000248: addiu $at, $zero, 3 +0x0000024c: bne $v0, $at, 0x284 ; if item id == 0x03 ; bow + 0x00000250: lui $t5, 0x8010 + 0x00000254: lw $t5, -0x7380($t5) + 0x00000258: lw $t4, -0x5990($t4) + 0x0000025c: lui $t7, 0x8010 + 0x00000260: lbu $t7, -0x733c($t7) + 0x00000264: and $t6, $t4, $t5 + 0x00000268: srav $t8, $t6, $t7 + 0x0000026c: bnez $t8, 0x27c + 0x00000270: nop + 0x00000274: jr $ra + 0x00000278: addiu $v0, $zero, 0xff ; if no bow, return FF + 0x0000027c: jr $ra + 0x00000280: move $v0, $zero ; if bow, return 0 + +0x00000284: addiu $at, $zero, 0x4b +0x00000288: beq $v0, $at, 0x298 ; if item id == 0x4B ; quiver 40 +0x0000028c: addiu $at, $zero, 0x4c +0x00000290: bnel $v0, $at, 0x2a4 ; if item id == 0x4C ; quiver 50 +0x00000294: addiu $at, $zero, 0x48 + 0x00000298: jr $ra + 0x0000029c: addiu $v0, $zero, 0xff ; return FF + +0x000002a0: addiu $at, $zero, 0x48 +0x000002a4: beq $v0, $at, 0x2b4 ; if item id == 0x48 ; bullet bag 40 +0x000002a8: addiu $at, $zero, 0x49 +0x000002ac: bnel $v0, $at, 0x2c0 ; if item id == 0x49 ; bullet bag 50 +0x000002b0: addiu $at, $zero, 0x4d + 0x000002b4: jr $ra + 0x000002b8: addiu $v0, $zero, 0xff ; return ff + +0x000002bc: addiu $at, $zero, 0x4d +0x000002c0: beq $v0, $at, 0x2d0 ; if item id == 0x4D ; bomb bag 20 +0x000002c4: lui $t9, 0x8012 +0x000002c8: addiu $at, $zero, 2 +0x000002cc: bne $v0, $at, 0x304 ; if item id == 0x02 ; bombs + 0x000002d0: lui $t0, 0x8010 + 0x000002d4: lw $t0, -0x737c($t0) + 0x000002d8: lw $t9, -0x5990($t9) + 0x000002dc: lui $t2, 0x8010 + 0x000002e0: lbu $t2, -0x733b($t2) + 0x000002e4: and $t1, $t9, $t0 + 0x000002e8: srav $t3, $t1, $t2 + 0x000002ec: bnez $t3, 0x2fc + 0x000002f0: nop + 0x000002f4: jr $ra + 0x000002f8: addiu $v0, $zero, 0xff ; if no bomb, return ff + 0x000002fc: jr $ra + 0x00000300: move $v0, $zero ; if bomb, return 0 + +0x00000304: slti $at, $v0, 0x98 +0x00000308: bnez $at, 0x320 ; if item id >= 0x98 +0x0000030c: slti $at, $v0, 0x9c +0x00000310: beql $at, $zero, 0x324 ; if item id < 0x9C +0x00000314: slti $at, $v0, 0x4e + ; stick and nut capacity upgrades = FF + 0x00000318: jr $ra + 0x0000031c: addiu $v0, $zero, 0xff + +0x00000320: slti $at, $v0, 0x4e +0x00000324: bnez $at, 0x33c ; if item id >= 0x4E +0x00000328: slti $at, $v0, 0x58 +0x0000032c: beql $at, $zero, 0x340 ; if item id < 0x58 + ; bomb bag 30/40, bracelets, scales, wallets = FF + 0x00000330: addiu $at, $zero, 0xb + 0x00000334: jr $ra + 0x00000338: addiu $v0, $zero, 0xff + +0x0000033c: addiu $at, $zero, 0xb +0x00000340: bnel $v0, $at, 0x354 ; if item id == 0x0B ; longshot +0x00000344: addiu $at, $zero, 0x58 + 0x00000348: jr $ra + 0x0000034c: addiu $v0, $zero, 0xff ; return FF + +0x00000350: addiu $at, $zero, 0x58 +0x00000354: beq $v0, $at, 0x368 ; if item id == 0x58 ; deku seeds 5 +0x00000358: lui $t4, 0x8012 +0x0000035c: addiu $at, $zero, 0x95 +0x00000360: bnel $v0, $at, 0x38c ; if item id == 0x95 ; deku seeds 30 +0x00000364: addiu $at, $zero, 0x10 + 0x00000368: lhu $t4, -0x4b3e($t4) + 0x0000036c: andi $t5, $t4, 8 + 0x00000370: bnez $t5, 0x380 + 0x00000374: nop + 0x00000378: jr $ra + 0x0000037c: addiu $v0, $zero, 0xff ; if no seed bag, return ff + 0x00000380: jr $ra + 0x00000384: addiu $v0, $zero, 0x58 ; if seed bag, return 58 + +0x00000388: addiu $at, $zero, 0x10 +0x0000038c: bnel $v0, $at, 0x3a0 ; if item id == 0x10 ; magic bean +0x00000390: addiu $at, $zero, 0x7a + 0x00000394: jr $ra + 0x00000398: addiu $v0, $zero, 0xff ; return FF + +0x0000039c: addiu $at, $zero, 0x7a +0x000003a0: beq $v0, $at, 0x3b0 ; if item id == 0x7A ; heart piece +0x000003a4: addiu $at, $zero, 0x73 +0x000003a8: bnel $v0, $at, 0x3bc ; if item id == 0x73 ; heart piece +0x000003ac: addiu $at, $zero, 0x72 + 0x000003b0: jr $ra + 0x000003b4: addiu $v0, $zero, 0xff ; return FF + +0x000003b8: addiu $at, $zero, 0x72 +0x000003bc: bnel $v0, $at, 0x3d0 ; if item id == 0x72 ; heart container +0x000003c0: addiu $at, $zero, 0x83 + 0x000003c4: jr $ra + 0x000003c8: addiu $v0, $zero, 0xff ; return FF + +0x000003cc: addiu $at, $zero, 0x83 +0x000003d0: bnel $v0, $at, 0x3e4 ; if item id == 0x83 ; recovery heart +0x000003d4: addiu $at, $zero, 0x78 + 0x000003d8: jr $ra + 0x000003dc: addiu $v0, $zero, 0x83 ; return 83 + +0x000003e0: addiu $at, $zero, 0x78 +0x000003e4: beq $v0, $at, 0x3f8 ; if item id == 0x78 ; small magic refill +0x000003e8: lui $t6, 0x8012 +0x000003ec: addiu $at, $zero, 0x79 +0x000003f0: bnel $v0, $at, 0x41c ; if item id == 0x79 ; large magic refill +0x000003f4: slti $at, $v0, 0x84 + 0x000003f8: lhu $t6, -0x4b06($t6) + 0x000003fc: andi $t7, $t6, 0x100 + 0x00000400: bnez $t7, 0x410 + 0x00000404: nop + 0x00000408: jr $ra + 0x0000040c: addiu $v0, $zero, 0xff ; no magic = return ff + 0x00000410: jr $ra + 0x00000414: move $v0, $a0 ; magic = return item id + +0x00000418: slti $at, $v0, 0x84 +0x0000041c: bnez $at, 0x438 ; if item id >= 0x84 +0x00000420: addiu $a2, $zero, 0x14 +0x00000424: slti $at, $v0, 0x8a +0x00000428: beqz $at, 0x438 ; if item id < 0x8A +0x0000042c: nop + ; rupee 1/5/20/50/200 = FF + 0x00000430: jr $ra + 0x00000434: addiu $v0, $zero, 0xff + +0x00000438: bne $a2, $v0, 0x448 ; if item id == 0x14 ; bottle +0x0000043c: slti $at, $v0, 0x15 + 0x00000440: jr $ra + 0x00000444: addiu $v0, $zero, 0xff ; return FF + +0x00000448: bnez $at, 0x454 ; if item id >= 0x15 +0x0000044c: slti $at, $v0, 0x21 +0x00000450: bnez $at, 0x45c ; if item id < 0x21 +0x00000454: addiu $at, $zero, 0x82 +0x00000458: bne $v0, $at, 0x510 ; if item id == 0x82 ; milk + ; if item is bottled item + 0x0000045c: sll $a0, $v1, 0x10 + 0x00000460: addiu $at, $zero, 0x1a + 0x00000464: beq $v0, $at, 0x4c8 + 0x00000468: sra $a0, $a0, 0x10 ; a0 = v1 & 0x0000FFFF + 0x0000046c: addiu $at, $zero, 0x1b + 0x00000470: beq $v0, $at, 0x4c8 ; if item id == 0x1B ; ruto's letter + 0x00000474: lui $t8, 0x8012 + 0x00000478: addiu $at, $zero, 0x82 + 0x0000047c: bne $v0, $at, 0x48c ; if item id == 0x82 ; milk + 0x00000480: addiu $t8, $t8, -0x5a30 ; t8 = inventory + 0x00000484: lui $a0, 0x8010 + 0x00000488: lbu $a0, -0x70b2($a0) ; a0 = ?? + 0x0000048c: move $v0, $zero ; v0 = 0 + 0x00000490: addu $v1, $a0, $t8 ; v1 = inventory item slot + 0x00000494: addu $t9, $v1, $v0 ; t9 = inventory item slot + + 0x00000498: lbu $t0, 0x74($t9) ; t0 = inventory item + 0x0000049c: addiu $v0, $v0, 1 ; v0++ + 0x000004a0: sll $v0, $v0, 0x10 + 0x000004a4: bne $a2, $t0, 0x4b4 ; if inventory item == item id + 0x000004a8: sra $v0, $v0, 0x10 ; v0 = v0 & 0x0000FFFF ? + 0x000004ac: jr $ra + 0x000004b0: addiu $v0, $zero, 0xff ; return FF + 0x000004b4: slti $at, $v0, 4 + 0x000004b8: bnezl $at, 0x498 ; if v0 < 4, loop + 0x000004bc: addu $t9, $v1, $v0 ; t9 = inventory item slot + 0x000004c0: b 0x52c ; return ?? + 0x000004c4: nop + + ; ruto's letter + 0x000004c8: lui $t1, 0x8012 + 0x000004cc: addiu $t1, $t1, -0x5a30 ; t1 = inventory + 0x000004d0: addu $v1, $a0, $t1 ; v1 = inventory item slot + 0x000004d4: addiu $a0, $zero, 0xff ; a0 = FF + 0x000004d8: move $v0, $zero ; v0 = 0 + 0x000004dc: addu $t2, $v1, $v0 ; t2 = inventory item slot + + 0x000004e0: lbu $t3, 0x74($t2) ; t3 = inventory item + 0x000004e4: addiu $v0, $v0, 1 ; v0++ + 0x000004e8: sll $v0, $v0, 0x10 + 0x000004ec: bne $a0, $t3, 0x4fc ; if inventory item == FF + 0x000004f0: sra $v0, $v0, 0x10 ; v0 = v0 & 0x0000FFFF ? + 0x000004f4: jr $ra + 0x000004f8: addiu $v0, $zero, 0xff ; return FF + 0x000004fc: slti $at, $v0, 4 + 0x00000500: bnezl $at, 0x4e0 ; if v0 < 4, loop + 0x00000504: addu $t2, $v1, $v0 ; t2 = inventory item slot + 0x00000508: b 0x52c ; return ?? + 0x0000050c: nop + +0x00000510: slti $at, $v0, 0x21 +0x00000514: bnez $at, 0x52c ; if item id >= 0x21 +0x00000518: slti $at, $v0, 0x38 +0x0000051c: beqz $at, 0x52c ; if item id >= 0x38 +0x00000520: nop + ; child/adult trade items + 0x00000524: jr $ra + 0x00000528: addiu $v0, $zero, 0xff ; return FF + +0x0000052c: lui $v0, 0x8012 +0x00000530: addu $v0, $v0, $a1 +0x00000534: lbu $v0, -0x59bc($v0) ; return ??? +0x00000538: jr $ra +0x0000053c: nop + + + + + + + + + + + + + + + + + + + + + +; Called when attempting to buy item +;a0 = ??? +;a1 = actor +;-------- +;v0 = 0 = already have one +; 1 = can buy! +; 2 = can't hold any more/already own +; 3 = no empty bottle +; 4 = not enough rupees +; 5 = not adult/can't buy + +func_0x00C0076C: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: sw a1, 0x1c(sp) +0x00000010: jal 0x71420 ; get inventory slot with bow +0x00000014: addiu a0, zero, 3 ; a0 = 3 +0x00000018: addiu at, zero, 0xff ; at = 0xFF +0x0000001c: bne v0, at, 0x2c ; if has bow +0x00000020: lw ra, 0x14(sp) +0x00000024: b 0xa8 +0x00000028: addiu v0, zero, 5 ; if v0 == 0xFF, return v0 = 5 + +0x0000002c: lui v0, 0x8012 +0x00000030: addiu v0, v0, -0x5a30 ; v0 = save context +0x00000034: lui t0, 0x8010 +0x00000038: lw t0, -0x7380(t0) ; t0 = bow_bitflag +0x0000003c: lw t9, 0xa0(v0) ; t9 = equipment +0x00000040: lui t2, 0x8010 +0x00000044: lbu t2, -0x733c(t2) ; t2 = bow_bit +0x00000048: lui t6, 0x8010 +0x0000004c: lbu t6, -0x70c9(t6) ; t6 = bowslot +0x00000050: and t1, t9, t0 ; t1 = equipment & bow_bitflag +0x00000054: srav t3, t1, t2 ; t3 = t1 >> bow_bit +0x00000058: sll t4, t3, 1 ; t4 = t3 << 1 +0x0000005c: lui t5, 0x8010 +0x00000060: addu t5, t5, t4 ; t5 = quiver_index +0x00000064: addu t7, v0, t6 ; t7 = save + bowslot +0x00000068: lb t8, 0x8c(t7) ; t8 = arrow_ammo +0x0000006c: lhu t5, -0x7334(t5) ; t5 = arrow_max +0x00000070: lw t7, 0x1c(sp) ; t7 = a1 +0x00000074: slt at, t8, t5 ; at = arrow_ammo < arrow_max +0x00000078: bnezl at, 0x8c ; if arrow_ammo < arrow_max +0x0000007c: lh t6, 0x34(v0) ; t6 = rupees +0x00000080: b 0xa8 +0x00000084: addiu v0, zero, 2 ; if arrow_ammo >= arrow_max, return v0 = 2 + +0x00000088: lh t6, 0x34(v0) ; unreachable? + +0x0000008c: lh t9, 0x1b8(t7) ; t9 = cost +0x00000090: addiu v0, zero, 1 ; v0 = 1 +0x00000094: slt at, t6, t9 ; at = rupees < cost +0x00000098: beqz at, 0xa8 ; if rupees < cost, return v0 = 1 +0x0000009c: nop +0x000000a0: b 0xa8 +0x000000a4: addiu v0, zero, 4 ; return v0 = 4 +0x000000a8: jr ra +0x000000ac: addiu sp, sp, 0x18 + +func_0x00C0081C: +0x00000000: lui v0, 0x8012 +0x00000004: addiu v0, v0, -0x5a30 +0x00000008: sw a0, (sp) +0x0000000c: lui t6, 0x8010 +0x00000010: lw t6, -0x73c4(t6) +0x00000014: lw t7, 0xa4(v0) +0x00000018: lui t9, 0x8010 +0x0000001c: lui t3, 0x8010 +0x00000020: and t8, t6, t7 +0x00000024: bnez t8, 0x34 +0x00000028: lui t5, 0x8010 +0x0000002c: jr ra +0x00000030: addiu v0, zero, 2 +0x00000034: lw t2, 0xa0(v0) +0x00000038: lw t3, -0x737c(t3) +0x0000003c: lbu t5, -0x733b(t5) +0x00000040: lbu t9, -0x70ca(t9) +0x00000044: and t4, t2, t3 +0x00000048: srav t6, t4, t5 +0x0000004c: sll t7, t6, 1 +0x00000050: lui t8, 0x8010 +0x00000054: addu t8, t8, t7 +0x00000058: addu t0, v0, t9 +0x0000005c: lb t1, 0x8c(t0) +0x00000060: lhu t8, -0x732c(t8) +0x00000064: slt at, t1, t8 +0x00000068: bnezl at, 0x7c +0x0000006c: lh t9, 0x34(v0) +0x00000070: jr ra +0x00000074: addiu v0, zero, 2 +0x00000078: lh t9, 0x34(v0) +0x0000007c: lh t0, 0x1b8(a1) +0x00000080: addiu v0, zero, 1 +0x00000084: slt at, t9, t0 +0x00000088: beqz at, 0x98 +0x0000008c: nop +0x00000090: jr ra +0x00000094: addiu v0, zero, 4 +0x00000098: jr ra +0x0000009c: nop + + +func_0x00C008BC: +0x00000000: addiu sp, sp, -0x18 +0x00000004: lui v1, 0x8012 +0x00000008: addiu v1, v1, -0x5a30 +0x0000000c: sw ra, 0x14(sp) +0x00000010: sw a0, 0x18(sp) +0x00000014: lui t7, 0x8010 +0x00000018: lw t7, -0x7364(t7) +0x0000001c: lw t6, 0xa0(v1) +0x00000020: lui t9, 0x8010 +0x00000024: lbu t9, -0x7335(t9) +0x00000028: and t8, t6, t7 +0x0000002c: lui v0, 0x8010 +0x00000030: srav t0, t8, t9 +0x00000034: sll t1, t0, 1 +0x00000038: addu v0, v0, t1 +0x0000003c: lhu v0, -0x72fc(v0) +0x00000040: lui t2, 0x8010 +0x00000044: beql v0, zero, 0x70 +0x00000048: lh t5, 0x34(v1) +0x0000004c: lbu t2, -0x70cb(t2) +0x00000050: addu t3, v1, t2 +0x00000054: lb t4, 0x8c(t3) +0x00000058: slt at, t4, v0 +0x0000005c: bnezl at, 0x70 +0x00000060: lh t5, 0x34(v1) +0x00000064: b 0xa8 +0x00000068: addiu v0, zero, 2 +0x0000006c: lh t5, 0x34(v1) +0x00000070: lh t6, 0x1b8(a1) +0x00000074: slt at, t5, t6 +0x00000078: beqz at, 0x88 +0x0000007c: nop +0x00000080: b 0xa8 +0x00000084: addiu v0, zero, 4 +0x00000088: jal 0x71420 +0x0000008c: addiu a0, zero, 1 +0x00000090: addiu at, zero, 0xff +0x00000094: bnel v0, at, 0xa8 +0x00000098: addiu v0, zero, 1 +0x0000009c: b 0xa8 +0x000000a0: move v0, zero +0x000000a4: addiu v0, zero, 1 +0x000000a8: lw ra, 0x14(sp) +0x000000ac: addiu sp, sp, 0x18 +0x000000b0: jr ra +0x000000b4: nop + + +func_0x00C00974: +0x00000000: addiu sp, sp, -0x18 +0x00000004: lui v1, 0x8012 +0x00000008: addiu v1, v1, -0x5a30 +0x0000000c: sw ra, 0x14(sp) +0x00000010: sw a0, 0x18(sp) +0x00000014: lui t7, 0x8010 +0x00000018: lw t7, -0x7368(t7) +0x0000001c: lw t6, 0xa0(v1) +0x00000020: lui t9, 0x8010 +0x00000024: lbu t9, -0x7336(t9) +0x00000028: and t8, t6, t7 +0x0000002c: lui v0, 0x8010 +0x00000030: srav t0, t8, t9 +0x00000034: sll t1, t0, 1 +0x00000038: addu v0, v0, t1 +0x0000003c: lhu v0, -0x7304(v0) +0x00000040: lui t2, 0x8010 +0x00000044: beql v0, zero, 0x70 +0x00000048: lh t5, 0x34(v1) +0x0000004c: lbu t2, -0x70cc(t2) +0x00000050: addu t3, v1, t2 +0x00000054: lb t4, 0x8c(t3) +0x00000058: slt at, t4, v0 +0x0000005c: bnezl at, 0x70 +0x00000060: lh t5, 0x34(v1) +0x00000064: b 0xa8 +0x00000068: addiu v0, zero, 2 +0x0000006c: lh t5, 0x34(v1) +0x00000070: lh t6, 0x1b8(a1) +0x00000074: slt at, t5, t6 +0x00000078: beqz at, 0x88 +0x0000007c: nop +0x00000080: b 0xa8 +0x00000084: addiu v0, zero, 4 +0x00000088: jal 0x71420 +0x0000008c: move a0, zero +0x00000090: addiu at, zero, 0xff +0x00000094: bnel v0, at, 0xa8 +0x00000098: addiu v0, zero, 1 +0x0000009c: b 0xa8 +0x000000a0: move v0, zero +0x000000a4: addiu v0, zero, 1 +0x000000a8: lw ra, 0x14(sp) +0x000000ac: addiu sp, sp, 0x18 +0x000000b0: jr ra +0x000000b4: nop + + +func_0x00C00A2C: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: sw a1, 0x1c(sp) +0x00000010: jal 0x71a94 +0x00000014: nop +0x00000018: bnez v0, 0x28 +0x0000001c: lw t7, 0x1c(sp) +0x00000020: b 0x68 +0x00000024: addiu v0, zero, 3 +0x00000028: lui t6, 0x8012 +0x0000002c: lh t6, -0x59fc(t6) +0x00000030: lh t8, 0x1b8(t7) +0x00000034: slt at, t6, t8 +0x00000038: beqz at, 0x48 +0x0000003c: nop +0x00000040: b 0x68 +0x00000044: addiu v0, zero, 4 +0x00000048: jal 0x71420 +0x0000004c: addiu a0, zero, 0x19 +0x00000050: addiu at, zero, 0xff +0x00000054: bnel v0, at, 0x68 +0x00000058: addiu v0, zero, 1 +0x0000005c: b 0x68 +0x00000060: move v0, zero +0x00000064: addiu v0, zero, 1 +0x00000068: lw ra, 0x14(sp) +0x0000006c: addiu sp, sp, 0x18 +0x00000070: jr ra +0x00000074: nop + + +func_0x00C00AA4: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: sw a1, 0x1c(sp) +0x00000010: jal 0x71a94 +0x00000014: nop +0x00000018: bnez v0, 0x28 +0x0000001c: lw t7, 0x1c(sp) +0x00000020: b 0x68 +0x00000024: addiu v0, zero, 3 +0x00000028: lui t6, 0x8012 +0x0000002c: lh t6, -0x59fc(t6) +0x00000030: lh t8, 0x1b8(t7) +0x00000034: slt at, t6, t8 +0x00000038: beqz at, 0x48 +0x0000003c: nop +0x00000040: b 0x68 +0x00000044: addiu v0, zero, 4 +0x00000048: jal 0x71420 +0x0000004c: addiu a0, zero, 0x15 +0x00000050: addiu at, zero, 0xff +0x00000054: bnel v0, at, 0x68 +0x00000058: addiu v0, zero, 1 +0x0000005c: b 0x68 +0x00000060: move v0, zero +0x00000064: addiu v0, zero, 1 +0x00000068: lw ra, 0x14(sp) +0x0000006c: addiu sp, sp, 0x18 +0x00000070: jr ra +0x00000074: nop + + +func_0x00C00B1C: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: sw a1, 0x1c(sp) +0x00000010: jal 0x71a94 +0x00000014: nop +0x00000018: bnez v0, 0x28 +0x0000001c: lw t7, 0x1c(sp) +0x00000020: b 0x68 +0x00000024: addiu v0, zero, 3 +0x00000028: lui t6, 0x8012 +0x0000002c: lh t6, -0x59fc(t6) +0x00000030: lh t8, 0x1b8(t7) +0x00000034: slt at, t6, t8 +0x00000038: beqz at, 0x48 +0x0000003c: nop +0x00000040: b 0x68 +0x00000044: addiu v0, zero, 4 +0x00000048: jal 0x71420 +0x0000004c: addiu a0, zero, 0x16 +0x00000050: addiu at, zero, 0xff +0x00000054: bnel v0, at, 0x68 +0x00000058: addiu v0, zero, 1 +0x0000005c: b 0x68 +0x00000060: move v0, zero +0x00000064: addiu v0, zero, 1 +0x00000068: lw ra, 0x14(sp) +0x0000006c: addiu sp, sp, 0x18 +0x00000070: jr ra +0x00000074: nop + + +func_0x00C00B94: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: sw a1, 0x1c(sp) +0x00000010: jal 0x71a94 +0x00000014: nop +0x00000018: bnez v0, 0x28 +0x0000001c: lw t7, 0x1c(sp) +0x00000020: b 0x68 +0x00000024: addiu v0, zero, 3 +0x00000028: lui t6, 0x8012 +0x0000002c: lh t6, -0x59fc(t6) +0x00000030: lh t8, 0x1b8(t7) +0x00000034: slt at, t6, t8 +0x00000038: beqz at, 0x48 +0x0000003c: nop +0x00000040: b 0x68 +0x00000044: addiu v0, zero, 4 +0x00000048: jal 0x71420 +0x0000004c: addiu a0, zero, 0x17 +0x00000050: addiu at, zero, 0xff +0x00000054: bnel v0, at, 0x68 +0x00000058: addiu v0, zero, 1 +0x0000005c: b 0x68 +0x00000060: move v0, zero +0x00000064: addiu v0, zero, 1 +0x00000068: lw ra, 0x14(sp) +0x0000006c: addiu sp, sp, 0x18 +0x00000070: jr ra +0x00000074: nop + + +func_0x00C00C0C: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw a0, 0x18(sp) +0x00000008: lui a0, 0x8012 +0x0000000c: lui v1, 0x8010 +0x00000010: addiu v1, v1, -0x7410 +0x00000014: addiu a0, a0, -0x5a30 +0x00000018: sw ra, 0x14(sp) +0x0000001c: lhu v0, 0x9c(a0) +0x00000020: lw t6, 8(v1) +0x00000024: and t7, t6, v0 +0x00000028: beql t7, zero, 0x4c +0x0000002c: lh t0, 0x34(a0) +0x00000030: lw t8, 0xc(v1) +0x00000034: and t9, t8, v0 +0x00000038: bnezl t9, 0x4c +0x0000003c: lh t0, 0x34(a0) +0x00000040: b 0x84 +0x00000044: addiu v0, zero, 2 +0x00000048: lh t0, 0x34(a0) +0x0000004c: lh t1, 0x1b8(a1) +0x00000050: slt at, t0, t1 +0x00000054: beqz at, 0x64 +0x00000058: nop +0x0000005c: b 0x84 +0x00000060: addiu v0, zero, 4 +0x00000064: jal 0x71420 +0x00000068: addiu a0, zero, 0x3d +0x0000006c: addiu at, zero, 0xff +0x00000070: bnel v0, at, 0x84 +0x00000074: addiu v0, zero, 1 +0x00000078: b 0x84 +0x0000007c: move v0, zero +0x00000080: addiu v0, zero, 1 +0x00000084: lw ra, 0x14(sp) +0x00000088: addiu sp, sp, 0x18 +0x0000008c: jr ra +0x00000090: nop + + +func_0x00C00CA0: +0x00000000: addiu sp, sp, -0x18 +0x00000004: lui v0, 0x8012 +0x00000008: addiu v0, v0, -0x5a30 +0x0000000c: sw ra, 0x14(sp) +0x00000010: sw a0, 0x18(sp) +0x00000014: lui t6, 0x8010 +0x00000018: lw t6, -0x73fc(t6) +0x0000001c: lhu t7, 0x9c(v0) +0x00000020: and t8, t6, t7 +0x00000024: beql t8, zero, 0x38 +0x00000028: lh t9, 0x34(v0) +0x0000002c: b 0x70 +0x00000030: addiu v0, zero, 2 +0x00000034: lh t9, 0x34(v0) +0x00000038: lh t0, 0x1b8(a1) +0x0000003c: slt at, t9, t0 +0x00000040: beqz at, 0x50 +0x00000044: nop +0x00000048: b 0x70 +0x0000004c: addiu v0, zero, 4 +0x00000050: jal 0x71420 +0x00000054: addiu a0, zero, 0x3f +0x00000058: addiu at, zero, 0xff +0x0000005c: bnel v0, at, 0x70 +0x00000060: addiu v0, zero, 1 +0x00000064: b 0x70 +0x00000068: move v0, zero +0x0000006c: addiu v0, zero, 1 +0x00000070: lw ra, 0x14(sp) +0x00000074: addiu sp, sp, 0x18 +0x00000078: jr ra +0x0000007c: nop + + +func_0x00C00D20: +0x00000000: addiu sp, sp, -0x18 +0x00000004: lui v0, 0x8012 +0x00000008: addiu v0, v0, -0x5a30 +0x0000000c: sw ra, 0x14(sp) +0x00000010: sw a0, 0x18(sp) +0x00000014: lui t6, 0x8010 +0x00000018: lw t6, -0x7400(t6) +0x0000001c: lhu t7, 0x9c(v0) +0x00000020: and t8, t6, t7 +0x00000024: beql t8, zero, 0x38 +0x00000028: lh t9, 0x34(v0) +0x0000002c: b 0x70 +0x00000030: addiu v0, zero, 2 +0x00000034: lh t9, 0x34(v0) +0x00000038: lh t0, 0x1b8(a1) +0x0000003c: slt at, t9, t0 +0x00000040: beqz at, 0x50 +0x00000044: nop +0x00000048: b 0x70 +0x0000004c: addiu v0, zero, 4 +0x00000050: jal 0x71420 +0x00000054: addiu a0, zero, 0x3e +0x00000058: addiu at, zero, 0xff +0x0000005c: bnel v0, at, 0x70 +0x00000060: addiu v0, zero, 1 +0x00000064: b 0x70 +0x00000068: move v0, zero +0x0000006c: addiu v0, zero, 1 +0x00000070: lw ra, 0x14(sp) +0x00000074: addiu sp, sp, 0x18 +0x00000078: jr ra +0x0000007c: nop + + +func_0x00C00DA0: +0x00000000: addiu sp, sp, -0x18 +0x00000004: lui v1, 0x8012 +0x00000008: addiu v1, v1, -0x5a30 ; v1 = save context +0x0000000c: sw ra, 0x14(sp) +0x00000010: sw a0, 0x18(sp) +0x00000014: lw t6, 4(v1) ; t6 = age +0x00000018: addiu at, zero, 5 ; at = 5 +0x0000001c: addiu v0, zero, 0x11 ; v0 = 0x11 +0x00000020: beqz t6, 0x30 ; if adult +0x00000024: lui t7, 0x8010 +0x00000028: b 0x30 ; if child, return v0 = 5 +0x0000002c: addiu v0, zero, 5 + +0x00000030: bne v0, at, 0x40 ; if 5 != 11??????? +0x00000034: nop +0x00000038: b 0x98 +0x0000003c: addiu v0, zero, 2 ; this is unreachable + +0x00000040: lw t7, -0x73ec(t7) ; fire tunic bitmask +0x00000044: lhu t8, 0x9c(v1) ; t8 = equipment +0x00000048: and t9, t7, t8 ; t9 = has fire tunic +0x0000004c: beql t9, zero, 0x60 ; if not has fire tunic +0x00000050: lh t0, 0x34(v1) ; t0 = rupees +0x00000054: b 0x98 ; if has fire tunic, return v0 = 2 +0x00000058: addiu v0, zero, 2 + +0x0000005c: lh t0, 0x34(v1) ; unreachable + +0x00000060: lh t1, 0x1b8(a1) ; t1 = cost +0x00000064: slt at, t0, t1 ; at = rupees < cost +0x00000068: beqz at, 0x78 +0x0000006c: nop +0x00000070: b 0x98 +0x00000074: addiu v0, zero, 4 +0x00000078: jal 0x71420 +0x0000007c: addiu a0, zero, 0x42 +0x00000080: addiu at, zero, 0xff +0x00000084: bnel v0, at, 0x98 +0x00000088: addiu v0, zero, 1 +0x0000008c: b 0x98 +0x00000090: move v0, zero +0x00000094: addiu v0, zero, 1 +0x00000098: lw ra, 0x14(sp) +0x0000009c: addiu sp, sp, 0x18 +0x000000a0: jr ra +0x000000a4: nop + + +func_0x00C00E48: +0x00000000: addiu sp, sp, -0x18 +0x00000004: lui v1, 0x8012 +0x00000008: addiu v1, v1, -0x5a30 +0x0000000c: sw ra, 0x14(sp) +0x00000010: sw a0, 0x18(sp) +0x00000014: lw t6, 4(v1) +0x00000018: addiu at, zero, 5 +0x0000001c: addiu v0, zero, 0x11 +0x00000020: beqz t6, 0x30 +0x00000024: lui t7, 0x8010 +0x00000028: b 0x30 +0x0000002c: addiu v0, zero, 5 +0x00000030: bne v0, at, 0x40 +0x00000034: nop +0x00000038: b 0x98 +0x0000003c: addiu v0, zero, 2 +0x00000040: lw t7, -0x73e8(t7) +0x00000044: lhu t8, 0x9c(v1) +0x00000048: and t9, t7, t8 +0x0000004c: beql t9, zero, 0x60 +0x00000050: lh t0, 0x34(v1) +0x00000054: b 0x98 +0x00000058: addiu v0, zero, 2 +0x0000005c: lh t0, 0x34(v1) +0x00000060: lh t1, 0x1b8(a1) +0x00000064: slt at, t0, t1 +0x00000068: beqz at, 0x78 +0x0000006c: nop +0x00000070: b 0x98 +0x00000074: addiu v0, zero, 4 +0x00000078: jal 0x71420 +0x0000007c: addiu a0, zero, 0x43 +0x00000080: addiu at, zero, 0xff +0x00000084: bnel v0, at, 0x98 +0x00000088: addiu v0, zero, 1 +0x0000008c: b 0x98 +0x00000090: move v0, zero +0x00000094: addiu v0, zero, 1 +0x00000098: lw ra, 0x14(sp) +0x0000009c: addiu sp, sp, 0x18 +0x000000a0: jr ra +0x000000a4: nop + + +func_0x00C00EF0: +0x00000000: lui v0, 0x8012 +0x00000004: addiu v0, v0, -0x5a30 +0x00000008: sw a0, (sp) +0x0000000c: lh t6, 0x30(v0) +0x00000010: lh t7, 0x2e(v0) +0x00000014: bnel t6, t7, 0x28 +0x00000018: lh t8, 0x34(v0) +0x0000001c: jr ra +0x00000020: addiu v0, zero, 2 +0x00000024: lh t8, 0x34(v0) +0x00000028: lh t9, 0x1b8(a1) +0x0000002c: addiu v0, zero, 1 +0x00000030: slt at, t8, t9 +0x00000034: beqz at, 0x44 +0x00000038: nop +0x0000003c: jr ra +0x00000040: addiu v0, zero, 4 +0x00000044: jr ra +0x00000048: nop + +------------------------------------------------------------------------------------------------------------ +func_0x00C00F3C: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: lui t6, 0x8012 +0x00000010: lh t6, -0x59fc(t6) +0x00000014: lh t7, 0x1b8(a1) +0x00000018: slt at, t6, t7 +0x0000001c: beqz at, 0x2c +0x00000020: nop +0x00000024: b 0x4c +0x00000028: addiu v0, zero, 4 +0x0000002c: jal 0x71420 +0x00000030: addiu a0, zero, 0x1a +0x00000034: addiu at, zero, 0xff +0x00000038: bnel v0, at, 0x4c +0x0000003c: addiu v0, zero, 1 +0x00000040: b 0x4c +0x00000044: move v0, zero +0x00000048: addiu v0, zero, 1 +0x0000004c: lw ra, 0x14(sp) +0x00000050: addiu sp, sp, 0x18 +0x00000054: jr ra +0x00000058: nop + + +func_0x00C00F98: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: lui t6, 0x8012 +0x00000010: lh t6, -0x59fc(t6) +0x00000014: lh t7, 0x1b8(a1) +0x00000018: slt at, t6, t7 +0x0000001c: beqz at, 0x2c +0x00000020: nop +0x00000024: b 0x4c +0x00000028: addiu v0, zero, 4 +0x0000002c: jal 0x71420 +0x00000030: addiu a0, zero, 0x23 +0x00000034: addiu at, zero, 0xff +0x00000038: bnel v0, at, 0x4c +0x0000003c: addiu v0, zero, 1 +0x00000040: b 0x4c +0x00000044: move v0, zero +0x00000048: addiu v0, zero, 1 +0x0000004c: lw ra, 0x14(sp) +0x00000050: addiu sp, sp, 0x18 +0x00000054: jr ra +0x00000058: nop + + +func_0x00C00FF4: +0x00000000: sw a0, (sp) +0x00000004: sw a1, 4(sp) +0x00000008: addiu v0, zero, 4 +0x0000000c: jr ra +0x00000010: nop + + +func_0x00C01008: +0x00000000: sw a0, (sp) +0x00000004: sw a1, 4(sp) +0x00000008: addiu v0, zero, 4 +0x0000000c: jr ra +0x00000010: nop + + +func_0x00C0101C: +0x00000000: addiu sp, sp, -0x18 +0x00000004: lui v0, 0x8012 +0x00000008: addiu v0, v0, -0x5a30 ;v0 = save +0x0000000c: sw ra, 0x14(sp) +0x00000010: sw a0, 0x18(sp) +0x00000014: lui t6, 0x8010 +0x00000018: lbu t6, -0x70c3(t6) ; t6 = bombchu slot id +0x0000001c: addu t7, v0, t6 ; t7 = save + bomchu slot id +0x00000020: lb t8, 0x8c(t7) ; t8 = bombchu count +0x00000024: slti at, t8, 0x32 +0x00000028: bnezl at, 0x3c ; if bombchu count < 50 +0x0000002c: lh t9, 0x34(v0) ; t9 = rupees +0x00000030: b 0x74 +0x00000034: addiu v0, zero, 2 ; if bombchu count >= 50, return v0 = 2 + +0x00000038: lh t9, 0x34(v0) ; unreachable + +0x0000003c: lh t0, 0x1b8(a1) ; t0 = cost +0x00000040: slt at, t9, t0 +0x00000044: beqz at, 0x54 ; if rupees < cost +0x00000048: nop +0x0000004c: b 0x74 +0x00000050: addiu v0, zero, 4 ; if rupees < cost return v0 = 4 + +0x00000054: jal 0x71420 ; v0 = bombchu item slot +0x00000058: addiu a0, zero, 9 +0x0000005c: addiu at, zero, 0xff +0x00000060: bnel v0, at, 0x74 ; if no bombchu item +0x00000064: addiu v0, zero, 1 ; if bombchu item, return v0 = 1 +0x00000068: b 0x74 +0x0000006c: move v0, zero ; if not bombchu item, return v0 = 0 + +0x00000070: addiu v0, zero, 1 ; unreachable + +0x00000074: lw ra, 0x14(sp) +0x00000078: addiu sp, sp, 0x18 +0x0000007c: jr ra +0x00000080: nop + + +func_0x00C010A0: +0x00000000: addiu sp, sp, -0x18 +0x00000004: lui v0, 0x8012 +0x00000008: addiu v0, v0, -0x5a30 ; v0 = save +0x0000000c: sw ra, 0x14(sp) +0x00000010: sw a0, 0x18(sp) +0x00000014: lui t0, 0x8010 +0x00000018: lw t0, -0x736c(t0) ; t0 = ?? +0x0000001c: lw t9, 0xa0(v0) ; t9 = equipment +0x00000020: lui t2, 0x8010 +0x00000024: lbu t2, -0x7337(t2) ; t2 = ?? +0x00000028: lui t6, 0x8010 +0x0000002c: lbu t6, -0x70c6(t6) ; t6 = ?? +0x00000030: and t1, t9, t0 ; t1 = equipment & t0 +0x00000034: srav t3, t1, t2 ; t3 = t1 >> t2 +0x00000038: sll t4, t3, 1 ; t4 = t3 << 1 +0x0000003c: lui t5, 0x8010 +0x00000040: addu t5, t5, t4 +0x00000044: addu t7, v0, t6 ; t7 = save + ?? +0x00000048: lb t8, 0x8c(t7) ; t8 = ammo +0x0000004c: lhu t5, -0x730c(t5) ; t5 = max_ammo +0x00000050: slt at, t8, t5 +0x00000054: bnezl at, 0x68 ; if ammo < max_ammo +0x00000058: lh t6, 0x34(v0) ; t6 = rupees + 0x0000005c: b 0xa0 + 0x00000060: addiu v0, zero, 2 ; return 2 +0x00000064: lh t6, 0x34(v0) ; unreachable + +0x00000068: lh t7, 0x1b8(a1) ; t7 = cost +0x0000006c: slt at, t6, t7 +0x00000070: beqz at, 0x80 ; if rupee < cost +0x00000074: nop + 0x00000078: b 0xa0 + 0x0000007c: addiu v0, zero, 4 ; return 4 +0x00000080: jal 0x71420 ; v0 = item in deku seed slot +0x00000084: addiu a0, zero, 0x58 ; a0 = deku seeds +0x00000088: addiu at, zero, 0xff +0x0000008c: bnel v0, at, 0xa0 ; if no item +0x00000090: addiu v0, zero, 1 + 0x00000094: b 0xa0 + 0x00000098: move v0, zero ; return 0 +0x0000009c: addiu v0, zero, 1 ; return 1 +0x000000a0: lw ra, 0x14(sp) +0x000000a4: addiu sp, sp, 0x18 +0x000000a8: jr ra +0x000000ac: nop + + +func_0x00C01150: +0x00000000: sw a0, (sp) +0x00000004: sw a1, 4(sp) +0x00000008: addiu v0, zero, 5 +0x0000000c: jr ra +0x00000010: nop + + +func_0x00C01164: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: sw a1, 0x1c(sp) +0x00000010: jal 0x71a94 +0x00000014: nop +0x00000018: bnez v0, 0x28 +0x0000001c: lw t7, 0x1c(sp) +0x00000020: b 0x68 +0x00000024: addiu v0, zero, 3 +0x00000028: lui t6, 0x8012 +0x0000002c: lh t6, -0x59fc(t6) +0x00000030: lh t8, 0x1b8(t7) +0x00000034: slt at, t6, t8 +0x00000038: beqz at, 0x48 +0x0000003c: nop +0x00000040: b 0x68 +0x00000044: addiu v0, zero, 4 +0x00000048: jal 0x71420 +0x0000004c: addiu a0, zero, 0x1c +0x00000050: addiu at, zero, 0xff +0x00000054: bnel v0, at, 0x68 +0x00000058: addiu v0, zero, 1 +0x0000005c: b 0x68 +0x00000060: move v0, zero +0x00000064: addiu v0, zero, 1 +0x00000068: lw ra, 0x14(sp) +0x0000006c: addiu sp, sp, 0x18 +0x00000070: jr ra +0x00000074: nop + + +func_0x00C011DC: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: sw a1, 0x1c(sp) +0x00000010: jal 0x71a94 +0x00000014: nop +0x00000018: bnez v0, 0x28 +0x0000001c: lw t7, 0x1c(sp) +0x00000020: b 0x68 +0x00000024: addiu v0, zero, 3 +0x00000028: lui t6, 0x8012 +0x0000002c: lh t6, -0x59fc(t6) +0x00000030: lh t8, 0x1b8(t7) +0x00000034: slt at, t6, t8 +0x00000038: beqz at, 0x48 +0x0000003c: nop +0x00000040: b 0x68 +0x00000044: addiu v0, zero, 4 +0x00000048: jal 0x71420 +0x0000004c: addiu a0, zero, 0x1d +0x00000050: addiu at, zero, 0xff +0x00000054: bnel v0, at, 0x68 +0x00000058: addiu v0, zero, 1 +0x0000005c: b 0x68 +0x00000060: move v0, zero +0x00000064: addiu v0, zero, 1 +0x00000068: lw ra, 0x14(sp) +0x0000006c: addiu sp, sp, 0x18 +0x00000070: jr ra +0x00000074: nop + + +func_0x00C01254: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: sw a1, 0x1c(sp) +0x00000010: jal 0x71a94 +0x00000014: nop +0x00000018: bnez v0, 0x28 +0x0000001c: lw t7, 0x1c(sp) +0x00000020: b 0x68 +0x00000024: addiu v0, zero, 3 +0x00000028: lui t6, 0x8012 +0x0000002c: lh t6, -0x59fc(t6) +0x00000030: lh t8, 0x1b8(t7) +0x00000034: slt at, t6, t8 +0x00000038: beqz at, 0x48 +0x0000003c: nop +0x00000040: b 0x68 +0x00000044: addiu v0, zero, 4 +0x00000048: jal 0x71420 +0x0000004c: addiu a0, zero, 0x20 +0x00000050: addiu at, zero, 0xff +0x00000054: bnel v0, at, 0x68 +0x00000058: addiu v0, zero, 1 +0x0000005c: b 0x68 +0x00000060: move v0, zero +0x00000064: addiu v0, zero, 1 +0x00000068: lw ra, 0x14(sp) +0x0000006c: addiu sp, sp, 0x18 +0x00000070: jr ra +0x00000074: nop + + +func_0x00C012CC: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: sw a1, 0x1c(sp) +0x00000010: jal 0x71a94 +0x00000014: nop +0x00000018: bnez v0, 0x28 +0x0000001c: lw t7, 0x1c(sp) +0x00000020: b 0x68 +0x00000024: addiu v0, zero, 3 +0x00000028: lui t6, 0x8012 +0x0000002c: lh t6, -0x59fc(t6) +0x00000030: lh t8, 0x1b8(t7) +0x00000034: slt at, t6, t8 +0x00000038: beqz at, 0x48 +0x0000003c: nop +0x00000040: b 0x68 +0x00000044: addiu v0, zero, 4 +0x00000048: jal 0x71420 +0x0000004c: addiu a0, zero, 0x18 +0x00000050: addiu at, zero, 0xff +0x00000054: bnel v0, at, 0x68 +0x00000058: addiu v0, zero, 1 +0x0000005c: b 0x68 +0x00000060: move v0, zero +0x00000064: addiu v0, zero, 1 +0x00000068: lw ra, 0x14(sp) +0x0000006c: addiu sp, sp, 0x18 +0x00000070: jr ra +0x00000074: nop + + + + + + + + + + + + + + +------------------------------------------------------------------------------------------------------------ +Function_3 +------------------------------------------------------------------------------------------------------------ +;a0 = global context +;a1 = actor +;-------- +;none +func_0x00C01344: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a0, 0x18($sp) +0x0000000c: sw $a1, 0x1c($sp) +0x00000010: lw $t6, 0x1c($sp) ; t6 = actor +0x00000014: addiu $a0, $zero, 3 ; a0 = 3 +0x00000018: jal 0x721f4 ; ? +0x0000001c: lh $a1, 0x1ba($t6) ; a1 = count +; subtract money +0x00000020: lw $t7, 0x1c($sp) ; t7 = actor +0x00000024: lh $a0, 0x1b8($t7) ; a0 = cost +0x00000028: negu $a0, $a0 ; +0x0000002c: sll $a0, $a0, 0x10 +0x00000030: jal 0x721cc +0x00000034: sra $a0, $a0, 0x10 ; a0 = -cost +0x00000038: lw $ra, 0x14($sp) +0x0000003c: addiu $sp, $sp, 0x18 +0x00000040: jr $ra +0x00000044: nop + + +func_0x00C0138C: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: lw $t6, 0x1c($sp) ; t6 = actor +0x00000010: addiu $at, $zero, 5 ; at = 5 +0x00000014: lh $v0, 0x1ba($t6) ; v0 = count +0x00000018: beq $v0, $at, 0x40 ; if count = 5 +0x0000001c: addiu $at, $zero, 0xa +0x00000020: beq $v0, $at, 0x50 ; if count = 10 +0x00000024: addiu $at, $zero, 0x14 +0x00000028: beq $v0, $at, 0x60 ; if count = 15 +0x0000002c: addiu $at, $zero, 0x1e +0x00000030: beq $v0, $at, 0x70 ; if count = 20 +0x00000034: nop +0x00000038: b 0x7c ; else give nothing +0x0000003c: lw $t7, 0x1c($sp) +; give bombs +0x00000040: jal 0x6fdcc +0x00000044: addiu $a1, $zero, 0x8e +0x00000048: b 0x7c +0x0000004c: lw $t7, 0x1c($sp) + +0x00000050: jal 0x6fdcc +0x00000054: addiu $a1, $zero, 0x8f +0x00000058: b 0x7c +0x0000005c: lw $t7, 0x1c($sp) + +0x00000060: jal 0x6fdcc +0x00000064: addiu $a1, $zero, 0x90 +0x00000068: b 0x7c +0x0000006c: lw $t7, 0x1c($sp) + +0x00000070: jal 0x6fdcc +0x00000074: addiu $a1, $zero, 0x91 +0x00000078: lw $t7, 0x1c($sp) +; subtract money +0x0000007c: lh $a0, 0x1b8($t7) +0x00000080: negu $a0, $a0 +0x00000084: sll $a0, $a0, 0x10 +0x00000088: jal 0x721cc +0x0000008c: sra $a0, $a0, 0x10 +0x00000090: lw $ra, 0x14($sp) +0x00000094: addiu $sp, $sp, 0x18 +0x00000098: jr $ra +0x0000009c: nop + + +func_0x00C0142C: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: lw $t6, 0x1c($sp) +0x00000010: addiu $at, $zero, 5 +0x00000014: lh $v0, 0x1ba($t6) +0x00000018: beq $v0, $at, 0x30 +0x0000001c: addiu $at, $zero, 0xa +0x00000020: beq $v0, $at, 0x40 +0x00000024: nop +0x00000028: b 0x4c +0x0000002c: lw $t7, 0x1c($sp) +0x00000030: jal 0x6fdcc +0x00000034: addiu $a1, $zero, 0x8c +0x00000038: b 0x4c +0x0000003c: lw $t7, 0x1c($sp) +0x00000040: jal 0x6fdcc +0x00000044: addiu $a1, $zero, 0x8d +0x00000048: lw $t7, 0x1c($sp) +0x0000004c: lh $a0, 0x1b8($t7) +0x00000050: negu $a0, $a0 +0x00000054: sll $a0, $a0, 0x10 +0x00000058: jal 0x721cc +0x0000005c: sra $a0, $a0, 0x10 +0x00000060: lw $ra, 0x14($sp) +0x00000064: addiu $sp, $sp, 0x18 +0x00000068: jr $ra +0x0000006c: nop + + +func_0x00C0149C: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: jal 0x6fdcc +0x00000010: move $a1, $zero +0x00000014: lw $t6, 0x1c($sp) +0x00000018: lh $a0, 0x1b8($t6) +0x0000001c: negu $a0, $a0 +0x00000020: sll $a0, $a0, 0x10 +0x00000024: jal 0x721cc +0x00000028: sra $a0, $a0, 0x10 +0x0000002c: lw $ra, 0x14($sp) +0x00000030: addiu $sp, $sp, 0x18 +0x00000034: jr $ra +0x00000038: nop + + +func_0x00C014D8: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: jal 0x6fad0 +0x00000010: nop +0x00000014: lw $t7, 0x1c($sp) +0x00000018: addiu $t6, $zero, 8 +0x0000001c: lui $at, 0x8012 +0x00000020: sh $t6, -0x59fa($at) +0x00000024: lh $a0, 0x1b8($t7) +0x00000028: negu $a0, $a0 +0x0000002c: sll $a0, $a0, 0x10 +0x00000030: jal 0x721cc +0x00000034: sra $a0, $a0, 0x10 +0x00000038: lw $ra, 0x14($sp) +0x0000003c: addiu $sp, $sp, 0x18 +0x00000040: jr $ra +0x00000044: nop + + +func_0x00C01520: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: jal 0x6fdcc +0x00000010: addiu $a1, $zero, 0x3f +0x00000014: lw $t6, 0x1c($sp) +0x00000018: lh $a0, 0x1b8($t6) +0x0000001c: negu $a0, $a0 +0x00000020: sll $a0, $a0, 0x10 +0x00000024: jal 0x721cc +0x00000028: sra $a0, $a0, 0x10 +0x0000002c: lw $ra, 0x14($sp) +0x00000030: addiu $sp, $sp, 0x18 +0x00000034: jr $ra +0x00000038: nop + + +func_0x00C0155C: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: jal 0x6fdcc +0x00000010: addiu $a1, $zero, 0x3e +0x00000014: lw $t6, 0x1c($sp) +0x00000018: lh $a0, 0x1b8($t6) +0x0000001c: negu $a0, $a0 +0x00000020: sll $a0, $a0, 0x10 +0x00000024: jal 0x721cc +0x00000028: sra $a0, $a0, 0x10 +0x0000002c: lw $ra, 0x14($sp) +0x00000030: addiu $sp, $sp, 0x18 +0x00000034: jr $ra +0x00000038: nop + + +func_0x00C01598: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: jal 0x6fdcc ; give goron tunic +0x00000010: addiu $a1, $zero, 0x42 ; a1 = goron tunic item +; subtract money +0x00000014: lw $t6, 0x1c($sp) ; t6 = actor +0x00000018: lh $a0, 0x1b8($t6) ; a0 = cost +0x0000001c: negu $a0, $a0 +0x00000020: sll $a0, $a0, 0x10 +0x00000024: jal 0x721cc +0x00000028: sra $a0, $a0, 0x10 +0x0000002c: lw $ra, 0x14($sp) +0x00000030: addiu $sp, $sp, 0x18 +0x00000034: jr $ra +0x00000038: nop + + +func_0x00C015D4: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: jal 0x6fdcc +0x00000010: addiu $a1, $zero, 0x43 +0x00000014: lw $t6, 0x1c($sp) +0x00000018: lh $a0, 0x1b8($t6) +0x0000001c: negu $a0, $a0 +0x00000020: sll $a0, $a0, 0x10 +0x00000024: jal 0x721cc +0x00000028: sra $a0, $a0, 0x10 +0x0000002c: lw $ra, 0x14($sp) +0x00000030: addiu $sp, $sp, 0x18 +0x00000034: jr $ra +0x00000038: nop + + +func_0x00C01610: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: lw $t6, 0x1c($sp) +0x00000010: jal 0x720bc +0x00000014: lh $a1, 0x1ba($t6) +0x00000018: lw $t7, 0x1c($sp) +0x0000001c: lh $a0, 0x1b8($t7) +0x00000020: negu $a0, $a0 +0x00000024: sll $a0, $a0, 0x10 +0x00000028: jal 0x721cc +0x0000002c: sra $a0, $a0, 0x10 +0x00000030: lw $ra, 0x14($sp) +0x00000034: addiu $sp, $sp, 0x18 +0x00000038: jr $ra +0x0000003c: nop + + +func_0x00C01650: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: jal 0x6fdcc +0x00000010: addiu $a1, $zero, 0x1a +0x00000014: lw $t6, 0x1c($sp) +0x00000018: lh $a0, 0x1b8($t6) +0x0000001c: negu $a0, $a0 +0x00000020: sll $a0, $a0, 0x10 +0x00000024: jal 0x721cc +0x00000028: sra $a0, $a0, 0x10 +0x0000002c: lw $ra, 0x14($sp) +0x00000030: addiu $sp, $sp, 0x18 +0x00000034: jr $ra +0x00000038: nop + + +func_0x00C0168C: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: jal 0x6fdcc +0x00000010: addiu $a1, $zero, 0x21 +0x00000014: lw $t6, 0x1c($sp) +0x00000018: lh $a0, 0x1b8($t6) +0x0000001c: negu $a0, $a0 +0x00000020: sll $a0, $a0, 0x10 +0x00000024: jal 0x721cc +0x00000028: sra $a0, $a0, 0x10 +0x0000002c: lw $ra, 0x14($sp) +0x00000030: addiu $sp, $sp, 0x18 +0x00000034: jr $ra +0x00000038: nop + + +func_0x00C016C8: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a0, 0x18($sp) +0x0000000c: lh $a0, 0x1b8($a1) +0x00000010: negu $a0, $a0 +0x00000014: sll $a0, $a0, 0x10 +0x00000018: jal 0x721cc +0x0000001c: sra $a0, $a0, 0x10 +0x00000020: lw $ra, 0x14($sp) +0x00000024: addiu $sp, $sp, 0x18 +0x00000028: jr $ra +0x0000002c: nop + + +func_0x00C016F8: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a0, 0x18($sp) +0x0000000c: lh $a0, 0x1b8($a1) +0x00000010: negu $a0, $a0 +0x00000014: sll $a0, $a0, 0x10 +0x00000018: jal 0x721cc +0x0000001c: sra $a0, $a0, 0x10 +0x00000020: lw $ra, 0x14($sp) +0x00000024: addiu $sp, $sp, 0x18 +0x00000028: jr $ra +0x0000002c: nop + + +func_0x00C01728: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: jal 0x6fdcc +0x00000010: addiu $a1, $zero, 0x95 +0x00000014: lw $t6, 0x1c($sp) +0x00000018: lh $a0, 0x1b8($t6) +0x0000001c: negu $a0, $a0 +0x00000020: sll $a0, $a0, 0x10 +0x00000024: jal 0x721cc +0x00000028: sra $a0, $a0, 0x10 +0x0000002c: lw $ra, 0x14($sp) +0x00000030: addiu $sp, $sp, 0x18 +0x00000034: jr $ra +0x00000038: nop + + +func_0x00C01764: +0x00000000: addiu $sp, $sp, -0x18 +0x00000004: sw $ra, 0x14($sp) +0x00000008: sw $a1, 0x1c($sp) +0x0000000c: lw $t6, 0x1c($sp) +0x00000010: lh $v0, 0x1c($t6) +0x00000014: slti $at, $v0, 0xa +0x00000018: bnez $at, 0x5c +0x0000001c: addiu $t7, $v0, -0x27 +0x00000020: slti $at, $v0, 0xb +0x00000024: bnez $at, 0x48 +0x00000028: sltiu $at, $t7, 5 +0x0000002c: beqz $at, 0x108 +0x00000030: sll $t7, $t7, 2 +0x00000034: lui $at, 0x8086 +0x00000038: addu $at, $at, $t7 +0x0000003c: lw $t7, 0x5070($at) +0x00000040: jr $t7 +0x00000044: nop +0x00000048: addiu $at, $zero, 0xa +0x0000004c: beq $v0, $at, 0xb0 +0x00000050: nop +0x00000054: b 0x10c +0x00000058: lw $t8, 0x1c($sp) +0x0000005c: addiu $at, $zero, 7 +0x00000060: beq $v0, $at, 0x80 +0x00000064: addiu $at, $zero, 8 +0x00000068: beq $v0, $at, 0x90 +0x0000006c: addiu $at, $zero, 9 +0x00000070: beq $v0, $at, 0xa0 +0x00000074: nop +0x00000078: b 0x10c +0x0000007c: lw $t8, 0x1c($sp) +; give item +0x00000080: jal 0x6fdcc +0x00000084: addiu $a1, $zero, 0x19 +0x00000088: b 0x10c +0x0000008c: lw $t8, 0x1c($sp) +0x00000090: jal 0x6fdcc +0x00000094: addiu $a1, $zero, 0x15 +0x00000098: b 0x10c +0x0000009c: lw $t8, 0x1c($sp) +0x000000a0: jal 0x6fdcc +0x000000a4: addiu $a1, $zero, 0x16 +0x000000a8: b 0x10c +0x000000ac: lw $t8, 0x1c($sp) +0x000000b0: jal 0x6fdcc +0x000000b4: addiu $a1, $zero, 0x17 +0x000000b8: b 0x10c +0x000000bc: lw $t8, 0x1c($sp) +0x000000c0: jal 0x6fdcc +0x000000c4: addiu $a1, $zero, 0x1c +0x000000c8: b 0x10c +0x000000cc: lw $t8, 0x1c($sp) +0x000000d0: jal 0x6fdcc +0x000000d4: addiu $a1, $zero, 0x1d +0x000000d8: b 0x10c +0x000000dc: lw $t8, 0x1c($sp) +0x000000e0: jal 0x6fdcc +0x000000e4: addiu $a1, $zero, 0x1e +0x000000e8: b 0x10c +0x000000ec: lw $t8, 0x1c($sp) +0x000000f0: jal 0x6fdcc +0x000000f4: addiu $a1, $zero, 0x20 +0x000000f8: b 0x10c +0x000000fc: lw $t8, 0x1c($sp) +0x00000100: jal 0x6fdcc +0x00000104: addiu $a1, $zero, 0x18 +;subtract money +0x00000108: lw $t8, 0x1c($sp) +0x0000010c: lh $a0, 0x1b8($t8) +0x00000110: negu $a0, $a0 +0x00000114: sll $a0, $a0, 0x10 +0x00000118: jal 0x721cc +0x0000011c: sra $a0, $a0, 0x10 +0x00000120: lw $ra, 0x14($sp) +0x00000124: addiu $sp, $sp, 0x18 +0x00000128: jr $ra +0x0000012c: nop + + + + + + + + + + + + + + + + + + + + + + + + + +------------------------------------------------------------------------------------------------------------ +Function_4 +------------------------------------------------------------------------------------------------------------ +;called when item is bought +;a0 = ??? +;a1 = actor +;----- +;no return +func_0x00C01894: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: lh t6, 0x1c(a1) ; t6 = actor variable +0x00000010: addiu at, zero, 0xc ; at = 0xc +0x00000014: lui t7, 0x8012 +0x00000018: bnel t6, at, 0x80 ; if var != 0xC Hylian Shield +0x0000001c: lh a0, 0x1b8(a1) ; a0 = cost + +0x00000020: lhu t7, -0x4b2a(t7) ; t7 = ??? +0x00000024: lui at, 0x8086 +0x00000028: andi t8, t7, 0x40 ; t8 = t7 & 0x40 +0x0000002c: beql t8, zero, 0x80 ; if not t8flag +0x00000030: lh a0, 0x1b8(a1) + +; hylian shield discount? +0x00000034: lwc1 f12, 0x5084(at) ; f12 = ??? +0x00000038: jal 0x26d64 +0x0000003c: sw a1, 0x1c(sp) +0x00000040: trunc.w.s f4, f0 +0x00000044: lw a1, 0x1c(sp) +0x00000048: lui t3, 0x8086 +0x0000004c: mfc1 t1, f4 +0x00000050: lh t9, 0x1b8(a1) +0x00000054: sll t2, t1, 1 +0x00000058: addu t3, t3, t2 +0x0000005c: lh t3, 0x502c(t3) +0x00000060: subu a0, t9, t3 +0x00000064: negu a0, a0 +0x00000068: sll a0, a0, 0x10 +0x0000006c: jal 0x721cc +0x00000070: sra a0, a0, 0x10 +0x00000074: b 0x94 +0x00000078: lw ra, 0x14(sp) + +0x0000007c: lh a0, 0x1b8(a1) ; unreachable +; subtract money +0x00000080: negu a0, a0 +0x00000084: sll a0, a0, 0x10 +0x00000088: jal 0x721cc +0x0000008c: sra a0, a0, 0x10 +0x00000090: lw ra, 0x14(sp) +0x00000094: addiu sp, sp, 0x18 +0x00000098: jr ra +0x0000009c: nop + +func_0x00C01934: +0x00000000: addiu sp, sp, -0x1b +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: lh a0, 0x1b8(a1) ; a0 = *(a1 + 0x1B8) +0x00000010: negu a0, a0 ; a0 = ~a0 +0x00000014: sll a0, a0, 0x10 ; a0 = a0 << 0x10 +0x00000018: jal 0x721cc +0x0000001c: sra a0, a0, 0x10 ; a0 = ~(*(a1 + 0x1B8)) & 0x0000FFFF +0x00000020: lw ra, 0x14(sp) +0x00000024: addiu sp, sp, 0x18 +0x00000028: jr ra +0x0000002c: nop + +func_0x00C01964: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: lh a0, 0x1b8(a1) +0x00000010: negu a0, a0 +0x00000014: sll a0, a0, 0x10 +0x00000018: jal 0x721cc +0x0000001c: sra a0, a0, 0x10 +0x00000020: lw ra, 0x14(sp) +0x00000024: addiu sp, sp, 0x18 +0x00000028: jr ra +0x0000002c: nop + +func_0x00C01994: +0x00000000: addiu sp, sp, -0x18 +0x00000004: sw ra, 0x14(sp) +0x00000008: sw a0, 0x18(sp) +0x0000000c: lh t6, 0x1c(a1) ; t6 = actor variable +0x00000010: addiu t7, t6, -0x15 ; t7 = t6 - 0x15 (bombchu index) +0x00000014: sltiu at, t7, 8 ; at = t7 < 8 +0x00000018: beqz at, 0xf0 ; if 0 >= bombchu index > 8 (not bombchu panic handler) +0x0000001c: sll t7, t7, 2 ; t7 = bombchu index << 2 +0x00000020: lui at, 0x8086 +0x00000024: addu at, at, t7 +0x00000028: lw t7, 0x5088(at) ; t7 = (??? + bombchu index) +0x0000002c: jr t7 ; jump to t7 +0x00000030: nop + +0x00000034: lui v0, 0x8012 +0x00000038: addiu v0, v0, -0x5a30 ; v0 = save context +0x0000003c: lhu t8, 0xef0(v0) ; t8 = item_get_flags +0x00000040: ori t9, t8, 0x40 ; t9 = t8 | bombchu_shot_slot_flag +0x00000044: b 0xf0 +0x00000048: sh t9, 0xef0(v0) ; + +0x0000004c: lui v0, 0x8012 +0x00000050: addiu v0, v0, -0x5a30 +0x00000054: lhu t0, 0xef0(v0) +0x00000058: ori t1, t0, 0x80 +0x0000005c: b 0xf0 +0x00000060: sh t1, 0xef0(v0) + +0x00000064: lui v0, 0x8012 +0x00000068: addiu v0, v0, -0x5a30 +0x0000006c: lhu t2, 0xef0(v0) +0x00000070: ori t3, t2, 0x100 +0x00000074: b 0xf0 +0x00000078: sh t3, 0xef0(v0) + +0x0000007c: lui v0, 0x8012 +0x00000080: addiu v0, v0, -0x5a30 +0x00000084: lhu t4, 0xef0(v0) +0x00000088: ori t5, t4, 0x200 +0x0000008c: b 0xf0 +0x00000090: sh t5, 0xef0(v0) + +0x00000094: lui v0, 0x8012 +0x00000098: addiu v0, v0, -0x5a30 +0x0000009c: lhu t6, 0xef0(v0) +0x000000a0: ori t7, t6, 0x400 +0x000000a4: b 0xf0 +0x000000a8: sh t7, 0xef0(v0) + +0x000000ac: lui v0, 0x8012 +0x000000b0: addiu v0, v0, -0x5a30 +0x000000b4: lhu t8, 0xef0(v0) +0x000000b8: ori t9, t8, 8 +0x000000bc: b 0xf0 +0x000000c0: sh t9, 0xef0(v0) + +0x000000c4: lui v0, 0x8012 +0x000000c8: addiu v0, v0, -0x5a30 +0x000000cc: lhu t0, 0xef0(v0) +0x000000d0: ori t1, t0, 0x10 +0x000000d4: b 0xf0 +0x000000d8: sh t1, 0xef0(v0) + +0x000000dc: lui v0, 0x8012 +0x000000e0: addiu v0, v0, -0x5a30 +0x000000e4: lhu t2, 0xef0(v0) +0x000000e8: ori t3, t2, 0x20 +0x000000ec: sh t3, 0xef0(v0) + +; subtract money +0x000000f0: lh a0, 0x1b8(a1) +0x000000f4: negu a0, a0 +0x000000f8: sll a0, a0, 0x10 +0x000000fc: jal 0x721cc +0x00000100: sra a0, a0, 0x10 +0x00000104: lw ra, 0x14(sp) +0x00000108: addiu sp, sp, 0x18 +0x0000010c: jr ra +0x00000110: nop + + +ext_func_0x721cc: ; add money +0x00000000: sw a0, (sp) +0x00000004: sll a0, a0, 0x10 +0x00000008: lui v0, 0x8012 +0x0000000c: addiu v0, v0, -0x5a30 +0x00000010: sra a0, a0, 0x10 +0x00000014: lh t6, 0x13cc(v0) +0x00000018: addu t7, t6, a0 +0x0000001c: sh t7, 0x13cc(v0) +0x00000020: jr ra +0x00000024: nop \ No newline at end of file diff --git a/OcarinaSongs.py b/OcarinaSongs.py new file mode 100644 index 000000000..927ef16c9 --- /dev/null +++ b/OcarinaSongs.py @@ -0,0 +1,379 @@ +PLAYBACK_START = 0xB781DC +PLAYBACK_LENGTH = 0xA0 +ACTIVATION_START = 0xB78E5C +ACTIVATION_LENGTH = 0x09 + +ACTIVATION_TO_PLAYBACK_NOTE = { + 0: 0x02, # A + 1: 0x05, # Down + 2: 0x09, # Right + 3: 0x0B, # Left + 4: 0x0E, # Up + 0xFF: 0xFF, # Rest +} + +import random +from Utils import random_choices + +# checks if one list is a sublist of the other (in either direction) +# python is magic..... +def subsong(song1, song2): + # convert both lists to strings + s1 = ''.join( map(chr, song1.activation)) + s2 = ''.join( map(chr, song2.activation)) + # check if either is a substring of the other + return (s1 in s2) or (s2 in s1) + +# give random durations and volumes to the notes +def fast_playback(activation): + playback = [] + for note_index, note in enumerate(activation): + playback.append( {'note': note, 'duration': 0x03, 'volume': 0x57} ) + return playback + +# give random durations and volumes to the notes +def random_playback(activation): + playback = [] + for note_index, note in enumerate(activation): + duration = random.randint(0x8, 0x20) + # make final note longer on average + if( note_index + 1 >= len(activation) ): + duration = random.randint(0x10, 0x30) + volume = random.randint(0x40, 0x60) + playback.append( {'note': note, 'duration': duration, 'volume': volume} ) + # randomly rest + if( random.random() < 0.1 ): + duration = random.randint(0x8, 0x18) + playback.append( {'note': 0xFF, 'duration': duration, 'volume': 0} ) + return playback + +# gives random volume and duration to the notes of piece +def random_piece_playback(piece): + playback = [] + for note in piece: + duration = random.randint(0x8, 0x20) + volume = random.randint(0x40, 0x60) + playback.append( {'note': note, 'duration': duration, 'volume': volume} ) + return playback + +# takes the volume/duration of playback, and notes of piece, and creates a playback piece +# assumes the lists are the same length +def copy_playback_info(playback, piece): + return [ { 'note': n, 'volume': p['volume'], 'duration': p['duration']} for (p, n) in zip(playback, piece) ] + +def identity(x): + return x + +def random_piece(count, allowed=range(0,5)): + return random_choices(allowed, k=count) + +def invert_piece(piece): + return [4 - note for note in piece] + +def reverse_piece(piece): + return piece[::-1] + +def clamp(val, low, high): + return max(low, min(high, val)) + +def transpose_piece(amount): + def transpose(piece): + return [clamp(note + amount, 0, 4) for note in piece] + return transpose + +def compose(f, g): + return lambda x: f(g(x)) + +def add_transform_to_piece(piece, transform): + return piece + transform(piece) + +def repeat(piece): + return 2 * piece + +# a Song contains it's simple note data, as well as the data to be stored into the rom +class Song(): + + def increase_duration_to(self, duration): + if self.total_duration >= duration: + return + + duration_needed = duration - self.total_duration + last_note_duration = self.playback[-1]['duration'] + last_note_adds = 0x7F - last_note_duration + + if last_note_adds >= duration_needed: + self.playback[-1]['duration'] += duration_needed + self.format_playback_data() + return + else: + self.playback[-1]['duration'] = 0x7F + duration_needed -= last_note_adds + while duration_needed >= 0x7F: + self.playback.append( {'note': 0xFF, 'duration': 0x7F, 'volume': 0} ) + duration_needed -= 0x7F + self.playback.append( {'note': 0xFF, 'duration': duration_needed, 'volume': 0} ) + self.format_playback_data() + + + def two_piece_playback(self, piece, extra_position='none', activation_transform=identity, playback_transform=identity): + piece_length = len(piece) + piece2 = activation_transform( piece ) + # add playback parameters + playback_piece1 = random_piece_playback(piece) + playback_piece2 = copy_playback_info(playback_transform(playback_piece1), piece2) + if extra_position == 'none': + self.length = 2 * piece_length + self.activation = piece + piece2 + # add a rest between + duration = random.randint(0x8, 0x18) + rest = {'note': 0xFF, 'duration': duration, 'volume': 0} + self.playback = playback_piece1 + [rest] + playback_piece2 + else: + self.length = 2 * piece_length + 1 + extra = random_piece(1) + extra_playback = random_piece_playback(extra) + if extra_position == 'start': + self.activation = extra + piece + piece2 + self.playback = extra_playback + playback_piece1 + playback_piece2 + elif extra_position == 'middle': + self.activation = piece + extra + piece2 + self.playback = playback_piece1 + extra_playback + playback_piece2 + elif extra_position == 'end': + self.activation = piece + piece2 + extra + self.playback = playback_piece1 + playback_piece2 + extra_playback + + # add rests between repeated notes in the playback so that they work in-game + def break_repeated_notes(self, duration=0x08): + new_playback = [] + for note_index, note in enumerate(self.playback): + new_playback.append(note) + if ( note_index + 1 < len(self.playback) ) and \ + ( self.playback[note_index]['note'] == self.playback[note_index + 1]['note'] ): + new_playback.append( {'note': 0xFF, 'duration': duration, 'volume': 0} ) + self.playback = new_playback + + # create the list of bytes that will be written into the rom for the activation + def format_activation_data(self): + # data is 1 byte for the song length, + # len bytes for the song, and the remainder is padding + padding = [0] * (ACTIVATION_LENGTH - (self.length + 1)) + self.activation_data = [self.length] + self.activation + padding + + # create the list of byte that will be written in to the rom for the playback + def format_playback_data(self): + self.playback_data = [] + + self.total_duration = 0 + for note in self.playback: + pitch = ACTIVATION_TO_PLAYBACK_NOTE[ note['note'] ] + self.playback_data += [pitch, 0, 0, note['duration'], note['volume'], 0, 0, 0] + self.total_duration += note['duration'] + # add a rest at the end + self.playback_data += [0xFF, 0, 0, 0, 0x5A, 0, 0, 0] + # pad the rest of the song + padding = [0] * (PLAYBACK_LENGTH - len(self.playback_data)) + self.playback_data += padding + + def display(self): + activation_string = 'Activation Data:\n\t' + ' '.join( map( "{:02x}".format, self.activation_data) ) + # break playback into groups of 8... + index = 0 + broken_up_playback = [] + while index < len(self.playback_data): + broken_up_playback.append( self.playback_data[index:index + 8]) + index += 8 + playback_string = 'Playback Data:\n\t' + '\n\t'.join( map( lambda line: ' '.join( map( "{:02x}".format, line) ), broken_up_playback ) ) + return activation_string + '\n' + playback_string + + # create a song, based on a given scheme + def __init__(self, rand_song=True, piece_size=3, extra_position='none', starting_range=range(0,5), activation_transform=identity, playback_transform=identity, activation=None): + if activation: + self.length = len(activation) + self.activation = activation + self.playback = fast_playback(self.activation) + self.break_repeated_notes(0x03) + self.format_playback_data() + self.increase_duration_to(45) + return + + if rand_song: + self.length = random.randint(4, 8) + self.activation = random_choices(range(0,5), k=self.length) + self.playback = random_playback(self.activation) + else: + if extra_position != 'none': + piece_size = 3 + piece = random_piece(piece_size, starting_range) + self.two_piece_playback(piece, extra_position, activation_transform, playback_transform) + + self.break_repeated_notes() + self.format_activation_data() + self.format_playback_data() + + __str__ = __repr__ = display + +# randomly choose song parameters +def get_random_song(): + + rand_song = random_choices([True, False], [1, 9])[0] + piece_size = random_choices([3, 4], [5, 2])[0] + extra_position = random_choices(['none', 'start', 'middle', 'end'], [12, 1, 1, 1])[0] + activation_transform = identity + playback_transform = identity + weight_damage = 0 + should_transpose = random_choices([True, False], [1, 4])[0] + starting_range=range(0,5) + if should_transpose: + weight_damage = 2 + direction = random_choices(['up', 'down'], [1, 1])[0] + if direction == 'up': + starting_range=range(0,4) + activation_transform = transpose_piece(1) + elif direction == 'down': + starting_range=range(1,5) + activation_transform = transpose_piece(-1) + should_invert = random_choices([True, False], [3 - weight_damage, 6])[0] + if should_invert: + weight_damage += 1 + activation_transform = compose(invert_piece, activation_transform) + should_reflect = random_choices([True, False], [5 - weight_damage, 4])[0] + if should_reflect: + activation_transform = compose(reverse_piece, activation_transform) + playback_transform = reverse_piece + + + # print([rand_song, piece_size, extra_position, starting_range, should_transpose, should_invert, should_reflect]) + + song = Song(rand_song, piece_size, extra_position, starting_range, activation_transform, playback_transform) + + # rate its difficulty + difficulty = 0 + difficulty = piece_size * 12 + if extra_position != 'none': + difficulty += 12 + if should_transpose: + difficulty += 25 + if should_reflect: + difficulty += 10 + if should_invert: + difficulty += 20 + if rand_song: + difficulty = 11 * len(song.activation) + + song.difficulty = difficulty + return song + + +# create a list of 12 songs, none of which are sub-strings of any other song +def generate_song_list(scarecrow_song=None): + songs = [] + + for _ in range(12): + while True: + # generate a completely random song + song = get_random_song() + # test the song against all existing songs + is_good = True + + for other_song in songs + [scarecrow_song] if scarecrow_song else songs: + if subsong(song, other_song): + is_good = False + if is_good: + songs.append(song) + break + + # sort the songs by length + songs.sort(key=lambda s: s.difficulty) + return songs + + + +# replace the playback and activation requirements for the ocarina songs +def replace_songs(rom, scarecrow_song=None): + songs = generate_song_list(scarecrow_song) + + #print('\n\n'.join(map(str, songs))) + + song_order = [ + 8, # zelda's lullaby + 6, # saria's song + 7, # epona's song + 11, # song of storms + 10, # song of time + 9, # sun's song + 5, # prelude of light + 0, # minuet of forest + 1, # bolero of fire + 2, # serenade of water + 3, # requiem of spirit + 4, # nocturne of shadow + ] + + for index, song in enumerate(songs): + + # fix the song of time + if song_order[index] == 10: + song.increase_duration_to(260) + + # write the song to the activation table + cur_offset = ACTIVATION_START + song_order[index] * ACTIVATION_LENGTH + rom.write_bytes(cur_offset, song.activation_data) + + # write the songs to the playback table + song_offset = PLAYBACK_START + song_order[index] * PLAYBACK_LENGTH + rom.write_bytes(song_offset, song.playback_data) + + +original_songs = [ + 'LURLUR', + 'ULRULR', + 'DRLDRL', + 'RDURDU', + 'RADRAD', + 'ADUADU', + 'AULRLR', + 'DADALDLD', + 'ADRRL', + 'ADALDA', + 'LRRALRD', + 'URURLU' +] + +note_map = { + 'A': 0, + 'D': 1, + 'R': 2, + 'L': 3, + 'U': 4 +} + +def verify_scarecrow_song_str(scarecrow_song_str:str, randomize_ocarina_songs:bool): + + if len(scarecrow_song_str) != 8: + raise Exception('Scarecrow Song must be 8 notes long') + + if len(set(scarecrow_song_str.upper())) == 1: + raise Exception('Scarecrow Song must contain at least two different notes') + + scarecrow_song = str_to_song(scarecrow_song_str) + + if not randomize_ocarina_songs: + for original_song in original_songs: + song_notes = [] + for c in original_song: + song_notes.append(note_map[c]) + song = Song(activation=song_notes) + + if subsong(scarecrow_song, song): + raise Exception('You may not have the Scarecrow Song contain an existing song') + + return scarecrow_song + +def str_to_song(song:str): + notes = [] + for c in song.upper(): + if c not in note_map: + raise Exception('Invalid note %s. Valid notes are A, D, R, L, U' % c) + + notes.append(note_map[c]) + return Song(activation=notes) diff --git a/OoTRandomizer.py b/OoTRandomizer.py index 44f0e8d93..0339c7fd6 100644 --- a/OoTRandomizer.py +++ b/OoTRandomizer.py @@ -8,7 +8,9 @@ from Gui import guiMain from Main import main -from Utils import is_bundled, close_console +from Utils import is_bundled, close_console, check_version, VersionError +from Patches import get_tunic_color_options, get_navi_color_options +from Settings import get_settings_from_command_line_args class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter): @@ -18,85 +20,8 @@ def _get_help_string(self, action): def start(): - parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) - parser.add_argument('--create_spoiler', help='Output a Spoiler File', action='store_true') - parser.add_argument('--bridge', default='medallions', const='medallions', nargs='?', choices=['medallions', 'vanilla', 'dungeons', 'open'], - help='''\ - Select requirement to spawn the Rainbow Bridge to reach Ganon's Castle. (default: %(default)s) - Medallions: Collect all six medallions to create the bridge. - Vanilla: Collect only the Shadow and Spirit Medallions and then view the Light Arrow cutscene. - All Dungeons: Collect all spiritual stones and all medallions to create the bridge. - Open: The bridge will spawn without an item requirement. - ''') - parser.add_argument('--rom', default='ZOOTDEC.z64', help='Path to an OoT 1.0 rom to use as a base.') - parser.add_argument('--loglevel', default='info', const='info', nargs='?', choices=['error', 'info', 'warning', 'debug'], help='Select level of logging for output.') - parser.add_argument('--seed', help='Define seed number to generate.', type=int) - parser.add_argument('--count', help='''\ - Use to batch generate multiple seeds with same settings. - If --seed is provided, it will be used for the first seed, then - used to derive the next seed (i.e. generating 10 seeds with - --seed given will produce the same 10 (different) roms each - time). - ''', type=int) - parser.add_argument('--open_forest', help='''\ - Mido no longer blocks the path to the Deku Tree and - the Kokiri boy no longer blocks the path out of the forest. - ''', action='store_true') - parser.add_argument('--open_door_of_time', help='''\ - The Door of Time is open from the beginning of the game. - ''', action='store_true') - parser.add_argument('--fast_ganon', help='''\ - The barrier within Ganon's Castle leading to Ganon's Tower is dispelled from the - beginning of the game, the Boss Key is not required in Ganon's Tower, Ganondorf - gives a hint for the location of Light Arrows, and the tower collapse sequence - is removed. - ''', action='store_true') - parser.add_argument('--nodungeonitems', help='''\ - Remove Maps and Compasses from Itempool, replacing them by - empty slots. - ''', action='store_true') - parser.add_argument('--beatableonly', help='''\ - Only check if the game is beatable with placement. Do not - ensure all locations are reachable. This only has an effect - on the restrictive algorithm currently. - ''', action='store_true') - parser.add_argument('--hints', help='''\ - Gossip Stones provide helpful hints about which items are - in inconvenient locations if the Stone of Agony is in - the player's inventory. - ''', action='store_true') - parser.add_argument('--kokiricolor', default='Kokiri Green', const='medallions', nargs='?', choices=['Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green', 'Random', 'True Random'], - help='''\ - Choose the color for Link's Kokiri Tunic. (default: %(default)s) - Color: Make the Kokiri Tunic this color. - Random: Choose a random color from this list of colors. - True Random: Choose a random color from any color the N64 can draw. - ''') - parser.add_argument('--goroncolor', default='Goron Red', const='medallions', nargs='?', choices=['Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green', 'Random', 'True Random'], - help='''\ - Choose the color for Link's Goron Tunic. (default: %(default)s) - Color: Make the Goron Tunic this color. - Random: Choose a random color from this list of colors. - True Random: Choose a random color from any color the N64 can draw. - ''') - parser.add_argument('--zoracolor', default='Zora Blue', const='medallions', nargs='?', choices=['Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green', 'Random', 'True Random'], - help='''\ - Choose the color for Link's Zora Tunic. (default: %(default)s) - Color: Make the Zora Tunic this color. - Random: Choose a random color from this list of colors. - True Random: Choose a random color from any color the N64 can draw. - ''') - parser.add_argument('--healthSFX', default='Default', const='Default', nargs='?', choices=['Default', 'Softer Beep', 'Rupee', 'Timer', 'Tamborine', 'Recovery Heart', 'Carrot Refill', 'Navi - Hey!', 'Zelda - Gasp', 'Cluck', 'Mweep!', 'Random', 'None'], - help='''\ - Select the sound effect that loops at low health. (default: %(default)s) - Sound: Replace the sound effect with the chosen sound. - Random: Replace the sound effect with a random sound from this list. - None: Eliminate heart beeps. - ''') - parser.add_argument('--suppress_rom', help='Do not create an output rom file.', action='store_true') - parser.add_argument('--compress_rom', help='Create a compressed version of the output rom file.', action='store_true') - parser.add_argument('--gui', help='Launch the GUI', action='store_true') - args = parser.parse_args() + + settings, gui, args_loglevel = get_settings_from_command_line_args() if is_bundled() and len(sys.argv) == 1: # for the bundled builds, if we have no arguments, the user @@ -108,23 +33,30 @@ def start(): sys.exit(0) # ToDo: Validate files further than mere existance - if not os.path.isfile(args.rom): - input('Could not find valid base rom for patching at expected path %s. Please run with -h to see help for further information. \nPress Enter to exit.' % args.rom) + if not os.path.isfile(settings.rom): + input('Could not find valid base rom for patching at expected path %s. Please run with -h to see help for further information. \nPress Enter to exit.' % settings.rom) sys.exit(1) # set up logger - loglevel = {'error': logging.ERROR, 'info': logging.INFO, 'warning': logging.WARNING, 'debug': logging.DEBUG}[args.loglevel] + loglevel = {'error': logging.ERROR, 'info': logging.INFO, 'warning': logging.WARNING, 'debug': logging.DEBUG}[args_loglevel] logging.basicConfig(format='%(message)s', level=loglevel) - if args.gui: - guiMain(args) - elif args.count is not None: - seed = args.seed - for _ in range(args.count): - main(seed=seed, args=args) - seed = random.randint(0, 999999999) + logger = logging.getLogger('') + if not settings.check_version: + try: + version_error = check_version(settings.checked_version) + except VersionError as e: + logger.warning(str(e)) + + if gui: + guiMain(settings) + elif settings.count is not None: + orig_seed = settings.seed + for i in range(settings.count): + settings.update_seed(orig_seed + '-' + str(i)) + main(settings) else: - main(seed=args.seed, args=args) + main(settings) if __name__ == '__main__': start() diff --git a/Patches.py b/Patches.py new file mode 100644 index 000000000..b86080a9e --- /dev/null +++ b/Patches.py @@ -0,0 +1,2027 @@ +import io +import json +import logging +import os +import platform +import struct +import subprocess +import random +import copy + +from Hints import writeGossipStoneHintsHints, buildBossRewardHints, buildGanonText, getSimpleHintNoPrefix +from Utils import data_path, default_output_path, random_choices +from Items import ItemFactory, item_data +from Messages import * +from OcarinaSongs import Song, str_to_song, replace_songs +from MQ import patch_files, File, update_dmadata, insert_space, add_relocations + +TunicColors = { + "Custom Color": [0, 0, 0], + "Kokiri Green": [0x1E, 0x69, 0x1B], + "Goron Red": [0x64, 0x14, 0x00], + "Zora Blue": [0x00, 0x3C, 0x64], + "Black": [0x30, 0x30, 0x30], + "White": [0xF0, 0xF0, 0xFF], + "Azure Blue": [0x13, 0x9E, 0xD8], + "Vivid Cyan": [0x13, 0xE9, 0xD8], + "Light Red": [0xF8, 0x7C, 0x6D], + "Fuchsia":[0xFF, 0x00, 0xFF], + "Purple": [0x95, 0x30, 0x80], + "MM Purple": [0x50, 0x52, 0x9A], + "Twitch Purple": [0x64, 0x41, 0xA5], + "Purple Heart": [0x8A, 0x2B, 0xE2], + "Persian Rose": [0xFF, 0x14, 0x93], + "Dirty Yellow": [0xE0, 0xD8, 0x60], + "Blush Pink": [0xF8, 0x6C, 0xF8], + "Hot Pink": [0xFF, 0x69, 0xB4], + "Rose Pink": [0xFF, 0x90, 0xB3], + "Orange": [0xE0, 0x79, 0x40], + "Gray": [0xA0, 0xA0, 0xB0], + "Gold": [0xD8, 0xB0, 0x60], + "Silver": [0xD0, 0xF0, 0xFF], + "Beige": [0xC0, 0xA0, 0xA0], + "Teal": [0x30, 0xD0, 0xB0], + "Blood Red": [0x83, 0x03, 0x03], + "Blood Orange": [0xFE, 0x4B, 0x03], + "Royal Blue": [0x40, 0x00, 0x90], + "Sonic Blue": [0x50, 0x90, 0xE0], + "NES Green": [0x00, 0xD0, 0x00], + "Dark Green": [0x00, 0x25, 0x18], + "Lumen": [80, 140, 240], +} + +NaviColors = { + "Custom Color": [0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00], + "Gold": [0xFE, 0xCC, 0x3C, 0xFF, 0xFE, 0xC0, 0x07, 0x00], + "White": [0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00], + "Green": [0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00], + "Light Blue": [0x96, 0x96, 0xFF, 0xFF, 0x96, 0x96, 0xFF, 0x00], + "Yellow": [0xFF, 0xFF, 0x00, 0xFF, 0xC8, 0x9B, 0x00, 0x00], + "Red": [0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00], + "Magenta": [0xFF, 0x00, 0xFF, 0xFF, 0xC8, 0x00, 0x9B, 0x00], + "Black": [0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00], + "Tatl": [0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0x98, 0x00, 0x00], + "Tael": [0x49, 0x14, 0x6C, 0xFF, 0xFF, 0x00, 0x00, 0x00], + "Fi": [0x2C, 0x9E, 0xC4, 0xFF, 0x2C, 0x19, 0x83, 0x00], + "Ciela": [0xE6, 0xDE, 0x83, 0xFF, 0xC6, 0xBE, 0x5B, 0x00], + "Epona": [0xD1, 0x49, 0x02, 0xFF, 0x55, 0x1F, 0x08, 0x00], + "Ezlo": [0x62, 0x9C, 0x5F, 0xFF, 0x3F, 0x5D, 0x37, 0x00], + "King of Red Lions": [0xA8, 0x33, 0x17, 0xFF, 0xDE, 0xD7, 0xC5, 0x00], + "Linebeck": [0x03, 0x26, 0x60, 0xFF, 0xEF, 0xFF, 0xFF, 0x00], + "Loftwing": [0xD6, 0x2E, 0x31, 0xFF, 0xFD, 0xE6, 0xCC, 0x00], + "Midna": [0x19, 0x24, 0x26, 0xFF, 0xD2, 0x83, 0x30, 0x00], + "Phantom Zelda": [0x97, 0x7A, 0x6C, 0xFF, 0x6F, 0x46, 0x67, 0x00], +} + +NaviSFX = { + 'None' : 0x0000, + 'Cluck' : 0x2812, + 'Rupee' : 0x4803, + 'Softer Beep' : 0x4804, + 'Recovery Heart': 0x480B, + 'Timer' : 0x481A, + 'Low Health' : 0x481B, + 'Notification' : 0x4820, + 'Tambourine' : 0x4842, + 'Carrot Refill' : 0x4845, + 'Zelda - Gasp' : 0x6879, + 'Mweep!' : 0x687A, + 'Ice Break' : 0x0875, + 'Explosion' : 0x180E, + 'Crate' : 0x2839, + 'Great Fairy' : 0x6858, + 'Moo' : 0x28DF, + 'Bark' : 0x28D8, + 'Ribbit' : 0x28B1, + 'Broken Pot' : 0x2887, + 'Cockadoodledoo': 0x2813, + 'Epona' : 0x2805, + 'Gold Skulltula': 0x39DA, + 'Redead' : 0x38E5, + 'Poe' : 0x38EC, + 'Ruto' : 0x6863, + 'Howl' : 0x28AE, + 'Business Scrub': 0x3882, + 'Guay' : 0x38B6, + 'H`lo!' : 0x6844 +} + +HealthSFX = { + 'None' : 0x0000, + 'Cluck' : 0x2812, + 'Softer Beep' : 0x4804, + 'Recovery Heart': 0x480B, + 'Timer' : 0x481A, + 'Notification' : 0x4820, + 'Tambourine' : 0x4842, + 'Carrot Refill' : 0x4845, + 'Navi - Random' : 0x6843, + 'Navi - Hey!' : 0x685F, + 'Zelda - Gasp' : 0x6879, + 'Mweep!' : 0x687A, + 'Iron Boots' : 0x080D, + 'Hammer' : 0x180A, + 'Sword Bounce' : 0x181A, + 'Bow' : 0x1830, + 'Gallop' : 0x2804, + 'Drawbridge' : 0x280E, + 'Switch' : 0x2815, + 'Bomb Bounce' : 0x282F, + 'Bark' : 0x28D8, + 'Ribbit' : 0x28B1, + 'Broken Pot' : 0x2887, + 'Business Scrub': 0x3882, + 'Guay' : 0x38B6, + 'Bongo Bongo' : 0x3950 +} + +def get_NaviSFX(): + return list(NaviSFX.keys()) + +def get_NaviSFX_options(): + return ["Default", "Random Choice"] + get_NaviSFX() + +def get_HealthSFX(): + return list(HealthSFX.keys()) + +def get_HealthSFX_options(): + return ["Default", "Random Choice"] + get_HealthSFX() + +def get_tunic_colors(): + return list(TunicColors.keys()) + +def get_tunic_color_options(): + return ["Random Choice", "Completely Random"] + get_tunic_colors() + +def get_navi_colors(): + return list(NaviColors.keys()) + +def get_navi_color_options(): + return ["Random Choice", "Completely Random"] + get_navi_colors() + +def patch_rom(world, rom): + with open(data_path('rom_patch.txt'), 'r') as stream: + for line in stream: + address, value = [int(x, 16) for x in line.split(',')] + rom.write_byte(address, value) + + # Write Randomizer title screen logo + with open(data_path('title.bin'), 'rb') as stream: + titleBytes = stream.read() + rom.write_bytes(0x01795300, titleBytes) + + # Increase the instance size of Bombchus prevent the heap from becoming corrupt when + # a Dodongo eats a Bombchu. Does not fix stale pointer issues with the animation + rom.write_int32(0xD6002C, 0x1F0) + + # Can always return to youth + rom.write_byte(0xCB6844, 0x35) + rom.write_byte(0x253C0E2, 0x03) # Moves sheik from pedestal + + # Fix child shooting gallery reward to be static + rom.write_bytes(0xD35EFC, [0x00, 0x00, 0x00, 0x00]) + + # Fix target in woods reward to be static + rom.write_bytes(0xE59CD4, [0x00, 0x00, 0x00, 0x00]) + + # Fix GS rewards to be static + rom.write_bytes(0xEA3934, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xEA3940 , [0x10, 0x00]) + + # Fix horseback archery rewards to be static + rom.write_byte(0xE12BA5, 0x00) + rom.write_byte(0xE12ADD, 0x00) + + # Fix adult shooting gallery reward to be static + rom.write_byte(0xD35F55, 0x00) + + # Fix deku theater rewards to be static + rom.write_bytes(0xEC9A7C, [0x00, 0x00, 0x00, 0x00]) #Sticks + rom.write_byte(0xEC9CD5, 0x00) #Nuts + + # Fix deku scrub who sells stick upgrade + rom.write_bytes(0xDF8060, [0x00, 0x00, 0x00, 0x00]) + + # Fix deku scrub who sells nut upgrade + rom.write_bytes(0xDF80D4, [0x00, 0x00, 0x00, 0x00]) + + # Fix rolling goron as child reward to be static + rom.write_bytes(0xED2960, [0x00, 0x00, 0x00, 0x00]) + + # Fix proximity text boxes (Navi) (Part 1) + rom.write_bytes(0xDF8B84, [0x00, 0x00, 0x00, 0x00]) + + # Fix final magic bean to cost 99 + rom.write_byte(0xE20A0F, 0x63) + rom.write_bytes(0x94FCDD, [0x08, 0x39, 0x39]) + + # Remove intro cutscene + rom.write_bytes(0xB06BBA, [0x00, 0x00]) + + # Remove locked door to Boss Key Chest in Fire Temple + if not world.keysanity and not world.dungeon_mq['FiT']: + rom.write_byte(0x22D82B7, 0x3F) + + # Change Bombchi Shop to be always open + rom.write_int32(0xC6CEDC, 0x240B0001) # li t3, 1 + + if world.bombchus_in_logic: + # Change Bowling Alley check to bombchus (Part 1) + rom.write_bytes(0x00E2D714, [0x81, 0xEF, 0xA6, 0x4C]) + rom.write_bytes(0x00E2D720, [0x24, 0x18, 0x00, 0x09, 0x11, 0xF8, 0x00, 0x06]) + + # Change Bowling Alley check to bombchus (Part 2) + rom.write_bytes(0x00E2D890, [0x81, 0x6B, 0xA6, 0x4C, 0x24, 0x0C, 0x00, 0x09, 0x51, 0x6C, 0x00, 0x0A]) + + # Cannot buy bombchu refills without Bombchus + rom.write_int32s(0xC01078, + [0x3C098012, # lui t1, 0x8012 + 0x812AA64C, # lb t2, -0x59B4(t1) ; bombchu item (SAVE_CONTEXT + 0x7C) + 0x340B0009, # li t3, 9 + 0x114B0002, # beq t2, t3, @@return ; if has bombchu, return 1 (can buy) + 0x34020000, # li v0, 0 + 0x34020002]) # li v0, 2 ; else, return 2 (can't buy) + else: + # Change Bowling Alley check to Bomb Bag (Part 1) + rom.write_bytes(0x00E2D716, [0xA6, 0x72]) + rom.write_byte(0x00E2D723, 0x18) + + # Change Bowling Alley check to Bomb Bag (Part 2) + rom.write_bytes(0x00E2D892, [0xA6, 0x72]) + rom.write_byte(0x00E2D897, 0x18) + + # Cannot buy bombchu refills without Bomb Bag + rom.write_int32s(0xC01078, + [0x3C098012, # lui t1, 0x8012 + 0x812AA673, # lb t2, -0x598D(t1) ; bombbag size (SAVE_CONTEXT + 0xA3) + 0x314A0038, # andi t2, t2, 0x38 + 0x15400002, # bnez t2, @@return ; If has bombbag, return 1 (can buy) + 0x24020000, # li v0, 0 + 0x24020002]) # li v0, 2 ; else, return 2, (can't buy) + + # Change Bazaar check to Bomb Bag (Child?) + rom.write_bytes(0x00C0082A, [0x00, 0x18]) + rom.write_bytes(0x00C0082C, [0x00, 0x0E, 0X74, 0X02]) + rom.write_byte(0x00C00833, 0xA0) + + # Change Bazaar check to Bomb Bag (Adult?) + rom.write_bytes(0x00DF7A8E, [0x00, 0x18]) + rom.write_bytes(0x00DF7A90, [0x00, 0x0E, 0X74, 0X02]) + rom.write_byte(0x00DF7A97, 0xA0) + + # Change Goron Shop check to Bomb Bag + rom.write_bytes(0x00C6ED86, [0x00, 0xA2]) + rom.write_bytes(0x00C6ED8A, [0x00, 0x18]) + + # Change graveyard graves to not allow grabbing on to the ledge + rom.write_byte(0x0202039D, 0x20) + rom.write_byte(0x0202043C, 0x24) + + # Fix Link the Goron to always work + rom.write_bytes(0xED2FAC, [0x80, 0x6E, 0x0F, 0x18]) + rom.write_bytes(0xED2FEC, [0x24, 0x0A, 0x00, 0x00]) + rom.write_bytes(0xAE74D8, [0x24, 0x0E, 0x00, 0x00]) + + # Fix King Zora Thawed to always work + rom.write_bytes(0xE55C4C, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xE56290, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xE56298, [0x00, 0x00, 0x00, 0x00]) + + # Fix Castle Courtyard to check for meeting Zelda, not Zelda fleeing, to block you + rom.write_bytes(0xCD5E76, [0x0E, 0xDC]) + rom.write_bytes(0xCD5E12, [0x0E, 0xDC]) + + # Cutscene for all medallions never triggers when leaving shadow or spirit temples(hopefully stops warp to colossus on shadow completion with boss reward shuffle) + rom.write_byte(0xACA409, 0xAD) + rom.write_byte(0xACA49D, 0xCE) + + # Speed Zelda's Letter scene + rom.write_bytes(0x290E08E, [0x05, 0xF0]) + rom.write_byte(0xEFCBA7, 0x08) + rom.write_byte(0xEFE7C7, 0x05) + #rom.write_byte(0xEFEAF7, 0x08) + #rom.write_byte(0xEFE7C7, 0x05) + rom.write_bytes(0xEFE938, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xEFE948, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xEFE950, [0x00, 0x00, 0x00, 0x00]) + + # Speed Zelda escaping from Hyrule Castle + Block_code = [0x00, 0x00, 0x00, 0x01, 0x00, 0x21, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02] + rom.write_bytes(0x1FC0CF8, Block_code) + + # Speed learning Zelda's Lullaby + rom.write_int32s(0x02E8E90C, [0x000003E8, 0x00000001]) # Terminator Execution + if world.shuffle_song_items: + rom.write_int16s(None, [0x0073, 0x001, 0x0002, 0x0002]) # ID, start, end, end + else: + rom.write_int16s(None, [0x0073, 0x003B, 0x003C, 0x003C]) # ID, start, end, end + + + rom.write_int32s(0x02E8E91C, [0x00000013, 0x0000000C]) # Textbox, Count + if world.shuffle_song_items: + rom.write_int16s(None, [0xFFFF, 0x0000, 0x0010, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + else: + rom.write_int16s(None, [0x0017, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x00D4, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + # Speed learning Sun's Song + if world.shuffle_song_items: + rom.write_int32(0x0332A4A4, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x0332A4A4, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x0332A868, [0x00000013, 0x00000008]) # Textbox, Count + rom.write_int16s(None, [0x0018, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x00D3, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + # Speed learning Saria's Song + if world.shuffle_song_items: + rom.write_int32(0x020B1734, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x020B1734, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x20B1DA8, [0x00000013, 0x0000000C]) # Textbox, Count + rom.write_int16s(None, [0x0015, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x00D1, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x020B19C0, [0x0000000A, 0x00000006]) # Link, Count + rom.write_int16s(0x020B19C8, [0x0011, 0x0000, 0x0010, 0x0000]) #action, start, end, ???? + rom.write_int16s(0x020B19F8, [0x003E, 0x0011, 0x0020, 0x0000]) #action, start, end, ???? + rom.write_int32s(None, [0x80000000, # ??? + 0x00000000, 0x000001D4, 0xFFFFF731, # start_XYZ + 0x00000000, 0x000001D4, 0xFFFFF712]) # end_XYZ + + # Speed learning Epona's Song + rom.write_int32s(0x029BEF60, [0x000003E8, 0x00000001]) # Terminator Execution + if world.shuffle_song_items: + rom.write_int16s(None, [0x005E, 0x0001, 0x0002, 0x0002]) # ID, start, end, end + else: + rom.write_int16s(None, [0x005E, 0x000A, 0x000B, 0x000B]) # ID, start, end, end + + rom.write_int32s(0x029BECB0, [0x00000013, 0x00000002]) # Textbox, Count + if world.shuffle_song_items: + rom.write_int16s(None, [0xFFFF, 0x0000, 0x0009, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + else: + rom.write_int16s(None, [0x00D2, 0x0000, 0x0009, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0xFFFF, 0x000A, 0x003C, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + # Speed learning Song of Time + rom.write_int32s(0x0252FB98, [0x000003E8, 0x00000001]) # Terminator Execution + if world.shuffle_song_items: + rom.write_int16s(None, [0x0035, 0x0001, 0x0002, 0x0002]) # ID, start, end, end + else: + rom.write_int16s(None, [0x0035, 0x003B, 0x003C, 0x003C]) # ID, start, end, end + + rom.write_int32s(0x0252FC80, [0x00000013, 0x0000000C]) # Textbox, Count + if world.shuffle_song_items: + rom.write_int16s(None, [0xFFFF, 0x0000, 0x0010, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + else: + rom.write_int16s(None, [0x0019, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x00D5, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32(0x01FC3B84, 0xFFFFFFFF) # Other Header?: frame_count + + # Speed learning Song of Storms + if world.shuffle_song_items: + rom.write_int32(0x03041084, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x03041084, 0x0000000A) # Header: frame_count + + rom.write_int32s(0x03041088, [0x00000013, 0x00000002]) # Textbox, Count + rom.write_int16s(None, [0x00D6, 0x0000, 0x0009, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0xFFFF, 0x00BE, 0x00C8, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + # Speed learning Minuet of Forest + if world.shuffle_song_items: + rom.write_int32(0x020AFF84, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x020AFF84, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x020B0800, [0x00000013, 0x0000000A]) # Textbox, Count + rom.write_int16s(None, [0x000F, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x0073, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x020AFF88, [0x0000000A, 0x00000005]) # Link, Count + rom.write_int16s(0x020AFF90, [0x0011, 0x0000, 0x0010, 0x0000]) #action, start, end, ???? + rom.write_int16s(0x020AFFC1, [0x003E, 0x0011, 0x0020, 0x0000]) #action, start, end, ???? + + rom.write_int32s(0x020B0488, [0x00000056, 0x00000001]) # Music Change, Count + rom.write_int16s(None, [0x003F, 0x0021, 0x0022, 0x0000]) #action, start, end, ???? + + rom.write_int32s(0x020B04C0, [0x0000007C, 0x00000001]) # Music Fade Out, Count + rom.write_int16s(None, [0x0004, 0x0000, 0x0000, 0x0000]) #action, start, end, ???? + + # Speed learning Bolero of Fire + if world.shuffle_song_items: + rom.write_int32(0x0224B5D4, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x0224B5D4, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x0224D7E8, [0x00000013, 0x0000000A]) # Textbox, Count + rom.write_int16s(None, [0x0010, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x0074, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x0224B5D8, [0x0000000A, 0x0000000B]) # Link, Count + rom.write_int16s(0x0224B5E0, [0x0011, 0x0000, 0x0010, 0x0000]) #action, start, end, ???? + rom.write_int16s(0x0224B610, [0x003E, 0x0011, 0x0020, 0x0000]) #action, start, end, ???? + + rom.write_int32s(0x0224B7F0, [0x0000002F, 0x0000000E]) # Sheik, Count + rom.write_int16s(0x0224B7F8, [0x0000]) #action + rom.write_int16s(0x0224B828, [0x0000]) #action + rom.write_int16s(0x0224B858, [0x0000]) #action + rom.write_int16s(0x0224B888, [0x0000]) #action + + # Speed learning Serenade of Water + if world.shuffle_song_items: + rom.write_int32(0x02BEB254, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x02BEB254, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x02BEC880, [0x00000013, 0x00000010]) # Textbox, Count + rom.write_int16s(None, [0x0011, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x0075, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x02BEB258, [0x0000000A, 0x0000000F]) # Link, Count + rom.write_int16s(0x02BEB260, [0x0011, 0x0000, 0x0010, 0x0000]) #action, start, end, ???? + rom.write_int16s(0x02BEB290, [0x003E, 0x0011, 0x0020, 0x0000]) #action, start, end, ???? + + rom.write_int32s(0x02BEB530, [0x0000002F, 0x00000006]) # Sheik, Count + rom.write_int16s(0x02BEB538, [0x0000, 0x0000, 0x018A, 0x0000]) #action, start, end, ???? + rom.write_int32s(None, [0x1BBB0000, # ??? + 0xFFFFFB10, 0x8000011A, 0x00000330, # start_XYZ + 0xFFFFFB10, 0x8000011A, 0x00000330]) # end_XYZ + + rom.write_int32s(0x02BEC848, [0x00000056, 0x00000001]) # Music Change, Count + rom.write_int16s(None, [0x0059, 0x0021, 0x0022, 0x0000]) #action, start, end, ???? + + # Speed learning Nocturne of Shadow + rom.write_int32s(0x01FFE458, [0x000003E8, 0x00000001]) # Other Scene? Terminator Execution + rom.write_int16s(None, [0x002F, 0x0001, 0x0002, 0x0002]) # ID, start, end, end + + rom.write_int32(0x01FFFDF4, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x02000FD8, [0x00000013, 0x0000000E]) # Textbox, Count + if world.shuffle_song_items: + rom.write_int16s(None, [0xFFFF, 0x0000, 0x0010, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + else: + rom.write_int16s(None, [0x0013, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x0077, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x02000128, [0x000003E8, 0x00000001]) # Terminator Execution + if world.shuffle_song_items: + rom.write_int16s(None, [0x0032, 0x0001, 0x0002, 0x0002]) # ID, start, end, end + else: + rom.write_int16s(None, [0x0032, 0x003A, 0x003B, 0x003B]) # ID, start, end, end + + # Speed learning Requiem of Spirit + rom.write_int32(0x0218AF14, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x0218C574, [0x00000013, 0x00000008]) # Textbox, Count + if world.shuffle_song_items: + rom.write_int16s(None, [0xFFFF, 0x0000, 0x0010, 0xFFFF, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + else: + rom.write_int16s(None, [0x0012, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x0076, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x0218B478, [0x000003E8, 0x00000001]) # Terminator Execution + if world.shuffle_song_items: + rom.write_int16s(None, [0x0030, 0x0001, 0x0002, 0x0002]) # ID, start, end, end + else: + rom.write_int16s(None, [0x0030, 0x003A, 0x003B, 0x003B]) # ID, start, end, end + + rom.write_int32s(0x0218AF18, [0x0000000A, 0x0000000B]) # Link, Count + rom.write_int16s(0x0218AF20, [0x0011, 0x0000, 0x0010, 0x0000]) #action, start, end, ???? + rom.write_int32s(None, [0x40000000, # ??? + 0xFFFFFAF9, 0x00000008, 0x00000001, # start_XYZ + 0xFFFFFAF9, 0x00000008, 0x00000001, # end_XYZ + 0x0F671408, 0x00000000, 0x00000001]) # normal_XYZ + rom.write_int16s(0x0218AF50, [0x003E, 0x0011, 0x0020, 0x0000]) #action, start, end, ???? + + # Speed learning Prelude of Light + if world.shuffle_song_items: + rom.write_int32(0x0252FD24, 0xFFFFFFFF) # Header: frame_count + else: + rom.write_int32(0x0252FD24, 0x0000003C) # Header: frame_count + + rom.write_int32s(0x02531320, [0x00000013, 0x0000000E]) # Textbox, Count + rom.write_int16s(None, [0x0014, 0x0000, 0x0010, 0x0002, 0x088B, 0xFFFF]) # ID, start, end, type, alt1, alt2 + rom.write_int16s(None, [0x0078, 0x0011, 0x0020, 0x0000, 0xFFFF, 0xFFFF]) # ID, start, end, type, alt1, alt2 + + rom.write_int32s(0x0252FF10, [0x0000002F, 0x00000009]) # Sheik, Count + rom.write_int16s(0x0252FF18, [0x0006, 0x0000, 0x0000, 0x0000]) #action, start, end, ???? + + rom.write_int32s(0x025313D0, [0x00000056, 0x00000001]) # Music Change, Count + rom.write_int16s(None, [0x003B, 0x0021, 0x0022, 0x0000]) #action, start, end, ???? + + # Speed scene after Deku Tree + rom.write_bytes(0x2077E20, [0x00, 0x07, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + rom.write_bytes(0x2078A10, [0x00, 0x0E, 0x00, 0x1F, 0x00, 0x20, 0x00, 0x20]) + Block_code = [0x00, 0x80, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x1E, 0x00, 0x28, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] + rom.write_bytes(0x2079570, Block_code) + + # Speed scene after Dodongo's Cavern + rom.write_bytes(0x2221E88, [0x00, 0x0C, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0x2223308, [0x00, 0x81, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + + # Speed scene after Jabu Jabu's Belly + rom.write_bytes(0xCA3530, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0x2113340, [0x00, 0x0D, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0x2113C18, [0x00, 0x82, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + rom.write_bytes(0x21131D0, [0x00, 0x01, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x3C]) + + # Speed scene after Forest Temple + rom.write_bytes(0xD4ED68, [0x00, 0x45, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0xD4ED78, [0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + rom.write_bytes(0x207B9D4, [0xFF, 0xFF, 0xFF, 0xFF]) + + # Speed scene after Fire Temple + rom.write_bytes(0x2001848, [0x00, 0x1E, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + rom.write_bytes(0xD100B4, [0x00, 0x62, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0xD10134, [0x00, 0x3C, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + + # Speed scene after Water Temple + rom.write_bytes(0xD5A458, [0x00, 0x15, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0xD5A3A8, [0x00, 0x3D, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + rom.write_bytes(0x20D0D20, [0x00, 0x29, 0x00, 0xC7, 0x00, 0xC8, 0x00, 0xC8]) + + # Speed scene after Shadow Temple + rom.write_bytes(0xD13EC8, [0x00, 0x61, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0xD13E18, [0x00, 0x41, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + + # Speed scene after Spirit Temple + rom.write_bytes(0xD3A0A8, [0x00, 0x60, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) + rom.write_bytes(0xD39FF0, [0x00, 0x3F, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) + + # Speed Nabooru defeat scene + rom.write_bytes(0x2F5AF84, [0x00, 0x00, 0x00, 0x05]) + rom.write_bytes(0x2F5C7DA, [0x00, 0x01, 0x00, 0x02]) + rom.write_bytes(0x2F5C7A2, [0x00, 0x03, 0x00, 0x04]) + rom.write_byte(0x2F5B369, 0x09) + rom.write_byte(0x2F5B491, 0x04) + rom.write_byte(0x2F5B559, 0x04) + rom.write_byte(0x2F5B621, 0x04) + rom.write_byte(0x2F5B761, 0x07) + + # Speed scene with all medallions + rom.write_bytes(0x2512680, [0x00, 0x74, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + + # Speed collapse of Ganon's Tower + rom.write_bytes(0x33FB328, [0x00, 0x76, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + + # Speed Phantom Ganon defeat scene + rom.write_bytes(0xC944D8, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xC94548, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xC94730, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xC945A8, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xC94594, [0x00, 0x00, 0x00, 0x00]) + + # Speed Twinrova defeat scene + rom.write_bytes(0xD678CC, [0x24, 0x01, 0x03, 0xA2, 0xA6, 0x01, 0x01, 0x42]) + rom.write_bytes(0xD67BA4, [0x10, 0x00]) + + # Speed scenes during final battle + # Ganondorf battle end + rom.write_byte(0xD82047, 0x09) + # Zelda descends + rom.write_byte(0xD82AB3, 0x66) + rom.write_byte(0xD82FAF, 0x65) + rom.write_bytes(0xD82D2E, [0x04, 0x1F]) + rom.write_bytes(0xD83142, [0x00, 0x6B]) + rom.write_bytes(0xD82DD8, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xD82ED4, [0x00, 0x00, 0x00, 0x00]) + rom.write_byte(0xD82FDF, 0x33) + # After tower collapse + rom.write_byte(0xE82E0F, 0x04) + # Ganon intro + rom.write_bytes(0xE83D28, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xE83B5C, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xE84C80, [0x10, 0x00]) + + # Speed completion of the trials in Ganon's Castle + rom.write_bytes(0x31A8090, [0x00, 0x6B, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) #Forest + rom.write_bytes(0x31A9E00, [0x00, 0x6E, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) #Fire + rom.write_bytes(0x31A8B18, [0x00, 0x6C, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) #Water + rom.write_bytes(0x31A9430, [0x00, 0x6D, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) #Shadow + rom.write_bytes(0x31AB200, [0x00, 0x70, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) #Spirit + rom.write_bytes(0x31AA830, [0x00, 0x6F, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) #Light + + # Speed obtaining Fairy Ocarina + rom.write_bytes(0x2150CD0, [0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x30]) + Block_code = [0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x3C, 0x00, 0x81, 0xFF, 0xFF] + rom.write_bytes(0x2151240, Block_code) + rom.write_bytes(0x2150E20, [0xFF, 0xFF, 0xFA, 0x4C]) + + # Speed Zelda Light Arrow cutscene + rom.write_bytes(0x2531B40, [0x00, 0x28, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + rom.write_bytes(0x2532FBC, [0x00, 0x75]) + rom.write_bytes(0x2532FEA, [0x00, 0x75, 0x00, 0x80]) + rom.write_byte(0x2533115, 0x05) + rom.write_bytes(0x2533141, [0x06, 0x00, 0x06, 0x00, 0x10]) + rom.write_bytes(0x2533171, [0x0F, 0x00, 0x11, 0x00, 0x40]) + rom.write_bytes(0x25331A1, [0x07, 0x00, 0x41, 0x00, 0x65]) + rom.write_bytes(0x2533642, [0x00, 0x50]) + rom.write_byte(0x253389D, 0x74) + rom.write_bytes(0x25338A4, [0x00, 0x72, 0x00, 0x75, 0x00, 0x79]) + rom.write_bytes(0x25338BC, [0xFF, 0xFF]) + rom.write_bytes(0x25338C2, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]) + rom.write_bytes(0x25339C2, [0x00, 0x75, 0x00, 0x76]) + rom.write_bytes(0x2533830, [0x00, 0x31, 0x00, 0x81, 0x00, 0x82, 0x00, 0x82]) + + # Speed Bridge of Light cutscene + rom.write_bytes(0x292D644, [0x00, 0x00, 0x00, 0xA0]) + rom.write_bytes(0x292D680, [0x00, 0x02, 0x00, 0x0A, 0x00, 0x6C, 0x00, 0x00]) + rom.write_bytes(0x292D6E8, [0x00, 0x27]) + rom.write_bytes(0x292D718, [0x00, 0x32]) + rom.write_bytes(0x292D810, [0x00, 0x02, 0x00, 0x3C]) + rom.write_bytes(0x292D924, [0xFF, 0xFF, 0x00, 0x14, 0x00, 0x96, 0xFF, 0xFF]) + + # Remove remaining owls + rom.write_bytes(0x1FE30CE, [0x01, 0x4B]) + rom.write_bytes(0x1FE30DE, [0x01, 0x4B]) + rom.write_bytes(0x1FE30EE, [0x01, 0x4B]) + rom.write_bytes(0x205909E, [0x00, 0x3F]) + rom.write_byte(0x2059094, 0x80) + + # Darunia won't dance + rom.write_bytes(0x22769E4, [0xFF, 0xFF, 0xFF, 0xFF]) + + # Zora moves quickly + rom.write_bytes(0xE56924, [0x00, 0x00, 0x00, 0x00]) + + # Speed Jabu Jabu swallowing Link + rom.write_bytes(0xCA0784, [0x00, 0x18, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + + # Ruto no longer points to Zora Sapphire + rom.write_bytes(0xD03BAC, [0xFF, 0xFF, 0xFF, 0xFF]) + + # Ruto never disappears from Jabu Jabu's Belly + rom.write_byte(0xD01EA3, 0x00) + + # Speed up Epona race start + rom.write_bytes(0x29BE984, [0x00, 0x00, 0x00, 0x02]) + rom.write_bytes(0x29BE9CA, [0x00, 0x01, 0x00, 0x02]) + + # Speed start of Horseback Archery + #rom.write_bytes(0x21B2064, [0x00, 0x00, 0x00, 0x02]) + #rom.write_bytes(0x21B20AA, [0x00, 0x01, 0x00, 0x02]) + + # Speed up Epona escape + rom.write_bytes(0x1FC8B36, [0x00, 0x2A]) + + # Speed up draining the well + rom.write_bytes(0xE0A010, [0x00, 0x2A, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) + rom.write_bytes(0x2001110, [0x00, 0x2B, 0x00, 0xB7, 0x00, 0xB8, 0x00, 0xB8]) + + # Speed up opening the royal tomb for both child and adult + rom.write_bytes(0x2025026, [0x00, 0x01]) + rom.write_bytes(0x2023C86, [0x00, 0x01]) + rom.write_byte(0x2025159, 0x02) + rom.write_byte(0x2023E19, 0x02) + + #Speed opening of Door of Time + rom.write_bytes(0xE0A176, [0x00, 0x02]) + rom.write_bytes(0xE0A35A, [0x00, 0x01, 0x00, 0x02]) + + # Poacher's Saw no longer messes up Deku Theater + rom.write_bytes(0xAE72CC, [0x00, 0x00, 0x00, 0x00]) + + # Learning Serenade tied to opening chest in room + Block_code = [0x3C, 0x0F, 0x80, 0x1D, 0x81, 0xE8, 0xA1, 0xDB, 0x24, 0x19, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0xA2, 0x1C, 0x44, + 0x00, 0x00, 0x00, 0x00] + rom.write_bytes(0xC7BCF0, Block_code) + + # Dampe Chest spawn condition looks at chest flag instead of having obtained hookshot + Block_code = [0x93, 0x18, 0xAE, 0x7E, 0x27, 0xA5, 0x00, 0x24, 0x33, 0x19, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00] + rom.write_bytes(0xDFEC40, Block_code) + + # Darunia sets an event flag and checks for it + Block_code = [0x24, 0x19, 0x00, 0x40, 0x8F, 0x09, 0xB4, 0xA8, 0x01, 0x39, 0x40, 0x24, + 0x01, 0x39, 0xC8, 0x25, 0xAF, 0x19, 0xB4, 0xA8, 0x24, 0x09, 0x00, 0x06] + rom.write_bytes(0xCF1AB8, Block_code) + + # Change Prelude CS to check for medallion + rom.write_bytes(0x00C805E6, [0x00, 0xA6]) + rom.write_bytes(0x00C805F2, [0x00, 0x01]) + + # Change Nocturne CS to check for medallions + rom.write_bytes(0x00ACCD8E, [0x00, 0xA6]) + rom.write_bytes(0x00ACCD92, [0x00, 0x01]) + rom.write_bytes(0x00ACCD9A, [0x00, 0x02]) + rom.write_bytes(0x00ACCDA2, [0x00, 0x04]) + + # Change King Zora to move even if Zora Sapphire is in inventory + rom.write_bytes(0x00E55BB0, [0x85, 0xCE, 0x8C, 0x3C]) + rom.write_bytes(0x00E55BB4, [0x84, 0x4F, 0x0E, 0xDA]) + + # Remove extra Forest Temple medallions + rom.write_bytes(0x00D4D37C, [0x00, 0x00, 0x00, 0x00]) + + # Remove extra Fire Temple medallions + rom.write_bytes(0x00AC9754, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0x00D0DB8C, [0x00, 0x00, 0x00, 0x00]) + + # Remove extra Water Temple medallions + rom.write_bytes(0x00D57F94, [0x00, 0x00, 0x00, 0x00]) + + # Remove extra Spirit Temple medallions + rom.write_bytes(0x00D370C4, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0x00D379C4, [0x00, 0x00, 0x00, 0x00]) + + # Remove extra Shadow Temple medallions + rom.write_bytes(0x00D116E0, [0x00, 0x00, 0x00, 0x00]) + + # Change Mido, Saria, and Kokiri to check for Deku Tree complete flag + # bitwise pointer for 0x80 + kokiriAddresses = [0xE52836, 0xE53A56, 0xE51D4E, 0xE51F3E, 0xE51D96, 0xE51E1E, 0xE51E7E, 0xE51EDE, 0xE51FC6, 0xE51F96, 0xE293B6, 0xE29B8E, 0xE62EDA, 0xE630D6, 0xE62642, 0xE633AA, 0xE6369E] + for kokiri in kokiriAddresses: + rom.write_bytes(kokiri, [0x8C, 0x0C]) + # Kokiri + rom.write_bytes(0xE52838, [0x94, 0x48, 0x0E, 0xD4]) + rom.write_bytes(0xE53A58, [0x94, 0x49, 0x0E, 0xD4]) + rom.write_bytes(0xE51D50, [0x94, 0x58, 0x0E, 0xD4]) + rom.write_bytes(0xE51F40, [0x94, 0x4B, 0x0E, 0xD4]) + rom.write_bytes(0xE51D98, [0x94, 0x4B, 0x0E, 0xD4]) + rom.write_bytes(0xE51E20, [0x94, 0x4A, 0x0E, 0xD4]) + rom.write_bytes(0xE51E80, [0x94, 0x59, 0x0E, 0xD4]) + rom.write_bytes(0xE51EE0, [0x94, 0x4E, 0x0E, 0xD4]) + rom.write_bytes(0xE51FC8, [0x94, 0x49, 0x0E, 0xD4]) + rom.write_bytes(0xE51F98, [0x94, 0x58, 0x0E, 0xD4]) + # Saria + rom.write_bytes(0xE293B8, [0x94, 0x78, 0x0E, 0xD4]) + rom.write_bytes(0xE29B90, [0x94, 0x68, 0x0E, 0xD4]) + # Mido + rom.write_bytes(0xE62EDC, [0x94, 0x6F, 0x0E, 0xD4]) + rom.write_bytes(0xE630D8, [0x94, 0x4F, 0x0E, 0xD4]) + rom.write_bytes(0xE62644, [0x94, 0x6F, 0x0E, 0xD4]) + rom.write_bytes(0xE633AC, [0x94, 0x68, 0x0E, 0xD4]) + rom.write_bytes(0xE636A0, [0x94, 0x48, 0x0E, 0xD4]) + + # Change adult Kokiri Forest to check for Forest Temple complete flag + rom.write_bytes(0xE5369E, [0xB4, 0xAC]) + rom.write_bytes(0xD5A83C, [0x80, 0x49, 0x0E, 0xDC]) + + # Change adult Goron City to check for Fire Temple complete flag + rom.write_bytes(0xED59DC, [0x80, 0xC9, 0x0E, 0xDC]) + + # Change Pokey to check DT complete flag + rom.write_bytes(0xE5400A, [0x8C, 0x4C]) + rom.write_bytes(0xE5400E, [0xB4, 0xA4]) + if world.open_forest: + rom.write_bytes(0xE5401C, [0x14, 0x0B]) + + # Fix Shadow Temple to check for different rewards for scene + rom.write_bytes(0xCA3F32, [0x00, 0x00, 0x25, 0x4A, 0x00, 0x10]) + + # Fix Spirit Temple to check for different rewards for scene + rom.write_bytes(0xCA3EA2, [0x00, 0x00, 0x25, 0x4A, 0x00, 0x08]) + + # Fix Biggoron to check a different flag. + rom.write_byte(0xED329B, 0x72) + rom.write_byte(0xED43E7, 0x72) + rom.write_bytes(0xED3370, [0x3C, 0x0D, 0x80, 0x12]) + rom.write_bytes(0xED3378, [0x91, 0xB8, 0xA6, 0x42, 0xA1, 0xA8, 0xA6, 0x42]) + rom.write_bytes(0xED6574, [0x00, 0x00, 0x00, 0x00]) + + # Remove the check on the number of days that passed for claim check. + rom.write_bytes(0xED4470, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xED4498, [0x00, 0x00, 0x00, 0x00]) + + # Fixed reward order for Bombchu Bowling + rom.write_bytes(0xE2E698, [0x80, 0xAA, 0xE2, 0x64]) + rom.write_bytes(0xE2E6A0, [0x80, 0xAA, 0xE2, 0x4C]) + rom.write_bytes(0xE2D440, [0x24, 0x19, 0x00, 0x00]) + + # Make fishing less obnoxious + Block_code = [0x3C, 0x0A, 0x80, 0x12, 0x8D, 0x4A, 0xA5, 0xD4, 0x14, 0x0A, 0x00, 0x06, + 0x31, 0x78, 0x00, 0x01, 0x14, 0x18, 0x00, 0x02, 0x3c, 0x18, 0x42, 0x30, + 0x3C, 0x18, 0x42, 0x50, 0x03, 0xe0, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x18, 0x00, 0x02, 0x3C, 0x18, 0x42, 0x10, 0x3C, 0x18, 0x42, 0x38, + 0x03, 0xE0, 0x00, 0x08] + rom.write_bytes(0x3480C00, Block_code) + rom.write_bytes(0xDBF434, [0x44, 0x98, 0x90, 0x00, 0xE6, 0x52, 0x01, 0x9C]) + rom.write_bytes(0xDBF484, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xDBF4A8, [0x00, 0x00, 0x00, 0x00]) + rom.write_bytes(0xDCBEAA, [0x42, 0x48]) #set adult fish size requirement + rom.write_bytes(0xDCBF26, [0x42, 0x48]) #set adult fish size requirement + rom.write_bytes(0xDCBF32, [0x42, 0x30]) #set child fish size requirement + rom.write_bytes(0xDCBF9E, [0x42, 0x30]) #set child fish size requirement + + # Dampe always digs something up and first dig is always the Piece of Heart + rom.write_bytes(0xCC3FA8, [0xA2, 0x01, 0x01, 0xF8]) + rom.write_bytes(0xCC4024, [0x00, 0x00, 0x00, 0x00]) + + # Allow owl to always carry the kid down Death Mountain + rom.write_bytes(0xE304F0, [0x24, 0x0E, 0x00, 0x01]) + + # Forbid Sun's Song from a bunch of cutscenes + Suns_scenes = [0x2016FC9, 0x2017219, 0x20173D9, 0x20174C9, 0x2017679, 0x20C1539, 0x20C15D9, 0x21A0719, 0x21A07F9, 0x2E90129, 0x2E901B9, 0x2E90249, 0x225E829, 0x225E939, 0x306D009] + for address in Suns_scenes: + rom.write_byte(address,0x01) + + # Remove disruptive text from Gerudo Training Grounds and early Shadow Temple (vanilla) + Wonder_text = [0x27C00BC, 0x27C00CC, 0x27C00DC, 0x27C00EC, 0x27C00FC, 0x27C010C, 0x27C011C, 0x27C012C, 0x27CE080, + 0x27CE090, 0x2887070, 0x2887080, 0x2887090, 0x2897070, 0x28C7134, 0x28D91BC, 0x28A60F4, 0x28AE084, + 0x28B9174, 0x28BF168, 0x28BF178, 0x28BF188, 0x28A1144, 0x28A6104, 0x28D0094] + for address in Wonder_text: + rom.write_byte(address, 0xFB) + + # Speed dig text for Dampe + rom.write_bytes(0x9532F8, [0x08, 0x08, 0x08, 0x59]) + + # Make item descriptions into a single box + Short_item_descriptions = [0x92EC84, 0x92F9E3, 0x92F2B4, 0x92F37A, 0x92F513, 0x92F5C6, 0x92E93B, 0x92EA12] + for address in Short_item_descriptions: + rom.write_byte(address,0x02) + + # Fix text for Pocket Cucco. + rom.write_byte(0xBEEF45, 0x0B) + rom.write_byte(0x92D41A, 0x2E) + Block_code = [0x59, 0x6f, 0x75, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x61, 0x20, 0x05, 0x41, + 0x50, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x20, 0x43, 0x75, 0x63, 0x63, 0x6f, + 0x2c, 0x20, 0x05, 0x40, 0x6f, 0x6e, 0x65, 0x01, 0x6f, 0x66, 0x20, 0x41, + 0x6e, 0x6a, 0x75, 0x27, 0x73, 0x20, 0x70, 0x72, 0x69, 0x7a, 0x65, 0x64, + 0x20, 0x68, 0x65, 0x6e, 0x73, 0x21, 0x20, 0x49, 0x74, 0x20, 0x66, 0x69, + 0x74, 0x73, 0x20, 0x01, 0x69, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, + 0x70, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x02] + rom.write_bytes(0x92D41C, Block_code) + + # Set hooks for various code + rom.write_bytes(0xDBF428, [0x0C, 0x10, 0x03, 0x00]) #Set Fishing Hook + + configure_dungeon_info(rom, world) + + rom.write_int32(rom.sym('cfg_file_select_hash'), world.settings.numeric_seed) + + # will be populated with data to be written to initial save + # see initial_save.asm and config.asm for more details on specifics + # or just use the following functions to add an entry to the table + initial_save_table = [] + + # will set the bits of value to the offset in the save (or'ing them with what is already there) + def write_bits_to_save(offset, value, filter=None): + nonlocal initial_save_table + + if filter and not filter(value): + return + + initial_save_table += [(offset & 0xFF00) >> 8, offset & 0xFF, 0x00, value] + + + + # will overwrite the byte at offset with the given value + def write_byte_to_save(offset, value, filter=None): + nonlocal initial_save_table + + if filter and not filter(value): + return + + initial_save_table += [(offset & 0xFF00) >> 8, offset & 0xFF, 0x01, value] + + # will overwrite the byte at offset with the given value + def write_bytes_to_save(offset, bytes, filter=None): + for i, value in enumerate(bytes): + write_byte_to_save(offset + i, value, filter) + + # will overwrite the byte at offset with the given value + def write_save_table(rom): + nonlocal initial_save_table + + table_len = len(initial_save_table) + if table_len > 0x400: + raise Exception("The Initial Save Table has exceeded it's maximum capacity: 0x%03X/0x400" % table_len) + rom.write_bytes(0x3481800, initial_save_table) + + + # Initial Save Data + write_bits_to_save(0x003F, 0x02) # Some Biggoron's Sword flag? + + write_bits_to_save(0x00D4 + 0x03 * 0x1C + 0x04 + 0x0, 0x08) # Forest Temple switch flag (Poe Sisters cutscene) + write_bits_to_save(0x00D4 + 0x05 * 0x1C + 0x04 + 0x1, 0x01) # Water temple switch flag (Ruto) + write_bits_to_save(0x00D4 + 0x51 * 0x1C + 0x04 + 0x2, 0x08) # Hyrule Field switch flag (Owl) + write_bits_to_save(0x00D4 + 0x55 * 0x1C + 0x04 + 0x0, 0x80) # Kokiri Forest switch flag (Owl) + write_bits_to_save(0x00D4 + 0x56 * 0x1C + 0x04 + 0x2, 0x40) # Sacred Forest Meadow switch flag (Owl) + write_bits_to_save(0x00D4 + 0x5B * 0x1C + 0x04 + 0x2, 0x01) # Lost Woods switch flag (Owl) + write_bits_to_save(0x00D4 + 0x5B * 0x1C + 0x04 + 0x3, 0x80) # Lost Woods switch flag (Owl) + write_bits_to_save(0x00D4 + 0x5C * 0x1C + 0x04 + 0x0, 0x80) # Desert Colossus switch flag (Owl) + write_bits_to_save(0x00D4 + 0x5F * 0x1C + 0x04 + 0x3, 0x20) # Hyrule Castle switch flag (Owl) + + write_bits_to_save(0x0ED4, 0x10) # "Met Deku Tree" + write_bits_to_save(0x0ED5, 0x20) # "Deku Tree Opened Mouth" + write_bits_to_save(0x0ED6, 0x08) # "Rented Horse From Ingo" + write_bits_to_save(0x0EDA, 0x08) # "Began Nabooru Battle" + write_bits_to_save(0x0EDC, 0x80) # "Entered the Master Sword Chamber" + write_bits_to_save(0x0EDD, 0x20) # "Pulled Master Sword from Pedestal" + write_bits_to_save(0x0EE0, 0x80) # "Spoke to Kaepora Gaebora by Lost Woods" + write_bits_to_save(0x0EE7, 0x20) # "Nabooru Captured by Twinrova" + write_bits_to_save(0x0EE7, 0x10) # "Spoke to Nabooru in Spirit Temple" + write_bits_to_save(0x0EED, 0x20) # "Sheik, Spawned at Master Sword Pedestal as Adult" + write_bits_to_save(0x0EED, 0x01) # "Nabooru Ordered to Fight by Twinrova" + write_bits_to_save(0x0EF9, 0x01) # "Greeted by Saria" + write_bits_to_save(0x0F0A, 0x04) # "Spoke to Ingo Once as Adult" + write_bits_to_save(0x0F1A, 0x04) # "Met Darunia in Fire Temple" + + write_bits_to_save(0x0ED7, 0x01) # "Spoke to Child Malon at Castle or Market" + write_bits_to_save(0x0ED7, 0x20) # "Spoke to Child Malon at Ranch" + write_bits_to_save(0x0ED7, 0x40) # "Invited to Sing With Child Malon" + write_bits_to_save(0x0F09, 0x10) # "Met Child Malon at Castle or Market" + write_bits_to_save(0x0F09, 0x20) # "Child Malon Said Epona Was Scared of You" + + write_bits_to_save(0x0F21, 0x04) # "Ruto in JJ (M3) Talk First Time" + write_bits_to_save(0x0F21, 0x02) # "Ruto in JJ (M2) Meet Ruto" + + write_bits_to_save(0x0EE2, 0x01) # "Began Ganondorf Battle" + write_bits_to_save(0x0EE3, 0x80) # "Began Bongo Bongo Battle" + write_bits_to_save(0x0EE3, 0x40) # "Began Barinade Battle" + write_bits_to_save(0x0EE3, 0x20) # "Began Twinrova Battle" + write_bits_to_save(0x0EE3, 0x10) # "Began Morpha Battle" + write_bits_to_save(0x0EE3, 0x08) # "Began Volvagia Battle" + write_bits_to_save(0x0EE3, 0x04) # "Began Phantom Ganon Battle" + write_bits_to_save(0x0EE3, 0x02) # "Began King Dodongo Battle" + write_bits_to_save(0x0EE3, 0x01) # "Began Gohma Battle" + + write_bits_to_save(0x0EE8, 0x01) # "Entered Deku Tree" + write_bits_to_save(0x0EE9, 0x80) # "Entered Temple of Time" + write_bits_to_save(0x0EE9, 0x40) # "Entered Goron City" + write_bits_to_save(0x0EE9, 0x20) # "Entered Hyrule Castle" + write_bits_to_save(0x0EE9, 0x10) # "Entered Zora's Domain" + write_bits_to_save(0x0EE9, 0x08) # "Entered Kakariko Village" + write_bits_to_save(0x0EE9, 0x02) # "Entered Death Mountain Trail" + write_bits_to_save(0x0EE9, 0x01) # "Entered Hyrule Field" + write_bits_to_save(0x0EEA, 0x04) # "Entered Ganon's Castle (Exterior)" + write_bits_to_save(0x0EEA, 0x02) # "Entered Death Mountain Crater" + write_bits_to_save(0x0EEA, 0x01) # "Entered Desert Colossus" + write_bits_to_save(0x0EEB, 0x80) # "Entered Zora's Fountain" + write_bits_to_save(0x0EEB, 0x40) # "Entered Graveyard" + write_bits_to_save(0x0EEB, 0x20) # "Entered Jabu-Jabu's Belly" + write_bits_to_save(0x0EEB, 0x10) # "Entered Lon Lon Ranch" + write_bits_to_save(0x0EEB, 0x08) # "Entered Gerudo's Fortress" + write_bits_to_save(0x0EEB, 0x04) # "Entered Gerudo Valley" + write_bits_to_save(0x0EEB, 0x02) # "Entered Lake Hylia" + write_bits_to_save(0x0EEB, 0x01) # "Entered Dodongo's Cavern" + write_bits_to_save(0x0F08, 0x08) # "Entered Hyrule Castle" + + # Make the Kakariko Gate not open with the MS + if not world.open_kakariko: + rom.write_int32(0xDD3538, 0x34190000) # li t9, 0 + + # Make all chest opening animations fast + if world.fast_chests: + rom.write_int32(0xBDA2E8, 0x240AFFFF) # addiu t2, r0, -1 + # replaces # lb t2, 0x0002 (t1) + + # Set up for Rainbow Bridge dungeons condition + Block_code = [0x15, 0x41, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0xEA, 0x00, 0xA5, + 0x24, 0x01, 0x00, 0x1C, 0x31, 0x4A, 0x00, 0x1C, 0x08, 0x07, 0x88, 0xD9] + rom.write_bytes(0x3480820, Block_code) + + # Gossip stones resond to stone of agony + Block_code = [0x3C, 0x01, 0x80, 0x12, 0x80, 0x21, 0xA6, 0x75, 0x30, 0x21, 0x00, 0x20, + 0x03, 0xE0, 0x00, 0x08] + # Gossip stones always respond + if(world.hints == 'always'): + Block_code = [0x24, 0x01, 0x00, 0x20, 0x03, 0xE0, 0x00, 0x08] + rom.write_bytes(0x3480840, Block_code) + + # Set up Rainbow Bridge conditions + if world.bridge == 'medallions': + Block_code = [0x80, 0xEA, 0x00, 0xA7, 0x24, 0x01, 0x00, 0x3F, + 0x31, 0x4A, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00] + rom.write_bytes(0xE2B454, Block_code) + elif world.bridge == 'open': + write_bits_to_save(0xEDC, 0x20) # "Rainbow Bridge Built by Sages" + elif world.bridge == 'dungeons': + Block_code = [0x80, 0xEA, 0x00, 0xA7, 0x24, 0x01, 0x00, 0x3F, + 0x08, 0x10, 0x02, 0x08, 0x31, 0x4A, 0x00, 0x3F] + rom.write_bytes(0xE2B454, Block_code) + + if world.open_forest: + write_bits_to_save(0xED5, 0x10) # "Showed Mido Sword & Shield" + + if world.open_door_of_time: + write_bits_to_save(0xEDC, 0x08) # "Opened the Door of Time" + + # "fast-ganon" stuff + if world.no_escape_sequence: + rom.write_bytes(0xD82A12, [0x05, 0x17]) # Sets exit from Ganondorf fight to entrance to Ganon fight + if world.unlocked_ganondorf: + write_bits_to_save(0x00D4 + 0x0A * 0x1C + 0x04 + 0x1, 0x10) # Ganon's Tower switch flag (unlock boss key door) + if world.skipped_trials['Forest']: + write_bits_to_save(0x0EEA, 0x08) # "Completed Forest Trial" + if world.skipped_trials['Fire']: + write_bits_to_save(0x0EEA, 0x40) # "Completed Fire Trial" + if world.skipped_trials['Water']: + write_bits_to_save(0x0EEA, 0x10) # "Completed Water Trial" + if world.skipped_trials['Spirit']: + write_bits_to_save(0x0EE8, 0x20) # "Completed Spirit Trial" + if world.skipped_trials['Shadow']: + write_bits_to_save(0x0EEA, 0x20) # "Completed Shadow Trial" + if world.skipped_trials['Light']: + write_bits_to_save(0x0EEA, 0x80) # "Completed Light Trial" + if world.trials == 0: + write_bits_to_save(0x0EED, 0x08) # "Dispelled Ganon's Tower Barrier" + + # open gerudo fortress + if world.gerudo_fortress == 'open': + write_bits_to_save(0x00A5, 0x40) # Give Gerudo Card + write_bits_to_save(0x0EE7, 0x0F) # Free all 4 carpenters + write_bits_to_save(0x00D4 + 0x0C * 0x1C + 0x04 + 0x1, 0x0F) # Thieves' Hideout switch flags (started all fights) + write_bits_to_save(0x00D4 + 0x0C * 0x1C + 0x04 + 0x2, 0x01) # Thieves' Hideout switch flags (heard yells/unlocked doors) + write_bits_to_save(0x00D4 + 0x0C * 0x1C + 0x04 + 0x3, 0xFE) # Thieves' Hideout switch flags (heard yells/unlocked doors) + write_bits_to_save(0x00D4 + 0x0C * 0x1C + 0x0C + 0x2, 0xD4) # Thieves' Hideout collection flags (picked up keys, marks fights finished as well) + elif world.gerudo_fortress == 'fast': + write_bits_to_save(0x0EE7, 0x0E) # Free 3 carpenters + write_bits_to_save(0x00D4 + 0x0C * 0x1C + 0x04 + 0x1, 0x0D) # Thieves' Hideout switch flags (started all fights) + write_bits_to_save(0x00D4 + 0x0C * 0x1C + 0x04 + 0x2, 0x01) # Thieves' Hideout switch flags (heard yells/unlocked doors) + write_bits_to_save(0x00D4 + 0x0C * 0x1C + 0x04 + 0x3, 0xDC) # Thieves' Hideout switch flags (heard yells/unlocked doors) + write_bits_to_save(0x00D4 + 0x0C * 0x1C + 0x0C + 0x2, 0xC4) # Thieves' Hideout collection flags (picked up keys, marks fights finished as well) + + # start with maps/compasses + if world.shuffle_mapcompass == 'startwith': + write_bits_to_save(0x00A8, 0x06) # "Deku Map/Compass" + write_bits_to_save(0x00A9, 0x06) # "Dodongo Map/Compass" + write_bits_to_save(0x00AA, 0x06) # "Jabu Map/Compass" + write_bits_to_save(0x00AB, 0x06) # "Forest Map/Compass" + write_bits_to_save(0x00AC, 0x06) # "Fire Map/Compass" + write_bits_to_save(0x00AD, 0x06) # "Water Map/Compass" + write_bits_to_save(0x00AF, 0x06) # "Shadow Map/Compass" + write_bits_to_save(0x00AE, 0x06) # "Spirit Map/Compass" + write_bits_to_save(0x00B0, 0x06) # "BotW Map/Compass" + write_bits_to_save(0x00B1, 0x06) # "Ice Map/Compass" + + # Revert change that Skips the Epona Race + if not world.no_epona_race: + rom.write_int32(0xA9E838, 0x03E00008) + + # skip castle guard stealth sequence + if world.no_guard_stealth: + # change the exit at child/day crawlspace to the end of zelda's goddess cutscene + rom.write_bytes(0x21F60DE, [0x05, 0xF0]) + + # patch mq scenes + mq_scenes = [] + if world.dungeon_mq['DT']: + mq_scenes.append(0) + if world.dungeon_mq['DC']: + mq_scenes.append(1) + if world.dungeon_mq['JB']: + mq_scenes.append(2) + if world.dungeon_mq['FoT']: + mq_scenes.append(3) + if world.dungeon_mq['FiT']: + mq_scenes.append(4) + if world.dungeon_mq['WT']: + mq_scenes.append(5) + if world.dungeon_mq['SpT']: + mq_scenes.append(6) + if world.dungeon_mq['ShT']: + mq_scenes.append(7) + if world.dungeon_mq['BW']: + mq_scenes.append(8) + if world.dungeon_mq['IC']: + mq_scenes.append(9) + # Scene 10 has no layout changes, so it doesn't need to be patched + if world.dungeon_mq['GTG']: + mq_scenes.append(11) + if world.dungeon_mq['GC']: + mq_scenes.append(13) + + patch_files(rom, mq_scenes) + + ### Load Shop File + # Move shop actor file to free space + shop_item_file = File({ + 'Name':'En_GirlA', + 'Start':'00C004E0', + 'End':'00C02E00', + 'RemapStart':'03485000', + }) + shop_item_file.relocate(rom) + + # Increase the shop item table size + shop_item_vram_start = rom.read_int32(0x00B5E490 + (0x20 * 4) + 0x08) + insert_space(rom, shop_item_file, shop_item_vram_start, 1, 0x3C + (0x20 * 50), 0x20 * 50) + + # Add relocation entries for shop item table + new_relocations = [] + for i in range(50, 100): + new_relocations.append(shop_item_file.start + 0x1DEC + (i * 0x20) + 0x04) + new_relocations.append(shop_item_file.start + 0x1DEC + (i * 0x20) + 0x14) + new_relocations.append(shop_item_file.start + 0x1DEC + (i * 0x20) + 0x1C) + add_relocations(rom, shop_item_file, new_relocations) + + # update actor table + rom.write_int32s(0x00B5E490 + (0x20 * 4), + [shop_item_file.start, + shop_item_file.end, + shop_item_vram_start, + shop_item_vram_start + (shop_item_file.end - shop_item_file.start)]) + + # Update DMA Table + update_dmadata(rom, shop_item_file) + + # Create 2nd Bazaar Room + bazaar_room_file = File({ + 'Name':'shop1_room_1', + 'Start':'028E4000', + 'End':'0290D7B0', + 'RemapStart':'03489000', + }) + bazaar_room_file.dma_key = 0x03472000 + bazaar_room_file.relocate(rom) + # Update DMA Table + update_dmadata(rom, bazaar_room_file) + + # Add new Bazaar Room to Bazaar Scene + rom.write_int32s(0x28E3030, [0x00010000, 0x02000058]) #reduce position list size + rom.write_int32s(0x28E3008, [0x04020000, 0x02000070]) #expand room list size + + rom.write_int32s(0x28E3070, [0x028E4000, 0x0290D7B0, + bazaar_room_file.start, bazaar_room_file.end]) #room list + rom.write_int16s(0x28E3080, [0x0000, 0x0001]) # entrance list + rom.write_int16(0x28E4076, 0x0005) # Change shop to Kakariko Bazaar + #rom.write_int16(0x3489076, 0x0005) # Change shop to Kakariko Bazaar + + # Load Message and Shop Data + messages = read_messages(rom) + shop_items = read_shop_items(rom, shop_item_file.start + 0x1DEC) + remove_unused_messages(messages) + + # Set Big Poe count to get reward from buyer + poe_points = world.big_poe_count * 100 + rom.write_int16(0xEE69CE, poe_points) + # update dialogue + if world.big_poe_count != 10: + new_message = "\x1AOh, you brought a Poe today!\x04\x1AHmmmm!\x04\x1AVery interesting!\x01This is a \x05\x41Big Poe\x05\x40!\x04\x1AI'll buy it for \x05\x4150 Rupees\x05\x40.\x04On top of that, I'll put \x05\x41100\x01points \x05\x40on your card.\x04\x1AIf you earn \x05\x41%d points\x05\x40, you'll\x01be a happy man! Heh heh." % poe_points + update_message_by_id(messages, 0x70f7, new_message) + new_message = "\x1AWait a minute! WOW!\x04\x1AYou have earned \x05\x41%d points\x05\x40!\x04\x1AYoung man, you are a genuine\x01\x05\x41Ghost Hunter\x05\x40!\x04\x1AIs that what you expected me to\x01say? Heh heh heh!\x04\x1ABecause of you, I have extra\x01inventory of \x05\x41Big Poes\x05\x40, so this will\x01be the last time I can buy a \x01ghost.\x04\x1AYou're thinking about what I \x01promised would happen when you\x01earned %d points. Heh heh.\x04\x1ADon't worry, I didn't forget.\x01Just take this." % (poe_points, poe_points) + update_message_by_id(messages, 0x70f8, new_message) + + # Sets hooks for gossip stone changes + if world.hints != 'none': + if world.hints != 'mask': + rom.write_bytes(0xEE7B84, [0x0C, 0x10, 0x02, 0x10]) + rom.write_bytes(0xEE7B8C, [0x24, 0x02, 0x00, 0x20]) + writeGossipStoneHintsHints(world, messages) + + # build silly ganon lines + buildGanonText(world, messages) + + # Write item overrides + override_table = get_override_table(world) + rom.write_bytes(0x3481000, sum(override_table, [])) + rom.write_byte(0x03481C00, world.id + 1) # Write player ID + + # Revert Song Get Override Injection + if not world.shuffle_song_items: + # general get song + rom.write_int32(0xAE5DF8, 0x240200FF) + rom.write_int32(0xAE5E04, 0xAD0F00A4) + # requiem of spirit + rom.write_int32s(0xAC9ABC, [0x3C010001, 0x00300821]) + # sun song + rom.write_int32(0xE09F68, 0x8C6F00A4) + rom.write_int32(0xE09F74, 0x01CFC024) + rom.write_int32(0xE09FB0, 0x240F0001) + # epona + rom.write_int32(0xD7E77C, 0x8C4900A4) + rom.write_int32(0xD7E784, 0x8D088C24) + rom.write_int32s(0xD7E8D4, [0x8DCE8C24, 0x8C4F00A4]) + rom.write_int32s(0xD7E140, [0x8DCE8C24, 0x8C6F00A4]) + rom.write_int32(0xD7EBBC, 0x14410008) + rom.write_int32(0xD7EC1C, 0x17010010) + # song of time + rom.write_int32(0xDB532C, 0x24050003) + + # Set default targeting option to Hold + if world.default_targeting == 'hold': + rom.write_byte(0xB71E6D, 0x01) + + # Set OHKO mode + if world.difficulty == 'ohko': + rom.write_int32(0xAE80A8, 0xA4A00030) # sh zero,48(a1) + rom.write_int32(0xAE80B4, 0x06000003) # bltz s0, +0003 + + # Patch songs and boss rewards + for location in world.get_locations(): + item = location.item + itemid = copy.copy(item.code) + locationaddress = location.address + secondaryaddress = location.address2 + + if itemid is None or location.address is None: + continue + + if location.type == 'Song' and not world.shuffle_song_items: + rom.write_byte(locationaddress, itemid[0]) + itemid[0] = itemid[0] + 0x0D + rom.write_byte(secondaryaddress, itemid[0]) + if location.name == 'Impa at Castle': + impa_fix = 0x65 - itemid[1] + rom.write_byte(0xD12ECB, impa_fix) + rom.write_byte(0x2E8E931, item_data[item.name]) #Fix text box + elif location.name == 'Song from Malon': + if item.name == 'Suns Song': + rom.write_byte(locationaddress, itemid[0]) + malon_fix = 0x8C34 - (itemid[1] * 4) + malon_fix_high = malon_fix >> 8 + malon_fix_low = malon_fix & 0x00FF + rom.write_bytes(0xD7E142, [malon_fix_high, malon_fix_low]) + rom.write_bytes(0xD7E8D6, [malon_fix_high, malon_fix_low]) # I really don't like hardcoding these addresses, but for now..... + rom.write_bytes(0xD7E786, [malon_fix_high, malon_fix_low]) + rom.write_byte(0x29BECB9, item_data[item.name]) #Fix text box + elif location.name == 'Song from Composer Grave': + sun_fix = 0x8C34 - (itemid[1] * 4) + sun_fix_high = sun_fix >> 8 + sun_fix_low = sun_fix & 0x00FF + rom.write_bytes(0xE09F66, [sun_fix_high, sun_fix_low]) + rom.write_byte(0x332A87D, item_data[item.name]) #Fix text box + elif location.name == 'Song from Saria': + saria_fix = 0x65 - itemid[1] + rom.write_byte(0xE2A02B, saria_fix) + rom.write_byte(0x20B1DBD, item_data[item.name]) #Fix text box + elif location.name == 'Song from Ocarina of Time': + rom.write_byte(0x252FC95, item_data[item.name]) #Fix text box + elif location.name == 'Song at Windmill': + windmill_fix = 0x65 - itemid[1] + rom.write_byte(0xE42ABF, windmill_fix) + rom.write_byte(0x3041091, item_data[item.name]) #Fix text box + elif location.name == 'Sheik Forest Song': + minuet_fix = 0x65 - itemid[1] + rom.write_byte(0xC7BAA3, minuet_fix) + rom.write_byte(0x20B0815, item_data[item.name]) #Fix text box + elif location.name == 'Sheik at Temple': + prelude_fix = 0x65 - itemid[1] + rom.write_byte(0xC805EF, prelude_fix) + rom.write_byte(0x2531335, item_data[item.name]) #Fix text box + elif location.name == 'Sheik in Crater': + bolero_fix = 0x65 - itemid[1] + rom.write_byte(0xC7BC57, bolero_fix) + rom.write_byte(0x224D7FD, item_data[item.name]) #Fix text box + elif location.name == 'Sheik in Ice Cavern': + serenade_fix = 0x65 - itemid[1] + rom.write_byte(0xC7BD77, serenade_fix) + rom.write_byte(0x2BEC895, item_data[item.name]) #Fix text box + elif location.name == 'Sheik in Kakariko': + nocturne_fix = 0x65 - itemid[1] + rom.write_byte(0xAC9A5B, nocturne_fix) + rom.write_byte(0x2000FED, item_data[item.name]) #Fix text box + elif location.name == 'Sheik at Colossus': + rom.write_byte(0x218C589, item_data[item.name]) #Fix text box + elif location.type == 'Boss': + if location.name == 'Links Pocket': + write_bits_to_save(item_data[item.name][1], item_data[item.name][0]) + else: + rom.write_byte(locationaddress, itemid) + rom.write_byte(secondaryaddress, item_data[item.name][2]) + if location.name == 'Bongo Bongo': + rom.write_bytes(0xCA3F32, [item_data[item.name][3][0], item_data[item.name][3][1]]) + rom.write_bytes(0xCA3F36, [item_data[item.name][3][2], item_data[item.name][3][3]]) + elif location.name == 'Twinrova': + rom.write_bytes(0xCA3EA2, [item_data[item.name][3][0], item_data[item.name][3][1]]) + rom.write_bytes(0xCA3EA6, [item_data[item.name][3][2], item_data[item.name][3][3]]) + + # add a cheaper bombchu pack to the bombchu shop + # describe + update_message_by_id(messages, 0x80FE, '\x08\x05\x41Bombchu (5 pieces) 60 Rupees\x01\x05\x40This looks like a toy mouse, but\x01it\'s actually a self-propelled time\x01bomb!\x09\x0A', 0x03) + # purchase + update_message_by_id(messages, 0x80FF, '\x08Bombchu 5 Pieces 60 Rupees\x01\x01\x1B\x05\x42Buy\x01Don\'t buy\x05\x40\x09', 0x03) + rbl_bombchu = shop_items[0x0018] + rbl_bombchu.price = 60 + rbl_bombchu.pieces = 5 + rbl_bombchu.get_item_id = 0x006A + rbl_bombchu.description_message = 0x80FE + rbl_bombchu.purchase_message = 0x80FF + + # Reduce 10 Pack Bombchus from 100 to 99 Rupees + shop_items[0x0015].price = 99 + shop_items[0x0019].price = 99 + shop_items[0x001C].price = 99 + update_message_by_id(messages, shop_items[0x001C].description_message, "\x08\x05\x41Bombchu (10 pieces) 99 Rupees\x01\x05\x40This looks like a toy mouse, but\x01it's actually a self-propelled time\x01bomb!\x09\x0A") + update_message_by_id(messages, shop_items[0x001C].purchase_message, "\x08Bombchu 10 pieces 99 Rupees\x09\x01\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40") + + shuffle_messages.shop_item_messages = [] + + # kokiri shop + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Kokiri Shop').locations, True) + shop_objs |= {0x00FC, 0x00B2, 0x0101, 0x0102, 0x00FD, 0x00C5} # Shop objects + rom.write_byte(0x2587029, len(shop_objs)) + rom.write_int32(0x258702C, 0x0300F600) + rom.write_int16s(0x2596600, list(shop_objs)) + + # kakariko bazaar + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Kakariko Bazaar').locations) + shop_objs |= {0x005B, 0x00B2, 0x00C5, 0x0107, 0x00C9, 0x016B} # Shop objects + rom.write_byte(0x28E4029, len(shop_objs)) + rom.write_int32(0x28E402C, 0x03007A40) + rom.write_int16s(0x28EBA40, list(shop_objs)) + + # castle town bazaar + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Castle Town Bazaar').locations) + shop_objs |= {0x005B, 0x00B2, 0x00C5, 0x0107, 0x00C9, 0x016B} # Shop objects + rom.write_byte(0x3489029, len(shop_objs)) + rom.write_int32(0x348902C, 0x03007A40) + rom.write_int16s(0x3490A40, list(shop_objs)) + + # goron shop + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Goron Shop').locations) + shop_objs |= {0x00C9, 0x00B2, 0x0103, 0x00AF} # Shop objects + rom.write_byte(0x2D33029, len(shop_objs)) + rom.write_int32(0x2D3302C, 0x03004340) + rom.write_int16s(0x2D37340, list(shop_objs)) + + # zora shop + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Zora Shop').locations) + shop_objs |= {0x005B, 0x00B2, 0x0104, 0x00FE} # Shop objects + rom.write_byte(0x2D5B029, len(shop_objs)) + rom.write_int32(0x2D5B02C, 0x03004B40) + rom.write_int16s(0x2D5FB40, list(shop_objs)) + + # kakariko potion shop + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Kakariko Potion Shop Front').locations) + shop_objs |= {0x0159, 0x00B2, 0x0175, 0x0122} # Shop objects + rom.write_byte(0x2D83029, len(shop_objs)) + rom.write_int32(0x2D8302C, 0x0300A500) + rom.write_int16s(0x2D8D500, list(shop_objs)) + + # market potion shop + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Castle Town Potion Shop').locations) + shop_objs |= {0x0159, 0x00B2, 0x0175, 0x00C5, 0x010C, 0x016B} # Shop objects + rom.write_byte(0x2DB0029, len(shop_objs)) + rom.write_int32(0x2DB002C, 0x03004E40) + rom.write_int16s(0x2DB4E40, list(shop_objs)) + + # bombchu shop + shop_objs = place_shop_items(rom, world, shop_items, messages, + world.get_region('Castle Town Bombchu Shop').locations) + shop_objs |= {0x0165, 0x00B2} # Shop objects + rom.write_byte(0x2DD8029, len(shop_objs)) + rom.write_int32(0x2DD802C, 0x03006A40) + rom.write_int16s(0x2DDEA40, list(shop_objs)) + + if world.shuffle_scrubs == 'off': + # Revert Deku Scrubs changes + rom.write_int32s(0xEBB85C, [ + 0x24010002, # addiu at, zero, 2 + 0x3C038012, # lui v1, 0x8012 + 0x14410004, # bne v0, at, 0xd8 + 0x2463A5D0, # addiu v1, v1, -0x5a30 + 0x94790EF0])# lhu t9, 0xef0(v1) + rom.write_int32(0xDF7CB0, + 0xA44F0EF0) # sh t7, 0xef0(v0) + else: + # Rebuild Deku Salescrub Item Table + scrub_items = [0x30, 0x31, 0x3E, 0x33, 0x34, 0x37, 0x38, 0x39, 0x3A, 0x77, 0x79] + rom.seek_address(0xDF8684) + for scrub_item in scrub_items: + # Price + if world.shuffle_scrubs == 'low': + rom.write_int16(None, 10) + elif world.shuffle_scrubs == 'random': + # this is a random value between 0-99 + # average value is ~33 rupees + rom.write_int16(None, int(random.betavariate(1, 2) * 99)) + else: # leave default price + rom.read_int16(None) + rom.write_int16(None, 1) # Count + rom.write_int32(None, scrub_item) # Item + rom.write_int32(None, 0x80A74FF8) # Can_Buy_Func + rom.write_int32(None, 0x80A75354) # Buy_Func + + # update actor IDs + set_deku_salesman_data(rom) + + # Update grotto id data + set_grotto_id_data(rom) + + if world.shuffle_smallkeys == 'remove' or world.shuffle_bosskeys == 'remove': + locked_doors = get_locked_doors(rom, world) + for _,[door_byte, door_bits] in locked_doors.items(): + write_bits_to_save(door_byte, door_bits) + + #Fix item chest animations + chestAnimations = { + 0x3D: 0xED, #0x13 #Heart Container + 0x3E: 0xEC, #0x14 #Piece of Heart + 0x42: 0x02, #0xFE #Small Key + 0x48: 0xF7, #0x09 #Recovery Heart + 0x4F: 0xED, #0x13 #Heart Container + 0x76: 0xEC, #0x14 #WINNER! Piece of Heart + } + if world.bombchus_in_logic: + #Fix bombchu chest animations + chestAnimations[0x6A] = 0x28 #0xD8 #Bombchu (5) + chestAnimations[0x03] = 0x28 #0xD8 #Bombchu (10) + chestAnimations[0x6B] = 0x28 #0xD8 #Bombchu (20) + for item_id, gfx_id in chestAnimations.items(): + rom.write_byte(0xBEEE8E + (item_id * 6) + 2, gfx_id) + + # Update chest type sizes + if world.correct_chest_sizes: + update_chest_sizes(rom, override_table) + # Move Ganon's Castle's Zelda's Lullaby Chest back so is reachable if large + if not world.dungeon_mq['GC']: + rom.write_int16(0x321B176, 0xFC40) # original 0xFC48 + + # give dungeon items the correct messages + message_patch_for_dungeon_items(messages, shop_items, world) + if world.shuffle_mapcompass == 'keysanity' and world.enhance_map_compass: + reward_list = {'Kokiri Emerald': "\x05\x42Kokiri Emerald\x05\x40", + 'Goron Ruby': "\x05\x41Goron Ruby\x05\x40", + 'Zora Sapphire': "\x05\x43Zora Sapphire\x05\x40", + 'Forest Medallion': "\x05\x42Forest Medallion\x05\x40", + 'Fire Medallion': "\x05\x41Fire Medallion\x05\x40", + 'Water Medallion': "\x05\x43Water Medallion\x05\x40", + 'Spirit Medallion': "\x05\x46Spirit Medallion\x05\x40", + 'Shadow Medallion': "\x05\x45Shadow Medallion\x05\x40", + 'Light Medallion': "\x05\x44Light Medallion\x05\x40" + } + dungeon_list = {'DT': ("the \x05\x42Deku Tree", 'Queen Gohma', 0x62, 0x88), + 'DC': ("\x05\x41Dodongo\'s Cavern", 'King Dodongo', 0x63, 0x89), + 'JB': ("\x05\x43Jabu Jabu\'s Belly", 'Barinade', 0x64, 0x8a), + 'FoT': ("the \x05\x42Forest Temple", 'Phantom Ganon', 0x65, 0x8b), + 'FiT': ("the \x05\x41Fire Temple", 'Volvagia', 0x7c, 0x8c), + 'WT': ("the \x05\x43Water Temple", 'Morpha', 0x7d, 0x8e), + 'SpT': ("the \x05\x46Spirit Temple", 'Twinrova', 0x7e, 0x8f), + 'IC': ("the \x05\x44Ice Cavern", None, 0x87, 0x92), + 'BW': ("the \x05\x45Bottom of the Well", None, 0xa2, 0xa5), + 'ShT': ("the \x05\x45Shadow Temple", 'Bongo Bongo', 0x7f, 0xa3), + } + for dungeon in world.dungeon_mq: + if dungeon in ['GTG', 'GC']: + pass + elif dungeon in ['BW', 'IC']: + dungeon_name, boss_name, compass_id, map_id = dungeon_list[dungeon] + if world.world_count > 1: + map_message = "\x13\x76\x08\x05\x42\x0F\x05\x40 found the \x05\x41Dungeon Map\x05\x40\x01for %s\x05\x40!\x09" % (dungeon_name) + else: + map_message = "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for %s\x05\x40!\x01It\'s %s!\x09" % (dungeon_name, "masterful" if world.dungeon_mq[dungeon] else "ordinary") + + if world.quest == 'mixed': + update_message_by_id(messages, map_id, map_message) + else: + dungeon_name, boss_name, compass_id, map_id = dungeon_list[dungeon] + dungeon_reward = reward_list[world.get_location(boss_name).item.name] + if world.world_count > 1: + compass_message = "\x13\x75\x08\x05\x42\x0F\x05\x40 found the \x05\x41Compass\x05\x40\x01for %s\x05\x40!\x09" % (dungeon_name) + else: + compass_message = "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for %s\x05\x40!\x01It holds the %s!\x09" % (dungeon_name, dungeon_reward) + update_message_by_id(messages, compass_id, compass_message) + if world.quest == 'mixed': + if world.world_count > 1: + map_message = "\x13\x76\x08\x05\x42\x0F\x05\x40 found the \x05\x41Dungeon Map\x05\x40\x01for %s\x05\x40!\x09" % (dungeon_name) + else: + map_message = "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for %s\x05\x40!\x01It\'s %s!\x09" % (dungeon_name, "masterful" if world.dungeon_mq[dungeon] else "ordinary") + update_message_by_id(messages, map_id, map_message) + + else: + # Set hints for boss reward shuffle + rom.write_bytes(0xE2ADB2, [0x70, 0x7A]) + rom.write_bytes(0xE2ADB6, [0x70, 0x57]) + buildBossRewardHints(world, messages) + + # update happy mask shop to use new SOLD OUT text id + rom.write_int16(shop_item_file.start + 0x1726, shop_items[0x26].description_message) + + # add song messages + add_song_messages(messages, world) + + # reduce item message lengths + update_item_messages(messages, world) + + # Add 3rd Wallet Upgrade + rom.write_int16(0xB6D57E, 0x0003) + rom.write_int16(0xB6EC52, 999) + tycoon_message = "\x08\x13\x57You got a \x05\x43Tycoon's Wallet\x05\x40!\x01Now you can hold\x01up to \x05\x46999\x05\x40 \x05\x46Rupees\x05\x40." + if world.world_count > 1: + tycoon_message = make_player_message(tycoon_message) + update_message_by_id(messages, 0x00F8, tycoon_message, 0x23) + + repack_messages(rom, messages) + write_shop_items(rom, shop_item_file.start + 0x1DEC, shop_items) + + # text shuffle + if world.text_shuffle == 'except_hints': + shuffle_messages(rom, except_hints=True) + elif world.text_shuffle == 'complete': + shuffle_messages(rom, except_hints=False) + + # output a text dump, for testing... + #with open('keysanity_' + str(world.seed) + '_dump.txt', 'w', encoding='utf-16') as f: + # messages = read_messages(rom) + # f.write('item_message_strings = {\n') + # for m in messages: + # f.write("\t0x%04X: \"%s\",\n" % (m.id, m.get_python_string())) + # f.write('}\n') + + + scarecrow_song = None + if world.free_scarecrow: + scarecrow_song = str_to_song(world.scarecrow_song) #verified valid string in Main.py + + write_bits_to_save(0x0EE6, 0x10) # Played song as adult + write_byte_to_save(0x12C5, 0x01) # Song is remembered + write_bytes_to_save(0x12C6, scarecrow_song.playback_data[:(16*8)], lambda v: v != 0) + + if world.ocarina_songs: + replace_songs(rom, scarecrow_song) + + # actually write the save table to rom + write_save_table(rom) + + # patch music + if world.background_music == 'random': + randomize_music(rom) + elif world.background_music == 'off': + disable_music(rom) + + # re-seed for aesthetic effects. They shouldn't be affected by the generation seed + random.seed() + + # patch tunic colors + Tunics = [ + (world.kokiricolor, 0x00B6DA38), # Kokiri Tunic + (world.goroncolor, 0x00B6DA3B), # Goron Tunic + (world.zoracolor, 0x00B6DA3E), # Zora Tunic + ] + colorList = get_tunic_colors() + + for tunic_option, address in Tunics: + # handle random + if tunic_option == 'Random Choice': + tunic_option = random.choice(colorList) + # handle completely random + if tunic_option == 'Completely Random': + color = [random.getrandbits(8), random.getrandbits(8), random.getrandbits(8)] + # grab the color from the list + elif tunic_option in TunicColors: + color = TunicColors[tunic_option] + # build color from hex code + else: + color = list(int(tunic_option[i:i+2], 16) for i in (0, 2 ,4)) + rom.write_bytes(address, color) + + # patch navi colors + Navi = [ + (world.navicolordefault, [0x00B5E184]), # Default + (world.navicolorenemy, [0x00B5E19C, 0x00B5E1BC]), # Enemy, Boss + (world.navicolornpc, [0x00B5E194]), # NPC + (world.navicolorprop, [0x00B5E174, 0x00B5E17C, 0x00B5E18C, + 0x00B5E1A4, 0x00B5E1AC, 0x00B5E1B4, + 0x00B5E1C4, 0x00B5E1CC, 0x00B5E1D4]), # Everything else + ] + naviList = get_navi_colors() + + for navi_option, navi_addresses in Navi: + # choose a random choice for the whole group + if navi_option == 'Random Choice': + navi_option = random.choice(naviList) + for address in navi_addresses: + # completely random is random for every subgroup + if navi_option == 'Completely Random': + color = [random.getrandbits(8), random.getrandbits(8), random.getrandbits(8), 0xFF, + random.getrandbits(8), random.getrandbits(8), random.getrandbits(8), 0x00] + # grab the color from the list + elif navi_option in NaviColors: + color = NaviColors[navi_option] + # build color from hex code + else: + color = list(int(navi_option[i:i+2], 16) for i in (0, 2 ,4)) + color = color + [0xFF] + color + [0x00] + rom.write_bytes(address, color) + + # Configurable Sound Effects + sfx_addresses = [ + (world.navisfxoverworld, [0xAE7EF2, 0xC26C7E], NaviSFX), # Navi Overworld Hint (0x685F) + (world.navisfxenemytarget, [0xAE7EC6], NaviSFX), # Navi Enemy Target Hint (0x6843) + (world.healthSFX, [0xADBA1A], HealthSFX) # Low Health Beep (0x481B) + ] + + for thisSFX, addresses, SFX_table in sfx_addresses: + if thisSFX == 'Random Choice': + thisSFX = random.choice(list(SFX_table.keys())) + if thisSFX != 'Default': + for address in addresses: + rom.write_int16(address, SFX_table[thisSFX]) + + return rom + +def get_override_table(world): + override_entries = [] + for location in world.get_locations(): + override_entries.append(get_override_entry(location)) + override_entries.sort() + return override_entries + +def get_override_entry(location): + scene = location.scene + default = location.default + item_id = location.item.index + if None in [scene, default, item_id]: + return [] + + player_id = (location.item.world.id + 1) << 3 + + if location.type in ['NPC', 'BossHeart', 'Song']: + return [scene, player_id | 0x00, default, item_id] + elif location.type == 'Chest': + flag = default & 0x1F + return [scene, player_id | 0x01, flag, item_id] + elif location.type == 'Collectable': + return [scene, player_id | 0x02, default, item_id] + elif location.type == 'GS Token': + return [scene, player_id | 0x03, default, item_id] + elif location.type == 'Shop' and location.item.type != 'Shop': + return [scene, player_id | 0x00, default, item_id] + elif location.type == 'GrottoNPC' and location.item.type != 'Shop': + return [scene, player_id | 0x04, default, item_id] + else: + return [] + + +chestTypeMap = { + # small big boss + 0x0000: [0x5000, 0x0000, 0x2000], #Large + 0x1000: [0x7000, 0x1000, 0x1000], #Large, Appears, Clear Flag + 0x2000: [0x5000, 0x0000, 0x2000], #Boss Key’s Chest + 0x3000: [0x8000, 0x3000, 0x3000], #Large, Falling, Switch Flag + 0x4000: [0x6000, 0x4000, 0x4000], #Large, Invisible + 0x5000: [0x5000, 0x0000, 0x2000], #Small + 0x6000: [0x6000, 0x4000, 0x4000], #Small, Invisible + 0x7000: [0x7000, 0x1000, 0x1000], #Small, Appears, Clear Flag + 0x8000: [0x8000, 0x3000, 0x3000], #Small, Falling, Switch Flag + 0x9000: [0x9000, 0x9000, 0x9000], #Large, Appears, Zelda's Lullaby + 0xA000: [0xA000, 0xA000, 0xA000], #Large, Appears, Sun's Song Triggered + 0xB000: [0xB000, 0xB000, 0xB000], #Large, Appears, Switch Flag + 0xC000: [0x5000, 0x0000, 0x2000], #Large + 0xD000: [0x5000, 0x0000, 0x2000], #Large + 0xE000: [0x5000, 0x0000, 0x2000], #Large + 0xF000: [0x5000, 0x0000, 0x2000], #Large +} + +chestAnimationExtendedFast = [ + 0x87, # Progressive Nut Capacity + 0x88, # Progressive Stick Capacity + 0x98, # Deku Tree Compass + 0x99, # Dodongo's Cavern Compass + 0x9A, # Jabu Jabu Compass + 0x9B, # Forest Temple Compass + 0x9C, # Fire Temple Compass + 0x9D, # Water Temple Compass + 0x9E, # Spirit Temple Compass + 0x9F, # Shadow Temple Compass + 0xA0, # Bottom of the Well Compass + 0xA1, # Ice Cavern Compass + 0xA2, # Deku Tree Map + 0xA3, # Dodongo's Cavern Map + 0xA4, # Jabu Jabu Map + 0xA5, # Forest Temple Map + 0xA6, # Fire Temple Map + 0xA7, # Water Temple Map + 0xA8, # Spirit Temple Map + 0xA9, # Shadow Temple Map + 0xAA, # Bottom of the Well Map + 0xAB, # Ice Cavern Map + 0xB6, # Recovery Heart + 0xB7, # Arrows (5) + 0xB8, # Arrows (10) + 0xB9, # Arrows (30) + 0xBA, # Bombs (5) + 0xBB, # Bombs (10) + 0xBC, # Bombs (20) + 0xBD, # Deku Nuts (5) + 0xBE, # Deku Nuts (10) + 0xD0, # Deku Stick (1) + 0xD1, # Deky Seeds (30) +] + + +def room_get_actors(rom, actor_func, room_data, scene, alternate=None): + actors = {} + room_start = alternate if alternate else room_data + command = 0 + while command != 0x14: # 0x14 = end header + command = rom.read_byte(room_data) + if command == 0x01: # actor list + actor_count = rom.read_byte(room_data + 1) + actor_list = room_start + (rom.read_int32(room_data + 4) & 0x00FFFFFF) + for _ in range(0, actor_count): + actor_id = rom.read_int16(actor_list) + entry = actor_func(rom, actor_id, actor_list, scene) + if entry: + actors[actor_list] = entry + actor_list = actor_list + 16 + if command == 0x18: # Alternate header list + header_list = room_start + (rom.read_int32(room_data + 4) & 0x00FFFFFF) + for alt_id in range(0,3): + header_data = room_start + (rom.read_int32(header_list) & 0x00FFFFFF) + if header_data != 0 and not alternate: + actors.update(room_get_actors(rom, actor_func, header_data, scene, room_start)) + header_list = header_list + 4 + room_data = room_data + 8 + return actors + + +def scene_get_actors(rom, actor_func, scene_data, scene, alternate=None, processed_rooms=None): + if processed_rooms == None: + processed_rooms = [] + actors = {} + scene_start = alternate if alternate else scene_data + command = 0 + while command != 0x14: # 0x14 = end header + command = rom.read_byte(scene_data) + if command == 0x04: #room list + room_count = rom.read_byte(scene_data + 1) + room_list = scene_start + (rom.read_int32(scene_data + 4) & 0x00FFFFFF) + for _ in range(0, room_count): + room_data = rom.read_int32(room_list); + + if not room_data in processed_rooms: + actors.update(room_get_actors(rom, actor_func, room_data, scene)) + processed_rooms.append(room_data) + room_list = room_list + 8 + if command == 0x0E: #transition actor list + actor_count = rom.read_byte(scene_data + 1) + actor_list = scene_start + (rom.read_int32(scene_data + 4) & 0x00FFFFFF) + for _ in range(0, actor_count): + actor_id = rom.read_int16(actor_list + 4) + entry = actor_func(rom, actor_id, actor_list, scene) + if entry: + actors[actor_list] = entry + actor_list = actor_list + 16 + if command == 0x18: # Alternate header list + header_list = scene_start + (rom.read_int32(scene_data + 4) & 0x00FFFFFF) + for alt_id in range(0,3): + header_data = scene_start + (rom.read_int32(header_list) & 0x00FFFFFF) + if header_data != 0 and not alternate: + actors.update(scene_get_actors(rom, actor_func, header_data, scene, scene_start, processed_rooms)) + header_list = header_list + 4 + + scene_data = scene_data + 8 + return actors + +def get_actor_list(rom, actor_func): + actors = {} + scene_table = 0x00B71440 + for scene in range(0x00, 0x65): + scene_data = rom.read_int32(scene_table + (scene * 0x14)); + actors.update(scene_get_actors(rom, actor_func, scene_data, scene)) + return actors + +def get_override_itemid(override_table, scene, type, flags): + for entry in override_table: + if len(entry) == 4 and entry[0] == scene and (entry[1] & 0x07) == type and entry[2] == flags: + return entry[3] + return None + +def update_chest_sizes(rom, override_table): + def get_chest(rom, actor_id, actor, scene): + if actor_id == 0x000A: #Chest Actor + actor_var = rom.read_int16(actor + 14) + return [scene, actor_var & 0x001F] + + chest_list = get_actor_list(rom, get_chest) + for actor, [scene, flags] in chest_list.items(): + item_id = get_override_itemid(override_table, scene, 1, flags) + + if None in [actor, scene, flags, item_id]: + continue + # Do not change the size of the chest under the grave in Dodongo's Cavern MQ. + if scene == 1 and flags == 1: + continue + + itemType = 0 # Item animation + + if item_id >= 0x80: # if extended item, always big except from exception list + itemType = 0 if item_id in chestAnimationExtendedFast else 1 + elif rom.read_byte(0xBEEE8E + (item_id * 6) + 2) & 0x80: # get animation from rom, ice trap is big + itemType = 0 # No animation, small chest + else: + itemType = 1 # Long animation, big chest + # Don't use boss chests + + default = rom.read_int16(actor + 14) + chestType = default & 0xF000 + newChestType = chestTypeMap[chestType][itemType] + default = (default & 0x0FFF) | newChestType + rom.write_int16(actor + 14, default) + +def set_grotto_id_data(rom): + def set_grotto_id(rom, actor_id, actor, scene): + if actor_id == 0x009B: #Grotto + actor_zrot = rom.read_int16(actor + 12) + actor_var = rom.read_int16(actor + 14); + grotto_scene = actor_var >> 12 + grotto_entrance = actor_zrot & 0x000F + grotto_id = actor_var & 0x00FF + + if grotto_scene == 0 and grotto_entrance in [2, 4, 7, 10]: + grotto_scenes.add(scene) + rom.write_byte(actor + 15, len(grotto_scenes)) + + grotto_scenes = set() + + get_actor_list(rom, set_grotto_id) + +def set_deku_salesman_data(rom): + def set_deku_salesman(rom, actor_id, actor, scene): + if actor_id == 0x0195: #Salesman + actor_var = rom.read_int16(actor + 14) + if actor_var == 6: + rom.write_int16(actor + 14, 0x0003) + + get_actor_list(rom, set_deku_salesman) + +def get_locked_doors(rom, world): + def locked_door(rom, actor_id, actor, scene): + actor_var = rom.read_int16(actor + 14) + actor_type = actor_var >> 6 + actor_flag = actor_var & 0x003F + + flag_id = (1 << actor_flag) + flag_byte = 3 - (actor_flag >> 3) + flag_bits = 1 << (actor_flag & 0x07) + + # If locked door, set the door's unlock flag + if world.shuffle_smallkeys == 'remove': + if actor_id == 0x0009 and actor_type == 0x02: + return [0x00D4 + scene * 0x1C + 0x04 + flag_byte, flag_bits] + if actor_id == 0x002E and actor_type == 0x0B: + return [0x00D4 + scene * 0x1C + 0x04 + flag_byte, flag_bits] + + # If boss door, set the door's unlock flag + if world.shuffle_bosskeys == 'remove': + if actor_id == 0x002E and actor_type == 0x05: + return [0x00D4 + scene * 0x1C + 0x04 + flag_byte, flag_bits] + + return get_actor_list(rom, locked_door) + +def place_shop_items(rom, world, shop_items, messages, locations, init_shop_id=False): + if init_shop_id: + place_shop_items.shop_id = 0x32 + + shop_objs = { 0x0148 } # Sold Out + messages + for location in locations: + shop_objs.add(location.item.object) + if location.item.type == 'Shop': + rom.write_int16(location.address, location.item.index) + else: + shop_id = place_shop_items.shop_id + rom.write_int16(location.address, shop_id) + shop_item = shop_items[shop_id] + + shop_item.object = location.item.object + shop_item.model = location.item.model - 1 + shop_item.price = location.price + shop_item.pieces = 1 + shop_item.get_item_id = location.default + shop_item.func1 = 0x808648CC + shop_item.func2 = 0x808636B8 + shop_item.func3 = 0x00000000 + shop_item.func4 = 0x80863FB4 + + message_id = (shop_id - 0x32) * 2 + shop_item.description_message = 0x8100 + message_id + shop_item.purchase_message = 0x8100 + message_id + 1 + + shuffle_messages.shop_item_messages.extend( + [shop_item.description_message, shop_item.purchase_message]) + + if location.item.dungeonitem or location.item.type == 'FortressSmallKey': + split_item_name = location.item.name.split('(') + split_item_name[1] = '(' + split_item_name[1] + if world.world_count > 1: + description_text = '\x08\x05\x41%s %d Rupees\x01%s\x01\x05\x42Player %d\x05\x40\x01Special deal! ONE LEFT!\x09\x0A\x02' % (split_item_name[0], location.price, split_item_name[1], location.item.world.id + 1) + else: + description_text = '\x08\x05\x41%s %d Rupees\x01%s\x01\x05\x40Special deal! ONE LEFT!\x01Get it while it lasts!\x09\x0A\x02' % (split_item_name[0], location.price, split_item_name[1]) + purchase_text = '\x08%s %d Rupees\x09\x01%s\x01\x1B\x05\x42Buy\x01Don\'t buy\x05\x40\x02' % (split_item_name[0], location.price, split_item_name[1]) + else: + shop_item_name = getSimpleHintNoPrefix(location.item) + + if world.world_count > 1: + description_text = '\x08\x05\x41%s %d Rupees\x01\x05\x42Player %d\x05\x40\x01Special deal! ONE LEFT!\x09\x0A\x02' % (shop_item_name, location.price, location.item.world.id + 1) + else: + description_text = '\x08\x05\x41%s %d Rupees\x01\x05\x40Special deal! ONE LEFT!\x01Get it while it lasts!\x09\x0A\x02' % (shop_item_name, location.price) + purchase_text = '\x08%s %d Rupees\x09\x01\x01\x1B\x05\x42Buy\x01Don\'t buy\x05\x40\x02' % (shop_item_name, location.price) + + update_message_by_id(messages, shop_item.description_message, description_text, 0x03) + update_message_by_id(messages, shop_item.purchase_message, purchase_text, 0x03) + + place_shop_items.shop_id += 1 + + return shop_objs + +# Format: (Title, Sequence ID) +bgm_sequence_ids = [ + ('Hyrule Field', 0x02), + ('Dodongos Cavern', 0x18), + ('Kakariko Adult', 0x19), + ('Battle', 0x1A), + ('Boss Battle', 0x1B), + ('Inside Deku Tree', 0x1C), + ('Market', 0x1D), + ('Title Theme', 0x1E), + ('House', 0x1F), + ('Jabu Jabu', 0x26), + ('Kakariko Child', 0x27), + ('Fairy Fountain', 0x28), + ('Zelda Theme', 0x29), + ('Fire Temple', 0x2A), + ('Forest Temple', 0x2C), + ('Castle Courtyard', 0x2D), + ('Ganondorf Theme', 0x2E), + ('Lon Lon Ranch', 0x2F), + ('Goron City', 0x30), + ('Miniboss Battle', 0x38), + ('Temple of Time', 0x3A), + ('Kokiri Forest', 0x3C), + ('Lost Woods', 0x3E), + ('Spirit Temple', 0x3F), + ('Horse Race', 0x40), + ('Ingo Theme', 0x42), + ('Fairy Flying', 0x4A), + ('Deku Tree', 0x4B), + ('Windmill Hut', 0x4C), + ('Shooting Gallery', 0x4E), + ('Sheik Theme', 0x4F), + ('Zoras Domain', 0x50), + ('Shop', 0x55), + ('Chamber of the Sages', 0x56), + ('Ice Cavern', 0x58), + ('Kaepora Gaebora', 0x5A), + ('Shadow Temple', 0x5B), + ('Water Temple', 0x5C), + ('Gerudo Valley', 0x5F), + ('Potion Shop', 0x60), + ('Kotake and Koume', 0x61), + ('Castle Escape', 0x62), + ('Castle Underground', 0x63), + ('Ganondorf Battle', 0x64), + ('Ganon Battle', 0x65), + ('Fire Boss', 0x6B), + ('Mini-game', 0x6C) +] + +def randomize_music(rom): + # Read in all the Music data + bgm_data = [] + for bgm in bgm_sequence_ids: + bgm_sequence = rom.read_bytes(0xB89AE0 + (bgm[1] * 0x10), 0x10) + bgm_instrument = rom.read_int16(0xB89910 + 0xDD + (bgm[1] * 2)) + bgm_data.append((bgm_sequence, bgm_instrument)) + + # shuffle data + random.shuffle(bgm_data) + + # Write Music data back in random ordering + for bgm in bgm_sequence_ids: + bgm_sequence, bgm_instrument = bgm_data.pop() + rom.write_bytes(0xB89AE0 + (bgm[1] * 0x10), bgm_sequence) + rom.write_int16(0xB89910 + 0xDD + (bgm[1] * 2), bgm_instrument) + + # Write Fairy Fountain instrument to File Select (uses same track but different instrument set pointer for some reason) + rom.write_int16(0xB89910 + 0xDD + (0x57 * 2), rom.read_int16(0xB89910 + 0xDD + (0x28 * 2))) + +def disable_music(rom): + # First track is no music + blank_track = rom.read_bytes(0xB89AE0 + (0 * 0x10), 0x10) + for bgm in bgm_sequence_ids: + rom.write_bytes(0xB89AE0 + (bgm[1] * 0x10), blank_track) + +def boss_reward_index(world, boss_name): + code = world.get_location(boss_name).item.code + if code >= 0x6C: + return code - 0x6C + else: + return 3 + code - 0x66 + +def configure_dungeon_info(rom, world): + mq_enable = world.quest == 'mixed' + mapcompass_keysanity = world.settings.enhance_map_compass + + bosses = ['Queen Gohma', 'King Dodongo', 'Barinade', 'Phantom Ganon', + 'Volvagia', 'Morpha', 'Twinrova', 'Bongo Bongo'] + dungeon_rewards = [boss_reward_index(world, boss) for boss in bosses] + + codes = ['DT', 'DC', 'JB', 'FoT', 'FiT', 'WT', 'SpT', 'ShT', + 'BW', 'IC', 'Tower (N/A)', 'GTG', 'Hideout (N/A)', 'GC'] + dungeon_is_mq = [1 if world.dungeon_mq.get(c) else 0 for c in codes] + + rom.write_int32(rom.sym('cfg_dungeon_info_enable'), 1) + rom.write_int32(rom.sym('cfg_dungeon_info_mq_enable'), int(mq_enable)) + rom.write_int32(rom.sym('cfg_dungeon_info_mq_need_map'), int(mapcompass_keysanity)) + rom.write_int32(rom.sym('cfg_dungeon_info_reward_need_compass'), int(mapcompass_keysanity)) + rom.write_int32(rom.sym('cfg_dungeon_info_reward_need_altar'), int(not mapcompass_keysanity)) + rom.write_bytes(rom.sym('cfg_dungeon_rewards'), dungeon_rewards) + rom.write_bytes(rom.sym('cfg_dungeon_is_mq'), dungeon_is_mq) diff --git a/README.html b/README.html new file mode 100644 index 000000000..cb0241ae0 --- /dev/null +++ b/README.html @@ -0,0 +1,436 @@ +

OoTRandomizer

+

This is a randomizer for The Legend of Zelda: Ocarina of Time for the Nintendo 64.

+

Installation

+

It is strongly suggested users get the latest release from here: https://github.com/AmazingAmpharos/OoT-Randomizer/releases . Simply download the .msi installer and run it. We support Windows, Mac, and Linux machines.

+

If you have an incompatible OS or you simply wish to run the script raw, clone this repository and either run '''Gui.py''' for a graphical interface or '''OoTRandomizer.py''' for the command line version. Both require Python 3.5+. This will be fully featured, but the seeds you generate will have different random factors than the bundled release.

+

This randomizer requires The Legend of Zelda: Ocarina of Time version 1.0 NTSC-US version. This randomizer includes an in-built decompressor, but if the user wishes a pre-decompressed ROM may be supplied as input. Please be sure your input ROM filename is either a .n64 or .z64 file. For users playing via any means other than on real N64 hardware, the use of the "Compress patched ROM" flag is strongly encouraged as uncompressed ROMs are impossible to inject for the Virtual Console and have random crashing problems on all emulators.

+

For general use, the recommended emulator is RetroArch; it has been shown to work with minimal issues. Bizhawk and Mupen64plus are generally good choices too. If you want to play on Project 64 for whatever reason, you can but you will need to set the rando to use 8 MB of RAM and will want to play with the cheat code 8109C58A 0000 to partially fix Project 64's tragically poor handling of OoT's pause menu. Project 64 also has one particular crash that only happens for some unknown settings configurations; we cannot support this. I cannot emphasize enough that it is a discouraged emulator to use.

+

General Description

+

This program takes The Legend of Zelda: Ocarina of Time and randomizes the locations of the items for a more dynamic play experience. Proper logic is used to ensure every seed is possible to complete without the use of glitches and will be safe from the possibility of softlocks with any possible usage of keys in dungeons.

+

The items that randomize currently are all items within chests including those in grottos, items given as rewards by NPCs including from minigames and Deku Scrub Salesmen, the items given by freestanding Pieces of Heart, Heart Containers, and Keys, and the items obtained when getting the Bottle and the Fire Arrows at Lake Hylia or the Ocarina of Time from the Castle Town moat. All dungeons will always have the same number of Maps, Compasses, Small Keys, and Boss Keys they had in the original game, but which chests within those dungeons have those things is random. The item pool will contain a Biggoron Sword that will not interfere with Medigoron's sale of the Giant's Knife (which is always vanilla), and a randomly selected adult trading quest item other than the Odd Potion will be somewhere in the item pool.

+

Certain types of items are now "progressive", meaning that no matter what order the player encounters these items they will function as a series of upgrades. The following item types will be progressive chains:

+

-Hookshot to Longshot -Bomb Bag to Big Bomb Bag to Biggest Bomb Bag -Goron Bracelet to Silver Gauntlets to Gold Gauntlets -Slingshot to Big Bullet Bag to Biggest Bullet Bag -Bow to Big Quiver to Biggest Quiver -Silver Scale to Gold Scale -Adult Wallet to Giant's Wallet -Deku Stick Capacity Upgrades -Deku Nut Capacity Upgrades -Magic Meter to Double Magic
-Fairy Ocarina to Ocarina of Time

+

To be more clear about which NPC items are shuffled, it's only the one time permanent item rewards for the most part like NPCs who originally gave Pieces of Heart or inventory items. The only exception is that even though in vanilla the reward for 40 Gold Skulltula Tokens was just 10 Bombchus that is still a randomized reward in randomizer (but the 200 rupees for all 100 Gold Skulltula Tokens is not randomized so the most tokens that could be required to complete a seed is 50). As a mercy to the player, the Ocarina Memory Game in the Lost Woods will start on the final round as that minigame was very long originally, the three day wait on the Claim Check is removed, Bombchu Bowling will have a fixed sequence of prizes that is of maximum convenience to the player, Dampe's Gravedigging Tour will always be won on the first dig, and the fishing minigame is made much simpler (8 lb fish for child now, 10 lb for adult). Additionally, any NPC who gives a trading quest item either for the child or for the adult other than Anju's initial gift as an adult does not have a randomized reward.

+

A special note is needed for the six Great Fairy Fountains scattered across Hyrule. All six of these fountains now give random item rewards, and the magic and life upgrades can now be found as normal items scattered around the world. Happy hunting!

+

The Ocarina songs are shuffled in a pool amongst themselves, and each learn spot will still have the original conditions it has always had. These conditions may not have all been obvious, but here are some high points. Saria will teach her song after completing the events in the Castle Courtyard. The warp songs can mostly only be learned by an adult, but the location for Requiem of Spirit is available for even a child if the Desert Colossus can be reached. The location for the Prelude of Light requires the Forest Medallion, and the location for the Nocturne of Shadow requires the Forest Medallion, Fire Medallion, and Water Medallions. A setting exists to shuffle all songs into the general item pool instead of limiting them to song specific slots.

+

Speaking of Medallions, each boss in the eight main dungeons will drop a random Spiritual Stone or Medallion, and instead of the Light Medallion being granted by the now removed "becoming an adult" cutscene, the player will start every seed with a random Spiritual Stone or Medallion. The pedestal in which the Spiritual Stones rest in the Temple of Time has hint text pointing to the locations of the Spiritual Stones and Medallions. A child will be able to read hints for the Spiritual Stones while an adult will be able to read hints for the Medallions. This information and some other relevant dungeon based info can be seen in the pause menu by holding the "A" button on the c-item menu.

+

To be very clear on this point, while the rewards for up to 50 Gold Skulltula Tokens are randomized, the tokens themselves are not.

+

As a service to the player in this very long game, many cutscenes have been greatly shortened or removed and text is as often as possible either omitted or sped up. We have been as thorough as our exploration of the game and various technical limitations will allow to make the parts of the game where you're watching and reading as short as possible to make as much of your time with this randomizer as possible actual gameplay. I'm sure someone somewhere will miss the owl's interjections; to that person, I'm sorry I guess?

+

A few bugs or other undesirable behaviors in the original game have been fixed. Of note, obtaining the Poacher's Saw will no longer prevent the player from obtaining the reward in the Deku Theater for showing the Mask of Truth, and becoming an adult will not automatically equip the child with the Kokiri Sword. Sheik will no longer prevent the player from returning to childhood before obtaining the Forest Medallion. Princess Ruto will never disappear from Jabu Jabu's Belly, and the condition for the Castle Courtyard being sealed off is now completing the events within as opposed to seeing the Ocarina of Time be thrown into the moat.

+

One small detail that is important to know is that the locked door in the Fire Temple leading to the section with the Boss Key Chest is removed. This was necessary due to the original design of the Fire Temple assuming that the player could not possibly have the Hammer before unlocking the doors leading into the depths of the dungeon. This is obviously not true in randomizer, and of all possible solutions to this problem, this seemed the least disruptive. A full clear of the Fire Temple will simply result in the player having one extra Small Key. Certain settings configurations will disable this behavior.

+

Two similar small details apply to the Master Quest versions of dungeons. In Water Temple MQ, a locked door leading to a Gold Skulltula in the northern basement was glitched such that it would not appear in the Gamecube release of Master Quest but was fixed in OoT3D's version of Master Quest. In the randomizer, the locked door works like an ordinary locked door similar to OoT3D. In Spirit Temple MQ, there is a particular chest that requires hitting a switch in a hole that the adult will later push a silver block into. The randomizer does some wizardry under the hood to ensure that the block will never be in the way for the child.

+

To be clear about the logic rules of what can be where, the randomizer will ensure a glitchless path through the seed will exist, but the randomizer will not prevent the use of glitches for those players who enjoy that sort of thing though we offer no guarantees that all glitches will have identical behavior to the original game. Glitchless can still mean that clever or unintuitive strategies may be required involving the use of things like Hover Boots, the Hookshot, or Scarecrow's Song that may not have been important options in the original game. The Lens of Truth is guaranteed available and useable before completion of the Treasure Chest Game is required or before walking through any invisible objects or opening any invisible chests is required with the exception of the one invisible wall that is required to enter the Bottom of the Well as the original game required passing that invisible wall to reach the Lens of Truth.

+

One last detail is that the menu is now more like the Majora's Mask menu in that the player can move the cursor through empty spaces. This fixes a major problem from the original game in that certain combinations of items would create menu shapes that would be impossible to fully menu through. As of version 3.0, this fix extends to the "equipment" subscreen as well.

+

Quirks to Know

+

While all the details of gameplay can't be detailed here, I want to inform you of a few non-obvious game sequences that are likely to get you stuck and one little glitch we can do nothing about.

+

-The condition to open the Door of Time is merely playing the Song of Time; the Spiritual Stones are not required. If you enter the Temple of Time via the Prelude of Light, playing the Song of Time will create a glitchy cutscene and will not open the door (but you're safe to exit and re-enter and open it properly).
-The condition to spawn the Ocarina of Time and learn that song is the three Spiritual Stones. The condition to learn a song from Sheik in the Temple of Time is possessing the Forest Medallion. The condition to learn a song from Sheik in Kakariko is possessing Forest, Fire, and Water Medallions.
-The running man in Hyrule Field only spawns if you have all three Spiritual Stones.
-Skull Kid will only buy the Skull Mask if you have played Saria's Song for him.
-The center of Death Mountain Crater as an adult can be reached from the summit as an adult by going around to the left with Hover Boots or by jumping down to the right and using a combination of the Longshot and Scarecrow's Song. This allows access to Sheik and the Fire Temple without a Bomb Bag.
-A sword must be equipped to play the fishing minigame. A Slingshot is not required for child target shooting, but the adult does need the Bow to receive the true prize.
-Other than the fishing minigame, the child can do anything that would seem to require the sword with Deku Sticks. You can buy as many as you want in the Kokiri Forest shop.
-In the randomizer, possessing the Bomb Bag is the requirement to get bomb drops, buy bombs or Bombchus, or play Bombchu Bowling. If the setting "Bombchus Are Considered in Logic" is used, finding any pack of Bombchus allows purchasing Bombchus and playing Bombchu Bowling while possessing a Bomb Bag allows the purchase of bombs.
-Only the Hookshot, not the Longshot, is needed to do everything on the rooftops of Kakariko.
-Grottos can be opened with either Bombs or the Hammer.
-The boulder maze in Goron City can be solved with the Hammer or partially with Bombs as is obvious, but less obvious is that it can be fully solved with Silver Gauntlets.
-The large colored blocks only encountered by the adult require Goron Bracelet to push.
-In a few places, out of sight Song of Time blocks can be summoned. The lava room in Gerudo Training Grounds, the beginning of Ganon's Castle Shadow Trial, and the last hallway with a caged Goron in Fire Temple are the main cases. -Adult Link can fully clear Dodongo's Cavern. He can even skip the first section by virtue of being tall.
-In the Forest Temple, you can reach the room with the Floormaster (vanilla) or Redead (MQ) early by using Hover Boots in the block push room.
-In the Fire Temple, you can reach the Boss Key door from the beginning with Hover Boots.
-In the Water Temple, you can from the start with the water down jump to the middle platform level, very carefully aim the Hookshot to the target above, and pull yourself to the highest level of the central platform. Then a very well spaced rolling jump can reach the water changing station to raise the water to the highest level. If you make poor key choices in Water Temple, this may be what you need to do to untangle the situation.
-In the Water Temple, Hover Boots can be used to reach the vanilla Boss Key chest without going through the room that requires Bombs and block pushing. Hover Boots can also be used in this temple to avoid the Longshot requirement for the middle level chest that requires the Bow.
-In the Water Temple, Farore's Wind can be placed in the central pillar and then the water can be raised to the highest level in order to reach the Gold Skulltula without the Longshot.
-In the Shadow Temple, you can avoid the need for the Longshot in the room with the invisible spikes by backflipping onto the chest for extra height.
-In the Shadow Temple, you can Hookshot the ladder to avoid pushing the block to get on the boat.
-In the Shadow Temple, a combination of the scarecrow and the Longshot can be used to reach Bongo Bongo without needing the Bow.
-In the Spirit Temple, the child can obtain the vanilla Map chest with Deku Sticks. No fire magic is needed.
-In the Spirit Temple, you can collect the silver rupees without Hover Boots by jumping directly onto the rolling boulder or with a jump slash.
-In the Spirit Temple, you can use the Longshot to cross from the hand with the Mirror Shield in vanilla to the other hand.
-In Ganon's Castle Spirit Trial, the web can be burned with a precise shot through the torch by a normal arrow. Fire Arrows are not required.
-Like Likes now only eat shields and not tunics.
-Several Gold Skulltula Tokens can be reached by clever/precise uses of jump slashes and spin attacks (possibly magic spin attacks).
-This is not a randomizer exclusive mechanic, but getting the ability to summon Pierre the Scarecrow requires playing an eight note song for Bonooru the Scarecrow as a child first and then the exact same song for him again as an adult.

+

Known issues

+

Sadly for this 3.0 release a few known issues exist. These will hopefully be addressed in future versions.

+

-The fishing minigame sometimes refuses to allow you to catch fish when playing specifically on Bizhawk. Save and quit (NOT savestate) and return to fix the issue.
-Draining the Bottom of the Well with Song of Storms sometimes crashes on specific configurations of Project 64. We aren't sure of the exact story, but this bug is easily avoided by playing on a different emulator and probably also avoidable by changing your settings and maybe graphics plug-in.
-Executing the collection delay glitch on various NPCs may have unpredictable and undesirable consequences. In particular this can be devastating with Biggoron; it is strongly suggested the player save before turning in the Claim Check.
-Saving and quitting on the very first frame after becomming an adult when you would trigger the Light Arrow cutscene can have undesired consequences. Just don't do that.
-This randomizer is based on the 1.0 version of Ocarina of Time so some of its specific bugs remain. Some of these like "empty bomb" can be disadvantagous to the player.

+

Settings

+

The OoT Randomizer has many different settings users can choose to customize their play experience. Here's a fully detailed list!

+

ROM Options

+

Base Rom

+

Specify the input ROM that will be used by the randomizer. Please be sure it is OoT US v1.0.

+

Output Directory

+

Specify where the output ROM will be written on your computer.

+

Create Spoiler Log

+

Decide whether to output a text file detailing where every item can be found and the sequence of play that will lead to seed completion. Selecting this option will create a different item configuration than using otherwise identical settings without printing a log; this is intended to prevent cheating in race environments.

+

Compress Rom

+

Decide the format of the output ROM. Compressed is generally recommended for most users; this is necessary for injection into a .wad for use on the Virtual Console, and all known N64 emulators have significant crashing problems with uncompressed ROMs. Real N64 hardware doesn't care so generation time can be improved by using the uncompressed option if you are playing on a real N64 with a flash cart. You can also choose not to output a ROM at all; this is useful if you just want to look at spoiler logs.

+

Default Targeting Option

+

This option specifies whether Z-targeting will default to "Switch" or "Hold" style. Either way, this can still be changed in-game as per usual.

+

Multi-World Generation

+

This option allows for multiple worlds to be generated to be used in co-op play. Each player will get a different ROM designed to work in conjunction with another to allow two players to work together to complete the game. Synchronization can be achieved on Bizhawk via the following script:

+

https://github.com/TestRunnerSRL/bizhawk-co-op

+

Player Count

+

Use this to specify how many players will be participating in this co-op playthrough.

+

Player ID

+

Use this to specify which player number you are in particular. Each participant in the co-op should choose a different number starting with 1.

+

Setting String

+

This is an 18 character string that specifies the totality of other gameplay relevant (non-cosmetic) settings used throughout the randomizer. This string can be shared between players and then the "Import Settings String" button can be pressed to automatically change all settings to match another player.

+

Seed

+

This is a string representing the particular configuration of items that will occur in your seed; the purpose is to combine a seed string with an identical settings string such that the randomizer will be able to generate the same game for multiple players. If this field is left blank, a random seed will be chosen.

+

Main Rules

+

Open Forest

+

Mido does not need to see a sword and shield to reach the Deku Tree and the Kokiri boy blocking the exit to the forest is gone. If this flag is not set, it is guaranteed that the Deku Tree can be completed without leaving the forest. This means that within the forest or the Deku Tree itself it will be possible to find the Kokiri Sword, Deku Shield for sale, and the Slingshot.

+

Open Kakariko Gate

+

The gate leading up Death Mountain from Kakariko Village is open from the beginning of the game. Normally this requires Zelda's Letter to open. This allows more diverse routing early in the game and prevents very long walks in seeds with the Weird Egg shuffled. Two things are important to note. Showing Zelda's Letter to the guard is still required to begin the Happy Mask sidequest and to receive a discount on purchasing Hylian Shields. The gate is simply gone for an adult no matter what.

+

Open Door of Time

+

The Door of Time is open from the beginning of the game. The Song of Time is still potentially useful to move Song of Time blocks, play songs for the frogs on Zora River, or for other such uses. If this flag is not used, the Door of Time must be opened to become an adult as in the original game, but all that is needed to open the Door of Time is the Song of Time and any ocarina. The Ocarina of Time in particular and the Spiritual Stones have nothing to do with this.

+

Gerudo Fortress

+

Default Behavior

+

Gerudo Fortress will work the same way it did in the original game. All four carpenters must be rescued in order for the Gerudo woman who gives the Gerudo Card to appear and for the Gerudo to stop being hostile. Rescuing a carpenter requires having a Gerudo Fortress Small Key and defeating the corresponding guard.

+

Rescue One Carpenter

+

Only the bottom left carpenter must be rescued to complete Gerudo Fortress. Only one Gerudo Fortress Small Key will exist because of this.

+

Start with Gerudo Card

+

The player will start with the Gerudo Card from the beginning of the game. The carpenters will be pre-rescued, and the bridge to Gerudo Fortress as an adult will be repaired from the beginning. The Gerudo Card is the requirement in the randomizer to enter Gerudo Training Grounds so it will be an accessible area from the moment adulthood is available.

+

Rainbow Bridge Requirement

+

This determines the condition under which the rainbow bridge to Ganon's Castle will spawn.

+

All Dungeons

+

The rainbow bridge spawn requires all medallions and spiritual stones to be in the player's possession.

+

All Medallions

+

All six of the medallions are required to open Ganon's Castle.

+

Vanilla

+

The rainbow bridge spawns under the same conditions it did in the original game, possession of the Light Arrows and having viewed the Zelda cutscene. This cutscene in the Temple of Time is triggered by possessing the Shadow and Spirit Medallions.

+

Open

+

The rainbow bridge is always present.

+

Random Number of Ganon's Trials

+

A random number of trials within Ganon's Castle from 0 to 6 will be chosen, and individual trials will be randomly disabled as necessary to match this number. Alternatively, a specific number of trials can be specified with the slider below. If a number of trials other than 0 or 6 is chosen and hints are enabled, hints will be added to the hint pool informing the player which trials are present (if 1 to 3 trials) or which are missing (if 4 or 5 trials).

+

All Locations Reachable

+

This option will set the logic to try to ensure Link can reach every item location in the game with the exception of "key for key" item locations (a single item spot behind a locked door containing the key to open the door). If this option is not used, the logic will allow some items to be in impossible locations so long as the set of reachable items is sufficient to complete the game.

+

Bombchus Are Considered in Logic

+

This option fundamentally changes how the Bombchu items found around the world function. With this option on, Bombchus are a progression item and operate as a form of progressive item. The first Bombchu pack found will be worth 20 Bombchus and subsequent packs will be worth 10 or 5 Bombchus. Finding Bombchus will be considered as logical progression, and having found any Bombchus will be the condition to play Bombchu Bowling or buy Bombchu refills from shops. This flag will also add Bombchu (5) buyable items to the shops in Kokiri Forest, Castle Town Bazaar, and Kakariko Bazaar. With this option off, randomly found Bombchu items are not considered as logical progression, randomly found Bombchus will have specific denominations based on the values from the original game, and finding a Bomb Bag is what enables playing Bombchu Bowling and buying Bombchus from shops which will not have their inventories edited.

+

Dungeons Have One Major Item

+

This option places one "major item" and one only in each of the dungeons. For the purpose of the randomizer, the dungeons are defined as the eight dungeons that contain either Medallions or Spiritual Stones as well as Bottom of the Well, Ice Cavern, Gerudo Training Grounds, and Ganon's Castle. The major items are any item usable with a c-button that is not simply a form of ammo (Bombchus are major only if "Bombchus are considered in logic" is on), songs, Mirror Shield, swords, tunics, boots, Double Defense, Magic Meter/Double Magic, Bullet Bags, Quivers, Bomb Bags, Strength Upgrades, Scales, Wallets, and the Stone of Agony. To be clear, this means that rupees, ammo, Deku Stick and Deku Nut ammo expansions, Pieces of Heart, Heart Containers, Gold Skulltula Tokens, Maps, Compasses, Small Keys, Boss Keys, Deku Shields, Hylian Shields, and Ice Traps are not considered major items. However, Small Keys and Boss Keys are considered major items if the appropriate "keysanity" settings are used. Note that unlike with the distribution of dungeon specific items like keys, this flag does consider the hands of the Desert Colossus as Spirit Temple locations, and to mirror the original game, Spirit Temple will get two items instead of just one.

+

Dungeon Quest

+

This option specifies the form dungeons will take. The item pool will be updated to reflect the items originally found in the dungeons used.

+

Vanilla

+

Dungeons will have the same internal layout as they did in the original The Legend of Zelda: Ocarina of Time.

+

Master Quest

+

Dungeons will have the internal layouts found in The Legend of Zelda: Ocarina of Time Master Quest.

+

Mixed

+

Dungeons will each have a random internal layout chosen between the vanilla and Master Quest forms.

+

Shuffle Kokiri Sword

+

This flag adds the Kokiri Sword to the shuffle. With it off, the Kokiri Sword will always be found in its original chest in the Kokiri Forest.

+

Shuffle Weird Egg

+

This flag adds the Weird Egg given by child Malon to the shuffle. With this flag on, child Malon will give a random item and the Weird Egg must be located to do the events at Hyrule Castle with Zelda and Impa. These events block interacting with Talon and Malon at Lon Lon Ranch as a child as well as Saria in Sacred Forest Meadow and the Happy Mask sidequest.

+

Shuffle Ocarinas

+

This flag adds both the Fairy Ocarina and the Ocarina of Time to the shuffle. The ocarinas are a progressive item; the first found will always be the Fairy Ocarina with the second being the Ocarina of Time even though the two are functionally identical. Without this flag on, leaving the Kokiri Forest to the Lost Woods bridge as a child will always grant one Ocarina and the other is always available at the gate of Castle Town as a child when all three Spiritual Stones are in the player's possession.

+

Shuffle Songs with Items

+

This flag adds the 12 standard ocarina songs to the shuffle as normal items. With this flag on, the spots that contained songs in the original game will simply give Link a random item, and the songs can be found as items freely. Without this flag on, songs are still randomized but only between each other. In either case, the Scarecrow's Song is not affected; it is still obtained by interacting with Bonooru at Lake Hylia first as a kid and then as an adult.

+

Shuffle Gerudo Card

+

This flag shuffles the Gerudo Card into the general item pool. In the randomizer, this is required to gain access to Gerudo Training Grounds, but it does not have any impact on the hostility of the Gerudo in Gerudo Fortress who still check for the carpenter rescue events. Without this flag, the Gerudo Card is always given by the Gerudo woman who spawns after the final carpenter is rescued. If Gerudo Fortress is cleared from the beginning of the game, the player starts the game with the Gerudo Card and this setting is voided.

+

Shuffle Deku Salescrubs

+

This flag makes every Deku Scrub Salesman in the world sell a random item instead of only the three that sold permanent upgrades in the original game. Using this flag adds the various low tier items the other scrubs sold to the item pool for the most part; the potion refills are replaced with Recovery Hearts for Red Potions and blue rupees for Green Potions. For each Deku Scrub that sold arrows/seeds depending on age, there will be a 75% chance of adding a 30 arrow item and a 25% chance of adding a 30 seed item to the pool. If this is set, once a Deku Scrub Salesman is used, it will disappear from the world forever. The individual settings in the dropdown can be used to set the price of each Deku Scrub Salesman to 10 rupees, leave the prices as what they were in the original game, or set each price to a random value from 0 to 99 rupees. In all cases, the text for the Deku Scrub Salesmen will not update.

+

Shopsanity

+

This setting randomizes the items sold in shops. When it is used, all shop items are randomly re-arranged among all 8 of the original game's shops. This setting causes the Bombchu Shop to be open from the very beginning of the game, and this setting considers the two shops in adult Kakariko Village to be distinct shops from the two similar shops in child Castle Town; however, the shops in Kokiri Forest, Goron City, and Zora Domain are the same shops as both ages. This setting overrides the "Bombchus considered in logic" editing of the shop item pool.

+

Off

+

This disables the Shopsanity feature.

+

Shuffled Shops (0 Items)

+

This causes all of the Shopsanity features described above.

+

Shuffled Shops (1-4 Items)

+

This not only causes all of the Shopsanity features described above, but it also adds 1-4 (depending on the exact setting) items from the general item pool into shops to buy for randomly chosen amounts of money. Lower value shop items are removed to make room for this, and low value junk items are added to the item pool to fill the extra empty chests this will implicitly create. Using this feature will also replace several of the rupee items found throughout the seed with higher value rupees and will add a third Wallet upgrade, the "Tycoon's Wallet", to the item pool which can hold up to 999 rupees. The items from the general item pool added to shops will always be on the far left of the shop inventories, and these items can always be bought if the player has enough rupees even if they are explosives without an appropriate container or a tunic as a child.

+

Shuffled Shops (Random Items)

+

This is similar to the 1-4 items variant but gives each shop a random number of new items from 0-4. Each shop can have a different amount of unique items with this setting.

+

Shuffle Dungeon Items

+

This setting allows the player to decide the natural distribution of dungeon items. Dungeon items can be found confined to their original dungeons, spread freely throughout the world, or prevented from existing completely. Items that are prevented from existing completely will be replaced in the item pool with an assortment of various low tier junk items. This feature can be specified for Maps/Compasses, Small Keys, and Boss Keys independently. If Small Keys or Boss Keys are prevented from existing, this will also remove all locks those keys would be used for from existing as well. If Small Keys are left in their original dungeons and the Fire Temple is not in the form of Master Quest, the locked door in the first room that leads to the normal location of the Boss Key will be removed.

+

Maps and Compasses Give Information

+

This setting, only available if you start with Maps and Compasses or they are spread across the world, disables the pedestal in the Temple of Time from giving information about the location of the Medallions and Spiritual Stones. Instead, the Compass from each of the eight eligible dungeons will tell the player which dungeon has which reward. If the dungeon quest is set to mixed, each of the ten Maps will tell the player whether any given dungeon is in the vanilla or Master Quest form. The Compasses from Bottom of the Well and Ice Cavern do not give any information.

+

Remove Ganon's Door Boss Lock

+

This setting removes the Boss Key lock from Ganon's Tower. This removes the need to locate the Ganon's Tower Boss Key to finish the game.

+

Tokensanity

+

This setting shuffles the Gold Skulltula item drops into the general pool of locations. The player can choose only to include Gold skulltulas found in dungeons for a more mild version of this setting.

+

Detailed Logic

+

Maximum Expected Skulltula Tokens

+

This setting can be used to reduce the number of Gold Skulltula Tokens that may be required to finish the game.

+

No Nighttime Skulltulas without Sun's Song

+

This setting causes the logic to expect the player to have an ocarina and the Sun's Song to get Gold Skulltula locations that are only found at nighttime.

+

No Big Poes

+

This setting will guarantee that the Big Poe vendor will not have an important item.

+

No Child Fishing

+

This setting will guarantee that the reward from child fishing is not an important item. This is mostly recommended if the player simply must play on Bizhawk.

+

No Adult Fishing

+

This setting will guarantee that the reward from adult fishing is not an important item. This is mostly recommended if the player simply must play on Bizhawk.

+

No Skull Mask Reward

+

This setting will guarantee that the item obtained from showing the Skull Mask in the Deku Theater is not an important item.

+

No Mask of Truth Reward

+

This setting will guarantee that the item obtained from showing the Mask of Truth in the Deku Theater is not an important item.

+

No 1500 Horseback Archery

+

This setting will guarantee that the item obtained from scoring 1500 points at the horseback archery challenge at Gerudo Fortress is not an important item.

+

No Lost Woods Memory Game

+

This setting will guarantee that the item obtained from winning the ocarina memory game in the Lost Woods is not an important item.

+

No Racing Dampe a Second Time

+

This setting will guarantee that the item obtained from finishing with a sub-minute time in the second Dampe race is not an important item.

+

No Biggoron Reward

+

This setting will guarantee that the item obtained from showing the Claim Check to Biggoron is not an important item.

+

Adult Trade Sequence

+

This pair of settings can be used to specify the earliest and latest items that can be allowed to randomly show up in the general item pool. Only one item will be in the item pool regardless of this setting; this can merely be used to limit the range of possibilities.

+

Enable All Tricks

+

This is a button to turn on all of the trick related flags.

+

Various Advanced Tricks

+

This setting allows a huge number of minor tricks to be allowed by the logic. Here is a complete list:

+

-A precise jumpslash with either a Deku Stick or the Kokiri Sword can be used to reach a Gold Skulltula on some vines in standad Deku Tree.
-The Bow can be used to knock down the stairs in Dodongo's Cavern with two well timed shots.
-The vines in Forest Temple leading to where the well drain switch is in the standard form can be barely reached with the standard Hookshot.
-The well in Forest Temple can be crossed with just Hookshot by shooting as low as possible on the vines from the far side and swimming under the ceiling. This is possible in both versions but can only be required in Forest Temple MQ.
-A Bombchu from the ground level can be used to hit the switch to bypass the block pushing puzzle in Forest Temple MQ.
-A rusted switch under a Song of Time block in the standard Fire Temple can be hit by using Hammer into the block.
-The location with the Boss Key chest in Fire Temple MQ can be reached without the Bow with very particular use of Din's Fire.
-The upper levels of the old boulder maze in Fire Temple MQ can be reached without explosives by using the Hammer through a wall.
-In the standard Spirit Temple, the bridge on child side can be lowered with a carefully timed Bombchu.
-The frozen switch in Spirit Temple MQ can be hit without a fire source by using the Bow and Song of Time very cleverly.
-The chest in the basement of the standard Bottom of the Well can be reached with only a Strength Upgrade by using a jump slash with a lit Deku Stick to access the bomb flowers in the basement.
-The silver rupees on the left side of Gerudo Training Grounds MQ can be collected with just Hookshot with a somewhat particular jump slash.
-The first room of the Spirit Trail in Ganon's Castle MQ can be cleared without the Bow by using a Hammer jump slash to hit the rusted switch through the thrones.
-The Gold Skulltula in adult Kokiri Forest can be reached without the Hookshot by using Hover Boots off one of the roots.
-The child can reach the chest on Death Mountain trail with just the Goron Bracelet by backwalking with the Bomb Flower intended to open Dodongo's Cavern and throwing the Bomb Flower at the wall very quickly.
-Gerudo Fortress can be cleared without any items other than those needed for access. The logic normally guarantees one of the Bow, Hookshot, or Hover Boots to help navigate the "kitchen".

+

Using this setting will also pre-set all of the lower logic flags to a reasonable configuration to match the trick level. These can then be edited as the player desires if the given configuration isn't desired.

+

Man on Roof without Hookshot

+

This allows the logic to consider a trick in which the player does a sidehop off the tall tower in Kakariko Village to reach the man on the rooftop with no items.

+

Child Deadhand without Kokiri Sword

+

This allows the logic to consider defeating the Deadhand in Bottom of the Well with Deku Sticks. This is not hard with use of the power crouch stab glitch, but consistently landing actual jump slashes on his unusual hitbox is pretty difficult and using normal slashes consumes 9 Deku Sticks.

+

Dodongo's Cavern Spike Trap Room Jump without Hover Boots

+

This allows the logic to consider that the adult can make a particularly useful jump in Dodongo's Cavern to reach the area with the Bomb Bag chest early. Due to the precision of the jump, normally the logic expects Hover Boots to complete this path.

+

Windmill PoH as Adult with Nothing

+

This allows the logic to consider a jump the adult can make in the windmill to reach the Piece of Heart within with no items. The jump requires leaping from an object on which it is not obvious Link is allowed to stand and has counterintuitive timing so it is not in standard logic.

+

Crater's Bean PoH with Hover Boots

+

This allows the logic to consider using Hover Boots to reach the Piece of Heart atop the volcano in Death Mountain Crater. The path involves walking up a very steep slope that is not visibly walkable so it is not in normal logic.

+

Zora's Domain Entry with Cucco

+

This allows the logic to consider using a Cucco on Zora River to enter Zora's Domain as a child without playing Zelda's Lullaby. It requires slipping behind the waterfall trickily from the left side.

+

Zora's Domain Entry with Hover Boots

+

This allows the logic to consider this similar trick to the above except as an adult with Hover Boots. This is actually a lot more difficult even though it can be done from either side of the waterfall.

+

Fewer Tunic Requirements

+

This relaxes the tunic requirements by the logic somewhat. Normally the logic expects a Goron Tunic to enter Fire Temple or complete the Fire Trial in Ganon's Castle and a Zora Tunic to enter Water Temple, collect the underwater silver rupees in Gerudo Training Grounds, or obtain the Piece of Heart at the bottom of the frozen Zora's Fountain. With this flag set, the Goron Tunic will not be required to actually enter Fire Temple, only to fight Volvagia or to reach the upper floors. The Zora Tunic requirements are removed completely except to reach the chest at the bottom of the central pillar in Water Temple.

+

Morpha with Gold Scale

+

This setting allows entry to the Water Temple with the Gold Scale to be considered. Since you cannot backtrack into Water Temple without Iron Boots, only the Spiritual Stone or Medallion obtained from defeating Morpha can be considered by logic either way; since you need the Water Temple Boss Key and Longshot to access Morpha normally, this means that this setting is only relevant in either keysanity or keysy relative to the locations of Boss Keys.

+

Lens of Truth

+

This setting alters the expectations about interacting with invisible objects without the Lens of Truth.

+

Required Everywhere

+

This setting requires the Lens of Truth to interact with any invisible object except for whatever was required in the original game to obtain the Lens of Truth.

+

Wasteland and Chest Minigame

+

This setting expects the Lens of Truth to be used only to cross the Haunted Wasteland and to win the Treasure Chest Minigame in Castle Town at night.

+

Only Chest Minigame

+

This setting expects the Lens of Truth to be used only to win the Treasure Chest Minigame in Castle Town at night.

+

Other

+

Skip Tower Collapse Sequence

+

This setting causes defeating Ganondorf to skip directly to the Ganon fight without the need to do the collapsing Ganon's Tower sequence.

+

Skip Interior Castle Guard Stealth Sequence

+

This setting causes entering the crawlspace at Hyrule Castle to deposit the player directly into the Castle Courtyard, bypassing the guard evasion sequence.

+

Skip Epona Race

+

This setting causes Epona to be stolen from Ingo from the start of the game, only requiring Epona's Song and an ocarina as an adult to summon.

+

Fast Chest Cutscenes

+

This setting causes all chests to open with a quick animation. If this setting is off, certain important items will trigger the slow opening animation.

+

Random Big Poe Target Count

+

This setting causes the number of Big Poes that must be turned into the vendor to obtain his item to be random from 1-10. Alternatively, the number of Big Poes requires can be selected manually with the slider below. Note that Big Poes can be found as pre-stocked Bottle contents, and the logic can expect using them if the required number is sufficiently low.

+

Start with Scarecrow's Song

+

This flag causes Pierre the Scarecrow to be available to summon for the adult from the beginning of the game. The box below can be used to specify the particular desired Scarecrow's Song. This song must be exactly eight notes long and must contain at least two different notes.

+

Randomize Ocarina Song Notes

+

This flag randomizes the particular notes in the 12 standard ocarina songs. This can predictably be pretty obnoxious. In general, the patterns chosen for the top row songs will be simpler than the patterns chosen for warp songs.

+

Chest Size Matches Contents

+

This flag causes keys, Ice Traps, and items flagged as progression items to appear in large treasure chests while other items will be in small treasure chests. This means that players can choose to skip small treasure chests since they will only contain handy, not essential, items.

+

Clearer Hints

+

This flag changes the text of Gossip Stone hints to be overwhelmingly explicit. This is helpful for players who do not have English as their first language, but the hints will be less "fun" and less like the sorts of things that would be said in the original game.

+

Gossip Stones

+

This flag changes the behavior of Gossip Stones to give hints to players. The hints will be distributed as such:

+

-If the required number of trials is 1-3, a hint will be added for each trial that must be done. If the required number of trials is 4 or 5, a hint will be added for each trial that can be skipped.
-Hints will be added for every one of the "always" locations that is allowed to have a random possibly valuable item under the current settings. These hints will tell the player what item is at each of these locations. These locations are the rewards for 30, 40, and 50 Gold Skulltula Tokens, the item obtained from Biggoron by showing the Claim Check, the item obtained from the Big Poe vendor, both the song and the item slots at the Ocarina of Time, and the item obtained from showing the Mask of Truth at the Deku Theater.
-Some hints will be given for items at a randomly selected number of other locations that are generally somewhat inconvenient to check. The total number of these hints will be either 11 or 12 minus the number of always hints placed.
-3 or 4 hints will be given naming a specific non-dungeon specific item that can be found in a randomly chosen dungeon.
-1 to 4 hints will be given naming a specific item found in a specific overworld region. Which part of this range is used is determined in part by how many trial hints are given.
-4 to 6 hints will be given naming what region specific progression items other than Gold Skulltula Tokens can be found.
-3 or 4 hints will be given naming specific regions that are "on the way of the hero" and thus contain at least one required progression item.
-All remaining hints (33 total unique Gossip Stones exist) will be filled with non-information junk hints.

+

This setting allows the player to specify which item is required to interact with the Gossip Stones. The Stone of Agony is the default option as it gives a fairly purposeless vanilla item a use and allows both kid and adult to interact with the Gossip Stones. The default Mask of Truth can be used, but this has the downside that the Mask of Truth can only be obtained with all Spiritual Stones which tends to make the hints not useful, and using the Mask of Truth requires being a child which is another big downside. There is also an option for the information to just be free for those wanting an easier mode.

+

Text Shuffle

+

This setting allows all the text in the game to be shuffled. This is mostly for comedy and is not intended to be a serious gameplay option.

+

No Text Shuffled

+

Leave the text alone.

+

Shuffled except Hints and Keys

+

Shuffle all text other than the useful text giving the player information.

+

All Text Shuffled

+

Shuffle all text even to the player's mechanical disadvantage.

+

Difficulty

+

This setting allows the player to tweak the item pool to make a somewhat harder experience.

+

Normal

+

Leave the item pool alone.

+

Hard

+

Heart Containers, Double Defense, and the second Magic Upgrade are replaced with junk items. One each of the ammo expansions (Quiver, Bullet Bag, Bomb Bag Deku Stick Capacity, Deku Nut Capacity) will also be replaced with junk items, and all Bombchu pick-ups other than three will similarly be replaced with junk.

+

Very Hard

+

In addition to the items from Hard, Pieces of Heart and Nayru's Love are also replaced with junk items. One more of each ammo expansion is removed resulting in zero extra ammo capacity for those item types, and only one Bombchu pick-up can be found.

+

OHKO

+

In addition to the item changes from Very Hard, Link dies in one hit. Ice Traps are replaced with Recovery Hearts.

+

Cosmetics

+

Background Music

+

Normal

+

Do not alter the background music.

+

No Music

+

Disable background music. Sound effects will still play. This may be desired by players who like to listen to their own music.

+

Random

+

Background music is shuffled so that different tracks may play in different areas. This may be silly.

+

Kokiri Tunic Color

+

This determines the color of Link's default Kokiri Tunic. This only affects the color when he's wearing it, not the color of the icon in the menu.

+

Most Colors

+

Simply get the particular color selected. Available colors are Kokiri Green, Goron Red, Zora Blue, Black, White, Azure Blue, Vivid Cyan, Light Red, Fuchsia, Purple, MM Purple, Twitch Purple, Purple Heart, Persian Rose, Dirty Yellow, Blush Pink, Hot Pink, Rose Pink, Orange, Gray, Gold, Silver, Beige, Teal, Blood Red, Blood Orange, Royal Blue, Sonic Blue, NES Green, Dark Green, and Lumen.

+

Random Choice

+

Choose a random color from the set of pre-made colors.

+

Completely Random

+

Generate a random color with numerically random RGB values.

+

Custom Color

+

A special interface will pop up that will allow the user to choose any color from a diverse color wheel or input a desired RGB value.

+

Goron Tunic Color

+

This determines the color of Link's Goron Tunic. This only affects the color when he's wearing it, not the color of the icon in the menu or when holding it up after acquiring it. The options are identical to those for the Kokiri Tunic.

+

Zora Tunic Color

+

This determines the color of Link's Zora Tunic. This only affects the color when he's wearing it, not the color of the icon in the menu or when holding it up after acquiring it. The options are identical to those for the Kokiri Tunic.

+

Low Health SFX

+

This determines which sound effect to play repeatedly when Link is very low on health. Several of these options are designed to be potentially more pleasant to listen to while a few are designed to be more amusing.

+

Particular Sounds

+

Set this particular sound for the heart beep. Available choices are Default, Softer Beep, Rupee, Timer, Tambourine, Recovery Heart, Carrot Refill, Navi - Hey!, Zelda - Gasp, Cluck, Mweep!, Iron Boots, Hammer, Sword Bounce, Bow, Gallop, Drawbridge, Switch, Bomb Bounce, Bark, Ribbit, Broken Pot, Business Scrub, Guay, and Bongo Bongo. Indeed, one of these is the sound a king might make when moving... very slowly.

+

Random Choice

+

Play a random SFX from the list of choices.

+

None

+

Disable low health heart beeps altogether.

+ +

These options can be used to set Navi's color in a variety of contexts. The lists of pre-set colors here is different, but the same types of options exist as for choosing tunic colors.

+ +

This option sets the SFX that will play when Navi is ready to give a hint. The options are very similar to the Low Health SFX.

+ +

This option sets the SFX that will play when Navi targets an enemy. The options are very similar to the Low Health SFX.

+

Command Line Options

+
-h, --help            
+

Show the help message and exit.

+
--check_version
+

Check for the latest version number online (default: False)

+
--checked_version CHECKED_VERSION
+

Check for the specified version number instead of a number from online.

+
--rom ROM
+

Path to a The Legend of Zelda: Ocarina of Time NTSC-US v1.0 ROM. (default: ZOOTDEC.z64)

+
--output_dir OUTPUT_DIR
+

Path to output directory for rom generation.

+
--seed SEED           
+

Define seed number to generate. (default: None)

+
--count COUNT         
+

Set the count option (default: None)

+
--world_count WORLD_COUNT       
+

Use to create a multi-world generation for co-op seeds. World count is the number of players. Warning: Increasing the world count will drastically increase generation time. (default: 1)

+
--player_num PLAYER_NUM       
+

Use to select world to generate when there are multiple worlds. (default: 1)

+
--create_spoiler      
+

Output a Spoiler File (default: False)

+
--compress_rom [{True,False,None}]
+

Create a compressed version of the output rom file. True: Compresses. Improves stability. Will take longer to generate False: Uncompressed. Unstable on emulator. Faster generation None: No ROM Output. Creates spoiler log only (default: True)

+
--open_forest
+

Set whether Kokiri children obstruct your path at the beginning of the game. (default: False)

+
--open_kakariko
+

The gate in Kakariko Village to Death Mountain Trail is always open, instead of needing Zelda's Letter. (default: False)

+
--open_door_of_time
+

Set whether the Door of Time is open from the beginning of the game. (default: False)

+
--gerudo_fortress [{normal,fast,open}]
+

Select how much of Gerudo Fortress is required. (default: normal)

+
--bridge [{medallions,vanilla,dungeons,open}]
+

Select the condition to spawn the Rainbow Bridge to Ganon's Castle. (default: medallions)

+
--all_reachable
+

Enables the "Only Ensure Seed Beatable" option (default: False)

+
--all_reachable
+

Enables the "Only Ensure Seed Beatable" option (default: False)

+
--bombchus_in_logic
+

Changes how the logic considers Bombchus and other Bombchu related mechanics (default: False)

+
--one_item_per_dungeon
+

Each dungeon will have exactly one major item. (default: False)

+
--trials_random
+

Sets the number of trials that must be cleared in Ganon's Castle to a random value (default: False)

+
--trials [{0,1,2,3,4,5,6}]
+

Sets the number of trials that must be cleared in Ganon's Castle (default: 6)

+
--no_escape_sequence
+

Removes the tower collapse sequence after defeating Ganondorf (default: False)

+
--no_guard_stealth
+

Removes the guard evasion sequence in Hyrule Castle (default: False)

+
--no_epona_race
+

Removes the need to race Ingo to acquire Epona (default: False)

+
--fast_chests
+

Causes all chests to open with a fast animation (default: False)

+
--big_poe_count_random
+

Sets the number of Big Poes that must be sold to the vendor for an item to a random value (default: False)

+
--big_poe_count [{1,2,3,4,5,6,7,8,9,10}]
+

Sets the number of Big Poes that must be sold to the vendor for an item (default: 10)

+
--free_scarecrow
+

Start the game with the Scarecrow's Song activated and Pierre possible for the adult to summon (default: False)

+
--scarecrow_song [SCARECROW_SONG]
+

Set Scarecrow's Song if --free_scarecrow is used. Valid notes: A, U, L, R, D (default: DAAAAAAA)

+
--shuffle_kokiri_sword
+

Include the Kokiri Sword as a randomized item (default: False)

+
--shuffle_weird_egg
+

Include the Weird Egg as a randomized item (default: False)

+
--shuffle_ocarinas
+

Include the two ocarinas as randomized items (default: False)

+
--shuffle_song_items
+

Treat the ocarina songs as normal items and shuffle them into the general item pool (default: False)

+
--shuffle_gerudo_card
+

Include the Gerudo Card to access Gerudo Training Grounds as a randomized item (default: False)

+
--shuffle_scrubs [{off,low,regular,random}]
+

Include all Deku Scrub Salesmen as randomized item and determine their prices (default: off)

+
--shopsanity [{off,0,1,2,3,4,random}]
+

Randomize shop items and add the chosen number of items from the general item pool to shop inventories (default: off)

+
--shuffle_mapcompass [{remove,startwith,dungeon,keysanity}]
+

Choose the locations Maps and Compasses can be found (default: dungeon)

+
--shuffle_smallkeys [{remove,dungeon,keysanity}]
+

Choose the locations Small Keys can be found (default: dungeon)

+
--shuffle_bosskeys [{remove,dungeon,keysanity}]
+

Choose the locations Boss Keys can be found (default: dungeon)

+
--enhance_map_compass
+

Change the functionality of the Map and Compass to give information about their dungeons. The Temple of Time Altar will no longer provide any dungeon information. (default: False)

+
--unlocked_ganondorf
+

Remove the Boss Key door leading to Ganondorf (default: False)

+
--tokensanity [{off,dungeons,all}]
+

Include the chosen Gold Skulltula Token locations in the item shuffle (default: off)

+
--quest [{vanilla,master,mixed}]
+

Choose the internal layout of the dungeons (default: vanilla)

+
--logic_skulltulas [{0,10,20,30,40,50}]
+

Choose the maximum number of Gold Skulltula Tokens that could be required (default: 50)

+
--logic_no_night_tokens_without_suns_song
+

Change logic to expect Sun's Song to defeat nighttime Gold Skulltulas (default: False)

+
--logic_no_big_poes
+

Prevent the Big Poe vendor from having a required item (default: False)

+
--logic_no_child_fishing
+

Prevent the prize from fishing as a child from being a required item (default: False)

+
--logic_no_adult_fishing
+

Prevent the prize from fishing as an adult from being a required item (default: False)

+
--logic_no_trade_skull_mask
+

Prevent the item obtained by showing the Skull Mask at the Deku Theater from being a required item (default: False)

+
--logic_no_trade_mask_of_truth
+

Prevent the item obtained by showing the Mask of Truth at the Deku Theater from being a required item (default: False)

+
--logic_no_1500_archery
+

Prevent the item obtained by scoring 1500 points at horseback archery from being a required item (default: False)

+
--logic_no_memory_game
+

Prevent the item obtained by completing the ocarina memory game in the Lost Woods from being a required item (default: False)

+
--logic_no_second_dampe_race
+

Prevent the prize won by finishing the second Dampe race in under 1 minute from being a required item (default: False)

+
--logic_no_trade_biggoron
+

Prevent the item obtained by showing the Claim Check to Biggoron from being a required item (default: False)

+
--logic_earliest_adult_trade [{pocket_egg,pocket_cucco,cojiro,odd_mushroom,poachers_saw,broken_sword,prescription,eyeball_frog,eyedrops,claim_check}]
+

Set the earliest item in the adult trade sequence that can be found in the item pool (default: pocket_egg)

+
--logic_latest_adult_trade [{pocket_egg,pocket_cucco,cojiro,odd_mushroom,poachers_saw,broken_sword,prescription,eyeball_frog,eyedrops,claim_check}]
+

Set the latest item in the adult trade sequence that can be found in the item pool (default: claim_check)

+
--logic_tricks
+

Enable the logic to consider a large number of minor tricks (default: False)

+
--logic_man_on_roof
+

Enable the logic to consider the trick to reach the man on the roof in Kakariko Village with a sidehop from the tower (default: False)

+
--logic_child_deadhand
+

Enable the logic to consider the child defeating Deadhand with only Deku Sticks (default: False)

+
--logic_dc_jump
+

Enable the logic to consider the trick to bypass the second Lizalfos fight room in Dodongo's Cavern as an adult with a simple jump (default: False)

+
--logic_windmill_poh
+

Enable the logic to consider the trick to reach the Piece of Heart in the windmill as an adult with nothing (default: False)

+
--logic_crater_bean_poh_with_hovers
+

Enable the logic to consider the trick to reach the Piece of Heart on the volcano in Death Mountain Crater with Hover Boots (default: False)

+
--logic_zora_with_cucco
+

Enable the logic to consider the trick to enter Zora's Domain as a child using a Cucco instead of playing Zelda's Lullaby (default: False)

+
--logic_zora_with_hovers
+

Enable the logic to consider the trick to enter Zora's Domain as an adult using Hover Boots instead of playing Zelda's Lullaby (default: False)

+
--logic_fewer_tunic_requirements
+

Reduce the number of locations for which the logic expects a tunic upgrade (default: False)

+
--logic_morpha_with_scale
+

Allows entering Water Temple and beating Morpha with Gold Scale instead of Iron Boots. The Longshot and Boss Key are still required to reach the boss. This means that this option is only relevant in keysanity or keysy. (default: False)

+
--logic_lens [{chest,chest-wasteland,all}]
+

Set which hidden objects the logic expects the Lens of Truth to be used on (default: all)

+
--ocarina_songs
+

Randomize the particular notes that must be played for each of the 12 standard ocarina songs (default: False)

+
--correct_chest_sizes
+

Set chest sizes based on contents (default: False)

+
--clearer_hints
+

Reword hints to be incredibly direct (default: False)

+
--hints [{none,mask,agony,always}]
+

Enable hints from Gossip Stones and select the condition to read them (default: agony)

+
--text_shuffle [{none,except_hints,complete}]
+

Shuffle the chosen text randomly (default: none)

+
--difficulty [{normal,hard,very_hard,ohko}]
+

Alter the item pool to increase difficulty. The ohko option also causes Link to die in one hit. (default: normal)

+
--default_targeting [{hold,switch}]
+

Set the default Z-targeting setting. It can still be changed in the game's options menu. (default: hold)

+
--background_music [{normal,off,random}]
+

Choose whether the game's background music will be left alone, disabled, or shuffled randomly. (default: normal)

+
--kokiricolor [{'Random Choice', 'Completely Random', 'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Azure Blue', 'Vivid Cyan', 'Light Red', 'Fuchsia', 'Purple', 'MM Purple', 'Twitch Purple', 'Purple Heart', 'Persian Rose', 'Dirty Yellow', 'Blush Pink', 'Hot Pink', 'Rose Pink', 'Orange', 'Gray', 'Gold', 'Silver', 'Beige', 'Teal', 'Blood Red', 'Blood Orange', 'Royal Blue', 'Sonic Blue', 'NES Green', 'Dark Green', 'Lumen'}]
+

Select the color of Link's Kokiri Tunic. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: Kokiri Green)

+
--goroncolor [{'Random Choice', 'Completely Random', 'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Azure Blue', 'Vivid Cyan', 'Light Red', 'Fuchsia', 'Purple', 'MM Purple', 'Twitch Purple', 'Purple Heart', 'Persian Rose', 'Dirty Yellow', 'Blush Pink', 'Hot Pink', 'Rose Pink', 'Orange', 'Gray', 'Gold', 'Silver', 'Beige', 'Teal', 'Blood Red', 'Blood Orange', 'Royal Blue', 'Sonic Blue', 'NES Green', 'Dark Green', 'Lumen'}]
+

Select the color of Link's Goron Tunic. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: Goron Red)

+
--zoracolor [{'Random Choice', 'Completely Random', 'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Azure Blue', 'Vivid Cyan', 'Light Red', 'Fuchsia', 'Purple', 'MM Purple', 'Twitch Purple', 'Purple Heart', 'Persian Rose', 'Dirty Yellow', 'Blush Pink', 'Hot Pink', 'Rose Pink', 'Orange', 'Gray', 'Gold', 'Silver', 'Beige', 'Teal', 'Blood Red', 'Blood Orange', 'Royal Blue', 'Sonic Blue', 'NES Green', 'Dark Green', 'Lumen'}]
+

Select the color of Link's Zora Tunic. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: Zora Blue)

+
--navicolordefault [{'Random Choice', 'Completely Random', 'Gold', 'White', 'Green', 'Light Blue', 'Yellow', 'Red', 'Magenta', 'Black', 'Tatl', 'Tael', 'Fi', 'Ciela', 'Epona', 'Ezlo', 'King of Red Lions', 'Linebeck', 'Loftwing', 'Midna', 'Phantom Zelda'}]
+

Select the color of Navi in idle. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: White)

+
--navicolorenemy [{'Random Choice', 'Completely Random', 'Gold', 'White', 'Green', 'Light Blue', 'Yellow', 'Red', 'Magenta', 'Black', 'Tatl', 'Tael', 'Fi', 'Ciela', 'Epona', 'Ezlo', 'King of Red Lions', 'Linebeck', 'Loftwing', 'Midna', 'Phantom Zelda'}]
+

Select the color of Navi when she is targeting an enemy. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: Yellow)

+
--navicolornpc [{'Random Choice', 'Completely Random', 'Gold', 'White', 'Green', 'Light Blue', 'Yellow', 'Red', 'Magenta', 'Black', 'Tatl', 'Tael', 'Fi', 'Ciela', 'Epona', 'Ezlo', 'King of Red Lions', 'Linebeck', 'Loftwing', 'Midna', 'Phantom Zelda'}]
+

Select the color of Navi when she is targeting an NPC. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: Light Blue)

+
--navicolorprop [{'Random Choice', 'Completely Random', 'Gold', 'White', 'Green', 'Light Blue', 'Yellow', 'Red', 'Magenta', 'Black', 'Tatl', 'Tael', 'Fi', 'Ciela', 'Epona', 'Ezlo', 'King of Red Lions', 'Linebeck', 'Loftwing', 'Midna', 'Phantom Zelda'}]
+

Select the color of Navi when she is targeting a prop. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: Green)

+
--navisfxoverworld [{'Default', 'Random Choice', 'None', 'Cluck', 'Rupee', 'Softer Beep', 'Recovery Heart', 'Timer', 'Low Health', 'Notification', 'Tambourine', 'Carrot Refill', 'Zelda - Gasp', 'Mweep!', 'Ice Break', 'Explosion', 'Crate', 'Great Fairy', 'Moo', 'Bark', 'Ribbit', 'Broken Pot', 'Cockadoodledoo', 'Epona', 'Gold Skulltula', 'Redead', 'Poe', 'Ruto', 'Howl', 'Business Scrub', 'Guay', "H'lo!"}]
+

Select the sound effect that plays when Navi wishes to speak with the player. (default: Default)

+
--navisfxenemytarget [{'Default', 'Random Choice', 'None', 'Cluck', 'Rupee', 'Softer Beep', 'Recovery Heart', 'Timer', 'Low Health', 'Notification', 'Tambourine', 'Carrot Refill', 'Zelda - Gasp', 'Mweep!', 'Ice Break', 'Explosion', 'Crate', 'Great Fairy', 'Moo', 'Bark', 'Ribbit', 'Broken Pot', 'Cockadoodledoo', 'Epona', 'Gold Skulltula', 'Redead', 'Poe', 'Ruto', 'Howl', 'Business Scrub', 'Guay', "H'lo!"}]
+

Select the sound effect that plays when Navi targets an enemy. (default: Default)

+
--healthSFX [{'Default', 'Random Choice', 'None', 'Cluck', 'Softer Beep', 'Recovery Heart', 'Timer', 'Notification', 'Tambourine', 'Carrot Refill', 'Navi - Random', 'Navi - Hey!', 'Zelda - Gasp', 'Mweep!', 'Iron Boots', 'Hammer', 'Sword Bounce', 'Bow', 'Gallop', 'Drawbridge', 'Switch', 'Bomb Bounce', 'Bark', 'Ribbit', 'Broken Pot', 'Business Scrub', 'Guay', 'Bongo Bongo'}]
+

Select the sound effect that loops at low health. (default: Default)

+
--gui
+

Open the graphical user interface. Preloads selections with set command line parameters.

+
--loglevel [{error,info,warning,debug}]
+

Select level of logging for output. (default: info)

+
--settings_string SETTINGS_STRING
+

Enter a settings string that will encode and override most individual settings.

diff --git a/README.md b/README.md index 811e493b4..59b0f933b 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,16 @@ This is a randomizer for _The Legend of Zelda: Ocarina of Time_ for the Nintendo # Installation It is strongly suggested users get the latest release from here: https://github.com/AmazingAmpharos/OoT-Randomizer/releases . -Simply download the .msi installer and run it if you have a Windows machine. +Simply download the .msi installer and run it. We support Windows, Mac, and Linux machines. -If you do not have Windows or you simply wish to run the script raw, clone this repository and either run '''Gui.py''' for a -graphical interface or '''OoTRandomizer.py''' for the command line version. Both require Python 3.5+. +If you have an incompatible OS or you simply wish to run the script raw, clone this repository and either run '''Gui.py''' for a +graphical interface or '''OoTRandomizer.py''' for the command line version. Both require Python 3.5+. This will be fully featured, +but the seeds you generate will have different random factors than the bundled release. -This randomizer requires The Legend of Zelda: Ocarina of Time version 1.0 NTSC-US version. Upon first being run, the randomizer will automatically -create a decompressed version of this ROM that can be used for input for slightly faster seed generation times. Please be sure your input ROM filename -is either a .n64 or .z64 file. For users playing via any means other than on real N64 hardware, the use of the "Compress patched ROM" flag is strongly -encouraged as uncompressed ROMs are impossible to inject for the Virtual Console and have random crashing problems on all emulators. +This randomizer requires The Legend of Zelda: Ocarina of Time version 1.0 NTSC-US version. This randomizer includes an in-built decompressor, but if +the user wishes a pre-decompressed ROM may be supplied as input. Please be sure your input ROM filename is either a .n64 or .z64 file. For users +playing via any means other than on real N64 hardware, the use of the "Compress patched ROM" flag is strongly encouraged as uncompressed ROMs are +impossible to inject for the Virtual Console and have random crashing problems on all emulators. For general use, the recommended emulator is RetroArch; it has been shown to work with minimal issues. Bizhawk and Mupen64plus are generally good choices too. If you want to play on Project 64 for whatever reason, you can but you will need to set the rando to use 8 MB of RAM and will want to play with the @@ -27,10 +28,11 @@ Proper logic is used to ensure every seed is possible to complete without the us with any possible usage of keys in dungeons. The items that randomize currently are all items within chests including those in grottos, items given as rewards by NPCs including from minigames and -Deku Scrub salesmen, the items given by freestanding Pieces of Heart, Heart Containers, and Keys, and the items obtained when getting the Bottle and the -Fire Arrows at Lake Hylia. All dungeons will always have the same number of Maps, Compasses, Small Keys, and Boss Keys they had in the original game, but -which chests within those dungeons have those things is random. The item pool will contain a Biggoron Sword that will not interfere with Medigoron's sale -of the Giant's Knife (which is always vanilla), and a randomly selected adult trading quest item other than the Odd Potion will be somewhere in the item pool. +Deku Scrub Salesmen, the items given by freestanding Pieces of Heart, Heart Containers, and Keys, and the items obtained when getting the Bottle and the +Fire Arrows at Lake Hylia or the Ocarina of Time from the Castle Town moat. All dungeons will always have the same number of Maps, Compasses, Small Keys, +and Boss Keys they had in the original game, but which chests within those dungeons have those things is random. The item pool will contain a Biggoron Sword +that will not interfere with Medigoron's sale of the Giant's Knife (which is always vanilla), and a randomly selected adult trading quest item other than the +Odd Potion will be somewhere in the item pool. Certain types of items are now "progressive", meaning that no matter what order the player encounters these items they will function as a series of upgrades. The following item types will be progressive chains: @@ -44,16 +46,16 @@ The following item types will be progressive chains: -Adult Wallet to Giant's Wallet -Deku Stick Capacity Upgrades -Deku Nut Capacity Upgrades --Magic Meter to Double Magic +-Magic Meter to Double Magic +-Fairy Ocarina to Ocarina of Time To be more clear about which NPC items are shuffled, it's only the one time permanent item rewards for the most part like NPCs who originally gave Pieces of Heart -or inventory items. The only exception is that even though in vanilla the reward for 40 Gold Skulltulla Tokens was just 10 Bombchus that is still a randomized reward -in randomizer (but the 200 rupees for all 100 Gold Skulltulla Tokens is not randomized so the most tokens that could be required to complete a seed is 50). As a mercy +or inventory items. The only exception is that even though in vanilla the reward for 40 Gold Skulltula Tokens was just 10 Bombchus that is still a randomized reward +in randomizer (but the 200 rupees for all 100 Gold Skulltula Tokens is not randomized so the most tokens that could be required to complete a seed is 50). As a mercy to the player, the Ocarina Memory Game in the Lost Woods will start on the final round as that minigame was very long originally, the three day wait on the Claim Check is removed, Bombchu Bowling will have a fixed sequence of prizes that is of maximum convenience to the player, Dampe's Gravedigging Tour will always be won on the first dig, and the fishing minigame is made much simpler (8 lb fish for child now, 10 lb for adult). Additionally, any NPC who gives a trading quest item either for the child -or for the adult other than Anju's initial gift as an adult does not have a randomized reward, and as a design decision, the Fairy Ocarina and Ocarina of Time are not -randomized. +or for the adult other than Anju's initial gift as an adult does not have a randomized reward. A special note is needed for the six Great Fairy Fountains scattered across Hyrule. All six of these fountains now give random item rewards, and the magic and life upgrades can now be found as normal items scattered around the world. Happy hunting! @@ -61,14 +63,16 @@ upgrades can now be found as normal items scattered around the world. Happy hunt The Ocarina songs are shuffled in a pool amongst themselves, and each learn spot will still have the original conditions it has always had. These conditions may not have all been obvious, but here are some high points. Saria will teach her song after completing the events in the Castle Courtyard. The warp songs can mostly only be learned by an adult, but the location for Requiem of Spirit is available for even a child if the Desert Colossus can be reached. The location for the Prelude of -Light requires the Forest Medallion, and the location for the Nocturne of Shadow requires the Forest Medallion, Fire Medallion, and Water Medallions. +Light requires the Forest Medallion, and the location for the Nocturne of Shadow requires the Forest Medallion, Fire Medallion, and Water Medallions. A setting +exists to shuffle all songs into the general item pool instead of limiting them to song specific slots. Speaking of Medallions, each boss in the eight main dungeons will drop a random Spiritual Stone or Medallion, and instead of the Light Medallion being granted by the now removed "becoming an adult" cutscene, the player will start every seed with a random Spiritual Stone or Medallion. The pedestal in which the Spiritual Stones rest in the Temple of Time has hint text pointing to the locations of the Spiritual Stones and Medallions. A child will be able to read hints for the Spiritual -Stones while an adult will be able to read hints for the Medallions. +Stones while an adult will be able to read hints for the Medallions. This information and some other relevant dungeon based info can be seen in the pause menu by +holding the "A" button on the c-item menu. -To be very clear on this point, while the rewards for up to 50 Gold Skulltulla Tokens are randomized, the tokens themselves are not. +To be very clear on this point, while the rewards for up to 50 Gold Skulltula Tokens are randomized, the tokens themselves are not. As a service to the player in this very long game, many cutscenes have been greatly shortened or removed and text is as often as possible either omitted or sped up. We have been as thorough as our exploration of the game and various technical limitations will allow to make the parts of the game where you're watching and reading @@ -83,7 +87,12 @@ the Castle Courtyard being sealed off is now completing the events within as opp One small detail that is important to know is that the locked door in the Fire Temple leading to the section with the Boss Key Chest is removed. This was necessary due to the original design of the Fire Temple assuming that the player could not possibly have the Hammer before unlocking the doors leading into the depths of the dungeon. This is obviously not true in randomizer, and of all possible solutions to this problem, this seemed the least disruptive. A full clear of the Fire Temple will -simply result in the player having one extra Small Key. +simply result in the player having one extra Small Key. Certain settings configurations will disable this behavior. + +Two similar small details apply to the Master Quest versions of dungeons. In Water Temple MQ, a locked door leading to a Gold Skulltula in the northern basement was +glitched such that it would not appear in the Gamecube release of Master Quest but was fixed in OoT3D's version of Master Quest. In the randomizer, the locked door +works like an ordinary locked door similar to OoT3D. In Spirit Temple MQ, there is a particular chest that requires hitting a switch in a hole that the adult will +later push a silver block into. The randomizer does some wizardry under the hood to ensure that the block will never be in the way for the child. To be clear about the logic rules of what can be where, the randomizer will ensure a glitchless path through the seed will exist, but the randomizer will not prevent the use of glitches for those players who enjoy that sort of thing though we offer no guarantees that all glitches will have identical behavior to the original game. @@ -93,7 +102,8 @@ or before walking through any invisible objects or opening any invisible chests the Bottom of the Well as the original game required passing that invisible wall to reach the Lens of Truth. One last detail is that the menu is now more like the Majora's Mask menu in that the player can move the cursor through empty spaces. This fixes a major problem from -the original game in that certain combinations of items would create menu shapes that would be impossible to fully menu through. +the original game in that certain combinations of items would create menu shapes that would be impossible to fully menu through. As of version 3.0, this fix extends +to the "equipment" subscreen as well. # Quirks to Know @@ -108,9 +118,10 @@ possessing the Forest Medallion. The condition to learn a song from Sheik in Kak -Skull Kid will only buy the Skull Mask if you have played Saria's Song for him. -The center of Death Mountain Crater as an adult can be reached from the summit as an adult by going around to the left with Hover Boots or by jumping down to the right and using a combination of the Longshot and Scarecrow's Song. This allows access to Sheik and the Fire Temple without a Bomb Bag. --A sword must be equipped to play the fishing minigame. A Slingshot is not required for child target shooting, but the adult does need the Bow. --Other than those minigames, the child can do anything that would seem to require the sword with Deku Sticks. You can buy as many as you want in the Kokiri Forest shop. --In the randomizer, possessing the Bomb Bag is the requirement to get bomb drops, buy bombs or Bombchus, or play Bombchu Bowling. +-A sword must be equipped to play the fishing minigame. A Slingshot is not required for child target shooting, but the adult does need the Bow to receive the true prize. +-Other than the fishing minigame, the child can do anything that would seem to require the sword with Deku Sticks. You can buy as many as you want in the Kokiri Forest shop. +-In the randomizer, possessing the Bomb Bag is the requirement to get bomb drops, buy bombs or Bombchus, or play Bombchu Bowling. If the setting "Bombchus Are Considered in +Logic" is used, finding any pack of Bombchus allows purchasing Bombchus and playing Bombchu Bowling while possessing a Bomb Bag allows the purchase of bombs. -Only the Hookshot, not the Longshot, is needed to do everything on the rooftops of Kakariko. -Grottos can be opened with either Bombs or the Hammer. -The boulder maze in Goron City can be solved with the Hammer or partially with Bombs as is obvious, but less obvious is that it can be fully solved with Silver Gauntlets. @@ -118,13 +129,15 @@ and using a combination of the Longshot and Scarecrow's Song. This allows access -In a few places, out of sight Song of Time blocks can be summoned. The lava room in Gerudo Training Grounds, the beginning of Ganon's Castle Shadow Trial, and the last hallway with a caged Goron in Fire Temple are the main cases. -Adult Link can fully clear Dodongo's Cavern. He can even skip the first section by virtue of being tall. --In the Forest Temple, you can reach the room with the Floormaster early by using Hover Boots in the block push room. +-In the Forest Temple, you can reach the room with the Floormaster (vanilla) or Redead (MQ) early by using Hover Boots in the block push room. -In the Fire Temple, you can reach the Boss Key door from the beginning with Hover Boots. -In the Water Temple, you can from the start with the water down jump to the middle platform level, very carefully aim the Hookshot to the target above, and pull yourself to the highest level of the central platform. Then a very well spaced rolling jump can reach the water changing station to raise the water to the highest level. If you make poor key choices in Water Temple, this may be what you need to do to untangle the situation. -In the Water Temple, Hover Boots can be used to reach the vanilla Boss Key chest without going through the room that requires Bombs and block pushing. Hover Boots can also be used in this temple to avoid the Longshot requirement for the middle level chest that requires the Bow. +-In the Water Temple, Farore's Wind can be placed in the central pillar and then the water can be raised to the highest level in order to reach the Gold Skulltula without +the Longshot. -In the Shadow Temple, you can avoid the need for the Longshot in the room with the invisible spikes by backflipping onto the chest for extra height. -In the Shadow Temple, you can Hookshot the ladder to avoid pushing the block to get on the boat. -In the Shadow Temple, a combination of the scarecrow and the Longshot can be used to reach Bongo Bongo without needing the Bow. @@ -132,62 +145,581 @@ also be used in this temple to avoid the Longshot requirement for the middle lev -In the Spirit Temple, you can collect the silver rupees without Hover Boots by jumping directly onto the rolling boulder or with a jump slash. -In the Spirit Temple, you can use the Longshot to cross from the hand with the Mirror Shield in vanilla to the other hand. -In Ganon's Castle Spirit Trial, the web can be burned with a precise shot through the torch by a normal arrow. Fire Arrows are not required. --While we guarantee tunics for Fire Temple and Water Temple, you can possibly force yourself to do without if you seriously let a Like Like eat the tunic and -then do not recover the tunic. It is almost always possible to do without, but it can make things really difficult on you. --Several Gold Skulltulla Tokens can be reached by clever/precise uses of jump slashes and spin attacks (possibly magic spin attacks). +-Like Likes now only eat shields and not tunics. +-Several Gold Skulltula Tokens can be reached by clever/precise uses of jump slashes and spin attacks (possibly magic spin attacks). +-This is not a randomizer exclusive mechanic, but getting the ability to summon Pierre the Scarecrow requires playing an eight note song for +Bonooru the Scarecrow as a child first and then the exact same song for him again as an adult. # Known issues -Sadly for this 2.0 release a few known issues exist. These will hopefully be addressed in future versions. +Sadly for this 3.0 release a few known issues exist. These will hopefully be addressed in future versions. -The fishing minigame sometimes refuses to allow you to catch fish when playing specifically on Bizhawk. Save and quit (NOT savestate) and return to fix the issue. -Draining the Bottom of the Well with Song of Storms sometimes crashes on specific configurations of Project 64. We aren't sure of the exact story, but this bug is easily avoided by playing on a different emulator and probably also avoidable by changing your settings and maybe graphics plug-in. --There's a funny bug where sometimes obtaining Biggoron Sword displays a second erroneous text box. This has no gameplay consequence. -Executing the collection delay glitch on various NPCs may have unpredictable and undesirable consequences. In particular this can be devastating with Biggoron; it is strongly suggested the player save before turning in the Claim Check. -Saving and quitting on the very first frame after becomming an adult when you would trigger the Light Arrow cutscene can have undesired consequences. Just don't do that. +-This randomizer is based on the 1.0 version of Ocarina of Time so some of its specific bugs remain. Some of these like "empty bomb" can be disadvantagous to the +player. # Settings -## Rainbow Bridge +The OoT Randomizer has many different settings users can choose to customize their play experience. Here's a fully detailed list! -This determines the condition under which the rainbow bridge to Ganon's Castle will spawn. +# ROM Options -### Medallions +## Base Rom -All six of the medallions are required to open Ganon's Castle. +Specify the input ROM that will be used by the randomizer. Please be sure it is OoT US v1.0. -### Vanilla +## Output Directory + +Specify where the output ROM will be written on your computer. + +## Create Spoiler Log + +Decide whether to output a text file detailing where every item can be found and the sequence of play that will lead to seed completion. Selecting this option will +create a different item configuration than using otherwise identical settings without printing a log; this is intended to prevent cheating in race environments. + +## Compress Rom + +Decide the format of the output ROM. Compressed is generally recommended for most users; this is necessary for injection into a .wad for use on the Virtual Console, +and all known N64 emulators have significant crashing problems with uncompressed ROMs. Real N64 hardware doesn't care so generation time can be improved by using +the uncompressed option if you are playing on a real N64 with a flash cart. You can also choose not to output a ROM at all; this is useful if you just want to look +at spoiler logs. + +## Default Targeting Option + +This option specifies whether Z-targeting will default to "Switch" or "Hold" style. Either way, this can still be changed in-game as per usual. + +## Multi-World Generation + +This option allows for multiple worlds to be generated to be used in co-op play. Each player will get a different ROM designed to work in conjunction with another +to allow two players to work together to complete the game. Synchronization can be achieved on Bizhawk via the following script: + +https://github.com/TestRunnerSRL/bizhawk-co-op + +### Player Count + +Use this to specify how many players will be participating in this co-op playthrough. + +### Player ID + +Use this to specify which player number you are in particular. Each participant in the co-op should choose a different number starting with 1. + +## Setting String + +This is an 18 character string that specifies the totality of other gameplay relevant (non-cosmetic) settings used throughout the randomizer. This string can be shared +between players and then the "Import Settings String" button can be pressed to automatically change all settings to match another player. + +## Seed + +This is a string representing the particular configuration of items that will occur in your seed; the purpose is to combine a seed string with an identical settings +string such that the randomizer will be able to generate the same game for multiple players. If this field is left blank, a random seed will be chosen. + +# Main Rules + +## Open Forest + +Mido does not need to see a sword and shield to reach the Deku Tree and the Kokiri boy blocking the exit to the forest is gone. If this flag is not set, it is +guaranteed that the Deku Tree can be completed without leaving the forest. This means that within the forest or the Deku Tree itself it will be possible to find +the Kokiri Sword, Deku Shield for sale, and the Slingshot. + +## Open Kakariko Gate + +The gate leading up Death Mountain from Kakariko Village is open from the beginning of the game. Normally this requires Zelda's Letter to open. This allows more +diverse routing early in the game and prevents very long walks in seeds with the Weird Egg shuffled. Two things are important to note. Showing Zelda's Letter to +the guard is still required to begin the Happy Mask sidequest and to receive a discount on purchasing Hylian Shields. The gate is simply gone for an adult no +matter what. + +## Open Door of Time -The rainbow bridge spawns under the same conditions it did in the original game, possession of the Light Arrows and having viewed the Zelda cutscene. +The Door of Time is open from the beginning of the game. The Song of Time is still potentially useful to move Song of Time blocks, play songs for the frogs on Zora +River, or for other such uses. If this flag is not used, the Door of Time must be opened to become an adult as in the original game, but all that is needed to open +the Door of Time is the Song of Time and any ocarina. The Ocarina of Time in particular and the Spiritual Stones have nothing to do with this. + +## Gerudo Fortress + +### Default Behavior + +Gerudo Fortress will work the same way it did in the original game. All four carpenters must be rescued in order for the Gerudo woman who gives the Gerudo Card to +appear and for the Gerudo to stop being hostile. Rescuing a carpenter requires having a Gerudo Fortress Small Key and defeating the corresponding guard. + +### Rescue One Carpenter + +Only the bottom left carpenter must be rescued to complete Gerudo Fortress. Only one Gerudo Fortress Small Key will exist because of this. + +### Start with Gerudo Card + +The player will start with the Gerudo Card from the beginning of the game. The carpenters will be pre-rescued, and the bridge to Gerudo Fortress as an adult will +be repaired from the beginning. The Gerudo Card is the requirement in the randomizer to enter Gerudo Training Grounds so it will be an accessible area from the +moment adulthood is available. + +## Rainbow Bridge Requirement + +This determines the condition under which the rainbow bridge to Ganon's Castle will spawn. ### All Dungeons The rainbow bridge spawn requires all medallions and spiritual stones to be in the player's possession. +### All Medallions + +All six of the medallions are required to open Ganon's Castle. + +### Vanilla + +The rainbow bridge spawns under the same conditions it did in the original game, possession of the Light Arrows and having viewed the Zelda cutscene. This +cutscene in the Temple of Time is triggered by possessing the Shadow and Spirit Medallions. + ### Open The rainbow bridge is always present. +## Random Number of Ganon's Trials + +A random number of trials within Ganon's Castle from 0 to 6 will be chosen, and individual trials will be randomly disabled as necessary to match this number. +Alternatively, a specific number of trials can be specified with the slider below. If a number of trials other than 0 or 6 is chosen and hints are enabled, +hints will be added to the hint pool informing the player which trials are present (if 1 to 3 trials) or which are missing (if 4 or 5 trials). + +## All Locations Reachable + +This option will set the logic to try to ensure Link can reach every item location in the game with the exception of "key for key" item locations (a single +item spot behind a locked door containing the key to open the door). If this option is not used, the logic will allow some items to be in impossible locations +so long as the set of reachable items is sufficient to complete the game. + +## Bombchus Are Considered in Logic + +This option fundamentally changes how the Bombchu items found around the world function. With this option on, Bombchus are a progression item and operate as +a form of progressive item. The first Bombchu pack found will be worth 20 Bombchus and subsequent packs will be worth 10 or 5 Bombchus. Finding Bombchus will +be considered as logical progression, and having found any Bombchus will be the condition to play Bombchu Bowling or buy Bombchu refills from shops. This flag +will also add Bombchu (5) buyable items to the shops in Kokiri Forest, Castle Town Bazaar, and Kakariko Bazaar. With this option off, randomly found Bombchu +items are not considered as logical progression, randomly found Bombchus will have specific denominations based on the values from the original game, and +finding a Bomb Bag is what enables playing Bombchu Bowling and buying Bombchus from shops which will not have their inventories edited. + +## Dungeons Have One Major Item + +This option places one "major item" and one only in each of the dungeons. For the purpose of the randomizer, the dungeons are defined as the eight dungeons that +contain either Medallions or Spiritual Stones as well as Bottom of the Well, Ice Cavern, Gerudo Training Grounds, and Ganon's Castle. The major items are any +item usable with a c-button that is not simply a form of ammo (Bombchus are major only if "Bombchus are considered in logic" is on), songs, Mirror Shield, swords, +tunics, boots, Double Defense, Magic Meter/Double Magic, Bullet Bags, Quivers, Bomb Bags, Strength Upgrades, Scales, Wallets, and the Stone of Agony. To be +clear, this means that rupees, ammo, Deku Stick and Deku Nut ammo expansions, Pieces of Heart, Heart Containers, Gold Skulltula Tokens, Maps, Compasses, +Small Keys, Boss Keys, Deku Shields, Hylian Shields, and Ice Traps are not considered major items. However, Small Keys and Boss Keys are considered major +items if the appropriate "keysanity" settings are used. Note that unlike with the distribution of dungeon specific items like keys, this flag does consider +the hands of the Desert Colossus as Spirit Temple locations, and to mirror the original game, Spirit Temple will get two items instead of just one. + +## Dungeon Quest + +This option specifies the form dungeons will take. The item pool will be updated to reflect the items originally found in the dungeons used. + +### Vanilla + +Dungeons will have the same internal layout as they did in the original The Legend of Zelda: Ocarina of Time. + +### Master Quest + +Dungeons will have the internal layouts found in The Legend of Zelda: Ocarina of Time Master Quest. + +### Mixed + +Dungeons will each have a random internal layout chosen between the vanilla and Master Quest forms. + +## Shuffle Kokiri Sword + +This flag adds the Kokiri Sword to the shuffle. With it off, the Kokiri Sword will always be found in its original chest in the Kokiri Forest. + +## Shuffle Weird Egg + +This flag adds the Weird Egg given by child Malon to the shuffle. With this flag on, child Malon will give a random item and the Weird Egg must be located +to do the events at Hyrule Castle with Zelda and Impa. These events block interacting with Talon and Malon at Lon Lon Ranch as a child as well as Saria in +Sacred Forest Meadow and the Happy Mask sidequest. + +## Shuffle Ocarinas + +This flag adds both the Fairy Ocarina and the Ocarina of Time to the shuffle. The ocarinas are a progressive item; the first found will always be the Fairy +Ocarina with the second being the Ocarina of Time even though the two are functionally identical. Without this flag on, leaving the Kokiri Forest to the +Lost Woods bridge as a child will always grant one Ocarina and the other is always available at the gate of Castle Town as a child when all three Spiritual +Stones are in the player's possession. + +## Shuffle Songs with Items + +This flag adds the 12 standard ocarina songs to the shuffle as normal items. With this flag on, the spots that contained songs in the original game will +simply give Link a random item, and the songs can be found as items freely. Without this flag on, songs are still randomized but only between each other. +In either case, the Scarecrow's Song is not affected; it is still obtained by interacting with Bonooru at Lake Hylia first as a kid and then as an adult. + +## Shuffle Gerudo Card + +This flag shuffles the Gerudo Card into the general item pool. In the randomizer, this is required to gain access to Gerudo Training Grounds, but it does +not have any impact on the hostility of the Gerudo in Gerudo Fortress who still check for the carpenter rescue events. Without this flag, the Gerudo +Card is always given by the Gerudo woman who spawns after the final carpenter is rescued. If Gerudo Fortress is cleared from the beginning of the game, +the player starts the game with the Gerudo Card and this setting is voided. + +## Shuffle Deku Salescrubs + +This flag makes every Deku Scrub Salesman in the world sell a random item instead of only the three that sold permanent upgrades in the original game. +Using this flag adds the various low tier items the other scrubs sold to the item pool for the most part; the potion refills are replaced with Recovery +Hearts for Red Potions and blue rupees for Green Potions. For each Deku Scrub that sold arrows/seeds depending on age, there will be a 75% chance of +adding a 30 arrow item and a 25% chance of adding a 30 seed item to the pool. If this is set, once a Deku Scrub Salesman is used, it will disappear +from the world forever. The individual settings in the dropdown can be used to set the price of each Deku Scrub Salesman to 10 rupees, leave the prices +as what they were in the original game, or set each price to a random value from 0 to 99 rupees. In all cases, the text for the Deku Scrub Salesmen +will not update. + +## Shopsanity + +This setting randomizes the items sold in shops. When it is used, all shop items are randomly re-arranged among all 8 of the original game's shops. +This setting causes the Bombchu Shop to be open from the very beginning of the game, and this setting considers the two shops in adult Kakariko +Village to be distinct shops from the two similar shops in child Castle Town; however, the shops in Kokiri Forest, Goron City, and Zora Domain are +the same shops as both ages. This setting overrides the "Bombchus considered in logic" editing of the shop item pool. + +### Off + +This disables the Shopsanity feature. + +### Shuffled Shops (0 Items) + +This causes all of the Shopsanity features described above. + +### Shuffled Shops (1-4 Items) + +This not only causes all of the Shopsanity features described above, but it also adds 1-4 (depending on the exact setting) items from the general +item pool into shops to buy for randomly chosen amounts of money. Lower value shop items are removed to make room for this, and low value junk items +are added to the item pool to fill the extra empty chests this will implicitly create. Using this feature will also replace several of the rupee +items found throughout the seed with higher value rupees and will add a third Wallet upgrade, the "Tycoon's Wallet", to the item pool which can hold +up to 999 rupees. The items from the general item pool added to shops will always be on the far left of the shop inventories, and these items can +always be bought if the player has enough rupees even if they are explosives without an appropriate container or a tunic as a child. + +### Shuffled Shops (Random Items) + +This is similar to the 1-4 items variant but gives each shop a random number of new items from 0-4. Each shop can have a different amount of unique +items with this setting. + +## Shuffle Dungeon Items + +This setting allows the player to decide the natural distribution of dungeon items. Dungeon items can be found confined to their original dungeons, +spread freely throughout the world, or prevented from existing completely. Items that are prevented from existing completely will be replaced in the +item pool with an assortment of various low tier junk items. This feature can be specified for Maps/Compasses, Small Keys, and Boss Keys independently. +If Small Keys or Boss Keys are prevented from existing, this will also remove all locks those keys would be used for from existing as well. If Small Keys +are left in their original dungeons and the Fire Temple is not in the form of Master Quest, the locked door in the first room that leads to the normal +location of the Boss Key will be removed. + +## Maps and Compasses Give Information + +This setting, only available if you start with Maps and Compasses or they are spread across the world, disables the pedestal in the Temple of Time from giving information about +the location of the Medallions and Spiritual Stones. Instead, the Compass from each of the eight eligible dungeons will tell the player which dungeon has +which reward. If the dungeon quest is set to mixed, each of the ten Maps will tell the player whether any given dungeon is in the vanilla or Master Quest +form. The Compasses from Bottom of the Well and Ice Cavern do not give any information. + +## Remove Ganon's Door Boss Lock + +This setting removes the Boss Key lock from Ganon's Tower. This removes the need to locate the Ganon's Tower Boss Key to finish the game. + +## Tokensanity + +This setting shuffles the Gold Skulltula item drops into the general pool of locations. The player can choose only to include Gold skulltulas +found in dungeons for a more mild version of this setting. + +# Detailed Logic + +## Maximum Expected Skulltula Tokens + +This setting can be used to reduce the number of Gold Skulltula Tokens that may be required to finish the game. + +## No Nighttime Skulltulas without Sun's Song + +This setting causes the logic to expect the player to have an ocarina and the Sun's Song to get Gold Skulltula locations that are only found at +nighttime. + +## No Big Poes + +This setting will guarantee that the Big Poe vendor will not have an important item. + +## No Child Fishing + +This setting will guarantee that the reward from child fishing is not an important item. This is mostly recommended if the player simply must play +on Bizhawk. + +## No Adult Fishing + +This setting will guarantee that the reward from adult fishing is not an important item. This is mostly recommended if the player simply must play +on Bizhawk. + +## No Skull Mask Reward + +This setting will guarantee that the item obtained from showing the Skull Mask in the Deku Theater is not an important item. + +## No Mask of Truth Reward + +This setting will guarantee that the item obtained from showing the Mask of Truth in the Deku Theater is not an important item. + +## No 1500 Horseback Archery + +This setting will guarantee that the item obtained from scoring 1500 points at the horseback archery challenge at Gerudo Fortress is not an +important item. + +## No Lost Woods Memory Game + +This setting will guarantee that the item obtained from winning the ocarina memory game in the Lost Woods is not an important item. + +## No Racing Dampe a Second Time + +This setting will guarantee that the item obtained from finishing with a sub-minute time in the second Dampe race is not an important item. + +## No Biggoron Reward + +This setting will guarantee that the item obtained from showing the Claim Check to Biggoron is not an important item. + +## Adult Trade Sequence + +This pair of settings can be used to specify the earliest and latest items that can be allowed to randomly show up in the general item pool. +Only one item will be in the item pool regardless of this setting; this can merely be used to limit the range of possibilities. + +## Enable All Tricks + +This is a button to turn on all of the trick related flags. + +## Various Advanced Tricks + +This setting allows a huge number of minor tricks to be allowed by the logic. Here is a complete list: + +-A precise jumpslash with either a Deku Stick or the Kokiri Sword can be used to reach a Gold Skulltula on some vines in standad Deku Tree. +-The Bow can be used to knock down the stairs in Dodongo's Cavern with two well timed shots. +-The vines in Forest Temple leading to where the well drain switch is in the standard form can be barely reached with the standard Hookshot. +-The well in Forest Temple can be crossed with just Hookshot by shooting as low as possible on the vines from the far side and swimming under +the ceiling. This is possible in both versions but can only be required in Forest Temple MQ. +-A Bombchu from the ground level can be used to hit the switch to bypass the block pushing puzzle in Forest Temple MQ. +-A rusted switch under a Song of Time block in the standard Fire Temple can be hit by using Hammer into the block. +-The location with the Boss Key chest in Fire Temple MQ can be reached without the Bow with very particular use of Din's Fire. +-The upper levels of the old boulder maze in Fire Temple MQ can be reached without explosives by using the Hammer through a wall. +-In the standard Spirit Temple, the bridge on child side can be lowered with a carefully timed Bombchu. +-The frozen switch in Spirit Temple MQ can be hit without a fire source by using the Bow and Song of Time very cleverly. +-The chest in the basement of the standard Bottom of the Well can be reached with only a Strength Upgrade by using a jump slash with a lit +Deku Stick to access the bomb flowers in the basement. +-The silver rupees on the left side of Gerudo Training Grounds MQ can be collected with just Hookshot with a somewhat particular jump slash. +-The first room of the Spirit Trail in Ganon's Castle MQ can be cleared without the Bow by using a Hammer jump slash to hit the rusted switch +through the thrones. +-The Gold Skulltula in adult Kokiri Forest can be reached without the Hookshot by using Hover Boots off one of the roots. +-The child can reach the chest on Death Mountain trail with just the Goron Bracelet by backwalking with the Bomb Flower intended to open +Dodongo's Cavern and throwing the Bomb Flower at the wall very quickly. +-Gerudo Fortress can be cleared without any items other than those needed for access. The logic normally guarantees one of the Bow, Hookshot, or +Hover Boots to help navigate the "kitchen". + +Using this setting will also pre-set all of the lower logic flags to a reasonable configuration to match the trick level. These can then be +edited as the player desires if the given configuration isn't desired. + +## Man on Roof without Hookshot + +This allows the logic to consider a trick in which the player does a sidehop off the tall tower in Kakariko Village to reach the man on the +rooftop with no items. + +## Child Deadhand without Kokiri Sword + +This allows the logic to consider defeating the Deadhand in Bottom of the Well with Deku Sticks. This is not hard with use of the power crouch +stab glitch, but consistently landing actual jump slashes on his unusual hitbox is pretty difficult and using normal slashes consumes 9 Deku Sticks. + +## Dodongo's Cavern Spike Trap Room Jump without Hover Boots + +This allows the logic to consider that the adult can make a particularly useful jump in Dodongo's Cavern to reach the area with the Bomb Bag chest early. +Due to the precision of the jump, normally the logic expects Hover Boots to complete this path. + +## Windmill PoH as Adult with Nothing + +This allows the logic to consider a jump the adult can make in the windmill to reach the Piece of Heart within with no items. The jump requires leaping +from an object on which it is not obvious Link is allowed to stand and has counterintuitive timing so it is not in standard logic. + +## Crater's Bean PoH with Hover Boots + +This allows the logic to consider using Hover Boots to reach the Piece of Heart atop the volcano in Death Mountain Crater. The path involves walking up a +very steep slope that is not visibly walkable so it is not in normal logic. + +## Zora's Domain Entry with Cucco + +This allows the logic to consider using a Cucco on Zora River to enter Zora's Domain as a child without playing Zelda's Lullaby. It requires slipping behind +the waterfall trickily from the left side. + +## Zora's Domain Entry with Hover Boots + +This allows the logic to consider this similar trick to the above except as an adult with Hover Boots. This is actually a lot more difficult even though it can +be done from either side of the waterfall. + +## Fewer Tunic Requirements + +This relaxes the tunic requirements by the logic somewhat. Normally the logic expects a Goron Tunic to enter Fire Temple or complete the Fire Trial in Ganon's Castle +and a Zora Tunic to enter Water Temple, collect the underwater silver rupees in Gerudo Training Grounds, or obtain the Piece of Heart at the bottom of the frozen Zora's +Fountain. With this flag set, the Goron Tunic will not be required to actually enter Fire Temple, only to fight Volvagia or to reach the upper floors. The Zora Tunic +requirements are removed completely except to reach the chest at the bottom of the central pillar in Water Temple. + +## Morpha with Gold Scale + +This setting allows entry to the Water Temple with the Gold Scale to be considered. Since you cannot backtrack into Water Temple without Iron Boots, only the Spiritual +Stone or Medallion obtained from defeating Morpha can be considered by logic either way; since you need the Water Temple Boss Key and Longshot to access Morpha normally, +this means that this setting is only relevant in either keysanity or keysy relative to the locations of Boss Keys. + +## Lens of Truth + +This setting alters the expectations about interacting with invisible objects without the Lens of Truth. + +### Required Everywhere + +This setting requires the Lens of Truth to interact with any invisible object except for whatever was required in the original game to obtain the Lens of Truth. + +### Wasteland and Chest Minigame + +This setting expects the Lens of Truth to be used only to cross the Haunted Wasteland and to win the Treasure Chest Minigame in Castle Town at night. + +### Only Chest Minigame + +This setting expects the Lens of Truth to be used only to win the Treasure Chest Minigame in Castle Town at night. + +# Other + +## Skip Tower Collapse Sequence + +This setting causes defeating Ganondorf to skip directly to the Ganon fight without the need to do the collapsing Ganon's Tower sequence. + +## Skip Interior Castle Guard Stealth Sequence + +This setting causes entering the crawlspace at Hyrule Castle to deposit the player directly into the Castle Courtyard, bypassing the guard +evasion sequence. + +## Skip Epona Race + +This setting causes Epona to be stolen from Ingo from the start of the game, only requiring Epona's Song and an ocarina as an adult to summon. + +## Fast Chest Cutscenes + +This setting causes all chests to open with a quick animation. If this setting is off, certain important items will trigger the slow opening animation. + +## Random Big Poe Target Count + +This setting causes the number of Big Poes that must be turned into the vendor to obtain his item to be random from 1-10. Alternatively, the number +of Big Poes requires can be selected manually with the slider below. Note that Big Poes can be found as pre-stocked Bottle contents, and the logic +can expect using them if the required number is sufficiently low. + +## Start with Scarecrow's Song + +This flag causes Pierre the Scarecrow to be available to summon for the adult from the beginning of the game. The box below can be used to +specify the particular desired Scarecrow's Song. This song must be exactly eight notes long and must contain at least two different notes. + +## Randomize Ocarina Song Notes + +This flag randomizes the particular notes in the 12 standard ocarina songs. This can predictably be pretty obnoxious. In general, the patterns chosen +for the top row songs will be simpler than the patterns chosen for warp songs. + +## Chest Size Matches Contents + +This flag causes keys, Ice Traps, and items flagged as progression items to appear in large treasure chests while other items will be in small treasure chests. +This means that players can choose to skip small treasure chests since they will only contain handy, not essential, items. + +## Clearer Hints + +This flag changes the text of Gossip Stone hints to be overwhelmingly explicit. This is helpful for players who do not have English as their first language, +but the hints will be less "fun" and less like the sorts of things that would be said in the original game. + +## Gossip Stones + +This flag changes the behavior of Gossip Stones to give hints to players. The hints will be distributed as such: + +-If the required number of trials is 1-3, a hint will be added for each trial that must be done. If the required number of trials is 4 or 5, a hint will be added +for each trial that can be skipped. +-Hints will be added for every one of the "always" locations that is allowed to have a random possibly valuable item under the current settings. These hints +will tell the player what item is at each of these locations. These locations are the rewards for 30, 40, and 50 Gold Skulltula Tokens, the item obtained from +Biggoron by showing the Claim Check, the item obtained from the Big Poe vendor, both the song and the item slots at the Ocarina of Time, and the item obtained +from showing the Mask of Truth at the Deku Theater. +-Some hints will be given for items at a randomly selected number of other locations that are generally somewhat inconvenient to check. The total number of these +hints will be either 11 or 12 minus the number of always hints placed. +-3 or 4 hints will be given naming a specific non-dungeon specific item that can be found in a randomly chosen dungeon. +-1 to 4 hints will be given naming a specific item found in a specific overworld region. Which part of this range is used is determined in part by how many +trial hints are given. +-4 to 6 hints will be given naming what region specific progression items other than Gold Skulltula Tokens can be found. +-3 or 4 hints will be given naming specific regions that are "on the way of the hero" and thus contain at least one required progression item. +-All remaining hints (33 total unique Gossip Stones exist) will be filled with non-information junk hints. + +This setting allows the player to specify which item is required to interact with the Gossip Stones. The Stone of Agony is the default option as it gives a +fairly purposeless vanilla item a use and allows both kid and adult to interact with the Gossip Stones. The default Mask of Truth can be used, but this has +the downside that the Mask of Truth can only be obtained with all Spiritual Stones which tends to make the hints not useful, and using the Mask of Truth +requires being a child which is another big downside. There is also an option for the information to just be free for those wanting an easier mode. + +## Text Shuffle + +This setting allows all the text in the game to be shuffled. This is mostly for comedy and is not intended to be a serious gameplay option. + +### No Text Shuffled + +Leave the text alone. + +### Shuffled except Hints and Keys + +Shuffle all text other than the useful text giving the player information. + +### All Text Shuffled + +Shuffle all text even to the player's mechanical disadvantage. + +## Difficulty + +This setting allows the player to tweak the item pool to make a somewhat harder experience. + +### Normal + +Leave the item pool alone. + +### Hard + +Heart Containers, Double Defense, and the second Magic Upgrade are replaced with junk items. One each +of the ammo expansions (Quiver, Bullet Bag, Bomb Bag Deku Stick Capacity, Deku Nut Capacity) will also +be replaced with junk items, and all Bombchu pick-ups other than three will similarly be replaced with +junk. + +### Very Hard + +In addition to the items from Hard, Pieces of Heart and Nayru's Love are also replaced with junk items. +One more of each ammo expansion is removed resulting in zero extra ammo capacity for those item types, +and only one Bombchu pick-up can be found. + +### OHKO + +In addition to the item changes from Very Hard, Link dies in one hit. Ice Traps are replaced with Recovery Hearts. + +# Cosmetics + +## Background Music + +### Normal + +Do not alter the background music. + +### No Music + +Disable background music. Sound effects will still play. This may be desired by players who like to listen to their own music. + +### Random + +Background music is shuffled so that different tracks may play in different areas. This may be silly. + ## Kokiri Tunic Color This determines the color of Link's default Kokiri Tunic. This only affects the color when he's wearing it, not the color of the icon in the menu. ### Most Colors -Simply get the particular color selected. Available colors are Kokiri Green, Goron Red, Zora Blue, Black, White, Purple, Yellow, Orange, Pink, Gray, -Brown, Gold, Silver, Beige, Teal, Royal Blue, Sonic Blue, Blood Red, Blood Orange, NES Green, and Dark Green. +Simply get the particular color selected. Available colors are Kokiri Green, Goron Red, Zora Blue, Black, White, Azure Blue, Vivid Cyan, Light Red, +Fuchsia, Purple, MM Purple, Twitch Purple, Purple Heart, Persian Rose, Dirty Yellow, Blush Pink, Hot Pink, Rose Pink, Orange, Gray, Gold, Silver, +Beige, Teal, Blood Red, Blood Orange, Royal Blue, Sonic Blue, NES Green, Dark Green, and Lumen. -### Random +### Random Choice Choose a random color from the set of pre-made colors. -### True Random +### Completely Random Generate a random color with numerically random RGB values. +### Custom Color + +A special interface will pop up that will allow the user to choose any color from a diverse color wheel or input a desired RGB value. + ## Goron Tunic Color This determines the color of Link's Goron Tunic. This only affects the color when he's wearing it, not the color of the icon in the menu or when @@ -205,78 +737,87 @@ more pleasant to listen to while a few are designed to be more amusing. ### Particular Sounds -Set this particular sound for the heart beep. Available choices are Default, Softer Beep, Rupee, Timer, Tamborine, Recovery Heart, Carrot Refill, -Navi - Hey!, Zelda - Gasp, Cluck, and Mweep!. The last of these is indeed the sound a king might make when moving... very slowly. +Set this particular sound for the heart beep. Available choices are Default, Softer Beep, Rupee, Timer, Tambourine, Recovery Heart, Carrot Refill, +Navi - Hey!, Zelda - Gasp, Cluck, Mweep!, Iron Boots, Hammer, Sword Bounce, Bow, Gallop, Drawbridge, Switch, Bomb Bounce, Bark, Ribbit, Broken Pot, +Business Scrub, Guay, and Bongo Bongo. Indeed, one of these is the sound a king might make when moving... very slowly. + +### Random Choice + +Play a random SFX from the list of choices. ### None Disable low health heart beeps altogether. -## Create Spoiler Log +## Navi Color -Output a Spoiler File. +These options can be used to set Navi's color in a variety of contexts. The lists of pre-set colors here is different, but the same types of options +exist as for choosing tunic colors. -## Do not Create Patched Rom +## Navi Hint -If set, will not produce a patched rom as output. Useful in conjunction with the spoiler log option to batch -generate spoilers for statistical analysis. +This option sets the SFX that will play when Navi is ready to give a hint. The options are very similar to the Low Health SFX. -## Compress patched Rom +## Navi Enemy Target -If set, the randomizer will additionally output a compressed ROM using Grant Man's bundled compressor. This compressor is the fastest -compressor out there and tuned specifically for this game, but in order to achieve its incredibly high speed, it does utilize every last bit -of CPU your computer will give it so your computer will slow to a crawl otherwise during the couple of minutes this will take. +This option sets the SFX that will play when Navi targets an enemy. The options are very similar to the Low Health SFX. -## Open Forest +# Command Line Options -Mido does not need to see a sword and shield to reach the Deku Tree and the Kokiri boy blocking the exit to the forest is gone. -If this flag is not set, it is guaranteed that the Deku Tree can be completed without leaving the forest. +``` +-h, --help +``` -## Open Door of Time +Show the help message and exit. -The Door of Time is open from the beginning of the game. The Song of Time is only useful to move Song of Time blocks. +``` +--check_version +``` -## Skip most of Ganon's Castle +Check for the latest version number online (default: False) -The barrier protecting Ganon's Tower within Ganon's Castle is dispelled from the start, the Boss Key doors within Ganon's Tower are unlocked by -default, Ganondorf will provide a hint for the location of Light Arrows, and the collapsing tower sequence is skipped. +``` +--checked_version CHECKED_VERSION +``` -## Place Dungeon Items +Check for the specified version number instead of a number from online. -If not set, Compasses and Maps are removed from the dungeon item pools and replaced by five rupee chests that may end up anywhere in the world. -This may lead to different amount of itempool items being placed in a dungeon than you are used to. +``` +--rom ROM +``` -## Only Ensure Seed Beatable +Path to a The Legend of Zelda: Ocarina of Time NTSC-US v1.0 ROM. (default: ZOOTDEC.z64) -If set, will only ensure that Ganon can be defeated, but not necessarily that all locations are reachable. +``` +--output_dir OUTPUT_DIR +``` -## Gossip Stone Hints with Stone of Agony +Path to output directory for rom generation. -If set, the 32 Gossip Stones scattered across Hyrule will have various hints informing the player of which items are in various inconvenient locations. The -Stone of Agony is the condition to be able to talk to the Gossip Stones in this mode instead of the Mask of Truth out of mercy to the player. The nine locations -we regarded as the most generally inconvenient for all medallions play will always have hints, those hints will appear in two places, and the logic will guarantee -access to the Stone of Agony before those places must be checked. Those places are the rewards for 30, 40, and 50 Gold Skulltullas, both rewards from the fishing -minigame, the song from the Ocarina of Time, the item from showing the Mask of Truth in the Deku Theater, the item for defeating 10 Big Poes, and the item for -redeeming the Claim Check with Biggoron. There will be seven other hints that only exist once for other somewhat inconvenient places for which there is no -guarantee of Stone of Agony access, and there will be seven other sorts of remarks from the Gossip Stones in the hint pool that may bring a smile to your face but -will not provide you with unique information for your quest. The unreachable Gossip Stone in the Kokiri Forest is included in this 32 Gossip Stone hint shuffle as -well so be aware that one instance of a hint will seem to effectively vanish every seed. +``` +--seed SEED +``` -## Seed +Define seed number to generate. (default: None) -Can be used to set a seed number to generate. Using the same seed with same settings on the same version of the randomizer will always yield an identical output. +``` +--count COUNT +``` -## Count +Set the count option (default: None) -Use to batch generate multiple seeds with same settings. If a seed number is provided, it will be used for the first seed, then used to derive the next seed (i.e. generating 10 seeds with the same seed number given will produce the same 10 (different) roms each time). +``` +--world_count WORLD_COUNT +``` -# Command Line Options +Use to create a multi-world generation for co-op seeds. World count is the number of players. +Warning: Increasing the world count will drastically increase generation time. (default: 1) ``` --h, --help +--player_num PLAYER_NUM ``` -Show the help message and exit. +Use to select world to generate when there are multiple worlds. (default: 1) ``` --create_spoiler @@ -284,6 +825,39 @@ Show the help message and exit. Output a Spoiler File (default: False) +``` +--compress_rom [{True,False,None}] +``` + +Create a compressed version of the output rom file. +True: Compresses. Improves stability. Will take longer to generate +False: Uncompressed. Unstable on emulator. Faster generation +None: No ROM Output. Creates spoiler log only (default: True) + +``` +--open_forest +``` + +Set whether Kokiri children obstruct your path at the beginning of the game. (default: False) + +``` +--open_kakariko +``` + +The gate in Kakariko Village to Death Mountain Trail is always open, instead of needing Zelda's Letter. (default: False) + +``` +--open_door_of_time +``` + +Set whether the Door of Time is open from the beginning of the game. (default: False) + +``` +--gerudo_fortress [{normal,fast,open}] +``` + +Select how much of Gerudo Fortress is required. (default: normal) + ``` --bridge [{medallions,vanilla,dungeons,open}] ``` @@ -291,104 +865,440 @@ Output a Spoiler File (default: False) Select the condition to spawn the Rainbow Bridge to Ganon's Castle. (default: medallions) ``` ---kokiricolor [{'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green', 'Random', 'True Random'}] +--all_reachable ``` -Select the color of Link's Kokiri Tunic. (default: Kokiri Green) +Enables the "Only Ensure Seed Beatable" option (default: False) ``` ---goroncolor [{'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green', 'Random', 'True Random'}] +--all_reachable ``` -Select the color of Link's Goron Tunic. (default: Goron Red) +Enables the "Only Ensure Seed Beatable" option (default: False) ``` ---zoracolor [{'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green', 'Random', 'True Random'}] +--bombchus_in_logic ``` -Select the color of Link's Zora Tunic. (default: Zora Blue) +Changes how the logic considers Bombchus and other Bombchu related mechanics (default: False) ``` ---healthSFX [{'Default', 'Softer Beep', 'Rupee', 'Timer', 'Tamborine', 'Recovery Heart', 'Carrot Refill', 'Navi - Hey!', 'Zelda - Gasp', 'Cluck', 'Mweep!', 'Random', 'None'}] +--one_item_per_dungeon ``` -Select the sound effect that loops at low health. (default: Default) +Each dungeon will have exactly one major item. (default: False) ``` ---rom ROM +--trials_random ``` -Path to a The Legend of Zelda: Ocarina of Time NTSC-US v1.0 ROM. (default: ZELOOTROMDEC.z64) +Sets the number of trials that must be cleared in Ganon's Castle to a random value (default: False) ``` ---loglevel [{error,info,warning,debug}] +--trials [{0,1,2,3,4,5,6}] ``` -Select level of logging for output. (default: info) +Sets the number of trials that must be cleared in Ganon's Castle (default: 6) ``` ---seed SEED +--no_escape_sequence ``` -Define seed number to generate. (default: None) +Removes the tower collapse sequence after defeating Ganondorf (default: False) ``` ---count COUNT +--no_guard_stealth ``` -Set the count option (default: None) +Removes the guard evasion sequence in Hyrule Castle (default: False) ``` ---open_forest +--no_epona_race ``` -Set whether Kokiri children obstruct your path at the beginning of the game. (default: False) +Removes the need to race Ingo to acquire Epona (default: False) ``` ---open_door_of_time +--fast_chests ``` -Set whether the Door of Time is open from the beginning of the game. (default: False) +Causes all chests to open with a fast animation (default: False) ``` ---fast_ganon +--big_poe_count_random ``` -Set whether most of Ganon's Castle can be skipped. (default: False) +Sets the number of Big Poes that must be sold to the vendor for an item to a random value (default: False) ``` ---nodungeonitems +--big_poe_count [{1,2,3,4,5,6,7,8,9,10}] ``` -If set, Compasses and Maps are removed from the dungeon item pools and replaced by five rupee chests that may end up anywhere in the world. -This may lead to different amount of itempool items being placed in a dungeon than you are used to. (default: False) +Sets the number of Big Poes that must be sold to the vendor for an item (default: 10) ``` ---beatableonly +--free_scarecrow ``` -Enables the "Only Ensure Seed Beatable" option (default: False) +Start the game with the Scarecrow's Song activated and Pierre possible for the adult to summon (default: False) + +``` +--scarecrow_song [SCARECROW_SONG] +``` + +Set Scarecrow's Song if --free_scarecrow is used. Valid notes: A, U, L, R, D (default: DAAAAAAA) + +``` +--shuffle_kokiri_sword +``` + +Include the Kokiri Sword as a randomized item (default: False) + +``` +--shuffle_weird_egg +``` + +Include the Weird Egg as a randomized item (default: False) + +``` +--shuffle_ocarinas +``` + +Include the two ocarinas as randomized items (default: False) + +``` +--shuffle_song_items +``` + +Treat the ocarina songs as normal items and shuffle them into the general item pool (default: False) + +``` +--shuffle_gerudo_card +``` + +Include the Gerudo Card to access Gerudo Training Grounds as a randomized item (default: False) + +``` +--shuffle_scrubs [{off,low,regular,random}] +``` + +Include all Deku Scrub Salesmen as randomized item and determine their prices (default: off) + +``` +--shopsanity [{off,0,1,2,3,4,random}] +``` + +Randomize shop items and add the chosen number of items from the general item pool to shop inventories (default: off) + +``` +--shuffle_mapcompass [{remove,startwith,dungeon,keysanity}] +``` + +Choose the locations Maps and Compasses can be found (default: dungeon) + +``` +--shuffle_smallkeys [{remove,dungeon,keysanity}] +``` + +Choose the locations Small Keys can be found (default: dungeon) + +``` +--shuffle_bosskeys [{remove,dungeon,keysanity}] +``` + +Choose the locations Boss Keys can be found (default: dungeon) + +``` +--enhance_map_compass +``` + +Change the functionality of the Map and Compass to give information about their dungeons. The Temple of Time Altar will no longer provide any dungeon information. (default: False) + +``` +--unlocked_ganondorf +``` + +Remove the Boss Key door leading to Ganondorf (default: False) + +``` +--tokensanity [{off,dungeons,all}] +``` + +Include the chosen Gold Skulltula Token locations in the item shuffle (default: off) + +``` +--quest [{vanilla,master,mixed}] +``` + +Choose the internal layout of the dungeons (default: vanilla) + +``` +--logic_skulltulas [{0,10,20,30,40,50}] +``` + +Choose the maximum number of Gold Skulltula Tokens that could be required (default: 50) + +``` +--logic_no_night_tokens_without_suns_song +``` + +Change logic to expect Sun's Song to defeat nighttime Gold Skulltulas (default: False) + +``` +--logic_no_big_poes +``` + +Prevent the Big Poe vendor from having a required item (default: False) + +``` +--logic_no_child_fishing +``` + +Prevent the prize from fishing as a child from being a required item (default: False) + +``` +--logic_no_adult_fishing +``` + +Prevent the prize from fishing as an adult from being a required item (default: False) + +``` +--logic_no_trade_skull_mask +``` + +Prevent the item obtained by showing the Skull Mask at the Deku Theater from being a required item (default: False) + +``` +--logic_no_trade_mask_of_truth +``` + +Prevent the item obtained by showing the Mask of Truth at the Deku Theater from being a required item (default: False) + +``` +--logic_no_1500_archery +``` + +Prevent the item obtained by scoring 1500 points at horseback archery from being a required item (default: False) + +``` +--logic_no_memory_game +``` + +Prevent the item obtained by completing the ocarina memory game in the Lost Woods from being a required item (default: False) + +``` +--logic_no_second_dampe_race +``` + +Prevent the prize won by finishing the second Dampe race in under 1 minute from being a required item (default: False) + +``` +--logic_no_trade_biggoron +``` + +Prevent the item obtained by showing the Claim Check to Biggoron from being a required item (default: False) + +``` +--logic_earliest_adult_trade [{pocket_egg,pocket_cucco,cojiro,odd_mushroom,poachers_saw,broken_sword,prescription,eyeball_frog,eyedrops,claim_check}] +``` + +Set the earliest item in the adult trade sequence that can be found in the item pool (default: pocket_egg) + +``` +--logic_latest_adult_trade [{pocket_egg,pocket_cucco,cojiro,odd_mushroom,poachers_saw,broken_sword,prescription,eyeball_frog,eyedrops,claim_check}] +``` + +Set the latest item in the adult trade sequence that can be found in the item pool (default: claim_check) + +``` +--logic_tricks +``` + +Enable the logic to consider a large number of minor tricks (default: False) + +``` +--logic_man_on_roof +``` + +Enable the logic to consider the trick to reach the man on the roof in Kakariko Village with a sidehop from the tower (default: False) + +``` +--logic_child_deadhand +``` + +Enable the logic to consider the child defeating Deadhand with only Deku Sticks (default: False) + +``` +--logic_dc_jump +``` + +Enable the logic to consider the trick to bypass the second Lizalfos fight room in Dodongo's Cavern as an adult with a simple jump (default: False) + +``` +--logic_windmill_poh +``` + +Enable the logic to consider the trick to reach the Piece of Heart in the windmill as an adult with nothing (default: False) + +``` +--logic_crater_bean_poh_with_hovers +``` + +Enable the logic to consider the trick to reach the Piece of Heart on the volcano in Death Mountain Crater with Hover Boots (default: False) + +``` +--logic_zora_with_cucco +``` + +Enable the logic to consider the trick to enter Zora's Domain as a child using a Cucco instead of playing Zelda's Lullaby (default: False) + +``` +--logic_zora_with_hovers +``` + +Enable the logic to consider the trick to enter Zora's Domain as an adult using Hover Boots instead of playing Zelda's Lullaby (default: False) + +``` +--logic_fewer_tunic_requirements +``` + +Reduce the number of locations for which the logic expects a tunic upgrade (default: False) + +``` +--logic_morpha_with_scale +``` + +Allows entering Water Temple and beating Morpha with Gold Scale instead of Iron Boots. The Longshot and Boss Key are still required to reach the boss. +This means that this option is only relevant in keysanity or keysy. (default: False) + +``` +--logic_lens [{chest,chest-wasteland,all}] +``` + +Set which hidden objects the logic expects the Lens of Truth to be used on (default: all) + +``` +--ocarina_songs +``` + +Randomize the particular notes that must be played for each of the 12 standard ocarina songs (default: False) + +``` +--correct_chest_sizes +``` + +Set chest sizes based on contents (default: False) ``` ---hints +--clearer_hints ``` -Gossip Stones provide helpful hints about which items are in inconvenient locations if the Stone of Agony is in the player's inventory. (default: False) +Reword hints to be incredibly direct (default: False) ``` ---suppress_rom +--hints [{none,mask,agony,always}] ``` -Enables the "Do not Create Patched Rom" option. (default: False) +Enable hints from Gossip Stones and select the condition to read them (default: agony) ``` ---compress_rom +--text_shuffle [{none,except_hints,complete}] ``` -Create a compressed version of the output ROM file. (default: False) +Shuffle the chosen text randomly (default: none) + +``` +--difficulty [{normal,hard,very_hard,ohko}] +``` + +Alter the item pool to increase difficulty. The ohko option also causes Link to die in one hit. (default: normal) + +``` +--default_targeting [{hold,switch}] +``` + +Set the default Z-targeting setting. It can still be changed in the game's options menu. (default: hold) + +``` +--background_music [{normal,off,random}] +``` + +Choose whether the game's background music will be left alone, disabled, or shuffled randomly. (default: normal) + +``` +--kokiricolor [{'Random Choice', 'Completely Random', 'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Azure Blue', 'Vivid Cyan', 'Light Red', 'Fuchsia', 'Purple', 'MM Purple', 'Twitch Purple', 'Purple Heart', 'Persian Rose', 'Dirty Yellow', 'Blush Pink', 'Hot Pink', 'Rose Pink', 'Orange', 'Gray', 'Gold', 'Silver', 'Beige', 'Teal', 'Blood Red', 'Blood Orange', 'Royal Blue', 'Sonic Blue', 'NES Green', 'Dark Green', 'Lumen'}] +``` + +Select the color of Link's Kokiri Tunic. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: Kokiri Green) + +``` +--goroncolor [{'Random Choice', 'Completely Random', 'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Azure Blue', 'Vivid Cyan', 'Light Red', 'Fuchsia', 'Purple', 'MM Purple', 'Twitch Purple', 'Purple Heart', 'Persian Rose', 'Dirty Yellow', 'Blush Pink', 'Hot Pink', 'Rose Pink', 'Orange', 'Gray', 'Gold', 'Silver', 'Beige', 'Teal', 'Blood Red', 'Blood Orange', 'Royal Blue', 'Sonic Blue', 'NES Green', 'Dark Green', 'Lumen'}] +``` + +Select the color of Link's Goron Tunic. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: Goron Red) + +``` +--zoracolor [{'Random Choice', 'Completely Random', 'Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Azure Blue', 'Vivid Cyan', 'Light Red', 'Fuchsia', 'Purple', 'MM Purple', 'Twitch Purple', 'Purple Heart', 'Persian Rose', 'Dirty Yellow', 'Blush Pink', 'Hot Pink', 'Rose Pink', 'Orange', 'Gray', 'Gold', 'Silver', 'Beige', 'Teal', 'Blood Red', 'Blood Orange', 'Royal Blue', 'Sonic Blue', 'NES Green', 'Dark Green', 'Lumen'}] +``` + +Select the color of Link's Zora Tunic. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: Zora Blue) + +``` +--navicolordefault [{'Random Choice', 'Completely Random', 'Gold', 'White', 'Green', 'Light Blue', 'Yellow', 'Red', 'Magenta', 'Black', 'Tatl', 'Tael', 'Fi', 'Ciela', 'Epona', 'Ezlo', 'King of Red Lions', 'Linebeck', 'Loftwing', 'Midna', 'Phantom Zelda'}] +``` + +Select the color of Navi in idle. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: White) + +``` +--navicolorenemy [{'Random Choice', 'Completely Random', 'Gold', 'White', 'Green', 'Light Blue', 'Yellow', 'Red', 'Magenta', 'Black', 'Tatl', 'Tael', 'Fi', 'Ciela', 'Epona', 'Ezlo', 'King of Red Lions', 'Linebeck', 'Loftwing', 'Midna', 'Phantom Zelda'}] +``` + +Select the color of Navi when she is targeting an enemy. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: Yellow) + +``` +--navicolornpc [{'Random Choice', 'Completely Random', 'Gold', 'White', 'Green', 'Light Blue', 'Yellow', 'Red', 'Magenta', 'Black', 'Tatl', 'Tael', 'Fi', 'Ciela', 'Epona', 'Ezlo', 'King of Red Lions', 'Linebeck', 'Loftwing', 'Midna', 'Phantom Zelda'}] +``` + +Select the color of Navi when she is targeting an NPC. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: Light Blue) + +``` +--navicolorprop [{'Random Choice', 'Completely Random', 'Gold', 'White', 'Green', 'Light Blue', 'Yellow', 'Red', 'Magenta', 'Black', 'Tatl', 'Tael', 'Fi', 'Ciela', 'Epona', 'Ezlo', 'King of Red Lions', 'Linebeck', 'Loftwing', 'Midna', 'Phantom Zelda'}] +``` + +Select the color of Navi when she is targeting a prop. Can also set Custom (#RRGGBB) using hexadecimal RGB values to set a custom color. (default: Green) + +``` +--navisfxoverworld [{'Default', 'Random Choice', 'None', 'Cluck', 'Rupee', 'Softer Beep', 'Recovery Heart', 'Timer', 'Low Health', 'Notification', 'Tambourine', 'Carrot Refill', 'Zelda - Gasp', 'Mweep!', 'Ice Break', 'Explosion', 'Crate', 'Great Fairy', 'Moo', 'Bark', 'Ribbit', 'Broken Pot', 'Cockadoodledoo', 'Epona', 'Gold Skulltula', 'Redead', 'Poe', 'Ruto', 'Howl', 'Business Scrub', 'Guay', "H'lo!"}] +``` + +Select the sound effect that plays when Navi wishes to speak with the player. (default: Default) + +``` +--navisfxenemytarget [{'Default', 'Random Choice', 'None', 'Cluck', 'Rupee', 'Softer Beep', 'Recovery Heart', 'Timer', 'Low Health', 'Notification', 'Tambourine', 'Carrot Refill', 'Zelda - Gasp', 'Mweep!', 'Ice Break', 'Explosion', 'Crate', 'Great Fairy', 'Moo', 'Bark', 'Ribbit', 'Broken Pot', 'Cockadoodledoo', 'Epona', 'Gold Skulltula', 'Redead', 'Poe', 'Ruto', 'Howl', 'Business Scrub', 'Guay', "H'lo!"}] +``` + +Select the sound effect that plays when Navi targets an enemy. (default: Default) + +``` +--healthSFX [{'Default', 'Random Choice', 'None', 'Cluck', 'Softer Beep', 'Recovery Heart', 'Timer', 'Notification', 'Tambourine', 'Carrot Refill', 'Navi - Random', 'Navi - Hey!', 'Zelda - Gasp', 'Mweep!', 'Iron Boots', 'Hammer', 'Sword Bounce', 'Bow', 'Gallop', 'Drawbridge', 'Switch', 'Bomb Bounce', 'Bark', 'Ribbit', 'Broken Pot', 'Business Scrub', 'Guay', 'Bongo Bongo'}] +``` + +Select the sound effect that loops at low health. (default: Default) ``` --gui ``` Open the graphical user interface. Preloads selections with set command line parameters. + +``` +--loglevel [{error,info,warning,debug}] +``` + +Select level of logging for output. (default: info) + +``` +--settings_string SETTINGS_STRING +``` + +Enter a settings string that will encode and override most individual settings. diff --git a/Regions.py b/Regions.py index c7db3c8cd..89e5331cb 100644 --- a/Regions.py +++ b/Regions.py @@ -1,180 +1,967 @@ import collections from BaseClasses import Region, Location, Entrance, RegionType +def shop_address(shop_id, shelf_id): + return 0xC71ED0 + (0x40 * shop_id) + (0x08 * shelf_id) def create_regions(world): world.regions = [ - create_ow_region('Kokiri Forest', ['Kokiri Sword Chest', 'GS1', 'GS2', 'GS3'], ['Links House', 'Mido House', 'Saria House', 'House of Twins', 'Know It All House', 'Kokiri Shop', 'Deku Tree', 'Lost Woods', 'Lost Woods Bridge', 'Kokiri Forest Storms Grotto']), - create_interior_region('Links House', ['Links Pocket'], ['Links House Exit', 'Child Forest Warp Pad', 'Adult Forest Warp Pad', 'Temple Warp Pad', 'Crater Warp Pad', 'Lake Warp Pad', 'Graveyard Warp Pad', 'Colossus Warp Pad']), - create_interior_region('Mido House', ['Mido Chest Top Left', 'Mido Chest Top Right', 'Mido Chest Bottom Left', 'Mido Chest Bottom Right'], ['Mido House Exit']), - create_interior_region('Saria House', None, ['Saria House Exit']), - create_interior_region('House of Twins', None, ['House of Twins Exit']), - create_interior_region('Know It All House', None, ['Know It All House Exit']), - create_interior_region('Kokiri Shop', None, ['Kokiri Shop Exit']), - create_dungeon_region('Deku Tree Lobby', ['Deku Tree Lobby Chest', 'Deku Tree Compass Chest', 'Deku Tree Compass Room Side Chest', 'Deku Tree Basement Chest', 'GS8', 'GS9', 'GS10'], ['Deku Tree Exit', 'Deku Tree Slingshot Passage', 'Deku Tree Basement Path']), - create_dungeon_region('Deku Tree Slingshot Room', ['Deku Tree Slingshot Chest', 'Deku Tree Slingshot Room Side Chest'], ['Deku Tree Slingshot Exit']), - create_dungeon_region('Deku Tree Boss Room', ['GS11', 'Queen Gohma Heart', 'Queen Gohma'], ['Deku Tree Basement Vines']), - create_ow_region('Lost Woods', ['Skull Kid', 'Ocarina Memory Game', 'Target in Woods', 'Deku Salesman Woods', 'GS4', 'GS5'], ['Lost Woods Front', 'Meadow Entrance', 'Woods to Goron City', 'Lost Woods Dive Warp', 'Adult Meadow Access', 'Lost Woods Generic Grotto', 'Deku Theater', 'Lost Woods Sales Grotto']), + create_ow_region( + 'Kokiri Forest', + ['Kokiri Sword Chest', 'GS Kokiri Know It All House', 'GS Kokiri Bean Patch', 'GS Kokiri House of Twins', + 'Deku Baba Sticks', 'Deku Baba Nuts'], + ['Links House', 'Mido House', 'Saria House', 'House of Twins', 'Know It All House', 'Kokiri Shop', 'Deku Tree', + 'Lost Woods', 'Lost Woods Bridge', 'Kokiri Forest Storms Grotto']), + create_interior_region( + 'Links House', + ['Links Pocket'], + ['Links House Exit', 'Child Forest Warp Pad', 'Adult Forest Warp Pad', 'Temple Warp Pad', 'Crater Warp Pad', + 'Lake Warp Pad', 'Graveyard Warp Pad', 'Colossus Warp Pad']), + create_interior_region( + 'Mido House', + ['Mido Chest Top Left', 'Mido Chest Top Right', 'Mido Chest Bottom Left', 'Mido Chest Bottom Right'], + ['Mido House Exit']), + create_interior_region( + 'Saria House', + None, + ['Saria House Exit']), + create_interior_region( + 'House of Twins', + None, + ['House of Twins Exit']), + create_interior_region( + 'Know It All House', + None, + ['Know It All House Exit']), + create_interior_region( + 'Kokiri Shop', + ['Kokiri Shop Item 1', 'Kokiri Shop Item 2', 'Kokiri Shop Item 3', 'Kokiri Shop Item 4', + 'Kokiri Shop Item 5', 'Kokiri Shop Item 6', 'Kokiri Shop Item 7', 'Kokiri Shop Item 8'], + ['Kokiri Shop Exit']), + create_ow_region( + 'Lost Woods', + ['Skull Kid', 'Ocarina Memory Game', 'Target in Woods', 'LW Deku Scrub Deku Stick Upgrade', + 'GS Lost Woods Bean Patch Near Bridge', 'GS Lost Woods Bean Patch Near Stage', + 'LW Deku Scrub Deku Nuts', 'LW Deku Scrub Deku Sticks'], + ['Lost Woods Front', 'Meadow Entrance', 'Woods to Goron City', 'Lost Woods Dive Warp', 'Adult Meadow Access', + 'Lost Woods Generic Grotto', 'Deku Theater', 'Lost Woods Sales Grotto']), create_ow_region('Sacred Forest Meadow Entryway', None, ['Meadow Exit', 'Meadow Gate', 'Front of Meadow Grotto']), - create_ow_region('Sacred Forest Meadow', ['Song from Saria'], ['Meadow Gate Exit', 'Meadow Fairy Grotto']), + create_ow_region( + 'Sacred Forest Meadow', + ['Song from Saria'], + ['Meadow Gate Exit', 'Meadow Fairy Grotto', 'Meadow Storms Grotto Child Access']), create_ow_region('Lost Woods Bridge', ['Gift from Saria'], ['Kokiri Forest Entrance', 'Forest Exit']), - create_ow_region('Hyrule Field', ['Ocarina of Time', 'Song from Ocarina of Time'], ['Field to Forest', 'Field to Lake', 'Field to Valley', 'Field to Castle Town', 'Field to Kakariko', 'Field to Zora River', 'Lon Lon Rance Entrance', - 'Remote Southern Grotto', 'Field Near Lake Outside Fence Grotto', 'Field Near Lake Inside Fence Grotto', 'Field Valley Grotto', 'Field West Castle Town Grotto', - 'Field Far West Castle Town Grotto', 'Field Kakariko Grotto', 'Field North Lon Lon Grotto']), - create_ow_region('Lake Hylia', ['Underwater Bottle', 'Lake Hylia Sun', 'Lake Hylia Freestanding PoH', 'GS55', 'GS56', 'GS57', 'GS58'], ['Lake Exit', 'Lake Hylia Dive Warp', 'Lake Hylia Lab', 'Fishing Hole', 'Water Temple Entrance', 'Lake Hylia Grotto']), - create_interior_region('Lake Hylia Lab', ['Diving in the Lab', 'GS59']), + create_ow_region('Hyrule Field', + ['Ocarina of Time', 'Song from Ocarina of Time'], + ['Field to Forest', 'Field to Lake', 'Field to Valley', 'Field to Castle Town', 'Field to Kakariko', + 'Field to Zora River', 'Lon Lon Rance Entrance', 'Remote Southern Grotto', 'Field Near Lake Outside Fence Grotto', + 'Field Near Lake Inside Fence Grotto', 'Field Valley Grotto', 'Field West Castle Town Grotto', + 'Field Far West Castle Town Grotto', 'Field Kakariko Grotto', 'Field North Lon Lon Grotto']), + create_ow_region( + 'Lake Hylia', + ['Underwater Bottle', 'Lake Hylia Sun', 'Lake Hylia Freestanding PoH', 'GS Lake Hylia Bean Patch', + 'GS Lake Hylia Lab Wall', 'GS Lake Hylia Small Island', 'GS Lake Hylia Giant Tree'], + ['Lake Exit', 'Lake Hylia Dive Warp', 'Lake Hylia Lab', 'Fishing Hole', 'Water Temple Entrance', 'Lake Hylia Grotto']), + create_interior_region('Lake Hylia Lab', ['Diving in the Lab', 'GS Lab Underwater Crate']), create_interior_region('Fishing Hole', ['Child Fishing', 'Adult Fishing']), - create_dungeon_region('Water Temple Lobby', ['Water Temple Map Chest', 'Water Temple Compass Chest', 'Water Temple Torches Chest', 'Water Temple Dragon Chest', 'Water Temple Central Bow Target Chest', 'Water Temple Boss Key Chest', 'Morpha Heart', 'Morpha', 'GS73', 'GS77'], ['Water Temple Exit', 'Water Temple Central Pillar', 'Water Temple Upper Locked Door']), - create_dungeon_region('Water Temple Middle Water Level', ['Water Temple Central Pillar Chest', 'Water Temple Cracked Wall Chest', 'GS75']), - create_dungeon_region('Water Temple Dark Link Region', ['Water Temple Dark Link Chest', 'Water Temple River Chest', 'GS74', 'GS76']), - create_ow_region('Gerudo Valley', ['Gerudo Valley Waterfall Freestanding PoH', 'Gerudo Valley Crate Freestanding PoH', 'GS86', 'GS87'], ['Valley Exit', 'Valley River', 'Bridge Crossing']), - create_ow_region('Gerudo Valley Far Side', ['Gerudo Valley Hammer Rocks Chest', 'GS88', 'GS89'], ['Fortress Entrance']), - create_ow_region('Gerudo Fortress', ['Gerudo Fortress Rooftop Chest', 'Horseback Archery 1000 Points', 'Horseback Archery 1500 Points', 'Gerudo Fortress Carpenter Rescue', 'GS90', 'GS91'], ['Haunted Wasteland Entrance', 'Gerudo Training Grounds Entrance']), - create_ow_region('Haunted Wasteland', ['Haunted Wasteland Structure Chest', 'GS92'], ['Haunted Wasteland Crossing']), - create_ow_region('Desert Colossus', ['Colossus Freestanding PoH', 'Sheik at Colossus', 'GS93', 'GS94', 'GS95'], ['Colossus Fairy', 'Spirit Temple Entrance']), - create_interior_region('Colossus Fairy', ['Desert Colossus Fairy Reward']), - create_dungeon_region('Gerudo Training Grounds Lobby', ['Gerudo Training Grounds Lobby Left Chest', 'Gerudo Training Grounds Lobby Right Chest', 'Gerudo Training Grounds Stalfos Chest', 'Gerudo Training Grounds Beamos Chest'], ['Gerudo Training Grounds Exit', 'Gerudo Training Ground Left Silver Rupees', 'Gerudo Training Ground Beamos', 'Gerudo Training Ground Central Door']), - create_dungeon_region('Gerudo Training Grounds Central Maze', ['Gerudo Training Grounds Hidden Ceiling Chest', 'Gerudo Training Grounds Maze Path First Chest', 'Gerudo Training Grounds Maze Path Second Chest', 'Gerudo Training Grounds Maze Path Third Chest', 'Gerudo Training Grounds Maze Path Final Chest'], ['Gerudo Training Grounds Right Locked Doors']), - create_dungeon_region('Gerudo Training Grounds Central Maze Right', ['Gerudo Training Grounds Maze Right Central Chest', 'Gerudo Training Grounds Maze Right Side Chest', 'Gerudo Training Grounds Freestanding Key'], ['Gerudo Training Grounds Maze Exit']), - create_dungeon_region('Gerudo Training Grounds Lava Room', ['Gerudo Training Grounds Underwater Silver Rupee Chest'], ['Gerudo Training Grounds Maze Ledge', 'Gerudo Training Grounds Right Hookshot Target']), - create_dungeon_region('Gerudo Training Grounds Hammer Room', ['Gerudo Training Grounds Hammer Room Clear Chest', 'Gerudo Training Grounds Hammer Room Switch Chest'], ['Gerudo Training Grounds Hammer Target', 'Gerudo Training Grounds Hammer Room Clear']), - create_dungeon_region('Gerudo Training Grounds Eye Statue Lower', ['Gerudo Training Grounds Eye Statue Chest'], ['Gerudo Training Grounds Eye Statue Exit']), - create_dungeon_region('Gerudo Training Grounds Eye Statue Upper', ['Gerudo Training Grounds Near Scarecrow Chest'], ['Gerudo Training Grounds Eye Statue Drop']), - create_dungeon_region('Gerudo Training Grounds Heavy Block Room', ['Gerudo Training Grounds Before Heavy Block Chest', 'Gerudo Training Grounds Heavy Block First Chest', 'Gerudo Training Grounds Heavy Block Second Chest', 'Gerudo Training Grounds Heavy Block Third Chest', 'Gerudo Training Grounds Heavy Block Fourth Chest'], ['Gerudo Training Grounds Hidden Hookshot Target']), - create_dungeon_region('Spirit Temple Lobby', None, ['Spirit Temple Exit', 'Spirit Temple Crawl Passage', 'Spirit Temple Silver Block']), - create_dungeon_region('Child Spirit Temple', ['Spirit Temple Child Left Chest', 'Spirit Temple Child Right Chest', 'GS96'], ['Child Spirit Temple Passthrough']), - create_dungeon_region('Early Adult Spirit Temple', ['Spirit Temple Compass Chest', 'Spirit Temple Early Adult Right Chest', 'Spirit Temple First Mirror Right Chest', 'Spirit Temple First Mirror Left Chest', 'GS99'], ['Adult Spirit Temple Passthrough']), - create_dungeon_region('Spirit Temple Central Chamber', ['Spirit Temple Map Chest', 'Spirit Temple Child Climb East Chest', 'Spirit Temple Child Climb North Chest', 'Spirit Temple Sun Block Room Chest', 'Spirit Temple Statue Hand Chest', 'Spirit Temple NE Main Room Chest', 'GS97', 'GS98', 'GS100'], ['Spirit Temple to Hands', 'Spirit Temple Central Locked Door']), - create_dungeon_region('Spirit Temple Outdoor Hands', ['Silver Gauntlets Chest', 'Mirror Shield Chest']), - create_dungeon_region('Spirit Temple Beyond Central Locked Door', ['Spirit Temple Near Four Armos Chest', 'Spirit Temple Hallway Left Invisible Chest', 'Spirit Temple Hallway Right Invisible Chest'], ['Spirit Temple Final Locked Door']), - create_dungeon_region('Spirit Temple Beyond Final Locked Door', ['Spirit Temple Boss Key Chest', 'Spirit Temple Topmost Chest', 'Twinrova Heart', 'Twinrova']), - create_ow_region('Castle Town', None, ['Castle Town Exit', 'Temple of Time', 'Hyrule Castle Grounds', 'Castle Town Rupee Room', 'Castle Town Bazaar', 'Castle Town Mask Shop', 'Castle Town Shooting Gallery', 'Ganons Castle Grounds', - 'Castle Town Bombchu Bowling', 'Castle Town Potion Shop', 'Castle Town Treasure Chest Game', 'Castle Town Bombchu Shop', 'Castle Town Dog Lady', 'Castle Town Man in Green House']), - create_interior_region('Temple of Time', ['Zelda'], ['Temple of Time Exit', 'Door of Time']), - create_interior_region('Beyond Door of Time', ['Master Sword Pedestal', 'Sheik at Temple'], ['Emerge as Adult']), - create_ow_region('Hyrule Castle Grounds', ['GS15'], ['Hyrule Castle Grounds Exit', 'Hyrule Castle Garden', 'Hyrule Castle Fairy', 'Castle Storms Grotto']), - create_ow_region('Hyrule Castle Garden', ['Zeldas Letter', 'Impa at Castle'], ['Hyrule Castle Garden Exit']), - create_interior_region('Hyrule Castle Fairy', ['Hyrule Castle Fairy Reward']), - create_ow_region('Ganons Castle Grounds', ['GS17'], ['Ganons Castle Grounds Exit', 'Ganons Castle Fairy', 'Rainbow Bridge']), + create_ow_region( + 'Gerudo Valley', + ['Gerudo Valley Waterfall Freestanding PoH', 'Gerudo Valley Crate Freestanding PoH', + 'GS Gerudo Valley Small Bridge', 'GS Gerudo Valley Bean Patch'], + ['Valley Exit', 'Valley River', 'Bridge Crossing']), + create_ow_region( + 'Gerudo Valley Far Side', + ['Gerudo Valley Hammer Rocks Chest', 'GS Gerudo Valley Behind Tent', 'GS Gerudo Valley Pillar'], + ['Fortress Entrance', 'Gerudo Valley Storms Grotto']), + create_ow_region( + 'Gerudo Fortress', + ['Gerudo Fortress Rooftop Chest', 'Horseback Archery 1000 Points', 'Horseback Archery 1500 Points', + 'Gerudo Fortress North F1 Carpenter', 'Gerudo Fortress North F2 Carpenter', + 'Gerudo Fortress South F1 Carpenter', 'Gerudo Fortress South F2 Carpenter', 'Gerudo Fortress Carpenter Rescue', + 'Gerudo Fortress Membership Card', 'GS Gerudo Fortress Archery Range', 'GS Gerudo Fortress Top Floor'], + ['Haunted Wasteland Entrance', 'Gerudo Training Grounds Entrance']), + create_ow_region( + 'Haunted Wasteland', + ['Haunted Wasteland Structure Chest', 'GS Wasteland Ruins'], + ['Haunted Wasteland Crossing']), + create_ow_region( + 'Desert Colossus', + ['Colossus Freestanding PoH', 'Sheik at Colossus', 'GS Desert Colossus Bean Patch', 'GS Desert Colossus Tree', + 'GS Desert Colossus Hill'], + ['Colossus Fairy', 'Spirit Temple Entrance', 'Desert Colossus Grotto']), + create_interior_region( + 'Colossus Fairy', + ['Desert Colossus Fairy Reward']), + create_ow_region( + 'Castle Town', + None, + ['Castle Town Exit', 'Temple of Time', 'Hyrule Castle Grounds', 'Castle Town Rupee Room', 'Castle Town Bazaar', + 'Castle Town Mask Shop', 'Castle Town Shooting Gallery', 'Ganons Castle Grounds', + 'Castle Town Bombchu Bowling', 'Castle Town Potion Shop', 'Castle Town Treasure Chest Game', + 'Castle Town Bombchu Shop', 'Castle Town Dog Lady', 'Castle Town Man in Green House']), + create_interior_region( + 'Temple of Time', + ['Zelda'], + ['Temple of Time Exit', 'Door of Time']), + create_interior_region( + 'Beyond Door of Time', + ['Master Sword Pedestal', 'Sheik at Temple'], + ['Emerge as Adult']), + create_ow_region( + 'Hyrule Castle Grounds', + ['Malon Egg', 'GS Hyrule Castle Tree'], + ['Hyrule Castle Grounds Exit', 'Hyrule Castle Garden', 'Hyrule Castle Fairy', 'Castle Storms Grotto']), + create_ow_region( + 'Hyrule Castle Garden', + ['Zeldas Letter', 'Impa at Castle'], + ['Hyrule Castle Garden Exit']), + create_interior_region( + 'Hyrule Castle Fairy', + ['Hyrule Castle Fairy Reward']), + create_ow_region( + 'Ganons Castle Grounds', + ['GS Outside Ganon\'s Castle'], + ['Ganons Castle Grounds Exit', 'Ganons Castle Fairy', 'Rainbow Bridge']), create_interior_region('Ganons Castle Fairy', ['Ganons Castle Fairy Reward']), - create_interior_region('Castle Town Rupee Room', ['10 Big Poes', 'GS14']), - create_interior_region('Castle Town Bazaar'), + create_interior_region('Castle Town Rupee Room', ['10 Big Poes', 'GS Castle Market Guard House']), + create_interior_region( + 'Castle Town Bazaar', + ['Castle Town Bazaar Item 1', 'Castle Town Bazaar Item 2', 'Castle Town Bazaar Item 3', + 'Castle Town Bazaar Item 4', 'Castle Town Bazaar Item 5', 'Castle Town Bazaar Item 6', + 'Castle Town Bazaar Item 7', 'Castle Town Bazaar Item 8']), create_interior_region('Castle Town Mask Shop'), create_interior_region('Castle Town Shooting Gallery', ['Child Shooting Gallery']), - create_interior_region('Castle Town Bombchu Bowling', ['Bombchu Bowling Bomb Bag', 'Bombchu Bowling Piece of Heart']), - create_interior_region('Castle Town Potion Shop'), + create_interior_region( + 'Castle Town Bombchu Bowling', + ['Bombchu Bowling Bomb Bag', 'Bombchu Bowling Piece of Heart']), + create_interior_region( + 'Castle Town Potion Shop', + ['Castle Town Potion Shop Item 1', 'Castle Town Potion Shop Item 2', + 'Castle Town Potion Shop Item 3', 'Castle Town Potion Shop Item 4', + 'Castle Town Potion Shop Item 5', 'Castle Town Potion Shop Item 6', + 'Castle Town Potion Shop Item 7', 'Castle Town Potion Shop Item 8']), create_interior_region('Castle Town Treasure Chest Game', ['Treasure Chest Game']), - create_interior_region('Castle Town Bombchu Shop'), + create_interior_region( + 'Castle Town Bombchu Shop', + ['Bombchu Shop Item 1', 'Bombchu Shop Item 2', 'Bombchu Shop Item 3', 'Bombchu Shop Item 4', + 'Bombchu Shop Item 5', 'Bombchu Shop Item 6', 'Bombchu Shop Item 7', 'Bombchu Shop Item 8']), create_interior_region('Castle Town Dog Lady', ['Dog Lady']), create_interior_region('Castle Town Man in Green House'), - create_ow_region('Kakariko Village', ['Man on Roof', 'Anju as Adult', 'Anjus Chickens', 'Sheik in Kakariko', 'GS22', 'GS23', 'GS24', 'GS25', 'GS26', 'GS27'], ['Kakariko Exit', 'Carpenter Boss House', 'House of Skulltulla', 'Impas House', 'Impas House Back', 'Windmill', 'Kakariko Bazaar', 'Kakariko Shooting Gallery', 'Bottom of the Well', - 'Kakariko Potion Shop Front', 'Kakariko Potion Shop Back', 'Odd Medicine Building', 'Kakariko Bombable Grotto', 'Kakariko Back Grotto', 'Graveyard Entrance', 'Death Mountain Entrance']), + create_ow_region( + 'Kakariko Village', + ['Man on Roof', 'Anju as Adult', 'Anjus Chickens', 'Sheik in Kakariko', 'GS Kakariko House Under Construction', + 'GS Kakariko Skulltula House', 'GS Kakariko Guard\'s House', 'GS Kakariko Tree', 'GS Kakariko Watchtower', + 'GS Kakariko Above Impa\'s House'], + ['Kakariko Exit', 'Carpenter Boss House', 'House of Skulltula', 'Impas House', 'Impas House Back', 'Windmill', + 'Kakariko Bazaar', 'Kakariko Shooting Gallery', 'Bottom of the Well', 'Kakariko Potion Shop Front', + 'Kakariko Potion Shop Back', 'Odd Medicine Building', 'Kakariko Bombable Grotto', 'Kakariko Back Grotto', + 'Graveyard Entrance', 'Death Mountain Entrance']), create_interior_region('Carpenter Boss House'), - create_interior_region('House of Skulltulla', ['10 Gold Skulltulla Reward', '20 Gold Skulltulla Reward', '30 Gold Skulltulla Reward', '40 Gold Skulltulla Reward', '50 Gold Skulltulla Reward']), + create_interior_region( + 'House of Skulltula', + ['10 Gold Skulltula Reward', '20 Gold Skulltula Reward', '30 Gold Skulltula Reward', + '40 Gold Skulltula Reward', '50 Gold Skulltula Reward']), create_interior_region('Impas House'), create_interior_region('Impas House Back', ['Impa House Freestanding PoH']), create_interior_region('Windmill', ['Windmill Freestanding PoH', 'Song at Windmill']), - create_interior_region('Kakariko Bazaar'), + create_interior_region( + 'Kakariko Bazaar', + ['Kakariko Bazaar Item 1', 'Kakariko Bazaar Item 2', 'Kakariko Bazaar Item 3', + 'Kakariko Bazaar Item 4', 'Kakariko Bazaar Item 5', 'Kakariko Bazaar Item 6', + 'Kakariko Bazaar Item 7', 'Kakariko Bazaar Item 8']), create_interior_region('Kakariko Shooting Gallery', ['Adult Shooting Gallery']), - create_interior_region('Kakariko Potion Shop Front'), + create_interior_region( + 'Kakariko Potion Shop Front', + ['Kakariko Potion Shop Item 1', 'Kakariko Potion Shop Item 2', + 'Kakariko Potion Shop Item 3', 'Kakariko Potion Shop Item 4', + 'Kakariko Potion Shop Item 5', 'Kakariko Potion Shop Item 6', + 'Kakariko Potion Shop Item 7', 'Kakariko Potion Shop Item 8']), create_interior_region('Kakariko Potion Shop Back'), create_interior_region('Odd Medicine Building'), - create_dungeon_region('Bottom of the Well', ['Bottom of the Well Front Left Hidden Wall', 'Bottom of the Well Front Center Bombable', 'Bottom of the Well Right Bottom Hidden Wall', 'Bottom of the Well Center Large Chest', 'Bottom of the Well Center Small Chest', 'Bottom of the Well Back Left Bombable', 'Bottom of the Well Freestanding Key', - 'Bottom of the Well Defeat Boss', 'Bottom of the Well Invisible Chest', 'Bottom of the Well Underwater Front Chest', 'Bottom of the Well Underwater Left Chest', 'Bottom of the Well Basement Chest', 'Bottom of the Well Locked Pits', 'Bottom of the Well Behind Right Grate', 'GS78', 'GS79', 'GS80'], ['Bottom of the Well Exit']), - create_ow_region('Graveyard', ['Graveyard Freestanding PoH', 'Gravedigging Tour', 'GS28', 'GS29'], ['Shield Grave', 'Composer Grave', 'Heart Piece Grave', 'Dampes Grave', 'Dampes House', 'Graveyard Exit']), + create_ow_region( + 'Graveyard', + ['Graveyard Freestanding PoH', 'Gravedigging Tour', 'GS Graveyard Wall', 'GS Graveyard Bean Patch'], + ['Shield Grave', 'Composer Grave', 'Heart Piece Grave', 'Dampes Grave', 'Dampes House', 'Graveyard Exit']), create_interior_region('Shield Grave', ['Shield Grave Chest']), create_interior_region('Heart Piece Grave', ['Heart Piece Grave Chest']), create_interior_region('Composer Grave', ['Composer Grave Chest', 'Song from Composer Grave']), create_interior_region('Dampes Grave', ['Hookshot Chest', 'Dampe Race Freestanding PoH']), create_interior_region('Dampes House'), create_ow_region('Shadow Temple Warp Region', None, ['Drop to Graveyard', 'Shadow Temple Entrance']), - create_dungeon_region('Shadow Temple Beginning', ['Shadow Temple Map Chest', 'Shadow Temple Hover Boots Chest'], ['Shadow Temple Exit', 'Shadow Temple First Pit']), - create_dungeon_region('Shadow Temple First Beamos', ['Shadow Temple Compass Chest', 'Shadow Temple Early Silver Rupee Chest'], ['Shadow Temple Bomb Wall']), - create_dungeon_region('Shadow Temple Huge Pit', ['Shadow Temple Invisible Blades Visible Chest', 'Shadow Temple Invisible Blades Invisible Chest', 'Shadow Temple Falling Spikes Lower Chest', 'Shadow Temple Falling Spikes Upper Chest', 'Shadow Temple Falling Spikes Switch Chest', 'Shadow Temple Invisible Spikes Chest', 'Shadow Temple Freestanding Key', 'GS81', 'GS82'], ['Shadow Temple Hookshot Target']), - create_dungeon_region('Shadow Temple Wind Tunnel', ['Shadow Temple Wind Hint Chest', 'Shadow Temple After Wind Enemy Chest', 'Shadow Temple After Wind Hidden Chest', 'GS83', 'GS84'], ['Shadow Temple Boat']), - create_dungeon_region('Shadow Temple Beyond Boat', ['Shadow Temple Spike Walls Left Chest', 'Shadow Temple Boss Key Chest', 'Shadow Temple Hidden Floormaster Chest', 'Bongo Bongo Heart', 'Bongo Bongo', 'GS85']), - create_ow_region('Death Mountain', ['Death Mountain Bombable Chest', 'Biggoron', 'DM Trail Freestanding PoH', 'GS30', 'GS31', 'GS32', 'GS33'], ['Death Mountain Exit', 'Goron City Entrance', 'Mountain Crater Entrance', 'Mountain Summit Fairy', 'Dodongos Cavern Rocks', 'Mountain Bombable Grotto', 'Mountain Storms Grotto']), - create_ow_region('Dodongos Cavern Entryway', None, ['Dodongos Cavern', 'Mountain Access from Behind Rock']), - create_ow_region('Goron City', ['Goron City Leftmost Maze Chest', 'Goron City Left Maze Chest', 'Goron City Right Maze Chest', 'Goron City Pot Freestanding PoH', 'Rolling Goron as Child', 'Link the Goron', 'GS34', 'GS35'], ['Goron City Exit', 'Goron City Bomb Wall', 'Darunias Chamber', 'Crater Access']), - create_ow_region('Goron City Woods Warp', None, ['Goron City from Woods', 'Goron City to Woods']), + create_ow_region( + 'Death Mountain', + ['Death Mountain Bombable Chest', 'DM Trail Freestanding PoH', 'GS Mountain Trail Bean Patch', + 'GS Mountain Trail Bomb Alcove', 'GS Mountain Trail Path to Crater', + 'GS Mountain Trail Above Dodongo\'s Cavern'], + ['Death Mountain Exit', 'Goron City Entrance', 'Mountain Crater Entrance', 'Mountain Summit Fairy', + 'Dodongos Cavern Rocks', 'Mountain Bombable Grotto', 'Mountain Storms Grotto']), + create_ow_region( + 'Dodongos Cavern Entryway', + None, + ['Dodongos Cavern', 'Mountain Access from Behind Rock']), + create_ow_region( + 'Goron City', + ['Goron City Leftmost Maze Chest', 'Goron City Left Maze Chest', 'Goron City Right Maze Chest', + 'Goron City Pot Freestanding PoH', 'Rolling Goron as Child', 'Link the Goron', 'GS Goron City Boulder Maze', + 'GS Goron City Center Platform', 'Goron City Stick Pot'], + ['Goron City Exit', 'Goron City Bomb Wall', 'Darunias Chamber', + 'Crater Access', 'Goron Shop', 'Goron City Grotto']), + create_ow_region( + 'Goron City Woods Warp', + None, + ['Goron City from Woods', 'Goron City to Woods']), + create_interior_region( + 'Goron Shop', + ['Goron Shop Item 1', 'Goron Shop Item 2', 'Goron Shop Item 3', 'Goron Shop Item 4', + 'Goron Shop Item 5', 'Goron Shop Item 6', 'Goron Shop Item 7', 'Goron Shop Item 8']), create_ow_region('Darunias Chamber', ['Darunias Joy'], ['Darunias Chamber Exit']), - create_ow_region('Death Mountain Crater Upper', ['DM Crater Wall Freestanding PoH', 'GS36'], ['Crater Exit', 'Crater Hover Boots', 'Crater Scarecrow', 'Top of Crater Grotto']), - create_ow_region('Death Mountain Crater Lower', None, ['Crater to City', 'Crater Fairy', 'Crater Bridge', 'Crater Ascent']), - create_ow_region('Death Mountain Crater Central', ['DM Crater Volcano Freestanding PoH', 'Sheik in Crater', 'GS37'], ['Crater Bridge Reverse', 'Fire Temple Entrance']), - create_interior_region('Crater Fairy', ['Crater Fairy Reward']), + create_ow_region( + 'Death Mountain Crater Upper', + ['DM Crater Wall Freestanding PoH', 'Biggoron', 'GS Death Mountain Crater Crate', 'DMC Deku Scrub Bombs'], + ['Crater Exit', 'Crater Hover Boots', 'Crater Scarecrow', 'Top of Crater Grotto']), + create_ow_region( + 'Death Mountain Crater Lower', + None, + ['Crater to City', 'Crater Fairy', 'Crater Bridge', 'Crater Ascent', 'DMC Hammer Grotto']), + create_ow_region( + 'Death Mountain Crater Central', + ['DM Crater Volcano Freestanding PoH', 'Sheik in Crater', 'GS Mountain Crater Bean Patch'], + ['Crater Bridge Reverse', 'Fire Temple Entrance']), + create_interior_region( + 'Crater Fairy', + ['Crater Fairy Reward']), create_interior_region('Mountain Summit Fairy', ['Mountain Summit Fairy Reward']), - create_dungeon_region('Dodongos Cavern Beginning', None, ['Dodongos Cavern Exit', 'Dodongos Cavern Lobby']), - create_dungeon_region('Dodongos Cavern Lobby', ['Dodongos Cavern Map Chest', 'Dodongos Cavern Compass Chest', 'GS38', 'GS42'], ['Dodongos Cavern Retreat', 'Dodongos Cavern Left Door']), - create_dungeon_region('Dodongos Cavern Climb', ['Dodongos Cavern Bomb Flower Platform', 'GS39'], ['Dodongos Cavern Bridge Fall', 'Dodongos Cavern Slingshot Target']), - create_dungeon_region('Dodongos Cavern Far Bridge', ['Dodongos Cavern Bomb Bag Chest', 'Dodongos Cavern End of Bridge Chest', 'GS41'], ['Dodongos Cavern Bomb Drop', 'Dodongos Cavern Bridge Fall 2']), - create_dungeon_region('Dodongos Cavern Boss Area', ['Chest Above King Dodongo', 'King Dodongo Heart', 'King Dodongo', 'GS40'], ['Dodongos Cavern Exit Skull']), - create_ow_region('Zora River Bottom', ['Zora River Lower Freestanding PoH', 'Zora River Upper Freestanding PoH', 'GS43'], ['Zora River Exit', 'Zora River Rocks', 'Zora River Adult', 'Zora River Plateau Open Grotto', 'Zora River Plateau Bombable Grotto']), - create_ow_region('Zora River Top', ['Magic Bean Salesman', 'Frog Ocarina Game', 'Frogs in the Rain', 'GS44'], ['Zora River Downstream', 'Zora River Dive Warp', 'Zora River Waterfall']), - create_ow_region('Zora River Adult', ['GS45', 'GS46'], ['Zoras Domain Adult Access']), - create_ow_region('Zoras Domain', ['Diving Minigame', 'Zoras Domain Torch Run', 'King Zora Moves'], ['Zoras Domain Exit', 'Zoras Domain Dive Warp', 'Behind King Zora', 'Zora Shop']), - create_ow_region('Zoras Fountain', ['GS48', 'GS49'], ['Zoras Fountain Exit', 'Jabu Jabus Belly', 'Zoras Fountain Fairy']), - create_ow_region('Zoras Domain Frozen', ['King Zora Thawed', 'GS47'], ['Zoras Fountain Adult Access']), - create_ow_region('Outside Ice Cavern', ['Zoras Fountain Iceberg Freestanding PoH', 'Zoras Fountain Bottom Freestanding PoH', 'GS50'], ['Ice Cavern Entrance']), - create_dungeon_region('Ice Cavern', ['Ice Cavern Map Chest', 'Ice Cavern Compass Chest', 'Ice Cavern Iron Boots Chest', 'Ice Cavern Freestanding PoH', 'Sheik in Ice Cavern', 'GS70', 'GS71', 'GS72'], ['Ice Cavern Exit']), - create_interior_region('Zora Shop'), + create_ow_region( + 'Zora River Front', + ['GS Zora River Tree'], + ['Zora River Rocks', 'Zora River Adult', 'Zora River Exit']), + create_ow_region( + 'Zora River Child', + ['Magic Bean Salesman', 'Frog Ocarina Game', 'Frogs in the Rain', 'GS Zora River Ladder'], + ['Zora River Child to Shared', 'Zora River Waterfall']), + create_ow_region( + 'Zora River Adult', + ['GS Zora River Near Raised Grottos', 'GS Zora River Above Bridge'], + ['Zoras Domain Adult Access', 'Zora River Adult to Shared']), + create_ow_region( + 'Zora River Shared', + ['Zora River Lower Freestanding PoH', 'Zora River Upper Freestanding PoH'], + ['Zora River Downstream', 'Zora River Plateau Open Grotto', 'Zora River Plateau Bombable Grotto', + 'Zora River Dive Warp', 'Zora River Storms Grotto']), + create_ow_region( + 'Zoras Domain', + ['Diving Minigame', 'Zoras Domain Torch Run', 'King Zora Moves', 'Zoras Domain Stick Pot', + 'Zoras Domain Nut Pot'], + ['Zoras Domain Exit', 'Zoras Domain Dive Warp', 'Behind King Zora', 'Zora Shop Child Access']), + create_ow_region( + 'Zoras Fountain', + ['GS Zora\'s Fountain Tree', 'GS Zora\'s Fountain Above the Log'], + ['Zoras Fountain Exit', 'Jabu Jabus Belly', 'Zoras Fountain Fairy']), + create_ow_region( + 'Zoras Domain Frozen', + ['King Zora Thawed', 'GS Zora\'s Domain Frozen Waterfall'], + ['Zoras Fountain Adult Access', 'Zora Shop Adult Access']), + create_ow_region( + 'Outside Ice Cavern', + ['Zoras Fountain Iceberg Freestanding PoH', 'Zoras Fountain Bottom Freestanding PoH', + 'GS Zora\'s Fountain Hidden Cave'], + ['Ice Cavern Entrance']), + create_interior_region( + 'Zora Shop', + ['Zora Shop Item 1', 'Zora Shop Item 2', 'Zora Shop Item 3', 'Zora Shop Item 4', + 'Zora Shop Item 5', 'Zora Shop Item 6', 'Zora Shop Item 7', 'Zora Shop Item 8']), create_interior_region('Zoras Fountain Fairy', ['Zoras Fountain Fairy Reward']), - create_dungeon_region('Jabu Jabus Belly Beginning', None, ['Jabu Jabus Belly Exit', 'Jabu Jabus Belly Ceiling Switch']), - create_dungeon_region('Jabu Jabus Belly Main', ['Boomerang Chest', 'GS51'], ['Jabu Jabus Belly Retreat', 'Jabu Jabus Belly Tentacles']), - create_dungeon_region('Jabu Jabus Belly Depths', ['Jabu Jabus Belly Map Chest', 'Jabu Jabus Belly Compass Chest', 'GS52', 'GS53'], ['Jabu Jabus Belly Elevator', 'Jabu Jabus Belly Octopus']), - create_dungeon_region('Jabu Jabus Belly Boss Area', ['Barinade Heart', 'Barinade', 'GS54'], ['Jabu Jabus Belly Final Backtrack']), - create_ow_region('Lon Lon Ranch', ['Epona', 'Song from Malon', 'GS18', 'GS19', 'GS20', 'GS21'], ['Lon Lon Exit', 'Talon House', 'Ingo Barn', 'Lon Lon Corner Tower', 'Lon Lon Grotto']), + create_ow_region( + 'Lon Lon Ranch', + ['Epona', 'Song from Malon', 'GS Lon Lon Ranch Tree', 'GS Lon Lon Ranch Rain Shed', + 'GS Lon Lon Ranch House Window', 'GS Lon Lon Ranch Back Wall'], + ['Lon Lon Exit', 'Talon House', 'Ingo Barn', 'Lon Lon Corner Tower', 'Lon Lon Grotto']), create_interior_region('Talon House', ['Talons Chickens']), create_interior_region('Ingo Barn'), create_interior_region('Lon Lon Corner Tower', ['Lon Lon Tower Freestanding PoH']), - create_interior_region('Forest Temple Entry Area', ['Sheik Forest Song', 'GS6', 'GS7'], ['Adult Meadow Exit', 'Forest Temple Entrance']), - create_dungeon_region('Forest Temple Lobby', ['Forest Temple First Chest', 'Forest Temple Chest Behind Lobby', 'GS60', 'GS61'], ['Forest Temple Exit', 'Forest Temple Song of Time Block', 'Forest Temple Lobby Eyeball Switch', 'Forest Temple Lobby Locked Door']), - create_dungeon_region('Forest Temple NW Outdoors', ['Forest Temple Well Chest', 'Forest Temple Map Chest', 'GS63'], ['Forest Temple Through Map Room']), - create_dungeon_region('Forest Temple NE Outdoors', ['Forest Temple Outside Hookshot Chest', 'GS62'], ['Forest Temple Well Connection', 'Forest Temple Outside to Lobby', 'Forest Temple Scarecrows Song']), - create_dungeon_region('Forest Temple Falling Room', ['Forest Temple Falling Room Chest'], ['Forest Temple Falling Room Exit', 'Forest Temple Elevator']), - create_dungeon_region('Forest Temple Block Push Room', ['Forest Temple Block Push Chest'], ['Forest Temple Outside Backdoor', 'Forest Temple Twisted Hall', 'Forest Temple Straightened Hall']), - create_dungeon_region('Forest Temple Straightened Hall', ['Forest Temple Boss Key Chest'], ['Forest Temple Boss Key Chest Drop']), - create_dungeon_region('Forest Temple Outside Upper Ledge', ['Forest Temple Floormaster Chest'], ['Forest Temple Outside Ledge Drop']), - create_dungeon_region('Forest Temple Bow Region', ['Forest Temple Bow Chest', 'Forest Temple Red Poe Chest', 'Forest Temple Blue Poe Chest'], ['Forest Temple Drop to Falling Room']), - create_dungeon_region('Forest Temple Boss Region', ['Forest Temple Near Boss Chest', 'Phantom Ganon Heart', 'Phantom Ganon', 'GS64']), - create_dungeon_region('Fire Temple Lower', ['Fire Temple Chest Near Boss', 'Fire Temple Fire Dancer Chest', 'Fire Temple Boss Key Chest', 'Fire Temple Big Lava Room Bombable Chest', 'Fire Temple Big Lava Room Open Chest', 'Volvagia Heart', 'Volvagia', 'GS65', 'GS69'], ['Fire Temple Exit', 'Fire Temple Early Climb']), - create_dungeon_region('Fire Temple Middle', ['Fire Temple Boulder Maze Lower Chest', 'Fire Temple Boulder Maze Upper Chest', 'Fire Temple Boulder Maze Side Room', 'Fire Temple Boulder Maze Bombable Pit', 'Fire Temple Scarecrow Chest', 'Fire Temple Map Chest', 'Fire Temple Compass Chest', 'GS66', 'GS67', 'GS68'], ['Fire Temple Fire Maze Escape']), - create_dungeon_region('Fire Temple Upper', ['Fire Temple Highest Goron Chest', 'Fire Temple Megaton Hammer Chest']), - create_dungeon_region('Ganons Castle Lobby', None, ['Ganons Castle Exit', 'Ganons Castle Forest Trial', 'Ganons Castle Fire Trial', 'Ganons Castle Water Trial', 'Ganons Castle Shadow Trial', 'Ganons Castle Spirit Trial', 'Ganons Castle Light Trial', 'Ganons Castle Tower']), - create_dungeon_region('Ganons Castle Forest Trial', ['Ganons Castle Forest Trial Chest', 'Ganons Castle Forest Trial Clear']), - create_dungeon_region('Ganons Castle Fire Trial', ['Ganons Castle Fire Trial Clear']), - create_dungeon_region('Ganons Castle Water Trial', ['Ganons Castle Water Trial Left Chest', 'Ganons Castle Water Trial Right Chest', 'Ganons Castle Water Trial Clear']), - create_dungeon_region('Ganons Castle Shadow Trial', ['Ganons Castle Shadow Trial First Chest', 'Ganons Castle Shadow Trial Second Chest', 'Ganons Castle Shadow Trial Clear']), - create_dungeon_region('Ganons Castle Spirit Trial', ['Ganons Castle Spirit Trial First Chest', 'Ganons Castle Spirit Trial Second Chest', 'Ganons Castle Spirit Trial Clear']), - create_dungeon_region('Ganons Castle Light Trial', ['Ganons Castle Light Trial First Left Chest', 'Ganons Castle Light Trial Second Left Chest', 'Ganons Castle Light Trial Third Left Chest', 'Ganons Castle Light Trial First Right Chest', 'Ganons Castle Light Trial Second Right Chest', 'Ganons Castle Light Trial Third Right Chest', 'Ganons Castle Light Trail Invisible Enemies Chest', 'Ganons Castle Light Trial Lullaby Chest', 'Ganons Castle Light Trial Clear']), - create_dungeon_region('Ganons Castle Tower', ['Ganons Tower Boss Key Chest', 'Ganon']), - create_grotto_region('Kokiri Forest Storms Grotto', ['Kokiri Forest Storms Grotto Chest']), - create_grotto_region('Lost Woods Generic Grotto', ['Lost Woods Generic Grotto Chest']), + create_interior_region( + 'Forest Temple Entry Area', + ['Sheik Forest Song', 'GS Lost Woods Above Stage', 'GS Sacred Forest Meadow'], + ['Adult Meadow Exit', 'Forest Temple Entrance', 'Meadow Storms Grotto Adult Access']), + create_dungeon_region( + 'Ganons Castle Tower', + ['Ganons Tower Boss Key Chest', 'Ganon']), + create_grotto_region( + 'Kokiri Forest Storms Grotto', + ['Kokiri Forest Storms Grotto Chest']), + create_grotto_region( + 'Lost Woods Generic Grotto', + ['Lost Woods Generic Grotto Chest']), create_grotto_region('Deku Theater', ['Deku Theater Skull Mask', 'Deku Theater Mask of Truth']), - create_grotto_region('Lost Woods Sales Grotto', ['Deku Salesman Lost Woods Grotto']), + create_grotto_region('Lost Woods Sales Grotto', + ['LW Grotto Deku Scrub Arrows', 'LW Grotto Deku Scrub Deku Nut Upgrade']), create_grotto_region('Meadow Fairy Grotto'), + create_grotto_region('Meadow Storms Grotto', + ['SFM Grotto Deku Scrub Red Potion', 'SFM Grotto Deku Scrub Green Potion']), create_grotto_region('Front of Meadow Grotto', ['Wolfos Grotto Chest']), - create_grotto_region('Lon Lon Grotto'), + create_grotto_region('Lon Lon Grotto', + ['LLR Grotto Deku Scrub Deku Nuts', 'LLR Grotto Deku Scrub Bombs', 'LLR Grotto Deku Scrub Arrows']), create_grotto_region('Remote Southern Grotto', ['Remote Southern Grotto Chest']), create_grotto_region('Field Near Lake Outside Fence Grotto', ['Field Near Lake Outside Fence Grotto Chest']), - create_grotto_region('Field Near Lake Inside Fence Grotto', ['Deku Salesman Hyrule Field Grotto']), - create_grotto_region('Field Valley Grotto', ['GS13']), + create_grotto_region('Field Near Lake Inside Fence Grotto', ['HF Grotto Deku Scrub Piece of Heart']), + create_grotto_region('Field Valley Grotto', ['GS Hyrule Field Near Gerudo Valley']), create_grotto_region('Field West Castle Town Grotto', ['Field West Castle Town Grotto Chest']), create_grotto_region('Field Far West Castle Town Grotto'), - create_grotto_region('Field Kakariko Grotto', ['GS12']), + create_grotto_region('Field Kakariko Grotto', ['GS Hyrule Field near Kakariko']), create_grotto_region('Field North Lon Lon Grotto', ['Tektite Grotto Freestanding PoH']), - create_grotto_region('Castle Storms Grotto', ['GS16']), + create_grotto_region('Castle Storms Grotto', ['GS Hyrule Castle Grotto']), create_grotto_region('Kakariko Bombable Grotto', ['Redead Grotto Chest']), create_grotto_region('Kakariko Back Grotto', ['Kakariko Back Grotto Chest']), create_grotto_region('Mountain Bombable Grotto'), create_grotto_region('Mountain Storms Grotto', ['Mountain Storms Grotto Chest']), + create_grotto_region('Goron City Grotto', + ['Goron Grotto Deku Scrub Deku Nuts', 'Goron Grotto Deku Scrub Bombs', 'Goron Grotto Deku Scrub Arrows']), create_grotto_region('Top of Crater Grotto', ['Top of Crater Grotto Chest']), + create_grotto_region('DMC Hammer Grotto', + ['DMC Grotto Deku Scrub Deku Nuts', 'DMC Grotto Deku Scrub Bombs', 'DMC Grotto Deku Scrub Arrows']), create_grotto_region('Zora River Plateau Open Grotto', ['Zora River Plateau Open Grotto Chest']), create_grotto_region('Zora River Plateau Bombable Grotto'), - create_grotto_region('Lake Hylia Grotto') + create_grotto_region('Zora River Storms Grotto', + ['ZR Grotto Deku Scrub Red Potion', 'ZR Grotto Deku Scrub Green Potion']), + create_grotto_region('Lake Hylia Grotto', + ['LH Grotto Deku Scrub Deku Nuts', 'LH Grotto Deku Scrub Bombs', 'LH Grotto Deku Scrub Arrows']), + create_grotto_region('Desert Colossus Grotto', + ['Desert Grotto Deku Scrub Red Potion', 'Desert Grotto Deku Scrub Green Potion']), + create_grotto_region('Gerudo Valley Storms Grotto', + ['Valley Grotto Deku Scrub Red Potion', 'Valley Grotto Deku Scrub Green Potion']), ] - world.intialize_regions() + if world.dungeon_mq['DT']: + world.regions.extend([ + create_dungeon_region( + 'Deku Tree Lobby', + ['Deku Tree MQ Lobby Chest', 'Deku Tree MQ Slingshot Chest', 'Deku Tree MQ Slingshot Room Back Chest', + 'Deku Tree MQ Basement Chest', 'GS Deku Tree MQ Lobby'], + ['Deku Tree Exit', 'Deku Tree Compass Passage', 'Deku Tree Basement Path']), + create_dungeon_region( + 'Deku Tree Compass Room', + ['Deku Tree MQ Compass Chest', 'GS Deku Tree MQ Compass Room'], + ['Deku Tree Compass Exit']), + create_dungeon_region( + 'Deku Tree Boss Room', + ['Deku Tree MQ Before Spinning Log Chest', 'Deku Tree MQ After Spinning Log Chest', + 'GS Deku Tree MQ Basement Ceiling', 'GS Deku Tree MQ Basement Back Room', + 'DT MQ Deku Scrub Deku Shield', 'Queen Gohma Heart', 'Queen Gohma'], + ['Deku Tree Basement Vines']) + ]) + else: + world.regions.extend([ + create_dungeon_region( + 'Deku Tree Lobby', + ['Deku Tree Lobby Chest', 'Deku Tree Compass Chest', 'Deku Tree Compass Room Side Chest', + 'Deku Tree Basement Chest', 'GS Deku Tree Compass Room', 'GS Deku Tree Basement Vines', + 'GS Deku Tree Basement Gate'], + ['Deku Tree Exit', 'Deku Tree Slingshot Passage', 'Deku Tree Basement Path']), + create_dungeon_region( + 'Deku Tree Slingshot Room', + ['Deku Tree Slingshot Chest', 'Deku Tree Slingshot Room Side Chest'], + ['Deku Tree Slingshot Exit']), + create_dungeon_region( + 'Deku Tree Boss Room', + ['GS Deku Tree Basement Back Room', 'Queen Gohma Heart', 'Queen Gohma'], + ['Deku Tree Basement Vines']) + ]) + + if world.dungeon_mq['DC']: + world.regions.extend([ + create_dungeon_region( + 'Dodongos Cavern Beginning', + None, + ['Dodongos Cavern Exit', 'Dodongos Cavern Lobby']), + create_dungeon_region( + 'Dodongos Cavern Lobby', + ['Dodongos Cavern MQ Map Chest', 'Dodongos Cavern MQ Compass Chest', 'Dodongos Cavern MQ Larva Room Chest', + 'Dodongos Cavern MQ Torch Puzzle Room Chest', 'Dodongos Cavern MQ Bomb Bag Chest', + 'GS Dodongo\'s Cavern MQ Song of Time Block Room', 'GS Dodongo\'s Cavern MQ Larva Room', + 'GS Dodongo\'s Cavern MQ Lizalfos Room', 'GS Dodongo\'s Cavern MQ Scrub Room', + 'DC MQ Deku Scrub Deku Sticks', 'DC MQ Deku Scrub Deku Seeds', + 'DC MQ Deku Scrub Deku Shield', 'DC MQ Deku Scrub Red Potion'], + ['Dodongos Cavern Bomb Drop']), + create_dungeon_region( + 'Dodongos Cavern Boss Area', + ['Dodongos Cavern MQ Under Grave Chest', 'Chest Above King Dodongo', 'King Dodongo Heart', + 'King Dodongo', 'GS Dodongo\'s Cavern MQ Back Area']), + ]) + else: + world.regions.extend([ + create_dungeon_region( + 'Dodongos Cavern Beginning', + None, + ['Dodongos Cavern Exit', 'Dodongos Cavern Lobby']), + create_dungeon_region( + 'Dodongos Cavern Lobby', + ['Dodongos Cavern Map Chest', 'Dodongos Cavern Compass Chest', 'GS Dodongo\'s Cavern East Side Room', + 'GS Dodongo\'s Cavern Scarecrow', 'DC Deku Scrub Deku Sticks', 'DC Deku Scrub Deku Shield'], + ['Dodongos Cavern Retreat', 'Dodongos Cavern Left Door']), + create_dungeon_region( + 'Dodongos Cavern Climb', + ['Dodongos Cavern Bomb Flower Platform', 'GS Dodongo\'s Cavern Vines Above Stairs', + 'DC Deku Scrub Deku Seeds', 'DC Deku Scrub Deku Nuts'], + ['Dodongos Cavern Bridge Fall', 'Dodongos Cavern Slingshot Target']), + create_dungeon_region( + 'Dodongos Cavern Far Bridge', + ['Dodongos Cavern Bomb Bag Chest', 'Dodongos Cavern End of Bridge Chest', + 'GS Dodongo\'s Cavern Alcove Above Stairs'], + ['Dodongos Cavern Bomb Drop', 'Dodongos Cavern Bridge Fall 2']), + create_dungeon_region( + 'Dodongos Cavern Boss Area', + ['Chest Above King Dodongo', 'King Dodongo Heart', 'King Dodongo', 'GS Dodongo\'s Cavern Back Room'], + ['Dodongos Cavern Exit Skull']) + ]) + + if world.dungeon_mq['JB']: + world.regions.extend([ + create_dungeon_region( + 'Jabu Jabus Belly Beginning', + ['Jabu Jabus Belly MQ Map Chest', 'Jabu Jabus Belly MQ Entry Side Chest'], + ['Jabu Jabus Belly Exit', 'Jabu Jabus Belly Cow Switch']), + create_dungeon_region( + 'Jabu Jabus Belly Main', + ['Jabu Jabus Belly MQ Second Room Lower Chest', 'Jabu Jabus Belly MQ Compass Chest', + 'Jabu Jabus Belly MQ Basement South Chest', 'Jabu Jabus Belly MQ Basement North Chest', + 'Jabu Jabus Belly MQ Boomerang Room Small Chest', 'MQ Boomerang Chest', 'GS Jabu Jabu MQ Boomerang Room'], + ['Jabu Jabus Belly Retreat', 'Jabu Jabus Belly Tentacle Access']), + create_dungeon_region( + 'Jabu Jabus Belly Depths', + ['Jabu Jabus Belly MQ Falling Like Like Room Chest', 'GS Jabu Jabu MQ Tailpasaran Room', + 'GS Jabu Jabu MQ Invisible Enemies Room'], + ['Jabu Jabus Belly Elevator', 'Jabu Jabus Belly Octopus']), + create_dungeon_region( + 'Jabu Jabus Belly Boss Area', + ['Jabu Jabus Belly MQ Second Room Upper Chest', 'Jabu Jabus Belly MQ Near Boss Chest', + 'Barinade Heart', 'Barinade', 'GS Jabu Jabu MQ Near Boss'], + ['Jabu Jabus Belly Final Backtrack']) + ]) + else: + world.regions.extend([ + create_dungeon_region( + 'Jabu Jabus Belly Beginning', + None, + ['Jabu Jabus Belly Exit', 'Jabu Jabus Belly Ceiling Switch']), + create_dungeon_region( + 'Jabu Jabus Belly Main', + ['Boomerang Chest', 'GS Jabu Jabu Water Switch Room', 'Jabu Deku Scrub Deku Nuts'], + ['Jabu Jabus Belly Retreat', 'Jabu Jabus Belly Tentacles']), + create_dungeon_region( + 'Jabu Jabus Belly Depths', + ['Jabu Jabus Belly Map Chest', 'Jabu Jabus Belly Compass Chest', 'GS Jabu Jabu Lobby Basement Lower', + 'GS Jabu Jabu Lobby Basement Upper'], + ['Jabu Jabus Belly Elevator', 'Jabu Jabus Belly Octopus']), + create_dungeon_region( + 'Jabu Jabus Belly Boss Area', + ['Barinade Heart', 'Barinade', 'GS Jabu Jabu Near Boss'], + ['Jabu Jabus Belly Final Backtrack']) + ]) + + if world.dungeon_mq['FoT']: + world.regions.extend([ + create_dungeon_region( + 'Forest Temple Lobby', + ['Forest Temple MQ First Chest', 'GS Forest Temple MQ First Hallway'], + ['Forest Temple Exit', 'Forest Temple Lobby Locked Door']), + create_dungeon_region( + 'Forest Temple Central Area', + ['Forest Temple MQ Chest Behind Lobby', 'GS Forest Temple MQ Block Push Room'], + ['Forest Temple West Eye Switch', 'Forest Temple East Eye Switch', + 'Forest Temple Block Puzzle Solve', 'Forest Temple Crystal Switch Jump']), + create_dungeon_region( + 'Forest Temple After Block Puzzle', + ['Forest Temple MQ Boss Key Chest'], + ['Forest Temple Twisted Hall']), + create_dungeon_region( + 'Forest Temple Outdoor Ledge', + ['Forest Temple MQ Redead Chest'], + ['Forest Temple Drop to NW Outdoors']), + create_dungeon_region( + 'Forest Temple NW Outdoors', + ['GS Forest Temple MQ Outdoor West'], + ['Forest Temple Well Connection', 'Forest Temple Webs']), + create_dungeon_region( + 'Forest Temple NE Outdoors', + ['Forest Temple MQ Well Chest', 'GS Forest Temple MQ Outdoor East', 'GS Forest Temple MQ Well'], + ['Forest Temple Climb to Top Ledges', 'Forest Temple Longshot to NE Outdoors Ledge']), + create_dungeon_region( + 'Forest Temple Outdoors Top Ledges', + ['Forest Temple MQ NE Outdoors Upper Chest'], + ['Forest Temple Top Drop to NE Outdoors']), + create_dungeon_region( + 'Forest Temple NE Outdoors Ledge', + ['Forest Temple MQ NE Outdoors Lower Chest'], + ['Forest Temple Drop to NE Outdoors', 'Forest Temple Song of Time Block Climb']), + create_dungeon_region( + 'Forest Temple Bow Region', + ['Forest Temple MQ Bow Chest', 'Forest Temple MQ Map Chest', 'Forest Temple MQ Compass Chest'], + ['Forest Temple Drop to Falling Room']), + create_dungeon_region( + 'Forest Temple Falling Room', + ['Forest Temple MQ Falling Room Chest'], + ['Forest Temple Falling Room Exit', 'Forest Temple Elevator']), + create_dungeon_region( + 'Forest Temple Boss Region', + ['Forest Temple MQ Near Boss Chest', 'Phantom Ganon Heart', 'Phantom Ganon']) + ]) + else: + world.regions.extend([ + create_dungeon_region( + 'Forest Temple Lobby', + ['Forest Temple First Chest', 'Forest Temple Chest Behind Lobby', 'GS Forest Temple First Room', + 'GS Forest Temple Lobby'], + ['Forest Temple Exit', 'Forest Temple Song of Time Block', 'Forest Temple Lobby Eyeball Switch', + 'Forest Temple Lobby Locked Door']), + create_dungeon_region( + 'Forest Temple NW Outdoors', + ['Forest Temple Well Chest', 'Forest Temple Map Chest', 'GS Forest Temple Outdoor West'], + ['Forest Temple Through Map Room']), + create_dungeon_region( + 'Forest Temple NE Outdoors', + ['Forest Temple Outside Hookshot Chest', 'GS Forest Temple Outdoor East'], + ['Forest Temple Well Connection', 'Forest Temple Outside to Lobby', 'Forest Temple Scarecrows Song']), + create_dungeon_region( + 'Forest Temple Falling Room', + ['Forest Temple Falling Room Chest'], + ['Forest Temple Falling Room Exit', 'Forest Temple Elevator']), + create_dungeon_region( + 'Forest Temple Block Push Room', + ['Forest Temple Block Push Chest'], + ['Forest Temple Outside Backdoor', 'Forest Temple Twisted Hall', 'Forest Temple Straightened Hall']), + create_dungeon_region( + 'Forest Temple Straightened Hall', + ['Forest Temple Boss Key Chest'], + ['Forest Temple Boss Key Chest Drop']), + create_dungeon_region( + 'Forest Temple Outside Upper Ledge', + ['Forest Temple Floormaster Chest'], + ['Forest Temple Outside Ledge Drop']), + create_dungeon_region( + 'Forest Temple Bow Region', + ['Forest Temple Bow Chest', 'Forest Temple Red Poe Chest', 'Forest Temple Blue Poe Chest'], + ['Forest Temple Drop to Falling Room']), + create_dungeon_region( + 'Forest Temple Boss Region', + ['Forest Temple Near Boss Chest', 'Phantom Ganon Heart', 'Phantom Ganon', 'GS Forest Temple Basement']) + ]) + + if world.dungeon_mq['FiT']: + world.regions.extend([ + create_dungeon_region( + 'Fire Temple Lower', + ['Fire Temple MQ Entrance Hallway Small Chest', 'Fire Temple MQ Chest Near Boss'], + ['Fire Temple Exit', 'Fire Temple Boss Door', 'Fire Temple Lower Locked Door', 'Fire Temple Hammer Statue']), + create_dungeon_region( + 'Fire Lower Locked Door', + ['Fire Temple MQ Megaton Hammer Chest', 'Fire Temple MQ Map Chest']), + create_dungeon_region( + 'Fire Big Lava Room', + ['Fire Temple MQ Boss Key Chest', 'Fire Temple MQ Big Lava Room Bombable Chest', 'GS Fire Temple MQ Big Lava Room'], + ['Fire Temple Early Climb']), + create_dungeon_region( + 'Fire Lower Maze', + ['Fire Temple MQ Maze Lower Chest'], + ['Fire Temple Maze Climb']), + create_dungeon_region( + 'Fire Upper Maze', + ['Fire Temple MQ Maze Upper Chest', 'Fire Temple MQ Maze Side Room', 'Fire Temple MQ Compass Chest', + 'GS Fire Temple MQ East Tower Top'], + ['Fire Temple Maze Escape']), + create_dungeon_region( + 'Fire Temple Upper', + ['Fire Temple MQ Freestanding Key', 'Fire Temple MQ West Tower Top Chest', 'GS Fire Temple MQ Fire Wall Maze Side Room', + 'GS Fire Temple MQ Fire Wall Maze Center', 'GS Fire Temple MQ Above Fire Wall Maze']), + create_dungeon_region( + 'Fire Boss Room', + ['Volvagia Heart', 'Volvagia']) + ]) + else: + world.regions.extend([ + create_dungeon_region( + 'Fire Temple Lower', + ['Fire Temple Chest Near Boss', 'Fire Temple Fire Dancer Chest', 'Fire Temple Boss Key Chest', + 'Fire Temple Big Lava Room Bombable Chest', 'Fire Temple Big Lava Room Open Chest', 'Volvagia Heart', + 'Volvagia', 'GS Fire Temple Song of Time Room', 'GS Fire Temple Basement'], + ['Fire Temple Exit', 'Fire Temple Early Climb']), + create_dungeon_region( + 'Fire Temple Middle', + ['Fire Temple Boulder Maze Lower Chest', 'Fire Temple Boulder Maze Upper Chest', + 'Fire Temple Boulder Maze Side Room', 'Fire Temple Boulder Maze Bombable Pit', 'Fire Temple Scarecrow Chest', + 'Fire Temple Map Chest', 'Fire Temple Compass Chest', 'GS Fire Temple Unmarked Bomb Wall', + 'GS Fire Temple East Tower Climb', 'GS Fire Temple East Tower Top'], + ['Fire Temple Fire Maze Escape']), + create_dungeon_region( + 'Fire Temple Upper', + ['Fire Temple Highest Goron Chest', 'Fire Temple Megaton Hammer Chest']) + ]) + + if world.dungeon_mq['WT']: + world.regions.extend([ + create_dungeon_region( + 'Water Temple Lobby', + ['Water Temple MQ Map Chest', 'Water Temple MQ Central Pillar Chest', 'Morpha Heart', 'Morpha'], + ['Water Temple Exit', 'Water Temple Water Level Switch', 'Water Temple Locked Door']), + create_dungeon_region( + 'Water Temple Lowered Water Levels', + ['Water Temple MQ Compass Chest', 'Water Temple MQ Longshot Chest', + 'GS Water Temple MQ Lizalfos Hallway', 'GS Water Temple MQ Before Upper Water Switch']), + create_dungeon_region( + 'Water Temple Dark Link Region', + ['Water Temple MQ Boss Key Chest', 'GS Water Temple MQ Serpent River'], + ['Water Temple Basement Gates Switch']), + create_dungeon_region( + 'Water Temple Basement Gated Areas', + ['Water Temple MQ Freestanding Key', 'GS Water Temple MQ South Basement', 'GS Water Temple MQ North Basement']) + ]) + else: + world.regions.extend([ + create_dungeon_region( + 'Water Temple Lobby', + ['Water Temple Map Chest', 'Water Temple Compass Chest', 'Water Temple Torches Chest', 'Water Temple Dragon Chest', + 'Water Temple Central Bow Target Chest', 'Water Temple Boss Key Chest', 'Morpha Heart', 'Morpha', + 'GS Water Temple South Basement', 'GS Water Temple Near Boss Key Chest'], + ['Water Temple Exit', 'Water Temple Central Pillar', 'Water Temple Upper Locked Door']), + create_dungeon_region( + 'Water Temple Middle Water Level', + ['Water Temple Central Pillar Chest', 'Water Temple Cracked Wall Chest', 'GS Water Temple Central Room']), + create_dungeon_region( + 'Water Temple Dark Link Region', + ['Water Temple Dark Link Chest', 'Water Temple River Chest', 'GS Water Temple Serpent River', + 'GS Water Temple Falling Platform Room']) + ]) + + if world.dungeon_mq['SpT']: + world.regions.extend([ + create_dungeon_region( + 'Spirit Temple Lobby', + ['Spirit Temple MQ Entrance Front Left Chest', 'Spirit Temple MQ Entrance Back Left Chest', + 'Spirit Temple MQ Entrance Back Right Chest'], + ['Spirit Temple Exit', 'Spirit Temple Crawl Passage', 'Spirit Temple Ceiling Passage']), + create_dungeon_region( + 'Child Spirit Temple', + ['Spirit Temple MQ Child Left Chest', 'Spirit Temple MQ Map Chest', 'Spirit Temple MQ Silver Block Hallway Chest'], + ['Child Spirit Temple to Shared']), + create_dungeon_region( + 'Adult Spirit Temple', + ['Spirit Temple MQ Child Center Chest', 'Spirit Temple MQ Child Climb South Chest', 'Spirit Temple MQ Lower NE Main Room Chest', + 'Spirit Temple MQ Upper NE Main Room Chest', 'Spirit Temple MQ Beamos Room Chest', 'Spirit Temple MQ Ice Trap Chest', + 'Spirit Temple MQ Boss Key Chest', 'GS Spirit Temple MQ Sun Block Room', 'GS Spirit Temple MQ Iron Knuckle West', + 'GS Spirit Temple MQ Iron Knuckle North'], + ['Adult Spirit Temple Descent', 'Adult Spirit Temple to Shared', 'Spirit Temple Climbable Wall', 'Mirror Shield Exit']), + create_dungeon_region( + 'Spirit Temple Shared', + ['Spirit Temple MQ Child Climb North Chest', 'Spirit Temple MQ Compass Chest', 'Spirit Temple MQ Sun Block Room Chest'], + ['Silver Gauntlets Exit']), + create_dungeon_region( + 'Lower Adult Spirit Temple', + ['Spirit Temple MQ Lower Adult Left Chest', 'Spirit Temple MQ Lower Adult Right Chest', + 'Spirit Temple MQ Entrance Front Right Chest', 'GS Spirit Temple MQ Lower Adult Left', + 'GS Spirit Temple MQ Lower Adult Right']), + create_dungeon_region( + 'Spirit Temple Boss Area', + ['Spirit Temple MQ Mirror Puzzle Invisible Chest', 'Twinrova Heart', 'Twinrova']), + create_dungeon_region( + 'Mirror Shield Hand', + ['Mirror Shield Chest']), + create_dungeon_region( + 'Silver Gauntlets Hand', + ['Silver Gauntlets Chest']) + ]) + else: + world.regions.extend([ + create_dungeon_region( + 'Spirit Temple Lobby', + None, + ['Spirit Temple Exit', 'Spirit Temple Crawl Passage', 'Spirit Temple Silver Block']), + create_dungeon_region( + 'Child Spirit Temple', + ['Spirit Temple Child Left Chest', 'Spirit Temple Child Right Chest', 'GS Spirit Temple Metal Fence', + 'Spirit Temple Nut Crate'], + ['Child Spirit Temple Climb']), + create_dungeon_region( + 'Child Spirit Temple Climb', + ['Spirit Temple Child Climb East Chest', 'Spirit Temple Child Climb North Chest', + 'GS Spirit Temple Bomb for Light Room'], + ['Child Spirit Temple Passthrough']), + create_dungeon_region( + 'Early Adult Spirit Temple', + ['Spirit Temple Compass Chest', 'Spirit Temple Early Adult Right Chest', + 'Spirit Temple First Mirror Right Chest', 'Spirit Temple First Mirror Left Chest', + 'GS Spirit Temple Boulder Room'], + ['Adult Spirit Temple Passthrough']), + create_dungeon_region( + 'Spirit Temple Central Chamber', + ['Spirit Temple Map Chest', 'Spirit Temple Sun Block Room Chest', 'Spirit Temple Statue Hand Chest', + 'Spirit Temple NE Main Room Chest', 'GS Spirit Temple Hall to West Iron Knuckle', 'GS Spirit Temple Lobby'], + ['Spirit Temple to Hands', 'Spirit Temple Central Locked Door', 'Spirit Temple Middle Child Door']), + create_dungeon_region( + 'Spirit Temple Outdoor Hands', + ['Silver Gauntlets Chest', 'Mirror Shield Chest']), + create_dungeon_region( + 'Spirit Temple Beyond Central Locked Door', + ['Spirit Temple Near Four Armos Chest', 'Spirit Temple Hallway Left Invisible Chest', + 'Spirit Temple Hallway Right Invisible Chest'], + ['Spirit Temple Final Locked Door']), + create_dungeon_region( + 'Spirit Temple Beyond Final Locked Door', + ['Spirit Temple Boss Key Chest', 'Spirit Temple Topmost Chest', 'Twinrova Heart', 'Twinrova']) + ]) + + if world.dungeon_mq['ShT']: + world.regions.extend([ + create_dungeon_region( + 'Shadow Temple Beginning', + None, + ['Shadow Temple Exit', 'Shadow Temple First Pit', 'Shadow Temple Beginning Locked Door']), + create_dungeon_region( + 'Shadow Temple Dead Hand Area', + ['Shadow Temple MQ Compass Chest', 'Shadow Temple MQ Hover Boots Chest']), + create_dungeon_region( + 'Shadow Temple First Beamos', + ['Shadow Temple MQ Map Chest', 'Shadow Temple MQ Early Gibdos Chest', 'Shadow Temple MQ Near Ship Invisible Chest'], + ['Shadow Temple Bomb Wall']), + create_dungeon_region( + 'Shadow Temple Huge Pit', + ['Shadow Temple MQ Invisible Blades Visible Chest', 'Shadow Temple MQ Invisible Blades Invisible Chest', + 'Shadow Temple MQ Beamos Silver Rupees Chest', 'Shadow Temple MQ Falling Spikes Lower Chest', + 'Shadow Temple MQ Falling Spikes Upper Chest', 'Shadow Temple MQ Falling Spikes Switch Chest', + 'Shadow Temple MQ Invisible Spikes Chest', 'Shadow Temple MQ Stalfos Room Chest', 'GS Shadow Temple MQ Crusher Room'], + ['Shadow Temple Hookshot Target']), + create_dungeon_region( + 'Shadow Temple Wind Tunnel', + ['Shadow Temple MQ Wind Hint Chest', 'Shadow Temple MQ After Wind Enemy Chest', 'Shadow Temple MQ After Wind Hidden Chest', + 'GS Shadow Temple MQ Wind Hint Room', 'GS Shadow Temple MQ After Wind'], + ['Shadow Temple Boat']), + create_dungeon_region( + 'Shadow Temple Beyond Boat', + ['Bongo Bongo Heart', 'Bongo Bongo', 'GS Shadow Temple MQ After Ship', 'GS Shadow Temple MQ Near Boss'], + ['Shadow Temple Longshot Target']), + create_dungeon_region( + 'Shadow Temple Invisible Maze', + ['Shadow Temple MQ Spike Walls Left Chest', 'Shadow Temple MQ Boss Key Chest', + 'Shadow Temple MQ Bomb Flower Chest', 'Shadow Temple MQ Freestanding Key']) + ]) + else: + world.regions.extend([ + create_dungeon_region( + 'Shadow Temple Beginning', + ['Shadow Temple Map Chest', 'Shadow Temple Hover Boots Chest'], + ['Shadow Temple Exit', 'Shadow Temple First Pit']), + create_dungeon_region( + 'Shadow Temple First Beamos', + ['Shadow Temple Compass Chest', 'Shadow Temple Early Silver Rupee Chest'], + ['Shadow Temple Bomb Wall']), + create_dungeon_region( + 'Shadow Temple Huge Pit', + ['Shadow Temple Invisible Blades Visible Chest', 'Shadow Temple Invisible Blades Invisible Chest', + 'Shadow Temple Falling Spikes Lower Chest', 'Shadow Temple Falling Spikes Upper Chest', + 'Shadow Temple Falling Spikes Switch Chest', 'Shadow Temple Invisible Spikes Chest', + 'Shadow Temple Freestanding Key', 'GS Shadow Temple Like Like Room', 'GS Shadow Temple Crusher Room', + 'GS Shadow Temple Single Giant Pot'], + ['Shadow Temple Hookshot Target']), + create_dungeon_region( + 'Shadow Temple Wind Tunnel', + ['Shadow Temple Wind Hint Chest', 'Shadow Temple After Wind Enemy Chest', + 'Shadow Temple After Wind Hidden Chest', 'GS Shadow Temple Near Ship'], + ['Shadow Temple Boat']), + create_dungeon_region( + 'Shadow Temple Beyond Boat', + ['Shadow Temple Spike Walls Left Chest', 'Shadow Temple Boss Key Chest', + 'Shadow Temple Hidden Floormaster Chest', 'Bongo Bongo Heart', 'Bongo Bongo', + 'GS Shadow Temple Triple Giant Pot']) + ]) + + if world.dungeon_mq['BW']: + world.regions.extend([ + create_dungeon_region( + 'Bottom of the Well', + ['Bottom of the Well MQ Compass Chest', 'Bottom of the Well MQ Map Chest', 'Bottom of the Well MQ Lens Chest', + 'Bottom of the Well MQ Dead Hand Freestanding Key', 'Bottom of the Well MQ East Inner Room Freestanding Key', + 'GS Well MQ Basement', 'GS Well MQ West Inner Room', 'GS Well MQ Coffin Room'], + ['Bottom of the Well Exit']) + ]) + else: + world.regions.extend([ + create_dungeon_region( + 'Bottom of the Well', + ['Bottom of the Well Front Left Hidden Wall', 'Bottom of the Well Front Center Bombable', + 'Bottom of the Well Right Bottom Hidden Wall', 'Bottom of the Well Center Large Chest', + 'Bottom of the Well Center Small Chest', 'Bottom of the Well Back Left Bombable', + 'Bottom of the Well Freestanding Key', 'Bottom of the Well Defeat Boss', 'Bottom of the Well Invisible Chest', + 'Bottom of the Well Underwater Front Chest', 'Bottom of the Well Underwater Left Chest', + 'Bottom of the Well Basement Chest', 'Bottom of the Well Locked Pits', 'Bottom of the Well Behind Right Grate', + 'GS Well West Inner Room', 'GS Well East Inner Room', 'GS Well Like Like Cage', 'Bottom of the Well Stick Pot'], + ['Bottom of the Well Exit']) + ]) + + if world.dungeon_mq['IC']: + world.regions.extend([ + create_dungeon_region( + 'Ice Cavern', + ['Ice Cavern MQ Map Chest', 'Ice Cavern MQ Compass Chest', 'Ice Cavern MQ Iron Boots Chest', + 'Ice Cavern MQ Freestanding PoH', 'Sheik in Ice Cavern', 'GS Ice Cavern MQ Red Ice', + 'GS Ice Cavern MQ Ice Block', 'GS Ice Cavern MQ Scarecrow'], + ['Ice Cavern Exit']) + ]) + else: + world.regions.extend([ + create_dungeon_region( + 'Ice Cavern', + ['Ice Cavern Map Chest', 'Ice Cavern Compass Chest', 'Ice Cavern Iron Boots Chest', + 'Ice Cavern Freestanding PoH', 'Sheik in Ice Cavern', 'GS Ice Cavern Spinning Scythe Room', + 'GS Ice Cavern Heart Piece Room', 'GS Ice Cavern Push Block Room'], + ['Ice Cavern Exit']) + ]) + + if world.dungeon_mq['GTG']: + world.regions.extend([ + create_dungeon_region( + 'Gerudo Training Grounds Lobby', + ['Gerudo Training Grounds MQ Lobby Left Chest', 'Gerudo Training Grounds MQ Lobby Right Chest', + 'Gerudo Training Grounds MQ Hidden Ceiling Chest', 'Gerudo Training Grounds MQ Maze Path First Chest', + 'Gerudo Training Grounds MQ Maze Path Second Chest', 'Gerudo Training Grounds MQ Maze Path Third Chest'], + ['Gerudo Training Grounds Exit', 'Gerudo Training Grounds Left Door', 'Gerudo Training Grounds Right Door']), + create_dungeon_region( + 'Gerudo Training Grounds Right Side', + ['Gerudo Training Grounds MQ Dinolfos Chest', 'Gerudo Training Grounds MQ Underwater Silver Rupee Chest']), + create_dungeon_region( + 'Gerudo Training Grounds Left Side', + ['Gerudo Training Grounds MQ First Iron Knuckle Chest'], + ['Gerudo Training Grounds Longshot Target']), + create_dungeon_region( + 'Gerudo Training Grounds Stalfos Room', + ['Gerudo Training Grounds MQ Before Heavy Block Chest', 'Gerudo Training Grounds MQ Heavy Block Chest'], + ['Gerudo Training Grounds Song of Time Block']), + create_dungeon_region( + 'Gerudo Training Grounds Back Areas', + ['Gerudo Training Grounds MQ Eye Statue Chest', 'Gerudo Training Grounds MQ Second Iron Knuckle Chest', + 'Gerudo Training Grounds MQ Flame Circle Chest'], + ['Gerudo Training Grounds Rusted Switch', 'Gerudo Training Grounds Loop Around']), + create_dungeon_region( + 'Gerudo Training Grounds Central Maze Right', + ['Gerudo Training Grounds MQ Maze Right Central Chest', 'Gerudo Training Grounds MQ Maze Right Side Chest', + 'Gerudo Training Grounds MQ Ice Arrows Chest']) + ]) + else: + world.regions.extend([ + create_dungeon_region( + 'Gerudo Training Grounds Lobby', + ['Gerudo Training Grounds Lobby Left Chest', 'Gerudo Training Grounds Lobby Right Chest', + 'Gerudo Training Grounds Stalfos Chest', 'Gerudo Training Grounds Beamos Chest'], + ['Gerudo Training Grounds Exit', 'Gerudo Training Ground Left Silver Rupees', 'Gerudo Training Ground Beamos', + 'Gerudo Training Ground Central Door']), + create_dungeon_region( + 'Gerudo Training Grounds Central Maze', + ['Gerudo Training Grounds Hidden Ceiling Chest', 'Gerudo Training Grounds Maze Path First Chest', + 'Gerudo Training Grounds Maze Path Second Chest', 'Gerudo Training Grounds Maze Path Third Chest', + 'Gerudo Training Grounds Maze Path Final Chest'], + ['Gerudo Training Grounds Right Locked Doors']), + create_dungeon_region( + 'Gerudo Training Grounds Central Maze Right', + ['Gerudo Training Grounds Maze Right Central Chest', 'Gerudo Training Grounds Maze Right Side Chest', + 'Gerudo Training Grounds Freestanding Key'], + ['Gerudo Training Grounds Maze Exit']), + create_dungeon_region( + 'Gerudo Training Grounds Lava Room', + ['Gerudo Training Grounds Underwater Silver Rupee Chest'], + ['Gerudo Training Grounds Maze Ledge', 'Gerudo Training Grounds Right Hookshot Target']), + create_dungeon_region( + 'Gerudo Training Grounds Hammer Room', + ['Gerudo Training Grounds Hammer Room Clear Chest', 'Gerudo Training Grounds Hammer Room Switch Chest'], + ['Gerudo Training Grounds Hammer Target', 'Gerudo Training Grounds Hammer Room Clear']), + create_dungeon_region( + 'Gerudo Training Grounds Eye Statue Lower', + ['Gerudo Training Grounds Eye Statue Chest'], + ['Gerudo Training Grounds Eye Statue Exit']), + create_dungeon_region( + 'Gerudo Training Grounds Eye Statue Upper', + ['Gerudo Training Grounds Near Scarecrow Chest'], + ['Gerudo Training Grounds Eye Statue Drop']), + create_dungeon_region( + 'Gerudo Training Grounds Heavy Block Room', + ['Gerudo Training Grounds Before Heavy Block Chest', 'Gerudo Training Grounds Heavy Block First Chest', + 'Gerudo Training Grounds Heavy Block Second Chest', 'Gerudo Training Grounds Heavy Block Third Chest', + 'Gerudo Training Grounds Heavy Block Fourth Chest'], + ['Gerudo Training Grounds Hidden Hookshot Target']) + ]) + + if world.dungeon_mq['GC']: + world.regions.extend([ + create_dungeon_region( + 'Ganons Castle Lobby', + None, + ['Ganons Castle Exit', 'Ganons Castle Forest Trial', 'Ganons Castle Fire Trial', 'Ganons Castle Water Trial', + 'Ganons Castle Shadow Trial', 'Ganons Castle Spirit Trial', 'Ganons Castle Light Trial', + 'Ganons Castle Tower', 'Ganons Castle Deku Scrubs']), + create_dungeon_region( + 'Ganons Castle Deku Scrubs', + ['GC MQ Deku Scrub Bombs', 'GC MQ Deku Scrub Arrows', 'GC MQ Deku Scrub Red Potion', 'GC MQ Deku Scrub Green Potion', + 'GC MQ Deku Scrub Deku Nuts']), + create_dungeon_region( + 'Ganons Castle Forest Trial', + ['Ganons Castle MQ Forest Trial First Chest', 'Ganons Castle MQ Forest Trial Second Chest', + 'Ganons Castle MQ Forest Trial Freestanding Key', 'Ganons Castle Forest Trial Clear']), + create_dungeon_region( + 'Ganons Castle Fire Trial', + ['Ganons Castle Fire Trial Clear']), + create_dungeon_region( + 'Ganons Castle Water Trial', + ['Ganons Castle MQ Water Trial Chest', 'Ganons Castle Water Trial Clear']), + create_dungeon_region( + 'Ganons Castle Shadow Trial', + ['Ganons Castle MQ Shadow Trial First Chest', 'Ganons Castle MQ Shadow Trial Second Chest', + 'Ganons Castle Shadow Trial Clear']), + create_dungeon_region( + 'Ganons Castle Spirit Trial', + ['Ganons Castle MQ Spirit Trial First Chest', 'Ganons Castle MQ Spirit Trial Second Chest', + 'Ganons Castle MQ Spirit Trial Sun Front Left Chest', 'Ganons Castle MQ Spirit Trial Sun Back Left Chest', + 'Ganons Castle MQ Spirit Trial Golden Gauntlets Chest', 'Ganons Castle MQ Spirit Trial Sun Back Right Chest', + 'Ganons Castle Spirit Trial Clear']), + create_dungeon_region( + 'Ganons Castle Light Trial', + ['Ganons Castle MQ Light Trial Lullaby Chest', 'Ganons Castle Light Trial Clear']) + ]) + else: + world.regions.extend([ + create_dungeon_region( + 'Ganons Castle Lobby', + None, + ['Ganons Castle Exit', 'Ganons Castle Forest Trial', 'Ganons Castle Fire Trial', 'Ganons Castle Water Trial', + 'Ganons Castle Shadow Trial', 'Ganons Castle Spirit Trial', 'Ganons Castle Light Trial', + 'Ganons Castle Tower', 'Ganons Castle Deku Scrubs']), + create_dungeon_region( + 'Ganons Castle Deku Scrubs', + ['GC Deku Scrub Bombs', 'GC Deku Scrub Arrows', 'GC Deku Scrub Red Potion', 'GC Deku Scrub Green Potion']), + create_dungeon_region( + 'Ganons Castle Forest Trial', + ['Ganons Castle Forest Trial Chest', 'Ganons Castle Forest Trial Clear']), + create_dungeon_region( + 'Ganons Castle Fire Trial', + ['Ganons Castle Fire Trial Clear']), + create_dungeon_region( + 'Ganons Castle Water Trial', + ['Ganons Castle Water Trial Left Chest', 'Ganons Castle Water Trial Right Chest', + 'Ganons Castle Water Trial Clear']), + create_dungeon_region( + 'Ganons Castle Shadow Trial', + ['Ganons Castle Shadow Trial First Chest', 'Ganons Castle Shadow Trial Second Chest', + 'Ganons Castle Shadow Trial Clear']), + create_dungeon_region( + 'Ganons Castle Spirit Trial', + ['Ganons Castle Spirit Trial First Chest', 'Ganons Castle Spirit Trial Second Chest', + 'Ganons Castle Spirit Trial Clear']), + create_dungeon_region( + 'Ganons Castle Light Trial', + ['Ganons Castle Light Trial First Left Chest', 'Ganons Castle Light Trial Second Left Chest', + 'Ganons Castle Light Trial Third Left Chest', 'Ganons Castle Light Trial First Right Chest', + 'Ganons Castle Light Trial Second Right Chest', 'Ganons Castle Light Trial Third Right Chest', + 'Ganons Castle Light Trail Invisible Enemies Chest', 'Ganons Castle Light Trial Lullaby Chest', + 'Ganons Castle Light Trial Clear']) + ]) + + world.initialize_regions() def create_ow_region(name, locations=None, exits=None): return _create_region(name, RegionType.Overworld, locations, exits) @@ -202,384 +989,760 @@ def _create_region(name, type, locations=None, exits=None): ret.locations.append(Location(location, address, address2, default, type, scene, hint, ret)) return ret -location_table = {'Kokiri Sword Chest': (0x20A6142, None, 0x04E0, 'Chest', 0x55, 'Kokiri Forest'), - 'Mido Chest Top Left': (0x2F7B08A, None, 0x59A0, 'Chest', 0x28, 'Kokiri Forest'), - 'Mido Chest Top Right': (0x2F7B09A, None, 0x59A1, 'Chest', 0x28, 'Kokiri Forest'), - 'Mido Chest Bottom Left': (0x2F7B0AA, None, 0x5982, 'Chest', 0x28, 'Kokiri Forest'), - 'Mido Chest Bottom Right': (0x2F7B0BA, None, 0x5903, 'Chest', 0x28, 'Kokiri Forest'), - 'Shield Grave Chest': (0x328B096, None, 0x5540, 'Chest', 0x40, 'the Graveyard'), - 'Heart Piece Grave Chest': (0x2D0A056, None, 0xA7C0, 'Chest', 0x3F, 'the Graveyard'), - 'Composer Grave Chest': (0x332D0EA, None, 0x8020, 'Chest', 0x41, 'the Graveyard'), - 'Death Mountain Bombable Chest': (0x223C3CA, 0x223C7B2, 0x5AA1, 'Chest', 0x60, 'Death Mountain Trail'), - 'Goron City Leftmost Maze Chest': (0x227C23A, 0x227C70A, 0x5AC0, 'Chest', 0x62, 'Goron City'), - 'Goron City Left Maze Chest': (0x227C24A, 0x227C71A, 0x5AA1, 'Chest', 0x62, 'Goron City'), - 'Goron City Right Maze Chest': (0x227C25A, 0x227C72A, 0x5AA2, 'Chest', 0x62, 'Goron City'), - 'Zoras Domain Torch Run': (0x2103166, None, 0xB7C0, 'Chest', 0x58, 'Zora\'s Domain'), - 'Hookshot Chest': (0x3063092, None, 0x1100, 'Chest', 0x48, 'the Graveyard'), - 'Gerudo Valley Hammer Rocks Chest': (0x213D676, None, 0x5AA0, 'Chest', 0x5A, 'Gerudo Valley'), - 'Gerudo Fortress Rooftop Chest': (0x21BD4AA, 0x21BD6EA, 0x07C0, 'Chest', 0x5D, 'Gerudo Fortress'), - 'Haunted Wasteland Structure Chest': (0x21E20DE, None, 0x8AA0, 'Chest', 0x5E, 'Haunted Wasteland'), - 'Redead Grotto Chest': (0x26CF076, None, 0x7ACA, 'Chest', 0x3E, 'Kakariko Village'), - 'Wolfos Grotto Chest': (0x26EB076, None, 0x7AB1, 'Chest', 0x3E, 'Sacred Forest Meadow'), - 'Deku Tree Lobby Chest': (0x24A7146, None, 0x0823, 'Chest', 0x00, 'Deku Tree'), - 'Deku Tree Slingshot Chest': (0x24C20C6, None, 0x00A1, 'Chest', 0x00, 'Deku Tree'), - 'Deku Tree Slingshot Room Side Chest': (0x24C20D6, None, 0x5905, 'Chest', 0x00, 'Deku Tree'), - 'Deku Tree Compass Chest': (0x25040D6, None, 0x0802, 'Chest', 0x00, 'Deku Tree'), - 'Deku Tree Compass Room Side Chest': (0x25040E6, None, 0x5906, 'Chest', 0x00, 'Deku Tree'), - 'Deku Tree Basement Chest': (0x24C8166, None, 0x5904, 'Chest', 0x00, 'Deku Tree'), - 'Dodongos Cavern Map Chest': (0x1F2819E, None, 0x0828, 'Chest', 0x01, 'Dodongo\'s Cavern'), - 'Dodongos Cavern Compass Chest': (0x1FAF0AA, None, 0x0805, 'Chest', 0x01, 'Dodongo\'s Cavern'), - 'Dodongos Cavern Bomb Flower Platform': (0x1F890DE, None, 0x59C6, 'Chest', 0x01, 'Dodongo\'s Cavern'), - 'Dodongos Cavern Bomb Bag Chest': (0x1F890CE, None, 0x0644, 'Chest', 0x01, 'Dodongo\'s Cavern'), - 'Dodongos Cavern End of Bridge Chest': (0x1F281CE, None, 0x552A, 'Chest', 0x01, 'Dodongo\'s Cavern'), - 'Chest Above King Dodongo': (0x2EB00BA, None, 0x5020, 'Chest', 0x12, 'Dodongo\'s Cavern'), - 'Boomerang Chest': (0x278A0BA, None, 0x10C1, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), - 'Jabu Jabus Belly Map Chest': (0x278E08A, None, 0x1822, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), - 'Jabu Jabus Belly Compass Chest': (0x279608A, None, 0xB804, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), - 'Forest Temple First Chest': (0x23E5092, None, 0x5843, 'Chest', 0x03, 'Forest Temple'), - 'Forest Temple Chest Behind Lobby': (0x2415082, None, 0x7840, 'Chest', 0x03, 'Forest Temple'), - 'Forest Temple Well Chest': (0x244A062, None, 0x5849, 'Chest', 0x03, 'Forest Temple'), - 'Forest Temple Map Chest': (0x2455076, None, 0x1821, 'Chest', 0x03, 'Forest Temple'), - 'Forest Temple Outside Hookshot Chest': (0x241F0D6, None, 0x5905, 'Chest', 0x03, 'Forest Temple'), - 'Forest Temple Falling Room Chest': (0x247E09E, None, 0x5947, 'Chest', 0x03, 'Forest Temple'), - 'Forest Temple Block Push Chest': (0x245B096, None, 0x8964, 'Chest', 0x03, 'Forest Temple'), - 'Forest Temple Boss Key Chest': (0xCB0DC2, None, 0x27EE, 'Chest', 0x03, 'Forest Temple'), - 'Forest Temple Floormaster Chest': (0x2490072, None, 0x7842, 'Chest', 0x03, 'Forest Temple'), - 'Forest Temple Bow Chest': (0x2415092, None, 0xB08C, 'Chest', 0x03, 'Forest Temple'), - 'Forest Temple Red Poe Chest': (0x246607E, None, 0x784D, 'Chest', 0x03, 'Forest Temple'), - 'Forest Temple Blue Poe Chest': (0x246F07E, None, 0x180F, 'Chest', 0x03, 'Forest Temple'), - 'Forest Temple Near Boss Chest': (0x2486082, None, 0x592B, 'Chest', 0x03, 'Forest Temple'), - 'Bottom of the Well Front Left Hidden Wall': (0x32D317E, None, 0x5848, 'Chest', 0x08, 'Bottom of the Well'), - 'Bottom of the Well Front Center Bombable': (0x32D30FE, None, 0x5062, 'Chest', 0x08, 'Bottom of the Well'), - 'Bottom of the Well Right Bottom Hidden Wall': (0x32D314E, None, 0x5845, 'Chest', 0x08, 'Bottom of the Well'), - 'Bottom of the Well Center Large Chest': (0x32D30EE, None, 0x0801, 'Chest', 0x08, 'Bottom of the Well'), - 'Bottom of the Well Center Small Chest': (0x32D31AE, None, 0x504E, 'Chest', 0x08, 'Bottom of the Well'), - 'Bottom of the Well Back Left Bombable': (0x32D313E, None, 0x5C84, 'Chest', 0x08, 'Bottom of the Well'), - 'Bottom of the Well Defeat Boss': (0x32FB0AA, None, 0x1143, 'Chest', 0x08, 'Bottom of the Well'), - 'Bottom of the Well Invisible Chest': (0x32FB0BA, None, 0x6AD4, 'Chest', 0x08, 'Bottom of the Well'), - 'Bottom of the Well Underwater Front Chest': (0x32D31BE, None, 0x5CD0, 'Chest', 0x08, 'Bottom of the Well'), - 'Bottom of the Well Underwater Left Chest': (0x32D318E, None, 0x5909, 'Chest', 0x08, 'Bottom of the Well'), - 'Bottom of the Well Basement Chest': (0x32E9252, None, 0x0827, 'Chest', 0x08, 'Bottom of the Well'), - 'Bottom of the Well Locked Pits': (0x32F90AA, None, 0x552A, 'Chest', 0x08, 'Bottom of the Well'), - 'Bottom of the Well Behind Right Grate': (0x32D319E, None, 0x554C, 'Chest', 0x08, 'Bottom of the Well'), - 'Fire Temple Chest Near Boss': (0x230808A, None, 0x5841, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Fire Dancer Chest': (0x2318082, None, 0x7CC0, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Boss Key Chest': (0x238A0D6, None, 0x27EC, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Big Lava Room Bombable Chest': (0x23AD076, None, 0x5842, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Big Lava Room Open Chest': (0x239D0A6, None, 0x5844, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Boulder Maze Lower Chest': (0x2323152, None, 0x5843, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Boulder Maze Upper Chest': (0x2323182, None, 0x5846, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Boulder Maze Side Room': (0x23B40B2, None, 0x5848, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Boulder Maze Bombable Pit': (0x231B0E2, None, 0x584B, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Scarecrow Chest': (0x2339082, None, 0x5ACD, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Map Chest': (0x237E0C2, None, 0x082A, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Compass Chest': (0x23C1082, None, 0x0807, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Highest Goron Chest': (0x2365066, None, 0x5849, 'Chest', 0x04, 'Fire Temple'), - 'Fire Temple Megaton Hammer Chest': (0x236C102, None, 0x01A5, 'Chest', 0x04, 'Fire Temple'), - 'Ice Cavern Map Chest': (0x2C4016A, None, 0x0820, 'Chest', 0x09, 'Ice Cavern'), - 'Ice Cavern Compass Chest': (0x2C4E236, None, 0x0801, 'Chest', 0x09, 'Ice Cavern'), - 'Ice Cavern Iron Boots Chest': (0x2C380A2, None, 0x15C2, 'Chest', 0x09, 'Ice Cavern'), - 'Water Temple Map Chest': (0x26690A6, None, 0x1822, 'Chest', 0x05, 'Water Temple'), - 'Water Temple Compass Chest': (0x25FC0D2, None, 0x0809, 'Chest', 0x05, 'Water Temple'), - 'Water Temple Torches Chest': (0x26640A6, None, 0x7841, 'Chest', 0x05, 'Water Temple'), - 'Water Temple Dragon Chest': (0x261F0BA, None, 0x584A, 'Chest', 0x05, 'Water Temple'), - 'Water Temple Central Bow Target Chest': (0x266D072, None, 0x5848, 'Chest', 0x05, 'Water Temple'), - 'Water Temple Central Pillar Chest': (0x25EF0D6, None, 0x5846, 'Chest', 0x05, 'Water Temple'), - 'Water Temple Cracked Wall Chest': (0x265B0A6, None, 0x5840, 'Chest', 0x05, 'Water Temple'), - 'Water Temple Boss Key Chest': (0x2657066, None, 0x27E5, 'Chest', 0x05, 'Water Temple'), - 'Water Temple Dark Link Chest': (0x261907A, None, 0x0127, 'Chest', 0x05, 'Water Temple'), - 'Water Temple River Chest': (0x26740DE, None, 0x5843, 'Chest', 0x05, 'Water Temple'), - 'Shadow Temple Map Chest': (0x27CC0AA, None, 0x1821, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Hover Boots Chest': (0x27DC0CA, None, 0x15E7, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Compass Chest': (0x27EC09E, None, 0x1803, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Early Silver Rupee Chest': (0x27E40F6, None, 0x5842, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Invisible Blades Visible Chest': (0x282212A, None, 0x588C, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Invisible Blades Invisible Chest': (0x282211A, None, 0x6976, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Falling Spikes Lower Chest': (0x2801132, None, 0x5945, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Falling Spikes Upper Chest': (0x2801142, None, 0x5886, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Falling Spikes Switch Chest': (0x2801122, None, 0x8844, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Invisible Spikes Chest': (0x28090EE, None, 0x7889, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Wind Hint Chest': (0x283609A, None, 0x6955, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple After Wind Enemy Chest': (0x28390FE, None, 0x7888, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple After Wind Hidden Chest': (0x28390EE, None, 0x6854, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Spike Walls Left Chest': (0x28130B6, None, 0x588A, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Boss Key Chest': (0x28130A6, None, 0x27EB, 'Chest', 0x07, 'Shadow Temple'), - 'Shadow Temple Hidden Floormaster Chest': (0x282508A, None, 0x784D, 'Chest', 0x07, 'Shadow Temple'), - 'Gerudo Training Grounds Lobby Left Chest': (0x28870CA, None, 0x8893, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Lobby Right Chest': (0x28870BA, None, 0x8947, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Stalfos Chest': (0x28970AA, None, 0x8840, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Beamos Chest': (0x28C715E, None, 0x8841, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Hidden Ceiling Chest': (0x28D010E, None, 0x584B, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Maze Path First Chest': (0x28D00CE, None, 0x5AA6, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Maze Path Second Chest': (0x28D00FE, None, 0x59CA, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Maze Path Third Chest': (0x28D00EE, None, 0x5969, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Maze Path Final Chest': (0x28D011E, None, 0x0B2C, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Maze Right Central Chest': (0x28D00BE, None, 0x5D45, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Maze Right Side Chest': (0x28D00DE, None, 0x5968, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Underwater Silver Rupee Chest': (0x28D91D6, None, 0x884D, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Hammer Room Clear Chest': (0x28B91AE, None, 0x7952, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Hammer Room Switch Chest': (0x28B919E, None, 0x5850, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Eye Statue Chest': (0x28AE09E, None, 0x8843, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Near Scarecrow Chest': (0x28D00AE, None, 0x5844, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Before Heavy Block Chest': (0x28A611E, None, 0x7971, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Heavy Block First Chest': (0x28DD0BE, None, 0x7ACF, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Heavy Block Second Chest': (0x28DD0AE, None, 0x788E, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Heavy Block Third Chest': (0x28DD08E, None, 0x6854, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Gerudo Training Grounds Heavy Block Fourth Chest': (0x28DD09E, None, 0x5F82, 'Chest', 0x0B, 'Gerudo Training Grounds'), - 'Spirit Temple Child Left Chest': (0x2B190BA, None, 0x5528, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple Child Right Chest': (0x2B13182, None, 0x8840, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple Compass Chest': (0x2B6B08A, None, 0x3804, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple Early Adult Right Chest': (0x2B6207A, None, 0x5847, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple First Mirror Right Chest': (0x2B700C6, None, 0x890D, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple First Mirror Left Chest': (0x2B700D6, None, 0x8F8E, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple Map Chest': (0x2B25126, None, 0xB823, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple Child Climb East Chest': (0x2B1D122, None, 0x8066, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple Child Climb North Chest': (0x2B1D132, None, 0x852C, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple Sun Block Room Chest': (0x2B481B2, None, 0x8841, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple Statue Hand Chest': (0x2B25136, None, 0x8842, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple NE Main Room Chest': (0x2B25146, None, 0x888F, 'Chest', 0x06, 'Spirit Temple'), - 'Silver Gauntlets Chest': (0x21A02DE, 0x21A06F2, 0x06AB, 'Chest', 0x5C, 'Desert Colossus'), - 'Mirror Shield Chest': (0x21A02CE, 0x21A06E2, 0x3569, 'Chest', 0x5C, 'Desert Colossus'), - 'Spirit Temple Near Four Armos Chest': (0x2B9F076, None, 0x5845, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple Hallway Left Invisible Chest': (0x2B900B6, None, 0x6914, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple Hallway Right Invisible Chest': (0x2B900C6, None, 0x6915, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple Boss Key Chest': (0x2BA4162, None, 0x27EA, 'Chest', 0x06, 'Spirit Temple'), - 'Spirit Temple Topmost Chest': (0x2BCF0FE, None, 0x8CF2, 'Chest', 0x06, 'Spirit Temple'), - 'Ganons Castle Forest Trial Chest': (0x31F106E, None, 0x7889, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Water Trial Left Chest': (0x31D7236, None, 0x5F87, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Water Trial Right Chest': (0x31D7226, None, 0x5906, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Shadow Trial First Chest': (0x32350CA, None, 0x5888, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Shadow Trial Second Chest': (0x32350BA, None, 0x36C5, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Spirit Trial First Chest': (0x3268132, None, 0x8D72, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Spirit Trial Second Chest': (0x3268142, None, 0x6954, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Light Trial First Left Chest': (0x321B11E, None, 0x588C, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Light Trial Second Left Chest': (0x321B10E, None, 0x5F8B, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Light Trial Third Left Chest': (0x321B12E, None, 0x590D, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Light Trial First Right Chest': (0x321B13E, None, 0x5F8E, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Light Trial Second Right Chest': (0x321B0FE, None, 0x596A, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Light Trial Third Right Chest': (0x321B14E, None, 0x5F8F, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Light Trail Invisible Enemies Chest': (0x321B15E, None, 0x7850, 'Chest', 0x0D, 'my castle'), - 'Ganons Castle Light Trial Lullaby Chest': (0x321B17E, None, 0x8851, 'Chest', 0x0D, 'my castle'), - 'Ganons Tower Boss Key Chest': (0x2F040EE, None, 0x27EB, 'Chest', 0x0A, 'my tower'), - 'Field West Castle Town Grotto Chest': (None, None, 0x00, 'Chest', 0x3E, 'Hyrule Field'), - 'Remote Southern Grotto Chest': (None, None, 0x02, 'Chest', 0x3E, 'Hyrule Field'), - 'Field Near Lake Outside Fence Grotto Chest': (None, None, 0x03, 'Chest', 0x3E, 'Hyrule Field'), - 'Kakariko Back Grotto Chest': (None, None, 0x08, 'Chest', 0x3E, 'Kakariko Village'), - 'Zora River Plateau Open Grotto Chest': (None, None, 0x09, 'Chest', 0x3E, 'Zora River'), - 'Kokiri Forest Storms Grotto Chest': (None, None, 0x0C, 'Chest', 0x3E, 'Kokiri Forest'), - 'Lost Woods Generic Grotto Chest': (None, None, 0x14, 'Chest', 0x3E, 'the Lost Woods'), - 'Mountain Storms Grotto Chest': (None, None, 0x17, 'Chest', 0x3E, 'Death Mountain Trail'), - 'Top of Crater Grotto Chest': (None, None, 0x1A, 'Chest', 0x3E, 'Death Mountain Crater'), - 'Impa at Castle': (0x2E8E925, 0x2E8E925, 0x0A, 'Song', None, None), - 'Song from Malon': (0xD7EB53, 0xD7EBCF, 0x09, 'Song', None, None), - 'Song from Composer Grave': (0x332A871, 0x332A871, 0x0B, 'Song', None, None), - 'Song from Saria': (0x20B1DB1, 0x20B1DB1, 0x08, 'Song', None, None), - 'Song from Ocarina of Time': (0x252FC89, 0x252FC89, 0x0C, 'Song', None, None), - 'Song at Windmill': (0xE42C07, 0xE42B8B, 0x0D, 'Song', None, None), - 'Sheik Forest Song': (0x20B0809, 0x20B0809, 0x02, 'Song', None, None), - 'Sheik at Temple': (0x2531329, 0x2531329, 0x07, 'Song', None, None), - 'Sheik in Crater': (0x224D7F1, 0x224D7F1, 0x03, 'Song', None, None), - 'Sheik in Ice Cavern': (0x2BEC889, 0x2BEC889, 0x04, 'Song', None, None), - 'Sheik in Kakariko': (0x2000FE1, 0x2000FE1, 0x06, 'Song', None, None), - 'Sheik at Colossus': (0x218C57D, 0x218C57D, 0x05, 'Song', None, None), - 'Gift from Saria': (None, None, None, 'NPC', None, 'the Lost Woods'), - 'Zeldas Letter': (None, None, None, 'NPC', None, 'Hyrule Castle'), - 'Zelda': (0x3481400, None, 0x5A, 'NPC', 0x43, 'the Temple of Time'), - 'Zoras Fountain Fairy Reward': (0x3481401, None, 0x5D, 'NPC', 0x3D, 'Zora\'s Fountain'), - 'Hyrule Castle Fairy Reward': (0x3481402, None, 0x5C, 'NPC', 0x3D, 'Hyrule Castle'), - 'Desert Colossus Fairy Reward': (0x3481403, None, 0x5E, 'NPC', 0x3D, 'Desert Colossus'), - 'Mountain Summit Fairy Reward': (0x3481404, None, 0x51, 'NPC', 0x3B, 'Death Mountain Trail'), - 'Crater Fairy Reward': (0x3481405, None, 0x52, 'NPC', 0x3B, 'Death Mountain Crater'), - 'Ganons Castle Fairy Reward': (0x3481406, None, 0x53, 'NPC', 0x3B, 'outside my castle'), - 'Treasure Chest Game': (None, None, 0x0A, 'Chest', 0x10, 'the market'), - 'Darunias Joy': (0xCF1BFF, None, 0x54, 'NPC', 0x62, 'Goron City'), - 'Diving Minigame': (0xE01A2B, 0xE01AA7, 0x37, 'NPC', 0x58, 'Zora\'s Domain'), - 'Child Fishing': (0xDCBFBF, None, 0x3E, 'NPC', 0x49, 'Lake Hylia'), - 'Adult Fishing': (0xDCC087, None, 0x38, 'NPC', 0x49, 'Lake Hylia'), - 'Diving in the Lab': (0xE2CB97, None, 0x3E, 'NPC', 0x38, 'Lake Hylia'), - 'Link the Goron': (0xED30EB, 0xED64F3, 0x2C, 'NPC', 0x62, 'Goron City'), - 'King Zora Thawed': (0xE56AD7, None, 0x2D, 'NPC', 0x58, 'Zora\'s Domain'), - 'Bombchu Bowling Bomb Bag': (0xE2F093, None, 0x34, 'NPC', 0x4B, 'the market'), - 'Bombchu Bowling Piece of Heart': (0xE2F097, None, 0x3E, 'NPC', 0x4B, 'the market'), - 'Dog Lady': (0xE65163, 0xE661BB, 0x3E, 'NPC', 0x35, 'the market'), - 'Skull Kid': (0xDF0F33, 0xDF0E9B, 0x3E, 'NPC', 0x5B, 'the Lost Woods'), - 'Ocarina Memory Game': (0xDF264F, None, 0x76, 'NPC', 0x5B, 'the Lost Woods'), - '10 Gold Skulltulla Reward': (0xEA7173, None, 0x45, 'NPC', 0x50, 'Kakariko Village'), - '20 Gold Skulltulla Reward': (0xEA7175, None, 0x39, 'NPC', 0x50, 'Kakariko Village'), - '30 Gold Skulltulla Reward': (0xEA7177, None, 0x46, 'NPC', 0x50, 'Kakariko Village'), - '40 Gold Skulltulla Reward': (0xEA7179, None, 0x03, 'NPC', 0x50, 'Kakariko Village'), - '50 Gold Skulltulla Reward': (0xEA717B, None, 0x3E, 'NPC', 0x50, 'Kakariko Village'), - 'Man on Roof': (0xE587E3, None, 0x3E, 'NPC', 0x52, 'Kakariko Village'), - 'Frog Ocarina Game': (0xDB13D3, None, 0x76, 'NPC', 0x54, 'Zora River'), - 'Frogs in the Rain': (0xDB1387, None, 0x3E, 'NPC', 0x54, 'Zora River'), - 'Horseback Archery 1000 Points': (0xE12B6F, 0xE12AA3, 0x3E, 'NPC', 0x5D, 'Gerudo Fortress'), - 'Horseback Archery 1500 Points': (0xE12BC3, 0xE12AFB, 0x30, 'NPC', 0x5D, 'Gerudo Fortress'), - 'Child Shooting Gallery': (0xD35EF3, None, 0x60, 'NPC', 0x42, 'the market'), - 'Adult Shooting Gallery': (0xD35F5B, None, 0x30, 'NPC', 0x42, 'Kakariko Village'), - 'Target in Woods': (0xE59CDF, None, 0x60, 'NPC', 0x5B, 'the Lost Woods'), - 'Deku Theater Skull Mask': (0xEC9A87, None, 0x77, 'NPC', 0x3E, 'the Lost Woods'), - 'Deku Theater Mask of Truth': (0xEC9CE7, None, 0x7A, 'NPC', 0x3E, 'the Lost Woods'), - 'Deku Salesman Woods': (0xDF8073, None, 0x77, 'NPC', 0x5B, 'the Lost Woods'), - 'Deku Salesman Lost Woods Grotto': (0xDF80E7, None, 0x79, 'NPC', 0x3E, 'the Lost Woods'), - 'Deku Salesman Hyrule Field Grotto': (0xDF86AB, None, 0x3E, 'NPC', 0x3E, 'Hyrule Field'), - 'Anju as Adult': (0xE1EABB, None, 0x1D, 'NPC', 0x52, 'Kakariko Village'), - 'Biggoron': (0xED338F, 0xED650F, 0x57, 'NPC', 0x60, 'Death Mountain Trail'), - 'Anjus Chickens': (0xE1E7A7, None, 0x0F, 'NPC', 0x52, 'Kakariko Village'), - 'Talons Chickens': (0xCC14EB, None, 0x14, 'NPC', 0x4C, 'Lon Lon Ranch'), - '10 Big Poes': (0xEE6AEF, None, 0x0F, 'NPC', 0x4D, 'the market'), - 'Rolling Goron as Child': (0xED296F, 0xED6503, 0x34, 'NPC', 0x62, 'Goron City'), - 'Lake Hylia Sun': (0xE9E1F2, None, 0x5B08, 'Chest', 0x57, 'Lake Hylia'), - 'Underwater Bottle': (0xDE10FB, None, 0x15, 'NPC', 0x57, 'Lake Hylia'), - 'Shadow Temple Freestanding Key': (None, None, 0x01, 'Collectable', 0x07, 'Shadow Temple'), - 'Bottom of the Well Freestanding Key': (None, None, 0x01, 'Collectable', 0x08, 'Bottom of the Well'), - 'Gerudo Training Grounds Freestanding Key': (None, None, 0x01, 'Collectable', 0x0B, 'Gerudo Training Grounds'), - 'Ice Cavern Freestanding PoH': (None, None, 0x01, 'Collectable', 0x09, 'Ice Cavern'), - 'Impa House Freestanding PoH': (None, None, 0x01, 'Collectable', 0x37, 'Kakariko Village'), - 'Tektite Grotto Freestanding PoH': (None, None, 0x01, 'Collectable', 0x3E, 'Hyrule Field'), - 'Windmill Freestanding PoH': (None, None, 0x01, 'Collectable', 0x48, 'Kakariko Village'), - 'Dampe Race Freestanding PoH': (None, None, 0x07, 'Collectable', 0x48, 'the Graveyard'), - 'Lon Lon Tower Freestanding PoH': (None, None, 0x01, 'Collectable', 0x4C, 'Lon Lon Ranch'), - 'Graveyard Freestanding PoH': (None, None, 0x04, 'Collectable', 0x53, 'the Graveyard'), - 'Gravedigging Tour': (None, None, 0x00, 'Collectable', 0x53, 'the Graveyard'), - 'Zora River Lower Freestanding PoH': (None, None, 0x04, 'Collectable', 0x54, 'Zora River'), - 'Zora River Upper Freestanding PoH': (None, None, 0x0B, 'Collectable', 0x54, 'Zora River'), - 'Lake Hylia Freestanding PoH': (None, None, 0x1E, 'Collectable', 0x57, 'Lake Hylia'), - 'Zoras Fountain Iceberg Freestanding PoH': (None, None, 0x01, 'Collectable', 0x59, 'Zora\'s Fountain'), - 'Zoras Fountain Bottom Freestanding PoH': (None, None, 0x14, 'Collectable', 0x59, 'Zora\'s Fountain'), - 'Gerudo Valley Waterfall Freestanding PoH': (None, None, 0x01, 'Collectable', 0x5A, 'Gerudo Valley'), - 'Gerudo Valley Crate Freestanding PoH': (None, None, 0x02, 'Collectable', 0x5A, 'Gerudo Valley'), - 'Colossus Freestanding PoH': (None, None, 0x0D, 'Collectable', 0x5C, 'Desert Colossus'), - 'DM Trail Freestanding PoH': (None, None, 0x1E, 'Collectable', 0x60, 'Death Mountain Trail'), - 'DM Crater Wall Freestanding PoH': (None, None, 0x02, 'Collectable', 0x61, 'Death Mountain Crater'), - 'DM Crater Volcano Freestanding PoH': (None, None, 0x08, 'Collectable', 0x61, 'Death Mountain Crater'), - 'Goron City Pot Freestanding PoH': (None, None, 0x1F, 'Collectable', 0x62, 'Goron City'), - 'Queen Gohma Heart': (None, None, 0x4F, 'BossHeart', 0x11, 'Deku Tree'), - 'King Dodongo Heart': (None, None, 0x4F, 'BossHeart', 0x12, 'Dodongo\'s Cavern'), - 'Barinade Heart': (None, None, 0x4F, 'BossHeart', 0x13, 'Jabu Jabu\'s Belly'), - 'Phantom Ganon Heart': (None, None, 0x4F, 'BossHeart', 0x14, 'Forest Temple'), - 'Volvagia Heart': (None, None, 0x4F, 'BossHeart', 0x15, 'Fire Temple'), - 'Morpha Heart': (None, None, 0x4F, 'BossHeart', 0x16, 'Water Temple'), - 'Twinrova Heart': (None, None, 0x4F, 'BossHeart', 0x17, 'Spirit Temple'), - 'Bongo Bongo Heart': (None, None, 0x4F, 'BossHeart', 0x18, 'Shadow Temple'), - 'Magic Bean Salesman': (None, None, None, 'Event', None, None), - 'King Zora Moves': (None, None, None, 'Event', None, None), - 'Ocarina of Time': (None, None, None, 'Event', None, 'Hyrule Field'), - 'Master Sword Pedestal': (None, None, None, 'Event', None, 'the Temple of Time'), - 'Epona': (None, None, None, 'Event', None, None), - 'Gerudo Fortress Carpenter Rescue': (None, None, None, 'Event', None, 'Gerudo Fortress'), - 'Ganons Castle Forest Trial Clear': (None, None, None, 'Event', None, None), - 'Ganons Castle Fire Trial Clear': (None, None, None, 'Event', None, None), - 'Ganons Castle Water Trial Clear': (None, None, None, 'Event', None, None), - 'Ganons Castle Shadow Trial Clear': (None, None, None, 'Event', None, None), - 'Ganons Castle Spirit Trial Clear': (None, None, None, 'Event', None, None), - 'Ganons Castle Light Trial Clear': (None, None, None, 'Event', None, None), - 'Links Pocket': (0x34806FB, 0x34806FF, None, 'Boss', None, None), - 'Queen Gohma': (0xCA315F, 0x2079571, 0x6C, 'Boss', None, None), - 'King Dodongo': (0xCA30DF, 0x2223309, 0x6D, 'Boss', None, None), - 'Barinade': (0xCA36EB, 0x2113C19, 0x6E, 'Boss', None, None), - 'Phantom Ganon': (0xCA3D07, 0xD4ED79, 0x66, 'Boss', None, None), - 'Volvagia': (0xCA3D93, 0xD10135, 0x67, 'Boss', None, None), - 'Morpha': (0xCA3E1F, 0xD5A3A9, 0x68, 'Boss', None, None), - 'Twinrova': (0xCA3EB3, 0xD39FF1, 0x69, 'Boss', None, None), - 'Bongo Bongo': (0xCA3F43, 0xD13E19, 0x6A, 'Boss', None, None), - 'Ganon': (None, None, None, 'Boss', None, None), - 'GS1': (None, None, None, 'GS Token', None, 'Kokiri Forest'), - 'GS2': (None, None, None, 'GS Token', None, 'Kokiri Forest'), - 'GS3': (None, None, None, 'GS Token', None, 'Kokiri Forest'), - 'GS4': (None, None, None, 'GS Token', None, 'the Lost Woods'), - 'GS5': (None, None, None, 'GS Token', None, 'the Lost Woods'), - 'GS6': (None, None, None, 'GS Token', None, 'the Lost Woods'), - 'GS7': (None, None, None, 'GS Token', None, 'Sacred Forest Meadow'), - 'GS8': (None, None, None, 'GS Token', None, 'Deku Tree'), - 'GS9': (None, None, None, 'GS Token', None, 'Deku Tree'), - 'GS10': (None, None, None, 'GS Token', None, 'Deku Tree'), - 'GS11': (None, None, None, 'GS Token', None, 'Deku Tree'), - 'GS12': (None, None, None, 'GS Token', None, 'Hyrule Field'), - 'GS13': (None, None, None, 'GS Token', None, 'Hyrule Field'), - 'GS14': (None, None, None, 'GS Token', None, 'the market'), - 'GS15': (None, None, None, 'GS Token', None, 'Hyrule Castle'), - 'GS16': (None, None, None, 'GS Token', None, 'Hyrule Castle'), - 'GS17': (None, None, None, 'GS Token', None, 'outside my castle'), - 'GS18': (None, None, None, 'GS Token', None, 'Lon Lon Ranch'), - 'GS19': (None, None, None, 'GS Token', None, 'Lon Lon Ranch'), - 'GS20': (None, None, None, 'GS Token', None, 'Lon Lon Ranch'), - 'GS21': (None, None, None, 'GS Token', None, 'Lon Lon Ranch'), - 'GS22': (None, None, None, 'GS Token', None, 'Kakariko Village'), - 'GS23': (None, None, None, 'GS Token', None, 'Kakariko Village'), - 'GS24': (None, None, None, 'GS Token', None, 'Kakariko Village'), - 'GS25': (None, None, None, 'GS Token', None, 'Kakariko Village'), - 'GS26': (None, None, None, 'GS Token', None, 'Kakariko Village'), - 'GS27': (None, None, None, 'GS Token', None, 'Kakariko Village'), - 'GS28': (None, None, None, 'GS Token', None, 'the Graveyard'), - 'GS29': (None, None, None, 'GS Token', None, 'the Graveyard'), - 'GS30': (None, None, None, 'GS Token', None, 'Death Mountain Trail'), - 'GS31': (None, None, None, 'GS Token', None, 'Death Mountain Trail'), - 'GS32': (None, None, None, 'GS Token', None, 'Death Mountain Trail'), - 'GS33': (None, None, None, 'GS Token', None, 'Death Mountain Trail'), - 'GS34': (None, None, None, 'GS Token', None, 'Goron City'), - 'GS35': (None, None, None, 'GS Token', None, 'Goron City'), - 'GS36': (None, None, None, 'GS Token', None, 'Death Mountain Crater'), - 'GS37': (None, None, None, 'GS Token', None, 'Death Mountain Crater'), - 'GS38': (None, None, None, 'GS Token', None, 'Dodongo\'s Cavern'), - 'GS39': (None, None, None, 'GS Token', None, 'Dodongo\'s Cavern'), - 'GS40': (None, None, None, 'GS Token', None, 'Dodongo\'s Cavern'), - 'GS41': (None, None, None, 'GS Token', None, 'Dodongo\'s Cavern'), - 'GS42': (None, None, None, 'GS Token', None, 'Dodongo\'s Cavern'), - 'GS43': (None, None, None, 'GS Token', None, 'Zora River'), - 'GS44': (None, None, None, 'GS Token', None, 'Zora River'), - 'GS45': (None, None, None, 'GS Token', None, 'Zora River'), - 'GS46': (None, None, None, 'GS Token', None, 'Zora River'), - 'GS47': (None, None, None, 'GS Token', None, 'Zora\'s Domain'), - 'GS48': (None, None, None, 'GS Token', None, 'Zora\'s Fountain'), - 'GS49': (None, None, None, 'GS Token', None, 'Zora\'s Fountain'), - 'GS50': (None, None, None, 'GS Token', None, 'Zora\'s Fountain'), - 'GS51': (None, None, None, 'GS Token', None, 'Jabu Jabu\'s Belly'), - 'GS52': (None, None, None, 'GS Token', None, 'Jabu Jabu\'s Belly'), - 'GS53': (None, None, None, 'GS Token', None, 'Jabu Jabu\'s Belly'), - 'GS54': (None, None, None, 'GS Token', None, 'Jabu Jabu\'s Belly'), - 'GS55': (None, None, None, 'GS Token', None, 'Lake Hylia'), - 'GS56': (None, None, None, 'GS Token', None, 'Lake Hylia'), - 'GS57': (None, None, None, 'GS Token', None, 'Lake Hylia'), - 'GS58': (None, None, None, 'GS Token', None, 'Lake Hylia'), - 'GS59': (None, None, None, 'GS Token', None, 'Lake Hylia'), - 'GS60': (None, None, None, 'GS Token', None, 'Forest Temple'), - 'GS61': (None, None, None, 'GS Token', None, 'Forest Temple'), - 'GS62': (None, None, None, 'GS Token', None, 'Forest Temple'), - 'GS63': (None, None, None, 'GS Token', None, 'Forest Temple'), - 'GS64': (None, None, None, 'GS Token', None, 'Forest Temple'), - 'GS65': (None, None, None, 'GS Token', None, 'Fire Temple'), - 'GS66': (None, None, None, 'GS Token', None, 'Fire Temple'), - 'GS67': (None, None, None, 'GS Token', None, 'Fire Temple'), - 'GS68': (None, None, None, 'GS Token', None, 'Fire Temple'), - 'GS69': (None, None, None, 'GS Token', None, 'Fire Temple'), - 'GS70': (None, None, None, 'GS Token', None, 'Ice Cavern'), - 'GS71': (None, None, None, 'GS Token', None, 'Ice Cavern'), - 'GS72': (None, None, None, 'GS Token', None, 'Ice Cavern'), - 'GS73': (None, None, None, 'GS Token', None, 'Water Temple'), - 'GS74': (None, None, None, 'GS Token', None, 'Water Temple'), - 'GS75': (None, None, None, 'GS Token', None, 'Water Temple'), - 'GS76': (None, None, None, 'GS Token', None, 'Water Temple'), - 'GS77': (None, None, None, 'GS Token', None, 'Water Temple'), - 'GS78': (None, None, None, 'GS Token', None, 'Bottom of the Well'), - 'GS79': (None, None, None, 'GS Token', None, 'Bottom of the Well'), - 'GS80': (None, None, None, 'GS Token', None, 'Bottom of the Well'), - 'GS81': (None, None, None, 'GS Token', None, 'Shadow Temple'), - 'GS82': (None, None, None, 'GS Token', None, 'Shadow Temple'), - 'GS83': (None, None, None, 'GS Token', None, 'Shadow Temple'), - 'GS84': (None, None, None, 'GS Token', None, 'Shadow Temple'), - 'GS85': (None, None, None, 'GS Token', None, 'Shadow Temple'), - 'GS86': (None, None, None, 'GS Token', None, 'Gerudo Valley'), - 'GS87': (None, None, None, 'GS Token', None, 'Gerudo Valley'), - 'GS88': (None, None, None, 'GS Token', None, 'Gerudo Valley'), - 'GS89': (None, None, None, 'GS Token', None, 'Gerudo Valley'), - 'GS90': (None, None, None, 'GS Token', None, 'Gerudo Fortress'), - 'GS91': (None, None, None, 'GS Token', None, 'Gerudo Fortress'), - 'GS92': (None, None, None, 'GS Token', None, 'Haunted Wasteland'), - 'GS93': (None, None, None, 'GS Token', None, 'Desert Colossus'), - 'GS94': (None, None, None, 'GS Token', None, 'Desert Colossus'), - 'GS95': (None, None, None, 'GS Token', None, 'Desert Colossus'), - 'GS96': (None, None, None, 'GS Token', None, 'Spirit Temple'), - 'GS97': (None, None, None, 'GS Token', None, 'Spirit Temple'), - 'GS98': (None, None, None, 'GS Token', None, 'Spirit Temple'), - 'GS99': (None, None, None, 'GS Token', None, 'Spirit Temple'), - 'GS100': (None, None, None, 'GS Token', None, 'Spirit Temple')} +location_table = { + 'Kokiri Sword Chest': (0x20A6142, None, 0x04E0, 'Chest', 0x55, 'Kokiri Forest'), + 'Mido Chest Top Left': (0x2F7B08A, None, 0x59A0, 'Chest', 0x28, 'Kokiri Forest'), + 'Mido Chest Top Right': (0x2F7B09A, None, 0x59A1, 'Chest', 0x28, 'Kokiri Forest'), + 'Mido Chest Bottom Left': (0x2F7B0AA, None, 0x5982, 'Chest', 0x28, 'Kokiri Forest'), + 'Mido Chest Bottom Right': (0x2F7B0BA, None, 0x5903, 'Chest', 0x28, 'Kokiri Forest'), + 'Shield Grave Chest': (0x328B096, None, 0x5540, 'Chest', 0x40, 'the Graveyard'), + 'Heart Piece Grave Chest': (0x2D0A056, None, 0xA7C0, 'Chest', 0x3F, 'the Graveyard'), + 'Composer Grave Chest': (0x332D0EA, None, 0x8020, 'Chest', 0x41, 'the Graveyard'), + 'Death Mountain Bombable Chest': (0x223C3CA, 0x223C7B2, 0x5AA1, 'Chest', 0x60, 'Death Mountain Trail'), + 'Goron City Leftmost Maze Chest': (0x227C23A, 0x227C70A, 0x5AC0, 'Chest', 0x62, 'Goron City'), + 'Goron City Right Maze Chest': (0x227C24A, 0x227C71A, 0x5AA1, 'Chest', 0x62, 'Goron City'), + 'Goron City Left Maze Chest': (0x227C25A, 0x227C72A, 0x5AA2, 'Chest', 0x62, 'Goron City'), + 'Zoras Domain Torch Run': (0x2103166, None, 0xB7C0, 'Chest', 0x58, 'Zora\'s Domain'), + 'Hookshot Chest': (0x3063092, None, 0x1100, 'Chest', 0x48, 'the Graveyard'), + 'Gerudo Valley Hammer Rocks Chest': (0x213D676, None, 0x5AA0, 'Chest', 0x5A, 'Gerudo Valley'), + 'Gerudo Fortress Rooftop Chest': (0x21BD4AA, 0x21BD6EA, 0x07C0, 'Chest', 0x5D, 'Gerudo Fortress'), + 'Haunted Wasteland Structure Chest': (0x21E20DE, None, 0x8AA0, 'Chest', 0x5E, 'Haunted Wasteland'), + 'Redead Grotto Chest': (0x26CF076, None, 0x7ACA, 'Chest', 0x3E, 'Kakariko Village'), + 'Wolfos Grotto Chest': (0x26EB076, None, 0x7AB1, 'Chest', 0x3E, 'Sacred Forest Meadow'), + 'Silver Gauntlets Chest': (0x21A02DE, 0x21A06F2, 0x06AB, 'Chest', 0x5C, 'Desert Colossus'), + 'Mirror Shield Chest': (0x21A02CE, 0x21A06E2, 0x3569, 'Chest', 0x5C, 'Desert Colossus'), + 'Field West Castle Town Grotto Chest': (None, None, 0x00, 'Chest', 0x3E, 'Hyrule Field'), + 'Remote Southern Grotto Chest': (None, None, 0x02, 'Chest', 0x3E, 'Hyrule Field'), + 'Field Near Lake Outside Fence Grotto Chest': (None, None, 0x03, 'Chest', 0x3E, 'Hyrule Field'), + 'Kakariko Back Grotto Chest': (None, None, 0x08, 'Chest', 0x3E, 'Kakariko Village'), + 'Zora River Plateau Open Grotto Chest': (None, None, 0x09, 'Chest', 0x3E, 'Zora\'s River'), + 'Kokiri Forest Storms Grotto Chest': (None, None, 0x0C, 'Chest', 0x3E, 'Kokiri Forest'), + 'Lost Woods Generic Grotto Chest': (None, None, 0x14, 'Chest', 0x3E, 'the Lost Woods'), + 'Mountain Storms Grotto Chest': (None, None, 0x17, 'Chest', 0x3E, 'Death Mountain Trail'), + 'Top of Crater Grotto Chest': (None, None, 0x1A, 'Chest', 0x3E, 'Death Mountain Crater'), + 'Impa at Castle': (0x2E8E925, 0x2E8E925, 0x67, 'Song', 0x51, 'Hyrule Castle'), + 'Song from Malon': (0xD7EB53, 0xD7EBCF, 0x68, 'Song', 0x63, 'Lon Lon Ranch'), + 'Song from Composer Grave': (0x332A871, 0x332A871, 0x6A, 'Song', 0x41, 'the Graveyard'), + 'Song from Saria': (0x20B1DB1, 0x20B1DB1, 0x69, 'Song', 0x56, 'Sacred Forest Meadow'), + 'Song from Ocarina of Time': (0x252FC89, 0x252FC89, 0x6B, 'Song', 0x51, 'Hyrule Field'), + 'Song at Windmill': (0xE42C07, 0xE42B8B, 0x6C, 'Song', 0x48, 'Kakariko Village'), + 'Sheik Forest Song': (0x20B0809, 0x20B0809, 0x61, 'Song', 0x56, 'Sacred Forest Meadow'), + 'Sheik at Temple': (0x2531329, 0x2531329, 0x66, 'Song', 0x43, 'Temple of Time'), + 'Sheik in Crater': (0x224D7F1, 0x224D7F1, 0x62, 'Song', 0x61, 'Death Mountain Crater'), + 'Sheik in Ice Cavern': (0x2BEC889, 0x2BEC889, 0x63, 'Song', 0x09, 'Ice Cavern'), + 'Sheik in Kakariko': (0x2000FE1, 0x2000FE1, 0x65, 'Song', 0x52, 'Kakariko Village'), + 'Sheik at Colossus': (0x218C57D, 0x218C57D, 0x64, 'Song', 0x5C, 'Desert Colossus'), + 'Gift from Saria': (None, None, 0x3B, 'NPC', 0x5B, 'the Lost Woods'), + 'Malon Egg': (None, None, 0x47, 'NPC', 0x5F, 'Hyrule Castle'), + 'Zeldas Letter': (None, None, None, 'NPC', None, 'Hyrule Castle'), + 'Zelda': (0x3481400, None, 0x5A, 'NPC', 0x43, 'Temple of Time'), + 'Zoras Fountain Fairy Reward': (0x3481401, None, 0x5D, 'NPC', 0x3D, 'Zora\'s Fountain'), + 'Hyrule Castle Fairy Reward': (0x3481402, None, 0x5C, 'NPC', 0x3D, 'Hyrule Castle'), + 'Desert Colossus Fairy Reward': (0x3481403, None, 0x5E, 'NPC', 0x3D, 'Desert Colossus'), + 'Mountain Summit Fairy Reward': (0x3481404, None, 0x51, 'NPC', 0x3B, 'Death Mountain Trail'), + 'Crater Fairy Reward': (0x3481405, None, 0x52, 'NPC', 0x3B, 'Death Mountain Crater'), + 'Ganons Castle Fairy Reward': (0x3481406, None, 0x53, 'NPC', 0x3B, 'outside Ganon\'s Castle'), + 'Treasure Chest Game': (None, None, 0x0A, 'Chest', 0x10, 'the Market'), + 'Darunias Joy': (0xCF1BFF, None, 0x54, 'NPC', 0x62, 'Goron City'), + 'Diving Minigame': (0xE01A2B, 0xE01AA7, 0x37, 'NPC', 0x58, 'Zora\'s Domain'), + 'Child Fishing': (0xDCBFBF, None, 0x3E, 'NPC', 0x49, 'Lake Hylia'), + 'Adult Fishing': (0xDCC087, None, 0x38, 'NPC', 0x49, 'Lake Hylia'), + 'Diving in the Lab': (0xE2CB97, None, 0x3E, 'NPC', 0x38, 'Lake Hylia'), + 'Link the Goron': (0xED30EB, 0xED64F3, 0x2C, 'NPC', 0x62, 'Goron City'), + 'King Zora Thawed': (0xE56AD7, None, 0x2D, 'NPC', 0x58, 'Zora\'s Domain'), + 'Bombchu Bowling Bomb Bag': (0xE2F093, None, 0x34, 'NPC', 0x4B, 'the Market'), + 'Bombchu Bowling Piece of Heart': (0xE2F097, None, 0x3E, 'NPC', 0x4B, 'the Market'), + 'Dog Lady': (0xE65163, 0xE661BB, 0x3E, 'NPC', 0x35, 'the Market'), + 'Skull Kid': (0xDF0F33, 0xDF0E9B, 0x3E, 'NPC', 0x5B, 'the Lost Woods'), + 'Ocarina Memory Game': (0xDF264F, None, 0x76, 'NPC', 0x5B, 'the Lost Woods'), + '10 Gold Skulltula Reward': (0xEA7173, None, 0x45, 'NPC', 0x50, 'Kakariko Village'), + '20 Gold Skulltula Reward': (0xEA7175, None, 0x39, 'NPC', 0x50, 'Kakariko Village'), + '30 Gold Skulltula Reward': (0xEA7177, None, 0x46, 'NPC', 0x50, 'Kakariko Village'), + '40 Gold Skulltula Reward': (0xEA7179, None, 0x03, 'NPC', 0x50, 'Kakariko Village'), + '50 Gold Skulltula Reward': (0xEA717B, None, 0x3E, 'NPC', 0x50, 'Kakariko Village'), + 'Man on Roof': (0xE587E3, None, 0x3E, 'NPC', 0x52, 'Kakariko Village'), + 'Frog Ocarina Game': (0xDB13D3, None, 0x76, 'NPC', 0x54, 'Zora\'s River'), + 'Frogs in the Rain': (0xDB1387, None, 0x3E, 'NPC', 0x54, 'Zora\'s River'), + 'Horseback Archery 1000 Points': (0xE12B6F, 0xE12AA3, 0x3E, 'NPC', 0x5D, 'Gerudo Fortress'), + 'Horseback Archery 1500 Points': (0xE12BC3, 0xE12AFB, 0x30, 'NPC', 0x5D, 'Gerudo Fortress'), + 'Child Shooting Gallery': (0xD35EF3, None, 0x60, 'NPC', 0x42, 'the Market'), + 'Adult Shooting Gallery': (0xD35F5B, None, 0x30, 'NPC', 0x42, 'Kakariko Village'), + 'Target in Woods': (0xE59CDF, None, 0x60, 'NPC', 0x5B, 'the Lost Woods'), + 'Deku Theater Skull Mask': (0xEC9A87, None, 0x77, 'NPC', 0x3E, 'the Lost Woods'), + 'Deku Theater Mask of Truth': (0xEC9CE7, None, 0x7A, 'NPC', 0x3E, 'the Lost Woods'), + 'Anju as Adult': (0xE1EABB, None, 0x1D, 'NPC', 0x52, 'Kakariko Village'), + 'Biggoron': (0xED338F, 0xED650F, 0x57, 'NPC', 0x60, 'Death Mountain Trail'), + 'Anjus Chickens': (0xE1E7A7, None, 0x0F, 'NPC', 0x52, 'Kakariko Village'), + 'Talons Chickens': (0xCC14EB, None, 0x14, 'NPC', 0x4C, 'Lon Lon Ranch'), + '10 Big Poes': (0xEE6AEF, None, 0x0F, 'NPC', 0x4D, 'the Market'), + 'Rolling Goron as Child': (0xED296F, 0xED6503, 0x34, 'NPC', 0x62, 'Goron City'), + 'Lake Hylia Sun': (0xE9E1F2, None, 0x5B08, 'Chest', 0x57, 'Lake Hylia'), + 'Underwater Bottle': (0xDE10FB, None, 0x15, 'NPC', 0x57, 'Lake Hylia'), + 'Impa House Freestanding PoH': (None, None, 0x01, 'Collectable', 0x37, 'Kakariko Village'), + 'Tektite Grotto Freestanding PoH': (None, None, 0x01, 'Collectable', 0x3E, 'Hyrule Field'), + 'Windmill Freestanding PoH': (None, None, 0x01, 'Collectable', 0x48, 'Kakariko Village'), + 'Dampe Race Freestanding PoH': (None, None, 0x07, 'Collectable', 0x48, 'the Graveyard'), + 'Lon Lon Tower Freestanding PoH': (None, None, 0x01, 'Collectable', 0x4C, 'Lon Lon Ranch'), + 'Graveyard Freestanding PoH': (None, None, 0x04, 'Collectable', 0x53, 'the Graveyard'), + 'Gravedigging Tour': (None, None, 0x00, 'Collectable', 0x53, 'the Graveyard'), + 'Zora River Lower Freestanding PoH': (None, None, 0x04, 'Collectable', 0x54, 'Zora\'s River'), + 'Zora River Upper Freestanding PoH': (None, None, 0x0B, 'Collectable', 0x54, 'Zora\'s River'), + 'Lake Hylia Freestanding PoH': (None, None, 0x1E, 'Collectable', 0x57, 'Lake Hylia'), + 'Zoras Fountain Iceberg Freestanding PoH': (None, None, 0x01, 'Collectable', 0x59, 'Zora\'s Fountain'), + 'Zoras Fountain Bottom Freestanding PoH': (None, None, 0x14, 'Collectable', 0x59, 'Zora\'s Fountain'), + 'Gerudo Valley Waterfall Freestanding PoH': (None, None, 0x01, 'Collectable', 0x5A, 'Gerudo Valley'), + 'Gerudo Valley Crate Freestanding PoH': (None, None, 0x02, 'Collectable', 0x5A, 'Gerudo Valley'), + 'Colossus Freestanding PoH': (None, None, 0x0D, 'Collectable', 0x5C, 'Desert Colossus'), + 'DM Trail Freestanding PoH': (None, None, 0x1E, 'Collectable', 0x60, 'Death Mountain Trail'), + 'DM Crater Wall Freestanding PoH': (None, None, 0x02, 'Collectable', 0x61, 'Death Mountain Crater'), + 'DM Crater Volcano Freestanding PoH': (None, None, 0x08, 'Collectable', 0x61, 'Death Mountain Crater'), + 'Goron City Pot Freestanding PoH': (None, None, 0x1F, 'Collectable', 0x62, 'Goron City'), + 'Gerudo Fortress North F1 Carpenter': (None, None, 0x0C, 'Collectable', 0x0C, 'Gerudo Fortress'), + 'Gerudo Fortress North F2 Carpenter': (None, None, 0x0A, 'Collectable', 0x0C, 'Gerudo Fortress'), + 'Gerudo Fortress South F1 Carpenter': (None, None, 0x0E, 'Collectable', 0x0C, 'Gerudo Fortress'), + 'Gerudo Fortress South F2 Carpenter': (None, None, 0x0F, 'Collectable', 0x0C, 'Gerudo Fortress'), + 'Gerudo Fortress Membership Card': (None, None, 0x3A, 'NPC', 0x0C, 'Gerudo Fortress'), + 'Queen Gohma Heart': (None, None, 0x4F, 'BossHeart', 0x11, 'Deku Tree'), + 'King Dodongo Heart': (None, None, 0x4F, 'BossHeart', 0x12, 'Dodongo\'s Cavern'), + 'Barinade Heart': (None, None, 0x4F, 'BossHeart', 0x13, 'Jabu Jabu\'s Belly'), + 'Phantom Ganon Heart': (None, None, 0x4F, 'BossHeart', 0x14, 'Forest Temple'), + 'Volvagia Heart': (None, None, 0x4F, 'BossHeart', 0x15, 'Fire Temple'), + 'Morpha Heart': (None, None, 0x4F, 'BossHeart', 0x16, 'Water Temple'), + 'Twinrova Heart': (None, None, 0x4F, 'BossHeart', 0x17, 'Spirit Temple'), + 'Bongo Bongo Heart': (None, None, 0x4F, 'BossHeart', 0x18, 'Shadow Temple'), + 'Magic Bean Salesman': (None, None, None, 'Event', None, 'Zora\'s River'), + 'King Zora Moves': (None, None, None, 'Event', None, 'Zora\'s Domain'), + 'Ocarina of Time': (None, None, 0x0C, 'NPC', 0x51, 'Hyrule Field'), + 'Master Sword Pedestal': (None, None, None, 'Event', None, 'Temple of Time'), + 'Epona': (None, None, None, 'Event', None, 'Lon Lon Ranch'), + 'Deku Baba Sticks': (None, None, None, 'Event', None, 'Kokiri Forest'), + 'Deku Baba Nuts': (None, None, None, 'Event', None, 'Kokiri Forest'), + 'Goron City Stick Pot': (None, None, None, 'Event', None, 'Goron City'), + 'Bottom of the Well Stick Pot': (None, None, None, 'Event', None, 'Bottom of the Well'), + 'Zoras Domain Stick Pot': (None, None, None, 'Event', None, 'Zora\'s Domain'), + 'Zoras Domain Nut Pot': (None, None, None, 'Event', None, 'Zora\'s Domain'), + 'Spirit Temple Nut Crate': (None, None, None, 'Event', None, 'Spirit Temple'), + 'Gerudo Fortress Carpenter Rescue': (None, None, None, 'Event', None, 'Gerudo Fortress'), + 'Ganons Castle Forest Trial Clear': (None, None, None, 'Event', None, 'Ganon\'s Castle'), + 'Ganons Castle Fire Trial Clear': (None, None, None, 'Event', None, 'Ganon\'s Castle'), + 'Ganons Castle Water Trial Clear': (None, None, None, 'Event', None, 'Ganon\'s Castle'), + 'Ganons Castle Shadow Trial Clear': (None, None, None, 'Event', None, 'Ganon\'s Castle'), + 'Ganons Castle Spirit Trial Clear': (None, None, None, 'Event', None, 'Ganon\'s Castle'), + 'Ganons Castle Light Trial Clear': (None, None, None, 'Event', None, 'Ganon\'s Castle'), + + # Deku Tree vanilla + 'Deku Tree Lobby Chest': (0x24A7146, None, 0x0823, 'Chest', 0x00, 'Deku Tree'), + 'Deku Tree Slingshot Chest': (0x24C20C6, None, 0x00A1, 'Chest', 0x00, 'Deku Tree'), + 'Deku Tree Slingshot Room Side Chest': (0x24C20D6, None, 0x5905, 'Chest', 0x00, 'Deku Tree'), + 'Deku Tree Compass Chest': (0x25040D6, None, 0x0802, 'Chest', 0x00, 'Deku Tree'), + 'Deku Tree Compass Room Side Chest': (0x25040E6, None, 0x5906, 'Chest', 0x00, 'Deku Tree'), + 'Deku Tree Basement Chest': (0x24C8166, None, 0x5904, 'Chest', 0x00, 'Deku Tree'), + # Deku Tree MQ + 'Deku Tree MQ Lobby Chest': (0, None, 0x0823, 'Chest', 0x00, 'Deku Tree'), + 'Deku Tree MQ Compass Chest': (0, None, 0x0801, 'Chest', 0x00, 'Deku Tree'), + 'Deku Tree MQ Slingshot Chest': (0, None, 0x10A6, 'Chest', 0x00, 'Deku Tree'), + 'Deku Tree MQ Slingshot Room Back Chest': (0, None, 0x8522, 'Chest', 0x00, 'Deku Tree'), + 'Deku Tree MQ Basement Chest': (0, None, 0x8524, 'Chest', 0x00, 'Deku Tree'), + 'Deku Tree MQ Before Spinning Log Chest': (0, None, 0x5905, 'Chest', 0x00, 'Deku Tree'), + 'Deku Tree MQ After Spinning Log Chest': (0, None, 0x5AA0, 'Chest', 0x00, 'Deku Tree'), + + # Dodongo's Cavern shared + 'Chest Above King Dodongo': (0x2EB00BA, None, 0x5020, 'Chest', 0x12, 'Dodongo\'s Cavern'), + # Dodongo's Cavern vanilla + 'Dodongos Cavern Map Chest': (0x1F2819E, None, 0x0828, 'Chest', 0x01, 'Dodongo\'s Cavern'), + 'Dodongos Cavern Compass Chest': (0x1FAF0AA, None, 0x0805, 'Chest', 0x01, 'Dodongo\'s Cavern'), + 'Dodongos Cavern Bomb Flower Platform': (0x1F890DE, None, 0x59C6, 'Chest', 0x01, 'Dodongo\'s Cavern'), + 'Dodongos Cavern Bomb Bag Chest': (0x1F890CE, None, 0x0644, 'Chest', 0x01, 'Dodongo\'s Cavern'), + 'Dodongos Cavern End of Bridge Chest': (0x1F281CE, None, 0x552A, 'Chest', 0x01, 'Dodongo\'s Cavern'), + # Dodongo's Cavern MQ + 'Dodongos Cavern MQ Map Chest': (0, None, 0x0820, 'Chest', 0x01, 'Dodongo\'s Cavern'), + 'Dodongos Cavern MQ Bomb Bag Chest': (0, None, 0x0644, 'Chest', 0x01, 'Dodongo\'s Cavern'), + 'Dodongos Cavern MQ Compass Chest': (0, None, 0x1805, 'Chest', 0x01, 'Dodongo\'s Cavern'), + 'Dodongos Cavern MQ Larva Room Chest': (0, None, 0x7522, 'Chest', 0x01, 'Dodongo\'s Cavern'), + 'Dodongos Cavern MQ Torch Puzzle Room Chest': (0, None, 0x59A3, 'Chest', 0x01, 'Dodongo\'s Cavern'), + 'Dodongos Cavern MQ Under Grave Chest': (0, None, 0x5541, 'Chest', 0x01, 'Dodongo\'s Cavern'), + + # Jabu Jabu's Belly vanilla + 'Boomerang Chest': (0x278A0BA, None, 0x10C1, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + 'Jabu Jabus Belly Map Chest': (0x278E08A, None, 0x1822, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + 'Jabu Jabus Belly Compass Chest': (0x279608A, None, 0xB804, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + # Jabu Jabu's Belly MQ + 'Jabu Jabus Belly MQ Entry Side Chest': (0, None, 0x8045, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + 'Jabu Jabus Belly MQ Map Chest': (0, None, 0xB823, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + 'Jabu Jabus Belly MQ Second Room Lower Chest': (0, None, 0x5042, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + 'Jabu Jabus Belly MQ Compass Chest': (0, None, 0xB800, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + 'Jabu Jabus Belly MQ Second Room Upper Chest': (0, None, 0x8907, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + 'Jabu Jabus Belly MQ Basement North Chest': (0, None, 0x8048, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + 'Jabu Jabus Belly MQ Basement South Chest': (0, None, 0x8064, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + 'Jabu Jabus Belly MQ Near Boss Chest': (0, None, 0x852A, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + 'Jabu Jabus Belly MQ Falling Like Like Room Chest': (0, None, 0x70E9, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + 'Jabu Jabus Belly MQ Boomerang Room Small Chest': (0, None, 0x5041, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + 'MQ Boomerang Chest': (0, None, 0x10C6, 'Chest', 0x02, 'Jabu Jabu\'s Belly'), + + # Forest Temple vanilla + 'Forest Temple First Chest': (0x23E5092, None, 0x5843, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple Chest Behind Lobby': (0x2415082, None, 0x7840, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple Well Chest': (0x244A062, None, 0x5849, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple Map Chest': (0x2455076, None, 0x1821, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple Outside Hookshot Chest': (0x241F0D6, None, 0x5905, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple Falling Room Chest': (0x247E09E, None, 0x5947, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple Block Push Chest': (0x245B096, None, 0x8964, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple Boss Key Chest': (0xCB0DC2, None, 0x27EE, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple Floormaster Chest': (0x2490072, None, 0x7842, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple Bow Chest': (0x2415092, None, 0xB08C, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple Red Poe Chest': (0x246607E, None, 0x784D, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple Blue Poe Chest': (0x246F07E, None, 0x180F, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple Near Boss Chest': (0x2486082, None, 0x592B, 'Chest', 0x03, 'Forest Temple'), + # Forest Temple MQ + 'Forest Temple MQ First Chest': (0, None, 0x8843, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple MQ Chest Behind Lobby': (0, None, 0x7840, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple MQ Bow Chest': (0, None, 0xB08C, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple MQ NE Outdoors Lower Chest': (0, None, 0x5841, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple MQ NE Outdoors Upper Chest': (0, None, 0x5845, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple MQ Well Chest': (0, None, 0x5849, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple MQ Map Chest': (0, None, 0x182D, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple MQ Compass Chest': (0, None, 0x180F, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple MQ Falling Room Chest': (0, None, 0x8926, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple MQ Near Boss Chest': (0, None, 0x592B, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple MQ Redead Chest': (0, None, 0x7842, 'Chest', 0x03, 'Forest Temple'), + 'Forest Temple MQ Boss Key Chest': (0, None, 0x27EE, 'Chest', 0x03, 'Forest Temple'), # This needs tested to see if it has changed from vanilla. + + # Fire Temple vanilla + 'Fire Temple Chest Near Boss': (0x230808A, None, 0x5841, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Fire Dancer Chest': (0x2318082, None, 0x7CC0, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Boss Key Chest': (0x238A0D6, None, 0x27EC, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Big Lava Room Bombable Chest': (0x23AD076, None, 0x5842, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Big Lava Room Open Chest': (0x239D0A6, None, 0x5844, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Boulder Maze Lower Chest': (0x2323152, None, 0x5843, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Boulder Maze Upper Chest': (0x2323182, None, 0x5846, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Boulder Maze Side Room': (0x23B40B2, None, 0x5848, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Boulder Maze Bombable Pit': (0x231B0E2, None, 0x584B, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Scarecrow Chest': (0x2339082, None, 0x5ACD, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Map Chest': (0x237E0C2, None, 0x082A, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Compass Chest': (0x23C1082, None, 0x0807, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Highest Goron Chest': (0x2365066, None, 0x5849, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple Megaton Hammer Chest': (0x236C102, None, 0x01A5, 'Chest', 0x04, 'Fire Temple'), + # Fire Temple MQ + 'Fire Temple MQ Chest Near Boss': (0, None, 0x5847, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple MQ Megaton Hammer Chest': (0, None, 0x11A0, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple MQ Compass Chest': (0, None, 0x080B, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple MQ Maze Lower Chest': (0, None, 0x5CC3, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple MQ Maze Upper Chest': (0, None, 0x5CE6, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple MQ West Tower Top Chest': (0, None, 0x5845, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple MQ Entrance Hallway Small Chest': (0, None, 0x7542, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple MQ Map Chest': (0, None, 0x082C, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple MQ Boss Key Chest': (0, None, 0x27E4, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple MQ Big Lava Room Bombable Chest': (0, None, 0x5841, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple MQ Maze Side Room': (0, None, 0x5848, 'Chest', 0x04, 'Fire Temple'), + 'Fire Temple MQ Freestanding Key': (None, None, 0x1C, 'Collectable', 0x04, 'Fire Temple'), + + # Water Temple vanilla + 'Water Temple Map Chest': (0x26690A6, None, 0x1822, 'Chest', 0x05, 'Water Temple'), + 'Water Temple Compass Chest': (0x25FC0D2, None, 0x0809, 'Chest', 0x05, 'Water Temple'), + 'Water Temple Torches Chest': (0x26640A6, None, 0x7841, 'Chest', 0x05, 'Water Temple'), + 'Water Temple Dragon Chest': (0x261F0BA, None, 0x584A, 'Chest', 0x05, 'Water Temple'), + 'Water Temple Central Bow Target Chest': (0x266D072, None, 0x5848, 'Chest', 0x05, 'Water Temple'), + 'Water Temple Central Pillar Chest': (0x25EF0D6, None, 0x5846, 'Chest', 0x05, 'Water Temple'), + 'Water Temple Cracked Wall Chest': (0x265B0A6, None, 0x5840, 'Chest', 0x05, 'Water Temple'), + 'Water Temple Boss Key Chest': (0x2657066, None, 0x27E5, 'Chest', 0x05, 'Water Temple'), + 'Water Temple Dark Link Chest': (0x261907A, None, 0x0127, 'Chest', 0x05, 'Water Temple'), + 'Water Temple River Chest': (0x26740DE, None, 0x5843, 'Chest', 0x05, 'Water Temple'), + # Water Temple MQ + 'Water Temple MQ Central Pillar Chest': (0, None, 0x8846, 'Chest', 0x05, 'Water Temple'), + 'Water Temple MQ Boss Key Chest': (0, None, 0x27E5, 'Chest', 0x05, 'Water Temple'), + 'Water Temple MQ Longshot Chest': (0, None, 0xB120, 'Chest', 0x05, 'Water Temple'), + 'Water Temple MQ Compass Chest': (0, None, 0x1801, 'Chest', 0x05, 'Water Temple'), + 'Water Temple MQ Map Chest': (0, None, 0xB822, 'Chest', 0x05, 'Water Temple'), + 'Water Temple MQ Freestanding Key': (None, None, 0x01, 'Collectable', 0x05, 'Water Temple'), + + # Spirit Temple vanilla + 'Spirit Temple Child Left Chest': (0x2B190BA, None, 0x5528, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Child Right Chest': (0x2B13182, None, 0x8840, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Compass Chest': (0x2B6B08A, None, 0x3804, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Early Adult Right Chest': (0x2B6207A, None, 0x5847, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple First Mirror Right Chest': (0x2B700C6, None, 0x890D, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple First Mirror Left Chest': (0x2B700D6, None, 0x8F8E, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Map Chest': (0x2B25126, None, 0xB823, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Child Climb East Chest': (0x2B1D122, None, 0x8066, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Child Climb North Chest': (0x2B1D132, None, 0x852C, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Sun Block Room Chest': (0x2B481B2, None, 0x8841, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Statue Hand Chest': (0x2B25136, None, 0x8842, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple NE Main Room Chest': (0x2B25146, None, 0x888F, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Near Four Armos Chest': (0x2B9F076, None, 0x5845, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Hallway Left Invisible Chest': (0x2B900B6, None, 0x6914, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Hallway Right Invisible Chest': (0x2B900C6, None, 0x6915, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Boss Key Chest': (0x2BA4162, None, 0x27EA, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple Topmost Chest': (0x2BCF0FE, None, 0x8CF2, 'Chest', 0x06, 'Spirit Temple'), + # Spirit Temple MQ + 'Spirit Temple MQ Entrance Front Left Chest': (0, None, 0x507A, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Entrance Back Right Chest': (0, None, 0x807F, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Entrance Front Right Chest': (0, None, 0x885B, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Entrance Back Left Chest': (0, None, 0x885E, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Child Center Chest': (0, None, 0x885D, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Map Chest': (0, None, 0x0820, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Child Left Chest': (0, None, 0x7848, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Child Climb North Chest': (0, None, 0x7066, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Child Climb South Chest': (0, None, 0x884C, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Compass Chest': (0, None, 0xB803, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Lower NE Main Room Chest': (0, None, 0x888F, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Upper NE Main Room Chest': (0, None, 0x6902, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Silver Block Hallway Chest': (0, None, 0x885C, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Sun Block Room Chest': (0, None, 0x8901, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Lower Adult Right Chest': (0, None, 0x5AA7, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Lower Adult Left Chest': (0, None, 0x7AA4, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Beamos Room Chest': (0, None, 0x7979, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Ice Trap Chest': (0, None, 0x5F98, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Boss Key Chest': (0, None, 0x27E5, 'Chest', 0x06, 'Spirit Temple'), + 'Spirit Temple MQ Mirror Puzzle Invisible Chest': (0, None, 0x6852, 'Chest', 0x06, 'Spirit Temple'), + + # Shadow Temple vanilla + 'Shadow Temple Map Chest': (0x27CC0AA, None, 0x1821, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Hover Boots Chest': (0x27DC0CA, None, 0x15E7, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Compass Chest': (0x27EC09E, None, 0x1803, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Early Silver Rupee Chest': (0x27E40F6, None, 0x5842, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Invisible Blades Visible Chest': (0x282212A, None, 0x588C, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Invisible Blades Invisible Chest': (0x282211A, None, 0x6976, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Falling Spikes Lower Chest': (0x2801132, None, 0x5945, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Falling Spikes Upper Chest': (0x2801142, None, 0x5886, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Falling Spikes Switch Chest': (0x2801122, None, 0x8844, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Invisible Spikes Chest': (0x28090EE, None, 0x7889, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Wind Hint Chest': (0x283609A, None, 0x6955, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple After Wind Enemy Chest': (0x28390FE, None, 0x7888, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple After Wind Hidden Chest': (0x28390EE, None, 0x6854, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Spike Walls Left Chest': (0x28130B6, None, 0x588A, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Boss Key Chest': (0x28130A6, None, 0x27EB, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Hidden Floormaster Chest': (0x282508A, None, 0x784D, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple Freestanding Key': (None, None, 0x01, 'Collectable', 0x07, 'Shadow Temple'), + # Shadow Temple MQ + 'Shadow Temple MQ Compass Chest': (0, None, 0x1801, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Hover Boots Chest': (0, None, 0x15E7, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Early Gibdos Chest': (0, None, 0x0822, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Map Chest': (0, None, 0x7843, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Beamos Silver Rupees Chest': (0, None, 0x892F, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Falling Spikes Switch Chest': (0, None, 0x8844, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Falling Spikes Lower Chest': (0, None, 0x5945, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Falling Spikes Upper Chest': (0, None, 0x5886, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Invisible Spikes Chest': (0, None, 0x7889, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Boss Key Chest': (0, None, 0x27EB, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Spike Walls Left Chest': (0, None, 0x588A, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Stalfos Room Chest': (0, None, 0x79D0, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Invisible Blades Invisible Chest': (0, None, 0x6856, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Invisible Blades Visible Chest': (0, None, 0x588C, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Bomb Flower Chest': (0, None, 0x794D, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Wind Hint Chest': (0, None, 0x6855, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ After Wind Hidden Chest': (0, None, 0x6934, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ After Wind Enemy Chest': (0, None, 0x7888, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Near Ship Invisible Chest': (0, None, 0x684E, 'Chest', 0x07, 'Shadow Temple'), + 'Shadow Temple MQ Freestanding Key': (None, None, 0x06, 'Collectable', 0x07, 'Shadow Temple'), + + # Bottom of the Well vanilla + 'Bottom of the Well Front Left Hidden Wall': (0x32D317E, None, 0x5848, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Front Center Bombable': (0x32D30FE, None, 0x5062, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Right Bottom Hidden Wall': (0x32D314E, None, 0x5845, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Center Large Chest': (0x32D30EE, None, 0x0801, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Center Small Chest': (0x32D31AE, None, 0x504E, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Back Left Bombable': (0x32D313E, None, 0x5C84, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Defeat Boss': (0x32FB0AA, None, 0x1143, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Invisible Chest': (0x32FB0BA, None, 0x6AD4, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Underwater Front Chest': (0x32D31BE, None, 0x5CD0, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Underwater Left Chest': (0x32D318E, None, 0x5909, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Basement Chest': (0x32E9252, None, 0x0827, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Locked Pits': (0x32F90AA, None, 0x552A, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Behind Right Grate': (0x32D319E, None, 0x554C, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well Freestanding Key': (None, None, 0x01, 'Collectable', 0x08, 'Bottom of the Well'), + # Bottom of the Well MQ + 'Bottom of the Well MQ Map Chest': (0, None, 0x0823, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well MQ Lens Chest': (0, None, 0xB141, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well MQ Compass Chest': (0, None, 0x1802, 'Chest', 0x08, 'Bottom of the Well'), + 'Bottom of the Well MQ Dead Hand Freestanding Key': (None, None, 0x02, 'Collectable', 0x08, 'Bottom of the Well'), + 'Bottom of the Well MQ East Inner Room Freestanding Key': (None, None, 0x01, 'Collectable', 0x08, 'Bottom of the Well'), + + # Ice Cavern vanilla + 'Ice Cavern Map Chest': (0x2C4016A, None, 0x0820, 'Chest', 0x09, 'Ice Cavern'), + 'Ice Cavern Compass Chest': (0x2C4E236, None, 0x0801, 'Chest', 0x09, 'Ice Cavern'), + 'Ice Cavern Iron Boots Chest': (0x2C380A2, None, 0x15C2, 'Chest', 0x09, 'Ice Cavern'), + 'Ice Cavern Freestanding PoH': (None, None, 0x01, 'Collectable', 0x09, 'Ice Cavern'), + # Ice Cavern MQ + 'Ice Cavern MQ Iron Boots Chest': (0, None, 0x15C2, 'Chest', 0x09, 'Ice Cavern'), + 'Ice Cavern MQ Compass Chest': (0, None, 0x0800, 'Chest', 0x09, 'Ice Cavern'), + 'Ice Cavern MQ Map Chest': (0, None, 0xB821, 'Chest', 0x09, 'Ice Cavern'), + 'Ice Cavern MQ Freestanding PoH': (None, None, 0x01, 'Collectable', 0x09, 'Ice Cavern'), + + # Gerudo Training Grounds vanilla + 'Gerudo Training Grounds Lobby Left Chest': (0x28870CA, None, 0x8893, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Lobby Right Chest': (0x28870BA, None, 0x8947, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Stalfos Chest': (0x28970AA, None, 0x8840, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Beamos Chest': (0x28C715E, None, 0x8841, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Hidden Ceiling Chest': (0x28D010E, None, 0x584B, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Maze Path First Chest': (0x28D00CE, None, 0x5AA6, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Maze Path Second Chest': (0x28D00FE, None, 0x59CA, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Maze Path Third Chest': (0x28D00EE, None, 0x5969, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Maze Path Final Chest': (0x28D011E, None, 0x0B2C, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Maze Right Central Chest': (0x28D00BE, None, 0x5D45, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Maze Right Side Chest': (0x28D00DE, None, 0x5968, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Underwater Silver Rupee Chest': (0x28D91D6, None, 0x884D, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Hammer Room Clear Chest': (0x28B91AE, None, 0x7952, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Hammer Room Switch Chest': (0x28B919E, None, 0x5850, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Eye Statue Chest': (0x28AE09E, None, 0x8843, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Near Scarecrow Chest': (0x28D00AE, None, 0x5844, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Before Heavy Block Chest': (0x28A611E, None, 0x7971, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Heavy Block First Chest': (0x28DD0BE, None, 0x7ACF, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Heavy Block Second Chest': (0x28DD0AE, None, 0x788E, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Heavy Block Third Chest': (0x28DD08E, None, 0x6854, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Heavy Block Fourth Chest': (0x28DD09E, None, 0x5F82, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds Freestanding Key': (None, None, 0x01, 'Collectable', 0x0B, 'Gerudo Training Grounds'), + # Gerudo Training Grounds MQ + 'Gerudo Training Grounds MQ Lobby Right Chest': (0, None, 0x5D47, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Lobby Left Chest': (0, None, 0x5953, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ First Iron Knuckle Chest': (0, None, 0x89A0, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Before Heavy Block Chest': (0, None, 0x7951, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Eye Statue Chest': (0, None, 0x8063, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Flame Circle Chest': (0, None, 0x884E, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Second Iron Knuckle Chest': (0, None, 0x7952, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Dinolfos Chest': (0, None, 0x8841, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Ice Arrows Chest': (0, None, 0xBB24, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Maze Right Central Chest': (0, None, 0x5885, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Maze Path First Chest': (0, None, 0x5986, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Maze Right Side Chest': (0, None, 0x5E48, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Maze Path Third Chest': (0, None, 0x5E49, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Maze Path Second Chest': (0, None, 0x59CA, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Hidden Ceiling Chest': (0, None, 0x5AAB, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Underwater Silver Rupee Chest': (0, None, 0x884D, 'Chest', 0x0B, 'Gerudo Training Grounds'), + 'Gerudo Training Grounds MQ Heavy Block Chest': (0, None, 0x7AA2, 'Chest', 0x0B, 'Gerudo Training Grounds'), + + # Ganon's Castle shared + 'Ganons Tower Boss Key Chest': (0x2F040EE, None, 0x27EB, 'Chest', 0x0A, 'Ganon\'s Tower'), + # Ganon's Castle vanilla + 'Ganons Castle Forest Trial Chest': (0x31F106E, None, 0x7889, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Water Trial Left Chest': (0x31D7236, None, 0x5F87, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Water Trial Right Chest': (0x31D7226, None, 0x5906, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Shadow Trial First Chest': (0x32350CA, None, 0x5888, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Shadow Trial Second Chest': (0x32350BA, None, 0x36C5, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Spirit Trial First Chest': (0x3268132, None, 0x8D72, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Spirit Trial Second Chest': (0x3268142, None, 0x6954, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Light Trial First Left Chest': (0x321B11E, None, 0x588C, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Light Trial Second Left Chest': (0x321B10E, None, 0x5F8B, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Light Trial Third Left Chest': (0x321B12E, None, 0x590D, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Light Trial First Right Chest': (0x321B13E, None, 0x5F8E, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Light Trial Second Right Chest': (0x321B0FE, None, 0x596A, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Light Trial Third Right Chest': (0x321B14E, None, 0x5F8F, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Light Trail Invisible Enemies Chest': (0x321B15E, None, 0x7850, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle Light Trial Lullaby Chest': (0x321B17E, None, 0x8851, 'Chest', 0x0D, 'Ganon\'s Castle'), + # Ganon's Castle MQ + 'Ganons Castle MQ Water Trial Chest': (0, None, 0x59C1, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle MQ Forest Trial First Chest': (0, None, 0x8942, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle MQ Forest Trial Second Chest': (0, None, 0x8023, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle MQ Light Trial Lullaby Chest': (0, None, 0x8904, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle MQ Shadow Trial First Chest': (0, None, 0x8940, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle MQ Shadow Trial Second Chest': (0, None, 0x8845, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle MQ Spirit Trial Golden Gauntlets Chest': (0, None, 0xB6C6, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle MQ Spirit Trial Sun Back Right Chest': (0, None, 0x8907, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle MQ Spirit Trial Sun Back Left Chest': (0, None, 0x8848, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle MQ Spirit Trial Sun Front Left Chest': (0, None, 0x8909, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle MQ Spirit Trial First Chest': (0, None, 0x506A, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle MQ Spirit Trial Second Chest': (0, None, 0x6954, 'Chest', 0x0D, 'Ganon\'s Castle'), + 'Ganons Castle MQ Forest Trial Freestanding Key': (None, None, 0x01, 'Collectable', 0x0D, 'Ganon\'s Castle'), + + # I don't think the addresses matter for Link's Pocket anymore, but they can't be None for some reason + 'Links Pocket': (0x34806FB, 0x34806FF, None, 'Boss', None, 'Link\'s Pocket'), + 'Queen Gohma': (0xCA315F, 0x2079571, 0x6C, 'Boss', None, 'Deku Tree'), + 'King Dodongo': (0xCA30DF, 0x2223309, 0x6D, 'Boss', None, 'Dodongo\'s Cavern'), + 'Barinade': (0xCA36EB, 0x2113C19, 0x6E, 'Boss', None, 'Jabu Jabu\'s Belly'), + 'Phantom Ganon': (0xCA3D07, 0xD4ED79, 0x66, 'Boss', None, 'Shadow Temple'), + 'Volvagia': (0xCA3D93, 0xD10135, 0x67, 'Boss', None, 'Fire Temple'), + 'Morpha': (0xCA3E1F, 0xD5A3A9, 0x68, 'Boss', None, 'Water Temple'), + 'Twinrova': (0xCA3EB3, 0xD39FF1, 0x69, 'Boss', None, 'Spirit Temple'), + 'Bongo Bongo': (0xCA3F43, 0xD13E19, 0x6A, 'Boss', None, 'Shadow Temple'), + 'Ganon': (None, None, None, 'Boss', None, 'Ganon\'s Castle'), + # note that the scene for skulltulas is not the actual scene the token appears in + # rather, it is the index of the grouping used when storing skulltula collection + # for example, zora river, zora's domain, and zora fountain are all a single 'scene' for skulltulas + 'GS Deku Tree Basement Back Room': (None, None, 0x01, 'GS Token', 0x00, 'Deku Tree'), + 'GS Deku Tree Basement Gate': (None, None, 0x02, 'GS Token', 0x00, 'Deku Tree'), + 'GS Deku Tree Basement Vines': (None, None, 0x04, 'GS Token', 0x00, 'Deku Tree'), + 'GS Deku Tree Compass Room': (None, None, 0x08, 'GS Token', 0x00, 'Deku Tree'), + + 'GS Deku Tree MQ Lobby': (None, None, 0x02, 'GS Token', 0x00, 'Deku Tree'), + 'GS Deku Tree MQ Compass Room': (None, None, 0x08, 'GS Token', 0x00, 'Deku Tree'), + 'GS Deku Tree MQ Basement Ceiling': (None, None, 0x04, 'GS Token', 0x00, 'Deku Tree'), + 'GS Deku Tree MQ Basement Back Room': (None, None, 0x01, 'GS Token', 0x00, 'Deku Tree'), + + 'GS Dodongo\'s Cavern Vines Above Stairs': (None, None, 0x01, 'GS Token', 0x01, 'Dodongo\'s Cavern'), + 'GS Dodongo\'s Cavern Scarecrow': (None, None, 0x02, 'GS Token', 0x01, 'Dodongo\'s Cavern'), + 'GS Dodongo\'s Cavern Alcove Above Stairs': (None, None, 0x04, 'GS Token', 0x01, 'Dodongo\'s Cavern'), + 'GS Dodongo\'s Cavern Back Room': (None, None, 0x08, 'GS Token', 0x01, 'Dodongo\'s Cavern'), + 'GS Dodongo\'s Cavern East Side Room': (None, None, 0x10, 'GS Token', 0x01, 'Dodongo\'s Cavern'), + + 'GS Dodongo\'s Cavern MQ Scrub Room': (None, None, 0x02, 'GS Token', 0x01, 'Dodongo\'s Cavern'), + 'GS Dodongo\'s Cavern MQ Song of Time Block Room': (None, None, 0x08, 'GS Token', 0x01, 'Dodongo\'s Cavern'), + 'GS Dodongo\'s Cavern MQ Lizalfos Room': (None, None, 0x04, 'GS Token', 0x01, 'Dodongo\'s Cavern'), + 'GS Dodongo\'s Cavern MQ Larva Room': (None, None, 0x10, 'GS Token', 0x01, 'Dodongo\'s Cavern'), + 'GS Dodongo\'s Cavern MQ Back Area': (None, None, 0x01, 'GS Token', 0x01, 'Dodongo\'s Cavern'), + + 'GS Jabu Jabu Lobby Basement Lower': (None, None, 0x01, 'GS Token', 0x02, 'Jabu Jabu\'s Belly'), + 'GS Jabu Jabu Lobby Basement Upper': (None, None, 0x02, 'GS Token', 0x02, 'Jabu Jabu\'s Belly'), + 'GS Jabu Jabu Near Boss': (None, None, 0x04, 'GS Token', 0x02, 'Jabu Jabu\'s Belly'), + 'GS Jabu Jabu Water Switch Room': (None, None, 0x08, 'GS Token', 0x02, 'Jabu Jabu\'s Belly'), + + 'GS Jabu Jabu MQ Tailpasaran Room': (None, None, 0x04, 'GS Token', 0x02, 'Jabu Jabu\'s Belly'), + 'GS Jabu Jabu MQ Invisible Enemies Room': (None, None, 0x08, 'GS Token', 0x02, 'Jabu Jabu\'s Belly'), + 'GS Jabu Jabu MQ Boomerang Room': (None, None, 0x01, 'GS Token', 0x02, 'Jabu Jabu\'s Belly'), + 'GS Jabu Jabu MQ Near Boss': (None, None, 0x02, 'GS Token', 0x02, 'Jabu Jabu\'s Belly'), + + 'GS Forest Temple Outdoor East': (None, None, 0x01, 'GS Token', 0x03, 'Forest Temple'), + 'GS Forest Temple First Room': (None, None, 0x02, 'GS Token', 0x03, 'Forest Temple'), + 'GS Forest Temple Outdoor West': (None, None, 0x04, 'GS Token', 0x03, 'Forest Temple'), + 'GS Forest Temple Lobby': (None, None, 0x08, 'GS Token', 0x03, 'Forest Temple'), + 'GS Forest Temple Basement': (None, None, 0x10, 'GS Token', 0x03, 'Forest Temple'), + + 'GS Forest Temple MQ First Hallway': (None, None, 0x02, 'GS Token', 0x03, 'Forest Temple'), + 'GS Forest Temple MQ Block Push Room': (None, None, 0x10, 'GS Token', 0x03, 'Forest Temple'), + 'GS Forest Temple MQ Outdoor East': (None, None, 0x01, 'GS Token', 0x03, 'Forest Temple'), + 'GS Forest Temple MQ Outdoor West': (None, None, 0x04, 'GS Token', 0x03, 'Forest Temple'), + 'GS Forest Temple MQ Well': (None, None, 0x08, 'GS Token', 0x03, 'Forest Temple'), + + 'GS Fire Temple Song of Time Room': (None, None, 0x01, 'GS Token', 0x04, 'Fire Temple'), + 'GS Fire Temple Basement': (None, None, 0x02, 'GS Token', 0x04, 'Fire Temple'), + 'GS Fire Temple Unmarked Bomb Wall': (None, None, 0x04, 'GS Token', 0x04, 'Fire Temple'), + 'GS Fire Temple East Tower Top': (None, None, 0x08, 'GS Token', 0x04, 'Fire Temple'), + 'GS Fire Temple East Tower Climb': (None, None, 0x10, 'GS Token', 0x04, 'Fire Temple'), + + 'GS Fire Temple MQ Above Fire Wall Maze': (None, None, 0x02, 'GS Token', 0x04, 'Fire Temple'), + 'GS Fire Temple MQ Fire Wall Maze Center': (None, None, 0x08, 'GS Token', 0x04, 'Fire Temple'), + 'GS Fire Temple MQ Big Lava Room': (None, None, 0x01, 'GS Token', 0x04, 'Fire Temple'), + 'GS Fire Temple MQ Fire Wall Maze Side Room': (None, None, 0x10, 'GS Token', 0x04, 'Fire Temple'), + 'GS Fire Temple MQ East Tower Top': (None, None, 0x04, 'GS Token', 0x04, 'Fire Temple'), + + 'GS Water Temple South Basement': (None, None, 0x01, 'GS Token', 0x05, 'Water Temple'), + 'GS Water Temple Falling Platform Room': (None, None, 0x02, 'GS Token', 0x05, 'Water Temple'), + 'GS Water Temple Central Room': (None, None, 0x04, 'GS Token', 0x05, 'Water Temple'), + 'GS Water Temple Near Boss Key Chest': (None, None, 0x08, 'GS Token', 0x05, 'Water Temple'), + 'GS Water Temple Serpent River': (None, None, 0x10, 'GS Token', 0x05, 'Water Temple'), + + 'GS Water Temple MQ Before Upper Water Switch': (None, None, 0x04, 'GS Token', 0x05, 'Water Temple'), + 'GS Water Temple MQ North Basement': (None, None, 0x08, 'GS Token', 0x05, 'Water Temple'), + 'GS Water Temple MQ Lizalfos Hallway': (None, None, 0x01, 'GS Token', 0x05, 'Water Temple'), + 'GS Water Temple MQ Serpent River': (None, None, 0x02, 'GS Token', 0x05, 'Water Temple'), + 'GS Water Temple MQ South Basement': (None, None, 0x10, 'GS Token', 0x05, 'Water Temple'), + + 'GS Spirit Temple Hall to West Iron Knuckle': (None, None, 0x01, 'GS Token', 0x06, 'Spirit Temple'), + 'GS Spirit Temple Boulder Room': (None, None, 0x02, 'GS Token', 0x06, 'Spirit Temple'), + 'GS Spirit Temple Lobby': (None, None, 0x04, 'GS Token', 0x06, 'Spirit Temple'), + 'GS Spirit Temple Bomb for Light Room': (None, None, 0x08, 'GS Token', 0x06, 'Spirit Temple'), + 'GS Spirit Temple Metal Fence': (None, None, 0x10, 'GS Token', 0x06, 'Spirit Temple'), + + 'GS Spirit Temple MQ Lower Adult Right': (None, None, 0x08, 'GS Token', 0x06, 'Spirit Temple'), + 'GS Spirit Temple MQ Lower Adult Left': (None, None, 0x02, 'GS Token', 0x06, 'Spirit Temple'), + 'GS Spirit Temple MQ Iron Knuckle West': (None, None, 0x04, 'GS Token', 0x06, 'Spirit Temple'), + 'GS Spirit Temple MQ Iron Knuckle North': (None, None, 0x10, 'GS Token', 0x06, 'Spirit Temple'), + 'GS Spirit Temple MQ Sun Block Room': (None, None, 0x01, 'GS Token', 0x06, 'Spirit Temple'), + + 'GS Shadow Temple Single Giant Pot': (None, None, 0x01, 'GS Token', 0x07, 'Shadow Temple'), + 'GS Shadow Temple Crusher Room': (None, None, 0x02, 'GS Token', 0x07, 'Shadow Temple'), + 'GS Shadow Temple Triple Giant Pot': (None, None, 0x04, 'GS Token', 0x07, 'Shadow Temple'), + 'GS Shadow Temple Like Like Room': (None, None, 0x08, 'GS Token', 0x07, 'Shadow Temple'), + 'GS Shadow Temple Near Ship': (None, None, 0x10, 'GS Token', 0x07, 'Shadow Temple'), + + 'GS Shadow Temple MQ Crusher Room': (None, None, 0x02, 'GS Token', 0x07, 'Shadow Temple'), + 'GS Shadow Temple MQ Wind Hint Room': (None, None, 0x01, 'GS Token', 0x07, 'Shadow Temple'), + 'GS Shadow Temple MQ After Wind': (None, None, 0x08, 'GS Token', 0x07, 'Shadow Temple'), + 'GS Shadow Temple MQ After Ship': (None, None, 0x10, 'GS Token', 0x07, 'Shadow Temple'), + 'GS Shadow Temple MQ Near Boss': (None, None, 0x04, 'GS Token', 0x07, 'Shadow Temple'), + + 'GS Well Like Like Cage': (None, None, 0x01, 'GS Token', 0x08, 'Bottom of the Well'), + 'GS Well East Inner Room': (None, None, 0x02, 'GS Token', 0x08, 'Bottom of the Well'), + 'GS Well West Inner Room': (None, None, 0x04, 'GS Token', 0x08, 'Bottom of the Well'), + + 'GS Well MQ Basement': (None, None, 0x01, 'GS Token', 0x08, 'Bottom of the Well'), + 'GS Well MQ Coffin Room': (None, None, 0x04, 'GS Token', 0x08, 'Bottom of the Well'), + 'GS Well MQ West Inner Room': (None, None, 0x02, 'GS Token', 0x08, 'Bottom of the Well'), + + 'GS Ice Cavern Push Block Room': (None, None, 0x01, 'GS Token', 0x09, 'Ice Cavern'), + 'GS Ice Cavern Spinning Scythe Room': (None, None, 0x02, 'GS Token', 0x09, 'Ice Cavern'), + 'GS Ice Cavern Heart Piece Room': (None, None, 0x04, 'GS Token', 0x09, 'Ice Cavern'), + + 'GS Ice Cavern MQ Scarecrow': (None, None, 0x01, 'GS Token', 0x09, 'Ice Cavern'), + 'GS Ice Cavern MQ Ice Block': (None, None, 0x04, 'GS Token', 0x09, 'Ice Cavern'), + 'GS Ice Cavern MQ Red Ice': (None, None, 0x02, 'GS Token', 0x09, 'Ice Cavern'), + + 'GS Hyrule Field Near Gerudo Valley': (None, None, 0x01, 'GS Token', 0x0A, 'Hyrule Field'), + 'GS Hyrule Field near Kakariko': (None, None, 0x02, 'GS Token', 0x0A, 'Hyrule Field'), + + 'GS Lon Lon Ranch Back Wall': (None, None, 0x01, 'GS Token', 0x0B, 'Lon Lon Ranch'), + 'GS Lon Lon Ranch Rain Shed': (None, None, 0x02, 'GS Token', 0x0B, 'Lon Lon Ranch'), + 'GS Lon Lon Ranch House Window': (None, None, 0x04, 'GS Token', 0x0B, 'Lon Lon Ranch'), + 'GS Lon Lon Ranch Tree': (None, None, 0x08, 'GS Token', 0x0B, 'Lon Lon Ranch'), + + 'GS Kokiri Bean Patch': (None, None, 0x01, 'GS Token', 0x0C, 'Kokiri Forest'), + 'GS Kokiri Know It All House': (None, None, 0x02, 'GS Token', 0x0C, 'Kokiri Forest'), + 'GS Kokiri House of Twins': (None, None, 0x04, 'GS Token', 0x0C, 'Kokiri Forest'), + + 'GS Lost Woods Bean Patch Near Bridge': (None, None, 0x01, 'GS Token', 0x0D, 'the Lost Woods'), + 'GS Lost Woods Bean Patch Near Stage': (None, None, 0x02, 'GS Token', 0x0D, 'the Lost Woods'), + 'GS Lost Woods Above Stage': (None, None, 0x04, 'GS Token', 0x0D, 'the Lost Woods'), + 'GS Sacred Forest Meadow': (None, None, 0x08, 'GS Token', 0x0D, 'Sacred Forest Meadow'), + + 'GS Outside Ganon\'s Castle': (None, None, 0x01, 'GS Token', 0x0E, 'outside Ganon\'s Castle'), + 'GS Hyrule Castle Grotto': (None, None, 0x02, 'GS Token', 0x0E, 'Hyrule Castle'), + 'GS Hyrule Castle Tree': (None, None, 0x04, 'GS Token', 0x0E, 'Hyrule Castle'), + 'GS Castle Market Guard House': (None, None, 0x08, 'GS Token', 0x0E, 'the Market'), + + 'GS Mountain Crater Bean Patch': (None, None, 0x01, 'GS Token', 0x0F, 'Death Mountain Crater'), + 'GS Mountain Trail Bean Patch': (None, None, 0x02, 'GS Token', 0x0F, 'Death Mountain Trail'), + 'GS Mountain Trail Bomb Alcove': (None, None, 0x04, 'GS Token', 0x0F, 'Death Mountain Trail'), + 'GS Mountain Trail Above Dodongo\'s Cavern': (None, None, 0x08, 'GS Token', 0x0F, 'Death Mountain Trail'), + 'GS Mountain Trail Path to Crater': (None, None, 0x10, 'GS Token', 0x0F, 'Death Mountain Trail'), + 'GS Goron City Center Platform': (None, None, 0x20, 'GS Token', 0x0F, 'Goron City'), + 'GS Goron City Boulder Maze': (None, None, 0x40, 'GS Token', 0x0F, 'Goron City'), + 'GS Death Mountain Crater Crate': (None, None, 0x80, 'GS Token', 0x0F, 'Death Mountain Crater'), + + 'GS Kakariko House Under Construction': (None, None, 0x08, 'GS Token', 0x10, 'Kakariko Village'), + 'GS Kakariko Skulltula House': (None, None, 0x10, 'GS Token', 0x10, 'Kakariko Village'), + 'GS Kakariko Guard\'s House': (None, None, 0x02, 'GS Token', 0x10, 'Kakariko Village'), + 'GS Kakariko Tree': (None, None, 0x20, 'GS Token', 0x10, 'Kakariko Village'), + 'GS Kakariko Watchtower': (None, None, 0x04, 'GS Token', 0x10, 'Kakariko Village'), + 'GS Kakariko Above Impa\'s House': (None, None, 0x40, 'GS Token', 0x10, 'Kakariko Village'), + 'GS Graveyard Wall': (None, None, 0x80, 'GS Token', 0x10, 'the Graveyard'), + 'GS Graveyard Bean Patch': (None, None, 0x01, 'GS Token', 0x10, 'the Graveyard'), + + 'GS Zora River Ladder': (None, None, 0x01, 'GS Token', 0x11, 'Zora\'s River'), + 'GS Zora River Tree': (None, None, 0x02, 'GS Token', 0x11, 'Zora\'s River'), + 'GS Zora\'s Fountain Above the Log': (None, None, 0x04, 'GS Token', 0x11, 'Zora\'s Fountain'), + 'GS Zora River Above Bridge': (None, None, 0x08, 'GS Token', 0x11, 'Zora\'s River'), + 'GS Zora River Near Raised Grottos': (None, None, 0x10, 'GS Token', 0x11, 'Zora\'s River'), + 'GS Zora\'s Fountain Hidden Cave': (None, None, 0x20, 'GS Token', 0x11, 'Zora\'s Fountain'), + 'GS Zora\'s Domain Frozen Waterfall': (None, None, 0x40, 'GS Token', 0x11, 'Zora\'s Domain'), + 'GS Zora\'s Fountain Tree': (None, None, 0x80, 'GS Token', 0x11, 'Zora\'s Fountain'), + + 'GS Lake Hylia Bean Patch': (None, None, 0x01, 'GS Token', 0x12, 'Lake Hylia'), + 'GS Lake Hylia Small Island': (None, None, 0x02, 'GS Token', 0x12, 'Lake Hylia'), + 'GS Lake Hylia Lab Wall': (None, None, 0x04, 'GS Token', 0x12, 'Lake Hylia'), + 'GS Lab Underwater Crate': (None, None, 0x08, 'GS Token', 0x12, 'Lake Hylia'), + 'GS Lake Hylia Giant Tree': (None, None, 0x10, 'GS Token', 0x12, 'Lake Hylia'), + + 'GS Gerudo Valley Bean Patch': (None, None, 0x01, 'GS Token', 0x13, 'Gerudo Valley'), + 'GS Gerudo Valley Small Bridge': (None, None, 0x02, 'GS Token', 0x13, 'Gerudo Valley'), + 'GS Gerudo Valley Pillar': (None, None, 0x04, 'GS Token', 0x13, 'Gerudo Valley'), + 'GS Gerudo Valley Behind Tent': (None, None, 0x08, 'GS Token', 0x13, 'Gerudo Valley'), + + 'GS Gerudo Fortress Archery Range': (None, None, 0x01, 'GS Token', 0x14, 'Gerudo Fortress'), + 'GS Gerudo Fortress Top Floor': (None, None, 0x02, 'GS Token', 0x14, 'Gerudo Fortress'), + 'GS Desert Colossus Bean Patch': (None, None, 0x01, 'GS Token', 0x15, 'Desert Colossus'), + 'GS Wasteland Ruins': (None, None, 0x02, 'GS Token', 0x15, 'Haunted Wasteland'), + 'GS Desert Colossus Hill': (None, None, 0x04, 'GS Token', 0x15, 'Desert Colossus'), + 'GS Desert Colossus Tree': (None, None, 0x08, 'GS Token', 0x15, 'Desert Colossus'), + + 'Kokiri Shop Item 1': (shop_address(0, 0), None, 0x30, 'Shop', 0x2D, 'Kokiri Forest'), + 'Kokiri Shop Item 2': (shop_address(0, 1), None, 0x31, 'Shop', 0x2D, 'Kokiri Forest'), + 'Kokiri Shop Item 3': (shop_address(0, 2), None, 0x32, 'Shop', 0x2D, 'Kokiri Forest'), + 'Kokiri Shop Item 4': (shop_address(0, 3), None, 0x33, 'Shop', 0x2D, 'Kokiri Forest'), + 'Kokiri Shop Item 5': (shop_address(0, 4), None, 0x34, 'Shop', 0x2D, 'Kokiri Forest'), + 'Kokiri Shop Item 6': (shop_address(0, 5), None, 0x35, 'Shop', 0x2D, 'Kokiri Forest'), + 'Kokiri Shop Item 7': (shop_address(0, 6), None, 0x36, 'Shop', 0x2D, 'Kokiri Forest'), + 'Kokiri Shop Item 8': (shop_address(0, 7), None, 0x37, 'Shop', 0x2D, 'Kokiri Forest'), + 'Kakariko Potion Shop Item 1': (shop_address(1, 0), None, 0x30, 'Shop', 0x30, 'Kakariko Village'), + 'Kakariko Potion Shop Item 2': (shop_address(1, 1), None, 0x31, 'Shop', 0x30, 'Kakariko Village'), + 'Kakariko Potion Shop Item 3': (shop_address(1, 2), None, 0x32, 'Shop', 0x30, 'Kakariko Village'), + 'Kakariko Potion Shop Item 4': (shop_address(1, 3), None, 0x33, 'Shop', 0x30, 'Kakariko Village'), + 'Kakariko Potion Shop Item 5': (shop_address(1, 4), None, 0x34, 'Shop', 0x30, 'Kakariko Village'), + 'Kakariko Potion Shop Item 6': (shop_address(1, 5), None, 0x35, 'Shop', 0x30, 'Kakariko Village'), + 'Kakariko Potion Shop Item 7': (shop_address(1, 6), None, 0x36, 'Shop', 0x30, 'Kakariko Village'), + 'Kakariko Potion Shop Item 8': (shop_address(1, 7), None, 0x37, 'Shop', 0x30, 'Kakariko Village'), + 'Bombchu Shop Item 1': (shop_address(2, 0), None, 0x30, 'Shop', 0x32, 'the Market'), + 'Bombchu Shop Item 2': (shop_address(2, 1), None, 0x31, 'Shop', 0x32, 'the Market'), + 'Bombchu Shop Item 3': (shop_address(2, 2), None, 0x32, 'Shop', 0x32, 'the Market'), + 'Bombchu Shop Item 4': (shop_address(2, 3), None, 0x33, 'Shop', 0x32, 'the Market'), + 'Bombchu Shop Item 5': (shop_address(2, 4), None, 0x34, 'Shop', 0x32, 'the Market'), + 'Bombchu Shop Item 6': (shop_address(2, 5), None, 0x35, 'Shop', 0x32, 'the Market'), + 'Bombchu Shop Item 7': (shop_address(2, 6), None, 0x36, 'Shop', 0x32, 'the Market'), + 'Bombchu Shop Item 8': (shop_address(2, 7), None, 0x37, 'Shop', 0x32, 'the Market'), + 'Castle Town Potion Shop Item 1': (shop_address(3, 0), None, 0x30, 'Shop', 0x31, 'the Market'), + 'Castle Town Potion Shop Item 2': (shop_address(3, 1), None, 0x31, 'Shop', 0x31, 'the Market'), + 'Castle Town Potion Shop Item 3': (shop_address(3, 2), None, 0x32, 'Shop', 0x31, 'the Market'), + 'Castle Town Potion Shop Item 4': (shop_address(3, 3), None, 0x33, 'Shop', 0x31, 'the Market'), + 'Castle Town Potion Shop Item 5': (shop_address(3, 4), None, 0x34, 'Shop', 0x31, 'the Market'), + 'Castle Town Potion Shop Item 6': (shop_address(3, 5), None, 0x35, 'Shop', 0x31, 'the Market'), + 'Castle Town Potion Shop Item 7': (shop_address(3, 6), None, 0x36, 'Shop', 0x31, 'the Market'), + 'Castle Town Potion Shop Item 8': (shop_address(3, 7), None, 0x37, 'Shop', 0x31, 'the Market'), + 'Castle Town Bazaar Item 1': (shop_address(4, 0), None, 0x30, 'Shop', 0x2C, 'the Market'), + 'Castle Town Bazaar Item 2': (shop_address(4, 1), None, 0x31, 'Shop', 0x2C, 'the Market'), + 'Castle Town Bazaar Item 3': (shop_address(4, 2), None, 0x32, 'Shop', 0x2C, 'the Market'), + 'Castle Town Bazaar Item 4': (shop_address(4, 3), None, 0x33, 'Shop', 0x2C, 'the Market'), + 'Castle Town Bazaar Item 5': (shop_address(4, 4), None, 0x34, 'Shop', 0x2C, 'the Market'), + 'Castle Town Bazaar Item 6': (shop_address(4, 5), None, 0x35, 'Shop', 0x2C, 'the Market'), + 'Castle Town Bazaar Item 7': (shop_address(4, 6), None, 0x36, 'Shop', 0x2C, 'the Market'), + 'Castle Town Bazaar Item 8': (shop_address(4, 7), None, 0x37, 'Shop', 0x2C, 'the Market'), + 'Kakariko Bazaar Item 1': (shop_address(5, 0), None, 0x38, 'Shop', 0x2C, 'Kakariko Village'), + 'Kakariko Bazaar Item 2': (shop_address(5, 1), None, 0x39, 'Shop', 0x2C, 'Kakariko Village'), + 'Kakariko Bazaar Item 3': (shop_address(5, 2), None, 0x3A, 'Shop', 0x2C, 'Kakariko Village'), + 'Kakariko Bazaar Item 4': (shop_address(5, 3), None, 0x3B, 'Shop', 0x2C, 'Kakariko Village'), + 'Kakariko Bazaar Item 5': (shop_address(5, 4), None, 0x3D, 'Shop', 0x2C, 'Kakariko Village'), + 'Kakariko Bazaar Item 6': (shop_address(5, 5), None, 0x3E, 'Shop', 0x2C, 'Kakariko Village'), + 'Kakariko Bazaar Item 7': (shop_address(5, 6), None, 0x3F, 'Shop', 0x2C, 'Kakariko Village'), + 'Kakariko Bazaar Item 8': (shop_address(5, 7), None, 0x40, 'Shop', 0x2C, 'Kakariko Village'), + 'Zora Shop Item 1': (shop_address(7, 0), None, 0x30, 'Shop', 0x2F, 'Zora\'s Domain'), + 'Zora Shop Item 2': (shop_address(7, 1), None, 0x31, 'Shop', 0x2F, 'Zora\'s Domain'), + 'Zora Shop Item 3': (shop_address(7, 2), None, 0x32, 'Shop', 0x2F, 'Zora\'s Domain'), + 'Zora Shop Item 4': (shop_address(7, 3), None, 0x33, 'Shop', 0x2F, 'Zora\'s Domain'), + 'Zora Shop Item 5': (shop_address(7, 4), None, 0x34, 'Shop', 0x2F, 'Zora\'s Domain'), + 'Zora Shop Item 6': (shop_address(7, 5), None, 0x35, 'Shop', 0x2F, 'Zora\'s Domain'), + 'Zora Shop Item 7': (shop_address(7, 6), None, 0x36, 'Shop', 0x2F, 'Zora\'s Domain'), + 'Zora Shop Item 8': (shop_address(7, 7), None, 0x37, 'Shop', 0x2F, 'Zora\'s Domain'), + 'Goron Shop Item 1': (shop_address(8, 0), None, 0x30, 'Shop', 0x2E, 'Goron City'), + 'Goron Shop Item 2': (shop_address(8, 1), None, 0x31, 'Shop', 0x2E, 'Goron City'), + 'Goron Shop Item 3': (shop_address(8, 2), None, 0x32, 'Shop', 0x2E, 'Goron City'), + 'Goron Shop Item 4': (shop_address(8, 3), None, 0x33, 'Shop', 0x2E, 'Goron City'), + 'Goron Shop Item 5': (shop_address(8, 4), None, 0x34, 'Shop', 0x2E, 'Goron City'), + 'Goron Shop Item 6': (shop_address(8, 5), None, 0x35, 'Shop', 0x2E, 'Goron City'), + 'Goron Shop Item 7': (shop_address(8, 6), None, 0x36, 'Shop', 0x2E, 'Goron City'), + 'Goron Shop Item 8': (shop_address(8, 7), None, 0x37, 'Shop', 0x2E, 'Goron City'), + + 'DC Deku Scrub Deku Nuts': (None, None, 0x30, 'NPC', 0x01, 'Dodongo\'s Cavern'), + 'DC Deku Scrub Deku Sticks': (None, None, 0x31, 'NPC', 0x01, 'Dodongo\'s Cavern'), + 'DC Deku Scrub Deku Seeds': (None, None, 0x33, 'NPC', 0x01, 'Dodongo\'s Cavern'), + 'DC Deku Scrub Deku Shield': (None, None, 0x34, 'NPC', 0x01, 'Dodongo\'s Cavern'), + 'Jabu Deku Scrub Deku Nuts': (None, None, 0x30, 'NPC', 0x02, 'Jabu Jabu\'s Belly'), + 'GC Deku Scrub Bombs': (None, None, 0x37, 'NPC', 0x0D, 'Ganon\'s Castle'), + 'GC Deku Scrub Arrows': (None, None, 0x33, 'NPC', 0x0D, 'Ganon\'s Castle'), + 'GC Deku Scrub Red Potion': (None, None, 0x39, 'NPC', 0x0D, 'Ganon\'s Castle'), + 'GC Deku Scrub Green Potion': (None, None, 0x3A, 'NPC', 0x0D, 'Ganon\'s Castle'), + + 'DT MQ Deku Scrub Deku Shield': (None, None, 0x34, 'NPC', 0x00, 'Deku Tree'), + 'DC MQ Deku Scrub Deku Sticks': (None, None, 0x31, 'NPC', 0x01, 'Dodongo\'s Cavern'), + 'DC MQ Deku Scrub Deku Seeds': (None, None, 0x33, 'NPC', 0x01, 'Dodongo\'s Cavern'), + 'DC MQ Deku Scrub Deku Shield': (None, None, 0x34, 'NPC', 0x01, 'Dodongo\'s Cavern'), + 'DC MQ Deku Scrub Red Potion': (None, None, 0x39, 'NPC', 0x01, 'Dodongo\'s Cavern'), + 'GC MQ Deku Scrub Deku Nuts': (None, None, 0x30, 'NPC', 0x0D, 'Ganon\'s Castle'), + 'GC MQ Deku Scrub Bombs': (None, None, 0x37, 'NPC', 0x0D, 'Ganon\'s Castle'), + 'GC MQ Deku Scrub Arrows': (None, None, 0x33, 'NPC', 0x0D, 'Ganon\'s Castle'), + 'GC MQ Deku Scrub Red Potion': (None, None, 0x39, 'NPC', 0x0D, 'Ganon\'s Castle'), + 'GC MQ Deku Scrub Green Potion': (None, None, 0x3A, 'NPC', 0x0D, 'Ganon\'s Castle'), + + 'HF Grotto Deku Scrub Piece of Heart': (None, None, 0x3E, 'GrottoNPC', 0x01, 'Hyrule Field'), + 'ZR Grotto Deku Scrub Red Potion': (None, None, 0x39, 'GrottoNPC', 0x02, 'Zora\'s River'), + 'ZR Grotto Deku Scrub Green Potion': (None, None, 0x3A, 'GrottoNPC', 0x02, 'Zora\'s River'), + 'SFM Grotto Deku Scrub Red Potion': (None, None, 0x39, 'GrottoNPC', 0x03, 'Sacred Forest Meadow'), + 'SFM Grotto Deku Scrub Green Potion': (None, None, 0x3A, 'GrottoNPC', 0x03, 'Sacred Forest Meadow'), + 'LH Grotto Deku Scrub Deku Nuts': (None, None, 0x30, 'GrottoNPC', 0x04, 'Lake Hylia'), + 'LH Grotto Deku Scrub Bombs': (None, None, 0x37, 'GrottoNPC', 0x04, 'Lake Hylia'), + 'LH Grotto Deku Scrub Arrows': (None, None, 0x33, 'GrottoNPC', 0x04, 'Lake Hylia'), + 'Valley Grotto Deku Scrub Red Potion': (None, None, 0x39, 'GrottoNPC', 0x05, 'Gerudo Valley'), + 'Valley Grotto Deku Scrub Green Potion': (None, None, 0x3A, 'GrottoNPC', 0x05, 'Gerudo Valley'), + 'LW Deku Scrub Deku Nuts': (None, None, 0x30, 'NPC', 0x5B, 'the Lost Woods'), + 'LW Deku Scrub Deku Sticks': (None, None, 0x31, 'NPC', 0x5B, 'the Lost Woods'), + 'LW Deku Scrub Deku Stick Upgrade': (None, None, 0x77, 'NPC', 0x5B, 'the Lost Woods'), + 'LW Grotto Deku Scrub Arrows': (None, None, 0x33, 'GrottoNPC', 0x06, 'the Lost Woods'), + 'LW Grotto Deku Scrub Deku Nut Upgrade': (None, None, 0x79, 'GrottoNPC', 0x06, 'the Lost Woods'), + 'Desert Grotto Deku Scrub Red Potion': (None, None, 0x39, 'GrottoNPC', 0x07, 'Desert Colossus'), + 'Desert Grotto Deku Scrub Green Potion': (None, None, 0x3A, 'GrottoNPC', 0x07, 'Desert Colossus'), + 'DMC Deku Scrub Bombs': (None, None, 0x37, 'NPC', 0x61, 'Death Mountain Crater'), + 'DMC Grotto Deku Scrub Deku Nuts': (None, None, 0x30, 'GrottoNPC', 0x08, 'Death Mountain Crater'), + 'DMC Grotto Deku Scrub Bombs': (None, None, 0x37, 'GrottoNPC', 0x08, 'Death Mountain Crater'), + 'DMC Grotto Deku Scrub Arrows': (None, None, 0x33, 'GrottoNPC', 0x08, 'Death Mountain Crater'), + 'Goron Grotto Deku Scrub Deku Nuts': (None, None, 0x30, 'GrottoNPC', 0x09, 'Goron City'), + 'Goron Grotto Deku Scrub Bombs': (None, None, 0x37, 'GrottoNPC', 0x09, 'Goron City'), + 'Goron Grotto Deku Scrub Arrows': (None, None, 0x33, 'GrottoNPC', 0x09, 'Goron City'), + 'LLR Grotto Deku Scrub Deku Nuts': (None, None, 0x30, 'GrottoNPC', 0x0A, 'Lon Lon Ranch'), + 'LLR Grotto Deku Scrub Bombs': (None, None, 0x37, 'GrottoNPC', 0x0A, 'Lon Lon Ranch'), + 'LLR Grotto Deku Scrub Arrows': (None, None, 0x33, 'GrottoNPC', 0x0A, 'Lon Lon Ranch'), +} diff --git a/Rom.py b/Rom.py index 7f1c4ccdc..96d0805ff 100644 --- a/Rom.py +++ b/Rom.py @@ -1,1127 +1,293 @@ -import io -import json -import logging -import os -import platform -import struct -import subprocess -import random - -from Hints import buildGossipHints, buildBossRewardHints, buildGanonText -from Utils import local_path, output_path -from Items import ItemFactory, item_data -from TextArray import text_array - -class LocalRom(object): - - def __init__(self, file, patch=True): - - validCRC = [] - validCRC.append(bytearray([0xEC, 0x70, 0x11, 0xB7, 0x76, 0x16, 0xD7, 0x2B])) # Compressed - validCRC.append(bytearray([0x70, 0xEC, 0xB7, 0x11, 0x16, 0x76, 0x2B, 0xD7])) # Byteswap compressed - validCRC.append(bytearray([0x93, 0x52, 0x2E, 0x7B, 0xE5, 0x06, 0xD4, 0x27])) # Decompressed - - os.chdir(os.path.dirname(os.path.realpath(__file__))) - #os.chdir(output_path(os.path.dirname(os.path.realpath(__file__)))) - with open(file, 'rb') as stream: - self.buffer = read_rom(stream) - file_name = os.path.splitext(file) - romCRC = self.buffer[0x10:0x18] - if romCRC not in validCRC: - raise RuntimeError('ROM is not a valid OoT 1.0 US ROM.') - if len(self.buffer) < 33554432 or len(self.buffer) > 67108864 or file_name[1] not in ['.z64', '.n64']: - raise RuntimeError('ROM is not a valid OoT 1.0 ROM.') - if len(self.buffer) == 33554432: - if platform.system() == 'Windows': - subprocess.call(["Decompress\Decompress.exe", file, output_path('ZOOTDEC.z64')]) - with open((output_path('ZOOTDEC.z64')), 'rb') as stream: - self.buffer = read_rom(stream) - elif platform.system() == 'Linux': - subprocess.call(["Decompress/Decompress", file]) - with open(("ZOOTDEC.z64"), 'rb') as stream: - self.buffer = read_rom(stream) - elif platform.system() == 'Darwin': - subprocess.call(["Decompress/Decompress.out", file]) - with open(("ZOOTDEC.z64"), 'rb') as stream: - self.buffer = read_rom(stream) - else: - raise RuntimeError('Unsupported operating system for decompression. Please supply an already decompressed ROM.') - # extend to 64MB - self.buffer.extend(bytearray([0x00] * (67108864 - len(self.buffer)))) - - - def write_byte(self, address, value): - self.buffer[address] = value - - def write_bytes(self, startaddress, values): - for i, value in enumerate(values): - self.write_byte(startaddress + i, value) - - def write_int16_to_rom(self, address, value): - self.write_bytes(address, int16_as_bytes(value)) - - def write_int32_to_rom(self, address, value): - self.write_bytes(address, int32_as_bytes(value)) - - def write_to_file(self, file): - with open(file, 'wb') as outfile: - outfile.write(self.buffer) - -def read_rom(stream): - "Reads rom into bytearray" - buffer = bytearray(stream.read()) - return buffer - - -def int16_as_bytes(value): - value = value & 0xFFFF - return [value & 0xFF, (value >> 8) & 0xFF] - -def int32_as_bytes(value): - value = value & 0xFFFFFFFF - return [value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF, (value >> 24) & 0xFF] - -def patch_rom(world, rom): - with open(local_path('data/base2current.json'), 'r') as stream: - patches = json.load(stream) - for patch in patches: - if isinstance(patch, dict): - for baseaddress, values in patch.items(): - rom.write_bytes(int(baseaddress), values) - - # Can always return to youth - rom.write_byte(0xCB6844, 0x35) - rom.write_byte(0x253C0E2, 0x03) # Moves sheik from pedestal - - # Fix child shooting gallery reward to be static - rom.write_bytes(0xD35EFC, [0x00, 0x00, 0x00, 0x00]) - - # Fix target in woods reward to be static - rom.write_bytes(0xE59CD4, [0x00, 0x00, 0x00, 0x00]) - - # Fix GS rewards to be static - rom.write_bytes(0xEA3934, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xEA3940 , [0x10, 0x00]) - - # Fix horseback archery rewards to be static - rom.write_byte(0xE12BA5, 0x00) - rom.write_byte(0xE12ADD, 0x00) - - # Fix adult shooting gallery reward to be static - rom.write_byte(0xD35F55, 0x00) - - # Fix deku theater rewards to be static - rom.write_bytes(0xEC9A7C, [0x00, 0x00, 0x00, 0x00]) #Sticks - rom.write_byte(0xEC9CD5, 0x00) #Nuts - - # Fix deku scrub who sells stick upgrade - rom.write_bytes(0xDF8060, [0x00, 0x00, 0x00, 0x00]) - - # Fix deku scrub who sells nut upgrade - rom.write_bytes(0xDF80D4, [0x00, 0x00, 0x00, 0x00]) - - # Fix rolling goron as child reward to be static - rom.write_bytes(0xED2960, [0x00, 0x00, 0x00, 0x00]) - - # Fix proximity text boxes (Navi) (Part 1) - rom.write_bytes(0xDF8B84, [0x00, 0x00, 0x00, 0x00]) - - # Fix final magic bean to cost 99 - rom.write_byte(0xE20A0F, 0x63) - rom.write_bytes(0x94FCDD, [0x08, 0x39, 0x39]) - - # Remove intro cutscene - rom.write_bytes(0xB06BBA, [0x00, 0x00]) - - # Remove locked door to Boss Key Chest in Fire Temple - rom.write_byte(0x22D82B7, 0x3F) - - # Change Bombchu Shop check to Bomb Bag - rom.write_bytes(0xC6CEDA, [0x00, 0xA2]) - rom.write_byte(0xC6CEDF, 0x18) - - # Change Bowling Alley check to Bomb Bag (Part 1) - rom.write_bytes(0x00E2D716, [0xA6, 0x72]) - rom.write_byte(0x00E2D723, 0x18) - - # Change Bowling Alley check to Bomb Bag (Part 2) - rom.write_bytes(0x00E2D892, [0xA6, 0x72]) - rom.write_byte(0x00E2D897, 0x18) - - # Change Bazaar check to Bomb Bag (Child?) - rom.write_bytes(0x00C0082A, [0x00, 0x18]) - rom.write_bytes(0x00C0082C, [0x00, 0x0E, 0X74, 0X02]) - rom.write_byte(0x00C00833, 0xA0) - - # Change Bazaar check to Bomb Bag (Adult?) - rom.write_bytes(0x00DF7A8E, [0x00, 0x18]) - rom.write_bytes(0x00DF7A90, [0x00, 0x0E, 0X74, 0X02]) - rom.write_byte(0x00DF7A97, 0xA0) - - # Change Goron Shop check to Bomb Bag - rom.write_bytes(0x00C6ED86, [0x00, 0xA2]) - rom.write_bytes(0x00C6ED8A, [0x00, 0x18]) - - # Change graveyard graves to not allow grabbing on to the ledge - rom.write_byte(0x0202039D, 0x20) - rom.write_byte(0x0202043C, 0x24) - - # Fix Link the Goron to always work - rom.write_bytes(0xED2FAC, [0x80, 0x6E, 0x0F, 0x18]) - rom.write_bytes(0xED2FEC, [0x24, 0x0A, 0x00, 0x00]) - rom.write_bytes(0xAE74D8, [0x24, 0x0E, 0x00, 0x00]) - - # Fix King Zora Thawed to always work - rom.write_bytes(0xE55C4C, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xE56290, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xE56298, [0x00, 0x00, 0x00, 0x00]) - - # Fix Castle Courtyard to check for meeting Zelda, not Zelda fleeing, to block you - rom.write_bytes(0xCD5E76, [0x0E, 0xDC]) - rom.write_bytes(0xCD5E12, [0x0E, 0xDC]) - - # Cutscene for all medallions never triggers when leaving shadow or spirit temples(hopefully stops warp to colossus on shadow completion with boss reward shuffle) - rom.write_byte(0xACA409, 0xAD) - rom.write_byte(0xACA49D, 0xCE) - - # Speed Zelda's Letter scene - rom.write_bytes(0x290E08E, [0x05, 0xF0]) - rom.write_byte(0xEFCBA7, 0x08) - rom.write_byte(0xEFE7C7, 0x05) - #rom.write_byte(0xEFEAF7, 0x08) - #rom.write_byte(0xEFE7C7, 0x05) - rom.write_bytes(0xEFE938, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xEFE948, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xEFE950, [0x00, 0x00, 0x00, 0x00]) - - # Speed Zelda escaping from Hyrule Castle - Block_code = [0x00, 0x00, 0x00, 0x01, 0x00, 0x21, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02] - rom.write_bytes(0x1FC0CF8, Block_code) - - # Speed learning Zelda's Lullaby - Block_code = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x73, 0x00, 0x3B, - 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0C, - 0x00, 0x17, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x08, 0x8B, 0xFF, 0xFF, - 0x00, 0xD4, 0x00, 0x11, 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x2E8E900, Block_code) - - # Speed learning Sun's Song - rom.write_bytes(0x332A4A6, [0x00, 0x3C]) - Block_code = [0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x02, 0x08, 0x8B, 0xFF, 0xFF, 0x00, 0xD3, 0x00, 0x11, - 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x332A868, Block_code) - - # Speed learning Saria's Song - rom.write_bytes(0x20B1736, [0x00, 0x3C]) - Block_code = [0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x15, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x02, 0x08, 0x8B, 0xFF, 0xFF, 0x00, 0xD1, 0x00, 0x11, - 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x20B1DA8, Block_code) - rom.write_bytes(0x20B19C8, [0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00]) - Block_code = [0x00, 0x3E, 0x00, 0x11, 0x00, 0x20, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xD4, 0xFF, 0xFF, 0xF7, 0x31, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xD4] - rom.write_bytes(0x20B19F8, Block_code) - - # Speed learning Epona's Song - rom.write_bytes(0x29BEF68, [0x00, 0x5E, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x0B]) - Block_code = [0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0xD2, 0x00, 0x00, - 0x00, 0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0A, - 0x00, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x29BECB0, Block_code) - - # Speed learning Song of Time - Block_code = [0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x19, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x02, 0x08, 0x8B, 0xFF, 0xFF, 0x00, 0xD5, 0x00, 0x11, - 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x252FC80, Block_code) - rom.write_bytes(0x252FBA0, [0x00, 0x35, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) - rom.write_bytes(0x1FC3B84, [0xFF, 0xFF, 0xFF, 0xFF]) - - # Speed learning Song of Storms - Block_code = [0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, - 0x00, 0xD6, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x00, 0xBE, 0x00, 0xC8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x3041084, Block_code) - - # Speed learning Minuet of Forest - rom.write_bytes(0x20AFF86, [0x00, 0x3C]) - Block_code = [0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x0F, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x02, 0x08, 0x8B, 0xFF, 0xFF, 0x00, 0x73, 0x00, 0x11, - 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x20B0800, Block_code) - rom.write_bytes(0x20AFF90, [0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00]) - rom.write_bytes(0x20AFFC1, [0x00, 0x3E, 0x00, 0x11, 0x00, 0x20, 0x00, 0x00]) - rom.write_bytes(0x20B0492, [0x00, 0x21, 0x00, 0x22]) - rom.write_bytes(0x20B04CA, [0x00, 0x00, 0x00, 0x00]) - - # Speed learning Bolero of Fire - rom.write_bytes(0x224B5D6, [0x00, 0x3C]) - Block_code = [0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x02, 0x08, 0x8B, 0xFF, 0xFF, 0x00, 0x74, 0x00, 0x11, - 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x224D7E8, Block_code) - rom.write_bytes(0x224B5E0, [0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00]) - rom.write_bytes(0x224B611, [0x00, 0x3E, 0x00, 0x11, 0x00, 0x20, 0x00, 0x00]) - rom.write_bytes(0x224B7F8, [0x00, 0x00]) - rom.write_bytes(0x224B828, [0x00, 0x00]) - rom.write_bytes(0x224B858, [0x00, 0x00]) - rom.write_bytes(0x224B888, [0x00, 0x00]) - - # Speed learning Serenade of Water - rom.write_bytes(0x2BEB256, [0x00, 0x3C]) - Block_code = [0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x10, 0x00, 0x11, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x02, 0x08, 0x8B, 0xFF, 0xFF, 0x00, 0x75, 0x00, 0x11, - 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x2BEC880, Block_code) - rom.write_bytes(0x2BEB260, [0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00]) - rom.write_bytes(0x2BEB290, [0x00, 0x3E, 0x00, 0x11, 0x00, 0x20, 0x00, 0x00]) - rom.write_bytes(0x2BEB538, [0x00, 0x00]) - rom.write_bytes(0x2BEB548, [0x80, 0x00]) - rom.write_bytes(0x2BEB554, [0x80, 0x00]) - rom.write_bytes(0x2BEC852, [0x00, 0x21, 0x00, 0x22]) - - # Speed learning Nocturne of Shadow - rom.write_bytes(0x1FFE460, [0x00, 0x2F, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) - rom.write_bytes(0x1FFFDF6, [0x00, 0x3C]) - Block_code = [0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x13, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x02, 0x08, 0x8B, 0xFF, 0xFF, 0x00, 0x77, 0x00, 0x11, - 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x2000FD8, Block_code) - rom.write_bytes(0x2000130, [0x00, 0x32, 0x00, 0x3A, 0x00, 0x3B, 0x00, 0x3B]) - - # Speed learning Requiem of Spirit - rom.write_bytes(0x218AF16, [0x00, 0x3C]) - Block_code = [0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x12, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x02, 0x08, 0x8B, 0xFF, 0xFF, 0x00, 0x76, 0x00, 0x11, - 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x218C574, Block_code) - rom.write_bytes(0x218B480, [0x00, 0x30, 0x00, 0x3A, 0x00, 0x3B, 0x00, 0x3B]) - Block_code = [0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFA, 0xF9, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, - 0xFF, 0xFF, 0xFA, 0xF9, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, - 0x0F, 0x67, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01] - rom.write_bytes(0x218AF20, Block_code) - rom.write_bytes(0x218AF50, [0x00, 0x3E, 0x00, 0x11, 0x00, 0x20, 0x00, 0x00]) - - # Speed learning Prelude of Light - rom.write_bytes(0x252FD26, [0x00, 0x3C]) - Block_code = [0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x14, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x02, 0x08, 0x8B, 0xFF, 0xFF, 0x00, 0x78, 0x00, 0x11, - 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x2531320, Block_code) - rom.write_byte(0x252FF1D, 0x00) - rom.write_bytes(0x25313DA, [0x00, 0x21, 0x00, 0x22]) - - # Speed scene after Deku Tree - rom.write_bytes(0x2077E20, [0x00, 0x07, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) - rom.write_bytes(0x2078A10, [0x00, 0x0E, 0x00, 0x1F, 0x00, 0x20, 0x00, 0x20]) - Block_code = [0x00, 0x80, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x00, 0x1E, 0x00, 0x28, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] - rom.write_bytes(0x2079570, Block_code) - - # Speed scene after Dodongo's Cavern - rom.write_bytes(0x2221E88, [0x00, 0x0C, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) - rom.write_bytes(0x2223308, [0x00, 0x81, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) - - # Speed scene after Jabu Jabu's Belly - rom.write_bytes(0xCA3530, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0x2113340, [0x00, 0x0D, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) - rom.write_bytes(0x2113C18, [0x00, 0x82, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) - rom.write_bytes(0x21131D0, [0x00, 0x01, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x3C]) - - # Speed scene after Forest Temple - rom.write_bytes(0xD4ED68, [0x00, 0x45, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) - rom.write_bytes(0xD4ED78, [0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) - rom.write_bytes(0x207B9D4, [0xFF, 0xFF, 0xFF, 0xFF]) - - # Speed scene after Fire Temple - rom.write_bytes(0x2001848, [0x00, 0x1E, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) - rom.write_bytes(0xD100B4, [0x00, 0x62, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) - rom.write_bytes(0xD10134, [0x00, 0x3C, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) - - # Speed scene after Water Temple - rom.write_bytes(0xD5A458, [0x00, 0x15, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) - rom.write_bytes(0xD5A3A8, [0x00, 0x3D, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) - rom.write_bytes(0x20D0D20, [0x00, 0x29, 0x00, 0xC7, 0x00, 0xC8, 0x00, 0xC8]) - - # Speed scene after Shadow Temple - rom.write_bytes(0xD13EC8, [0x00, 0x61, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) - rom.write_bytes(0xD13E18, [0x00, 0x41, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) - - # Speed scene after Spirit Temple - rom.write_bytes(0xD3A0A8, [0x00, 0x60, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3C]) - rom.write_bytes(0xD39FF0, [0x00, 0x3F, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00]) - - # Speed Nabooru defeat scene - rom.write_bytes(0x2F5AF84, [0x00, 0x00, 0x00, 0x05]) - rom.write_bytes(0x2F5C7DA, [0x00, 0x01, 0x00, 0x02]) - rom.write_bytes(0x2F5C7A2, [0x00, 0x03, 0x00, 0x04]) - rom.write_byte(0x2F5B369, 0x09) - rom.write_byte(0x2F5B491, 0x04) - rom.write_byte(0x2F5B559, 0x04) - rom.write_byte(0x2F5B621, 0x04) - rom.write_byte(0x2F5B761, 0x07) - - # Speed scene with all medallions - rom.write_bytes(0x2512680, [0x00, 0x74, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) - - # Speed collapse of Ganon's Tower - rom.write_bytes(0x33FB328, [0x00, 0x76, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) - - # Speed Phantom Ganon defeat scene - rom.write_bytes(0xC944D8, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xC94548, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xC94730, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xC945A8, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xC94594, [0x00, 0x00, 0x00, 0x00]) - - # Speed Twinrova defeat scene - rom.write_bytes(0xD678CC, [0x24, 0x01, 0x03, 0xA2, 0xA6, 0x01, 0x01, 0x42]) - rom.write_bytes(0xD67BA4, [0x10, 0x00]) - - # Speed scenes during final battle - # Ganondorf battle end - rom.write_byte(0xD82047, 0x09) - # Zelda descends - rom.write_byte(0xD82AB3, 0x66) - rom.write_byte(0xD82FAF, 0x65) - rom.write_bytes(0xD82D2E, [0x04, 0x1F]) - rom.write_bytes(0xD83142, [0x00, 0x6B]) - rom.write_bytes(0xD82DD8, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xD82ED4, [0x00, 0x00, 0x00, 0x00]) - rom.write_byte(0xD82FDF, 0x33) - # After tower collapse - rom.write_byte(0xE82E0F, 0x04) - # Ganon intro - rom.write_bytes(0xE83D28, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xE83B5C, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xE84C80, [0x10, 0x00]) - - # Speed completion of the trials in Ganon's Castle - rom.write_bytes(0x31A8090, [0x00, 0x6B, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) #Forest - rom.write_bytes(0x31A9E00, [0x00, 0x6E, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) #Fire - rom.write_bytes(0x31A8B18, [0x00, 0x6C, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) #Water - rom.write_bytes(0x31A9430, [0x00, 0x6D, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) #Shadow - rom.write_bytes(0x31AB200, [0x00, 0x70, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) #Spirit - rom.write_bytes(0x31AA830, [0x00, 0x6F, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) #Light - - # Speed obtaining Fairy Ocarina - rom.write_bytes(0x2151230, [0x00, 0x72, 0x00, 0x3C, 0x00, 0x3D, 0x00, 0x3D]) - Block_code = [0x00, 0x4A, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x00, 0x3C, 0x00, 0x81, 0xFF, 0xFF] - rom.write_bytes(0x2151240, Block_code) - rom.write_bytes(0x2150E20, [0xFF, 0xFF, 0xFA, 0x4C]) - - # Speed Zelda Light Arrow cutscene - rom.write_bytes(0x2531B40, [0x00, 0x28, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) - rom.write_bytes(0x2532FBC, [0x00, 0x75]) - rom.write_bytes(0x2532FEA, [0x00, 0x75, 0x00, 0x80]) - rom.write_byte(0x2533115, 0x05) - rom.write_bytes(0x2533141, [0x06, 0x00, 0x06, 0x00, 0x10]) - rom.write_bytes(0x2533171, [0x0F, 0x00, 0x11, 0x00, 0x40]) - rom.write_bytes(0x25331A1, [0x07, 0x00, 0x41, 0x00, 0x65]) - rom.write_bytes(0x2533642, [0x00, 0x50]) - rom.write_byte(0x253389D, 0x74) - rom.write_bytes(0x25338A4, [0x00, 0x72, 0x00, 0x75, 0x00, 0x79]) - rom.write_bytes(0x25338BC, [0xFF, 0xFF]) - rom.write_bytes(0x25338C2, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]) - rom.write_bytes(0x25339C2, [0x00, 0x75, 0x00, 0x76]) - rom.write_bytes(0x2533830, [0x00, 0x31, 0x00, 0x81, 0x00, 0x82, 0x00, 0x82]) - - # Speed Bridge of Light cutscene - rom.write_bytes(0x292D644, [0x00, 0x00, 0x00, 0xA0]) - rom.write_bytes(0x292D680, [0x00, 0x02, 0x00, 0x0A, 0x00, 0x6C, 0x00, 0x00]) - rom.write_bytes(0x292D6E8, [0x00, 0x27]) - rom.write_bytes(0x292D718, [0x00, 0x32]) - rom.write_bytes(0x292D810, [0x00, 0x02, 0x00, 0x3C]) - rom.write_bytes(0x292D924, [0xFF, 0xFF, 0x00, 0x14, 0x00, 0x96, 0xFF, 0xFF]) - - # Remove remaining owls - rom.write_bytes(0x1FE30CE, [0x01, 0x4B]) - rom.write_bytes(0x1FE30DE, [0x01, 0x4B]) - rom.write_bytes(0x1FE30EE, [0x01, 0x4B]) - rom.write_bytes(0x205909E, [0x00, 0x3F]) - rom.write_byte(0x2059094, 0x80) - - # Darunia won't dance - rom.write_bytes(0x22769E4, [0xFF, 0xFF, 0xFF, 0xFF]) - - # Zora moves quickly - rom.write_bytes(0xE56924, [0x00, 0x00, 0x00, 0x00]) - - # Speed Jabu Jabu swallowing Link - rom.write_bytes(0xCA0784, [0x00, 0x18, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) - - # Ruto no longer points to Zora Sapphire - rom.write_bytes(0xD03BAC, [0xFF, 0xFF, 0xFF, 0xFF]) - - # Ruto never disappears from Jabu Jabu's Belly - rom.write_byte(0xD01EA3, 0x00) - - # Speed up Epona race start - rom.write_bytes(0x29BE984, [0x00, 0x00, 0x00, 0x02]) - rom.write_bytes(0x29BE9CA, [0x00, 0x01, 0x00, 0x02]) - - # Speed start of Horseback Archery - #rom.write_bytes(0x21B2064, [0x00, 0x00, 0x00, 0x02]) - #rom.write_bytes(0x21B20AA, [0x00, 0x01, 0x00, 0x02]) - - # Speed up Epona escape - rom.write_bytes(0x1FC8B36, [0x00, 0x2A]) - - # Speed up draining the well - rom.write_bytes(0xE0A010, [0x00, 0x2A, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02]) - rom.write_bytes(0x2001110, [0x00, 0x2B, 0x00, 0xB7, 0x00, 0xB8, 0x00, 0xB8]) - - # Speed up opening the royal tomb for both child and adult - rom.write_bytes(0x2025026, [0x00, 0x01]) - rom.write_bytes(0x2023C86, [0x00, 0x01]) - rom.write_byte(0x2025159, 0x02) - rom.write_byte(0x2023E19, 0x02) - - #Speed opening of Door of Time - rom.write_bytes(0xE0A176, [0x00, 0x02]) - rom.write_bytes(0xE0A35A, [0x00, 0x01, 0x00, 0x02]) - - # Poacher's Saw no longer messes up Deku Theater - rom.write_bytes(0xAE72CC, [0x00, 0x00, 0x00, 0x00]) - - # Learning Serenade tied to opening chest in room - Block_code = [0x3C, 0x0F, 0x80, 0x1D, 0x81, 0xE8, 0xA1, 0xDB, 0x24, 0x19, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0xA2, 0x1C, 0x44, - 0x00, 0x00, 0x00, 0x00] - rom.write_bytes(0xC7BCF0, Block_code) - - # Dampe Chest spawn condition looks at chest flag instead of having obtained hookshot - Block_code = [0x93, 0x18, 0xAE, 0x7E, 0x27, 0xA5, 0x00, 0x24, 0x33, 0x19, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00] - rom.write_bytes(0xDFEC40, Block_code) - - # Darunia sets an event flag and checks for it - Block_code = [0x24, 0x19, 0x00, 0x40, 0x8F, 0x09, 0xB4, 0xA8, 0x01, 0x39, 0x40, 0x24, - 0x01, 0x39, 0xC8, 0x25, 0xAF, 0x19, 0xB4, 0xA8, 0x24, 0x09, 0x00, 0x06] - rom.write_bytes(0xCF1AB8, Block_code) - - # Change Prelude CS to check for medallion - rom.write_bytes(0x00C805E6, [0x00, 0xA6]) - rom.write_bytes(0x00C805F2, [0x00, 0x01]) - - # Change Nocturne CS to check for medallions - rom.write_bytes(0x00ACCD8E, [0x00, 0xA6]) - rom.write_bytes(0x00ACCD92, [0x00, 0x01]) - rom.write_bytes(0x00ACCD9A, [0x00, 0x02]) - rom.write_bytes(0x00ACCDA2, [0x00, 0x04]) - - # Change King Zora to move even if Zora Sapphire is in inventory - rom.write_bytes(0x00E55BB0, [0x85, 0xCE, 0x8C, 0x3C]) - rom.write_bytes(0x00E55BB4, [0x84, 0x4F, 0x0E, 0xDA]) - - # Remove extra Forest Temple medallions - rom.write_bytes(0x00D4D37C, [0x00, 0x00, 0x00, 0x00]) - - # Remove extra Fire Temple medallions - rom.write_bytes(0x00AC9754, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0x00D0DB8C, [0x00, 0x00, 0x00, 0x00]) - - # Remove extra Water Temple medallions - rom.write_bytes(0x00D57F94, [0x00, 0x00, 0x00, 0x00]) - - # Remove extra Spirit Temple medallions - rom.write_bytes(0x00D370C4, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0x00D379C4, [0x00, 0x00, 0x00, 0x00]) - - # Remove extra Shadow Temple medallions - rom.write_bytes(0x00D116E0, [0x00, 0x00, 0x00, 0x00]) - - # Change Mido, Saria, and Kokiri to check for Deku Tree complete flag - # bitwise pointer for 0x80 - kokiriAddresses = [0xE52836, 0xE53A56, 0xE51D4E, 0xE51F3E, 0xE51D96, 0xE51E1E, 0xE51E7E, 0xE51EDE, 0xE51FC6, 0xE51F96, 0xE293B6, 0xE29B8E, 0xE62EDA, 0xE630D6, 0xE62642, 0xE633AA, 0xE6369E] - for kokiri in kokiriAddresses: - rom.write_bytes(kokiri, [0x8C, 0x0C]) - # Kokiri - rom.write_bytes(0xE52838, [0x94, 0x48, 0x0E, 0xD4]) - rom.write_bytes(0xE53A58, [0x94, 0x49, 0x0E, 0xD4]) - rom.write_bytes(0xE51D50, [0x94, 0x58, 0x0E, 0xD4]) - rom.write_bytes(0xE51F40, [0x94, 0x4B, 0x0E, 0xD4]) - rom.write_bytes(0xE51D98, [0x94, 0x4B, 0x0E, 0xD4]) - rom.write_bytes(0xE51E20, [0x94, 0x4A, 0x0E, 0xD4]) - rom.write_bytes(0xE51E80, [0x94, 0x59, 0x0E, 0xD4]) - rom.write_bytes(0xE51EE0, [0x94, 0x4E, 0x0E, 0xD4]) - rom.write_bytes(0xE51FC8, [0x94, 0x49, 0x0E, 0xD4]) - rom.write_bytes(0xE51F98, [0x94, 0x58, 0x0E, 0xD4]) - # Saria - rom.write_bytes(0xE293B8, [0x94, 0x78, 0x0E, 0xD4]) - rom.write_bytes(0xE29B90, [0x94, 0x68, 0x0E, 0xD4]) - # Mido - rom.write_bytes(0xE62EDC, [0x94, 0x6F, 0x0E, 0xD4]) - rom.write_bytes(0xE630D8, [0x94, 0x4F, 0x0E, 0xD4]) - rom.write_bytes(0xE62644, [0x94, 0x6F, 0x0E, 0xD4]) - rom.write_bytes(0xE633AC, [0x94, 0x68, 0x0E, 0xD4]) - rom.write_bytes(0xE636A0, [0x94, 0x48, 0x0E, 0xD4]) - - # Change adult Kokiri Forest to check for Forest Temple complete flag - rom.write_bytes(0xE5369E, [0xB4, 0xAC]) - rom.write_bytes(0xD5A83C, [0x80, 0x49, 0x0E, 0xDC]) - - # Change adult Goron City to check for Fire Temple complete flag - rom.write_bytes(0xED59DC, [0x80, 0xC9, 0x0E, 0xDC]) - - # Change Pokey to check DT complete flag - rom.write_bytes(0xE5400A, [0x8C, 0x4C]) - rom.write_bytes(0xE5400E, [0xB4, 0xA4]) - if world.open_forest: - rom.write_bytes(0xE5401C, [0x14, 0x0B]) - - # Fix Shadow Temple to check for different rewards for scene - rom.write_bytes(0xCA3F32, [0x00, 0x00, 0x25, 0x4A, 0x00, 0x10]) - - # Fix Spirit Temple to check for different rewards for scene - rom.write_bytes(0xCA3EA2, [0x00, 0x00, 0x25, 0x4A, 0x00, 0x08]) - - # Fire Arrows now in a chest, always spawn - rom.write_bytes(0xE9E202, [0x00, 0x0A]) - rom.write_bytes(0xE9E1F2, [0x5B, 0x08]) - rom.write_bytes(0xE9E1D8, [0x00, 0x00, 0x00, 0x00]) - - # Fix Biggoron to check a different flag. - rom.write_byte(0xED329B, 0x72) - rom.write_byte(0xED43E7, 0x72) - rom.write_bytes(0xED3370, [0x3C, 0x0D, 0x80, 0x12]) - rom.write_bytes(0xED3378, [0x91, 0xB8, 0xA6, 0x42, 0xA1, 0xA8, 0xA6, 0x42]) - rom.write_bytes(0xED6574, [0x00, 0x00, 0x00, 0x00]) - - # Remove the check on the number of days that passed for claim check. - rom.write_bytes(0xED4470, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xED4498, [0x00, 0x00, 0x00, 0x00]) - - # Fixed reward order for Bombchu Bowling - rom.write_bytes(0xE2E698, [0x80, 0xAA, 0xE2, 0x64]) - rom.write_bytes(0xE2E6A0, [0x80, 0xAA, 0xE2, 0x4C]) - rom.write_bytes(0xE2D440, [0x24, 0x19, 0x00, 0x00]) - - # Make fishing less obnoxious - Block_code = [0x3C, 0x0A, 0x80, 0x12, 0x8D, 0x4A, 0xA5, 0xD4, 0x14, 0x0A, 0x00, 0x06, - 0x31, 0x78, 0x00, 0x01, 0x14, 0x18, 0x00, 0x02, 0x3c, 0x18, 0x42, 0x30, - 0x3C, 0x18, 0x42, 0x50, 0x03, 0xe0, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x18, 0x00, 0x02, 0x3C, 0x18, 0x42, 0x10, 0x3C, 0x18, 0x42, 0x38, - 0x03, 0xE0, 0x00, 0x08] - rom.write_bytes(0x3480C00, Block_code) - rom.write_bytes(0xDBF434, [0x44, 0x98, 0x90, 0x00, 0xE6, 0x52, 0x01, 0x9C]) - rom.write_bytes(0xDBF484, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xDBF4A8, [0x00, 0x00, 0x00, 0x00]) - rom.write_bytes(0xDCBEAA, [0x42, 0x48]) #set adult fish size requirement - rom.write_bytes(0xDCBF26, [0x42, 0x48]) #set adult fish size requirement - rom.write_bytes(0xDCBF32, [0x42, 0x30]) #set child fish size requirement - rom.write_bytes(0xDCBF9E, [0x42, 0x30]) #set child fish size requirement - - # Dampe always digs something up and first dig is always the Piece of Heart - rom.write_bytes(0xCC3FA8, [0xA2, 0x01, 0x01, 0xF8]) - rom.write_bytes(0xCC4024, [0x00, 0x00, 0x00, 0x00]) - - # Allow owl to always carry the kid down Death Mountain - rom.write_bytes(0xE304F0, [0x24, 0x0E, 0x00, 0x01]) - - # Forbid Sun's Song from a bunch of cutscenes - Suns_scenes = [0x2016FC9, 0x2017219, 0x20173D9, 0x20174C9, 0x2017679, 0x20C1539, 0x20C15D9, 0x21A0719, 0x21A07F9, 0x2E90129, 0x2E901B9, 0x2E90249, 0x225E829, 0x225E939, 0x306D009] - for address in Suns_scenes: - rom.write_byte(address,0x01) - - # Remove forcible text triggers - Wonder_text = [0x27C00C6, 0x27C00D6, 0x27C00E6, 0x27C00F6, 0x27C0106, 0x27C0116, 0x27C0126, 0x27C0136] - for address in Wonder_text: - rom.write_byte(address, 0x02) - rom.write_byte(0x27CE08A, 0x09) - rom.write_byte(0x27CE09A, 0x0F) - Wonder_text = [0x288707A, 0x288708A, 0x288709A, 0x289707A, 0x28C713E, 0x28D91C6] - for address in Wonder_text: - rom.write_byte(address, 0x0C) - Wonder_text = [0x28A60FE, 0x28AE08E, 0x28B917E, 0x28BF172, 0x28BF182, 0x28BF192] - for address in Wonder_text: - rom.write_byte(address, 0x0D) - rom.write_byte(0x28A114E, 0x0E) - rom.write_byte(0x28A610E, 0x0E) - Wonder_text = [0x9367F6, 0x93673D, 0x93679D] - for address in Wonder_text: - rom.write_byte(address, 0x08) - Wonder_text = [0x289707B, 0x28AE08F, 0x28C713F] - for address in Wonder_text: - rom.write_byte(address, 0xAF) - rom.write_byte(0x28A114F, 0x6F) - rom.write_byte(0x28B917F, 0x6F) - rom.write_byte(0x28A60FF, 0xEF) - rom.write_byte(0x28D91C7, 0xEF) - Wonder_text = [0x28A610F, 0x28BF173, 0x28BF183, 0x28BF193] - for address in Wonder_text: - rom.write_byte(address, 0x2F) - Wonder_text = [0x27CE08B, 0x27C00C7, 0x27C00D7, 0x27C0117, 0x27C0127] - for address in Wonder_text: - rom.write_byte(address, 0x3D) - rom.write_byte(0x27C00E7, 0x7D) - rom.write_byte(0x27C00F7, 0x7D) - rom.write_byte(0x27C0107, 0xBD) - rom.write_byte(0x27C0137, 0xBD) - Wonder_text = [0x27C00BC, 0x27C00CC, 0x27C00DC, 0x27C00EC, 0x27C00FC, 0x27C010C, 0x27C011C, 0x27C012C, 0x27CE080, 0x27CE090, 0x2887070, 0x2887080, 0x2887090, 0x2897070, 0x28C7134, 0x28D91BC, 0x28A60F4, 0x28AE084, 0x28B9174, 0x28BF168, 0x28BF178, 0x28BF188, 0x28A1144, 0x28A6104] - for address in Wonder_text: - rom.write_byte(address, 0xFE) - - # Speed text - for address in text_array: - rom.write_byte(address, 0x08) - - # Speed Happy Mask shop text - rom.write_bytes(0x9602E4, [0x08, 0x48, 0x69, 0x79, 0x65, 0x65, 0x21, 0x01]) - rom.write_bytes(0x960344, [0x08, 0x08, 0x08, 0x08, 0x57]) - Block_code = [0x6D, 0x6F, 0x6E, 0x65, 0x79, 0x20, 0x05, 0x40, 0x62, 0x61, 0x63, 0x6B, - 0x20, 0x68, 0x65, 0x72, 0x65, 0x2E, 0x04, 0x08, 0x08] - rom.write_bytes(0x9603AB, Block_code) - Block_code = [0x73, 0x69, 0x67, 0x6E, 0x20, 0x01, 0x05, 0x40, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, - 0x2E, 0x04, 0x08, 0x08] - rom.write_bytes(0x9603F8, Block_code) - rom.write_bytes(0x961160, [0x08, 0x08, 0x08, 0x08]) - rom.write_bytes(0x9611AF, [0x08, 0x08, 0x08, 0x08, 0x44]) - rom.write_bytes(0x9609F0, [0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x54]) - rom.write_bytes(0x960459, [0x08, 0x08]) - rom.write_bytes(0x9604C4, [0x08, 0x08, 0x41, 0x20, 0x6D, 0x61, 0x73, 0x6B, 0x20, 0x08, 0x08]) - rom.write_bytes(0x960513, [0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x54]) - Block_code = [0x08, 0x53, 0x6F, 0x6D, 0x65, 0x6F, 0x6E, 0x65, 0x20, 0x6D, 0x61, 0x79, - 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x01, 0x6D, - 0x61, 0x73, 0x6B, 0x2E, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08] - rom.write_bytes(0x960555, Block_code) - rom.write_bytes(0x9605F5, [0x08, 0x08]) - Block_code = [0x08, 0x50, 0x61, 0x79, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x72, 0x65, 0x63, - 0x65, 0x69, 0x76, 0x65, 0x64, 0x21, 0x0B, 0x02] - rom.write_bytes(0x960718, Block_code) - Block_code = [0x08, 0x56, 0x65, 0x72, 0x79, 0x20, 0x77, 0x65, 0x6C, 0x6C, 0x20, 0x64, - 0x6F, 0x6E, 0x65, 0x21, 0x01, 0x41, 0x6C, 0x6C, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x6D, 0x61, 0x73, 0x6B, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, - 0x6F, 0x6C, 0x64, 0x20, 0x6F, 0x75, 0x74, 0x2E, 0x01, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08] - rom.write_bytes(0x96078C, Block_code) - rom.write_bytes(0x960913, [0x04, 0x08, 0x08]) - Block_code = [0x08, 0x46, 0x72, 0x6F, 0x6D, 0x20, 0x6E, 0x6F, 0x77, 0x20, 0x6F, 0x6E, - 0x20, 0x79, 0x6F, 0x75, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x62, 0x6F, 0x72, - 0x72, 0x6F, 0x77, 0x20, 0x61, 0x6E, 0x79, 0x01, 0x6D, 0x61, 0x73, 0x6B, - 0x20, 0x79, 0x6F, 0x75, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x2E, 0x01, 0x4A, - 0x75, 0x73, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x66, 0x61, 0x69, - 0x74, 0x68, 0x2E, 0x2E, 0x2E, 0x0B, 0x02] - rom.write_bytes(0x960924, Block_code) - Block_code = [0x08, 0x08, 0x08, 0x57, 0x65, 0x6C, 0x63, 0x6F, 0x6D, 0x65, 0x21, 0x01, - 0x57, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6D, 0x61, 0x73, 0x6B, 0x20, 0x63, - 0x61, 0x6E, 0x20, 0x49, 0x20, 0x6C, 0x65, 0x6E, 0x64, 0x20, 0x79, 0x6F, - 0x75, 0x3F, 0x0B, 0x02] - rom.write_bytes(0x960968, Block_code) - Block_code = [0x08, 0x57, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6D, - 0x61, 0x73, 0x6B, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x63, 0x61, 0x6E, 0x20, - 0x73, 0x65, 0x65, 0x20, 0x69, 0x6E, 0x74, 0x6F, 0x20, 0x01, 0x08, 0x08, - 0x08, 0x20, 0x70, 0x65, 0x6F, 0x70, 0x6C, 0x65, 0x27, 0x73, 0x20, 0x6D, - 0x69, 0x6E, 0x64, 0x73, 0x2E, 0x20, 0x49, 0x74, 0x27, 0x73, 0x20, 0x75, - 0x73, 0x65, 0x66, 0x75, 0x6C, 0x2C, 0x01, 0x62, 0x75, 0x74, 0x20, 0x73, - 0x63, 0x61, 0x72, 0x79, 0x21, 0x04, 0x08] - rom.write_bytes(0x960A44, Block_code) - rom.write_byte(0x960AA3, 0x01) - rom.write_byte(0x960AC6, 0x01) - Happy_mask_turn_ins = [0x96066C, 0x961064, 0x9610B8, 0x96110C] #addresses with the same fix for lines upon returning profits from a sold mask - for address in Happy_mask_turn_ins: - rom.write_bytes(address, [0x08, 0x08, 0x08, 0x08, 0x47]) - - # Speed up various shops - rom.write_bytes(0x9550D0, [0x08, 0x48, 0x65, 0x79, 0x21, 0x08, 0x08, 0x08, 0x08]) - rom.write_bytes(0x93189C, [0x08, 0x4D, 0x79, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08]) - rom.write_bytes(0x95EC04, [0x08, 0x49, 0x74, 0x27, 0x73, 0x08, 0x08]) - Block_code = [0x08, 0x08, 0x08, 0x08, 0x57, 0x65, 0x20, 0x73, 0x65, 0x6C, 0x6C, 0x20, - 0x73, 0x68, 0x69, 0x65, 0x6C, 0x64, 0x73, 0x2C] - rom.write_bytes(0x941734, Block_code) - rom.write_bytes(0x949A94, [0x08, 0x59, 0x6F, 0x75, 0x27, 0x72, 0x65]) - rom.write_bytes(0x949B04, [0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x4F]) - rom.write_bytes(0x949B6A, [0x08, 0x08, 0x08, 0x08, 0x08, 0x4C]) - rom.write_bytes(0x949BC0, [0x08, 0x08, 0x08, 0x57]) - Block_code = [0x08, 0x08, 0x08, 0x08, 0x08, 0x57, 0x61, 0x6E, 0x74, 0x20, 0x74, 0x6F, - 0x20, 0x62, 0x79, 0x20, 0x66, 0x69, 0x73, 0x68, 0x3F, 0x20, 0x59, 0x6F, - 0x75, 0x27, 0x6C, 0x6C] - rom.write_bytes(0x94E57C, Block_code) - Block_code = [0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x54, 0x68, 0x61, 0x6E, 0x6B, 0x73, - 0x20, 0x74, 0x6F, 0x20, 0x79, 0x6F, 0x75, 0x2C, 0x20, 0x49, 0x27, 0x6D, - 0x20, 0x4F, 0x4B, 0x21] - rom.write_bytes(0x9498C8, Block_code) - rom.write_bytes(0x927E38, Block_code) - Block_code = [0x59, 0x6F, 0x75, 0x20, 0x68, 0x65, 0x61, 0x72, 0x64, 0x20, 0x61, 0x62, - 0x6F, 0x75, 0x74, 0x20, 0x75, 0x73, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, - 0x74, 0x68, 0x65, 0x01, 0x67, 0x75, 0x61, 0x72, 0x64, 0x20, 0x61, 0x74, - 0x20, 0x44, 0x65, 0x61, 0x74, 0x68, 0x20, 0x4D, 0x6F, 0x75, 0x6E, 0x74, - 0x61, 0x69, 0x6E, 0x20, 0x67, 0x61, 0x74, 0x65, 0x3F, 0x01, 0x08, 0x08, - 0x08, 0x08, 0x08] - rom.write_bytes(0x9650BC, Block_code) - Block_code = [0x08, 0x08, 0x08, 0x08, 0x57, 0x65, 0x20, 0x6D, 0x6F, 0x76, 0x65, 0x64, - 0x20, 0x68, 0x65, 0x72, 0x65, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x43, - 0x61, 0x73, 0x74, 0x6C, 0x65, 0x20, 0x01, 0x54] - rom.write_bytes(0x9318F8, Block_code) - Block_code = [0x08, 0x41, 0x6E, 0x20, 0x6F, 0x6C, 0x64, 0x20, 0x77, 0x69, 0x74, 0x63, - 0x68, 0x20, 0x72, 0x75, 0x6E, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x50, - 0x6F, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x68, 0x6F, 0x70, 0x01, 0x62, - 0x65, 0x68, 0x69, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6F, - 0x6E, 0x65, 0x2E, 0x20, 0x59, 0x6F, 0x75, 0x20, 0x63, 0x61, 0x6E, 0x20, - 0x67, 0x65, 0x74, 0x20, 0x74, 0x6F, 0x01] - rom.write_bytes(0x954DA0, Block_code) - Block_code = [0x08, 0x45, 0x76, 0x65, 0x72, 0x79, 0x62, 0x6F, 0x64, 0x79, 0x20, 0x68, - 0x61, 0x73, 0x20, 0x63, 0x6F, 0x6D, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6B, - 0x21, 0x01, 0x49, 0x74, 0x27, 0x73, 0x20, 0x62, 0x75, 0x73, 0x69, 0x6E, - 0x65, 0x73, 0x73, 0x20, 0x61, 0x73, 0x20, 0x75, 0x73, 0x75, 0x61, 0x6C, - 0x21, 0x0B, 0x02] - rom.write_bytes(0x94B57C, Block_code) - rom.write_bytes(0x94B3AC, [0x08, 0x4F, 0x68, 0x20, 0x6E, 0x6F, 0x21, 0x20]) - Block_code = [0x08, 0x08, 0x08, 0x08, 0x08, 0x44, 0x6F] - rom.write_bytes(0x94E5BC, Block_code) - rom.write_bytes(0x92CB2C, Block_code) - Block_code = [0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08] - rom.write_bytes(0x94E639, Block_code) - rom.write_bytes(0x92CBA9, Block_code) - rom.write_bytes(0x9650BC, [0x08, 0x08, 0x08, 0x08, 0x48]) - - # Speed dig text for Dampe - rom.write_bytes(0x9532F8, [0x08, 0x08, 0x08, 0x59]) - - # Make item descriptions into a single box - Short_item_descriptions = [0x92EC84, 0x92F9E3, 0x92F2B4, 0x92F37A, 0x92F513, 0x92F5C6, 0x92E93B, 0x92EA12] - for address in Short_item_descriptions: - rom.write_byte(address,0x02) - - # Fix text for Pocket Cucco. - rom.write_byte(0xBEEF45, 0x0B) - rom.write_byte(0x92D41A, 0x2E) - Block_code = [0x59, 0x6f, 0x75, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x61, 0x20, 0x05, 0x41, - 0x50, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x20, 0x43, 0x75, 0x63, 0x63, 0x6f, - 0x2c, 0x20, 0x05, 0x40, 0x6f, 0x6e, 0x65, 0x01, 0x6f, 0x66, 0x20, 0x41, - 0x6e, 0x6a, 0x75, 0x27, 0x73, 0x20, 0x70, 0x72, 0x69, 0x7a, 0x65, 0x64, - 0x20, 0x68, 0x65, 0x6e, 0x73, 0x21, 0x20, 0x49, 0x74, 0x20, 0x66, 0x69, - 0x74, 0x73, 0x20, 0x01, 0x69, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, - 0x70, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x02] - rom.write_bytes(0x92D41C, Block_code) - - # DMA in extra code - Block_code = [0xAF, 0xBF, 0x00, 0x1C, 0xAF, 0xA4, 0x01, 0x40, 0x3C, 0x05, 0x03, 0x48, - 0x3C, 0x04, 0x80, 0x40, 0x0C, 0x00, 0x03, 0x7C, 0x24, 0x06, 0x50, 0x00, - 0x0C, 0x10, 0x02, 0x00] - rom.write_bytes(0xB17BB4, Block_code) - Block_code = [0x3C, 0x02, 0x80, 0x12, 0x24, 0x42, 0xD2, 0xA0, 0x24, 0x0E, 0x01, 0x40, - 0xAC, 0x2E, 0xE5, 0x00, 0x03, 0xE0, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00] - rom.write_bytes(0x3480800, Block_code) - rom.write_bytes(0xD270, [0x03, 0x48, 0x00, 0x00, 0x03, 0x48, 0x50, 0x00, 0x03, 0x48, 0x00, 0x00]) - - # Fix checksum (Thanks Nintendo) - Block_code = [0x93, 0x5E, 0x8E, 0x5B, 0xD0, 0x9C, 0x5A, 0x58] - rom.write_bytes(0x10, Block_code) - - # Set hooks for various code -# rom.write_bytes(0xBD6C94, ...) #Progressive Items Object Hook, unsure where this case is called - rom.write_bytes(0xB06C2C, [0x0C, 0x10, 0x01, 0x80]) #Save Writing Hook - rom.write_bytes(0xDBF428, [0x0C, 0x10, 0x03, 0x00]) #Set Fishing Hook - - # Write Initial Save File - Block_code = [0xA2, 0x28, 0x80, 0x20, 0x24, 0x05, 0x80, 0x02, 0x24, 0x0F, 0x00, 0x84, - 0x24, 0x18, 0x00, 0x01, 0x24, 0x19, 0x00, 0x08, 0x24, 0x08, 0x00, 0x80, - 0xA6, 0x25, 0x00, 0xD8, 0xA2, 0x2F, 0x00, 0xDA, 0xA2, 0x38, 0x01, 0x65, - 0xA2, 0x39, 0x09, 0xB6, 0xA2, 0x28, 0x0A, 0x24, 0xA2, 0x38, 0x0A, 0xCE, - 0xA2, 0x28, 0x0A, 0xCF, 0xA2, 0x28, 0x0A, 0xE8, 0x24, 0x05, 0x00, 0x20, - 0xA2, 0x25, 0x0B, 0x3F, 0xA2, 0x28, 0x0E, 0xDC, 0xA2, 0x25, 0x0E, 0xDD, - 0xA2, 0x25, 0x0E, 0xED, 0xA2, 0x38, 0x0E, 0xF9, 0xA2, 0x39, 0x0E, 0xDA, - 0xA2, 0x28, 0x0E, 0xE0, 0xA2, 0x38, 0x02, 0x0E, 0xA2, 0x39, 0x01, 0x49, - 0xA2, 0x39, 0x0E, 0xD6, 0x24, 0x05, 0x01, 0xFF, 0x24, 0x0F, 0x01, 0xFB, - 0x24, 0x18, 0x07, 0xFF, 0x24, 0x19, 0x00, 0x04, 0x24, 0x08, 0x00, 0x30, - 0xA6, 0x25, 0x0E, 0xE2, 0xA6, 0x2F, 0x0E, 0xE8, 0xA6, 0x38, 0x0E, 0xEA, - 0xA2, 0x28, 0x0E, 0xE7, 0xA2, 0x39, 0x0F, 0x1A, 0x24, 0x08, 0x10, 0x20, - 0x24, 0x19, 0x00, 0x2C, 0x24, 0x18, 0x00, 0x49, 0x24, 0x0F, 0x00, 0x02, - 0x24, 0x05, 0x00, 0x40, 0xA6, 0x28, 0x0E, 0xD4, 0x00, 0x00, 0x00, 0x00, - 0xA2, 0x38, 0x00, 0xF6, 0xA2, 0x2F, 0x00, 0x3F, 0xA2, 0x25, 0x0A, 0x42, - 0x92, 0x25, 0x0E, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xA2, 0x25, 0x0E, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x24, 0x08, 0x0F, 0x01, 0x24, 0x19, 0x00, 0x09, - 0x24, 0x18, 0x00, 0x03, 0x24, 0x0F, 0x00, 0x04, 0x24, 0x05, 0x00, 0x06, - 0xA6, 0x28, 0x01, 0x10, 0xA2, 0x39, 0x01, 0x2C, 0xA2, 0x38, 0x01, 0x2E, - 0xA2, 0x2F, 0x0F, 0x0A, 0xA2, 0x25, 0x0F, 0x21, 0x24, 0x05, 0x00, 0x00, - 0xA2, 0x25, 0x00, 0xA7, 0x24, 0x0F, 0x00, 0x21, 0xA2, 0x2F, 0x0E, 0xED, - 0x24, 0x0F, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x08] - rom.write_bytes(0x3480600, Block_code) - - # Set up for Rainbow Bridge dungeons condition - Block_code = [0x15, 0x41, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0xEA, 0x00, 0xA5, - 0x24, 0x01, 0x00, 0x1C, 0x31, 0x4A, 0x00, 0x1C, 0x08, 0x07, 0x88, 0xD9] - rom.write_bytes(0x3480820, Block_code) - - # Gossip stones resond to stone of agony - Block_code = [0x3C, 0x01, 0x80, 0x12, 0x80, 0x21, 0xA6, 0x75, 0x30, 0x21, 0x00, 0x20, - 0x03, 0xE0, 0x00, 0x08] - rom.write_bytes(0x3480840, Block_code) - - # Set up Rainbow Bridge conditions - if world.bridge == 'medallions': - Block_code = [0x80, 0xEA, 0x00, 0xA7, 0x24, 0x01, 0x00, 0x3F, - 0x31, 0x4A, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00] - rom.write_bytes(0xE2B454, Block_code) - elif world.bridge == 'open': - rom.write_bytes(0x34806B8, [0x34, 0xA5, 0x00, 0x20]) - elif world.bridge == 'dungeons': - Block_code = [0x80, 0xEA, 0x00, 0xA7, 0x24, 0x01, 0x00, 0x3F, - 0x08, 0x10, 0x02, 0x08, 0x31, 0x4A, 0x00, 0x3F] - rom.write_bytes(0xE2B454, Block_code) - - if world.open_forest: - #rom.write_byte(0x2081148, 0x80) - rom.write_bytes(0x34806C4, [0x92, 0x25, 0x0E, 0xD5, 0x34, 0xA5, 0x00, 0x10, 0xA2, 0x25, 0x0E, 0xD5]) - - if world.open_door_of_time: - rom.write_bytes(0x34806BC, [0x34, 0xA5, 0x00, 0x08]) - - if world.fast_ganon: - rom.write_bytes(0xD82A12, [0x05, 0x17]) # Sets exit from Ganondorf fight to entrance to Ganon fight - rom.write_byte(0x348066A, 0x21) # Flag Spirit Trial as clear - rom.write_byte(0x348066E, 0xFF) # Flag the other five trials as clear - rom.write_byte(0x3480703, 0x29) # The barrier is dispelled. - rom.write_bytes(0x348070C, [0xA2, 0x2F, 0x01, 0xF1]) # Remove Ganon's Castle Boss Key door - - # Sets hooks for gossip stone changes - if world.hints: - rom.write_bytes(0xEE7B84, [0x0C, 0x10, 0x02, 0x10]) - rom.write_bytes(0xEE7B8C, [0x24, 0x02, 0x00, 0x20]) - address = 0xB85B11 - offset = 0xBE4C - for i in range(0,33): - offset_high = offset >> 8 - offset_low = offset & 0x00FF - rom.write_bytes(address, [0x00, offset_high, offset_low]) - offset = offset + 0x5C - address = address + 0x08 - buildGossipHints(world, rom) - - # Set hints for boss reward shuffle - rom.write_bytes(0xE2ADB2, [0x70, 0x7A]) - rom.write_bytes(0xE2ADB6, [0x70, 0x57]) - rom.write_byte(0xB8811E, 0x20) - rom.write_byte(0xB88236, 0x20) - buildBossRewardHints(world, rom) - - # build silly ganon lines - buildGanonText(world, rom) - - # Write item overrides - rom.write_bytes(0x3481000, get_override_table(world)) - - # Patch songs and boss rewards - for location in world.get_locations(): - item = location.item - itemid = item.code - locationaddress = location.address - secondaryaddress = location.address2 - - if itemid is None or location.address is None: - continue - - if location.type == 'Song': - rom.write_byte(locationaddress, itemid) - itemid = itemid + 0x0D - rom.write_byte(secondaryaddress, itemid) - if location.name == 'Impa at Castle': - impa_fix = 0x65 - item.index - rom.write_byte(0xD12ECB, impa_fix) - impa_fix = 0x8C34 - (item.index * 4) - impa_fix_high = impa_fix >> 8 - impa_fix_low = impa_fix & 0x00FF - rom.write_bytes(0xB063FE, [impa_fix_high, impa_fix_low]) - rom.write_byte(0x2E8E931, item_data[item.name]) #Fix text box - elif location.name == 'Song from Malon': - if item.name == 'Suns Song': - rom.write_byte(locationaddress, itemid) - malon_fix = 0x8C34 - (item.index * 4) - malon_fix_high = malon_fix >> 8 - malon_fix_low = malon_fix & 0x00FF - rom.write_bytes(0xD7E142, [malon_fix_high, malon_fix_low]) - #rom.write_bytes(0xD7E8D6, [malon_fix_high, malon_fix_low]) # I don't know what this does, may be useful? - rom.write_bytes(0xD7E786, [malon_fix_high, malon_fix_low]) - rom.write_byte(0x29BECB9, item_data[item.name]) #Fix text box - elif location.name == 'Song from Composer Grave': - sun_fix = 0x8C34 - (item.index * 4) - sun_fix_high = sun_fix >> 8 - sun_fix_low = sun_fix & 0x00FF - rom.write_bytes(0xE09F66, [sun_fix_high, sun_fix_low]) - rom.write_byte(0x332A87D, item_data[item.name]) #Fix text box - elif location.name == 'Song from Saria': - saria_fix = 0x65 - item.index - rom.write_byte(0xE2A02B, saria_fix) - saria_fix = 0x8C34 - (item.index * 4) - saria_fix_high = saria_fix >> 8 - saria_fix_low = saria_fix & 0x00FF - rom.write_bytes(0xE29382, [saria_fix_high, saria_fix_low]) - rom.write_byte(0x20B1DBD, item_data[item.name]) #Fix text box - elif location.name == 'Song from Ocarina of Time': - rom.write_byte(0x252FC95, item_data[item.name]) #Fix text box - elif location.name == 'Song at Windmill': - windmill_fix = 0x65 - item.index - rom.write_byte(0xE42ABF, windmill_fix) - rom.write_byte(0x3041091, item_data[item.name]) #Fix text box - elif location.name == 'Sheik Forest Song': - minuet_fix = 0x65 - item.index - rom.write_byte(0xC7BAA3, minuet_fix) - rom.write_byte(0x20B0815, item_data[item.name]) #Fix text box - elif location.name == 'Sheik at Temple': - prelude_fix = 0x65 - item.index - rom.write_byte(0xC805EF, prelude_fix) - rom.write_byte(0x2531335, item_data[item.name]) #Fix text box - elif location.name == 'Sheik in Crater': - bolero_fix = 0x65 - item.index - rom.write_byte(0xC7BC57, bolero_fix) - rom.write_byte(0x224D7FD, item_data[item.name]) #Fix text box - elif location.name == 'Sheik in Ice Cavern': - serenade_fix = 0x65 - item.index - rom.write_byte(0xC7BD77, serenade_fix) - rom.write_byte(0x2BEC895, item_data[item.name]) #Fix text box - elif location.name == 'Sheik in Kakariko': - nocturne_fix = 0x65 - item.index - rom.write_byte(0xAC9A5B, nocturne_fix) - rom.write_byte(0x2000FED, item_data[item.name]) #Fix text box - elif location.name == 'Sheik at Colossus': - rom.write_byte(0x218C589, item_data[item.name]) #Fix text box - elif location.type == 'Boss': - if location.name == 'Links Pocket': - rom.write_byte(locationaddress, item_data[item.name][0]) - rom.write_byte(secondaryaddress, item_data[item.name][1]) - else: - rom.write_byte(locationaddress, itemid) - rom.write_byte(secondaryaddress, item_data[item.name][2]) - if location.name == 'Bongo Bongo': - rom.write_bytes(0xCA3F32, [item_data[item.name][3][0], item_data[item.name][3][1]]) - rom.write_bytes(0xCA3F36, [item_data[item.name][3][2], item_data[item.name][3][3]]) - elif location.name == 'Twinrova': - rom.write_bytes(0xCA3EA2, [item_data[item.name][3][0], item_data[item.name][3][1]]) - rom.write_bytes(0xCA3EA6, [item_data[item.name][3][2], item_data[item.name][3][3]]) - - # patch tunic colors - # Custom color tunic stuff - Tunics = [] - Tunics.append(0x00B6DA38) # Kokiri Tunic - Tunics.append(0x00B6DA3B) # Goron Tunic - Tunics.append(0x00B6DA3E) # Zora Tunic - colorList = ['Kokiri Green', 'Goron Red', 'Zora Blue', 'Black', 'White', 'Purple', 'Yellow', 'Orange', 'Pink', 'Gray', 'Brown', 'Gold', 'Silver', 'Beige', 'Teal', 'Royal Blue', 'Sonic Blue', 'Blood Red', 'Blood Orange', 'NES Green', 'Dark Green'] - randomColors = random.choices(colorList, k=3) - - for i in range(len(Tunics)): - if world.colors[i] == 'Random': - thisColor = randomColors[i] - else: - thisColor = world.colors[i] - randColor = [random.getrandbits(8), random.getrandbits(8), random.getrandbits(8)] - if thisColor == 'Kokiri Green': - color = [0x1E, 0x69, 0x1B] - elif thisColor == 'Goron Red': - color = [0x64, 0x14, 0x00] - elif thisColor == 'Zora Blue': - color = [0x00, 0x3C, 0x64] - elif thisColor == 'Black': - color = [0x30, 0x30, 0x30] - elif thisColor == 'White': - color = [0xF0, 0xF0, 0xFF] - elif thisColor == 'Purple': - color = [0x95, 0x30, 0x80] - elif thisColor == 'Yellow': - color = [0xE0, 0xD8, 0x60] - elif thisColor == 'Orange': - color = [0xE0, 0x79, 0x40] - elif thisColor == 'Pink': - color = [0xFF, 0x90, 0xB3] - elif thisColor == 'Gray': - color = [0xA0, 0xA0, 0xB0] - elif thisColor == 'Brown': - color = [0x95, 0x59, 0x0A] - elif thisColor == 'Gold': - color = [0xD8, 0xB0, 0x60] - elif thisColor == 'Silver': - color = [0xD0, 0xF0, 0xFF] - elif thisColor == 'Beige': - color = [0xC0, 0xA0, 0xA0] - elif thisColor == 'Teal': - color = [0x30, 0xD0, 0xB0] - elif thisColor == 'Royal Blue': - color = [0x40, 0x00, 0x90] - elif thisColor == 'Sonic Blue': - color = [0x50, 0x90, 0xE0] - elif thisColor == 'Blood Red': - color = [0x30, 0x10, 0x10] - elif thisColor == 'Blood Orange': - color = [0xF0, 0x30, 0x30] - elif thisColor == 'NES Green': - color = [0x00, 0xD0, 0x00] - elif thisColor == 'Dark Green': - color = [0x00, 0x25, 0x18] - elif thisColor == 'True Random': - color = randColor - rom.write_bytes(Tunics[i], color) - - #Low health beep - healthSFXList = ['Default', 'Softer Beep', 'Rupee', 'Timer', 'Tamborine', 'Recovery Heart', 'Carrot Refill', 'Navi - Hey!', 'Zelda - Gasp', 'Cluck', 'Mweep!', 'None'] - randomSFX = random.choice(healthSFXList) - address = 0xADBA1A - - if world.healthSFX == 'Random': - thisHealthSFX = randomSFX - else: - thisHealthSFX = world.healthSFX - if thisHealthSFX == 'Default': - healthSFX = [0x48, 0x1B] - elif thisHealthSFX == 'Softer Beep': - healthSFX = [0x48, 0x04] - elif thisHealthSFX == 'Rupee': - healthSFX = [0x48, 0x03] - elif thisHealthSFX == 'Timer': - healthSFX = [0x48, 0x1A] - elif thisHealthSFX == 'Tamborine': - healthSFX = [0x48, 0x42] - elif thisHealthSFX == 'Recovery Heart': - healthSFX = [0x48, 0x0B] - elif thisHealthSFX == 'Carrot Refill': - healthSFX = [0x48, 0x45] - elif thisHealthSFX == 'Navi - Hey!': - healthSFX = [0x68, 0x5F] - elif thisHealthSFX == 'Zelda - Gasp': - healthSFX = [0x68, 0x79] - elif thisHealthSFX == 'Cluck': - healthSFX = [0x28, 0x12] - elif thisHealthSFX == 'Mweep!': - healthSFX = [0x68, 0x7A] - elif thisHealthSFX == 'None': - healthSFX = [0x00, 0x00, 0x00, 0x00] - address = 0xADBA14 - rom.write_bytes(address, healthSFX) - - return rom - -def get_override_table(world): - override_entries = [] - for location in world.get_locations(): - override_entries.append(get_override_entry(location)) - override_entries.sort() - return sum(override_entries, []) - -def get_override_entry(location): - scene = location.scene - default = location.default - item_id = location.item.index - if None in [scene, default, item_id]: - return [] - - if location.type in ['NPC', 'BossHeart']: - return [scene, 0x00, default, item_id] - elif location.type == 'Chest': - flag = default & 0x1F - return [scene, 0x01, flag, item_id] - elif location.type == 'Collectable': - return [scene, 0x02, default, item_id] - else: - return [] +import io +import json +import logging +import os +import platform +import struct +import subprocess +import random +import copy +from Utils import is_bundled, subprocess_args + +from Utils import local_path, data_path, default_output_path + +DMADATA_START = 0x7430 + +class LocalRom(object): + def __init__(self, settings, patch=True): + self.last_address = None + + file = settings.rom + decomp_file = 'ZOOTDEC.z64' + + os.chdir(local_path()) + + with open(data_path('symbols.json'), 'r') as stream: + symbols = json.load(stream) + self.symbols = { name: int(addr, 16) for name, addr in symbols.items() } + + try: + # Read decompressed file if it exists + self.read_rom(decomp_file) + # This is mainly for validation testing, but just in case... + self.decompress_rom_file(decomp_file, decomp_file) + except Exception as ex: + # No decompressed file, instead read Input ROM + self.read_rom(file) + self.decompress_rom_file(file, decomp_file) + + # Add file to maximum size + self.buffer.extend(bytearray([0x00] * (0x4000000 - len(self.buffer)))) + + def decompress_rom_file(self, file, decomp_file): + validCRC = [ + [0xEC, 0x70, 0x11, 0xB7, 0x76, 0x16, 0xD7, 0x2B], # Compressed + [0x70, 0xEC, 0xB7, 0x11, 0x16, 0x76, 0x2B, 0xD7], # Byteswap compressed + [0x93, 0x52, 0x2E, 0x7B, 0xE5, 0x06, 0xD4, 0x27], # Decompressed + ] + + # Validate ROM file + file_name = os.path.splitext(file) + romCRC = list(self.buffer[0x10:0x18]) + if romCRC not in validCRC: + # Bad CRC validation + raise RuntimeError('ROM file %s is not a valid OoT 1.0 US ROM.' % file) + elif len(self.buffer) < 0x2000000 or len(self.buffer) > (0x4000000) or file_name[1] not in ['.z64', '.n64']: + # ROM is too big, or too small, or not a bad type + raise RuntimeError('ROM file %s is not a valid OoT 1.0 US ROM.' % file) + elif len(self.buffer) == 0x2000000: + # If Input ROM is compressed, then Decompress it + subcall = [] + + if is_bundled(): + sub_dir = "." + else: + sub_dir = "Decompress" + + if platform.system() == 'Windows': + if 8 * struct.calcsize("P") == 64: + subcall = [sub_dir + "\\Decompress.exe", file, decomp_file] + else: + subcall = [sub_dir + "\\Decompress32.exe", file, decomp_file] + elif platform.system() == 'Linux': + subcall = [sub_dir + "/Decompress", file, decomp_file] + elif platform.system() == 'Darwin': + subcall = [sub_dir + "/Decompress.out", file, decomp_file] + else: + raise RuntimeError('Unsupported operating system for decompression. Please supply an already decompressed ROM.') + + subprocess.call(subcall, **subprocess_args()) + self.read_rom(decomp_file) + else: + # ROM file is a valid and already uncompressed + pass + + def sym(self, symbol_name): + return self.symbols.get(symbol_name) + + def seek_address(self, address): + self.last_address = address + + def read_byte(self, address): + if address == None: + address = self.last_address + self.last_address = address + 1 + return self.buffer[address] + + def read_bytes(self, address, len): + if address == None: + address = self.last_address + self.last_address = address + len + return self.buffer[address : address + len] + + def read_int16(self, address): + if address == None: + address = self.last_address + self.last_address += 2 + return int16.unpack_from(self.buffer, address)[0] + + def read_int24(self, address): + if address == None: + address = self.last_address + return bytes_as_int24(self.read_bytes(address, 3)) + + def read_int32(self, address): + if address == None: + address = self.last_address + self.last_address += 4 + return int32.unpack_from(self.buffer, address)[0] + + def write_byte(self, address, value): + if address == None: + address = self.last_address + self.buffer[address] = value + self.last_address = address + 1 + + def write_sbyte(self, address, value): + if address == None: + address = self.last_address + self.write_bytes(address, struct.pack('b', value)) + + def write_int16(self, address, value): + if address == None: + address = self.last_address + self.write_bytes(address, int16_as_bytes(value)) + + def write_int24(self, address, value): + if address == None: + address = self.last_address + self.write_bytes(address, int24_as_bytes(value)) + + def write_int32(self, address, value): + if address == None: + address = self.last_address + self.write_bytes(address, int32_as_bytes(value)) + + def write_f32(self, address, value:float): + if address == None: + address = self.last_address + self.write_bytes(address, struct.pack('>f', value)) + + def write_bytes(self, startaddress, values): + if startaddress == None: + startaddress = self.last_address + for i, value in enumerate(values): + self.write_byte(startaddress + i, value) + + def write_int16s(self, startaddress, values): + if startaddress == None: + startaddress = self.last_address + for i, value in enumerate(values): + self.write_int16(startaddress + (i * 2), value) + + def write_int24s(self, startaddress, values): + if startaddress == None: + startaddress = self.last_address + for i, value in enumerate(values): + self.write_int24(startaddress + (i * 3), value) + + def write_int32s(self, startaddress, values): + if startaddress == None: + startaddress = self.last_address + for i, value in enumerate(values): + self.write_int32(startaddress + (i * 4), value) + + def write_to_file(self, file): + self.verify_dmadata() + self.update_crc() + with open(file, 'wb') as outfile: + outfile.write(self.buffer) + + def update_crc(self): + t1 = t2 = t3 = t4 = t5 = t6 = 0xDF26F436 + u32 = 0xFFFFFFFF + + words = [t[0] for t in int32.iter_unpack(self.buffer[0x1000:0x101000])] + words2 = [t[0] for t in int32.iter_unpack(self.buffer[0x750:0x850])] + + for cur in range(len(words)): + d = words[cur] + + if ((t6 + d) & u32) < t6: + t4 += 1 + + t6 = (t6+d) & u32 + t3 ^= d + shift = d & 0x1F + r = ((d << shift) | (d >> (32 - shift))) & u32 + t5 = (t5 + r) & u32 + + if t2 > d: + t2 ^= r + else: + t2 ^= t6 ^ d + + data2 = words2[cur & 0x3F] + t1 += data2 ^ d + t1 &= u32 + + crc0 = t6 ^ t4 ^ t3 + crc1 = t5 ^ t2 ^ t1 + + # Finally write the crc back to the rom + self.write_int32s(0x10, [crc0, crc1]) + + + def read_rom(self, file): + # "Reads rom into bytearray" + with open(file, 'rb') as stream: + self.buffer = bytearray(stream.read()) + + # dmadata/file management helper functions + + def _get_dmadata_record(rom, cur): + start = rom.read_int32(cur) + end = rom.read_int32(cur+0x04) + size = end-start + return start, end, size + + + def verify_dmadata(rom): + cur = DMADATA_START + overlapping_records = [] + dma_data = [] + + while True: + this_start, this_end, this_size = rom._get_dmadata_record(cur) + + if this_start == 0 and this_end == 0: + break + + dma_data.append((this_start, this_end, this_size)) + cur += 0x10 + + dma_data.sort(key=lambda v: v[0]) + + for i in range(0, len(dma_data) - 1): + this_start, this_end, this_size = dma_data[i] + next_start, next_end, next_size = dma_data[i + 1] + + if this_end > next_start: + overlapping_records.append( + '0x%08X - 0x%08X (Size: 0x%04X)\n0x%08X - 0x%08X (Size: 0x%04X)' % \ + (this_start, this_end, this_size, next_start, next_end, next_size) + ) + + if len(overlapping_records) > 0: + raise Exception("Overlapping DMA Data Records!\n%s" % \ + '\n-------------------------------------\n'.join(overlapping_records)) + + + def update_dmadata_record(rom, key, start, end): + cur = DMADATA_START + dma_start, dma_end, dma_size = rom._get_dmadata_record(cur) + while dma_start != key: + if dma_start == 0 and dma_end == 0: + break + + cur += 0x10 + dma_start, dma_end, dma_size = rom._get_dmadata_record(cur) + + if dma_start == 0: + raise Exception('dmadata update failed: key {0:x} not found in dmadata'.format(key)) + + else: + rom.write_int32s(cur, [start, end, start, 0]) + +int16 = struct.Struct('>H') +int32 = struct.Struct('>I') + +def int16_as_bytes(value): + value = value & 0xFFFF + return [(value >> 8) & 0xFF, value & 0xFF] + +def int24_as_bytes(value): + value = value & 0xFFFFFF + return [(value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF] + +def int32_as_bytes(value): + value = value & 0xFFFFFFFF + return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF] + +def bytes_as_int24(values): + return (values[0] << 16) | (values[1] << 8) | values[2] diff --git a/Rules.py b/Rules.py index 76d9d4438..6d381f349 100644 --- a/Rules.py +++ b/Rules.py @@ -1,419 +1,2206 @@ -import collections -import logging - - -def set_rules(world): - global_rules(world) - - if world.bridge == 'medallions': - # require all medallions to form the bridge - set_rule(world.get_entrance('Rainbow Bridge'), lambda state: state.has('Forest Medallion') and state.has('Fire Medallion') and state.has('Water Medallion') and state.has('Shadow Medallion') and state.has('Spirit Medallion') and state.has('Light Medallion')) - elif world.bridge == 'vanilla': - # require only what vanilla did to form the bridge - set_rule(world.get_entrance('Rainbow Bridge'), lambda state: state.has('Light Arrows') and state.has('Shadow Medallion') and state.has('Spirit Medallion')) - elif world.bridge == 'dungeons': - # require all medallions and stones to form the bridge - set_rule(world.get_entrance('Rainbow Bridge'), lambda state: state.has('Forest Medallion') and state.has('Fire Medallion') and state.has('Water Medallion') and state.has('Shadow Medallion') and state.has('Spirit Medallion') and state.has('Light Medallion') and state.has('Kokiri Emerald') and state.has('Goron Ruby') and state.has('Zora Sapphire')) - - -def set_rule(spot, rule): - spot.access_rule = rule - -def set_always_allow(spot, rule): - spot.always_allow = rule - - -def add_rule(spot, rule, combine='and'): - old_rule = spot.access_rule - if combine == 'or': - spot.access_rule = lambda state: rule(state) or old_rule(state) - else: - spot.access_rule = lambda state: rule(state) and old_rule(state) - - -def forbid_item(location, item): - old_rule = location.item_rule - location.item_rule = lambda i: i.name != item and old_rule(i) - - -def item_in_locations(state, item, locations): - for location in locations: - if item_name(state, location) == item: - return True - return False - -def item_name(state, location): - location = state.world.get_location(location) - if location.item is None: - return None - return location.item.name - - -def global_rules(world): - # ganon can only carry triforce - world.get_location('Ganon').item_rule = lambda item: item.name == 'Triforce' - - # these are default save&quit points and always accessible - world.get_region('Links House').can_reach = lambda state: True - - # overworld requirements - set_rule(world.get_entrance('Deku Tree'), lambda state: state.has('Kokiri Sword') or world.open_forest) - set_rule(world.get_entrance('Lost Woods Bridge'), lambda state: world.open_forest or (state.has('Slingshot') and state.has('Kokiri Sword'))) - set_rule(world.get_entrance('Deku Tree Basement Path'), lambda state: state.has('Slingshot')) - set_rule(world.get_location('Skull Kid'), lambda state: state.has('Sarias Song')) - set_rule(world.get_location('Ocarina Memory Game'), lambda state: state.has('Fairy Ocarina') or state.has('Ocarina of Time')) - set_rule(world.get_location('Target in Woods'), lambda state: state.has('Slingshot')) - set_rule(world.get_location('Deku Theater Skull Mask'), lambda state: state.has('Zeldas Letter')) - set_rule(world.get_location('Deku Theater Mask of Truth'), lambda state: state.has('Zeldas Letter') and state.has('Sarias Song') and state.has('Kokiri Emerald') and state.has('Goron Ruby') and state.has('Zora Sapphire') and state.guarantee_hint()) #Must befriend Skull Kid to sell Skull Mask, all stones to spawn running man. - set_rule(world.get_location('Anju as Adult'), lambda state: state.is_adult()) - set_rule(world.get_location('Man on Roof'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('Impa House Freestanding PoH'), lambda state: (state.has('Progressive Hookshot') and state.is_adult()) or state.has('Bomb Bag')) - set_rule(world.get_location('10 Gold Skulltulla Reward'), lambda state: state.has('Gold Skulltulla Token', 10)) - set_rule(world.get_location('20 Gold Skulltulla Reward'), lambda state: state.has('Gold Skulltulla Token', 20)) - set_rule(world.get_location('30 Gold Skulltulla Reward'), lambda state: state.has('Gold Skulltulla Token', 30) and state.guarantee_hint()) - set_rule(world.get_location('40 Gold Skulltulla Reward'), lambda state: state.has('Gold Skulltulla Token', 40) and state.guarantee_hint()) - set_rule(world.get_location('50 Gold Skulltulla Reward'), lambda state: state.has('Gold Skulltulla Token', 50) and state.guarantee_hint()) - set_rule(world.get_location('Heart Piece Grave Chest'), lambda state: state.has('Suns Song')) - set_rule(world.get_entrance('Composer Grave'), lambda state: state.has('Zeldas Lullaby')) - set_rule(world.get_location('Composer Grave Chest'), lambda state: state.has_fire_source()) - set_rule(world.get_entrance('Bottom of the Well'), lambda state: state.has('Song of Storms')) - set_rule(world.get_location('Bottom of the Well Front Left Hidden Wall'), lambda state: state.has('Lens of Truth') and state.has('Magic Meter')) - set_rule(world.get_location('Bottom of the Well Front Center Bombable'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Bottom of the Well Right Bottom Hidden Wall'), lambda state: state.has('Lens of Truth') and state.has('Magic Meter')) - set_rule(world.get_location('Bottom of the Well Center Large Chest'), lambda state: state.has('Lens of Truth') and state.has('Magic Meter')) - set_rule(world.get_location('Bottom of the Well Center Small Chest'), lambda state: state.has('Lens of Truth') and state.has('Magic Meter')) - set_rule(world.get_location('Bottom of the Well Back Left Bombable'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Bottom of the Well Defeat Boss'), lambda state: state.has('Zeldas Lullaby') and state.has('Kokiri Sword')) #Sword not strictly necessary but frankly being forced to do this with sticks isn't fair - set_rule(world.get_location('Bottom of the Well Invisible Chest'), lambda state: state.has('Zeldas Lullaby') and state.has('Lens of Truth') and state.has('Magic Meter')) - set_rule(world.get_location('Bottom of the Well Underwater Front Chest'), lambda state: state.has('Zeldas Lullaby')) - set_rule(world.get_location('Bottom of the Well Underwater Left Chest'), lambda state: state.has('Zeldas Lullaby')) - set_rule(world.get_location('Bottom of the Well Basement Chest'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Bottom of the Well Locked Pits'), lambda state: state.has('Small Key (Bottom of the Well)', 3) and state.has('Lens of Truth') and state.has('Magic Meter')) #These pits are really unfair. - set_rule(world.get_location('Bottom of the Well Behind Right Grate'), lambda state: state.has('Small Key (Bottom of the Well)', 3) and state.has('Lens of Truth') and state.has('Magic Meter')) - set_rule(world.get_entrance('Death Mountain Entrance'), lambda state: state.has('Zeldas Letter') or state.is_adult()) - set_rule(world.get_location('Death Mountain Bombable Chest'), lambda state: state.can_blast()) - set_rule(world.get_location('Biggoron'), lambda state: state.can_blast() and state.is_adult() and state.can_finish_adult_trades() and state.guarantee_hint()) - set_rule(world.get_location('Goron City Leftmost Maze Chest'), lambda state: state.is_adult() and (state.has('Progressive Strength Upgrade', 2) or state.has('Hammer'))) - set_rule(world.get_location('Goron City Left Maze Chest'), lambda state: state.can_blast() or (state.has('Progressive Strength Upgrade', 2) and state.is_adult())) - set_rule(world.get_location('Goron City Right Maze Chest'), lambda state: state.can_blast() or (state.has('Progressive Strength Upgrade', 2) and state.is_adult())) - set_rule(world.get_location('Rolling Goron as Child'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Goron City Pot Freestanding PoH'), lambda state: (state.has('Bomb Bag') or state.has('Progressive Strength Upgrade')) and (state.has('Zeldas Lullaby') or (state.has('Dins Fire') and state.has('Magic Meter')))) - set_rule(world.get_entrance('Darunias Chamber'), lambda state: state.has('Zeldas Lullaby')) - set_rule(world.get_location('Darunias Joy'), lambda state: state.has('Sarias Song')) - set_rule(world.get_entrance('Goron City from Woods'), lambda state: state.can_blast() and (world.open_forest or (state.has('Slingshot') and state.has('Kokiri Sword')))) - set_rule(world.get_entrance('Dodongos Cavern Rocks'), lambda state: state.can_blast() or state.has('Progressive Strength Upgrade') or state.is_adult()) - set_rule(world.get_entrance('Dodongos Cavern Lobby'), lambda state: state.can_blast() or state.has('Progressive Strength Upgrade')) - set_rule(world.get_entrance('Dodongos Cavern Left Door'), lambda state: state.has('Bomb Bag') or state.has('Progressive Strength Upgrade') or (state.has('Dins Fire') and state.has('Magic Meter'))) - set_rule(world.get_entrance('Dodongos Cavern Slingshot Target'), lambda state: state.has('Slingshot') or ((state.has('Bow') or state.has('Hover Boots')) and state.is_adult())) - set_rule(world.get_location('Dodongos Cavern End of Bridge Chest'), lambda state: state.has('Bomb Bag') or ((state.has('Bow') or state.has('Hover Boots')) and state.is_adult() and state.has('Hammer'))) - set_rule(world.get_entrance('Dodongos Cavern Bomb Drop'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Song from Saria'), lambda state: state.has('Zeldas Letter')) - set_rule(world.get_entrance('Mountain Summit Fairy'), lambda state: state.can_blast()) - set_rule(world.get_location('Crater Fairy Reward'), lambda state: state.has('Zeldas Lullaby')) - set_rule(world.get_location('Mountain Summit Fairy Reward'), lambda state: state.has('Zeldas Lullaby')) - set_rule(world.get_entrance('Mountain Crater Entrance'), lambda state: state.can_blast()) - set_rule(world.get_entrance('Hyrule Castle Fairy'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Hyrule Castle Fairy Reward'), lambda state: state.has('Zeldas Lullaby')) - set_rule(world.get_entrance('Ganons Castle Grounds'), lambda state: state.is_adult()) - set_rule(world.get_entrance('Ganons Castle Fairy'), lambda state: state.has('Progressive Strength Upgrade', 3)) - set_rule(world.get_location('Ganons Castle Fairy Reward'), lambda state: state.has('Zeldas Lullaby')) - set_rule(world.get_location('Bombchu Bowling Bomb Bag'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Bombchu Bowling Piece of Heart'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Adult Shooting Gallery'), lambda state: state.has('Bow') and state.is_adult()) - set_rule(world.get_location('10 Big Poes'), lambda state: state.has('Bow') and state.has('Epona') and state.has_bottle() and state.is_adult() and state.guarantee_hint()) - set_rule(world.get_location('Treasure Chest Game'), lambda state: state.has('Lens of Truth') and state.has('Magic Meter')) - set_rule(world.get_entrance('Lost Woods Dive Warp'), lambda state: state.can_dive() and (world.open_forest or (state.has('Slingshot') and state.has('Kokiri Sword')))) - set_rule(world.get_entrance('Zora River Dive Warp'), lambda state: state.can_dive()) - set_rule(world.get_entrance('Lake Hylia Dive Warp'), lambda state: state.can_dive()) - set_rule(world.get_entrance('Zoras Domain Dive Warp'), lambda state: state.can_dive()) - set_rule(world.get_entrance('Zora River Waterfall'), lambda state: state.has('Zeldas Lullaby')) - set_rule(world.get_entrance('Zora River Rocks'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Zora River Lower Freestanding PoH'), lambda state: state.has('Bomb Bag') or state.has('Progressive Scale') or (state.has('Hover Boots') and state.is_adult())) - set_rule(world.get_location('Zora River Upper Freestanding PoH'), lambda state: state.has('Bomb Bag') or state.has('Progressive Scale') or (state.has('Hover Boots') and state.is_adult())) - set_rule(world.get_location('Frog Ocarina Game'), lambda state: state.has('Zeldas Lullaby') and state.has('Sarias Song') and state.has('Suns Song') and state.has('Eponas Song') and state.has('Song of Time') and state.has('Song of Storms')) - set_rule(world.get_location('Frogs in the Rain'), lambda state: state.has('Song of Storms')) - set_rule(world.get_location('Underwater Bottle'), lambda state: state.can_dive()) - set_rule(world.get_location('King Zora Moves'), lambda state: state.has('Bottle with Letter')) - set_rule(world.get_entrance('Behind King Zora'), lambda state: state.has('Bottle with Letter')) - set_rule(world.get_entrance('Zora River Adult'), lambda state: state.is_adult()) - set_rule(world.get_entrance('Zoras Domain Adult Access'), lambda state: state.has('Zeldas Lullaby')) - set_rule(world.get_entrance('Zoras Fountain Adult Access'), lambda state: state.can_reach('Zoras Fountain')) - set_rule(world.get_entrance('Jabu Jabus Belly'), lambda state: state.has_bottle()) - set_rule(world.get_entrance('Zoras Fountain Fairy'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Zoras Fountain Fairy Reward'), lambda state: state.has('Zeldas Lullaby')) - set_rule(world.get_entrance('Jabu Jabus Belly Ceiling Switch'), lambda state: state.has('Slingshot') or state.has('Bomb Bag') or state.has('Boomerang')) - set_rule(world.get_entrance('Jabu Jabus Belly Tentacles'), lambda state: state.has('Boomerang')) - set_rule(world.get_location('Ice Cavern Map Chest'), lambda state: state.has_bottle()) - set_rule(world.get_location('Ice Cavern Compass Chest'), lambda state: state.has_bottle()) - set_rule(world.get_location('Ice Cavern Freestanding PoH'), lambda state: state.has_bottle()) - set_rule(world.get_location('Ice Cavern Iron Boots Chest'), lambda state: state.has_bottle()) - set_rule(world.get_location('Sheik in Ice Cavern'), lambda state: state.has_bottle() and state.is_adult()) - set_rule(world.get_location('Ocarina of Time'), lambda state: state.has('Kokiri Emerald') and state.has('Goron Ruby') and state.has('Zora Sapphire') and state.guarantee_hint()) - set_rule(world.get_location('Song from Ocarina of Time'), lambda state: state.has('Kokiri Emerald') and state.has('Goron Ruby') and state.has('Zora Sapphire') and state.guarantee_hint()) - set_rule(world.get_entrance('Door of Time'), lambda state: state.has('Song of Time') or world.open_door_of_time) - set_rule(world.get_location('Talons Chickens'), lambda state: state.has('Zeldas Letter')) - set_rule(world.get_location('Epona'), lambda state: state.has('Eponas Song') and state.is_adult()) - set_rule(world.get_entrance('Adult Forest Warp Pad'), lambda state: state.has('Minuet of Forest') and state.is_adult()) - set_rule(world.get_entrance('Child Forest Warp Pad'), lambda state: state.has('Minuet of Forest')) - set_rule(world.get_entrance('Adult Meadow Access'), lambda state: state.has('Sarias Song') and state.is_adult()) - set_rule(world.get_entrance('Forest Temple Entrance'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_entrance('Forest Temple Song of Time Block'), lambda state: state.has('Song of Time')) - set_rule(world.get_entrance('Forest Temple Lobby Eyeball Switch'), lambda state: state.has('Bow') and state.is_adult()) - set_rule(world.get_entrance('Forest Temple Lobby Locked Door'), lambda state: state.has('Progressive Strength Upgrade') and state.has('Small Key (Forest Temple)', 1)) - set_rule(world.get_entrance('Forest Temple Well Connection'), lambda state: ((state.has('Iron Boots') or state.has('Progressive Hookshot', 2)) and state.is_adult()) or state.has('Progressive Scale', 2)) #Longshot can grab some very high up vines to drain the well. - set_rule(world.get_entrance('Forest Temple Scarecrows Song'), lambda state: False) #For some reason you can't actually activate this from below. Cool game. - set_rule(world.get_entrance('Forest Temple Elevator'), lambda state: state.has('Bow') and state.is_adult() and state.has('Progressive Strength Upgrade') and state.has('Small Key (Forest Temple)', 3)) - set_rule(world.get_entrance('Forest Temple Outside Backdoor'), lambda state: state.has('Hover Boots') and state.is_adult()) - set_rule(world.get_entrance('Forest Temple Twisted Hall'), lambda state: state.has('Small Key (Forest Temple)', 3)) - set_rule(world.get_entrance('Forest Temple Straightened Hall'), lambda state: state.has('Small Key (Forest Temple)', 2) and state.has('Bow')) - set_rule(world.get_entrance('Forest Temple Drop to Falling Room'), lambda state: state.has('Small Key (Forest Temple)', 5) and (state.has('Bow') or (state.has('Dins Fire') and state.has('Magic Meter')))) - set_rule(world.get_location('Forest Temple Block Push Chest'), lambda state: state.has('Bow') and state.is_adult()) - set_rule(world.get_location('Forest Temple Red Poe Chest'), lambda state: state.has('Bow') and state.is_adult()) - set_rule(world.get_location('Forest Temple Blue Poe Chest'), lambda state: state.has('Bow') and state.is_adult()) - set_rule(world.get_location('Phantom Ganon'), lambda state: state.has('Boss Key (Forest Temple)')) - set_rule(world.get_location('Phantom Ganon Heart'), lambda state: state.has('Boss Key (Forest Temple)')) - set_rule(world.get_entrance('Dampes Grave'), lambda state: state.is_adult()) - set_rule(world.get_location('Graveyard Freestanding PoH'), lambda state: state.is_adult() and (state.has('Magic Bean') or state.has('Progressive Hookshot', 2))) - set_rule(world.get_location('Song at Windmill'), lambda state: state.is_adult()) - set_rule(world.get_location('Windmill Freestanding PoH'), lambda state: (state.is_adult() and state.has('Song of Time')) or state.has('Boomerang')) - set_rule(world.get_entrance('Temple Warp Pad'), lambda state: state.has('Prelude of Light')) - set_rule(world.get_location('Sheik at Temple'), lambda state: state.has('Forest Medallion') and state.is_adult()) - set_rule(world.get_location('Diving in the Lab'), lambda state: state.has('Progressive Scale', 2)) - set_rule(world.get_location('Child Fishing'), lambda state: state.has('Kokiri Sword')) - set_rule(world.get_location('Adult Fishing'), lambda state: state.is_adult() and (state.has('Progressive Hookshot') or state.has('Magic Bean'))) - set_rule(world.get_location('Lake Hylia Freestanding PoH'), lambda state: state.is_adult() and (state.has('Progressive Hookshot') or state.has('Magic Bean'))) - set_rule(world.get_location('Lake Hylia Sun'), lambda state: state.has('Progressive Hookshot', 2) and state.has('Bow') and state.is_adult()) - set_rule(world.get_entrance('Crater Hover Boots'), lambda state: state.is_adult() and state.has('Hover Boots')) - set_rule(world.get_entrance('Crater Ascent'), lambda state: state.is_adult() and state.has_GoronTunic()) - set_rule(world.get_entrance('Crater Scarecrow'), lambda state: state.is_adult() and state.has('Progressive Hookshot', 2) and state.has_GoronTunic()) - set_rule(world.get_entrance('Crater Bridge'), lambda state: state.is_adult() and (state.has('Hover Boots') or state.has('Progressive Hookshot'))) - set_rule(world.get_entrance('Crater Bridge Reverse'), lambda state: state.is_adult() and (state.has('Hover Boots') or state.has('Progressive Hookshot'))) - set_rule(world.get_entrance('Crater Warp Pad'), lambda state: state.has('Bolero of Fire')) - set_rule(world.get_entrance('Crater Fairy'), lambda state: state.is_adult() and state.has('Hammer')) - set_rule(world.get_location('DM Crater Volcano Freestanding PoH'), lambda state: state.is_adult() and state.has('Magic Bean') and state.has('Bolero of Fire')) - set_rule(world.get_entrance('Fire Temple Entrance'), lambda state: state.is_adult() and state.has_GoronTunic()) - set_rule(world.get_entrance('Fire Temple Early Climb'), lambda state: state.has('Small Key (Fire Temple)', 3) and state.has('Progressive Strength Upgrade') and (state.has('Bomb Bag') or ((state.has('Bow') or state.has('Progressive Hookshot')) and state.is_adult()))) - set_rule(world.get_entrance('Fire Temple Fire Maze Escape'), lambda state: state.has('Small Key (Fire Temple)', 7) or (state.has('Small Key (Fire Temple)', 6) and state.has('Hover Boots') and state.has('Hammer') and state.is_adult())) - set_rule(world.get_location('Fire Temple Fire Dancer Chest'), lambda state: state.is_adult() and state.has('Hammer')) - set_rule(world.get_location('Fire Temple Boss Key Chest'), lambda state: state.is_adult() and state.has('Hammer')) - set_rule(world.get_location('Fire Temple Big Lava Room Bombable Chest'), lambda state: state.has('Small Key (Fire Temple)', 1) and state.has('Bomb Bag')) - set_rule(world.get_location('Fire Temple Big Lava Room Open Chest'), lambda state: state.has('Small Key (Fire Temple)', 1)) - set_rule(world.get_location('Fire Temple Map Chest'), lambda state: state.has('Small Key (Fire Temple)', 5) or (state.has('Small Key (Fire Temple)', 4) and state.is_adult() and state.has('Bow'))) - set_rule(world.get_location('Fire Temple Boulder Maze Upper Chest'), lambda state: state.has('Small Key (Fire Temple)', 5)) - set_rule(world.get_location('Fire Temple Boulder Maze Bombable Pit'), lambda state: state.has('Small Key (Fire Temple)', 5) and state.has('Bomb Bag')) - set_rule(world.get_location('Fire Temple Scarecrow Chest'), lambda state: state.has('Small Key (Fire Temple)', 5) and state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('Fire Temple Compass Chest'), lambda state: state.has('Small Key (Fire Temple)', 6)) - set_rule(world.get_location('Fire Temple Highest Goron Chest'), lambda state: state.has('Song of Time') and state.has('Hammer') and state.is_adult()) - set_rule(world.get_location('Fire Temple Megaton Hammer Chest'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Volvagia'), lambda state: state.has('Hammer') and state.is_adult() and state.has('Boss Key (Fire Temple)') and (state.has('Hover Boots') or (state.can_reach('Fire Temple Upper') and (state.has('Song of Time') or state.has('Bomb Bag'))))) - set_rule(world.get_location('Volvagia Heart'), lambda state: state.has('Hammer') and state.is_adult() and state.has('Boss Key (Fire Temple)') and (state.has('Hover Boots') or (state.can_reach('Fire Temple Upper') and (state.has('Song of Time') or state.has('Bomb Bag'))))) - set_rule(world.get_location('Sheik in Crater'), lambda state: state.is_adult()) - set_rule(world.get_location('Link the Goron'), lambda state: state.is_adult() and (state.has('Progressive Strength Upgrade') or state.has('Bomb Bag') or state.has('Bow'))) - set_rule(world.get_entrance('Crater Access'), lambda state: state.is_adult() and (state.has('Progressive Strength Upgrade') or state.has('Bomb Bag'))) - set_rule(world.get_entrance('Lake Warp Pad'), lambda state: state.has('Serenade of Water')) - set_rule(world.get_location('King Zora Thawed'), lambda state: state.has_bottle() and (state.can_reach('Ice Cavern') or state.can_reach('Ganons Castle Water Trial') or state.has('Progressive Wallet', 2))) - set_rule(world.get_location('Zoras Fountain Bottom Freestanding PoH'), lambda state: state.has('Iron Boots')) - set_rule(world.get_entrance('Water Temple Entrance'), lambda state: state.is_adult() and (state.has('Zora Tunic') or (state.has('Progressive Wallet', 2) and state.has_bottle() and state.has('Zeldas Lullaby'))) and state.has('Iron Boots') and state.has('Progressive Hookshot')) - set_rule(world.get_entrance('Water Temple Central Pillar'), lambda state: (state.has('Bow') or (state.has('Dins Fire') and state.has('Magic Meter')) or state.has('Small Key (Water Temple)', 5)) and state.has('Zeldas Lullaby')) - set_rule(world.get_entrance('Water Temple Upper Locked Door'), lambda state: state.has('Small Key (Water Temple)', 5) and (state.has('Zeldas Lullaby') or world.keysanity)) - set_rule(world.get_location('Water Temple Torches Chest'), lambda state: (state.has('Bow') or (state.has('Dins Fire') and state.has('Magic Meter'))) and state.has('Zeldas Lullaby')) - set_rule(world.get_location('Water Temple Dragon Chest'), lambda state: (state.has('Progressive Strength Upgrade') and state.has('Zeldas Lullaby')) or (state.has('Small Key (Water Temple)', 6) and (state.has('Zeldas Lullaby') or world.keysanity) and state.has('Song of Time') and state.has('Bow'))) - set_rule(world.get_location('Water Temple Central Bow Target Chest'), lambda state: state.has('Bow') and state.has('Progressive Strength Upgrade') and state.has('Zeldas Lullaby') and (state.has('Hover Boots') or state.has('Progressive Hookshot', 2))) - set_always_allow(world.get_location('Water Temple Boss Key Chest'), lambda item, state: item.name == 'Small Key (Water Temple)') - set_rule(world.get_location('Water Temple Boss Key Chest'), lambda state: (state.has('Small Key (Water Temple)', 6) and (state.has('Zeldas Lullaby') or world.keysanity) and ((state.has('Bomb Bag') and state.has('Progressive Strength Upgrade')) or state.has('Hover Boots')) and state.has('Progressive Hookshot', 2)) or item_name(state, 'Water Temple Boss Key Chest') == 'Small Key (Water Temple)') #If key for key, this lets the logic reduce the small key reqs for every other locked door. - set_rule(world.get_location('Morpha'), lambda state: state.has('Boss Key (Water Temple)') and state.has('Progressive Hookshot', 2)) - set_rule(world.get_location('Morpha Heart'), lambda state: state.has('Boss Key (Water Temple)') and state.has('Progressive Hookshot', 2)) - set_rule(world.get_location('Water Temple Cracked Wall Chest'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Water Temple Dark Link Chest'), lambda state: state.has('Small Key (Water Temple)', 6) and (state.has('Zeldas Lullaby') or world.keysanity)) - set_rule(world.get_location('Water Temple River Chest'), lambda state: state.has('Small Key (Water Temple)', 6) and state.has('Song of Time') and state.has('Bow') and (state.has('Zeldas Lullaby') or world.keysanity)) - set_rule(world.get_location('Sheik in Kakariko'), lambda state: state.has('Forest Medallion') and state.has('Fire Medallion') and state.has('Water Medallion')) - set_rule(world.get_entrance('Graveyard Warp Pad'), lambda state: state.has('Nocturne of Shadow')) - set_rule(world.get_entrance('Shadow Temple Entrance'), lambda state: state.has('Dins Fire') and state.has('Magic Meter') and state.has('Lens of Truth') and state.is_adult() and (state.has('Hover Boots') or state.has('Progressive Hookshot'))) - set_rule(world.get_entrance('Shadow Temple First Pit'), lambda state: state.has('Hover Boots')) - set_rule(world.get_entrance('Shadow Temple Bomb Wall'), lambda state: state.has('Bomb Bag') and state.has('Small Key (Shadow Temple)', 1)) - set_rule(world.get_entrance('Shadow Temple Hookshot Target'), lambda state: state.has('Progressive Hookshot') and state.has('Small Key (Shadow Temple)', 3)) - set_rule(world.get_entrance('Shadow Temple Boat'), lambda state: state.has('Zeldas Lullaby') and state.has('Small Key (Shadow Temple)', 4)) - set_rule(world.get_location('Shadow Temple Falling Spikes Upper Chest'), lambda state: state.has('Progressive Strength Upgrade')) - set_rule(world.get_location('Shadow Temple Falling Spikes Switch Chest'), lambda state: state.has('Progressive Strength Upgrade')) - set_rule(world.get_location('Shadow Temple Invisible Spikes Chest'), lambda state: state.has('Small Key (Shadow Temple)', 2)) - set_rule(world.get_location('Shadow Temple Freestanding Key'), lambda state: state.has('Small Key (Shadow Temple)', 2) and state.has('Progressive Hookshot')) - set_rule(world.get_location('Bongo Bongo'), lambda state: state.has('Small Key (Shadow Temple)', 5) and (state.has('Bow') or state.has('Progressive Hookshot', 2)) and state.has('Boss Key (Shadow Temple)')) - set_rule(world.get_location('Bongo Bongo Heart'), lambda state: state.has('Small Key (Shadow Temple)', 5) and (state.has('Bow') or state.has('Progressive Hookshot', 2)) and state.has('Boss Key (Shadow Temple)')) - set_rule(world.get_entrance('Bridge Crossing'), lambda state: (state.has('Epona') or state.has('Progressive Hookshot', 2)) and state.is_adult()) - set_rule(world.get_location('Gerudo Valley Hammer Rocks Chest'), lambda state: state.has('Hammer') and state.is_adult()) - set_rule(world.get_entrance('Fortress Entrance'), lambda state: (state.has('Bow') or state.has('Progressive Hookshot') or state.has('Hover Boots')) and state.is_adult()) - set_rule(world.get_entrance('Gerudo Training Grounds Entrance'), lambda state: state.has('Gerudo Membership Card') and state.is_adult()) - set_rule(world.get_entrance('Haunted Wasteland Entrance'), lambda state: state.has('Gerudo Membership Card') and state.is_adult() and (state.has('Hover Boots') or state.has('Progressive Hookshot', 2))) - set_rule(world.get_entrance('Haunted Wasteland Crossing'), lambda state: state.has('Lens of Truth') and state.has('Magic Meter')) - set_rule(world.get_entrance('Colossus Warp Pad'), lambda state: state.has('Requiem of Spirit')) - set_rule(world.get_entrance('Colossus Fairy'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Colossus Freestanding PoH'), lambda state: state.has('Requiem of Spirit') and state.has('Magic Bean') and state.is_adult()) - set_rule(world.get_location('Desert Colossus Fairy Reward'), lambda state: state.has('Zeldas Lullaby')) - set_rule(world.get_location('Gerudo Fortress Rooftop Chest'), lambda state: (state.has('Hover Boots') or state.has('Progressive Hookshot')) and state.is_adult()) - set_rule(world.get_location('Horseback Archery 1000 Points'), lambda state: state.has('Gerudo Membership Card') and state.has('Epona') and state.has('Bow') and state.is_adult()) - set_rule(world.get_location('Horseback Archery 1500 Points'), lambda state: state.has('Gerudo Membership Card') and state.has('Epona') and state.has('Bow') and state.is_adult()) - set_rule(world.get_location('Haunted Wasteland Structure Chest'), lambda state: state.has_fire_source()) - set_rule(world.get_entrance('Gerudo Training Ground Left Silver Rupees'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_entrance('Gerudo Training Ground Beamos'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_entrance('Gerudo Training Grounds Right Locked Doors'), lambda state: state.has('Small Key (Gerudo Training Grounds)', 9)) - set_rule(world.get_entrance('Gerudo Training Grounds Maze Ledge'), lambda state: state.has('Song of Time')) - set_rule(world.get_entrance('Gerudo Training Grounds Right Hookshot Target'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_entrance('Gerudo Training Grounds Hammer Target'), lambda state: state.has('Hammer') and state.has('Bow') and state.is_adult()) - set_rule(world.get_entrance('Gerudo Training Grounds Hidden Hookshot Target'), lambda state: state.has('Progressive Hookshot') and state.has('Lens of Truth') and state.has('Magic Meter') and state.is_adult()) - set_rule(world.get_location('Gerudo Training Grounds Lobby Left Chest'), lambda state: state.has('Bow') and state.is_adult()) - set_rule(world.get_location('Gerudo Training Grounds Lobby Right Chest'), lambda state: state.has('Bow') and state.is_adult()) - set_rule(world.get_location('Gerudo Training Grounds Beamos Chest'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('Gerudo Training Grounds Hidden Ceiling Chest'), lambda state: state.has('Small Key (Gerudo Training Grounds)', 3) and state.has('Lens of Truth') and state.has('Magic Meter')) - set_rule(world.get_location('Gerudo Training Grounds Maze Path First Chest'), lambda state: state.has('Small Key (Gerudo Training Grounds)', 4)) - set_rule(world.get_location('Gerudo Training Grounds Maze Path Second Chest'), lambda state: state.has('Small Key (Gerudo Training Grounds)', 6)) - set_rule(world.get_location('Gerudo Training Grounds Maze Path Third Chest'), lambda state: state.has('Small Key (Gerudo Training Grounds)', 7)) - set_rule(world.get_location('Gerudo Training Grounds Maze Path Final Chest'), lambda state: (state.has('Small Key (Gerudo Training Grounds)', 9)) or (item_name(state, 'Gerudo Training Grounds Maze Path Final Chest') == 'Small Key (Gerudo Training Grounds)' and state.has('Small Key (Gerudo Training Grounds)', 8))) #Allow key for key - set_always_allow(world.get_location('Gerudo Training Grounds Maze Path Final Chest'), lambda item, state: item.name == 'Small Key (Gerudo Training Grounds)') - set_rule(world.get_location('Gerudo Training Grounds Underwater Silver Rupee Chest'), lambda state: state.has('Progressive Hookshot') and state.has('Song of Time') and state.has('Iron Boots') and state.is_adult()) - set_rule(world.get_location('Gerudo Training Grounds Hammer Room Switch Chest'), lambda state: state.has('Hammer') and state.is_adult()) - set_rule(world.get_location('Gerudo Training Grounds Eye Statue Chest'), lambda state: state.has('Bow') and state.is_adult()) - set_rule(world.get_location('Gerudo Training Grounds Near Scarecrow Chest'), lambda state: state.has('Bow') and state.is_adult()) - set_rule(world.get_location('Gerudo Training Grounds Heavy Block First Chest'), lambda state: state.has('Progressive Strength Upgrade', 2) and state.has('Lens of Truth') and state.has('Magic Meter') and state.is_adult()) - set_rule(world.get_location('Gerudo Training Grounds Heavy Block Second Chest'), lambda state: state.has('Progressive Strength Upgrade', 2) and state.has('Lens of Truth') and state.has('Magic Meter') and state.is_adult()) - set_rule(world.get_location('Gerudo Training Grounds Heavy Block Third Chest'), lambda state: state.has('Progressive Strength Upgrade', 2) and state.has('Lens of Truth') and state.has('Magic Meter') and state.is_adult()) - set_rule(world.get_location('Gerudo Training Grounds Heavy Block Fourth Chest'), lambda state: state.has('Progressive Strength Upgrade', 2) and state.has('Lens of Truth') and state.has('Magic Meter') and state.is_adult()) - set_rule(world.get_entrance('Spirit Temple Crawl Passage'), lambda state: state.has('Requiem of Spirit')) - set_rule(world.get_entrance('Spirit Temple Silver Block'), lambda state: state.has('Progressive Strength Upgrade', 2) and state.is_adult()) - set_rule(world.get_entrance('Child Spirit Temple Passthrough'), lambda state: state.has('Bomb Bag') and state.has('Small Key (Spirit Temple)', 1)) - set_rule(world.get_entrance('Adult Spirit Temple Passthrough'), lambda state: state.has('Small Key (Spirit Temple)', 1)) - set_rule(world.get_entrance('Spirit Temple Central Locked Door'), lambda state: state.has('Small Key (Spirit Temple)', 4) and state.has('Progressive Strength Upgrade', 2) and state.is_adult()) - set_rule(world.get_entrance('Spirit Temple Final Locked Door'), lambda state: state.has('Small Key (Spirit Temple)', 5) and (state.has('Progressive Hookshot') or state.has('Bow') or state.has('Bomb Bag'))) - set_rule(world.get_location('Spirit Temple Child Left Chest'), lambda state: state.has('Boomerang') or state.has('Slingshot')) - set_rule(world.get_location('Spirit Temple Child Right Chest'), lambda state: state.has('Boomerang') or state.has('Slingshot')) - set_rule(world.get_location('Spirit Temple Compass Chest'), lambda state: state.has('Progressive Hookshot') and state.has('Zeldas Lullaby')) - set_rule(world.get_location('Spirit Temple Early Adult Right Chest'), lambda state: state.has('Bow') or state.has('Progressive Hookshot') or state.has('Bomb Bag')) #Bomb Bag option requires a very specific Bombchu use, Hover Boots can be skipped by jumping on top of the rolling rock. - set_rule(world.get_location('Spirit Temple First Mirror Right Chest'), lambda state: state.has('Small Key (Spirit Temple)', 3)) - set_rule(world.get_location('Spirit Temple First Mirror Left Chest'), lambda state: state.has('Small Key (Spirit Temple)', 3)) - set_rule(world.get_location('Spirit Temple Map Chest'), lambda state: (state.has('Small Key (Spirit Temple)', 5) and state.has('Requiem of Spirit')) or (state.has('Magic Meter') and (state.has('Dins Fire') or (state.has('Fire Arrows') and state.has('Bow') and state.has('Progressive Strength Upgrade', 2) and state.has('Small Key (Spirit Temple)', 3) and state.is_adult())))) - set_rule(world.get_location('Spirit Temple Child Climb East Chest'), lambda state: state.has('Bomb Bag') or ((state.has('Boomerang') or state.has('Slingshot')) and (state.has('Progressive Hookshot') or state.has('Bow'))) or (state.has('Small Key (Spirit Temple)', 3) and state.has('Progressive Strength Upgrade', 2) and state.is_adult() and (state.has('Progressive Hookshot') or state.has('Bow'))) or (state.has('Small Key (Spirit Temple)', 5) and state.has('Requiem of Spirit') and (state.has('Boomerang') or state.has('Slingshot')))) - set_rule(world.get_location('Spirit Temple Child Climb North Chest'), lambda state: state.has('Bomb Bag') or ((state.has('Boomerang') or state.has('Slingshot')) and (state.has('Progressive Hookshot') or state.has('Bow'))) or (state.has('Small Key (Spirit Temple)', 3) and state.has('Progressive Strength Upgrade', 2) and state.is_adult() and (state.has('Progressive Hookshot') or state.has('Bow'))) or (state.has('Small Key (Spirit Temple)', 5) and state.has('Requiem of Spirit') and (state.has('Boomerang') or state.has('Slingshot')))) - set_rule(world.get_location('Spirit Temple Sun Block Room Chest'), lambda state: (state.has('Small Key (Spirit Temple)', 5) and state.has('Bomb Bag') and state.has('Requiem of Spirit')) or (state.has_fire_source() and (state.has('Bomb Bag') or state.has('Small Key (Spirit Temple)', 2)))) - set_rule(world.get_location('Spirit Temple Statue Hand Chest'), lambda state: state.has('Small Key (Spirit Temple)', 3) and state.has('Progressive Strength Upgrade', 2) and state.is_adult() and state.has('Zeldas Lullaby')) - set_rule(world.get_location('Spirit Temple NE Main Room Chest'), lambda state: state.has('Small Key (Spirit Temple)', 3) and state.has('Progressive Strength Upgrade', 2) and state.is_adult() and state.has('Zeldas Lullaby') and state.has('Progressive Hookshot')) - set_rule(world.get_location('Mirror Shield Chest'), lambda state: state.has('Small Key (Spirit Temple)', 4) and state.has('Progressive Strength Upgrade', 2) and state.is_adult() and state.has('Bomb Bag')) - set_rule(world.get_location('Silver Gauntlets Chest'), lambda state: (state.has('Small Key (Spirit Temple)', 3) and state.has('Progressive Hookshot', 2) and state.has('Bomb Bag')) or state.has('Small Key (Spirit Temple)', 5)) - set_rule(world.get_location('Spirit Temple Near Four Armos Chest'), lambda state: state.has('Mirror Shield') and state.has('Bomb Bag')) - set_rule(world.get_location('Spirit Temple Hallway Left Invisible Chest'), lambda state: state.has('Magic Meter') and state.has('Lens of Truth') and state.has('Bomb Bag')) - set_rule(world.get_location('Spirit Temple Hallway Right Invisible Chest'), lambda state: state.has('Magic Meter') and state.has('Lens of Truth') and state.has('Bomb Bag')) - set_rule(world.get_location('Spirit Temple Boss Key Chest'), lambda state: state.has('Zeldas Lullaby') and state.has('Bow') and state.has('Progressive Hookshot') and state.can_blast()) - set_rule(world.get_location('Spirit Temple Topmost Chest'), lambda state: state.has('Mirror Shield')) - set_rule(world.get_location('Twinrova'), lambda state: state.has('Mirror Shield') and state.has('Bomb Bag') and state.has('Progressive Hookshot') and state.has('Boss Key (Spirit Temple)')) - set_rule(world.get_location('Twinrova Heart'), lambda state: state.has('Mirror Shield') and state.has('Bomb Bag') and state.has('Progressive Hookshot') and state.has('Boss Key (Spirit Temple)')) - set_rule(world.get_location('Zelda'), lambda state: state.has('Shadow Medallion') and state.has('Spirit Medallion')) - set_rule(world.get_entrance('Ganons Castle Light Trial'), lambda state: state.has('Progressive Strength Upgrade', 3)) - set_rule(world.get_entrance('Ganons Castle Tower'), lambda state: state.has('Forest Trial Clear') and state.has('Fire Trial Clear') and state.has('Water Trial Clear') and state.has('Shadow Trial Clear') and state.has('Spirit Trial Clear') and state.has('Light Trial Clear')) - set_rule(world.get_location('Ganons Castle Forest Trial Clear'), lambda state: state.has('Magic Meter') and state.has('Bow') and state.has('Light Arrows') and (state.has('Fire Arrows') or (state.has('Progressive Hookshot') and state.has('Dins Fire')))) - set_rule(world.get_location('Ganons Castle Fire Trial Clear'), lambda state: state.has_GoronTunic() and state.has('Progressive Strength Upgrade', 3) and state.has('Magic Meter') and state.has('Bow') and state.has('Light Arrows') and state.has('Progressive Hookshot', 2)) - set_rule(world.get_location('Ganons Castle Water Trial Clear'), lambda state: state.has_bottle() and state.has('Hammer') and state.has('Magic Meter') and state.has('Bow') and state.has('Light Arrows')) - set_rule(world.get_location('Ganons Castle Shadow Trial Clear'), lambda state: state.has('Magic Meter') and state.has('Bow') and state.has('Light Arrows') and state.has('Hammer') and (state.has('Fire Arrows') or state.has('Progressive Hookshot', 2)) and (state.has('Lens of Truth') or (state.has('Hover Boots') and state.has('Progressive Hookshot', 2)))) - set_rule(world.get_location('Ganons Castle Shadow Trial First Chest'), lambda state: (state.has('Magic Meter') and state.has('Bow') and state.has('Fire Arrows')) or state.has('Progressive Hookshot') or state.has('Hover Boots') or state.has('Song of Time')) - set_rule(world.get_location('Ganons Castle Shadow Trial Second Chest'), lambda state: (state.has('Magic Meter') and state.has('Bow') and state.has('Fire Arrows')) or (state.has('Progressive Hookshot', 2) and state.has('Hover Boots'))) - set_rule(world.get_location('Ganons Castle Spirit Trial Clear'), lambda state: state.has('Magic Meter') and state.has('Bow') and state.has('Light Arrows') and state.has('Mirror Shield') and state.has('Bomb Bag') and state.has('Progressive Hookshot')) - set_rule(world.get_location('Ganons Castle Spirit Trial First Chest'), lambda state: state.has('Progressive Hookshot') and (state.has('Magic Meter') or state.has('Bomb Bag'))) - set_rule(world.get_location('Ganons Castle Spirit Trial Second Chest'), lambda state: state.has('Progressive Hookshot') and state.has('Magic Meter') and state.has('Bomb Bag') and state.has('Lens of Truth')) - set_rule(world.get_location('Ganons Castle Light Trial Clear'), lambda state: state.has('Magic Meter') and state.has('Bow') and state.has('Progressive Hookshot') and state.has('Light Arrows') and state.has('Small Key (Ganons Castle)', 2)) - set_rule(world.get_location('Ganons Castle Light Trail Invisible Enemies Chest'), lambda state: state.has('Magic Meter') and state.has('Lens of Truth')) - set_rule(world.get_location('Ganons Castle Light Trial Lullaby Chest'), lambda state: state.has('Zeldas Lullaby') and state.has('Small Key (Ganons Castle)', 1)) - set_rule(world.get_location('Ganon'), lambda state: state.has('Boss Key (Ganons Castle)')) - set_rule(world.get_entrance('Kokiri Forest Storms Grotto'), lambda state: state.has('Song of Storms')) - set_rule(world.get_entrance('Lost Woods Generic Grotto'), lambda state: state.can_blast()) - set_rule(world.get_entrance('Lost Woods Sales Grotto'), lambda state: state.has('Bomb Bag') or (state.has('Hammer') and state.is_adult() and (state.has('Minuet of Forest') or state.has('Sarias Song')))) - set_rule(world.get_entrance('Front of Meadow Grotto'), lambda state: state.has('Bomb Bag') or (state.has('Hammer') and state.is_adult() and (state.has('Minuet of Forest') or state.has('Sarias Song')))) - set_rule(world.get_entrance('Remote Southern Grotto'), lambda state: state.can_blast()) - set_rule(world.get_entrance('Field Near Lake Inside Fence Grotto'), lambda state: state.can_blast()) - set_rule(world.get_entrance('Field Valley Grotto'), lambda state: state.can_blast()) - set_rule(world.get_entrance('Field West Castle Town Grotto'), lambda state: state.can_blast()) - set_rule(world.get_entrance('Field Far West Castle Town Grotto'), lambda state: state.can_blast()) - set_rule(world.get_entrance('Field Kakariko Grotto'), lambda state: state.can_blast()) - set_rule(world.get_entrance('Field North Lon Lon Grotto'), lambda state: state.can_blast()) - set_rule(world.get_entrance('Castle Storms Grotto'), lambda state: state.has('Song of Storms')) - set_rule(world.get_entrance('Kakariko Bombable Grotto'), lambda state: state.can_blast()) - set_rule(world.get_entrance('Mountain Bombable Grotto'), lambda state: state.can_blast()) - set_rule(world.get_entrance('Mountain Storms Grotto'), lambda state: state.has('Song of Storms')) - set_rule(world.get_entrance('Top of Crater Grotto'), lambda state: state.can_blast()) - set_rule(world.get_entrance('Zora River Plateau Open Grotto'), lambda state: state.has('Bomb Bag') or state.has('Progressive Scale') or state.is_adult()) - set_rule(world.get_entrance('Zora River Plateau Bombable Grotto'), lambda state: state.can_blast()) - set_rule(world.get_location('Tektite Grotto Freestanding PoH'), lambda state: state.has('Progressive Scale', 2) or (state.has('Iron Boots') and state.is_adult())) - set_rule(world.get_location('GS2'), lambda state: state.has_bottle()) - set_rule(world.get_location('GS3'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS4'), lambda state: state.has_bottle()) - set_rule(world.get_location('GS5'), lambda state: state.has_bottle()) - set_rule(world.get_location('GS6'), lambda state: state.has('Magic Bean')) - set_rule(world.get_location('GS7'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS9'), lambda state: state.has('Slingshot') or state.has('Bomb Bag') or state.has('Boomerang') or (state.has('Dins Fire') and state.has('Magic Meter'))) - set_rule(world.get_location('GS11'), lambda state: state.has('Boomerang') and state.has('Bomb Bag')) - set_rule(world.get_location('GS12'), lambda state: (state.has('Boomerang') and state.has('Bomb Bag')) or (state.has('Progressive Hookshot') and state.is_adult())) - set_rule(world.get_location('GS13'), lambda state: (state.has('Hammer') and state.has_fire_source() and state.has('Progressive Hookshot') and state.is_adult()) or (state.has('Boomerang') and state.has('Bomb Bag') and state.has('Dins Fire') and state.has('Magic Meter'))) - set_rule(world.get_location('GS16'), lambda state: state.has('Boomerang') and state.has('Bomb Bag')) - set_rule(world.get_location('GS20'), lambda state: state.has('Boomerang')) - set_rule(world.get_location('GS21'), lambda state: state.has('Boomerang')) - set_rule(world.get_location('GS26'), lambda state: state.has('Slingshot') or state.has('Bomb Bag')) - set_rule(world.get_location('GS27'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS28'), lambda state: state.has('Boomerang')) - set_rule(world.get_location('GS29'), lambda state: state.has_bottle()) - set_rule(world.get_location('GS30'), lambda state: state.has_bottle() and (state.has('Bomb Bag') or state.has('Progressive Strength Upgrade'))) - set_rule(world.get_location('GS31'), lambda state: state.can_blast()) - set_rule(world.get_location('GS32'), lambda state: state.has('Hammer') and state.is_adult()) - set_rule(world.get_location('GS33'), lambda state: state.has('Hammer') and state.is_adult()) - set_rule(world.get_location('GS34'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('GS35'), lambda state: state.is_adult()) - set_rule(world.get_location('GS37'), lambda state: state.has('Bolero of Fire') and state.has_bottle()) - set_rule(world.get_location('GS39'), lambda state: state.has('Bomb Bag') or (state.has('Boomerang') or state.has('Slingshot') and state.has('Progressive Strength Upgrade')) or (state.has('Dins Fire') and state.has('Magic Meter')) or (state.is_adult and (state.has('Progressive Hookshot') or state.has('Bow') or state.has('Biggoron Sword')))) - set_rule(world.get_location('GS41'), lambda state: (state.has('Progressive Hookshot') and state.is_adult()) or (state.has('Boomerang') and (state.has('Bomb Bag') or state.has('Progressive Strength Upgrade')))) - set_rule(world.get_location('GS42'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS45'), lambda state: state.has('Progressive Hookshot')) - set_rule(world.get_location('GS46'), lambda state: state.has('Progressive Hookshot')) - set_rule(world.get_location('GS47'), lambda state: state.has('Progressive Hookshot') or state.has('Bow') or state.has('Magic Meter')) - set_rule(world.get_location('GS49'), lambda state: state.has('Boomerang')) - set_rule(world.get_location('GS50'), lambda state: state.has('Progressive Strength Upgrade', 2) and state.can_blast() and state.has('Progressive Hookshot')) -# Jabu Jabu GS need no reqs becuase the access reqs for their zones cover them. - set_rule(world.get_location('GS55'), lambda state: state.has_bottle()) - set_rule(world.get_location('GS56'), lambda state: state.has('Boomerang')) - set_rule(world.get_location('GS58'), lambda state: state.is_adult() and state.has('Progressive Hookshot', 2)) - set_rule(world.get_location('GS59'), lambda state: state.is_adult() and state.has('Iron Boots') and state.has('Progressive Hookshot')) - set_rule(world.get_location('GS60'), lambda state: (state.has('Progressive Hookshot') or state.has('Bow') or (state.has('Dins Fire') and state.has('Magic Meter'))) and state.is_adult()) - set_rule(world.get_location('GS61'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS62'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS63'), lambda state: (state.has('Progressive Hookshot', 2) or (state.has('Progressive Hookshot') and state.can_reach('Forest Temple Outside Upper Ledge'))) and state.is_adult()) - set_rule(world.get_location('GS64'), lambda state: state.has('Progressive Hookshot')) - set_rule(world.get_location('GS65'), lambda state: state.has('Small Key (Fire Temple)', 1) and state.has('Song of Time')) - set_rule(world.get_location('GS66'), lambda state: state.has('Bomb Bag')) - set_rule(world.get_location('GS67'), lambda state: state.has('Small Key (Fire Temple)', 5) and state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS68'), lambda state: state.has('Small Key (Fire Temple)', 5) and state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS69'), lambda state: state.has('Hammer') and state.is_adult()) - set_rule(world.get_location('GS70'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS71'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS72'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS73'), lambda state: state.has('Bomb Bag') and state.has('Magic Meter')) - set_rule(world.get_location('GS74'), lambda state: state.has('Song of Time') and state.has('Small Key (Water Temple)', 6)) - set_rule(world.get_location('GS75'), lambda state: state.has('Progressive Hookshot', 2)) - set_rule(world.get_location('GS76'), lambda state: state.has('Progressive Hookshot', 2)) - set_rule(world.get_location('GS77'), lambda state: state.has('Progressive Hookshot', 2) and ((state.has('Bomb Bag') and state.has('Progressive Strength Upgrade')) or state.has('Hover Boots')) and state.has('Small Key (Water Temple)', 6)) #5 keys would be better but it wouldn't be compatible with the key for key scenarios, 6 will be identical pre-keysanity. - set_rule(world.get_location('GS78'), lambda state: state.has('Small Key (Bottom of the Well)', 3) and state.has('Boomerang') and (state.has('Progressive Strength Upgrade') or state.has('Bomb Bag') or (state.has('Lens of Truth') and state.has('Magic Meter')))) - set_rule(world.get_location('GS79'), lambda state: state.has('Small Key (Bottom of the Well)', 3) and state.has('Boomerang')) - set_rule(world.get_location('GS80'), lambda state: state.has('Small Key (Bottom of the Well)', 3) and state.has('Boomerang')) - set_rule(world.get_location('GS81'), lambda state: state.has('Progressive Hookshot')) - set_rule(world.get_location('GS82'), lambda state: state.has('Progressive Hookshot')) - set_rule(world.get_location('GS84'), lambda state: state.has('Progressive Hookshot', 2) and state.has('Progressive Strength Upgrade') and state.has('Small Key (Shadow Temple)', 4)) - set_rule(world.get_location('GS86'), lambda state: state.has('Boomerang')) - set_rule(world.get_location('GS87'), lambda state: state.has_bottle()) - set_rule(world.get_location('GS88'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS89'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS90'), lambda state: state.has('Progressive Hookshot') and state.has('Gerudo Membership Card') and state.is_adult()) - set_rule(world.get_location('GS92'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS93'), lambda state: state.has_bottle() and state.has('Requiem of Spirit')) - set_rule(world.get_location('GS94'), lambda state: state.has('Progressive Hookshot') and state.is_adult()) - set_rule(world.get_location('GS95'), lambda state: ((state.has('Magic Bean') and state.has('Requiem of Spirit')) or state.has('Progressive Hookshot', 2)) and state.is_adult()) - set_rule(world.get_location('GS96'), lambda state: state.has('Boomerang')) - set_rule(world.get_location('GS98'), lambda state: (state.has('Boomerang') and state.has('Progressive Hookshot')) or (state.has('Boomerang') and state.has('Small Key (Spirit Temple)', 5) and state.has('Bomb Bag') and state.has('Requiem of Spirit')) or (state.has('Progressive Hookshot') and state.has('Progressive Strength Upgrade', 2) and state.is_adult() and state.has('Small Key (Spirit Temple)', 3))) - set_rule(world.get_location('GS99'), lambda state: state.has('Song of Time') and (state.has('Bow') or state.has('Progressive Hookshot') or state.has('Bomb Bag'))) - set_rule(world.get_location('GS100'), lambda state: state.has('Progressive Strength Upgrade', 2) and state.has('Small Key (Spirit Temple)', 3) and state.is_adult() and (state.has('Progressive Hookshot') or state.has('Hover Boots'))) - - for location in world.get_locations(): - if location.type != 'Chest': - forbid_item(location, 'Ice Trap') +import collections +import logging + + +def set_rules(world): + global_rules(world) + + if world.bridge == 'medallions': + # require all medallions to form the bridge + set_rule( + world.get_entrance('Rainbow Bridge'), + lambda state: state.has('Forest Medallion') and + state.has('Fire Medallion') and + state.has('Water Medallion') and + state.has('Shadow Medallion') and + state.has('Spirit Medallion') and + state.has('Light Medallion')) + elif world.bridge == 'vanilla': + # require only what vanilla did to form the bridge + set_rule( + world.get_entrance('Rainbow Bridge'), + lambda state: state.has('Light Arrows') and + state.has('Shadow Medallion') and + state.has('Spirit Medallion')) + elif world.bridge == 'dungeons': + # require all medallions and stones to form the bridge + set_rule( + world.get_entrance('Rainbow Bridge'), + lambda state: state.has('Forest Medallion') and + state.has('Fire Medallion') and + state.has('Water Medallion') and + state.has('Shadow Medallion') and + state.has('Spirit Medallion') and + state.has('Light Medallion') and + state.has('Kokiri Emerald') and + state.has('Goron Ruby') and + state.has('Zora Sapphire')) + + +def set_rule(spot, rule): + spot.access_rule = rule + +def set_always_allow(spot, rule): + spot.always_allow = rule + + +def add_rule(spot, rule, combine='and'): + old_rule = spot.access_rule + if combine == 'or': + spot.access_rule = lambda state: rule(state) or old_rule(state) + else: + spot.access_rule = lambda state: rule(state) and old_rule(state) + +def add_item_rule(spot, rule, combine='and'): + old_rule = spot.item_rule + if combine == 'or': + spot.item_rule = lambda item: rule(item) or old_rule(item) + else: + spot.item_rule = lambda item: rule(item) and old_rule(item) + +def forbid_item(location, item): + old_rule = location.item_rule + location.item_rule = lambda i: i.name != item and old_rule(i) + + +def item_in_locations(state, item, locations): + for location in locations: + if item_name(state, location) == item: + return True + return False + +def item_name(state, location): + location = state.world.get_location(location) + if location.item is None: + return None + return location.item.name + + +def global_rules(world): + + expected_skulltulas = world.logic_skulltulas + + # ganon can only carry triforce + world.get_location('Ganon').item_rule = lambda item: item.name == 'Triforce' + + # these are default save&quit points and always accessible + world.get_region('Links House').can_reach = lambda state: True + + # dungeon requirements (including gold skulltulas) + if world.dungeon_mq['DT']: + dung_rules_dtmq(world) + else: + dung_rules_dt0(world) + if world.dungeon_mq['DC']: + dung_rules_dcmq(world) + else: + dung_rules_dc0(world) + if world.dungeon_mq['JB']: + dung_rules_jbmq(world) + else: + dung_rules_jb0(world) + if world.dungeon_mq['FoT']: + dung_rules_fotmq(world) + else: + dung_rules_fot0(world) + if world.dungeon_mq['FiT']: + dung_rules_fitmq(world) + else: + dung_rules_fit0(world) + if world.dungeon_mq['WT']: + dung_rules_wtmq(world) + else: + dung_rules_wt0(world) + if world.dungeon_mq['SpT']: + dung_rules_sptmq(world) + else: + dung_rules_spt0(world) + if world.dungeon_mq['ShT']: + dung_rules_shtmq(world) + else: + dung_rules_sht0(world) + if world.dungeon_mq['BW']: + dung_rules_bwmq(world) + else: + dung_rules_bw0(world) + if world.dungeon_mq['IC']: + dung_rules_icmq(world) + else: + dung_rules_ic0(world) + if world.dungeon_mq['GTG']: + dung_rules_gtgmq(world) + else: + dung_rules_gtg0(world) + if world.dungeon_mq['GC']: + dung_rules_gcmq(world) + else: + dung_rules_gc0(world) + + # overworld requirements + set_rule( + world.get_location('Deku Baba Sticks'), + lambda state: (state.has('Kokiri Sword') and state.has('Buy Deku Shield')) or + (world.open_forest and (state.is_adult() or state.has('Kokiri Sword') or state.has('Boomerang')))) + set_rule( + world.get_location('Deku Baba Nuts'), + lambda state: (state.has('Kokiri Sword') and state.has('Buy Deku Shield')) or + (world.open_forest and + (state.is_adult() or + state.has_slingshot() or + state.has_sticks() or + state.has_explosives() or + state.has('Kokiri Sword') or + state.can_use('Dins Fire')))) + set_rule( + world.get_entrance('Deku Tree'), + lambda state: (state.has('Kokiri Sword') and state.has('Buy Deku Shield')) or world.open_forest) + set_rule(world.get_entrance('Lost Woods Bridge'), lambda state: state.can_leave_forest()) + set_rule(world.get_location('Skull Kid'), lambda state: state.can_play('Sarias Song')) + set_rule( + world.get_location('Ocarina Memory Game'), + lambda state: (not world.logic_no_memory_game) and state.has_ocarina()) + set_rule(world.get_location('Target in Woods'), lambda state: state.has_slingshot()) + set_rule( + world.get_location('Deku Theater Skull Mask'), + lambda state: (not world.logic_no_trade_skull_mask) and state.has('Zeldas Letter')) + set_rule( + world.get_location('Deku Theater Mask of Truth'), + lambda state: (not world.logic_no_trade_mask_of_truth) and + (state.has('Zeldas Letter') and + state.can_play('Sarias Song') and + state.has('Kokiri Emerald') and + state.has('Goron Ruby') and + state.has('Zora Sapphire') and + state.guarantee_hint())) #Must befriend Skull Kid to sell Skull Mask, all stones to spawn running man. + set_rule(world.get_location('Anju as Adult'), lambda state: state.is_adult()) + set_rule(world.get_location('Man on Roof'), lambda state: world.logic_man_on_roof or state.can_use('Hookshot')) + set_rule( + world.get_location('10 Gold Skulltula Reward'), + lambda state: (expected_skulltulas >= 10) and state.has('Gold Skulltula Token', 10)) + set_rule( + world.get_location('20 Gold Skulltula Reward'), + lambda state: (expected_skulltulas >= 20) and state.has('Gold Skulltula Token', 20)) + set_rule( + world.get_location('30 Gold Skulltula Reward'), + lambda state: (expected_skulltulas >= 30) and state.has('Gold Skulltula Token', 30) and state.guarantee_hint()) + set_rule( + world.get_location('40 Gold Skulltula Reward'), + lambda state: (expected_skulltulas >= 40) and state.has('Gold Skulltula Token', 40) and state.guarantee_hint()) + set_rule( + world.get_location('50 Gold Skulltula Reward'), + lambda state: (expected_skulltulas >= 50) and state.has('Gold Skulltula Token', 50) and state.guarantee_hint()) + set_rule(world.get_location('Heart Piece Grave Chest'), lambda state: state.can_play('Suns Song')) + set_rule(world.get_entrance('Composer Grave'), lambda state: state.can_play('Zeldas Lullaby')) + set_rule( + world.get_location('Song from Composer Grave'), + lambda state: state.is_adult() or + (state.has_slingshot() or + state.has('Boomerang') or + state.has_sticks() or + state.has_explosives() or + state.has('Kokiri Sword'))) + set_rule(world.get_location('Composer Grave Chest'), lambda state: state.has_fire_source()) + set_rule( + world.get_entrance('Bottom of the Well'), + lambda state: state.can_play('Song of Storms') and + (world.dungeon_mq['BW'] or + state.can_child_attack() or + state.has_nuts())) + set_rule( + world.get_entrance('Death Mountain Entrance'), + lambda state: state.has('Zeldas Letter') or state.is_adult() or world.open_kakariko) + set_rule( + world.get_entrance('Dodongos Cavern Rocks'), + lambda state: state.has_explosives() or state.has('Progressive Strength Upgrade') or state.is_adult()) + set_rule( + world.get_location('DM Trail Freestanding PoH'), + lambda state: world.open_kakariko or + (world.difficulty != 'ohko') or + state.has('Zeldas Letter') or + state.can_blast_or_smash() or + state.can_use('Dins Fire') or + state.can_use('Nayrus Love') or + state.has_bow() or + state.has('Progressive Strength Upgrade') or + state.has_bottle() or + state.has('Hover Boots')) + set_rule( + world.get_location('Death Mountain Bombable Chest'), + lambda state: state.can_blast_or_smash() or (world.logic_tricks and state.has('Progressive Strength Upgrade'))) + set_rule( + world.get_location('Biggoron'), + lambda state: (not world.logic_no_trade_biggoron) and + state.is_adult() and + state.can_finish_adult_trades() and + state.guarantee_hint()) + set_rule( + world.get_location('Goron City Leftmost Maze Chest'), + lambda state: state.can_use('Hammer') or state.can_use('Silver Gauntlets')) + set_rule( + world.get_location('Goron City Left Maze Chest'), + lambda state: state.can_blast_or_smash() or + state.can_use('Silver Gauntlets')) + set_rule( + world.get_location('Goron City Right Maze Chest'), + lambda state: state.can_blast_or_smash() or state.can_use('Silver Gauntlets')) + set_rule( + world.get_location('Rolling Goron as Child'), + lambda state: state.has('Bomb Bag') and state.has_explosives()) + set_rule( + world.get_location('Goron City Pot Freestanding PoH'), + lambda state: (state.has_bombs() or state.has('Progressive Strength Upgrade')) and + ((state.can_play('Zeldas Lullaby') and state.has_sticks()) or state.can_use('Dins Fire'))) + set_rule(world.get_entrance('Darunias Chamber'), lambda state: state.can_play('Zeldas Lullaby')) + set_rule(world.get_location('Darunias Joy'), lambda state: state.can_play('Sarias Song')) + set_rule( + world.get_location('Goron City Stick Pot'), + lambda state: world.open_kakariko or + state.has('Zeldas Letter') or + state.has_explosives() or + state.can_use('Dins Fire')) + set_rule( + world.get_entrance('Goron City from Woods'), + lambda state: (state.can_blast_or_smash() or + state.can_use('Dins Fire') or + ((state.has_bow() or state.has('Progressive Strength Upgrade')) and state.is_adult())) and + state.can_leave_forest()) + set_rule(world.get_location('Song from Saria'), lambda state: state.has('Zeldas Letter')) + set_rule(world.get_entrance('Mountain Summit Fairy'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_location('Crater Fairy Reward'), lambda state: state.can_play('Zeldas Lullaby')) + set_rule(world.get_location('Mountain Summit Fairy Reward'), lambda state: state.can_play('Zeldas Lullaby')) + set_rule(world.get_entrance('Mountain Crater Entrance'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_entrance('Hyrule Castle Fairy'), lambda state: state.has_explosives()) + set_rule(world.get_location('Hyrule Castle Fairy Reward'), lambda state: state.can_play('Zeldas Lullaby')) + set_rule(world.get_entrance('Hyrule Castle Garden'), lambda state: state.has('Weird Egg') or (not world.shuffle_weird_egg)) + set_rule(world.get_entrance('Ganons Castle Grounds'), lambda state: state.is_adult()) + set_rule(world.get_entrance('Ganons Castle Fairy'), lambda state: state.can_use('Golden Gauntlets')) + set_rule(world.get_location('Ganons Castle Fairy Reward'), lambda state: state.can_play('Zeldas Lullaby')) + set_rule(world.get_location('Bombchu Bowling Bomb Bag'), lambda state: state.has_bombchus()) + set_rule(world.get_location('Bombchu Bowling Piece of Heart'), lambda state: state.has_bombchus()) + set_rule(world.get_location('Adult Shooting Gallery'), lambda state: state.has('Bow') and state.is_adult()) + set_rule( + world.get_location('10 Big Poes'), + lambda state: (not world.logic_no_big_poes) and + state.is_adult() and + ((state.can_use('Bow') and + state.has('Epona') and + state.has_bottle() and + state.guarantee_hint()) or + state.has('Bottle with Big Poe', world.big_poe_count))) + set_rule(world.get_location('Treasure Chest Game'), lambda state: state.can_use('Lens of Truth')) + set_rule(world.get_entrance('Lost Woods Dive Warp'), lambda state: state.can_dive() and state.can_leave_forest()) + set_rule(world.get_entrance('Zora River Dive Warp'), lambda state: state.can_dive()) + set_rule(world.get_entrance('Lake Hylia Dive Warp'), lambda state: state.can_dive()) + set_rule(world.get_entrance('Zoras Domain Dive Warp'), lambda state: state.can_dive()) + set_rule( + world.get_entrance('Zora River Waterfall'), + lambda state: state.can_play('Zeldas Lullaby') or world.logic_zora_with_cucco) + set_rule(world.get_entrance('Zora River Rocks'), lambda state: state.has_explosives()) + set_rule( + world.get_location('Zora River Lower Freestanding PoH'), + lambda state: state.has_explosives() or state.can_dive() or state.can_use('Hover Boots')) + set_rule( + world.get_location('Zora River Upper Freestanding PoH'), + lambda state: state.has_explosives() or state.can_dive() or state.can_use('Hover Boots')) + set_rule( + world.get_location('Frog Ocarina Game'), + lambda state: state.can_play('Zeldas Lullaby') and + state.can_play('Sarias Song') and + state.can_play('Suns Song') and + state.can_play('Eponas Song') and + state.can_play('Song of Time') and + state.can_play('Song of Storms')) + set_rule(world.get_location('Frogs in the Rain'), lambda state: state.can_play('Song of Storms')) + set_rule(world.get_location('Underwater Bottle'), lambda state: state.can_dive()) + set_rule(world.get_location('King Zora Moves'), lambda state: state.has('Bottle with Letter')) + set_rule(world.get_entrance('Behind King Zora'), lambda state: state.has('Bottle with Letter')) + set_rule(world.get_entrance('Zora River Adult'), lambda state: state.is_adult()) + set_rule( + world.get_entrance('Zoras Domain Adult Access'), + lambda state: state.can_play('Zeldas Lullaby') or (state.has('Hover Boots') and world.logic_zora_with_hovers)) + set_rule(world.get_entrance('Zoras Fountain Adult Access'), lambda state: state.can_reach('Zoras Fountain')) + set_rule(world.get_location('Zoras Domain Torch Run'), lambda state: state.has_sticks()) + set_rule(world.get_entrance('Jabu Jabus Belly'), lambda state: state.has_bottle()) + set_rule(world.get_entrance('Zoras Fountain Fairy'), lambda state: state.has_explosives()) + set_rule(world.get_location('Zoras Fountain Fairy Reward'), lambda state: state.can_play('Zeldas Lullaby')) + set_rule( + world.get_location('Ocarina of Time'), + lambda state: state.has('Kokiri Emerald') and + state.has('Goron Ruby') and + state.has('Zora Sapphire') and + state.guarantee_hint()) + set_rule( + world.get_location('Song from Ocarina of Time'), + lambda state: state.has('Kokiri Emerald') and + state.has('Goron Ruby') and + state.has('Zora Sapphire') and + state.guarantee_hint()) + set_rule( + world.get_entrance('Door of Time'), + lambda state: state.can_play('Song of Time') or world.open_door_of_time) + set_rule(world.get_location('Talons Chickens'), lambda state: state.has('Zeldas Letter')) + set_rule(world.get_location('Song from Malon'), lambda state: state.has('Zeldas Letter') and state.has_ocarina()) + set_rule(world.get_location('Epona'), lambda state: state.can_play('Eponas Song') and state.is_adult()) + set_rule( + world.get_entrance('Adult Forest Warp Pad'), + lambda state: state.can_play('Minuet of Forest') and state.is_adult()) + set_rule(world.get_entrance('Child Forest Warp Pad'), lambda state: state.can_play('Minuet of Forest')) + set_rule( + world.get_entrance('Meadow Gate'), + lambda state: state.has_slingshot() or + state.has_sticks() or + state.has_explosives() or + state.has('Kokiri Sword') or + state.can_use('Dins Fire')) + set_rule( + world.get_entrance('Adult Meadow Access'), + lambda state: state.can_play('Sarias Song') and state.is_adult()) + set_rule(world.get_entrance('Forest Temple Entrance'), lambda state: state.can_use('Hookshot')) + set_rule(world.get_entrance('Dampes Grave'), lambda state: state.is_adult()) + set_rule(world.get_location('Dampe Race Freestanding PoH'), lambda state: not world.logic_no_second_dampe_race) + set_rule( + world.get_location('Graveyard Freestanding PoH'), + lambda state: state.can_use('Magic Bean') or state.can_use('Longshot')) + set_rule(world.get_location('Song at Windmill'), lambda state: state.is_adult() and state.has_ocarina()) + set_rule( + world.get_location('Windmill Freestanding PoH'), + lambda state: (state.is_adult() and (world.logic_windmill_poh or state.can_play('Song of Time'))) or + state.has('Boomerang')) + set_rule( + world.get_entrance('Temple Warp Pad'), + lambda state: state.can_play('Prelude of Light') and state.can_leave_forest()) + set_rule(world.get_location('Sheik at Temple'), lambda state: state.has('Forest Medallion') and state.is_adult()) + set_rule(world.get_location('Diving in the Lab'), lambda state: state.has('Progressive Scale', 2)) + set_rule( + world.get_location('Child Fishing'), + lambda state: (not world.logic_no_child_fishing) and state.has('Kokiri Sword')) + set_rule( + world.get_location('Adult Fishing'), + lambda state: (not world.logic_no_adult_fishing) and + (state.can_use('Scarecrow') or + state.can_use('Magic Bean') or + state.can_reach(world.get_location('Morpha')))) + set_rule( + world.get_location('Lake Hylia Freestanding PoH'), + lambda state: state.can_use('Scarecrow') or state.can_use('Magic Bean')) + set_rule( + world.get_location('Lake Hylia Sun'), + lambda state: (state.can_use('Distant Scarecrow') or state.can_reach(world.get_location('Morpha'))) and + state.can_use('Bow')) + set_rule(world.get_entrance('Crater Hover Boots'), lambda state: state.can_use('Hover Boots')) + set_rule(world.get_entrance('Crater Ascent'), lambda state: state.is_adult()) + set_rule(world.get_entrance('Crater Scarecrow'), lambda state: state.can_use('Distant Scarecrow')) + set_rule(world.get_entrance('Crater Bridge'), lambda state: state.can_use('Hover Boots') or state.can_use('Hookshot')) + set_rule( + world.get_entrance('Crater Bridge Reverse'), + lambda state: state.can_use('Hover Boots') or state.can_use('Hookshot') or state.can_use('Magic Bean')) + set_rule( + world.get_entrance('Crater Warp Pad'), + lambda state: state.can_play('Bolero of Fire') and state.can_leave_forest()) + set_rule(world.get_entrance('Crater Fairy'), lambda state: state.can_use('Hammer')) + set_rule( + world.get_location('DM Crater Volcano Freestanding PoH'), + lambda state: (state.can_use('Magic Bean') and state.can_play('Bolero of Fire')) or + (world.logic_crater_bean_poh_with_hovers and state.can_use('Hover Boots'))) + set_rule( + world.get_entrance('Fire Temple Entrance'), + lambda state: state.is_adult() and (world.logic_fewer_tunic_requirements or state.has_GoronTunic())) + set_rule(world.get_location('Sheik in Crater'), lambda state: state.is_adult()) + set_rule( + world.get_location('Link the Goron'), + lambda state: state.is_adult() and + (state.has('Progressive Strength Upgrade') or state.has_explosives() or state.has_bow())) + set_rule( + world.get_entrance('Crater Access'), + lambda state: state.is_adult() and + (state.has('Progressive Strength Upgrade') or state.has_explosives() or state.has_bow())) + set_rule( + world.get_entrance('Goron Shop'), + lambda state: state.has_explosives() or + state.has('Progressive Strength Upgrade') or + state.can_use('Bow') or + state.can_use('Dins Fire') or + ((state.has('Zeldas Letter') or world.open_kakariko or state.can_use('Hammer')) and + (state.can_play('Zeldas Lullaby') and state.has_sticks()))) + set_rule( + world.get_entrance('Lake Warp Pad'), + lambda state: state.can_play('Serenade of Water') and state.can_leave_forest()) + set_rule(world.get_location('King Zora Thawed'), lambda state: state.has_blue_fire()) + set_rule(world.get_entrance('Zora Shop Adult Access'), lambda state: state.has_blue_fire()) + set_rule( + world.get_location('Zoras Fountain Bottom Freestanding PoH'), + lambda state: state.has('Iron Boots') and (world.logic_fewer_tunic_requirements or state.has_ZoraTunic())) + set_rule( + world.get_entrance('Water Temple Entrance'), + lambda state: (state.has('Iron Boots') or (world.logic_morpha_with_scale and state.has('Progressive Scale', 2))) and + state.can_use('Hookshot') and (world.logic_fewer_tunic_requirements or state.has_ZoraTunic())) + set_rule( + world.get_location('Sheik in Kakariko'), + lambda state: state.is_adult() and + state.has('Forest Medallion') and + state.has('Fire Medallion') and + state.has('Water Medallion')) + set_rule(world.get_entrance('Kakariko Potion Shop Front'), lambda state: state.is_adult()) + set_rule(world.get_entrance('Kakariko Potion Shop Back'), lambda state: state.is_adult()) + set_rule(world.get_entrance('Kakariko Bazaar'), lambda state: state.is_adult()) + set_rule( + world.get_entrance('Graveyard Warp Pad'), + lambda state: state.can_play('Nocturne of Shadow') and state.can_leave_forest()) + set_rule( + world.get_entrance('Shadow Temple Entrance'), + lambda state: state.can_use('Dins Fire') and + state.can_see_with_lens() and + (state.can_use('Hover Boots') or state.can_use('Hookshot'))) + set_rule( + world.get_entrance('Bridge Crossing'), + lambda state: state.has('Epona') or + state.can_use('Longshot') or + ((world.gerudo_fortress == 'open') and state.is_adult())) + set_rule(world.get_location('Gerudo Valley Hammer Rocks Chest'), lambda state: state.can_use('Hammer')) + set_rule( + world.get_location('Gerudo Fortress North F2 Carpenter'), + lambda state: state.can_use('Bow') or + state.can_use('Hookshot') or + state.can_use('Hover Boots') or + world.logic_tricks) + set_rule(world.get_location('Gerudo Fortress Carpenter Rescue'), lambda state: state.can_finish_GerudoFortress()) + set_rule(world.get_location('Gerudo Fortress Membership Card'), lambda state: state.can_finish_GerudoFortress()) + set_rule( + world.get_entrance('Gerudo Training Grounds Entrance'), + lambda state: state.has('Carpenter Rescue') and state.has('Gerudo Membership Card') and state.is_adult()) + set_rule( + world.get_entrance('Haunted Wasteland Entrance'), + lambda state: state.has('Carpenter Rescue') and (state.can_use('Hover Boots') or state.can_use('Longshot'))) + set_rule( + world.get_entrance('Haunted Wasteland Crossing'), + lambda state: (world.logic_lens == 'chest') or state.can_use('Lens of Truth')) + set_rule( + world.get_entrance('Colossus Warp Pad'), + lambda state: state.can_play('Requiem of Spirit') and state.can_leave_forest()) + set_rule(world.get_entrance('Colossus Fairy'), lambda state: state.has_explosives()) + set_rule( + world.get_location('Colossus Freestanding PoH'), + lambda state: state.can_play('Requiem of Spirit') and state.can_use('Magic Bean')) + set_rule(world.get_location('Desert Colossus Fairy Reward'), lambda state: state.can_play('Zeldas Lullaby')) + set_rule( + world.get_location('Gerudo Fortress Rooftop Chest'), + lambda state: state.can_use('Hover Boots') or state.can_use('Scarecrow') or state.can_use('Longshot')) + set_rule( + world.get_location('Horseback Archery 1000 Points'), + lambda state: state.has('Carpenter Rescue') and state.has('Epona') and state.has('Bow') and state.is_adult()) + set_rule( + world.get_location('Horseback Archery 1500 Points'), + lambda state: (not world.logic_no_1500_archery) and + state.has('Carpenter Rescue') and + state.has('Epona') and + state.has('Bow') and state.is_adult()) + set_rule(world.get_location('Haunted Wasteland Structure Chest'), lambda state: state.has_fire_source()) + set_rule( + world.get_location('Zelda'), + lambda state: state.has('Shadow Medallion') and state.has('Spirit Medallion') and state.is_adult()) + set_rule( + world.get_location('Ganon'), + lambda state: (state.has('Boss Key (Ganons Castle)') or world.unlocked_ganondorf) and + state.can_use('Light Arrows')) + set_rule(world.get_entrance('Kokiri Forest Storms Grotto'), lambda state: state.can_play('Song of Storms')) + set_rule(world.get_entrance('Lost Woods Generic Grotto'), lambda state: state.can_blast_or_smash()) + set_rule( + world.get_entrance('Lost Woods Sales Grotto'), + lambda state: state.has_explosives() or + (state.can_use('Hammer') and + (state.can_play('Minuet of Forest') or state.can_play('Sarias Song')))) + set_rule( + world.get_entrance('Front of Meadow Grotto'), + lambda state: state.has_explosives() or + (state.can_use('Hammer') and + (state.can_play('Minuet of Forest') or state.can_play('Sarias Song')))) + set_rule(world.get_entrance('Remote Southern Grotto'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_entrance('Field Near Lake Inside Fence Grotto'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_entrance('Field Valley Grotto'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_entrance('Field West Castle Town Grotto'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_entrance('Field Far West Castle Town Grotto'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_entrance('Field Kakariko Grotto'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_entrance('Field North Lon Lon Grotto'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_entrance('Castle Storms Grotto'), lambda state: state.can_play('Song of Storms')) + set_rule( + world.get_entrance('Kakariko Bombable Grotto'), + lambda state: state.can_blast_or_smash() and + (state.is_adult() or + (state.has_sticks() or state.has('Kokiri Sword') or state.can_use('Dins Fire')))) + set_rule(world.get_entrance('Mountain Bombable Grotto'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_entrance('Mountain Storms Grotto'), lambda state: state.can_play('Song of Storms')) + set_rule(world.get_entrance('Top of Crater Grotto'), lambda state: state.can_blast_or_smash()) + set_rule( + world.get_entrance('Zora River Plateau Open Grotto'), + lambda state: state.has_explosives() or state.can_dive() or state.is_adult()) + set_rule(world.get_entrance('Zora River Plateau Bombable Grotto'), lambda state: state.can_blast_or_smash()) + set_rule( + world.get_location('Tektite Grotto Freestanding PoH'), + lambda state: state.has('Progressive Scale', 2) or state.can_use('Iron Boots')) + set_rule( + world.get_location('GS Kokiri Know It All House'), + lambda state: state.nighttime() and + (state.can_leave_forest() or state.can_play('Suns Song')) and + state.can_child_attack()) + set_rule( + world.get_location('GS Kokiri Bean Patch'), + lambda state: state.has_bottle() and + state.can_child_attack() and + (state.can_leave_forest() or + state.has('Kokiri Sword') or + state.has_sticks() or + state.has('Boomerang') or + state.has_explosives() or + state.has('Buy Bottle Bug'))) + set_rule( + world.get_location('GS Kokiri House of Twins'), + lambda state: (state.can_use('Hookshot') or (world.logic_tricks and state.can_use('Hover Boots'))) and + state.nighttime()) + set_rule( + world.get_location('GS Lost Woods Bean Patch Near Bridge'), + lambda state: state.has_bottle() and + state.can_child_attack() and + (state.can_leave_forest() or + state.has('Kokiri Sword') or + state.has_sticks() or + state.has('Boomerang') or + state.has_explosives() or + state.has('Buy Bottle Bug'))) + set_rule( + world.get_location('GS Lost Woods Bean Patch Near Stage'), + lambda state: state.has_bottle() and + (state.can_child_attack() or (world.shuffle_scrubs == 'off' and state.has('Buy Deku Shield'))) and + (state.can_leave_forest() or + state.has('Kokiri Sword') or + state.has_sticks() or + state.has('Boomerang') or + state.has_explosives() or + state.has('Buy Bottle Bug'))) + set_rule( + world.get_location('GS Lost Woods Above Stage'), + lambda state: state.can_use('Magic Bean') and state.nighttime()) + set_rule( + world.get_location('GS Sacred Forest Meadow'), + lambda state: state.can_use('Hookshot') and state.nighttime()) + set_rule( + world.get_location('GS Hyrule Field near Kakariko'), + lambda state: (state.has('Boomerang') and state.has_explosives()) or state.can_use('Hookshot')) + set_rule( + world.get_location('GS Hyrule Field Near Gerudo Valley'), + lambda state: (state.has('Hammer') and state.has_fire_source() and state.can_use('Hookshot')) or + (state.has('Boomerang') and state.has_explosives() and state.can_use('Dins Fire'))) + set_rule(world.get_location('GS Hyrule Castle Tree'), lambda state: state.can_child_attack()) + set_rule( + world.get_location('GS Hyrule Castle Grotto'), + lambda state: state.has('Boomerang') and state.has_explosives()) + set_rule(world.get_location('GS Lon Lon Ranch Rain Shed'), lambda state: state.nighttime()) + set_rule( + world.get_location('GS Lon Lon Ranch House Window'), + lambda state: state.has('Boomerang') and state.nighttime()) + set_rule( + world.get_location('GS Lon Lon Ranch Back Wall'), + lambda state: state.has('Boomerang') and state.nighttime()) + set_rule(world.get_location('GS Kakariko House Under Construction'), lambda state: state.nighttime()) + set_rule(world.get_location('GS Kakariko Skulltula House'), lambda state: state.nighttime()) + set_rule(world.get_location('GS Kakariko Guard\'s House'), lambda state: state.nighttime()) + set_rule(world.get_location('GS Kakariko Tree'), lambda state: state.nighttime()) + set_rule( + world.get_location('GS Kakariko Watchtower'), + lambda state: (state.has_slingshot() or state.has_bombchus()) and state.nighttime()) + set_rule( + world.get_location('GS Kakariko Above Impa\'s House'), + lambda state: state.can_use('Hookshot') and state.nighttime()) + set_rule(world.get_location('GS Graveyard Wall'), lambda state: state.has('Boomerang') and state.nighttime()) + set_rule( + world.get_location('GS Graveyard Bean Patch'), + lambda state: state.has_bottle() and state.can_child_attack()) + set_rule( + world.get_location('GS Mountain Trail Bean Patch'), + lambda state: state.has_bottle() and (state.has_explosives() or state.has('Progressive Strength Upgrade'))) + set_rule(world.get_location('GS Mountain Trail Bomb Alcove'), lambda state: state.can_blast_or_smash()) + set_rule( + world.get_location('GS Mountain Trail Path to Crater'), + lambda state: state.can_use('Hammer') and state.nighttime()) + set_rule( + world.get_location('GS Mountain Trail Above Dodongo\'s Cavern'), + lambda state: state.can_use('Hammer') and state.nighttime()) + set_rule(world.get_location('GS Goron City Boulder Maze'), lambda state: state.has_explosives()) + set_rule( + world.get_location('GS Death Mountain Crater Crate'), + lambda state: state.can_blast_or_smash() and state.can_child_attack()) + set_rule(world.get_location('GS Goron City Center Platform'), lambda state: state.is_adult()) + set_rule( + world.get_location('GS Mountain Crater Bean Patch'), + lambda state: state.can_play('Bolero of Fire') and state.has_bottle() and state.can_child_attack()) + set_rule(world.get_location('GS Zora River Ladder'), lambda state: state.nighttime() and state.can_child_attack()) + set_rule( + world.get_location('GS Zora River Near Raised Grottos'), + lambda state: state.can_use('Hookshot') and state.nighttime()) + set_rule( + world.get_location('GS Zora River Above Bridge'), + lambda state: state.can_use('Hookshot') and state.nighttime()) + set_rule( + world.get_location('GS Zora\'s Domain Frozen Waterfall'), + lambda state: state.nighttime() and + (state.has('Progressive Hookshot') or state.has_bow() or state.has('Magic Meter'))) + set_rule( + world.get_location('GS Zora\'s Fountain Above the Log'), + lambda state: state.has('Boomerang') and state.nighttime()) + set_rule( + world.get_location('GS Zora\'s Fountain Hidden Cave'), + lambda state: state.has('Progressive Strength Upgrade', 2) and + state.can_blast_or_smash() and + state.has('Progressive Hookshot') and + state.nighttime()) + set_rule( + world.get_location('GS Lake Hylia Bean Patch'), + lambda state: state.has_bottle() and state.can_child_attack()) + set_rule(world.get_location('GS Lake Hylia Lab Wall'), lambda state: state.has('Boomerang') and state.nighttime()) + set_rule( + world.get_location('GS Lake Hylia Small Island'), + lambda state: state.nighttime() and state.can_child_attack()) + set_rule(world.get_location('GS Lake Hylia Giant Tree'), lambda state: state.can_use('Longshot')) + set_rule( + world.get_location('GS Lab Underwater Crate'), + lambda state: state.has('Iron Boots') and state.can_use('Hookshot')) + set_rule( + world.get_location('GS Gerudo Valley Small Bridge'), + lambda state: state.has('Boomerang') and state.nighttime()) + set_rule( + world.get_location('GS Gerudo Valley Bean Patch'), + lambda state: state.has_bottle() and state.can_child_attack()) + set_rule( + world.get_location('GS Gerudo Valley Behind Tent'), + lambda state: state.can_use('Hookshot') and state.nighttime()) + set_rule( + world.get_location('GS Gerudo Valley Pillar'), + lambda state: state.can_use('Hookshot') and state.nighttime()) + set_rule( + world.get_location('GS Gerudo Fortress Archery Range'), + lambda state: state.can_use('Hookshot') and state.has('Carpenter Rescue') and state.nighttime()) + set_rule( + world.get_location('GS Gerudo Fortress Top Floor'), + lambda state: state.nighttime() and + (state.can_use('Bow') or + state.can_use('Hookshot') or + state.can_use('Hover Boots') or + world.logic_tricks)) + set_rule(world.get_location('GS Wasteland Ruins'), lambda state: state.can_use('Hookshot')) + set_rule( + world.get_location('GS Desert Colossus Bean Patch'), + lambda state: state.has_bottle() and state.can_play('Requiem of Spirit') and state.can_child_attack()) + set_rule( + world.get_location('GS Desert Colossus Tree'), + lambda state: state.can_use('Hookshot') and state.nighttime()) + set_rule( + world.get_location('GS Desert Colossus Hill'), + lambda state: ((state.can_use('Magic Bean') and state.can_play('Requiem of Spirit')) or + state.can_use('Longshot')) and + state.nighttime()) + set_rule(world.get_location('GS Zora River Tree'), lambda state: state.can_child_attack()) + set_rule(world.get_location('HF Grotto Deku Scrub Piece of Heart'), lambda state: state.can_stun_deku()) + set_rule( + world.get_entrance('Zora River Storms Grotto'), + lambda state: state.can_play('Song of Storms') and state.can_stun_deku()) + set_rule( + world.get_entrance('Meadow Storms Grotto Child Access'), + lambda state: state.can_play('Song of Storms') and + (state.can_child_attack() or state.has_nuts() or state.has('Buy Deku Shield'))) + set_rule(world.get_entrance('Meadow Storms Grotto Adult Access'), lambda state: state.can_play('Song of Storms')) + set_rule(world.get_entrance('Lake Hylia Grotto'), lambda state: state.can_stun_deku()) + set_rule(world.get_location('LW Deku Scrub Deku Nuts'), lambda state: state.can_stun_deku()) + set_rule(world.get_location('LW Deku Scrub Deku Sticks'), lambda state: state.can_stun_deku()) + set_rule(world.get_location('LW Deku Scrub Deku Stick Upgrade'), lambda state: state.can_stun_deku()) + set_rule(world.get_entrance('Desert Colossus Grotto'), lambda state: state.can_use('Silver Gauntlets')) + set_rule( + world.get_location('DMC Deku Scrub Bombs'), + lambda state: state.can_blast_or_smash() and + (state.can_child_attack() or state.has_nuts() or state.has('Buy Deku Shield'))) + set_rule(world.get_entrance('DMC Hammer Grotto'), lambda state: state.can_use('Hammer')) + set_rule( + world.get_entrance('Goron City Grotto'), + lambda state: state.is_adult() and + ((state.can_play('Song of Time') and + (world.difficulty != 'ohko' or state.has_GoronTunic() or state.can_use('Longshot') or state.can_use('Nayrus Love'))) or + (world.difficulty != 'ohko' and state.has_GoronTunic() and state.can_use('Hookshot')) or + (state.can_use('Nayrus Love') and state.can_use('Hookshot')))) + set_rule( + world.get_entrance('Lon Lon Grotto'), + lambda state: state.can_child_attack() or state.has_nuts() or state.has('Buy Deku Shield')) + set_rule(world.get_entrance('Gerudo Valley Storms Grotto'), lambda state: state.can_play('Song of Storms')) + + + for location in world.get_locations(): + if location.type != 'Chest': + forbid_item(location, 'Ice Trap') + add_item_rule(location, lambda i: not (i.type == 'Song' and not i.world.shuffle_song_items and i.world.id != location.world.id)) + add_item_rule(location, lambda i: not (i.type == 'Shop' and i.world.id != location.world.id)) + if location.type == 'Shop': + if location.parent_region.name in ['Castle Town Bombchu Shop', 'Castle Town Potion Shop', 'Castle Town Bazaar']: + if not world.check_beatable_only: + forbid_item(location, 'Buy Goron Tunic') + forbid_item(location, 'Buy Zora Tunic') + + if location.name in world.shop_prices: + location.price = world.shop_prices[location.name] + if location.price > 200: + set_rule(location, lambda state: state.has('Progressive Wallet', 2)) + elif location.price > 99: + set_rule(location, lambda state: state.has('Progressive Wallet')) + + +# This function should be ran once after the shop items are placed in the world. +# It should be ran before other items are placed in the world so that logic has +# the correct checks for them. This is save to do since every shop is still +# accessible when all items are obtained and every shop item is not. +# This function should also be called when a world is copied if the original world +# had called this function because the world.copy does not copy the rules +def set_shop_rules(world): + for location in world.get_filled_locations(): + if location.item.type == 'Shop': + # Add wallet requirements + if location.item.name in ['Buy Arrows (50)', 'Buy Fish', 'Buy Goron Tunic', 'Buy Bombchu (20)', 'Buy Bombs (30)']: + add_rule(location, lambda state: state.has('Progressive Wallet')) + elif location.item.name in ['Buy Zora Tunic', 'Buy Blue Fire']: + add_rule(location, lambda state: state.has('Progressive Wallet', 2)) + + # Add adult only checks + if location.item.name in ['Buy Goron Tunic', 'Buy Zora Tunic']: + if location.parent_region.name == 'Goron Shop': + add_rule( + location, + lambda state: state.is_adult() and + (state.has_explosives() or + state.has('Progressive Strength Upgrade') or + state.has_bow())) + elif location.parent_region.name == 'Zora Shop': + add_rule(location, lambda state: state.can_reach('Zora Shop Adult Access', 'Entrance')) + elif location.parent_region.name in ['Castle Town Bombchu Shop', 'Castle Town Potion Shop', 'Castle Town Bazaar']: + set_rule(location, lambda state: False) + else: + add_rule(location, lambda state: state.is_adult()) + + # Add item prerequisit checks + if location.item.name in ['Buy Blue Fire', + 'Buy Blue Potion', + 'Buy Bottle Bug', + 'Buy Fish', + 'Buy Green Potion', + 'Buy Poe', + 'Buy Red Potion [30]', + 'Buy Red Potion [40]', + 'Buy Red Potion [50]', + 'Buy Fairy\'s Spirit']: + add_rule(location, lambda state: state.has_bottle()) + if location.item.name in ['Buy Bombchu (10)', 'Buy Bombchu (20)', 'Buy Bombchu (5)']: + add_rule(location, lambda state: state.has_bombchus_item()) + + +# Deku Tree Vanilla +def dung_rules_dt0(world): + set_rule( + world.get_entrance('Deku Tree Basement Path'), + lambda state: state.has_slingshot() and (state.has_sticks() or state.can_use('Dins Fire'))) + set_rule(world.get_entrance('Deku Tree Slingshot Passage'), lambda state: state.has('Buy Deku Shield')) + + # Boss + set_rule( + world.get_location('Queen Gohma Heart'), + lambda state: state.has('Buy Deku Shield') and (state.has('Kokiri Sword') or state.has_sticks())) + set_rule( + world.get_location('Queen Gohma'), + lambda state: state.has('Buy Deku Shield') and (state.has('Kokiri Sword') or state.has_sticks())) + + # GS + set_rule(world.get_location('GS Deku Tree Basement Back Room'), lambda state: state.has('Boomerang') and (state.has_explosives())) + set_rule(world.get_location('GS Deku Tree Basement Gate'), lambda state: state.can_child_attack()) + set_rule( + world.get_location('GS Deku Tree Basement Vines'), + lambda state: state.has_slingshot() or + state.has('Boomerang') or + state.has_explosives() or + state.can_use('Dins Fire') or + (world.logic_tricks and (state.has_sticks() or state.has('Kokiri Sword')))) + set_rule(world.get_location('GS Deku Tree Compass Room'), lambda state: state.can_child_attack()) + +# Deku Tree MQ +def dung_rules_dtmq(world): + set_rule( + world.get_entrance('Deku Tree Compass Passage'), + lambda state: state.has_slingshot() and (state.has_sticks() or state.can_use('Dins Fire'))) + set_rule( + world.get_entrance('Deku Tree Basement Path'), + lambda state: state.has_slingshot() and (state.has_sticks() or state.can_use('Dins Fire'))) + set_rule(world.get_location('Deku Tree MQ Slingshot Chest'), lambda state: state.can_child_attack()) + set_rule( + world.get_location('Deku Tree MQ Slingshot Room Back Chest'), + lambda state: state.has_sticks() or state.can_use('Dins Fire')) + set_rule( + world.get_location('Deku Tree MQ Basement Chest'), + lambda state: state.has_sticks() or state.can_use('Dins Fire')) + set_rule(world.get_location('Deku Tree MQ After Spinning Log Chest'), lambda state: state.can_play('Song of Time')) + + # Boss + set_rule( + world.get_location('Queen Gohma Heart'), + lambda state: state.has('Buy Deku Shield') and (state.has('Kokiri Sword') or state.has_sticks())) + set_rule( + world.get_location('Queen Gohma'), + lambda state: state.has('Buy Deku Shield') and (state.has('Kokiri Sword') or state.has_sticks())) + + # GS + set_rule(world.get_location('GS Deku Tree MQ Lobby'), lambda state: state.can_child_attack()) + set_rule( + world.get_location('GS Deku Tree MQ Compass Room'), + lambda state: state.has('Boomerang') and + ((state.has_bombs() and state.can_play('Song of Time')) or state.has_bombchus())) + set_rule( + world.get_location('GS Deku Tree MQ Basement Ceiling'), + lambda state: state.has('Boomerang') and state.can_play('Song of Time')) + set_rule(world.get_location('GS Deku Tree MQ Basement Back Room'), lambda state: state.has('Boomerang')) + +# Dodongo's Cavern Vanilla +def dung_rules_dc0(world): + set_rule( + world.get_entrance('Dodongos Cavern Lobby'), + lambda state: state.can_blast_or_smash() or state.has('Progressive Strength Upgrade')) + set_rule( + world.get_entrance('Dodongos Cavern Left Door'), + lambda state: (state.is_adult() or + ((state.has_sticks() or state.can_use('Dins Fire')) and + (state.has_slingshot() or state.has_sticks() or state.has_explosives() or state.has('Kokiri Sword')))) and + (state.has_explosives() or + state.has('Progressive Strength Upgrade') or + state.can_use('Dins Fire') or + (world.logic_tricks and state.can_use('Bow')))) + set_rule( + world.get_location('Dodongos Cavern Compass Chest'), + lambda state: state.is_adult() or + state.has_sticks() or + (state.can_use('Dins Fire') and (state.has_slingshot() or state.has_explosives() or state.has('Kokiri Sword')))) + set_rule( + world.get_location('DC Deku Scrub Deku Sticks'), + lambda state: state.is_adult() or + state.has_slingshot() or + state.has_sticks() or + state.has_explosives() or + state.has('Kokiri Sword')) + set_rule( + world.get_entrance('Dodongos Cavern Slingshot Target'), + lambda state: (state.has_slingshot() and (state.has_explosives() or state.has('Progressive Strength Upgrade'))) or + ((state.has_bow() or state.has('Hover Boots') or state.has('Progressive Hookshot', 2) or world.logic_dc_jump) and + state.is_adult())) + set_rule(world.get_location('DC Deku Scrub Deku Nuts'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_location('DC Deku Scrub Deku Seeds'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_location('Dodongos Cavern End of Bridge Chest'), lambda state: state.can_blast_or_smash()) + set_rule(world.get_entrance('Dodongos Cavern Bomb Drop'), lambda state: state.has_explosives()) + + # Boss + set_rule( + world.get_location('King Dodongo'), + lambda state: (state.has_bombs() or state.has('Progressive Strength Upgrade')) and + (state.is_adult() or state.has_sticks() or state.has('Kokiri Sword'))) + set_rule( + world.get_location('King Dodongo Heart'), + lambda state: (state.has_bombs() or state.has('Progressive Strength Upgrade')) and + (state.is_adult() or state.has_sticks() or state.has('Kokiri Sword'))) + + # GS + set_rule( + world.get_location('GS Dodongo\'s Cavern East Side Room'), + lambda state: state.has_explosives() or + state.is_adult() or + state.has_slingshot() or + state.has('Boomerang') or + state.has_sticks() or + state.has('Kokiri Sword')) + set_rule( + world.get_location('GS Dodongo\'s Cavern Alcove Above Stairs'), + lambda state: state.can_use('Hookshot') or + (state.has('Boomerang') and (state.has_explosives() or state.has('Progressive Strength Upgrade')))) + set_rule( + world.get_location('GS Dodongo\'s Cavern Scarecrow'), + lambda state: state.can_use('Scarecrow') or state.can_use('Longshot')) + +# Dodongo's Cavern MQ +def dung_rules_dcmq(world): + set_rule( + world.get_entrance('Dodongos Cavern Lobby'), + lambda state: state.can_blast_or_smash() or state.has('Progressive Strength Upgrade')) + set_rule(world.get_entrance('Dodongos Cavern Bomb Drop'), lambda state: state.has_explosives()) + set_rule( + world.get_location('Dodongos Cavern MQ Compass Chest'), + lambda state: state.is_adult() or state.can_child_attack() or state.has_nuts()) + set_rule( + world.get_location('Dodongos Cavern MQ Torch Puzzle Room Chest'), + lambda state: state.can_blast_or_smash() or + state.has_sticks() or + state.can_use('Dins Fire') or + (state.is_adult() and (world.logic_dc_jump or state.has('Hover Boots') or state.has('Progressive Hookshot')))) + set_rule( + world.get_location('Dodongos Cavern MQ Larva Room Chest'), + lambda state: (state.has_sticks() and (state.has_explosives() or state.has('Progressive Strength Upgrade'))) or + state.has_fire_source()) + set_rule( + world.get_location('Dodongos Cavern MQ Bomb Bag Chest'), + lambda state: state.is_adult() or + (state.has_slingshot() and + (state.has_explosives() or + ((state.has_sticks() or state.can_use('Dins Fire')) and + (world.difficulty != 'ohko' or state.has_bottle() or state.can_use('Nayrus Love')))))) + set_rule(world.get_location('DC MQ Deku Scrub Deku Sticks'), lambda state: state.can_stun_deku()) + set_rule(world.get_location('DC MQ Deku Scrub Deku Seeds'), lambda state: state.can_stun_deku()) + set_rule(world.get_location('DC MQ Deku Scrub Deku Shield'), lambda state: state.can_stun_deku()) + set_rule( + world.get_location('DC MQ Deku Scrub Red Potion'), + lambda state: state.is_adult() or + state.has_explosives() or + ((state.has_sticks() or state.can_use('Dins Fire')) and + (world.difficulty != 'ohko' or state.has_bottle() or state.can_use('Nayrus Love')))) + + # Boss + set_rule( + world.get_location('King Dodongo'), + lambda state: (state.has_bombs() or state.has('Progressive Strength Upgrade')) and + (state.is_adult() or state.has_sticks() or state.has('Kokiri Sword'))) + set_rule( + world.get_location('King Dodongo Heart'), + lambda state: (state.has_bombs() or state.has('Progressive Strength Upgrade')) and + (state.is_adult() or state.has_sticks() or state.has('Kokiri Sword'))) + + # GS + set_rule( + world.get_location('GS Dodongo\'s Cavern MQ Song of Time Block Room'), + lambda state: state.can_play('Song of Time') and (state.can_child_attack() or state.is_adult())) + set_rule( + world.get_location('GS Dodongo\'s Cavern MQ Larva Room'), + lambda state: (state.has_sticks() and (state.has_explosives or state.has('Progressive Strength Upgrade'))) or + state.has_fire_source()) + set_rule(world.get_location('GS Dodongo\'s Cavern MQ Lizalfos Room'), lambda state: state.can_blast_or_smash()) + set_rule( + world.get_location('GS Dodongo\'s Cavern MQ Scrub Room'), + lambda state: (state.has('Boomerang') and + (state.has_slingshot() or (state.is_adult() and state.has_explosives())) and + (state.has_explosives() or + (state.has('Progressive Strength Upgrade') and + (state.can_use('Hammer') or + ((state.has_sticks() or state.can_use('Dins Fire') or (state.is_adult() and (world.logic_dc_jump or state.has('Hover Boots')))) and + (world.difficulty != 'ohko' or state.has_bottle() or state.can_use('Nayrus Love'))))))) or + (state.can_use('Hookshot') and (state.has_explosives() or state.has('Progressive Strength Upgrade') or state.has_bow() or state.can_use('Dins Fire')))) + +# Jabu Jabu's Belly Vanilla +def dung_rules_jb0(world): + set_rule( + world.get_entrance('Jabu Jabus Belly Ceiling Switch'), + lambda state: state.has_slingshot() or state.has_explosives() or state.has('Boomerang')) + set_rule(world.get_entrance('Jabu Jabus Belly Tentacles'), lambda state: state.has('Boomerang')) + set_rule( + world.get_entrance('Jabu Jabus Belly Octopus'), + lambda state: state.has_sticks() or state.has('Kokiri Sword')) + +# Jabu Jabu's Belly MQ +def dung_rules_jbmq(world): + set_rule(world.get_entrance('Jabu Jabus Belly Cow Switch'), lambda state: state.has_slingshot()) + set_rule( + world.get_entrance('Jabu Jabus Belly Tentacle Access'), + lambda state: state.has_explosives() and state.has('Boomerang')) + set_rule( + world.get_entrance('Jabu Jabus Belly Octopus'), + lambda state: state.has_sticks() or (state.has('Kokiri Sword') and state.can_use('Dins Fire'))) + set_rule(world.get_location('Jabu Jabus Belly MQ Map Chest'), lambda state: state.has_explosives()) + set_rule(world.get_location('Jabu Jabus Belly MQ Entry Side Chest'), lambda state: state.has_slingshot()) + + # GS + set_rule(world.get_location('GS Jabu Jabu MQ Boomerang Room'), lambda state: state.can_play('Song of Time')) + set_rule( + world.get_location('GS Jabu Jabu MQ Tailpasaran Room'), + lambda state: state.has_sticks() or state.can_use('Dins Fire')) + set_rule(world.get_location('GS Jabu Jabu MQ Invisible Enemies Room'), lambda state: state.can_see_with_lens()) + +# Forest Temple Vanilla +def dung_rules_fot0(world): + set_rule(world.get_entrance('Forest Temple Song of Time Block'), lambda state: state.can_play('Song of Time')) + set_rule(world.get_entrance('Forest Temple Lobby Eyeball Switch'), lambda state: state.can_use('Bow')) + set_rule( + world.get_entrance('Forest Temple Lobby Locked Door'), + lambda state: state.has('Small Key (Forest Temple)', 1)) + set_rule( + world.get_entrance('Forest Temple Well Connection'), + lambda state: state.can_use('Iron Boots') or + state.can_use('Longshot') or + state.has('Progressive Scale', 2) or + (world.logic_tricks and state.can_use('Hookshot'))) #Longshot can grab some very high up vines to drain the well. + set_rule(world.get_entrance('Forest Temple Scarecrows Song'), lambda state: False) #For some reason you can't actually activate this from below. Cool game. + set_rule(world.get_entrance('Forest Temple Elevator'), lambda state: state.can_use('Bow')) + set_rule(world.get_entrance('Forest Temple Outside Backdoor'), lambda state: state.can_use('Hover Boots')) + set_rule( + world.get_entrance('Forest Temple Twisted Hall'), + lambda state: state.has('Progressive Strength Upgrade') and state.has('Small Key (Forest Temple)', 3)) + set_rule( + world.get_entrance('Forest Temple Straightened Hall'), + lambda state: state.has('Progressive Strength Upgrade') and + state.has('Small Key (Forest Temple)', 2) and + state.can_use('Bow')) + set_rule( + world.get_entrance('Forest Temple Drop to Falling Room'), + lambda state: state.has('Small Key (Forest Temple)', 5) and + (state.has('Bow') or state.can_use('Dins Fire'))) + set_rule( + world.get_location('Forest Temple Block Push Chest'), + lambda state: state.has('Progressive Strength Upgrade') and state.can_use('Bow')) + set_rule(world.get_location('Forest Temple Red Poe Chest'), lambda state: state.can_use('Bow')) + set_rule(world.get_location('Forest Temple Blue Poe Chest'), lambda state: state.can_use('Bow')) + + # Boss + set_rule(world.get_location('Phantom Ganon'), lambda state: state.has('Boss Key (Forest Temple)')) + set_rule(world.get_location('Phantom Ganon Heart'), lambda state: state.has('Boss Key (Forest Temple)')) + + # GS + set_rule( + world.get_location('GS Forest Temple First Room'), + lambda state: state.can_use('Hookshot') or state.can_use('Bow') or state.can_use('Dins Fire')) + set_rule(world.get_location('GS Forest Temple Lobby'), lambda state: state.can_use('Hookshot')) + set_rule(world.get_location('GS Forest Temple Outdoor East'), lambda state: state.can_use('Hookshot')) + set_rule( + world.get_location('GS Forest Temple Outdoor West'), + lambda state: state.can_use('Longshot') or + (state.can_use('Hookshot') and state.can_reach('Forest Temple Outside Upper Ledge'))) + set_rule(world.get_location('GS Forest Temple Basement'), lambda state: state.can_use('Hookshot')) + +# Forest Temple MQ +def dung_rules_fotmq(world): + set_rule( + world.get_entrance('Forest Temple Lobby Locked Door'), + lambda state: state.has('Small Key (Forest Temple)', 1)) + set_rule(world.get_entrance('Forest Temple West Eye Switch'), lambda state: state.can_use('Bow')) + set_rule(world.get_entrance('Forest Temple East Eye Switch'), lambda state: state.can_use('Bow')) + set_rule( + world.get_entrance('Forest Temple Crystal Switch Jump'), + lambda state: (state.has_bombchus() and world.logic_tricks) or + state.has('Progressive Strength Upgrade') or + state.can_use('Hover Boots')) + set_rule( + world.get_entrance('Forest Temple Block Puzzle Solve'), + lambda state: (state.has_bombchus() and world.logic_tricks) or + state.has('Progressive Strength Upgrade')) + set_rule(world.get_entrance('Forest Temple Twisted Hall'), lambda state: state.has('Small Key (Forest Temple)', 4)) + set_rule( + world.get_entrance('Forest Temple Well Connection'), + lambda state: state.can_use('Iron Boots') or + state.can_use('Longshot') or + state.has('Progressive Scale', 2) or + (world.logic_tricks and state.can_use('Hookshot'))) + set_rule(world.get_entrance('Forest Temple Webs'), lambda state: state.can_use('Fire Arrows')) + set_rule( + world.get_entrance('Forest Temple Climb to Top Ledges'), + lambda state: state.can_use('Longshot') or + state.can_use('Hover Boots') or + state.can_play('Song of Time') or + (world.logic_tricks and state.can_use('Hookshot'))) + set_rule(world.get_entrance('Forest Temple Longshot to NE Outdoors Ledge'), lambda state: state.can_use('Longshot')) + set_rule(world.get_entrance('Forest Temple Song of Time Block Climb'), lambda state: state.can_play('Song of Time')) + set_rule( + world.get_entrance('Forest Temple Drop to Falling Room'), + lambda state: state.has('Small Key (Forest Temple)', 5) and + (state.can_use('Bow') or state.can_use('Dins Fire'))) # Only 5 keys because the door you could 'waste' your key on is the door you're trying to use keys to get to. + set_rule( + world.get_entrance('Forest Temple Elevator'), + lambda state: state.can_use('Bow') and + state.has('Small Key (Forest Temple)', 6) and + state.can_reach('Forest Temple Bow Region')) + if not (world.keysanity or world.tokensanity != 'off'): # Normal seeds will fail to generate if the Boss Key is placed at this location, as it must be a key to progress into the temple. This solution not ideal as it does not allow the Boss Key to appear at this location in beatable only seeds. + forbid_item(world.get_location('Forest Temple MQ First Chest'), 'Boss Key (Forest Temple)') + set_rule(world.get_location('Forest Temple MQ Chest Behind Lobby'), lambda state: state.can_play('Song of Time')) + set_rule(world.get_location('Forest Temple MQ Boss Key Chest'), lambda state: state.has('Small Key (Forest Temple)', 3)) + set_rule(world.get_location('Forest Temple MQ Well Chest'), lambda state: state.can_use('Bow')) + set_rule(world.get_location('Forest Temple MQ Map Chest'), lambda state: state.can_use('Bow')) + set_rule(world.get_location('Forest Temple MQ Compass Chest'), lambda state: state.can_use('Bow')) + + # Boss + set_rule(world.get_location('Phantom Ganon'), lambda state: state.has('Boss Key (Forest Temple)')) + set_rule(world.get_location('Phantom Ganon Heart'), lambda state: state.has('Boss Key (Forest Temple)')) + + # GS + set_rule(world.get_location('GS Forest Temple MQ Well'), lambda state: state.can_use('Iron Boots') or state.can_use('Bow')) + +# Fire Temple Vanilla +def dung_rules_fit0(world): + set_rule( + world.get_entrance('Fire Temple Early Climb'), + lambda state: state.has_GoronTunic() and + state.has('Small Key (Fire Temple)', 4) and + state.has('Progressive Strength Upgrade') and + (state.has_explosives() or ((state.has_bow() or state.has('Progressive Hookshot')) and state.is_adult()))) + set_rule( + world.get_entrance('Fire Temple Fire Maze Escape'), + lambda state: state.has('Small Key (Fire Temple)', 8) or + (state.has('Small Key (Fire Temple)', 7) and state.can_use('Hover Boots') and state.can_use('Hammer'))) + set_rule( + world.get_location('Fire Temple Fire Dancer Chest'), + lambda state: (state.has('Small Key (Fire Temple)', 8) or not world.keysanity) and + state.can_use('Hammer')) + set_rule( + world.get_location('Fire Temple Boss Key Chest'), + lambda state: (state.has('Small Key (Fire Temple)', 8) or not world.keysanity) and state.can_use('Hammer')) + set_rule( + world.get_location('Fire Temple Big Lava Room Bombable Chest'), + lambda state: state.has('Small Key (Fire Temple)', 2) and state.has_explosives()) + set_rule( + world.get_location('Fire Temple Big Lava Room Open Chest'), + lambda state: state.has('Small Key (Fire Temple)', 2)) + set_rule( + world.get_location('Fire Temple Map Chest'), + lambda state: state.has('Small Key (Fire Temple)', 6) or + (state.has('Small Key (Fire Temple)', 5) and state.can_use('Bow'))) + set_rule( + world.get_location('Fire Temple Boulder Maze Upper Chest'), + lambda state: state.has('Small Key (Fire Temple)', 6)) + set_rule( + world.get_location('Fire Temple Boulder Maze Bombable Pit'), + lambda state: state.has('Small Key (Fire Temple)', 6) and state.has_explosives()) + set_rule( + world.get_location('Fire Temple Scarecrow Chest'), + lambda state: state.has('Small Key (Fire Temple)', 6) and state.can_use('Scarecrow')) + set_rule(world.get_location('Fire Temple Compass Chest'), lambda state: state.has('Small Key (Fire Temple)', 7)) + set_rule( + world.get_location('Fire Temple Highest Goron Chest'), + lambda state: state.can_use('Hammer') and + (state.can_play('Song of Time') or + (world.logic_tricks and (state.can_use('Hover Boots') or state.has_explosives())))) + set_rule(world.get_location('Fire Temple Megaton Hammer Chest'), lambda state: state.has_explosives()) + + # Boss + set_rule( + world.get_location('Volvagia'), + lambda state: state.has_GoronTunic() and + state.can_use('Hammer') and + state.has('Boss Key (Fire Temple)') and + (state.has('Hover Boots') or (state.can_reach('Fire Temple Upper') and (state.can_play('Song of Time') or state.has_explosives())))) + set_rule( + world.get_location('Volvagia Heart'), + lambda state: state.has_GoronTunic() and + state.can_use('Hammer') and + state.has('Boss Key (Fire Temple)') and + (state.has('Hover Boots') or (state.can_reach('Fire Temple Upper') and (state.can_play('Song of Time') or state.has_explosives())))) + + # GS + set_rule( + world.get_location('GS Fire Temple Song of Time Room'), + lambda state: state.has('Small Key (Fire Temple)', 2) and state.can_play('Song of Time')) + set_rule( + world.get_location('GS Fire Temple Unmarked Bomb Wall'), + lambda state: state.has('Small Key (Fire Temple)', 4) and state.has_explosives()) + set_rule( + world.get_location('GS Fire Temple East Tower Climb'), + lambda state: state.has('Small Key (Fire Temple)', 6) and state.can_use('Scarecrow')) + set_rule( + world.get_location('GS Fire Temple East Tower Top'), + lambda state: state.has('Small Key (Fire Temple)', 6) and state.can_use('Scarecrow')) + set_rule( + world.get_location('GS Fire Temple Basement'), + lambda state: (state.has('Small Key (Fire Temple)', 8) or not world.keysanity) and state.can_use('Hammer')) + +# Fire Temple MQ +def dung_rules_fitmq(world): + set_rule( + world.get_entrance('Fire Temple Lower Locked Door'), + lambda state: state.has('Small Key (Fire Temple)', 5) and + (state.has_explosives() or state.has('Hammer') or state.has('Progressive Hookshot'))) + set_rule(world.get_entrance('Fire Temple Hammer Statue'), lambda state: state.can_use('Hammer')) + set_rule( + world.get_entrance('Fire Temple Early Climb'), + lambda state: state.has_GoronTunic() and state.has('Small Key (Fire Temple)', 2) and state.has_fire_source()) + set_rule( + world.get_entrance('Fire Temple Maze Climb'), + lambda state: (state.has_explosives() or world.logic_tricks) and state.can_use('Hookshot')) + set_rule( + world.get_entrance('Fire Temple Maze Escape'), + lambda state: state.has('Small Key (Fire Temple)', 3) and state.has_bow()) + set_rule( + world.get_location('Fire Temple MQ Chest Near Boss'), + lambda state: (state.has('Hover Boots') and state.has_fire_source()) or + (state.has('Progressive Hookshot') and + (state.can_use('Fire Arrows') or + (state.can_use('Dins Fire') and + (world.difficulty != 'ohko' or + state.has_GoronTunic() or + state.has_bow() or + state.has('Progressive Hookshot', 2)))))) + set_rule(world.get_location('Fire Temple MQ Map Chest'), lambda state: state.has('Hammer')) + set_rule( + world.get_location('Fire Temple MQ Boss Key Chest'), + lambda state: state.has_fire_source() and + (state.has_bow() or world.logic_tricks) and + state.has('Progressive Hookshot')) + set_rule( + world.get_location('Fire Temple MQ Big Lava Room Bombable Chest'), + lambda state: state.has_fire_source() and state.has('Progressive Hookshot') and state.has_explosives()) + set_rule(world.get_location('Fire Temple MQ Maze Side Room'), lambda state: state.has_explosives()) + set_rule(world.get_location('Fire Temple MQ Compass Chest'), lambda state: state.has_explosives()) + set_rule( + world.get_location('Fire Temple MQ West Tower Top Chest'), + lambda state: state.has('Small Key (Fire Temple)', 4)) + + # Boss + set_rule( + world.get_entrance('Fire Temple Boss Door'), + lambda state: state.has_fire_source() and + state.has_GoronTunic() and + state.has('Hammer') and + state.has('Boss Key (Fire Temple)') and + (state.has('Hover Boots') or state.can_reach('Fire Temple Upper'))) + + # GS + set_rule( + world.get_location('GS Fire Temple MQ East Tower Top'), + lambda state: state.can_play('Song of Time') or state.can_use('Longshot')) + set_rule( + world.get_location('GS Fire Temple MQ Fire Wall Maze Side Room'), + lambda state: state.can_play('Song of Time') or state.has('Hover Boots')) + set_rule(world.get_location('GS Fire Temple MQ Fire Wall Maze Center'), lambda state: state.has_explosives()) + set_rule( + world.get_location('GS Fire Temple MQ Above Fire Wall Maze'), + lambda state: state.has('Small Key (Fire Temple)', 5) or + ((item_name(state, 'GS Fire Temple MQ Above Fire Wall Maze') == 'Small Key (Fire Temple)' or + not (world.keys_placed or item_name(state, 'GS Fire Temple MQ Above Fire Wall Maze') == 'Boss Key (Fire Temple)')) and + state.has('Small Key (Fire Temple)', 4))) + +# Water Temple Vanilla +def dung_rules_wt0(world): + set_rule( + world.get_entrance('Water Temple Central Pillar'), + lambda state: (state.has_bow() or state.can_use('Dins Fire') or state.has('Small Key (Water Temple)', 5)) and + state.can_play('Zeldas Lullaby') and state.has('Iron Boots')) + set_rule( + world.get_entrance('Water Temple Upper Locked Door'), + lambda state: state.has('Small Key (Water Temple)', 5) and + state.has('Iron Boots') and + (state.can_play('Zeldas Lullaby') or world.keysanity)) + set_rule(world.get_location('Water Temple Map Chest'), lambda state: state.has('Iron Boots')) + set_rule(world.get_location('Water Temple Compass Chest'), lambda state: state.has('Iron Boots')) + set_rule( + world.get_location('Water Temple Torches Chest'), + lambda state: (state.has_bow() or state.can_use('Dins Fire')) and + state.can_play('Zeldas Lullaby') and + state.has('Iron Boots')) + set_rule( + world.get_location('Water Temple Dragon Chest'), + lambda state: state.has('Iron Boots') and + ((state.has('Progressive Strength Upgrade') and state.can_play('Zeldas Lullaby')) or + (state.has('Small Key (Water Temple)', 6) and + (state.can_play('Zeldas Lullaby') or world.keysanity) and + state.can_play('Song of Time') and + state.has_bow()))) + set_rule( + world.get_location('Water Temple Central Bow Target Chest'), + lambda state: state.has_bow() and + state.has('Iron Boots') and + state.has('Progressive Strength Upgrade') and + state.can_play('Zeldas Lullaby') and + (state.has('Hover Boots') or state.can_use('Longshot'))) + set_rule( + world.get_location('Water Temple Boss Key Chest'), + lambda state: (state.has('Small Key (Water Temple)', 6) and + state.has('Iron Boots') and + (state.can_play('Zeldas Lullaby') or world.keysanity) and + ((state.has_explosives() and state.has('Progressive Strength Upgrade')) or state.has('Hover Boots')) and + state.can_use('Longshot')) or + (state.has('Small Key (Water Temple)', 5) and + (item_name(state, 'Water Temple Boss Key Chest') == 'Small Key (Water Temple)' or + not (world.keys_placed or item_name(state, 'Water Temple Boss Key Chest') == 'Boss Key (Water Temple)')))) #If key for key, this lets the logic reduce the small key reqs for every other locked door. + set_rule(world.get_location('Water Temple Cracked Wall Chest'), lambda state: state.has_explosives()) + set_rule( + world.get_location('Water Temple Dark Link Chest'), + lambda state: state.has('Small Key (Water Temple)', 6) and + (state.can_play('Zeldas Lullaby') or world.keysanity)) + set_rule( + world.get_location('Water Temple River Chest'), + lambda state: state.has('Small Key (Water Temple)', 6) and + state.can_play('Song of Time') and + state.has_bow() and + (state.can_play('Zeldas Lullaby') or world.keysanity)) + set_rule(world.get_location('Water Temple Central Pillar Chest'), lambda state: state.has_ZoraTunic()) + + # Boss + set_rule( + world.get_location('Morpha'), + lambda state: state.has('Boss Key (Water Temple)') and state.can_use('Longshot')) + set_rule( + world.get_location('Morpha Heart'), + lambda state: state.has('Boss Key (Water Temple)') and + state.can_use('Longshot') and + state.has('Iron Boots')) + + # GS + set_rule( + world.get_location('GS Water Temple South Basement'), + lambda state: state.has_explosives() and state.can_play('Zeldas Lullaby') and state.has('Iron Boots')) + set_rule( + world.get_location('GS Water Temple Serpent River'), + lambda state: state.can_play('Song of Time') and state.has('Small Key (Water Temple)', 6)) + set_rule(world.get_location('GS Water Temple Falling Platform Room'), lambda state: state.can_use('Longshot')) + set_rule( + world.get_location('GS Water Temple Central Room'), + lambda state: state.can_use('Longshot') or state.can_use('Farores Wind')) + set_rule( + world.get_location('GS Water Temple Near Boss Key Chest'), + lambda state: state.can_use('Longshot') and + state.has('Iron Boots') and + (state.can_play('Zeldas Lullaby') or world.keysanity) and + state.has('Small Key (Water Temple)', 5)) # Longshot just reaches without the need to actually go near + +# Water Temple MQ +def dung_rules_wtmq(world): + set_rule( + world.get_entrance('Water Temple Water Level Switch'), + lambda state: state.can_play('Zeldas Lullaby') and state.has('Iron Boots')) + set_rule( + world.get_entrance('Water Temple Locked Door'), + lambda state: state.has('Small Key (Water Temple)') and state.can_use('Longshot') and state.has('Iron Boots')) + set_rule( + world.get_entrance('Water Temple Basement Gates Switch'), + lambda state: state.can_use('Dins Fire') and (state.has('Hover Boots') or state.has_ocarina())) + set_rule( + world.get_location('Water Temple MQ Map Chest'), + lambda state: state.has_fire_source() and state.has('Iron Boots')) + set_rule( + world.get_location('Water Temple MQ Central Pillar Chest'), + lambda state: state.has_ZoraTunic() and + state.has('Iron Boots') and + (state.can_use('Fire Arrows') or (state.can_use('Dins Fire') and state.can_play('Song of Time')))) + set_rule( + world.get_location('Water Temple MQ Compass Chest'), + lambda state: state.has_bow() or state.can_use('Dins Fire')) + set_rule(world.get_location('Water Temple MQ Boss Key Chest'), lambda state: state.can_use('Dins Fire')) + + # Boss + set_rule( + world.get_location('Morpha'), + lambda state: state.has('Boss Key (Water Temple)') and state.can_use('Longshot')) + set_rule( + world.get_location('Morpha Heart'), + lambda state: state.has('Boss Key (Water Temple)') and state.can_use('Longshot') and state.has('Iron Boots')) + + # GS + set_rule(world.get_location('GS Water Temple MQ Lizalfos Hallway'), lambda state: state.can_use('Dins Fire')) + set_rule(world.get_location('GS Water Temple MQ Before Upper Water Switch'), lambda state: state.can_use('Longshot')) + set_rule(world.get_location('GS Water Temple MQ South Basement'), lambda state: state.can_use('Fire Arrows')) + set_rule( + world.get_location('GS Water Temple MQ North Basement'), + lambda state: state.has('Small Key (Water Temple)', 2) or + ((item_name(state, 'GS Water Temple MQ North Basement') == 'Small Key (Water Temple)' or + not (world.keys_placed or item_name(state, 'GS Water Temple MQ North Basement') == 'Boss Key (Water Temple)')) and + state.has('Small Key (Water Temple)'))) + +# Spirit Temple Vanilla +def dung_rules_spt0(world): + set_rule(world.get_entrance('Spirit Temple Crawl Passage'), lambda state: state.can_play('Requiem of Spirit')) + set_rule(world.get_entrance('Spirit Temple Silver Block'), lambda state: state.can_use('Silver Gauntlets')) + set_rule(world.get_entrance('Child Spirit Temple Climb'), lambda state: state.has('Small Key (Spirit Temple)', 1)) + set_rule(world.get_entrance('Child Spirit Temple Passthrough'), lambda state: state.has_explosives()) + set_rule( + world.get_entrance('Adult Spirit Temple Passthrough'), + lambda state: state.has('Small Key (Spirit Temple)', 1)) + set_rule( + world.get_entrance('Spirit Temple Central Locked Door'), + lambda state: state.has('Small Key (Spirit Temple)', 4) and state.can_use('Silver Gauntlets')) + set_rule( + world.get_entrance('Spirit Temple Final Locked Door'), + lambda state: state.has('Small Key (Spirit Temple)', 5) and + (state.can_use('Longshot') or + state.has_bombchus() or + ((state.has_bombs() or state.has_nuts() or state.can_use('Dins Fire')) and + (state.has_bow() or state.can_use('Hookshot') or state.has('Hammer'))))) + set_rule( + world.get_location('Spirit Temple Child Left Chest'), + lambda state: (state.has('Boomerang') or state.has_slingshot() or (state.has_bombchus() and world.logic_tricks)) and + (state.has_sticks() or + state.has_explosives() or + ((state.has_nuts() or state.has('Boomerang')) and (state.has('Kokiri Sword') or state.has_slingshot())))) + set_rule( + world.get_location('Spirit Temple Child Right Chest'), + lambda state: (state.has('Boomerang') or state.has_slingshot() or (state.has_bombchus() and world.logic_tricks)) and + (state.has_sticks() or + state.has_explosives() or + ((state.has_nuts() or state.has('Boomerang')) and (state.has('Kokiri Sword') or state.has_slingshot()))) and + (state.has_sticks() or state.can_use('Dins Fire'))) + set_rule( + world.get_location('Spirit Temple Compass Chest'), + lambda state: state.has('Progressive Hookshot') and state.can_play('Zeldas Lullaby')) + set_rule( + world.get_location('Spirit Temple Early Adult Right Chest'), + lambda state: state.has_bow() or state.has('Progressive Hookshot') or state.has_bombchus()) #requires a very specific Bombchu use, Hover Boots can be skipped by jumping on top of the rolling rock. + set_rule( + world.get_location('Spirit Temple First Mirror Right Chest'), + lambda state: state.has('Small Key (Spirit Temple)', 3)) + set_rule( + world.get_location('Spirit Temple First Mirror Left Chest'), + lambda state: state.has('Small Key (Spirit Temple)', 3)) + # All of these paths that include a check for bombchus_in_logic need to ensure that you have access to bombchu + # refills as well. That's currently always true thanks to bombchu bowling. But other the sources require bombchus + # already to be bought, which is not how we'd need it to work if bombchu refills were suddenly to become more + # scarce. So for now I opted not to put in the check for bombchu refills. + set_rule( + world.get_location('Spirit Temple Map Chest'), + lambda state: ((state.has_explosives() or state.has('Small Key (Spirit Temple)', 3) or (state.has('Small Key (Spirit Temple)', 2) and world.bombchus_in_logic)) and + state.has('Magic Meter') and + (state.has('Dins Fire') or (state.has('Fire Arrows') and state.has_bow() and state.has_sticks()))) or + (state.has('Small Key (Spirit Temple)', 5) and + state.has_explosives() and + state.can_play('Requiem of Spirit') and + state.has_sticks()) or + (state.has('Small Key (Spirit Temple)', 3) and + state.can_use('Fire Arrows') and + state.can_use('Silver Gauntlets'))) + set_rule( + world.get_location('Spirit Temple Child Climb East Chest'), + lambda state: state.has_projectile('both') or + ((state.has('Small Key (Spirit Temple)', 3) or (state.has('Small Key (Spirit Temple)', 2) and world.bombchus_in_logic)) and + state.can_use('Silver Gauntlets') and + state.has_projectile('adult')) or + (state.has('Small Key (Spirit Temple)', 5) and + state.can_play('Requiem of Spirit') and + state.has_projectile('child'))) + set_rule( + world.get_location('Spirit Temple Child Climb North Chest'), + lambda state: state.has_projectile('both') or + ((state.has('Small Key (Spirit Temple)', 3) or (state.has('Small Key (Spirit Temple)', 2) and world.bombchus_in_logic)) and + state.can_use('Silver Gauntlets') and + state.has_projectile('adult')) or + (state.has('Small Key (Spirit Temple)', 5) and + state.can_play('Requiem of Spirit') and + state.has_projectile('child'))) + set_rule( + world.get_location('Spirit Temple Sun Block Room Chest'), + lambda state: ((state.has_explosives() or state.has('Small Key (Spirit Temple)', 3) or (state.has('Small Key (Spirit Temple)', 2) and world.bombchus_in_logic)) and + state.has('Magic Meter') and + (state.has('Dins Fire') or (state.has('Fire Arrows') and state.has_bow() and state.has_sticks()))) or + (state.has('Small Key (Spirit Temple)', 5) and + state.has_explosives() and + state.can_play('Requiem of Spirit') and + state.has_sticks()) or + (state.has('Small Key (Spirit Temple)', 3) and + state.can_use('Fire Arrows') and + state.can_use('Silver Gauntlets'))) + set_rule( + world.get_location('Spirit Temple Statue Hand Chest'), + lambda state: state.has('Small Key (Spirit Temple)', 3) and + state.can_use('Silver Gauntlets') and + state.can_play('Zeldas Lullaby')) + set_rule( + world.get_location('Spirit Temple NE Main Room Chest'), + lambda state: state.has('Small Key (Spirit Temple)', 3) and + state.can_use('Silver Gauntlets') and + state.can_play('Zeldas Lullaby') and + (state.has('Progressive Hookshot') or state.has('Hover Boots'))) + set_rule( + world.get_location('Mirror Shield Chest'), + lambda state: state.has('Small Key (Spirit Temple)', 4) and + state.can_use('Silver Gauntlets') and + state.has_explosives()) + set_rule( + world.get_location('Silver Gauntlets Chest'), + lambda state: (state.has('Small Key (Spirit Temple)', 3) and + state.has('Progressive Hookshot', 2) and + state.has_explosives()) or + state.has('Small Key (Spirit Temple)', 5)) + set_rule( + world.get_location('Spirit Temple Near Four Armos Chest'), + lambda state: state.has('Mirror Shield') and state.has_explosives()) + set_rule( + world.get_location('Spirit Temple Hallway Left Invisible Chest'), + lambda state: state.can_see_with_lens() and state.has_explosives()) + set_rule( + world.get_location('Spirit Temple Hallway Right Invisible Chest'), + lambda state: state.can_see_with_lens() and state.has_explosives()) + set_rule( + world.get_location('Spirit Temple Boss Key Chest'), + lambda state: state.can_play('Zeldas Lullaby') and + state.has_bow() and + state.has('Progressive Hookshot') and + state.can_blast_or_smash()) + set_rule(world.get_location('Spirit Temple Topmost Chest'), lambda state: state.has('Mirror Shield')) + + # Boss + set_rule( + world.get_location('Twinrova'), + lambda state: state.has('Mirror Shield') and + state.has_explosives() and + state.has('Progressive Hookshot') and + state.has('Boss Key (Spirit Temple)')) + set_rule( + world.get_location('Twinrova Heart'), + lambda state: state.has('Mirror Shield') and + state.has_explosives() and + state.has('Progressive Hookshot') and + state.has('Boss Key (Spirit Temple)')) + + # GS + set_rule( + world.get_location('GS Spirit Temple Metal Fence'), + lambda state: (state.has('Boomerang') or state.has_slingshot() or (state.has_bombchus() and world.logic_tricks)) and + (state.has_sticks() or + state.has_explosives() or + ((state.has_nuts() or state.has('Boomerang')) and (state.has('Kokiri Sword') or state.has_slingshot())))) + set_rule( + world.get_location('GS Spirit Temple Hall to West Iron Knuckle'), + lambda state: (state.has_explosives() and state.has('Boomerang') and state.has('Progressive Hookshot')) or + (state.has('Boomerang') and + state.has('Small Key (Spirit Temple)', 5) and + state.has_explosives() and + state.can_play('Requiem of Spirit')) or + (state.has('Progressive Hookshot') and + state.can_use('Silver Gauntlets') and + (state.has('Small Key (Spirit Temple)', 3) or + (state.has('Small Key (Spirit Temple)', 2) and state.has('Boomerang') and world.bombchus_in_logic)))) + set_rule( + world.get_location('GS Spirit Temple Boulder Room'), + lambda state: state.can_play('Song of Time') and + (state.has_bow() or state.has('Progressive Hookshot') or state.has_bombchus())) + set_rule( + world.get_location('GS Spirit Temple Lobby'), + lambda state: state.can_use('Silver Gauntlets') and + state.has('Small Key (Spirit Temple)', 3) and + (state.can_use('Longshot') or state.can_use('Scarecrow') or state.has('Hover Boots'))) + set_rule( + world.get_location('GS Spirit Temple Bomb for Light Room'), + lambda state: state.has_projectile('both') or + state.can_use('Dins Fire') or + ((world.difficulty != 'ohko' or state.has_bottle() or state.can_use('Nayrus Love')) and + (state.has_sticks() or state.has('Kokiri Sword') or state.has_projectile('child'))) or + (state.can_play('Requiem of Spirit') and state.has('Small Key (Spirit Temple)', 5) and + state.has_projectile('child')) or + ((state.has('Small Key (Spirit Temple)', 3) or (state.has('Small Key (Spirit Temple)', 2) and world.bombchus_in_logic)) and + state.can_use('Silver Gauntlets') and + (state.has_projectile('adult') or + world.difficulty != 'ohko' or state.has_bottle() or state.can_use('Nayrus Love')))) + +# Spirit Temple MQ +def dung_rules_sptmq(world): + set_rule(world.get_entrance('Spirit Temple Crawl Passage'), lambda state: state.can_play('Requiem of Spirit')) + set_rule( + world.get_entrance('Spirit Temple Ceiling Passage'), + lambda state: state.has_bombchus() and state.can_use('Longshot') and state.can_use('Silver Gauntlets')) + set_rule( + world.get_entrance('Child Spirit Temple to Shared'), + lambda state: state.has_bombchus() and state.has('Small Key (Spirit Temple)', 2)) + set_rule( + world.get_entrance('Adult Spirit Temple Descent'), + lambda state: state.can_use('Fire Arrows') and state.has('Mirror Shield')) + set_rule( + world.get_entrance('Spirit Temple Climbable Wall'), + lambda state: state.has('Small Key (Spirit Temple)', 6) and state.can_play('Zeldas Lullaby') and state.has('Hammer')) + set_rule( + world.get_location('Spirit Temple MQ Entrance Back Left Chest'), + lambda state: state.can_blast_or_smash() and + ((state.can_play('Requiem of Spirit') and state.has_slingshot()) or state.can_use('Bow'))) + set_rule( + world.get_location('Spirit Temple MQ Entrance Back Right Chest'), + lambda state: state.has_bombchus() or + state.can_use('Bow') or + state.can_use('Hookshot') or + (state.can_play('Requiem of Spirit') and (state.has_slingshot() or state.has('Boomerang')))) + set_rule( + world.get_location('Spirit Temple MQ Map Chest'), + lambda state: state.has_sticks() or state.has('Kokiri Sword') or state.has_explosives()) + set_rule( + world.get_location('Spirit Temple MQ Child Left Chest'), + lambda state: (state.has_sticks() or state.has('Kokiri Sword')) and + state.has_bombchus() and + state.has_slingshot() and + state.can_use('Dins Fire')) + set_rule( + world.get_location('Spirit Temple MQ Silver Block Hallway Chest'), + lambda state: state.has_bombchus() and + state.has('Small Key (Spirit Temple)', 7) and + state.has_slingshot() and + (state.can_use('Dins Fire') or + (state.can_use('Longshot') and + state.can_use('Silver Gauntlets') and + (state.can_use('Fire Arrows') or (world.logic_tricks and state.has_bow() and state.can_play('Song of Time')))))) + set_rule( + world.get_location('Spirit Temple MQ Child Center Chest'), + lambda state: state.has('Small Key (Spirit Temple)', 7) and + state.has('Hammer') and + state.can_play('Requiem of Spirit')) + set_rule( + world.get_location('Spirit Temple MQ Child Climb South Chest'), + lambda state: state.has('Small Key (Spirit Temple)', 7)) + set_rule( + world.get_location('Spirit Temple MQ Lower NE Main Room Chest'), + lambda state: state.can_play('Zelda Lullaby')) + set_rule(world.get_location('Spirit Temple MQ Upper NE Main Room Chest'), lambda state: state.can_see_with_lens()) + set_rule( + world.get_location('Spirit Temple MQ Beamos Room Chest'), + lambda state: state.has('Small Key (Spirit Temple)', 5)) + set_rule( + world.get_location('Spirit Temple MQ Ice Trap Chest'), + lambda state: state.has('Small Key (Spirit Temple)', 5) and state.can_play('Song of Time')) + set_rule( + world.get_entrance('Mirror Shield Exit'), + lambda state: state.has('Small Key (Spirit Temple)', 5) and + state.can_play('Song of Time') and + state.can_see_with_lens()) + set_rule( + world.get_location('Spirit Temple MQ Boss Key Chest'), + lambda state: state.has('Small Key (Spirit Temple)', 5) and + state.can_play('Song of Time') and + state.has('Mirror Shield')) + set_rule(world.get_location('Spirit Temple MQ Entrance Front Right Chest'), lambda state: state.has('Hammer')) + set_rule( + world.get_location('Spirit Temple MQ Lower Adult Right Chest'), + lambda state: state.has('Small Key (Spirit Temple)', 7) and + state.has('Hammer') and + state.has_ocarina() and + state.has('Song of Time') and + state.has('Eponas Song') and + state.has('Suns Song') and + state.has('Song of Storms') and + state.has('Zeldas Lullaby')) + set_rule( + world.get_location('Spirit Temple MQ Child Climb North Chest'), + lambda state: state.has('Small Key (Spirit Temple)', 6)) + set_rule( + world.get_location('Spirit Temple MQ Compass Chest'), + lambda state: (state.can_play('Requiem of Spirit') and state.has('Small Key (Spirit Temple)', 7) and state.has_slingshot()) or + (state.can_use('Longshot') and state.can_use('Silver Gauntlets') and state.has_bow()) or + (state.has_slingshot() and state.has_bow())) + set_rule( + world.get_location('Spirit Temple MQ Sun Block Room Chest'), + lambda state: state.can_play('Song of Time') or + (state.can_use('Longshot') and state.can_use('Silver Gauntlets'))) + set_rule( + world.get_entrance('Silver Gauntlets Exit'), + lambda state: (state.has('Small Key (Spirit Temple)', 7) and + (state.can_play('Song of Time') or (state.can_use('Longshot') and state.can_use('Silver Gauntlets')))) or + (state.has('Small Key (Spirit Temple)', 4) and state.can_play('Song of Time') and state.can_see_with_lens())) + set_rule( + world.get_location('Spirit Temple MQ Mirror Puzzle Invisible Chest'), + lambda state: state.can_see_with_lens()) + + # Boss + set_rule( + world.get_location('Twinrova'), + lambda state: state.has('Mirror Shield') and state.has('Boss Key (Spirit Temple)')) + set_rule( + world.get_location('Twinrova Heart'), + lambda state: state.has('Mirror Shield') and state.has('Boss Key (Spirit Temple)')) + + # GS + set_rule( + world.get_location('GS Spirit Temple MQ Lower Adult Right'), + lambda state: state.has('Small Key (Spirit Temple)', 7) and + state.has('Hammer') and + state.has_ocarina() and + state.has('Song of Time') and + state.has('Eponas Song') and + state.has('Suns Song') and + state.has('Song of Storms') and + state.has('Zeldas Lullaby')) + set_rule( + world.get_location('GS Spirit Temple MQ Iron Knuckle West'), + lambda state: state.has('Small Key (Spirit Temple)', 7)) + set_rule( + world.get_location('GS Spirit Temple MQ Iron Knuckle North'), + lambda state: state.has('Small Key (Spirit Temple)', 7)) + +# Shadow Temple Vanilla +def dung_rules_sht0(world): + set_rule(world.get_entrance('Shadow Temple First Pit'), lambda state: state.has('Hover Boots')) + set_rule( + world.get_entrance('Shadow Temple Bomb Wall'), + lambda state: state.has_explosives() and state.has('Small Key (Shadow Temple)', 1)) + set_rule( + world.get_entrance('Shadow Temple Hookshot Target'), + lambda state: state.has('Progressive Hookshot') and state.has('Small Key (Shadow Temple)', 3)) + set_rule( + world.get_entrance('Shadow Temple Boat'), + lambda state: state.can_play('Zeldas Lullaby') and state.has('Small Key (Shadow Temple)', 4)) + set_rule( + world.get_location('Shadow Temple Falling Spikes Upper Chest'), + lambda state: state.has('Progressive Strength Upgrade')) + set_rule( + world.get_location('Shadow Temple Falling Spikes Switch Chest'), + lambda state: state.has('Progressive Strength Upgrade')) + set_rule( + world.get_location('Shadow Temple Invisible Spikes Chest'), + lambda state: state.has('Small Key (Shadow Temple)', 2)) + set_rule( + world.get_location('Shadow Temple Freestanding Key'), + lambda state: state.has('Small Key (Shadow Temple)', 2) and + state.has('Progressive Hookshot') and + (state.has_bombs() or state.has('Progressive Strength Upgrade'))) + + # Boss + set_rule( + world.get_location('Bongo Bongo'), + lambda state: state.has('Small Key (Shadow Temple)', 5) and + (state.has('Bow') or state.can_use('Distant Scarecrow')) and + state.has('Boss Key (Shadow Temple)')) + set_rule( + world.get_location('Bongo Bongo Heart'), + lambda state: state.has('Small Key (Shadow Temple)', 5) and + (state.has('Bow') or state.can_use('Distant Scarecrow')) and + state.has('Boss Key (Shadow Temple)')) + + # GS + set_rule(world.get_location('GS Shadow Temple Like Like Room'), lambda state: state.has('Progressive Hookshot')) + set_rule(world.get_location('GS Shadow Temple Crusher Room'), lambda state: state.has('Progressive Hookshot')) + set_rule( + world.get_location('GS Shadow Temple Single Giant Pot'), + lambda state: state.has('Small Key (Shadow Temple)', 2) and state.has('Progressive Hookshot')) + set_rule( + world.get_location('GS Shadow Temple Near Ship'), + lambda state: state.can_use('Longshot') and state.has('Small Key (Shadow Temple)', 4)) + +# Shadow Temple MQ +def dung_rules_shtmq(world): + set_rule( + world.get_entrance('Shadow Temple First Pit'), + lambda state: state.can_use('Fire Arrows') or state.has('Hover Boots')) + set_rule( + world.get_entrance('Shadow Temple Beginning Locked Door'), + lambda state: state.has_explosives() and state.has('Small Key (Shadow Temple)', 6)) + set_rule( + world.get_entrance('Shadow Temple Bomb Wall'), + lambda state: state.has_explosives() and state.has('Small Key (Shadow Temple)', 2)) + set_rule( + world.get_entrance('Shadow Temple Hookshot Target'), + lambda state: state.has('Hover Boots') and + state.has('Progressive Hookshot') and + state.has('Small Key (Shadow Temple)', 4)) + set_rule( + world.get_entrance('Shadow Temple Boat'), + lambda state: state.can_play('Zeldas Lullaby') and state.has('Small Key (Shadow Temple)', 5)) + set_rule( + world.get_entrance('Shadow Temple Longshot Target'), + lambda state: state.has_bow() and state.can_play('Song of Time') and state.can_use('Longshot')) + set_rule( + world.get_location('Shadow Temple MQ Hover Boots Chest'), + lambda state: state.can_play('Song of Time') and state.has_bow()) + set_rule( + world.get_location('Shadow Temple MQ Invisible Blades Visible Chest'), + lambda state: state.can_play('Song of Time')) + set_rule( + world.get_location('Shadow Temple MQ Invisible Blades Invisible Chest'), + lambda state: state.can_play('Song of Time')) + set_rule( + world.get_location('Shadow Temple MQ Beamos Silver Rupees Chest'), + lambda state: state.can_use('Longshot')) + set_rule( + world.get_location('Shadow Temple MQ Falling Spikes Upper Chest'), + lambda state: state.has('Progressive Strength Upgrade')) + set_rule( + world.get_location('Shadow Temple MQ Falling Spikes Switch Chest'), + lambda state: state.has('Progressive Strength Upgrade')) + set_rule( + world.get_location('Shadow Temple MQ Invisible Spikes Chest'), + lambda state: state.has('Hover Boots') and state.has('Small Key (Shadow Temple)', 3)) + set_rule( + world.get_location('Shadow Temple MQ Stalfos Room Chest'), + lambda state: state.has('Hover Boots') and + state.has('Small Key (Shadow Temple)', 3) and + state.can_use('Longshot')) + set_rule( + world.get_location('Shadow Temple MQ Spike Walls Left Chest'), + lambda state: state.has('Small Key (Shadow Temple)', 6)) + set_rule( + world.get_location('Shadow Temple MQ Boss Key Chest'), + lambda state: state.has('Small Key (Shadow Temple)', 6)) + + # Boss + set_rule( + world.get_location('Bongo Bongo'), + lambda state: state.has_bow() and state.has('Boss Key (Shadow Temple)')) + set_rule( + world.get_location('Bongo Bongo Heart'), + lambda state: state.has_bow() and state.has('Boss Key (Shadow Temple)')) + + # GS + set_rule(world.get_location('GS Shadow Temple MQ Crusher Room'), lambda state: state.has('Progressive Hookshot')) + set_rule(world.get_location('GS Shadow Temple MQ Near Boss'), lambda state: state.has_bow()) + + +# Bottom of the Well Vanilla +def dung_rules_bw0(world): + set_rule(world.get_location('Bottom of the Well Front Left Hidden Wall'), lambda state: state.can_see_with_lens()) + set_rule(world.get_location('Bottom of the Well Front Center Bombable'), lambda state: state.has_explosives()) + set_rule(world.get_location('Bottom of the Well Right Bottom Hidden Wall'), lambda state: state.can_see_with_lens()) + set_rule(world.get_location('Bottom of the Well Center Large Chest'), lambda state: state.can_see_with_lens()) + set_rule(world.get_location('Bottom of the Well Center Small Chest'), lambda state: state.can_see_with_lens()) + set_rule(world.get_location('Bottom of the Well Back Left Bombable'), lambda state: state.has_explosives()) + set_rule( + world.get_location('Bottom of the Well Defeat Boss'), + lambda state: state.can_play('Zeldas Lullaby') and + (state.has('Kokiri Sword') or (state.has_sticks() and world.logic_child_deadhand))) #Sword not strictly necessary but frankly being forced to do this with sticks isn't fair + set_rule( + world.get_location('Bottom of the Well Invisible Chest'), + lambda state: state.can_play('Zeldas Lullaby') and state.can_see_with_lens()) + set_rule( + world.get_location('Bottom of the Well Underwater Front Chest'), + lambda state: state.can_play('Zeldas Lullaby')) + set_rule( + world.get_location('Bottom of the Well Underwater Left Chest'), + lambda state: state.can_play('Zeldas Lullaby')) + set_rule( + world.get_location('Bottom of the Well Basement Chest'), + lambda state: state.has_explosives() or + (((state.has('Small Key (Bottom of the Well)', 3) and state.can_see_with_lens()) or + state.can_use('Dins Fire') or + (world.logic_tricks and state.has_sticks())) and + state.has('Progressive Strength Upgrade'))) + set_rule( + world.get_location('Bottom of the Well Locked Pits'), + lambda state: state.has('Small Key (Bottom of the Well)', 3) and state.can_see_with_lens()) #These pits are really unfair. + set_rule( + world.get_location('Bottom of the Well Behind Right Grate'), + lambda state: state.has('Small Key (Bottom of the Well)', 3) and state.can_see_with_lens()) + set_rule( + world.get_location('Bottom of the Well Freestanding Key'), + lambda state: state.has_sticks() or state.can_use('Dins Fire')) + + # GS + set_always_allow( + world.get_location('GS Well West Inner Room'), + lambda item, state: item.name == 'Small Key (Bottom of the Well)') + set_rule( + world.get_location('GS Well West Inner Room'), + lambda state: state.has('Boomerang') and + state.can_see_with_lens() and + (state.has('Small Key (Bottom of the Well)', 3) or + item_name(state, 'GS Well West Inner Room') == 'Small Key (Bottom of the Well)')) + set_always_allow( + world.get_location('GS Well East Inner Room'), + lambda item, state: item.name == 'Small Key (Bottom of the Well)') + set_rule( + world.get_location('GS Well East Inner Room'), + lambda state: state.has('Boomerang') and + state.can_see_with_lens() and + (state.has('Small Key (Bottom of the Well)', 3) or + item_name(state, 'GS Well East Inner Room') == 'Small Key (Bottom of the Well)')) + set_rule( + world.get_location('GS Well Like Like Cage'), + lambda state: state.has('Small Key (Bottom of the Well)', 3) and + state.has('Boomerang') and + state.can_see_with_lens()) + +# Bottom of the Well MQ +def dung_rules_bwmq(world): + set_rule( + world.get_location('Bottom of the Well MQ Compass Chest'), + lambda state: state.has('Kokiri Sword') or (state.has_sticks() and world.logic_child_deadhand)) + set_rule( + world.get_location('Bottom of the Well MQ Dead Hand Freestanding Key'), + lambda state: state.has_explosives()) + set_rule( + world.get_location('Bottom of the Well MQ Map Chest'), + lambda state: state.can_play('Zeldas Lullaby') or state.has_explosives()) + set_rule( + world.get_location('Bottom of the Well MQ East Inner Room Freestanding Key'), + lambda state: state.can_play('Zeldas Lullaby') or state.has_explosives()) + set_always_allow( + world.get_location('Bottom of the Well MQ Lens Chest'), + lambda item, state: item.name == 'Small Key (Bottom of the Well)') + set_rule( + world.get_location('Bottom of the Well MQ Lens Chest'), + lambda state: state.has_explosives() and + (state.has('Small Key (Bottom of the Well)', 2) or + item_name(state, 'Bottom of the Well MQ Lens Chest') == 'Small Key (Bottom of the Well)')) + + # GS + set_rule(world.get_location('GS Well MQ Basement'), lambda state: state.can_child_attack()) + set_rule( + world.get_location('GS Well MQ West Inner Room'), + lambda state: state.can_child_attack() and + (state.can_play('Zeldas Lullaby') or state.has_explosives()) and state.can_see_with_lens()) + set_always_allow( + world.get_location('GS Well MQ Coffin Room'), + lambda item, state: item.name == 'Small Key (Bottom of the Well)') + set_rule( + world.get_location('GS Well MQ Coffin Room'), + lambda state: state.can_child_attack() and + (state.has('Small Key (Bottom of the Well)', 2) or + item_name(state, 'GS Well MQ Coffin Room') == 'Small Key (Bottom of the Well)')) + +# Ice Cavern Vanilla +def dung_rules_ic0(world): + set_rule(world.get_location('Ice Cavern Map Chest'), lambda state: state.has_bottle()) + set_rule(world.get_location('Ice Cavern Compass Chest'), lambda state: state.has_bottle()) + set_rule(world.get_location('Ice Cavern Freestanding PoH'), lambda state: state.has_bottle()) + set_rule(world.get_location('Ice Cavern Iron Boots Chest'), lambda state: state.has_bottle()) + set_rule(world.get_location('Sheik in Ice Cavern'), lambda state: state.has_bottle() and state.is_adult()) + + # GS + set_rule(world.get_location('GS Ice Cavern Spinning Scythe Room'), lambda state: state.can_use('Hookshot')) + set_rule( + world.get_location('GS Ice Cavern Heart Piece Room'), + lambda state: state.can_use('Hookshot') and state.has_bottle()) + set_rule( + world.get_location('GS Ice Cavern Push Block Room'), + lambda state: state.can_use('Hookshot') and state.has_bottle()) + +# Ice Cavern MQ +def dung_rules_icmq(world): + set_rule(world.get_entrance('Ice Cavern Entrance'), lambda state: state.has_bottle()) + set_rule(world.get_location('Ice Cavern MQ Freestanding PoH'), lambda state: state.has_explosives()) + + # GS + set_rule(world.get_location('GS Ice Cavern MQ Red Ice'), lambda state: state.can_play('Song of Time')) + set_rule( + world.get_location('GS Ice Cavern MQ Scarecrow'), + lambda state: state.can_use('Scarecrow') or (state.has('Hover Boots') and state.can_use('Longshot'))) + +# Gerudo Training Grounds Vanilla +def dung_rules_gtg0(world): + set_rule(world.get_entrance('Gerudo Training Ground Left Silver Rupees'), lambda state: state.can_use('Hookshot')) + set_rule(world.get_entrance('Gerudo Training Ground Beamos'), lambda state: state.has_explosives()) + set_rule( + world.get_entrance('Gerudo Training Grounds Right Locked Doors'), + lambda state: state.has('Small Key (Gerudo Training Grounds)', 9)) + set_rule(world.get_entrance('Gerudo Training Grounds Maze Ledge'), lambda state: state.can_play('Song of Time')) + set_rule(world.get_entrance('Gerudo Training Grounds Right Hookshot Target'), lambda state: state.can_use('Hookshot')) + set_rule( + world.get_entrance('Gerudo Training Grounds Hammer Target'), + lambda state: state.can_use('Hammer') and state.has_bow()) + set_rule( + world.get_entrance('Gerudo Training Grounds Hidden Hookshot Target'), + lambda state: state.can_use('Hookshot') and state.can_see_with_lens()) + set_rule(world.get_location('Gerudo Training Grounds Lobby Left Chest'), lambda state: state.can_use('Bow')) + set_rule(world.get_location('Gerudo Training Grounds Lobby Right Chest'), lambda state: state.can_use('Bow')) + set_rule(world.get_location('Gerudo Training Grounds Beamos Chest'), lambda state: state.has_explosives()) + set_rule( + world.get_location('Gerudo Training Grounds Hidden Ceiling Chest'), + lambda state: state.has('Small Key (Gerudo Training Grounds)', 3) and state.can_see_with_lens()) + set_rule( + world.get_location('Gerudo Training Grounds Maze Path First Chest'), + lambda state: state.has('Small Key (Gerudo Training Grounds)', 4)) + set_rule( + world.get_location('Gerudo Training Grounds Maze Path Second Chest'), + lambda state: state.has('Small Key (Gerudo Training Grounds)', 6)) + set_rule( + world.get_location('Gerudo Training Grounds Maze Path Third Chest'), + lambda state: state.has('Small Key (Gerudo Training Grounds)', 7)) + set_rule( + world.get_location('Gerudo Training Grounds Maze Path Final Chest'), + lambda state: (state.has('Small Key (Gerudo Training Grounds)', 9)) or + (item_name(state, 'Gerudo Training Grounds Maze Path Final Chest') == 'Small Key (Gerudo Training Grounds)' and + state.has('Small Key (Gerudo Training Grounds)', 8))) #Allow key for key + set_always_allow( + world.get_location('Gerudo Training Grounds Maze Path Final Chest'), + lambda item, state: item.name == 'Small Key (Gerudo Training Grounds)') + set_rule( + world.get_location('Gerudo Training Grounds Underwater Silver Rupee Chest'), + lambda state: state.can_use('Hookshot') and + state.can_play('Song of Time') and + state.has('Iron Boots') and + (world.logic_fewer_tunic_requirements or state.has_ZoraTunic())) + set_rule(world.get_location('Gerudo Training Grounds Hammer Room Switch Chest'), lambda state: state.can_use('Hammer')) + set_rule(world.get_location('Gerudo Training Grounds Eye Statue Chest'), lambda state: state.can_use('Bow')) + set_rule(world.get_location('Gerudo Training Grounds Near Scarecrow Chest'), lambda state: state.can_use('Bow')) + set_rule( + world.get_location('Gerudo Training Grounds Heavy Block First Chest'), + lambda state: state.can_use('Silver Gauntlets') and state.can_see_with_lens()) + set_rule( + world.get_location('Gerudo Training Grounds Heavy Block Second Chest'), + lambda state: state.can_use('Silver Gauntlets') and state.can_see_with_lens()) + set_rule( + world.get_location('Gerudo Training Grounds Heavy Block Third Chest'), + lambda state: state.can_use('Silver Gauntlets') and state.can_see_with_lens()) + set_rule( + world.get_location('Gerudo Training Grounds Heavy Block Fourth Chest'), + lambda state: state.can_use('Silver Gauntlets') and state.can_see_with_lens()) + +# Gerudo Training Grounds MQ +def dung_rules_gtgmq(world): + set_rule(world.get_entrance('Gerudo Training Grounds Left Door'), lambda state: state.has_fire_source()) + set_rule(world.get_entrance('Gerudo Training Grounds Right Door'), lambda state: state.has_bow()) + set_rule( + world.get_entrance('Gerudo Training Grounds Longshot Target'), + lambda state: state.can_use('Longshot') or + (world.logic_tricks and state.can_use('Hookshot'))) + set_rule( + world.get_entrance('Gerudo Training Grounds Song of Time Block'), + lambda state: state.can_play('Song of Time') and state.can_see_with_lens() and state.has_bottle()) + set_rule(world.get_entrance('Gerudo Training Grounds Rusted Switch'), lambda state: state.has('Hammer')) + set_rule(world.get_location('Gerudo Training Grounds MQ Hidden Ceiling Chest'), lambda state: state.can_see_with_lens()) + set_rule( + world.get_location('Gerudo Training Grounds MQ Maze Path Third Chest'), + lambda state: state.has('Small Key (Gerudo Training Grounds)', 1)) + set_rule( + world.get_location('Gerudo Training Grounds MQ Underwater Silver Rupee Chest'), + lambda state: (state.has('Hover Boots') or (state.can_reach('Gerudo Training Grounds Central Maze Right') and (state.can_use('Longshot') or state.has_bow()))) and + state.has_fire_source() and + state.has('Iron Boots') and + (world.logic_fewer_tunic_requirements or state.has_ZoraTunic()) and + (world.difficulty != 'ohko' or (state.has_bottle() or state.can_use('Nayrus Love')))) + set_rule( + world.get_location('Gerudo Training Grounds MQ Heavy Block Chest'), + lambda state: state.can_use('Silver Gauntlets')) + set_rule(world.get_location('Gerudo Training Grounds MQ Eye Statue Chest'), lambda state: state.has_bow()) + set_rule( + world.get_location('Gerudo Training Grounds MQ Ice Arrows Chest'), + lambda state: state.has('Small Key (Gerudo Training Grounds)', 3) or + (item_name(state, 'Gerudo Training Grounds MQ Ice Arrows Chest') == 'Small Key (Gerudo Training Grounds)' and + state.has('Small Key (Gerudo Training Grounds)'))) + set_always_allow( + world.get_location('Gerudo Training Grounds MQ Ice Arrows Chest'), + lambda item, state: item.name == 'Small Key (Gerudo Training Grounds)') + +# Ganon's Castle Vanilla +def dung_rules_gc0(world): + set_rule(world.get_entrance('Ganons Castle Light Trial'), lambda state: state.can_use('Golden Gauntlets')) + set_rule( + world.get_entrance('Ganons Castle Tower'), + lambda state: (world.skipped_trials['Forest'] or state.has('Forest Trial Clear')) and + (world.skipped_trials['Fire'] or state.has('Fire Trial Clear')) and + (world.skipped_trials['Water'] or state.has('Water Trial Clear')) and + (world.skipped_trials['Shadow'] or state.has('Shadow Trial Clear')) and + (world.skipped_trials['Spirit'] or state.has('Spirit Trial Clear')) and + (world.skipped_trials['Light'] or state.has('Light Trial Clear'))) + set_rule( + world.get_location('Ganons Castle Forest Trial Clear'), + lambda state: state.can_use('Light Arrows') and (state.has('Fire Arrows') or state.has('Dins Fire'))) + set_rule( + world.get_location('Ganons Castle Fire Trial Clear'), + lambda state: state.has_GoronTunic() and + state.can_use('Golden Gauntlets') and + state.can_use('Light Arrows') and + state.can_use('Longshot')) + set_rule( + world.get_location('Ganons Castle Water Trial Clear'), + lambda state: state.has_bottle() and state.has('Hammer') and state.can_use('Light Arrows')) + set_rule( + world.get_location('Ganons Castle Shadow Trial Clear'), + lambda state: state.can_use('Light Arrows') and + state.has('Hammer') and + ((state.has('Fire Arrows') and state.can_see_with_lens()) or + (state.can_use('Longshot') and (state.has('Hover Boots') or (state.has('Dins Fire') and state.can_see_with_lens()))))) + set_rule( + world.get_location('Ganons Castle Shadow Trial First Chest'), + lambda state: state.can_use('Fire Arrows') or + state.has('Progressive Hookshot') or + state.has('Hover Boots') or + state.can_play('Song of Time')) + set_rule( + world.get_location('Ganons Castle Shadow Trial Second Chest'), + lambda state: state.can_use('Fire Arrows') or + (state.can_use('Longshot') and (state.has('Hover Boots') or state.can_use('Dins Fire')))) + set_rule( + world.get_location('Ganons Castle Spirit Trial Clear'), + lambda state: state.can_use('Light Arrows') and + state.has('Mirror Shield') and + state.has_bombchus() and + state.has('Progressive Hookshot')) + set_rule( + world.get_location('Ganons Castle Spirit Trial First Chest'), + lambda state: state.has('Progressive Hookshot')) + set_rule( + world.get_location('Ganons Castle Spirit Trial Second Chest'), + lambda state: state.has('Progressive Hookshot') and state.has_bombchus() and state.can_see_with_lens()) + set_rule( + world.get_location('Ganons Castle Light Trial Clear'), + lambda state: state.can_use('Light Arrows') and + state.has('Progressive Hookshot') and + state.has('Small Key (Ganons Castle)', 2)) + set_rule( + world.get_location('Ganons Castle Light Trail Invisible Enemies Chest'), + lambda state: state.can_see_with_lens()) + set_rule( + world.get_location('Ganons Castle Light Trial Lullaby Chest'), + lambda state: state.can_play('Zeldas Lullaby') and state.has('Small Key (Ganons Castle)', 1)) + set_rule(world.get_entrance('Ganons Castle Deku Scrubs'), lambda state: state.can_see_with_lens()) + +# Ganon's Castle MQ +def dung_rules_gcmq(world): + set_rule(world.get_entrance('Ganons Castle Light Trial'), lambda state: state.can_use('Golden Gauntlets')) + set_rule( + world.get_entrance('Ganons Castle Tower'), + lambda state: (world.skipped_trials['Forest'] or state.has('Forest Trial Clear')) and + (world.skipped_trials['Fire'] or state.has('Fire Trial Clear')) and + (world.skipped_trials['Water'] or state.has('Water Trial Clear')) and + (world.skipped_trials['Shadow'] or state.has('Shadow Trial Clear')) and + (world.skipped_trials['Spirit'] or state.has('Spirit Trial Clear')) and + (world.skipped_trials['Light'] or state.has('Light Trial Clear'))) + set_rule(world.get_location('Ganons Castle MQ Forest Trial First Chest'), lambda state: state.has_bow()) + set_rule(world.get_location('Ganons Castle MQ Forest Trial Second Chest'), lambda state: state.has_fire_source()) + set_rule( + world.get_location('Ganons Castle MQ Forest Trial Freestanding Key'), + lambda state: state.has('Progressive Hookshot')) + set_rule( + world.get_location('Ganons Castle Forest Trial Clear'), + lambda state: state.can_use('Light Arrows') and state.can_play('Song of Time')) + set_rule( + world.get_location('Ganons Castle Fire Trial Clear'), + lambda state: state.has_GoronTunic() and + state.can_use('Golden Gauntlets') and + state.can_use('Light Arrows') and + (state.can_use('Longshot') or state.has('Hover Boots'))) + set_rule(world.get_location('Ganons Castle MQ Water Trial Chest'), lambda state: state.has_bottle()) + set_rule( + world.get_location('Ganons Castle Water Trial Clear'), + lambda state: state.has_bottle() and state.can_use('Light Arrows') and state.has('Small Key (Ganons Castle)', 3)) + set_rule( + world.get_location('Ganons Castle MQ Shadow Trial First Chest'), + lambda state: (state.has_bow() and (state.has('Progressive Hookshot') or state.has('Hover Boots'))) or + (state.has('Hover Boots') and + state.can_see_with_lens() and + (state.has_explosives() or state.has('Progressive Strength Upgrade') or state.can_use('Dins Fire')))) + set_rule( + world.get_location('Ganons Castle MQ Shadow Trial Second Chest'), + lambda state: state.has_bow() and + state.can_see_with_lens() and + (state.has('Hover Boots') or (state.has('Progressive Hookshot') and state.has_fire_source()))) + set_rule( + world.get_location('Ganons Castle Shadow Trial Clear'), + lambda state: state.can_use('Light Arrows') and + state.can_see_with_lens() and + (state.has('Hover Boots') or (state.has('Progressive Hookshot') and state.has_fire_source()))) + set_rule( + world.get_location('Ganons Castle MQ Spirit Trial First Chest'), + lambda state: (state.has_bow() or world.logic_tricks) and state.has('Hammer')) + set_rule( + world.get_location('Ganons Castle MQ Spirit Trial Second Chest'), + lambda state: (state.has_bow() or world.logic_tricks) and + state.has('Hammer') and + state.has_bombchus() and + state.can_see_with_lens()) + set_rule( + world.get_location('Ganons Castle MQ Spirit Trial Sun Front Left Chest'), + lambda state: state.has('Hammer') and + state.has_bombchus() and + state.can_use('Fire Arrows') and + state.has('Mirror Shield')) + set_rule( + world.get_location('Ganons Castle MQ Spirit Trial Sun Back Left Chest'), + lambda state: state.has('Hammer') and + state.has_bombchus() and + state.can_use('Fire Arrows') and + state.has('Mirror Shield')) + set_rule( + world.get_location('Ganons Castle MQ Spirit Trial Golden Gauntlets Chest'), + lambda state: state.has('Hammer') and + state.has_bombchus() and + state.can_use('Fire Arrows') and + state.has('Mirror Shield')) + set_rule( + world.get_location('Ganons Castle MQ Spirit Trial Sun Back Right Chest'), + lambda state: state.has('Hammer') and + state.has_bombchus() and + state.can_use('Fire Arrows') and + state.has('Mirror Shield')) + set_rule( + world.get_location('Ganons Castle Spirit Trial Clear'), + lambda state: state.can_use('Light Arrows') and + state.has('Hammer') and + state.has_bombchus() and + state.has('Fire Arrows') and + state.has('Mirror Shield')) + set_rule( + world.get_location('Ganons Castle MQ Light Trial Lullaby Chest'), + lambda state: state.can_play('Zeldas Lullaby')) + set_rule( + world.get_location('Ganons Castle Light Trial Clear'), + lambda state: state.can_use('Light Arrows') and + state.has('Progressive Hookshot') and + state.has('Small Key (Ganons Castle)', 3)) + set_rule(world.get_entrance('Ganons Castle Deku Scrubs'), lambda state: state.can_see_with_lens()) diff --git a/Settings.py b/Settings.py new file mode 100644 index 000000000..54490ea1c --- /dev/null +++ b/Settings.py @@ -0,0 +1,2130 @@ +import argparse +import textwrap +import string +import re +import random +import hashlib + +from Patches import get_tunic_color_options, get_navi_color_options, get_NaviSFX_options, get_HealthSFX_options +from version import __version__ +from Utils import random_choices + +class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter): + + def _get_help_string(self, action): + return textwrap.dedent(action.help) + + +# 32 characters +letters = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789" +index_to_letter = { i: letters[i] for i in range(32) } +letter_to_index = { v: k for k, v in index_to_letter.items() } + +def bit_string_to_text(bits): + # pad the bits array to be multiple of 5 + if len(bits) % 5 > 0: + bits += [0] * (5 - len(bits) % 5) + # convert to characters + result = "" + for i in range(0, len(bits), 5): + chunk = bits[i:i + 5] + value = 0 + for b in range(5): + value |= chunk[b] << b + result += index_to_letter[value] + return result + +def text_to_bit_string(text): + bits = [] + for c in text: + index = letter_to_index[c] + for b in range(5): + bits += [ (index >> b) & 1 ] + return bits + +# holds the info for a single setting +class Setting_Info(): + + def __init__(self, name, type, bitwidth=0, shared=False, args_params={}, gui_params=None): + self.name = name # name of the setting, used as a key to retrieve the setting's value everywhere + self.type = type # type of the setting's value, used to properly convert types in GUI code + self.bitwidth = bitwidth # number of bits needed to store the setting, used in converting settings to a string + self.shared = shared # whether or not the setting is one that should be shared, used in converting settings to a string + self.args_params = args_params # parameters that should be pased to the command line argument parser's add_argument() function + self.gui_params = gui_params # parameters that the gui uses to build the widget components + + # create the choices parameters from the gui options if applicable + if gui_params and 'options' in gui_params and 'choices' not in args_params \ + and not ('type' in args_params and callable(args_params['type'])): + if isinstance(gui_params['options'], list): + self.args_params['choices'] = list(gui_params['options']) + elif isinstance(gui_params['options'], dict): + self.args_params['choices'] = list(gui_params['options'].values()) + + +# holds the particular choices for a run's settings +class Settings(): + + def get_settings_display(self): + padding = 0 + for setting in filter(lambda s: s.shared, setting_infos): + padding = max( len(setting.name), padding ) + padding += 2 + output = '' + for setting in filter(lambda s: s.shared, setting_infos): + name = setting.name + ': ' + ' ' * (padding - len(setting.name)) + val = str(self.__dict__[setting.name]) + output += name + val + '\n' + return output + + def get_settings_string(self): + bits = [] + for setting in filter(lambda s: s.shared and s.bitwidth > 0, setting_infos): + value = self.__dict__[setting.name] + i_bits = [] + if setting.type == bool: + i_bits = [ 1 if value else 0 ] + if setting.type == str: + index = setting.args_params['choices'].index(value) + # https://stackoverflow.com/questions/10321978/integer-to-bitfield-as-a-list + i_bits = [1 if digit=='1' else 0 for digit in bin(index)[2:]] + i_bits.reverse() + if setting.type == int: + value = value - ('min' in setting.gui_params and setting.gui_params['min'] or 0) + value = int(value / ('step' in setting.gui_params and setting.gui_params['step'] or 1)) + value = min(value, ('max' in setting.gui_params and setting.gui_params['max'] or value)) + # https://stackoverflow.com/questions/10321978/integer-to-bitfield-as-a-list + i_bits = [1 if digit=='1' else 0 for digit in bin(value)[2:]] + i_bits.reverse() + # pad it + i_bits += [0] * ( setting.bitwidth - len(i_bits) ) + bits += i_bits + return bit_string_to_text(bits) + + def update_with_settings_string(self, text): + bits = text_to_bit_string(text) + + for setting in filter(lambda s: s.shared and s.bitwidth > 0, setting_infos): + cur_bits = bits[:setting.bitwidth] + bits = bits[setting.bitwidth:] + value = None + if setting.type == bool: + value = True if cur_bits[0] == 1 else False + if setting.type == str: + index = 0 + for b in range(setting.bitwidth): + index |= cur_bits[b] << b + value = setting.args_params['choices'][index] + if setting.type == int: + value = 0 + for b in range(setting.bitwidth): + value |= cur_bits[b] << b + value = value * ('step' in setting.gui_params and setting.gui_params['step'] or 1) + value = value + ('min' in setting.gui_params and setting.gui_params['min'] or 0) + self.__dict__[setting.name] = value + + self.settings_string = self.get_settings_string() + self.numeric_seed = self.get_numeric_seed() + + def get_numeric_seed(self): + # salt seed with the settings, and hash to get a numeric seed + full_string = self.settings_string + __version__ + self.seed + return int(hashlib.sha256(full_string.encode('utf-8')).hexdigest(), 16) + + def sanatize_seed(self): + # leave only alphanumeric and some punctuation + self.seed = re.sub(r'[^a-zA-Z0-9_-]', '', self.seed, re.UNICODE) + + def update_seed(self, seed): + self.seed = seed + self.sanatize_seed() + self.numeric_seed = self.get_numeric_seed() + + def update(self): + self.settings_string = self.get_settings_string() + self.numeric_seed = self.get_numeric_seed() + + # add the settings as fields, and calculate information based on them + def __init__(self, settings_dict): + self.__dict__.update(settings_dict) + for info in setting_infos: + if info.name not in self.__dict__: + if info.type == bool: + self.__dict__[info.name] = True if info.gui_params['default'] == 'checked' else False + if info.type == str: + if 'default' in info.args_params: + self.__dict__[info.name] = info.gui_params['default'] or info.args_params['default'] + else: + self.__dict__[info.name] = "" + if info.type == int: + self.__dict__[info.name] = info.gui_params['default'] or 1 + self.settings_string = self.get_settings_string() + if(self.seed is None): + # https://stackoverflow.com/questions/2257441/random-string-generation-with-upper-case-letters-and-digits-in-python + self.seed = ''.join(random_choices(string.ascii_uppercase + string.digits, k=10)) + self.sanatize_seed() + self.numeric_seed = self.get_numeric_seed() + +def parse_custom_tunic_color(s): + if s == 'Custom Color': + raise argparse.ArgumentTypeError('Specify custom color by using \'Custom (#xxxxxx)\'') + elif re.match(r'^Custom \(#[A-Fa-f0-9]{6}\)$', s): + return re.findall(r'[A-Fa-f0-9]{6}', s)[0] + elif s in get_tunic_color_options(): + return s + else: + raise argparse.ArgumentTypeError('Invalid color specified') + +def parse_custom_navi_color(s): + if s == 'Custom Color': + raise argparse.ArgumentTypeError('Specify custom color by using \'Custom (#xxxxxx)\'') + elif re.match(r'^Custom \(#[A-Fa-f0-9]{6}\)$', s): + return re.findall(r'[A-Fa-f0-9]{6}', s)[0] + elif s in get_navi_color_options(): + return s + else: + raise argparse.ArgumentTypeError('Invalid color specified') + +# a list of the possible settings +setting_infos = [ + Setting_Info('check_version', bool, 0, False, + { + 'help': '''\ + Checks if you are on the latest version + ''', + 'action': 'store_true' + }), + Setting_Info('checked_version', str, 0, False, { + 'default': '', + 'help': 'Supress version warnings if checked_version is less than __version__.'}), + Setting_Info('rom', str, 0, False, { + 'default': 'ZOOTDEC.z64', + 'help': 'Path to an OoT 1.0 rom to use as a base.'}), + Setting_Info('output_dir', str, 0, False, { + 'default': '', + 'help': 'Path to output directory for rom generation.'}), + Setting_Info('seed', str, 0, False, { + 'help': 'Define seed number to generate.'}), + Setting_Info('count', int, 0, False, { + 'help': '''\ + Use to batch generate multiple seeds with same settings. + If --seed is provided, it will be used for the first seed, then + used to derive the next seed (i.e. generating 10 seeds with + --seed given will produce the same 10 (different) roms each + time). + ''', + 'type': int}), + Setting_Info('world_count', int, 0, False, { + 'default': 1, + 'help': '''\ + Use to create a multi-world generation for co-op seeds. + World count is the number of players. Warning: Increasing + the world count will drastically increase generation time. + ''', + 'type': int}), + Setting_Info('player_num', int, 0, False, { + 'default': 1, + 'help': '''\ + Use to select world to generate when there are multiple worlds. + ''', + 'type': int}), + Setting_Info('create_spoiler', bool, 1, True, + { + 'help': 'Output a Spoiler File', + 'action': 'store_true' + }, + { + 'text': 'Create Spoiler Log', + 'group': 'rom_tab', + 'widget': 'Checkbutton', + 'default': 'checked', + 'dependency': lambda guivar: guivar['compress_rom'].get() != 'No ROM Output', + 'tooltip':'''\ + Enabling this will change the seed. + ''' + }), + Setting_Info('compress_rom', str, 2, False, + { + 'default': 'True', + 'const': 'True', + 'nargs': '?', + 'help': '''\ + Create a compressed version of the output ROM file. + True: Compresses. Improves stability. Will take longer to generate + False: Uncompressed. Unstable. Faster generation + None: No ROM Output. Creates spoiler log only + ''', + }, + { + 'text': 'Compress ROM', + 'group': 'rom_tab', + 'widget': 'Radiobutton', + 'default': 'Compressed [Stable]', + 'horizontal': True, + 'options': { + 'Compressed [Stable]': 'True', + 'Uncompressed [Crashes]': 'False', + 'No ROM Output': 'None', + }, + 'tooltip':'''\ + The first time compressed generation will take a while, + but subsequent generations will be quick. It is highly + recommended to compress or the game will crash + frequently except on real N64 hardware. + ''' + }), + Setting_Info('open_forest', bool, 1, True, + { + 'help': '''\ + Mido no longer blocks the path to the Deku Tree, and + the Kokiri boy no longer blocks the path out of the forest. + ''', + 'action': 'store_true' + }, + { + 'text': 'Open Forest', + 'group': 'open', + 'widget': 'Checkbutton', + 'default': 'checked', + 'tooltip':'''\ + Mido no longer blocks the path to the Deku Tree, + and the Kokiri boy no longer blocks the path out + of the forest. + + When this option is off, the Kokiri Sword and + Slingshot are always available somewhere + in the forest. + ''' + }), + Setting_Info('open_kakariko', bool, 1, True, + { + 'help': '''\ + The gate in Kakariko Village to Death Mountain Trail + is always open instead of needing Zelda's Letter. + ''', + 'action': 'store_true' + }, + { + 'text': 'Open Kakariko Gate', + 'group': 'open', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + The gate in Kakariko Village to Death Mountain Trail + is always open instead of needing Zelda's Letter. + + Either way, the gate is always open as an adult. + ''' + }), + Setting_Info('open_door_of_time', bool, 1, True, + { + 'help': ''' + The Door of Time is open from the beginning of the game. + ''', + 'action': 'store_true' + }, + { + 'text': 'Open Door of Time', + 'group': 'open', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + The Door of Time starts opened instead of needing to + play the Song of Time. If this is not set, only + an Ocarina and Song of Time must be found to open + the Door of Time. + ''' + }), + Setting_Info('gerudo_fortress', str, 2, True, + { + 'default': 'normal', + 'const': 'normal', + 'nargs': '?', + 'help': '''Select how much of Gerudo Fortress is required. (default: %(default)s) + Normal: Free all four carpenters to get the Gerudo Card. + Fast: Free only the carpenter closest to Link's prison to get the Gerudo Card. + Open: Start with the Gerudo Card and all its benefits. + ''' + }, + { + 'text': 'Gerudo Fortress', + 'group': 'open', + 'widget': 'Combobox', + 'default': 'Default Behavior', + 'options': { + 'Default Behavior': 'normal', + 'Rescue One Carpenter': 'fast', + 'Start with Gerudo Card': 'open', + }, + 'tooltip':'''\ + 'Rescue One Carpenter': Only the bottom left + carpenter must be rescued. + + 'Start with Gerudo Card': The carpenters are rescued from + the start of the game, and the player starts with the Gerudo + Card in the inventory allowing access to Gerudo Training Grounds. + ''' + }), + Setting_Info('bridge', str, 2, True, + { + 'default': 'medallions', + 'const': 'medallions', + 'nargs': '?', + 'help': '''\ + Select requirement to spawn the Rainbow Bridge to reach Ganon's Castle. (default: %(default)s) + Medallions: Collect all six medallions to create the bridge. + Vanilla: Collect only the Shadow and Spirit Medallions and possess the Light Arrows. + All Dungeons: Collect all spiritual stones and all medallions to create the bridge. + Open: The bridge will spawn without an item requirement. + ''' + }, + { + 'text': 'Rainbow Bridge Requirement', + 'group': 'open', + 'widget': 'Combobox', + 'default': 'All Medallions', + 'options': { + 'All Dungeons': 'dungeons', + 'All Medallions': 'medallions', + 'Vanilla Requirements': 'vanilla', + 'Always Open': 'open', + }, + 'tooltip':'''\ + 'All Dungeons': All Medallions and Stones + + 'All Medallions': All 6 Medallions only + + 'Vanilla Requirements': Spirit and Shadow + Medallions and the Light Arrows + + 'Always Open': Rainbow Bridge is always present + ''' + }), + Setting_Info('all_reachable', bool, 1, True, + { + 'help': '''\ + When disabled, only check if the game is beatable with + placement. Do not ensure all locations are reachable. + ''', + 'action': 'store_true' + }, + { + 'text': 'All Locations Reachable', + 'group': 'world', + 'widget': 'Checkbutton', + 'default': 'checked', + 'tooltip':'''\ + When this option is enabled, the randomizer will + guarantee that every item is obtainable and every + location is reachable. + + When disabled, only required items and locations + to beat the game will be guaranteed reachable. + + Even when enabled, some locations may still be able + to hold the keys needed to reach them. + ''' + }), + Setting_Info('bombchus_in_logic', bool, 1, True, + { + 'help': '''\ + Bombchus will be considered in logic. This has a few effects: + -Back Alley shop will open once you've found Bombchus. + -It will sell an affordable pack (5 for 60) and never sell out. + -Bombchus refills cannot be bought until Bombchus have been obtained. + ''', + 'action': 'store_true' + }, + { + 'text': 'Bombchus Are Considered in Logic', + 'group': 'world', + 'widget': 'Checkbutton', + 'default': 'checked', + 'tooltip':'''\ + Bombchus are properly considered in logic. + + The first Bombchu pack will always be 20. + Subsequent packs will be 5 or 10 based on + how many you have. + + Bombchus can be purchased for 60/99/180 + rupees once they are been found. + + Bombchu Bowling opens with Bombchus. + Bombchus are available at Kokiri Shop + and the Bazaar. Bombchu refills cannot + be bought until Bombchus have been + obtained. + ''', + }), + Setting_Info('one_item_per_dungeon', bool, 1, True, + { + 'help': '''\ + Each dungeon will have exactly one major item. + Does not include dungeon items or GS Tokens. + ''', + 'action': 'store_true' + }, + { + 'text': 'Dungeons Have One Major Item', + 'group': 'world', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Dungeons have exactly one major + item. This naturally makes each + dungeon similar in value instaed + of valued based on chest count. + + Spirit Temple Colossus hands count + as part of the dungeon. Spirit + Temple has TWO items to match + vanilla distribution. + + Dungeon items and GS Tokens do + not count as major items. + ''', + }), + Setting_Info('trials_random', bool, 1, True, + { + 'help': '''\ + Sets the number of trials must be cleared to enter + Ganon's Tower to a random value. + ''', + 'action': 'store_true' + }, + { + 'text': 'Random Number of Ganon\'s Trials', + 'group': 'open', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Sets a random number of trials to + enter Ganon's Tower. + ''' + }), + Setting_Info('trials', int, 3, True, + { + 'default': 6, + 'const': 6, + 'nargs': '?', + 'choices': [0, 1, 2, 3, 4, 5, 6], + 'help': '''\ + Select how many trials must be cleared to enter Ganon's Tower. + The trials you must complete will be selected randomly. + ''', + 'type': int + }, + { + 'group': 'open', + 'widget': 'Scale', + 'default': 6, + 'min': 0, + 'max': 6, + 'random': True, + 'tooltip':'''\ + Trials are randomly selected. If hints are + enabled, then there will be hints for which + trials need to be completed. + ''', + 'dependency': lambda guivar: not guivar['trials_random'].get(), + }), + Setting_Info('no_escape_sequence', bool, 1, True, + { + 'help': '''\ + The tower collapse escape sequence between Ganondorf and Ganon will be skipped. + ''', + 'action': 'store_true' + }, + { + 'text': 'Skip Tower Collapse Escape Sequence', + 'group': 'convenience', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + The tower collapse escape sequence between + Ganondorf and Ganon will be skipped. + ''' + }), + Setting_Info('no_guard_stealth', bool, 1, True, + { + 'help': '''\ + The crawlspace into Hyrule Castle will take you straight to Zelda. + ''', + 'action': 'store_true' + }, + { + 'text': 'Skip Interior Castle Guard Stealth Sequence', + 'group': 'convenience', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + The crawlspace into Hyrule Castle goes + straight to Zelda, skipping the guards. + ''' + }), + Setting_Info('no_epona_race', bool, 1, True, + { + 'help': '''\ + Having Epona's Song will allow you to summon Epona without racing Ingo. + ''', + 'action': 'store_true' + }, + { + 'text': 'Skip Epona Race', + 'group': 'convenience', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Epona can be summoned with Epona's Song + without needing to race Ingo. + ''' + }), + Setting_Info('fast_chests', bool, 1, True, + { + 'help': '''\ + Makes all chests open without the large chest opening cutscene. + ''', + 'action': 'store_true' + }, + { + 'text': 'Fast Chest Cutscenes', + 'group': 'convenience', + 'widget': 'Checkbutton', + 'default': 'checked', + 'tooltip':'''\ + All chest animations are fast. If disabled, + the animation time is slow for major items. + ''' + }), + Setting_Info('big_poe_count_random', bool, 1, True, + { + 'help': '''\ + Sets a random number of Big Poes to receive an item from the buyer. + ''', + 'action': 'store_true' + }, + { + 'text': 'Random Big Poe Target Count', + 'group': 'convenience', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + The Poe buyer will give a reward for turning + in a random number of Big Poes. + ''' + }), + Setting_Info('big_poe_count', int, 4, True, + { + 'default': 10, + 'const': 10, + 'nargs': '?', + 'choices': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + 'help': '''\ + Select the number of Big Poes to receive an item from the buyer. + ''', + 'type': int, + }, + { + 'group': 'convenience', + 'widget': 'Scale', + 'default': 10, + 'min': 1, + 'max': 10, + 'tooltip':'''\ + The Poe buyer will give a reward for turning + in the chosen number of Big Poes. + ''', + 'dependency': lambda guivar: not guivar['big_poe_count_random'].get(), + }), + Setting_Info('free_scarecrow', bool, 1, True, + { + 'help': '''\ + Start with Scarecrow's Song. You do not need + to play it as child or adult at the scarecrow + patch to be able to summon Pierre. + ''', + 'action': 'store_true' + }, + { + 'text': 'Start with Scarecrow\'s Song', + 'group': 'convenience', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Skips needing to go to Lake Hylia as both + child and adult to learn Scarecrow's Song. + ''' + }), + Setting_Info('scarecrow_song', str, 0, False, + { + 'default': 'DAAAAAAA', + 'const': 'DAAAAAAA', + 'nargs': '?', + 'help': '''\ + The song started with if 'free_scarecrow' is True + Valid notes: A, U, L, R, D + ''', + }, + { + 'group': 'convenience', + 'widget': 'Entry', + 'default': 'DAAAAAAA', + 'dependency': lambda guivar: guivar['free_scarecrow'].get(), + 'tooltip':'''\ + The song must be 8 notes long and have + at least two different notes. + Valid notes are: + 'A': A Button + 'D': C-Down + 'U': C-Up + 'L': C-Left + 'R': C-Right + ''' + }), + Setting_Info('shuffle_kokiri_sword', bool, 1, True, + { + 'help': '''\ + Shuffles the Kokiri Sword into the pool. + ''', + 'action': 'store_true' + }, + { + 'text': 'Shuffle Kokiri Sword', + 'group': 'logic', + 'widget': 'Checkbutton', + 'default': 'checked', + 'tooltip':'''\ + Disabling this will make the Kokiri Sword + always available at the start. + ''' + }), + Setting_Info('shuffle_weird_egg', bool, 1, True, + { + 'help': '''\ + Shuffles the Weird Egg item from Malon into the pool. + This means that you need to find the egg before going Zelda. + ''', + 'action': 'store_true' + }, + { + 'text': 'Shuffle Weird Egg', + 'group': 'logic', + 'widget': 'Checkbutton', + 'default': 'checked', + 'tooltip':'''\ + You need to find the egg before going Zelda. + This means the Weird Egg locks the rewards from + Impa, Saria, Malon, and Talon as well as the + Happy Mask sidequest. + ''' + }), + Setting_Info('shuffle_ocarinas', bool, 1, True, + { + 'help': '''\ + Shuffles the Fairy Ocarina and the Ocarina of Time into the pool. + This means that you need to find an ocarina before playing songs. + ''', + 'action': 'store_true' + }, + { + 'text': 'Shuffle Ocarinas', + 'group': 'logic', + 'widget': 'Checkbutton', + 'default': 'checked', + 'tooltip':'''\ + The Fairy Ocarina and Ocarina of Time are + randomized. One will be required before + songs can be played. + ''' + }), + Setting_Info('shuffle_song_items', bool, 1, True, + { + 'help': '''\ + Shuffles the songs with with rest of the item pool so that + songs can appear at other locations and items can appear at + the song locations. + ''', + 'action': 'store_true' + }, + { + 'text': 'Shuffle Songs with Items', + 'group': 'logic', + 'widget': 'Checkbutton', + 'default': 'checked', + 'tooltip':'''\ + Songs can appear anywhere as normal items. + + If this option is not set, songs will still + be shuffled but will be limited to the + locations that has songs in the original game. + ''' + }), + Setting_Info('shuffle_gerudo_card', bool, 1, True, + { + 'help': '''\ + Shuffles the Gerudo Card into the item pool. + The Gerudo Card does not stop guards from throwing you in jail. + It only grants access to Gerudo Training Grounds after all carpenters + have been rescued. This option does nothing if "gerudo_fortress" is "open". + ''', + 'action': 'store_true' + }, + { + 'text': 'Shuffle Gerudo Card', + 'group': 'logic', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'dependency': lambda guivar: guivar['gerudo_fortress'].get() != 'Start with Gerudo Card', + 'tooltip':'''\ + Gerudo Card is required to enter + Gerudo Training Grounds. + ''' + }), + Setting_Info('shuffle_scrubs', str, 3, True, + { + 'default': 'off', + 'const': 'off', + 'nargs': '?', + 'help': '''\ + Deku Scrub Salesmen are randomized: + off: Only the 3 Scrubs that give one-time items + in the vanilla game will have random items. + low: All Scrubs will have random items and their + prices will be reduced to 10 rupees each. + regular: All Scrubs will have random items and each + of them will demand their vanilla prices. + random: All Scrubs will have random items and their + price will also be random between 10-99 rupees. + ''' + }, + { + 'text': 'Scrub Shuffle', + 'group': 'logic', + 'widget': 'Combobox', + 'default': 'Off', + 'options': { + 'Off': 'off', + 'On (Affordable)': 'low', + 'On (Expensive)': 'regular', + 'On (Random Prices)': 'random', + }, + 'tooltip':'''\ + 'Off': Only the 3 Scrubs that give one-time + items in the vanilla game (PoH, Deku Nut + capacity, and Deku Stick capacity) will + have random items. + + 'Affordable': All Scrub prices will be + reduced to 10 rupees each. + + 'Expensive': All Scrub prices will be + their vanilla prices. This will require + spending over 1000 rupees on Scrubs. + + 'Random Prices': All Scrub prices will be + between 0-99 rupees. This will on average + be very, very expensive overall. + + The texts of the Scrubs are not updated. + ''' + }), + Setting_Info('shopsanity', str, 3, True, + { + 'default': 'off', + 'const': 'off', + 'nargs': '?', + 'help': '''\ + Shop contents are randomized. Non-shop items + are one time purchases. This setting also + changes the item pool to introduce a new Wallet + upgrade and more money. + off: Normal Shops* + 0-4: Shop contents are shuffled and N non-shop + items are added to every shop. So more + possible item locations. + random: Shop contents are shuffles and each shop + will have a random number of non-shop items + ''' + }, + { + 'text': 'Shopsanity', + 'group': 'logic', + 'widget': 'Combobox', + 'default': 'Off', + 'options': { + 'Off': 'off', + 'Shuffled Shops (0 Items)': '0', + 'Shuffled Shops (1 Items)': '1', + 'Shuffled Shops (2 Items)': '2', + 'Shuffled Shops (3 Items)': '3', + 'Shuffled Shops (4 Items)': '4', + 'Shuffled Shops (Random)': 'random', + }, + 'tooltip':'''\ + Shop contents are randomized. + (X Items): Shops have X random non-shop (Special + Deal!) items. They will always be on the left + side, and some of the lower value shop items + will be replaced to make room for these. + + (Random): Each shop will have a random number + of non-shop items up to a maximum of 4. + + The non-shop items have no requirements except + money, while the normal shop items (such as + 200/300 rupee tunics) have normal vanilla + requirements. This means that, for example, + as a child you cannot buy 200/300 rupee + tunics, but you can buy non-shop tunics. + + Non-shop Bombchus will unlock the chu slot + in your inventory, which, if Bombchus are in + logic, is needed to buy Bombchu refills. + Otherwise, the Bomb Bag is required. + ''' + }), + Setting_Info('shuffle_mapcompass', str, 2, True, + { + 'default': 'dungeon', + 'const': 'dungeon', + 'nargs': '?', + 'help': '''\ + Sets the Map and Compass placement rules + remove: Maps and Compasses are removed from the world. + startwith: Start with all Maps and Compasses. + dungeon: Maps and Compasses are put in their dungeon. + keysanity: Maps and Compasses can appear anywhere. + ''' + }, + { + 'text': 'Shuffle Dungeon Items', + 'group': 'logic', + 'widget': 'Combobox', + 'default': 'Maps/Compasses: Dungeon Only', + 'options': { + 'Maps/Compasses: Remove': 'remove', + 'Maps/Compasses: Start With': 'startwith', + 'Maps/Compasses: Dungeon Only': 'dungeon', + 'Maps/Compasses: Anywhere': 'keysanity' + }, + 'tooltip':'''\ + 'Remove': Maps and Compasses are removed. + This will add a small amount of money and + refill items to the pool. + + 'Start With': Maps and Compasses are given to + you from the start. This will add a small + amount of money and refill items to the pool. + + 'Dungeon': Maps and Compasses can only appear + in their respective dungeon. + + 'Anywhere': Maps and Compasses can appear + anywhere in the world. + + Setting 'Remove', 'Start With, or 'Anywhere' will + add 2 more possible locations to each Dungeons. + This makes dungeons more profitable, especially + Ice Cavern, Water Temple, and Jabu Jabu's Belly. + ''' + }), + Setting_Info('shuffle_smallkeys', str, 2, True, + { + 'default': 'dungeon', + 'const': 'dungeon', + 'nargs': '?', + 'help': '''\ + Sets the Small Keys placement rules + remove: Small Keys are removed from the world. + dungeon: Small Keys are put in their dungeon. + keysanity: Small Keys can appear anywhere. + ''' + }, + { + 'group': 'logic', + 'widget': 'Combobox', + 'default': 'Small Keys: Dungeon Only', + 'options': { + 'Small Keys: Remove (Keysy)': 'remove', + 'Small Keys: Dungeon Only': 'dungeon', + 'Small Keys: Anywhere (Keysanity)': 'keysanity' + }, + 'tooltip':'''\ + 'Remove': Small Keys are removed. All locked + doors in dungeons will be unlocked. An easier + mode. + + 'Dungeon': Small Keys can only appear in their + respective dungeon. If Fire Temple is not a + Master Quest dungeon, the door to the Boss Key + chest will be unlocked + + 'Anywhere': Small Keys can appear + anywhere in the world. A difficult mode since + it is more likely to need to enter a dungeon + multiple times. + + Try different combination out, such as: + 'Small Keys: Dungeon' + 'Boss Keys: Anywhere' + for a milder Keysanity experience. + ''' + }), + Setting_Info('shuffle_bosskeys', str, 2, True, + { + 'default': 'dungeon', + 'const': 'dungeon', + 'nargs': '?', + 'help': '''\ + Sets the Boss Keys placement rules + remove: Boss Keys are removed from the world. + dungeon: Boss Keys are put in their dungeon. + keysanity: Boss Keys can appear anywhere. + ''' + }, + { + 'group': 'logic', + 'widget': 'Combobox', + 'default': 'Boss Keys: Dungeon Only', + 'options': { + 'Boss Keys: Remove (Keysy)': 'remove', + 'Boss Keys: Dungeon Only': 'dungeon', + 'Boss Keys: Anywhere (Keysanity)': 'keysanity' + }, + 'tooltip':'''\ + 'Remove': Boss Keys are removed. All locked + doors in dungeons will be unlocked. An easier + mode. + + 'Dungeon': Boss Keys can only appear in their + respective dungeon. + + 'Anywhere': Boss Keys can appear + anywhere in the world. A difficult mode since + it is more likely to need to enter a dungeon + multiple times. + + Try different combination out, such as: + 'Small Keys: Dungeon' + 'Boss Keys: Anywhere' + for a milder Keysanity experience. + ''' + }), + Setting_Info('enhance_map_compass', bool, 1, True, + { + 'help': '''\ + Gives the Map and Compass extra functionality. + Map will tell if a dungeon is vanilla or Master Quest. + Compass will tell what medallion or stone is within. + The Temple of Time Altar will no longer provide any + information. If the maps and compasses are removed then + the information will be unavailable. + ''', + 'action': 'store_true' + }, + { + 'text': 'Maps and Compasses Give Information', + 'group': 'logic', + 'widget': 'Checkbutton', + 'default': 'checked', + 'tooltip':'''\ + Gives the Map and Compass extra functionality. + Map will tell if a dungeon is vanilla or Master Quest. + Compass will tell what medallion or stone is within. + The Temple of Time Altar will no longer provide any + information. + + 'Maps/Compasses: Remove': The dungeon information is + not available anywhere in the game. + + 'Maps/Compasses: Start With': The dungeon information + is available immediately from the dungeon menu. + ''', + }), + Setting_Info('unlocked_ganondorf', bool, 1, True, + { + 'help': '''\ + The Boss Key door in Ganon's Tower will start unlocked. + ''', + 'action': 'store_true' + }, + { + 'text': 'Remove Ganon\'s Boss Door Lock', + 'group': 'logic', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + The Boss Key door in Ganon's Tower + will start unlocked. This is intended + to be used with reduced trial + requirements to make it more likely + that skipped trials can be avoided. + ''', + 'dependency': lambda guivar: guivar['shuffle_bosskeys'].get() != 'Boss Keys: Remove (Keysy)', + }), + Setting_Info('tokensanity', str, 2, True, + { + 'default': 'off', + 'const': 'off', + 'nargs': '?', + 'help': '''\ + Gold Skulltula Tokens will be shuffled into the pool, + and Gold Skulltula locations can have any item. + off: Don't use this feature + dungeons: Only dungeon Skulltulas will be shuffled + all: All Gold Skulltulas will be shuffled + ''' + }, + { + 'text': 'Tokensanity', + 'group': 'logic', + 'widget': 'Combobox', + 'default': 'Off', + 'options': { + 'Off': 'off', + 'Dungeons Only': 'dungeons', + 'All Tokens': 'all', + }, + 'tooltip':'''\ + Token reward from Gold Skulltulas are + shuffled into the pool. + + 'Dungeons Only': This only shuffles + the GS locations that are within + dungeons, increasing the value of + most dungeons and making internal + dungeon exploration more diverse. + + 'All Tokens': Effectively adds 100 + new locations for items to appear. + ''' + }), + Setting_Info('quest', str, 2, True, + { + 'default': 'vanilla', + 'const': 'vanilla', + 'nargs': '?', + 'help': '''\ + Select requirement to spawn the Rainbow Bridge to reach Ganon's Castle. (default: %(default)s) + Vanilla: Dungeons will be the original Ocarina of Time dungeons. + Master: Dungeons will be in the form of the Master Quest. + Mixed: Each dungeon will randomly be either standard or Master Quest. + ''' + }, + { + 'text': 'Dungeon Quest', + 'group': 'world', + 'widget': 'Combobox', + 'default': 'Vanilla', + 'options': { + 'Vanilla': 'vanilla', + 'Master Quest': 'master', + 'Mixed': 'mixed', + }, + 'tooltip':'''\ + 'Vanilla': Dungeons will be in their + default OoT form. + + 'Master Quest': Dungeons will be in the + form found in OoT: Master Quest. + + 'Mixed': Each dungeon will have a + random chance to be in either form. + ''', + }), + Setting_Info('logic_skulltulas', int, 3, True, + { + 'default': 50, + 'const': 50, + 'nargs': '?', + 'choices': [0, 10, 20, 30, 40, 50], + 'help': '''\ + Choose the maximum number of Gold Skulltula Tokens you will be expected to collect. + ''', + 'type': int + }, + { + 'text': 'Maximum Expected Skulltula Tokens', + 'group': 'rewards', + 'widget': 'Scale', + 'default': 50, + 'min': 0, + 'max': 50, + 'step': 10, + 'tooltip':'''\ + Choose the maximum number of Gold Skulltula + Tokens you will be expected to collect. + ''' + }), + Setting_Info('logic_no_night_tokens_without_suns_song', bool, 1, True, + { + 'help': '''\ + You will not be expected to collect nighttime-only skulltulas + unless you have Sun's Song + ''', + 'action': 'store_true' + }, + { + 'text': 'No Nighttime Skulltulas without Sun\'s Song', + 'group': 'rewards', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + GS Tokens that can only be obtained + during the night expect you to have Sun's + Song to collect them. This prevents needing + to wait until night for some locations. + ''' + }), + Setting_Info('logic_no_big_poes', bool, 1, True, + { + 'help': '''\ + You will not be expected to collect 10 big poes. + ''', + 'action': 'store_true' + }, + { + 'text': 'No Big Poes', + 'group': 'rewards', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + The Big Poe vendor will not have a + required item. + ''' + }), + Setting_Info('logic_no_child_fishing', bool, 1, True, + { + 'help': '''\ + You will not be expected to obtain the child fishing reward. + ''', + 'action': 'store_true' + }, + { + 'text': 'No Child Fishing', + 'group': 'rewards', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Fishing does not work correctly on + Bizhawk. + ''' + }), + Setting_Info('logic_no_adult_fishing', bool, 1, True, + { + 'help': '''\ + You will not be expected to obtain the adult fishing reward. + ''', + 'action': 'store_true' + }, + { + 'text': 'No Adult Fishing', + 'group': 'rewards', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Fishing does not work correctly on + Bizhawk. + ''' + }), + Setting_Info('logic_no_trade_skull_mask', bool, 1, True, + { + 'help': '''\ + You will not be expected to show the Skull Mask at the forest stage. + ''', + 'action': 'store_true' + }, + { + 'text': 'No Skull Mask Reward', + 'group': 'rewards', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Showing off the Skull Mask will + not yield a required item. + ''' + }), + Setting_Info('logic_no_trade_mask_of_truth', bool, 1, True, + { + 'help': '''\ + You will not be expected to show the Mask of Truth at the forest stage. + ''', + 'action': 'store_true' + }, + { + 'text': 'No Mask of Truth Reward', + 'group': 'rewards', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Showing off the Mask of Truth + will not yield a required item. + ''' + }), + Setting_Info('logic_no_1500_archery', bool, 1, True, + { + 'help': '''\ + You will not be expected to win the 1500 point horseback archery reward. + ''', + 'action': 'store_true' + }, + { + 'text': 'No 1500 Horseback Archery', + 'group': 'rewards', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Scoring 1500 points at horseback + archery will not yield a required item. + ''' + }), + Setting_Info('logic_no_memory_game', bool, 1, True, + { + 'help': '''\ + You will not be expected to play the ocarina memory game in Lost Woods. + ''', + 'action': 'store_true' + }, + { + 'text': 'No Lost Woods Memory Game', + 'group': 'rewards', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Playing the ocarina memory game + will not yield a required item. + ''' + }), + Setting_Info('logic_no_second_dampe_race', bool, 1, True, + { + 'help': '''\ + You will not be expected to race Dampe a second time. + ''', + 'action': 'store_true' + }, + { + 'text': 'No Racing Dampe a Second Time', + 'group': 'rewards', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + The second Dampe race will + not yield a required item. + ''' + }), + Setting_Info('logic_no_trade_biggoron', bool, 1, True, + { + 'help': '''\ + You will not be expected to show the Claim Check to Biggoron. + ''', + 'action': 'store_true' + }, + { + 'text': 'No Biggoron Reward', + 'group': 'rewards', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Showing the Claim Check to Biggoron + will not yield a required item. + ''' + }), + Setting_Info('logic_earliest_adult_trade', str, 4, True, + { + 'default': 'pocket_egg', + 'const': 'always', + 'nargs': '?', + 'help': '''\ + Select the earliest item that can appear in the adult trade sequence: + 'pocket_egg' + 'pocket_cucco' + 'cojiro' + 'odd_mushroom' + 'poachers_saw' + 'broken_sword' + 'prescription' + 'eyeball_frog' + 'eyedrops' + 'claim_check' + ''' + }, + { + 'text': 'Adult Trade Sequence', + 'group': 'rewards', + 'widget': 'Combobox', + 'dependency': lambda guivar: not guivar['logic_no_trade_biggoron'].get(), + 'default': 'Earliest: Pocket Egg', + 'options': { + 'Earliest: Pocket Egg': 'pocket_egg', + 'Earliest: Pocket Cucco': 'pocket_cucco', + 'Earliest: Cojiro': 'cojiro', + 'Earliest: Odd Mushroom': 'odd_mushroom', + 'Earliest: Poacher\'s Saw': 'poachers_saw', + 'Earliest: Broken Sword': 'broken_sword', + 'Earliest: Prescription': 'prescription', + 'Earliest: Eyeball Frog': 'eyeball_frog', + 'Earliest: Eyedrops': 'eyedrops', + 'Earliest: Claim Check': 'claim_check'}, + 'tooltip':'''\ + Select the earliest item that can appear in the adult trade sequence. + ''' + }), + Setting_Info('logic_latest_adult_trade', str, 4, True, + { + 'default': 'claim_check', + 'const': 'always', + 'nargs': '?', + 'help': '''\ + Select the latest item that can appear in the adult trade sequence: + 'pocket_egg' + 'pocket_cucco' + 'cojiro' + 'odd_mushroom' + 'poachers_saw' + 'broken_sword' + 'prescription' + 'eyeball_frog' + 'eyedrops' + 'claim_check' + ''' + }, + { + 'group': 'rewards', + 'widget': 'Combobox', + 'dependency': lambda guivar: not guivar['logic_no_trade_biggoron'].get(), + 'default': 'Latest: Claim Check', + 'options': { + 'Latest: Pocket Egg': 'pocket_egg', + 'Latest: Pocket Cucco': 'pocket_cucco', + 'Latest: Cojiro': 'cojiro', + 'Latest: Odd Mushroom': 'odd_mushroom', + 'Latest: Poacher\'s Saw': 'poachers_saw', + 'Latest: Broken Sword': 'broken_sword', + 'Latest: Prescription': 'prescription', + 'Latest: Eyeball Frog': 'eyeball_frog', + 'Latest: Eyedrops': 'eyedrops', + 'Latest: Claim Check': 'claim_check'}, + 'tooltip':'''\ + Select the latest item that can appear in the adult trade sequence. + ''' + }), + Setting_Info('logic_tricks', bool, 1, True, + { + 'help': '''\ + Enable various advanced tricks that do not require glitches. + ''', + 'action': 'store_true' + }, + { + 'text': 'Various Advanced Tricks', + 'group': 'tricks', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Enables a large number of minor + tricks that do not require glitches. + ''' + }), + Setting_Info('logic_man_on_roof', bool, 1, True, + { + 'help': '''\ + The man on the roof will not require the Hookshot in logic. + ''', + 'action': 'store_true' + }, + { + 'text': 'Man on Roof without Hookshot', + 'group': 'tricks', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Can be reached by side-hopping off + the watchtower. + ''' + }), + Setting_Info('logic_child_deadhand', bool, 1, True, + { + 'help': '''\ + Deadhand in the Bottom of the Well will not require the Kokiri sword in logic. + ''', + 'action': 'store_true' + }, + { + 'text': 'Child Deadhand without Kokiri Sword', + 'group': 'tricks', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Requires 9 sticks or 5 jump slashes. + ''' + }), + Setting_Info('logic_dc_jump', bool, 1, True, + { + 'help': '''\ + Jumping towards the Bomb Bag chest in Dodongo's Cavern as an adult + will not require Hover Boots in logic. + ''', + 'action': 'store_true' + }, + { + 'text': 'Dodongo\'s Cavern Spike Trap Room Jump without Hover Boots', + 'group': 'tricks', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Jump is adult only. + ''' + }), + Setting_Info('logic_windmill_poh', bool, 1, True, + { + 'help': '''\ + Getting the Piece of Heart in the windmill as an adult will require nothing in logic. + ''', + 'action': 'store_true' + }, + { + 'text': 'Windmill PoH as Adult with Nothing', + 'group': 'tricks', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Can jump up to the spinning platform from + below as adult. + ''' + }), + Setting_Info('logic_crater_bean_poh_with_hovers', bool, 1, True, + { + 'help': '''\ + The Piece of Heart in Death Mountain Crater that normally requires the bean to + reach will optionally require the Hover Boots in logic. + ''', + 'action': 'store_true' + }, + { + 'text': "Crater's Bean PoH with Hover Boots", + 'group': 'tricks', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Hover from the base of the bridge + near Goron City and walk up the + very steep slope. + ''' + }), + Setting_Info('logic_zora_with_cucco', bool, 1, True, + { + 'help': '''\ + Zora's Domain can be entered with a Cucco as child in logic. + ''', + 'action': 'store_true' + }, + { + 'text': "Zora's Domain Entry with Cucco", + 'group': 'tricks', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Can fly behind the waterfall with + a cucco as child. + ''' + }), + Setting_Info('logic_zora_with_hovers', bool, 1, True, + { + 'help': '''\ + Zora's Domain can be entered with Hover Boots as Adult in logic. + ''', + 'action': 'store_true' + }, + { + 'text': "Zora's Domain Entry with Hover Boots", + 'group': 'tricks', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Can hover behind the waterfall as adult. + This is very difficult. + ''' + }), + Setting_Info('logic_fewer_tunic_requirements', bool, 1, True, + { + 'help': '''\ + Allows the following possible without Goron or Zora Tunic: + Enter Water Temple + Enter Fire Temple + Zoras Fountain Bottom Freestanding PoH + Gerudo Training Grounds Underwater Silver Rupee Chest + ''', + 'action': 'store_true' + }, + { + 'text': "Fewer Tunic Requirements", + 'group': 'tricks', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Allows the following possible without Tunics: + - Enter Water Temple. The key below the center + pillar still requires Zora Tunic. + - Enter Fire Temple. Only the first floor is + accessible, and not Volvagia. + - Zora's Fountain Bottom Freestanding PoH. + Might not have enough health to resurface. + - Gerudo Training Grounds Underwater + Silver Rupee Chest. May need to make multiple + trips. + ''' + }), + Setting_Info('logic_morpha_with_scale', bool, 1, True, + { + 'help': '''\ + Allows entering Water Temple and beating + Morpha with Gold Scale instead of Iron Boots. + Only applicable for keysanity and keysy. + ''', + 'action': 'store_true' + }, + { + 'text': "Morpha with Gold Scale", + 'group': 'tricks', + 'widget': 'Checkbutton', + 'default': 'checked', + 'tooltip':'''\ + Allows entering Water Temple and beating + Morpha with Gold Scale instead of Iron Boots. + Only applicable for keysanity and keysy due + to the logic always seeing every chest in + Water Temple that could contain the Boss Key + as requiring Iron Boots. + ''', + 'dependency': lambda guivar: guivar['shuffle_bosskeys'].get() != 'Boss Keys: Dungeon Only' + }), + Setting_Info('logic_lens', str, 2, True, + { + 'default': 'all', + 'const': 'always', + 'nargs': '?', + 'help': '''\ + Choose what expects the Lens of Truth: + all: All lens spots expect the lens (except those that did not in the original game) + chest-wasteland: Only wasteland and chest minigame expect the lens + chest: Only the chest minigame expects the lens + ''' + }, + { + 'text': 'Lens of Truth', + 'group': 'tricks', + 'widget': 'Combobox', + 'default': 'Required Everywhere', + 'options': { + 'Required Everywhere': 'all', + 'Wasteland and Chest Minigame': 'chest-wasteland', + 'Only Chest Minigame': 'chest', + }, + 'tooltip':'''\ + 'Required everywhere': every invisible or + fake object will expect you to have the + Lens of Truth and Magic. The exception is + passing through the first wall in Bottom of + the Well, since that is required in vanilla. + + 'Wasteland': The lens is needed to follow + the ghost guide across the Haunted Wasteland. + ''' + }), + Setting_Info('ocarina_songs', bool, 1, True, + { + 'help': '''\ + Randomizes the notes needed to play each ocarina song. + ''', + 'action': 'store_true' + }, + { + 'text': 'Randomize Ocarina Song Notes', + 'group': 'other', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Will need to memorize a new set of songs. + Can be silly, but difficult. Songs are + generally sensible, and warp songs are + typically more difficult. + ''' + }), + Setting_Info('correct_chest_sizes', bool, 1, True, + { + 'help': '''\ + Updates the chest sizes to match their contents. + Small Chest = Non-required Item + Big Chest = Progression Item + ''', + 'action': 'store_true' + }, + { + 'text': 'Chest Size Matches Contents', + 'group': 'other', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + Chests will be large if they contain a major + item and small if they don't. This allows skipping + chests if they are small. However, skipping + small chests will mean having low health, + ammo, and rupees, so doing so is a risk. + ''' + }), + Setting_Info('clearer_hints', bool, 1, True, + { + 'help': '''\ + The hints provided by Gossip Stones are + very direct. + ''', + 'action': 'store_true' + }, + { + 'text': 'Clearer Hints', + 'group': 'other', + 'widget': 'Checkbutton', + 'default': 'unchecked', + 'tooltip':'''\ + The hints provided by Gossip Stones will + be very direct if this option is enabled. + ''' + }), + Setting_Info('hints', str, 2, True, + { + 'default': 'none', + 'const': 'agony', + 'nargs': '?', + 'help': '''\ + Choose how Gossip Stones behave + none: Default behavior + mask: Have useful hints that are read with the Mask of Truth. + agony: Have useful hints that are read with Stone of Agony. + always: Have useful hints which can always be read. + ''' + }, + { + 'text': 'Gossip Stones', + 'group': 'other', + 'widget': 'Combobox', + 'default': 'Hints; Need Stone of Agony', + 'options': { + 'No Hints': 'none', + 'Hints; Need Mask of Truth': 'mask', + 'Hints; Need Stone of Agony': 'agony', + 'Hints; Need Nothing': 'always', + }, + 'tooltip':'''\ + Gossip Stones can be made to give hints + about where items can be found. + + Different settings can be chosen to + decide which item is needed to + speak to Gossip Stones. Choosing to + stick with the Mask of Truth will + make the hints very difficult to + obtain. + + Hints for 'on the way of the hero' are + locations that contain items that are + required to beat the game. + ''' + }), + Setting_Info('text_shuffle', str, 2, True, + { + 'default': 'none', + 'const': 'none', + 'nargs': '?', + 'help': '''\ + Choose how to shuffle the game's messages. + none: Default behavior + except_hints: All non-useful text is shuffled. + complete: All text is shuffled. + ''' + }, + { + 'text': 'Text Shuffle', + 'group': 'other', + 'widget': 'Combobox', + 'default': 'No Text Shuffled', + 'options': { + 'No Text Shuffled': 'none', + 'Shuffled except Hints and Keys': 'except_hints', + 'All Text Shuffled': 'complete', + }, + 'tooltip':'''\ + Will make things confusing for comedic value. + + 'Shuffled except Hints and Keys': Key texts + are not shuffled because in keysanity it is + inconvenient to figure out which keys are which + without the correct text. Similarly, non-shop + items sold in shops will also retain standard + text for the purpose of accurate price checks. + ''' + }), + Setting_Info('difficulty', str, 2, True, + { + 'default': 'normal', + 'const': 'normal', + 'nargs': '?', + 'help': '''\ + Change the item pool for an added challenge. + normal: Default items + hard: Double defense, double magic, and all 8 heart containers are removed. Ammo + for each type can only be expanded once and you can only find three Bombchu packs. + very_hard: Double defense, double magic, Nayru's Love, and all health upgrades are removed. + No ammo expansions are available and you can only find one Bombchu pack. + ohko: Same as very hard, and Link will die in one hit. + ''' + }, + { + 'text': 'Difficulty', + 'group': 'other', + 'widget': 'Combobox', + 'default': 'Normal', + 'options': { + 'Normal': 'normal', + 'Hard': 'hard', + 'Very Hard': 'very_hard', + 'OHKO': 'ohko' + }, + 'tooltip':'''\ + Makes health less available, reduces + ammo expansions, and reduces Bombchus + in the item pool by three. + + 'Hard': Heart Containers, Double Magic, + and Double Defense are removed. Only + one extra Quiver, Bullet Bag, Bomb Bag, + Deku Stick and Deku Nut Capacity Upgrades + will be available. Only three Bombchu + packs are available. + + 'Very Hard': Heart Containers, Pieces of + Heart, Double Magic, Double Defense, + and Nayru's Love are removed. No extra + Quivers, Bullet Bags, Bomb Bags, or + Deku Stick and Deku Nut Capacity Upgrades + will be available. Only one Bombchu + pack is available. + + 'OHKO': Link dies in one hit. + ''' + }), + Setting_Info('default_targeting', str, 1, False, + { + 'default': 'hold', + 'const': 'always', + 'nargs': '?', + 'help': '''\ + Choose what the default Z-targeting is. + ''' + }, + { + 'text': 'Default Targeting Option', + 'group': 'rom_tab', + 'widget': 'Combobox', + 'default': 'Hold', + 'options': { + 'Hold': 'hold', + 'Switch': 'switch', + } + }), + Setting_Info('background_music', str, 2, False, + { + 'default': 'normal', + 'const': 'normal', + 'nargs': '?', + 'help': '''\ + Sets the background music behavior + normal: Areas play their normal background music + off: No background music + random: Areas play random background music + ''' + }, + { + 'text': 'Background Music', + 'group': 'cosmetics', + 'widget': 'Combobox', + 'default': 'Normal', + 'options': { + 'Normal': 'normal', + 'No Music': 'off', + 'Random': 'random', + }, + 'tooltip': '''\ + 'No Music': No background music. + is played. + + 'Random': Area background music is + randomized. + ''' + }), + + Setting_Info('kokiricolor', str, 0, False, + { + 'default': 'Kokiri Green', + 'const': 'Kokiri Green', + 'nargs': '?', + 'type': parse_custom_tunic_color, + 'help': '''\ + Choose the color for Link's Kokiri Tunic. (default: %(default)s) + Color: Make the Kokiri Tunic this color. + Random Choice: Choose a random color from this list of colors. + Completely Random: Choose a random color from any color the N64 can draw. + ''' + }, + { + 'text': 'Kokiri Tunic Color', + 'group': 'tuniccolor', + 'widget': 'Combobox', + 'default': 'Kokiri Green', + 'options': get_tunic_color_options(), + 'tooltip':'''\ + 'Random Choice': Choose a random + color from this list of colors. + 'Completely Random': Choose a random + color from any color the N64 can draw. + ''' + }), + Setting_Info('goroncolor', str, 0, False, + { + 'default': 'Goron Red', + 'const': 'Goron Red', + 'nargs': '?', + 'type': parse_custom_tunic_color, + 'help': '''\ + Choose the color for Link's Goron Tunic. (default: %(default)s) + Color: Make the Goron Tunic this color. + Random Choice: Choose a random color from this list of colors. + Completely Random: Choose a random color from any color the N64 can draw. + ''' + }, + { + 'text': 'Goron Tunic Color', + 'group': 'tuniccolor', + 'widget': 'Combobox', + 'default': 'Goron Red', + 'options': get_tunic_color_options(), + 'tooltip':'''\ + 'Random Choice': Choose a random + color from this list of colors. + 'Completely Random': Choose a random + color from any color the N64 can draw. + ''' + }), + Setting_Info('zoracolor', str, 0, False, + { + 'default': 'Zora Blue', + 'const': 'Zora Blue', + 'nargs': '?', + 'type': parse_custom_tunic_color, + 'help': '''\ + Choose the color for Link's Zora Tunic. (default: %(default)s) + Color: Make the Zora Tunic this color. + Random Choice: Choose a random color from this list of colors. + Completely Random: Choose a random color from any color the N64 can draw. + ''' + }, + { + 'text': 'Zora Tunic Color', + 'group': 'tuniccolor', + 'widget': 'Combobox', + 'default': 'Zora Blue', + 'options': get_tunic_color_options(), + 'tooltip':'''\ + 'Random Choice': Choose a random + color from this list of colors. + 'Completely Random': Choose a random + color from any color the N64 can draw. + ''' + }), + Setting_Info('navicolordefault', str, 0, False, + { + 'default': 'White', + 'const': 'White', + 'nargs': '?', + 'type': parse_custom_navi_color, + 'help': '''\ + Choose the color for Navi when she is idle. (default: %(default)s) + Color: Make the Navi this color. + Random Choice: Choose a random color from this list of colors. + Completely Random: Choose a random color from any color the N64 can draw. + ''' + }, + { + 'text': 'Navi Idle', + 'group': 'navicolor', + 'widget': 'Combobox', + 'default': 'White', + 'options': get_navi_color_options(), + 'tooltip':'''\ + 'Random Choice': Choose a random + color from this list of colors. + 'Completely Random': Choose a random + color from any color the N64 can draw. + ''' + }), + Setting_Info('navicolorenemy', str, 0, False, + { + 'default': 'Yellow', + 'const': 'Yellow', + 'nargs': '?', + 'type': parse_custom_navi_color, + 'help': '''\ + Choose the color for Navi when she is targeting an enemy. (default: %(default)s) + Color: Make the Navi this color. + Random Choice: Choose a random color from this list of colors. + Completely Random: Choose a random color from any color the N64 can draw. + ''' + }, + { + 'text': 'Navi Targeting Enemy', + 'group': 'navicolor', + 'widget': 'Combobox', + 'default': 'Yellow', + 'options': get_navi_color_options(), + 'tooltip':'''\ + 'Random Choice': Choose a random + color from this list of colors. + 'Completely Random': Choose a random + color from any color the N64 can draw. + ''' + }), + Setting_Info('navicolornpc', str, 0, False, + { + 'default': 'Light Blue', + 'const': 'Light Blue', + 'nargs': '?', + 'type': parse_custom_navi_color, + 'help': '''\ + Choose the color for Navi when she is targeting an NPC. (default: %(default)s) + Color: Make the Navi this color. + Random Choice: Choose a random color from this list of colors. + Completely Random: Choose a random color from any color the N64 can draw. + ''' + }, + { + 'text': 'Navi Targeting NPC', + 'group': 'navicolor', + 'widget': 'Combobox', + 'default': 'Light Blue', + 'options': get_navi_color_options(), + 'tooltip':'''\ + 'Random Choice': Choose a random + color from this list of colors. + 'Completely Random': Choose a random + color from any color the N64 can draw. + ''' + }), + Setting_Info('navicolorprop', str, 0, False, + { + 'default': 'Green', + 'const': 'Green', + 'nargs': '?', + 'type': parse_custom_navi_color, + 'help': '''\ + Choose the color for Navi when she is targeting a prop. (default: %(default)s) + Color: Make the Navi this color. + Random Choice: Choose a random color from this list of colors. + Completely Random: Choose a random color from any color the N64 can draw. + ''' + }, + { + 'text': 'Navi Targeting Prop', + 'group': 'navicolor', + 'widget': 'Combobox', + 'default': 'Green', + 'options': get_navi_color_options(), + 'tooltip':'''\ + 'Random Choice': Choose a random + color from this list of colors. + 'Completely Random': Choose a random + color from any color the N64 can draw. + ''' + }), + Setting_Info('navisfxoverworld', str, 0, False, + { + 'default': 'Default', + 'const': 'Default', + 'nargs': '?', + 'help': '''\ + Select the sound effect that plays when Navi has a hint. (default: %(default)s) + Sound: Replace the sound effect with the chosen sound. + Random Choice: Replace the sound effect with a random sound from this list. + None: Eliminate Navi hint sounds. + ''' + }, + { + 'text': 'Navi Hint', + 'group': 'navihint', + 'widget': 'Combobox', + 'default': 'Default', + 'options': get_NaviSFX_options(), + }), + Setting_Info('navisfxenemytarget', str, 0, False, + { + 'default': 'Default', + 'const': 'Default', + 'nargs': '?', + 'help': '''\ + Select the sound effect that plays when targeting an enemy. (default: %(default)s) + Sound: Replace the sound effect with the chosen sound. + Random Choice: Replace the sound effect with a random sound from this list. + None: Eliminate Navi hint sounds. + ''' + }, + { + 'text': 'Navi Enemy Target', + 'group': 'navihint', + 'widget': 'Combobox', + 'default': 'Default', + 'options': get_NaviSFX_options(), + }), + Setting_Info('healthSFX', str, 0, False, + { + 'default': 'Default', + 'const': 'Default', + 'nargs': '?', + 'help': '''\ + Select the sound effect that loops at low health. (default: %(default)s) + Sound: Replace the sound effect with the chosen sound. + Random Choice: Replace the sound effect with a random sound from this list. + None: Eliminate heart beeps. + ''' + }, + { + 'text': 'Low Health SFX', + 'group': 'lowhp', + 'widget': 'Combobox', + 'default': 'Default', + 'options': get_HealthSFX_options(), + 'tooltip':'''\ + 'Random Choice': Choose a random + sound from this list. + 'Default': Beep. Beep. Beep. + ''' + }), +] + +# gets the randomizer settings, whether to open the gui, and the logger level from command line arguments +def get_settings_from_command_line_args(): + parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) + for info in setting_infos: + parser.add_argument("--" + info.name, **info.args_params) + + parser.add_argument('--gui', help='Launch the GUI', action='store_true') + parser.add_argument('--loglevel', default='info', const='info', nargs='?', choices=['error', 'info', 'warning', 'debug'], help='Select level of logging for output.') + parser.add_argument('--settings_string', help='Provide sharable settings using a settings string. This will override all flags that it specifies.') + + args = parser.parse_args() + + result = {} + for info in setting_infos: + result[info.name] = vars(args)[info.name] + settings = Settings(result) + + if args.settings_string is not None: + settings.update_with_settings_string(args.settings_string) + + return settings, args.gui, args.loglevel diff --git a/TextArray.py b/TextArray.py deleted file mode 100644 index 3a5ed5798..000000000 --- a/TextArray.py +++ /dev/null @@ -1,2227 +0,0 @@ -text_array = [0x9257e4, -0x925852, -0x9258ce, -0x925be2, -0x925bfa, -0x925ca0, -0x925ccd, -0x925d0b, -0x925fa4, -0x9272bc, -0x9272da, -0x927354, -0x9273d5, -0x927406, -0x92743c, -0x927474, -0x927476, -0x9274b3, -0x9274b5, -0x9274ea, -0x9274ec, -0x927517, -0x927544, -0x927548, -0x927565, -0x927567, -0x9275d8, -0x9275ed, -0x92763f, -0x927648, -0x927678, -0x9276d8, -0x92772e, -0x927793, -0x92780a, -0x927870, -0x927b7c, -0x927b9e, -0x927c10, -0x927c4b, -0x927c91, -0x927cf1, -0x92c5e8, -0x92c650, -0x92c658, -0x92c6dc, -0x92c75e, -0x92c780, -0x92c798, -0x92c801, -0x92c840, -0x92c8c0, -0x92c904, -0x92c98b, -0x92c9d4, -0x92ca2a, -0x92ca78, -0x92cc24, -0x92cc45, -0x92cc5c, -0x92cc95, -0x92ccd6, -0x92cd24, -0x92cd54, -0x92cd95, -0x92cdd2, -0x92cdfe, -0x92cdff, -0x92ce09, -0x92ce0a, -0x92ce0c, -0x92ce44, -0x92cea2, -0x92cee8, -0x92cf45, -0x92cf70, -0x92cfac, -0x92cfb2, -0x92cff8, -0x92d000, -0x92d022, -0x92d084, -0x92d0c3, -0x92d0f0, -0x92d110, -0x92d178, -0x92d19b, -0x92d1d8, -0x92d217, -0x92d266, -0x92d27c, -0x92d2a5, -0x92d2dc, -0x92d31d, -0x92d344, -0x92d392, -0x92d3a8, -0x92d3c3, -0x92d418, -0x92d457, -0x92d494, -0x92d4d7, -0x92d514, -0x92d553, -0x92d590, -0x92d5d6, -0x92d63d, -0x92d6ba, -0x92d72e, -0x92d7a1, -0x92d809, -0x92d878, -0x92d8f2, -0x92d968, -0x92da2c, -0x92da2d, -0x92da35, -0x92da36, -0x92daad, -0x92db19, -0x92dbfa, -0x92dc87, -0x92dcab, -0x92dd58, -0x92dfb4, -0x92e24c, -0x92e2a2, -0x92e3a9, -0x92e467, -0x92e59c, -0x92e5c2, -0x92e60f, -0x92e690, -0x92e708, -0x92e728, -0x92e775, -0x92e815, -0x92e8ef, -0x92e9c6, -0x92ea60, -0x92ea80, -0x92eacd, -0x92eb04, -0x92eb23, -0x92eb66, -0x92ebcf, -0x92ec38, -0x92ed24, -0x92ed49, -0x92eda8, -0x92edcc, -0x92ee2d, -0x92eeb0, -0x92eed6, -0x92ef94, -0x92efbc, -0x92eff8, -0x92f021, -0x92f058, -0x92f082, -0x92f0bc, -0x92f0e6, -0x92f120, -0x92f149, -0x92f174, -0x92f19e, -0x92f1d4, -0x92f1f4, -0x92f270, -0x92f336, -0x92f3f9, -0x92f462, -0x92f572, -0x92f658, -0x92f761, -0x92f764, -0x92f78b, -0x92f7e0, -0x92f85b, -0x92f905, -0x92f989, -0x92fa73, -0x92fad0, -0x92faf4, -0x92fb48, -0x92fb67, -0x92fbc1, -0x92fc44, -0x92fcc1, -0x92fce0, -0x92fcff, -0x92fd38, -0x92fd58, -0x92fdb1, -0x92fe46, -0x92fe68, -0x92fe99, -0x92fecc, -0x92ff03, -0x92ff44, -0x92ff61, -0x92ff9c, -0x92ffbe, -0x930008, -0x930027, -0x930064, -0x93008a, -0x9300b4, -0x9300db, -0x93013c, -0x9301b4, -0x9301db, -0x930267, -0x9302a8, -0x9302ca, -0x930328, -0x930349, -0x9303a9, -0x930464, -0x93047f, -0x9304af, -0x930530, -0x93059c, -0x9305c1, -0x9306d1, -0x930718, -0x930740, -0x930784, -0x9307a8, -0x930803, -0x930899, -0x9308e6, -0x930929, -0x930a71, -0x930a74, -0x930a93, -0x930af8, -0x930b16, -0x930b75, -0x930bf0, -0x930c10, -0x930c6c, -0x930c9c, -0x930ccc, -0x930d00, -0x930d34, -0x930d68, -0x930d9c, -0x930dc1, -0x930e3b, -0x930ea4, -0x930ed7, -0x930f38, -0x930f6d, -0x930f96, -0x930fcd, -0x930fe4, -0x931009, -0x931068, -0x93108e, -0x9310d0, -0x9310f5, -0x931184, -0x931196, -0x9311ba, -0x9311d8, -0x9311fd, -0x931234, -0x931264, -0x93129a, -0x9312cc, -0x931304, -0x931387, -0x9313b9, -0x9313d0, -0x931422, -0x931424, -0x93147b, -0x93149a, -0x9314c9, -0x9314f8, -0x93152b, -0x931591, -0x9315b8, -0x9315f4, -0x93170c, -0x93172c, -0x931784, -0x9317a0, -0x9317f5, -0x931883, -0x931973, -0x9319dd, -0x931a4c, -0x931ad5, -0x931b52, -0x931bde, -0x931be4, -0x931c05, -0x931c5a, -0x931d3a, -0x931d9c, -0x931da0, -0x931de9, -0x931dec, -0x931e3d, -0x931ec4, -0x931f28, -0x931f92, -0x931fe7, -0x931fec, -0x932007, -0x932054, -0x932072, -0x9320be, -0x932126, -0x93219c, -0x9321b9, -0x932281, -0x932308, -0x932380, -0x9323d1, -0x932490, -0x932510, -0x93252c, -0x9325ad, -0x9325c7, -0x932649, -0x9326bc, -0x9326f1, -0x932737, -0x932747, -0x9327c1, -0x9327e4, -0x932868, -0x9328e8, -0x932968, -0x9329dd, -0x932a5c, -0x932ada, -0x932b35, -0x932bd1, -0x932c06, -0x932c08, -0x932c29, -0x932c7c, -0x932c9d, -0x932d2e, -0x932d43, -0x932d48, -0x932d6c, -0x932d90, -0x932db8, -0x932de0, -0x932e08, -0x932e30, -0x932e5b, -0x932e8a, -0x932e9c, -0x932ec8, -0x932ef5, -0x932f08, -0x932f35, -0x932f66, -0x932ffa, -0x933049, -0x933089, -0x93308b, -0x9330e8, -0x933193, -0x933231, -0x933314, -0x933337, -0x93333c, -0x933363, -0x933368, -0x933389, -0x93338c, -0x933401, -0x933440, -0x9334ac, -0x9334d8, -0x93352c, -0x933590, -0x9335bb, -0x93361f, -0x933624, -0x93366c, -0x9336d4, -0x933793, -0x9337cd, -0x933821, -0x93383e, -0x9338e1, -0x93392b, -0x933997, -0x9339e3, -0x933a15, -0x933a8a, -0x933b1e, -0x933bae, -0x933c3a, -0x933d44, -0x933d8c, -0x933df4, -0x933e40, -0x933eac, -0x933ef8, -0x933f40, -0x933f80, -0x933ffd, -0x93408c, -0x93411c, -0x93418c, -0x93420c, -0x93425c, -0x934314, -0x934343, -0x93437c, -0x9343d0, -0x93444c, -0x93449a, -0x93452c, -0x934570, -0x9345b0, -0x9345e8, -0x934634, -0x934672, -0x934704, -0x93475c, -0x9347b4, -0x934818, -0x934870, -0x9348bc, -0x934908, -0x934980, -0x934a08, -0x934a34, -0x934a8c, -0x934a9c, -0x935ca8, -0x935cd2, -0x935d08, -0x935d30, -0x935d84, -0x935dec, -0x935e3c, -0x935e74, -0x935edc, -0x935f30, -0x935f88, -0x935fbc, -0x935fe4, -0x93602c, -0x93605c, -0x9360b4, -0x9360e8, -0x936108, -0x936188, -0x9361c0, -0x93621c, -0x936260, -0x93628c, -0x936432, -0x9365d6, -0x9365ff, -0x93664f, -0x9366b8, -0x9366e9, -0x9368b7, -0x936a29, -0x936aa7, -0x936b13, -0x936bac, -0x936bb7, -0x936dbd, -0x936e2b, -0x936e8c, -0x936eba, -0x936ef4, -0x936f26, -0x936f5f, -0x936fc4, -0x936ffd, -0x937041, -0x937043, -0x937044, -0x937056, -0x937057, -0x9371b0, -0x9371f5, -0x937237, -0x937296, -0x937318, -0x9373a1, -0x9376cf, -0x937748, -0x937767, -0x937785, -0x9377a1, -0x9377b3, -0x9377f7, -0x93781d, -0x937854, -0x937894, -0x9378b3, -0x9378f1, -0x93791a, -0x937965, -0x9379c8, -0x9379e0, -0x937a2d, -0x937a83, -0x937add, -0x937af5, -0x937b25, -0x937b3c, -0x937b55, -0x937b80, -0x937ba8, -0x937bbd, -0x937c33, -0x937c4c, -0x937cad, -0x937cf6, -0x937d61, -0x937d78, -0x937daf, -0x937dc0, -0x937df9, -0x937e66, -0x937ea4, -0x937efd, -0x937f74, -0x937fd5, -0x938046, -0x93808f, -0x9380e6, -0x93815d, -0x9381b8, -0x938217, -0x93825a, -0x9382a6, -0x9382e0, -0x938322, -0x938376, -0x9383a7, -0x9383e4, -0x938414, -0x93843e, -0x9384a4, -0x938534, -0x9385b5, -0x9385ea, -0x93866f, -0x9386a1, -0x938736, -0x938760, -0x9387a6, -0x9387ea, -0x93881f, -0x938848, -0x93885d, -0x938874, -0x9388e2, -0x938945, -0x9389a0, -0x9389f2, -0x938a6b, -0x938ae1, -0x938b1b, -0x938b56, -0x938bb5, -0x938c18, -0x938c95, -0x938d1d, -0x938d5d, -0x938d73, -0x938dbb, -0x938e2b, -0x9399f5, -0x939a64, -0x939aa9, -0x939ae3, -0x939b1c, -0x939b58, -0x939b8c, -0x939c00, -0x939c78, -0x939cc6, -0x939d2f, -0x939db1, -0x939e00, -0x939e5c, -0x939eaf, -0x939f03, -0x939f78, -0x939fe6, -0x93a019, -0x93a087, -0x93a103, -0x93a148, -0x93a180, -0x93a1b9, -0x93a1ed, -0x93a286, -0x93a2ef, -0x93a338, -0x93a367, -0x93a3aa, -0x93a3da, -0x93a44f, -0x93a4bc, -0x93a4fe, -0x93a56b, -0x93a5af, -0x93a626, -0x93a645, -0x93a688, -0x93a6be, -0x93a729, -0x93a783, -0x93a788, -0x93a7f2, -0x93a851, -0x93a89a, -0x93a8de, -0x93a94c, -0x93a99f, -0x93aa16, -0x93aa8a, -0x93aad3, -0x93ab37, -0x93abab, -0x93ac1d, -0x93ac88, -0x93acb4, -0x93ad12, -0x93ad5f, -0x93ad9c, -0x93ae14, -0x93ae84, -0x93aef8, -0x93af30, -0x93af8d, -0x93afd7, -0x93b01c, -0x93b068, -0x93b0a5, -0x93b0d4, -0x93b106, -0x93b17f, -0x93b1c8, -0x93b215, -0x93b28c, -0x93b31c, -0x93b362, -0x93b3a4, -0x93b3e7, -0x93b44c, -0x93b49b, -0x93b4d3, -0x93b545, -0x93b576, -0x93b59b, -0x93b5fe, -0x93b666, -0x93b6c8, -0x93b97b, -0x93b99c, -0x93b9d4, -0x93b9fc, -0x93ba2d, -0x93ba57, -0x93ba88, -0x93bac2, -0x93baec, -0x93bb19, -0x93bb47, -0x93bb74, -0x93bba2, -0x93bbc6, -0x93bbea, -0x93bc11, -0x93bc38, -0x93bc62, -0x93bc8c, -0x93bcba, -0x93bcbc, -0x93bcee, -0x93bd48, -0x93bd5c, -0x93bd6c, -0x93be60, -0x93be91, -0x93be98, -0x93bed7, -0x93bf01, -0x93c1f4, -0x93c278, -0x93c2b9, -0x93c3a0, -0x93c3cb, -0x93c405, -0x93c558, -0x93c57e, -0x93c5a0, -0x93c5bc, -0x93c5d4, -0x93c5f8, -0x93c630, -0x93c668, -0x93c680, -0x93c6c0, -0x93c760, -0x93c785, -0x93c796, -0x93c7df, -0x93c831, -0x93c8ac, -0x93c8ca, -0x93c998, -0x93c9c6, -0x93c9ee, -0x93cb80, -0x93cb8e, -0x93cba4, -0x93cbd1, -0x93cc5d, -0x93ccb7, -0x93cced, -0x93ce0c, -0x93ce66, -0x93d040, -0x93d184, -0x93d2e9, -0x93d2ec, -0x93d34e, -0x93d3b1, -0x93d3fa, -0x93d424, -0x93d48a, -0x93d4a9, -0x93d4c6, -0x93d503, -0x93d524, -0x93d55f, -0x93d592, -0x93d593, -0x93d594, -0x93d5ac, -0x93d5ad, -0x93d5af, -0x93d5b0, -0x93d5be, -0x93d5bf, -0x93d5c4, -0x93d5e8, -0x93d5e9, -0x93d5ea, -0x93d5fa, -0x93d5fb, -0x93d654, -0x93d6a1, -0x93d73c, -0x93d749, -0x93d74b, -0x93d7f0, -0x93e6c4, -0x93e6df, -0x93e705, -0x93e74a, -0x93e770, -0x93e9b8, -0x93e9fb, -0x93ed0c, -0x93ed5d, -0x93edb9, -0x93ee34, -0x93ee59, -0x93eeac, -0x93ef00, -0x93efd8, -0x93f060, -0x93f08a, -0x93f0e5, -0x93f0f4, -0x93f159, -0x93f1b4, -0x93f1e7, -0x93f247, -0x93f4e0, -0x93f523, -0x93f575, -0x93f5a9, -0x93f5f8, -0x93f609, -0x93f648, -0x93f656, -0x93f6cc, -0x93f740, -0x93f77a, -0x93f7ac, -0x93f7dc, -0x93f849, -0x93f88f, -0x93f8d4, -0x93f934, -0x93f94c, -0x93f95b, -0x93f97a, -0x93f9a3, -0x93f9f9, -0x93fa02, -0x93fa03, -0x93fa1e, -0x93fa1f, -0x93fd1c, -0x93fd48, -0x93fdc5, -0x93fe82, -0x93fecf, -0x93fef3, -0x93ff1a, -0x93ff44, -0x93ff51, -0x93ffaf, -0x93ffbf, -0x940014, -0x940024, -0x940074, -0x9400cb, -0x94012c, -0x940188, -0x9401d7, -0x9402ec, -0x94032b, -0x94035a, -0x9403a0, -0x9403d5, -0x940400, -0x94042f, -0x9404b0, -0x9404d1, -0x94050e, -0x940570, -0x9405b0, -0x9405ec, -0x9405fb, -0x940609, -0x940645, -0x94064c, -0x94065e, -0x940662, -0x9406fc, -0x94074c, -0x940784, -0x9407d6, -0x94081e, -0x940868, -0x9408f9, -0x940943, -0x940999, -0x9409ec, -0x940a2d, -0x940a4c, -0x940a98, -0x940b01, -0x940b5c, -0x940b6f, -0x940b70, -0x940b7c, -0x940b7d, -0x940b9f, -0x940ba1, -0x940bc4, -0x940bf6, -0x940bf8, -0x940c48, -0x940cb6, -0x940cdb, -0x940f7a, -0x940f87, -0x941012, -0x941018, -0x941037, -0x941082, -0x9410d2, -0x941168, -0x9411b0, -0x9411d8, -0x9411ec, -0x9412a4, -0x9412e3, -0x9413d0, -0x941411, -0x941421, -0x941422, -0x941423, -0x94142b, -0x94142c, -0x94144e, -0x94145e, -0x94147d, -0x941535, -0x94156b, -0x9415f4, -0x941612, -0x941644, -0x941758, -0x941804, -0x94184c, -0x9418a0, -0x9418bb, -0x941a28, -0x941a71, -0x941ac8, -0x941ad3, -0x941afe, -0x941b30, -0x941cb8, -0x941d30, -0x941d74, -0x941d98, -0x941dd8, -0x942078, -0x9420d0, -0x9420de, -0x942114, -0x942129, -0x942162, -0x942210, -0x942225, -0x942248, -0x94225b, -0x94227b, -0x94228c, -0x9423b3, -0x9427b8, -0x94280d, -0x94280e, -0x94280f, -0x942818, -0x942819, -0x94281b, -0x942827, -0x94283f, -0x94288f, -0x9428cc, -0x9428fa, -0x942961, -0x9429b1, -0x942a08, -0x942a35, -0x942afc, -0x942e9c, -0x942f04, -0x942f40, -0x942f47, -0x942f9c, -0x943070, -0x9430a1, -0x9430a8, -0x9430c1, -0x9430fe, -0x943210, -0x94326f, -0x9432b7, -0x943306, -0x943349, -0x94334a, -0x94334f, -0x943355, -0x94335a, -0x94335f, -0x943366, -0x943367, -0x943368, -0x943399, -0x94339a, -0x94339f, -0x9433a4, -0x9433a9, -0x9433af, -0x9433b0, -0x9433b1, -0x9434b0, -0x9434c9, -0x94353e, -0x9435b2, -0x9435f5, -0x943634, -0x9436bb, -0x943736, -0x94378a, -0x943802, -0x94382e, -0x9438c0, -0x9438cc, -0x9438dc, -0x9438ff, -0x943904, -0x943907, -0x943908, -0x94390d, -0x943913, -0x943919, -0x94391d, -0x94391e, -0x943964, -0x94397d, -0x9439b0, -0x9439ea, -0x9439ec, -0x943a52, -0x943ae0, -0x943b2f, -0x943c67, -0x943dd8, -0x943e34, -0x944128, -0x944192, -0x9441dc, -0x944228, -0x94428a, -0x9442a2, -0x9442a4, -0x944304, -0x944347, -0x9443a0, -0x9443ea, -0x9448ec, -0x9448fb, -0x9448fd, -0x94496c, -0x94498c, -0x9449bc, -0x9449f4, -0x944a60, -0x944a6f, -0x944a9e, -0x944aac, -0x944b70, -0x944bb4, -0x944bd9, -0x944c25, -0x944c7b, -0x944cd4, -0x944d27, -0x944d28, -0x944d29, -0x944d33, -0x944d34, -0x944d3e, -0x944dec, -0x944e38, -0x944ea0, -0x944eda, -0x944f88, -0x944fd9, -0x94507c, -0x9450fa, -0x945135, -0x945170, -0x945258, -0x945259, -0x945277, -0x945278, -0x9454b4, -0x9454b5, -0x9454cf, -0x9454d0, -0x945508, -0x9455c4, -0x9455ee, -0x94562d, -0x94566f, -0x945ad8, -0x945b1c, -0x945b64, -0x945bd1, -0x945c24, -0x945c96, -0x945cdf, -0x945d4c, -0x945d57, -0x945d6d, -0x945dbb, -0x945ff4, -0x946030, -0x946044, -0x9461d0, -0x9462ca, -0x94631c, -0x946488, -0x946658, -0x946670, -0x946688, -0x946689, -0x94668a, -0x946690, -0x946691, -0x946693, -0x94669d, -0x9466cc, -0x9466db, -0x9467a4, -0x9467d2, -0x946870, -0x946871, -0x946872, -0x94687b, -0x94687c, -0x946882, -0x9468a6, -0x9468d7, -0x946908, -0x946963, -0x94698e, -0x9469cc, -0x946a08, -0x946a35, -0x946a87, -0x946ab8, -0x946b00, -0x946b50, -0x946b7c, -0x946b83, -0x946bec, -0x946c2f, -0x946c96, -0x946cd4, -0x946d1e, -0x947274, -0x9472e2, -0x94735e, -0x947672, -0x94768a, -0x947730, -0x94775d, -0x94779b, -0x947a34, -0x947ab0, -0x947ba4, -0x947bb6, -0x947be5, -0x947c92, -0x947cb2, -0x947cbd, -0x947cec, -0x947cfa, -0x947cfc, -0x947d4d, -0x947d74, -0x947de0, -0x947e45, -0x947f0e, -0x948354, -0x948359, -0x948396, -0x9483a3, -0x9483b7, -0x9483bc, -0x9483ed, -0x948445, -0x94847a, -0x948628, -0x9486a0, -0x9486b9, -0x948728, -0x94876f, -0x948796, -0x94881b, -0x9488bc, -0x9488c2, -0x948914, -0x948974, -0x948997, -0x948a0e, -0x948a93, -0x948ab6, -0x948b64, -0x948b9f, -0x948bca, -0x948c22, -0x948c36, -0x948d4c, -0x948d6a, -0x948de4, -0x948e65, -0x948e96, -0x948ecc, -0x948f04, -0x948f06, -0x948f43, -0x948f45, -0x948f7a, -0x948f7c, -0x948fa7, -0x948fd4, -0x948fd8, -0x948ff5, -0x948ff7, -0x949068, -0x94907d, -0x9490cf, -0x9490d8, -0x949108, -0x949168, -0x9491be, -0x949223, -0x94929a, -0x949300, -0x94960c, -0x94962e, -0x9496a0, -0x9496db, -0x949721, -0x949781, -0x949ce8, -0x949d27, -0x949d42, -0x949d64, -0x949d6b, -0x949d81, -0x949dbe, -0x949ded, -0x949e22, -0x949e47, -0x949e82, -0x949ed0, -0x949ed7, -0x949f22, -0x949f65, -0x94a068, -0x94a0bf, -0x94a0eb, -0x94a122, -0x94a16f, -0x94a1a8, -0x94a1d8, -0x94a228, -0x94a254, -0x94a285, -0x94a2e3, -0x94a32b, -0x94a36c, -0x94a3ae, -0x94a3cf, -0x94a425, -0x94a49c, -0x94a4be, -0x94a4d3, -0x94a4fe, -0x94a542, -0x94a5ab, -0x94a623, -0x94a68c, -0x94a6c5, -0x94a720, -0x94a756, -0x94a798, -0x94a810, -0x94a84c, -0x94a860, -0x94a8c7, -0x94a940, -0x94a9bc, -0x94aa32, -0x94aa8c, -0x94aade, -0x94aae4, -0x94ab09, -0x94abb0, -0x94ac02, -0x94ac49, -0x94ac8c, -0x94ad44, -0x94ad80, -0x94adcd, -0x94adf6, -0x94ae44, -0x94ae9b, -0x94b21c, -0x94b24e, -0x94b276, -0x94b2c4, -0x94b440, -0x94b4a8, -0x94b4c0, -0x94b4f2, -0x94b671, -0x94b6a5, -0x94b6fd, -0x94b704, -0x94b76e, -0x94b7f1, -0x94b85f, -0x94b8e3, -0x94bbd0, -0x94bc18, -0x94bc63, -0x94bcbb, -0x94bce8, -0x94bd0f, -0x94bd8d, -0x94bdd4, -0x94be0c, -0x94be7c, -0x94be9b, -0x94bf15, -0x94bf74, -0x94bf9b, -0x94c020, -0x94c047, -0x94c0a4, -0x94c0cb, -0x94c13e, -0x94c180, -0x94c1a7, -0x94c1eb, -0x94c240, -0x94c260, -0x94c320, -0x94c3a0, -0x94c3e4, -0x94c45c, -0x94c475, -0x94c4cc, -0x94c50c, -0x94c542, -0x94c57a, -0x94c604, -0x94c680, -0x94c6d2, -0x94c788, -0x94c791, -0x94c7e2, -0x94c847, -0x94c849, -0x94c86b, -0x94c870, -0x94c87e, -0x94c8af, -0x94c9b4, -0x94cca4, -0x94ce04, -0x94ce21, -0x94ce4d, -0x94ce87, -0x94cf58, -0x94cf94, -0x94cfe7, -0x94d04d, -0x94d124, -0x94d131, -0x94d180, -0x94d1c0, -0x94d2e9, -0x94d2eb, -0x94d38c, -0x94d3bd, -0x94d404, -0x94d452, -0x94d4c2, -0x94d538, -0x94d61e, -0x94d635, -0x94d638, -0x94d67c, -0x94d6db, -0x94d71a, -0x94d770, -0x94d860, -0x94d874, -0x94d88d, -0x94d89f, -0x94d8a1, -0x94d8d4, -0x94d8e5, -0x94d8f1, -0x94d904, -0x94d90c, -0x94d912, -0x94d962, -0x94d964, -0x94d99e, -0x94d9f8, -0x94da44, -0x94dacf, -0x94dadd, -0x94dadf, -0x94db38, -0x94db54, -0x94dd0c, -0x94dd67, -0x94ddb1, -0x94de14, -0x94de21, -0x94de88, -0x94ded4, -0x94df17, -0x94df85, -0x94dfe9, -0x94e078, -0x94e0e0, -0x94e0e8, -0x94e16c, -0x94e1ee, -0x94e210, -0x94e228, -0x94e291, -0x94e2d0, -0x94e350, -0x94e394, -0x94e41b, -0x94e464, -0x94e4ba, -0x94e508, -0x94e6b4, -0x94e6d5, -0x94e6ec, -0x94e725, -0x94e766, -0x94e7b4, -0x94e7e4, -0x94e825, -0x94e862, -0x94e88e, -0x94e88f, -0x94e899, -0x94e89a, -0x94e89c, -0x94e8d4, -0x94e932, -0x94e978, -0x94e9d5, -0x94ea00, -0x94ea3c, -0x94ea42, -0x94ea88, -0x94ead8, -0x94eb10, -0x94eb2c, -0x94eb37, -0x94ebbc, -0x94ebec, -0x94ec38, -0x94ecb0, -0x94ecb4, -0x94ecf3, -0x94ed2d, -0x94ed54, -0x94ede0, -0x94edf4, -0x94ee1b, -0x94ee23, -0x94ee62, -0x94ee6d, -0x94ee8e, -0x94eeb5, -0x94eed2, -0x94eef2, -0x94ef01, -0x94ef03, -0x94ef43, -0x94ef52, -0x94ef54, -0x94ef8f, -0x94efe1, -0x94f00b, -0x94f048, -0x94f097, -0x94f0a3, -0x94f0b6, -0x94f0c5, -0x94f0c8, -0x94f0e7, -0x94f117, -0x94f120, -0x94f18b, -0x94f1e4, -0x94f1f0, -0x94f23c, -0x94f269, -0x94f26b, -0x94f26c, -0x94f270, -0x94f271, -0x94f288, -0x94f2c2, -0x94f2f9, -0x94f358, -0x94f3f8, -0x94f4a0, -0x94f4b8, -0x94f4f4, -0x94f522, -0x94f57c, -0x94f5c8, -0x94f600, -0x94f614, -0x94f652, -0x94f6a9, -0x94f72c, -0x94f730, -0x94f7c0, -0x94f850, -0x94f8e8, -0x94f960, -0x94fa04, -0x94fab4, -0x94fb4c, -0x94fbe0, -0x94fc8c, -0x9501ac, -0x950b16, -0x950d6e, -0x950dae, -0x950dc9, -0x950e80, -0x950eb5, -0x950f09, -0x950f4b, -0x950f67, -0x950f82, -0x95157c, -0x951f93, -0x952185, -0x952280, -0x952282, -0x952283, -0x952288, -0x952291, -0x952298, -0x952299, -0x95229a, -0x95241b, -0x9524d2, -0x9524f1, -0x952511, -0x9525cc, -0x952611, -0x952613, -0x952637, -0x952639, -0x952665, -0x952667, -0x9526ec, -0x9526f0, -0x95271d, -0x952804, -0x95280e, -0x95280f, -0x952814, -0x95281d, -0x952825, -0x952826, -0x952827, -0x952836, -0x952838, -0x952870, -0x9528b5, -0x952bb0, -0x952bba, -0x952bbc, -0x952bbd, -0x952bc2, -0x952bc9, -0x952bcd, -0x952bd4, -0x952bd5, -0x952bd6, -0x952be9, -0x952c19, -0x952c86, -0x952ce7, -0x952d12, -0x952d5f, -0x952db3, -0x952df4, -0x952dfe, -0x952e00, -0x952e01, -0x952e06, -0x952e0d, -0x952e11, -0x952e18, -0x952e19, -0x952e1a, -0x952e2d, -0x952e58, -0x9531a0, -0x9531aa, -0x9531d0, -0x95321f, -0x953259, -0x95329c, -0x953360, -0x953370, -0x9533c4, -0x95342f, -0x95349c, -0x95350a, -0x953543, -0x95355e, -0x953560, -0x9535be, -0x9535c4, -0x95360e, -0x953688, -0x9536b0, -0x9536be, -0x95373b, -0x953783, -0x9537c4, -0x95382b, -0x95389a, -0x953917, -0x953952, -0x9539a6, -0x9539d8, -0x953a30, -0x953ac0, -0x953b2e, -0x953b81, -0x953bea, -0x953c38, -0x953d68, -0x953da8, -0x953dfb, -0x953e58, -0x953ea9, -0x953ef8, -0x953f76, -0x953fc3, -0x95406c, -0x954090, -0x954104, -0x954154, -0x9541ac, -0x954210, -0x954490, -0x9544b0, -0x9544c0, -0x9544f0, -0x954730, -0x95478d, -0x954860, -0x9548d1, -0x954938, -0x95496c, -0x9549a1, -0x9549d7, -0x954a10, -0x954bac, -0x954bfe, -0x954c59, -0x954ccb, -0x954fdb, -0x954fdc, -0x954fe2, -0x954fe3, -0x95503c, -0x955099, -0x9552f0, -0x95536c, -0x9553e2, -0x9553ee, -0x955437, -0x95548c, -0x9554ff, -0x955568, -0x9555dd, -0x9555e9, -0x95562a, -0x955682, -0x9556cc, -0x955727, -0x955733, -0x95580c, -0x95584a, -0x95590c, -0x955a20, -0x955a70, -0x955ad4, -0x955b4f, -0x955bb8, -0x955c90, -0x955cd5, -0x955d34, -0x9560b0, -0x9560c3, -0x956159, -0x9561c2, -0x9563f4, -0x956448, -0x956c94, -0x956ede, -0x956f4a, -0x956f4c, -0x956faa, -0x95702d, -0x957077, -0x9570ce, -0x957121, -0x957177, -0x957290, -0x9572b0, -0x957322, -0x957361, -0x9573a0, -0x9573e2, -0x9573e3, -0x9573eb, -0x9573f2, -0x9573f7, -0x9573f8, -0x9573fa, -0x957400, -0x95740d, -0x95742b, -0x95744e, -0x95746d, -0x9574f8, -0x957512, -0x957577, -0x9575ab, -0x957618, -0x9577b0, -0x95798a, -0x95798c, -0x95799a, -0x9579de, -0x957b70, -0x957c90, -0x957d60, -0x957da9, -0x957e40, -0x957e7b, -0x957eb8, -0x957edc, -0x957ee5, -0x957f10, -0x957f6f, -0x957f88, -0x957fce, -0x958021, -0x95809d, -0x958111, -0x958137, -0x95813c, -0x95816c, -0x95818a, -0x9581d0, -0x95823f, -0x95828c, -0x95830f, -0x958355, -0x95839e, -0x95841c, -0x95842a, -0x958514, -0x958534, -0x958564, -0x95858c, -0x9585e4, -0x958624, -0x95863c, -0x958664, -0x958690, -0x9586ac, -0x9586e8, -0x958744, -0x9587a0, -0x9587d4, -0x9587ec, -0x9588bc, -0x958920, -0x958934, -0x958943, -0x95895a, -0x9589af, -0x958a07, -0x958a4d, -0x958a84, -0x958a8c, -0x958aa8, -0x958af9, -0x958b04, -0x958b11, -0x958b20, -0x958b34, -0x958b50, -0x958b56, -0x958b70, -0x9592da, -0x9592fd, -0x959350, -0x95937d, -0x959392, -0x9593ad, -0x9593d4, -0x9593ed, -0x959408, -0x95942b, -0x959453, -0x959469, -0x959475, -0x959483, -0x95948e, -0x9594a1, -0x9594a8, -0x9594fd, -0x959575, -0x9595b0, -0x959608, -0x95965b, -0x9596a5, -0x95972c, -0x95976c, -0x9597d2, -0x9597d4, -0x959818, -0x95987d, -0x9598f0, -0x95997f, -0x959ad0, -0x959be4, -0x959df8, -0x959e47, -0x959e7b, -0x95a024, -0x95a042, -0x95a141, -0x95a537, -0x95a538, -0x95a545, -0x95a546, -0x95a5b8, -0x95a5e1, -0x95a62d, -0x95a697, -0x95a7f4, -0x95a828, -0x95a88a, -0x95a8b5, -0x95a90c, -0x95aa59, -0x95aa5a, -0x95aa64, -0x95aa65, -0x95ab99, -0x95ab9a, -0x95aba4, -0x95aba5, -0x95ac6b, -0x95ac70, -0x95ac71, -0x95ac7a, -0x95ac83, -0x95ac8c, -0x95ac8d, -0x95ac8e, -0x95ad65, -0x95b15c, -0x95b16b, -0x95b1eb, -0x95b1f0, -0x95b21f, -0x95b264, -0x95b2a5, -0x95b2fe, -0x95b33a, -0x95b3af, -0x95b3d7, -0x95b3d8, -0x95b3df, -0x95b3ea, -0x95b3f2, -0x95b3f7, -0x95b3fc, -0x95b408, -0x95b409, -0x95b428, -0x95b452, -0x95b4b2, -0x95b4fc, -0x95b608, -0x95ba74, -0x95ba9f, -0x95bb8c, -0x95bbb1, -0x95bbca, -0x95bbe4, -0x95bc9b, -0x95bce4, -0x95bcf4, -0x95bcf6, -0x95bd3c, -0x95bd46, -0x95bd48, -0x95bd78, -0x95bde0, -0x95be9c, -0x95beba, -0x95bf78, -0x95bf90, -0x95c028, -0x95c1b0, -0x95c1e1, -0x95c219, -0x95c26d, -0x95c2bf, -0x95c39c, -0x95c3af, -0x95c450, -0x95c466, -0x95c468, -0x95c49c, -0x95c4ba, -0x95c4ec, -0x95c552, -0x95c59a, -0x95c5d1, -0x95c621, -0x95c624, -0x95c62a, -0x95c633, -0x95c638, -0x95c648, -0x95c700, -0x95c774, -0x95c794, -0x95c7fb, -0x95c84f, -0x95c8bd, -0x95c93e, -0x95cb5c, -0x95cb6c, -0x95cb7e, -0x95cb8c, -0x95cbc4, -0x95cbec, -0x95ce2c, -0x95d164, -0x95d16c, -0x95d194, -0x95d1c1, -0x95d226, -0x95d26c, -0x95d2ed, -0x95d374, -0x95d3a4, -0x95d3e4, -0x95d42c, -0x95d48f, -0x95d4c8, -0x95d502, -0x95d5f0, -0x95d602, -0x95d63f, -0x95d69a, -0x95d705, -0x95d784, -0x95d7cb, -0x95d7eb, -0x95d807, -0x95d828, -0x95d85c, -0x95d8af, -0x95d8d8, -0x95d926, -0x95d955, -0x95d9bc, -0x95da15, -0x95da77, -0x95dadc, -0x95db0c, -0x95db94, -0x95dbb1, -0x95dbd0, -0x95dbee, -0x95dc17, -0x95dc40, -0x95dcb5, -0x95dd4c, -0x95dd8c, -0x95ddb0, -0x95ddc8, -0x95de03, -0x95de5c, -0x95de98, -0x95df10, -0x95df9d, -0x95e016, -0x95e0a8, -0x95e126, -0x95e1ac, -0x95e200, -0x95e288, -0x95e309, -0x95e34c, -0x95e38c, -0x95e3c5, -0x95e40c, -0x95e43c, -0x95e500, -0x95e575, -0x95e5a4, -0x95e5c8, -0x95e5f0, -0x95e630, -0x95e664, -0x95e690, -0x95e6e9, -0x95e747, -0x95e828, -0x95e868, -0x95e8d0, -0x95e8e1, -0x95e922, -0x95e964, -0x95e97c, -0x95ea58, -0x95eaad, -0x95eae2, -0x95eb2f, -0x95eb7c, -0x95ebc3, -0x95ebea, -0x95ec70, -0x95eca0, -0x95ed1c, -0x95ed94, -0x95ee06, -0x95ee6c, -0x95eec0, -0x95ef12, -0x95ef8c, -0x95efd5, -0x95f030, -0x95f098, -0x95f118, -0x95f1a4, -0x95f1e8, -0x95f248, -0x95f2d1, -0x95f34e, -0x95f3b0, -0x95f404, -0x95f45c, -0x95f4d4, -0x95f531, -0x95f59e, -0x95f5c4, -0x95f620, -0x95f668, -0x95f6c4, -0x95f71d, -0x95f7ae, -0x95f890, -0x95f8f4, -0x95f934, -0x95f9ab, -0x95f9fc, -0x95fafe, -0x95fb04, -0x95fb5b, -0x95fbb2, -0x95fbf3, -0x95fc4a, -0x95fc76, -0x95fc90, -0x95fcca, -0x95fd2c, -0x95fd49, -0x95fd7f, -0x95fdc8, -0x95fe0c, -0x95fe2a, -0x95fe68, -0x95fe89, -0x95feb8, -0x95fee1, -0x95ff36, -0x95ff3d, -0x9601b6, -0x96020f, -0x9604c1, -0x960733, -0x96075d, -0x9607dc, -0x96080f, -0x960864, -0x9608b6, -0x9608c8, -0x9609ed, -0x960b14, -0x960b4f, -0x960b8b, -0x960bd2, -0x960c15, -0x960c4e, -0x960c8a, -0x960cd1, -0x960d10, -0x960d62, -0x960dc6, -0x960e28, -0x960e82, -0x960eb3, -0x960ef0, -0x960f2c, -0x960f67, -0x960fa3, -0x960fde, -0x961018, -0x961056, -0x9611ec, -0x961238, -0x961289, -0x9612c0, -0x961300, -0x961324, -0x96134c, -0x96139e, -0x9613b4, -0x9613ec, -0x9613f4, -0x961410, -0x961468, -0x961499, -0x961508, -0x96151c, -0x961540, -0x961580, -0x961598, -0x9615f3, -0x9615f8, -0x961623, -0x961628, -0x961684, -0x96169c, -0x9616a0, -0x9616a1, -0x9616a2, -0x9616a9, -0x9616aa, -0x9616b0, -0x9616b1, -0x9616b2, -0x9616c6, -0x9616c7, -0x9616db, -0x9616dc, -0x9616e0, -0x9616f0, -0x9616f4, -0x96171e, -0x961754, -0x96178c, -0x96178d, -0x961794, -0x961795, -0x96195d, -0x961960, -0x961c54, -0x961ca0, -0x961cc9, -0x961d06, -0x961d5d, -0x961d8c, -0x961deb, -0x961e1d, -0x961e9f, -0x961f80, -0x961f9e, -0x961f9f, -0x961fa0, -0x961fa9, -0x961faa, -0x961fac, -0x961fb5, -0x961fd4, -0x961ffd, -0x962008, -0x962026, -0x96202e, -0x962058, -0x9620ae, -0x9620f0, -0x962105, -0x962128, -0x962158, -0x96218b, -0x9621f6, -0x962252, -0x962284, -0x962296, -0x962297, -0x962298, -0x96229c, -0x9622a3, -0x9622a7, -0x9622a8, -0x9622b8, -0x9622bc, -0x9622e8, -0x96236c, -0x9623c7, -0x962428, -0x96248c, -0x9624d6, -0x962500, -0x962512, -0x962564, -0x962662, -0x962753, -0x962812, -0x9629c3, -0x962cf8, -0x962d42, -0x962d61, -0x96508a, -0x9650b8, -0x9602EB] diff --git a/TextBox.py b/TextBox.py new file mode 100644 index 000000000..6d994b109 --- /dev/null +++ b/TextBox.py @@ -0,0 +1,276 @@ +import Messages + +# Least common multiple of all possible character widths. A line wrap must occur when the combined widths of all of the +# characters on a line reach this value. +LINE_WIDTH = 1801800 + +# Attempting to display more lines in a single text box will cause additional lines to bleed past the bottom of the box. +LINES_PER_BOX = 4 + +# Attempting to display more characters in a single text box will cause buffer overflows. First, visual artifacts will +# appear in lower areas of the text box. Eventually, the text box will become uncloseable. +MAX_CHARACTERS_PER_BOX = 200 + +LINE_BREAK = '&' +BOX_BREAK = '^' + + +def lineWrap(text): + boxes = text.split(BOX_BREAK) + boxesWithWrappedLines = [] + + for box in boxes: + forcedLines = box.split(LINE_BREAK) + lines = [line.strip() for forcedLine in forcedLines for line in _wrapLines(forcedLine)] + wrapped = LINE_BREAK.join(lines) + + if len(lines) > LINES_PER_BOX: + print('Wrapped text exceeds maximum lines per text box. Original text:\n' + box) + + # Subtracting line count so that line breaks aren't counted as characters + if len(wrapped) - (len(lines) - 1) > MAX_CHARACTERS_PER_BOX: + print('Text length exceeds maximum characters per text box. Original text:\n' + box) + + boxesWithWrappedLines.append(wrapped) + + return BOX_BREAK.join(boxesWithWrappedLines) + + +def _wrapLines(text): + lines = [] + currentLine = [] + currentWidth = 0 + + for word in text.split(' '): + currentLinePlusWord = currentLine.copy() + currentLinePlusWord.append(word) + currentLinePlusWordWidth = _calculateWidth(currentLinePlusWord) + + if (currentLinePlusWordWidth <= LINE_WIDTH): + currentLine = currentLinePlusWord + currentWidth = currentLinePlusWordWidth + else: + lines.append(' '.join(currentLine)) + currentLine = [word] + currentWidth = _calculateWidth(currentLine) + + lines.append(' '.join(currentLine)) + + return lines + + +def _calculateWidth(words): + wordsWidth = 0 + for word in words: + index = 0 + while index < len(word): + character = word[index] + index += 1 + if ord(character) in Messages.CONTROL_CODES: + index += Messages.CONTROL_CODES[ord(character)][1] + else: + wordsWidth += _getCharacterWidth(character) + spacesWidth = _getCharacterWidth(' ') * (len(words) - 1) + + return wordsWidth + spacesWidth + + +def _getCharacterWidth(character): + try: + return characterTable[character] + except KeyError: + # Control character for color settings; does not affect the width + if character == '#': + return 0 + # Control character for displaying the player's name; assume greater than average width + elif character == '@': + return characterTable['M'] * 8 + # A sane default with the most common character width + else : + return characterTable[' '] + + +# Tediously measured by filling a full line of a gossip stone's text box with one character until it is reasonably full +# (with a right margin) and counting how many characters fit. OoT does not appear to use any kerning, but, if it does, +# it will only make the characters more space-efficient, so this is an underestimate of the number of letters per line, +# at worst. This ensures that we will never bleed text out of the text box while line wrapping. +# Larger numbers in the denominator mean more of that character fits on a line; conversely, larger values in this table +# mean the character is wider and can't fit as many on one line. +characterTable = { + 'a': 51480, # LINE_WIDTH / 35 + 'b': 51480, # LINE_WIDTH / 35 + 'c': 51480, # LINE_WIDTH / 35 + 'd': 51480, # LINE_WIDTH / 35 + 'e': 51480, # LINE_WIDTH / 35 + 'f': 34650, # LINE_WIDTH / 52 + 'g': 51480, # LINE_WIDTH / 35 + 'h': 51480, # LINE_WIDTH / 35 + 'i': 25740, # LINE_WIDTH / 70 + 'j': 34650, # LINE_WIDTH / 52 + 'k': 51480, # LINE_WIDTH / 35 + 'l': 25740, # LINE_WIDTH / 70 + 'm': 81900, # LINE_WIDTH / 22 + 'n': 51480, # LINE_WIDTH / 35 + 'o': 51480, # LINE_WIDTH / 35 + 'p': 51480, # LINE_WIDTH / 35 + 'q': 51480, # LINE_WIDTH / 35 + 'r': 42900, # LINE_WIDTH / 42 + 's': 51480, # LINE_WIDTH / 35 + 't': 42900, # LINE_WIDTH / 42 + 'u': 51480, # LINE_WIDTH / 35 + 'v': 51480, # LINE_WIDTH / 35 + 'w': 81900, # LINE_WIDTH / 22 + 'x': 51480, # LINE_WIDTH / 35 + 'y': 51480, # LINE_WIDTH / 35 + 'z': 51480, # LINE_WIDTH / 35 + 'A': 81900, # LINE_WIDTH / 22 + 'B': 51480, # LINE_WIDTH / 35 + 'C': 72072, # LINE_WIDTH / 25 + 'D': 72072, # LINE_WIDTH / 25 + 'E': 51480, # LINE_WIDTH / 35 + 'F': 51480, # LINE_WIDTH / 35 + 'G': 81900, # LINE_WIDTH / 22 + 'H': 60060, # LINE_WIDTH / 30 + 'I': 25740, # LINE_WIDTH / 70 + 'J': 51480, # LINE_WIDTH / 35 + 'K': 60060, # LINE_WIDTH / 30 + 'L': 51480, # LINE_WIDTH / 35 + 'M': 81900, # LINE_WIDTH / 22 + 'N': 72072, # LINE_WIDTH / 25 + 'O': 81900, # LINE_WIDTH / 22 + 'P': 51480, # LINE_WIDTH / 35 + 'Q': 81900, # LINE_WIDTH / 22 + 'R': 60060, # LINE_WIDTH / 30 + 'S': 60060, # LINE_WIDTH / 30 + 'T': 51480, # LINE_WIDTH / 35 + 'U': 60060, # LINE_WIDTH / 30 + 'V': 72072, # LINE_WIDTH / 25 + 'W': 100100, # LINE_WIDTH / 18 + 'X': 72072, # LINE_WIDTH / 25 + 'Y': 60060, # LINE_WIDTH / 30 + 'Z': 60060, # LINE_WIDTH / 30 + ' ': 51480, # LINE_WIDTH / 35 + '1': 25740, # LINE_WIDTH / 70 + '2': 51480, # LINE_WIDTH / 35 + '3': 51480, # LINE_WIDTH / 35 + '4': 60060, # LINE_WIDTH / 30 + '5': 51480, # LINE_WIDTH / 35 + '6': 51480, # LINE_WIDTH / 35 + '7': 51480, # LINE_WIDTH / 35 + '8': 51480, # LINE_WIDTH / 35 + '9': 51480, # LINE_WIDTH / 35 + '0': 60060, # LINE_WIDTH / 30 + '!': 51480, # LINE_WIDTH / 35 + '?': 72072, # LINE_WIDTH / 25 + '\'': 17325, # LINE_WIDTH / 104 + '"': 34650, # LINE_WIDTH / 52 + '.': 25740, # LINE_WIDTH / 70 + ',': 25740, # LINE_WIDTH / 70 + '/': 51480, # LINE_WIDTH / 35 + '-': 34650, # LINE_WIDTH / 52 + '_': 51480, # LINE_WIDTH / 35 + '(': 42900, # LINE_WIDTH / 42 + ')': 42900, # LINE_WIDTH / 42 + '$': 51480 # LINE_WIDTH / 35 +} + +# To run tests, enter the following into a python3 REPL: +# >>> from TextBox import test_lineWrapTests +# >>> test_lineWrapTests() +def test_lineWrapTests(): + test_wrapSimpleLine() + test_honorForcedLineWraps() + test_honorBoxBreaks() + test_honorControlCharacters() + test_honorPlayerName() + test_maintainMultipleForcedBreaks() + test_trimWhitespace() + test_supportLongWords() + + +def test_wrapSimpleLine(): + words = 'Hello World! Hello World! Hello World!' + expected = 'Hello World! Hello World! Hello&World!' + result = lineWrap(words) + + if result != expected: + print('"Wrap Simple Line" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Wrap Simple Line" test passed!') + + +def test_honorForcedLineWraps(): + words = 'Hello World! Hello World!&Hello World! Hello World! Hello World!' + expected = 'Hello World! Hello World!&Hello World! Hello World! Hello&World!' + result = lineWrap(words) + + if result != expected: + print('"Honor Forced Line Wraps" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Honor Forced Line Wraps" test passed!') + + +def test_honorBoxBreaks(): + words = 'Hello World! Hello World!^Hello World! Hello World! Hello World!' + expected = 'Hello World! Hello World!^Hello World! Hello World! Hello&World!' + result = lineWrap(words) + + if result != expected: + print('"Honor Box Breaks" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Honor Box Breaks" test passed!') + + +def test_honorControlCharacters(): + words = 'Hello World! #Hello# World! Hello World!' + expected = 'Hello World! #Hello# World! Hello&World!' + result = lineWrap(words) + + if result != expected: + print('"Honor Control Characters" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Honor Control Characters" test passed!') + + +def test_honorPlayerName(): + words = 'Hello @! Hello World! Hello World!' + expected = 'Hello @! Hello World!&Hello World!' + result = lineWrap(words) + + if result != expected: + print('"Honor Player Name" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Honor Player Name" test passed!') + + +def test_maintainMultipleForcedBreaks(): + words = 'Hello World!&&&Hello World!' + expected = 'Hello World!&&&Hello World!' + result = lineWrap(words) + + if result != expected: + print('"Maintain Multiple Forced Breaks" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Maintain Multiple Forced Breaks" test passed!') + + +def test_trimWhitespace(): + words = 'Hello World! & Hello World!' + expected = 'Hello World!&Hello World!' + result = lineWrap(words) + + if result != expected: + print('"Trim Whitespace" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Trim Whitespace" test passed!') + + +def test_supportLongWords(): + words = 'Hello World! WWWWWWWWWWWWWWWWWWWW Hello World!' + expected = 'Hello World!&WWWWWWWWWWWWWWWWWWWW&Hello World!' + result = lineWrap(words) + + if result != expected: + print('"Support Long Words" test failed: Got ' + result + ', wanted ' + expected) + else: + print('"Support Long Words" test passed!') diff --git a/Utils.py b/Utils.py index e31664740..201503325 100644 --- a/Utils.py +++ b/Utils.py @@ -1,61 +1,56 @@ -import os +import os, os.path import subprocess import sys +import urllib.request +from urllib.error import URLError, HTTPError +import re +from version import __version__ +import random +import itertools +import bisect +import logging def is_bundled(): return getattr(sys, 'frozen', False) -def local_path(path): +def local_path(path=''): if local_path.cached_path is not None: return os.path.join(local_path.cached_path, path) if is_bundled(): # we are running in a bundle - local_path.cached_path = sys._MEIPASS # pylint: disable=protected-access,no-member + local_path.cached_path = os.path.dirname(os.path.realpath(sys.executable)) else: # we are running in a normal Python environment - local_path.cached_path = os.path.dirname(os.path.abspath(__file__)) + local_path.cached_path = os.path.dirname(os.path.realpath(__file__)) return os.path.join(local_path.cached_path, path) local_path.cached_path = None -def output_path(path): - if output_path.cached_path is not None: - return os.path.join(output_path.cached_path, path) - if not is_bundled(): - output_path.cached_path = '.' - return os.path.join(output_path.cached_path, path) - else: - # has been packaged, so cannot use CWD for output. - if sys.platform == 'win32': - #windows - import ctypes.wintypes - CSIDL_PERSONAL = 5 # My Documents - SHGFP_TYPE_CURRENT = 0 # Get current, not default value - - buf = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH) - ctypes.windll.shell32.SHGetFolderPathW(None, CSIDL_PERSONAL, None, SHGFP_TYPE_CURRENT, buf) - - documents = buf.value - - elif sys.platform == 'darwin': - from AppKit import NSSearchPathForDirectoriesInDomains # pylint: disable=import-error - # http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSSearchPathForDirectoriesInDomains - NSDocumentDirectory = 9 - NSUserDomainMask = 1 - # True for expanding the tilde into a fully qualified path - documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, True)[0] - else: - raise NotImplementedError('Not supported yet') - - output_path.cached_path = os.path.join(documents, 'OoTRandomizer') - if not os.path.exists(output_path.cached_path): - os.mkdir(output_path.cached_path) - return os.path.join(output_path.cached_path, path) - -output_path.cached_path = None +def data_path(path=''): + if data_path.cached_path is not None: + return os.path.join(data_path.cached_path, path) + + # Even if it's bundled we use __file__ + # if it's not bundled, then we want to use the source.py dir + Data + # if it's bundled, then we want to use the extraction dir + Data + data_path.cached_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data") + + return os.path.join(data_path.cached_path, path) + +data_path.cached_path = None + + +def default_output_path(path): + if path == '': + path = local_path('Output') + + if not os.path.exists(path): + os.mkdir(path) + return path + def open_file(filename): if sys.platform == 'win32': @@ -67,8 +62,97 @@ def open_file(filename): def close_console(): if sys.platform == 'win32': #windows - import ctypes.wintypes + import win32gui, win32con try: - ctypes.windll.kernel32.FreeConsole() + win32gui.ShowWindow(win32gui.GetForegroundWindow(), win32con.SW_HIDE) except Exception: pass + +def compare_version(a, b): + if not a and not b: + return 0 + elif a and not b: + return 1 + elif not a and b: + return -1 + + sa = a.replace(' ', '.').split('.') + sb = b.replace(' ', '.').split('.') + + for i in range(0,3): + if int(sa[i]) > int(sb[i]): + return 1 + if int(sa[i]) < int(sb[i]): + return -1 + return 0 + +class VersionError(Exception): + pass + +def check_version(checked_version): + if compare_version(checked_version, __version__) < 0: + try: + with urllib.request.urlopen('http://raw.githubusercontent.com/TestRunnerSRL/OoT-Randomizer/Dev/version.py') as versionurl: + version = versionurl.read() + version = re.search(".__version__ = '(.+)'", str(version)).group(1) + + if compare_version(version, __version__) > 0: + raise VersionError("You do not seem to be on the latest version!\nYou are on version " + __version__ + ", and the latest is version " + version + ".") + except (URLError, HTTPError) as e: + logger = logging.getLogger('') + logger.warning("Could not fetch latest version: " + str(e)) + +# Shim for the sole purpose of maintaining compatibility with older versions of Python 3. +def random_choices(population, weights=None, k=1): + pop_size = len(population) + if (weights is None): + weights = [1] * pop_size + else: + assert (pop_size == len(weights)), "population and weights mismatch" + + CDF = list(itertools.accumulate(weights)) + + result = [] + for i in range(k): + x = random.random() * CDF[-1] + result.append(population[bisect.bisect(CDF, x)]) + + return result + + +# From the pyinstaller Wiki: https://github.com/pyinstaller/pyinstaller/wiki/Recipe-subprocess +# Create a set of arguments which make a ``subprocess.Popen`` (and +# variants) call work with or without Pyinstaller, ``--noconsole`` or +# not, on Windows and Linux. Typical use:: +# subprocess.call(['program_to_run', 'arg_1'], **subprocess_args()) +def subprocess_args(include_stdout=True): + # The following is true only on Windows. + if hasattr(subprocess, 'STARTUPINFO'): + # On Windows, subprocess calls will pop up a command window by default + # when run from Pyinstaller with the ``--noconsole`` option. Avoid this + # distraction. + si = subprocess.STARTUPINFO() + si.dwFlags |= subprocess.STARTF_USESHOWWINDOW + # Windows doesn't search the path by default. Pass it an environment so + # it will. + env = os.environ + else: + si = None + env = None + + # ``subprocess.check_output`` doesn't allow specifying ``stdout``:: + # So, add it only if it's needed. + if include_stdout: + ret = {'stdout': subprocess.PIPE} + else: + ret = {} + + # On Windows, running this from the binary produced by Pyinstaller + # with the ``--noconsole`` option requires redirecting everything + # (stdin, stdout, stderr) to avoid an OSError exception + # "[Error 6] the handle is invalid." + ret.update({'stdin': subprocess.PIPE, + 'stderr': subprocess.PIPE, + 'startupinfo': si, + 'env': env }) + return ret diff --git a/data/ER16.gif b/data/ER16.gif index ceb4a8588..f4a954cb5 100644 Binary files a/data/ER16.gif and b/data/ER16.gif differ diff --git a/data/ER32.gif b/data/ER32.gif index 3847e6700..1a8dd9b6c 100644 Binary files a/data/ER32.gif and b/data/ER32.gif differ diff --git a/data/ER48.gif b/data/ER48.gif index f34cfb4d0..664c4c55c 100644 Binary files a/data/ER48.gif and b/data/ER48.gif differ diff --git a/data/base2current.json b/data/base2current.json deleted file mode 100644 index 2a621add8..000000000 --- a/data/base2current.json +++ /dev/null @@ -1 +0,0 @@ -[{"9083985": [0, 0, 0]}, {"9083989": [0, 0, 0, 0, 0, 0]}, {"9083996": [0, 0, 0, 0]}, {"9084004": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084048": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084060": [0, 0, 0, 0, 0]}, {"9084067": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084112": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084124": [0, 0, 0, 0, 0]}, {"9084131": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084176": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084188": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084240": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084252": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084304": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084316": [0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084326": [0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084368": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084380": [0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084390": [0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084432": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084444": [0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084454": [0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084496": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084560": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084624": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084643": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084688": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084707": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084752": [0, 0, 0, 0]}, {"9084757": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"9084772": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"11111472": [12, 16, 10, 20]}, {"11325064": [12, 16, 10, 236, 0, 0, 0, 0, 0, 0]}, {"11325076": [0]}, {"11325079": [0, 0, 0]}, {"11325083": [0]}, {"11426272": [8, 16, 11, 63]}, {"11427312": [12, 16, 11, 232]}, {"11881272": [12, 16, 11, 248]}, {"11882076": [12, 16, 11, 213]}, {"12250476": [0, 0]}, {"12250479": [0]}, {"12285876": [0, 0]}, {"12285879": [0]}, {"12286096": [12, 16, 11, 30, 0, 0]}, {"12286103": [0]}, {"12286288": [12, 16, 11, 37, 0, 0]}, {"12286295": [0]}, {"12286880": [0, 0]}, {"12286883": [0]}, {"12286972": [0, 0]}, {"12286975": [0]}, {"12287036": [12, 16, 11, 44, 0, 0]}, {"12287043": [0]}, {"12287064": [12, 16, 11, 23, 0, 0]}, {"12287071": [0]}, {"12381372": [8, 16, 9, 228]}, {"12381377": [0, 0, 0, 0, 0]}, {"12381383": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"12381395": [0]}, {"12427425": [16, 9, 177]}, {"12427480": [12, 16, 9, 206]}, {"12427492": [0, 0]}, {"12427495": [0]}, {"12427876": [12, 16, 9, 210]}, {"12427888": [0, 0]}, {"12427891": [0]}, {"12428008": [36, 10, 255, 255]}, {"12474768": [12, 16, 10, 244, 0, 0, 0, 0]}, {"12491456": [12, 16, 9, 240]}, {"12491480": [12, 16, 9, 249]}, {"12491492": [0, 0]}, {"12491742": [131, 131]}, {"13144796": [52, 14, 0, 1]}, {"13144860": [52, 10, 0, 1]}, {"13145925": [16, 10, 193]}, {"13146216": [146, 14, 29, 40]}, {"13146276": [146, 25, 29, 41]}, {"13146312": [146, 10, 29, 42]}, {"13330528": [12, 16, 11, 51]}, {"14357459": [118]}, {"14624335": [118]}, {"14872723": [52]}, {"15506663": [122]}, {"55055360": [90, 93, 92, 94, 81, 82, 83]}, {"55058464": [255, 255, 255, 255, 255, 255, 255, 255, 128, 64, 37, 196, 128, 64, 36, 72, 255, 255, 255, 255, 255, 255, 255, 255, 128, 64, 37, 196, 128, 64, 36, 100, 255, 255, 255, 255, 255, 255, 255, 255, 128, 64, 37, 196, 128, 64, 36, 140, 255, 255, 255, 255, 255, 255, 255, 255, 128, 64, 37, 196, 128, 64, 36, 180, 255, 255, 255, 255, 255, 255, 255, 255, 128, 64, 37, 196, 128, 64, 36, 220, 255, 255, 255, 255, 255, 255, 255, 255, 128, 64, 37, 196, 128, 64, 37, 4, 255, 255, 255, 255, 255, 255, 255, 255, 128, 64, 37, 196, 128, 64, 37, 32, 255, 255, 255, 255, 255, 255, 255, 255, 128, 64, 37, 196, 128, 64, 37, 60, 255, 255, 255, 255, 255, 255, 255, 255, 128, 64, 37, 196, 128, 64, 37, 88, 83, 65, 1, 67]}, {"55058613": [198, 21, 255, 128, 64, 37, 220, 128, 64, 36, 64, 83, 65, 1, 68]}, {"55058629": [198, 22, 255, 128, 64, 37, 220, 128, 64, 36, 64, 83, 65, 1, 69]}, {"55058645": [198, 23, 255, 128, 64, 37, 220, 128, 64, 36, 64, 83, 65, 1, 70]}, {"55058661": [198, 24, 255, 128, 64, 37, 220, 128, 64, 36, 64, 83, 65, 1, 71]}, {"55058677": [198, 25, 255, 128, 64, 37, 220, 128, 64, 36, 64, 83, 65, 1, 93]}, {"55058693": [198, 28, 255, 128, 64, 37, 220, 128, 64, 36, 64, 83, 65, 1, 122]}, {"55058709": [198, 29, 255, 128, 64, 37, 220, 128, 64, 36, 64, 83, 65, 1, 249]}, {"55058725": [198, 30, 255, 128, 64, 37, 220, 128, 64, 36, 64, 83, 65, 1, 151]}, {"55058741": [198, 32, 255, 128, 64, 37, 220, 128, 64, 36, 64, 83, 65, 10, 199]}, {"55058757": [185, 1, 3, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 10, 199]}, {"55058773": [185, 1, 4, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 10, 199]}, {"55058789": [185, 1, 5, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 10, 199]}, {"55058805": [185, 1, 6, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 10, 199]}, {"55058821": [185, 1, 7, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 10, 199]}, {"55058837": [185, 1, 10, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 11, 103]}, {"55058853": [184, 2]}, {"55058856": [128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 11, 103]}, {"55058869": [184, 2, 1, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 11, 103]}, {"55058885": [184, 2, 2, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 11, 103]}, {"55058901": [184, 2, 3, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 11, 103]}, {"55058917": [184, 2, 4, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 11, 103]}, {"55058933": [184, 2, 5, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 11, 103]}, {"55058949": [184, 2, 6, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 11, 103]}, {"55058965": [184, 2, 7, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 11, 103]}, {"55058981": [184, 2, 8, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 11, 103]}, {"55058997": [184, 2, 9, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 28, 102]}, {"55059013": [200, 4]}, {"55059016": [128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 28, 102]}, {"55059029": [200, 4, 1, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 28, 102]}, {"55059045": [200, 4, 2, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 28, 102]}, {"55059061": [200, 4, 3, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 28, 102]}, {"55059077": [200, 4, 4, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 28, 102]}, {"55059093": [200, 4, 5, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 28, 102]}, {"55059109": [200, 4, 6, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 28, 102]}, {"55059125": [200, 4, 7, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 28, 102]}, {"55059141": [200, 4, 8, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 28, 102]}, {"55059157": [200, 4, 9, 128, 64, 38, 24, 128, 64, 36, 64, 83, 65, 254, 96]}, {"55059173": [170, 3, 255, 128, 64, 38, 52, 128, 64, 36, 64, 83, 65, 254, 96]}, {"55059189": [170, 4, 255, 128, 64, 38, 52, 128, 64, 36, 64, 83, 65, 254, 96]}, {"55059205": [170, 5, 255, 128, 64, 38, 52, 128, 64, 36, 64, 83, 65, 254, 96]}, {"55059221": [170, 6, 255, 128, 64, 38, 52, 128, 64, 36, 64, 83, 65, 254, 96]}, {"55059237": [170, 7, 255, 128, 64, 38, 52, 128, 64, 36, 64, 83, 65, 254, 96]}, {"55059253": [170, 8, 255, 128, 64, 38, 52, 128, 64, 36, 64, 83, 65, 254, 96]}, {"55059269": [170, 11, 255, 128, 64, 38, 52, 128, 64, 36, 64, 83, 65, 254, 96]}, {"55059285": [170, 12, 255, 128, 64, 38, 52, 128, 64, 36, 64, 83, 65, 254, 96]}, {"55059301": [170, 13, 255, 128, 64, 38, 52, 128, 64, 36, 64, 83, 61, 67, 12]}, {"55059317": [248, 255, 255, 128, 64, 37, 204, 128, 64, 36, 64, 77, 131, 9, 85]}, {"55059333": [183, 255, 255, 128, 64, 37, 196, 128, 64, 36, 64, 83, 146, 219, 230]}, {"55059349": [216, 255, 255, 128, 64, 37, 196, 128, 64, 37, 140, 83, 147, 218, 230]}, {"55059365": [216, 255, 255, 128, 64, 37, 196, 128, 64, 37, 140, 83, 148, 217, 230]}, {"55059381": [216, 255, 255, 128, 64, 37, 196, 128, 64, 37, 140, 83, 142, 224, 50]}, {"55059397": [206, 255, 255, 128, 64, 37, 196, 128, 64, 37, 168, 83, 143, 224, 50]}, {"55059413": [206, 255, 255, 128, 64, 37, 196, 128, 64, 37, 168, 83, 144, 224, 50]}, {"55059429": [206, 255, 255, 128, 64, 37, 196, 128, 64, 37, 168, 83, 140, 238, 52]}, {"55059445": [187, 255, 255, 128, 64, 37, 196, 128, 64, 36, 64, 83, 141, 238, 52]}, {"55059461": [187, 255, 255, 128, 64, 37, 196, 128, 64, 36, 64, 79, 65, 19, 233]}, {"55059477": [189, 255, 255, 128, 64, 38, 92, 128, 64, 36, 64, 79, 65, 226, 228]}, {"55059493": [205, 255, 255, 128, 64, 38, 124, 128, 64, 37, 116, 79, 65, 225, 232]}, {"55059509": [205, 255, 255, 128, 64, 38, 156, 128, 64, 36, 64, 3, 224]}, {"55059523": [8, 52, 162]}, {"55059528": [144, 136]}, {"55059531": [125, 52, 1]}, {"55059535": [255, 17, 1]}, {"55059539": [2, 52, 2]}, {"55059543": [8, 52, 2]}, {"55059547": [9, 3, 224]}, {"55059551": [8]}, {"55059556": [144, 136]}, {"55059559": [163, 49, 8]}, {"55059563": [192, 17]}, {"55059567": [5, 52, 2]}, {"55059571": [84, 52, 1]}, {"55059575": [64, 17, 1]}, {"55059579": [2, 52, 2]}, {"55059583": [53, 52, 2]}, {"55059587": [54, 3, 224]}, {"55059591": [8]}, {"55059596": [144, 136]}, {"55059599": [163, 49, 8]}, {"55059603": [24, 17]}, {"55059607": [5, 52, 2]}, {"55059611": [50, 52, 1]}, {"55059615": [8, 17, 1]}, {"55059619": [2, 52, 2]}, {"55059623": [51, 52, 2]}, {"55059627": [52, 3, 224]}, {"55059631": [8]}, {"55059636": [144, 136]}, {"55059639": [163, 49, 8]}, {"55059643": [3, 17]}, {"55059647": [5, 52, 2]}, {"55059651": [4, 52, 1]}, {"55059655": [1, 17, 1]}, {"55059659": [2, 52, 2]}, {"55059663": [48, 52, 2]}, {"55059667": [49, 3, 224]}, {"55059671": [8]}, {"55059676": [144, 136]}, {"55059679": [162, 49, 8]}, {"55059683": [192, 17]}, {"55059687": [5, 52, 2]}, {"55059691": [5, 52, 1]}, {"55059695": [64, 17, 1]}, {"55059699": [2, 52, 2]}, {"55059703": [96, 52, 2]}, {"55059707": [123, 3, 224]}, {"55059711": [8]}, {"55059716": [144, 136]}, {"55059719": [162, 49, 8]}, {"55059723": [48, 17]}, {"55059727": [2, 52, 2]}, {"55059731": [69, 52, 2]}, {"55059735": [70, 3, 224]}, {"55059739": [8]}, {"55059744": [144, 136]}, {"55059747": [162, 49, 8]}, {"55059751": [6, 17]}, {"55059755": [2, 52, 2]}, {"55059759": [55, 52, 2]}, {"55059763": [56, 3, 224]}, {"55059767": [8]}, {"55059772": [144, 136]}, {"55059775": [161, 49, 8]}, {"55059779": [32, 17]}, {"55059783": [2, 52, 2]}, {"55059787": [121, 52, 2]}, {"55059791": [122, 3, 224]}, {"55059795": [8]}, {"55059800": [144, 136]}, {"55059803": [161, 49, 8]}, {"55059807": [4, 17]}, {"55059811": [2, 52, 2]}, {"55059815": [119, 52, 2]}, {"55059819": [120, 3, 224]}, {"55059823": [8]}, {"55059828": [144, 136]}, {"55059831": [50, 17]}, {"55059835": [2, 52, 2]}, {"55059839": [192, 52, 2]}, {"55059843": [193, 3, 224]}, {"55059847": [8]}, {"55059852": [144, 136]}, {"55059855": [163, 49, 8]}, {"55059859": [3, 17]}, {"55059863": [2, 52, 2]}, {"55059867": [77, 52, 162]}, {"55059872": [3, 224]}, {"55059875": [8]}, {"55059880": [144, 136]}, {"55059883": [163, 49, 8]}, {"55059887": [24, 17]}, {"55059891": [2, 52, 2]}, {"55059895": [77, 52, 162]}, {"55059900": [3, 224]}, {"55059903": [8]}, {"55059908": [3, 224]}, {"55059911": [8]}, {"55059916": [52, 8]}, {"55059919": [1, 160, 136]}, {"55059923": [62, 3, 224]}, {"55059927": [8]}, {"55059932": [36, 136]}, {"55059935": [134, 36, 9, 255, 255, 37, 41]}, {"55059943": [1, 52, 1]}, {"55059947": [3]}, {"55059949": [41, 8, 42, 20, 32]}, {"55059955": [7]}, {"55059960": [1, 9, 80, 33, 145, 75]}, {"55059968": [52, 1]}, {"55059971": [255, 21, 97, 255, 247]}, {"55059980": [161, 69]}, {"55059984": [3, 224]}, {"55059987": [8]}, {"55059992": [36, 136]}, {"55059995": [168, 1, 6, 64, 33, 145, 9]}, {"55060004": [1, 37, 72, 37, 161, 9]}, {"55060012": [3, 224]}, {"55060015": [8]}, {"55060020": [36, 136]}, {"55060023": [188, 1, 5, 64, 33, 129, 9]}, {"55060032": [5, 33]}, {"55060035": [2]}, {"55060040": [52, 9]}, {"55060044": [37, 41]}, {"55060047": [1, 161, 9]}, {"55060052": [3, 224]}, {"55060055": [8]}, {"55060060": [52, 8]}, {"55060063": [1, 160, 136]}, {"55060067": [61, 52, 8]}, {"55060071": [20, 160, 136]}, {"55060075": [207, 52, 8, 1, 64, 164, 136, 20, 36, 3, 224]}, {"55060087": [8]}, {"55060092": [52, 8]}, {"55060095": [1, 160, 136]}, {"55060099": [50, 160, 136]}, {"55060103": [58, 52, 8]}, {"55060107": [48, 164, 136, 19, 244, 160, 136]}, {"55060115": [51, 3, 224]}, {"55060119": [8]}, {"55060124": [52, 8]}, {"55060127": [2, 160, 136]}, {"55060131": [50, 52, 8]}, {"55060135": [1, 160, 136]}, {"55060139": [58, 160, 136]}, {"55060143": [60, 52, 8]}, {"55060147": [96, 164, 136, 19, 244, 160, 136]}, {"55060155": [51, 3, 224]}, {"55060159": [8]}, {"55060164": [48, 132]}, {"55060167": [255, 60, 8, 128, 18, 37, 8, 165, 208, 52, 1]}, {"55060179": [140, 16, 129]}, {"55060183": [22, 145, 2]}, {"55060187": [117, 52, 1]}, {"55060191": [141, 16, 129]}, {"55060195": [19, 145, 2]}, {"55060199": [117, 16, 128]}, {"55060203": [17, 145, 2]}, {"55060207": [116, 52, 1]}, {"55060211": [138, 16, 129]}, {"55060215": [14, 145, 2]}, {"55060219": [116, 52, 1]}, {"55060223": [139, 16, 129]}, {"55060227": [11, 145, 2]}, {"55060231": [116, 52, 1]}, {"55060235": [88, 16, 129]}, {"55060239": [8, 52, 2]}, {"55060244": [52, 1]}, {"55060247": [120, 16, 129]}, {"55060251": [5, 52, 2]}, {"55060256": [52, 1]}, {"55060259": [121, 16, 129]}, {"55060263": [2, 52, 2]}, {"55060268": [52, 2]}, {"55060271": [255, 3, 224]}, {"55060275": [8]}, {"55060280": [143, 166]}, {"55060283": [48, 132, 197]}, {"55060287": [4, 8, 16, 9, 214]}, {"55060296": [143, 185]}, {"55060299": [44, 135, 37]}, {"55060303": [4, 8, 16, 9, 214]}, {"55060312": [60, 10, 128, 64, 37, 74, 32]}, {"55060320": [141, 75]}, {"55060323": [12, 17, 96]}, {"55060327": [2]}, {"55060332": [149, 69]}, {"55060335": [4, 60, 10, 128, 64, 37, 74, 32, 16, 161, 64]}, {"55060348": [60, 10, 128, 30, 37, 74, 137, 132, 165, 64]}, {"55060360": [3, 224]}, {"55060363": [8]}, {"55060368": [60, 8, 128, 64, 37, 8, 32]}, {"55060376": [141, 9]}, {"55060379": [12, 17, 32]}, {"55060383": [2]}, {"55060388": [129, 3]}, {"55060391": [2]}, {"55060393": [3, 15, 195]}, {"55060397": [97, 64, 38, 1, 1, 64, 35, 160, 136, 8, 82, 3, 224]}, {"55060411": [8]}, {"55060416": [144, 69]}, {"55060419": [3, 60, 8, 128, 64, 37, 8, 32]}, {"55060428": [141, 9]}, {"55060431": [12, 17, 32]}, {"55060435": [2]}, {"55060440": [145, 5]}, {"55060443": [3, 3, 224]}, {"55060447": [8]}, {"55060452": [143, 162]}, {"55060455": [36, 144, 69]}, {"55060460": [60, 8, 128, 64, 37, 8, 32]}, {"55060468": [141, 9]}, {"55060471": [12, 17, 32]}, {"55060475": [19]}, {"55060480": [145, 5]}, {"55060483": [1, 175, 164]}, {"55060488": [175, 165]}, {"55060491": [4, 175, 166]}, {"55060495": [8, 39, 189, 255, 232, 175, 191]}, {"55060503": [16, 60, 4, 128, 18, 36, 132, 165, 208, 145, 5]}, {"55060515": [6, 145, 6]}, {"55060519": [7, 141, 9]}, {"55060523": [8, 1, 32, 248, 9]}, {"55060532": [143, 191]}, {"55060535": [16, 39, 189]}, {"55060539": [24, 143, 164]}, {"55060544": [143, 165]}, {"55060547": [4, 143, 166]}, {"55060551": [8, 3, 224]}, {"55060555": [8]}, {"55060560": [160, 230, 4, 36, 39, 189, 255, 224, 175, 162]}, {"55060571": [16, 175, 163]}, {"55060575": [20, 175, 191]}, {"55060579": [24, 12, 16, 10, 33]}, {"55060588": [143, 162]}, {"55060591": [16, 143, 163]}, {"55060595": [20, 143, 191]}, {"55060599": [24, 39, 189]}, {"55060603": [32, 3, 224]}, {"55060607": [8]}, {"55060612": [39, 189, 255, 232, 175, 191]}, {"55060619": [16, 60, 8, 128, 64, 37, 8, 32]}, {"55060628": [173]}, {"55060632": [173]}, {"55060635": [4, 173]}, {"55060639": [8, 173]}, {"55060643": [12, 60, 8, 128, 30, 37, 8, 170, 48, 129, 9, 4, 36, 17, 32]}, {"55060659": [42]}, {"55060665": [9, 15, 195, 1, 33, 32, 38]}, {"55060673": [129, 32, 35, 141, 5, 4, 40, 12, 16, 10, 91]}, {"55060688": [4, 64]}, {"55060691": [34]}, {"55060696": [52, 68]}, {"55060700": [12, 16, 10, 160]}, {"55060708": [16, 96]}, {"55060711": [12]}, {"55060716": [60, 8, 128, 64, 37, 8, 32]}, {"55060724": [140, 105]}, {"55060728": [173, 9]}, {"55060732": [140, 105]}, {"55060735": [4, 173, 9]}, {"55060739": [4, 140, 105]}, {"55060743": [8, 173, 9]}, {"55060747": [8, 52, 9]}, {"55060751": [1, 173, 9]}, {"55060755": [12, 144, 98]}, {"55060760": [60, 8, 128, 30, 37, 8, 170, 48, 141, 9, 4, 40, 149, 42]}, {"55060776": [52, 1]}, {"55060779": [10, 21, 65]}, {"55060783": [6]}, {"55060788": [149, 42]}, {"55060791": [28, 49, 74, 240, 31]}, {"55060797": [2, 89, 64, 1, 75, 80, 37, 165, 42]}, {"55060807": [28, 129, 9, 4, 36, 5, 33]}, {"55060815": [2]}, {"55060821": [2, 16, 35, 161, 2, 4, 36, 143, 191]}, {"55060831": [16, 39, 189]}, {"55060835": [24, 3, 224]}, {"55060839": [8]}, {"55060844": [39, 189, 255, 232, 175, 191]}, {"55060851": [16, 12, 16, 10, 105]}, {"55060860": [36, 1, 255, 255, 16, 65]}, {"55060867": [4]}, {"55060872": [52, 68]}, {"55060876": [12, 16, 10, 147]}, {"55060884": [143, 191]}, {"55060887": [16, 39, 189]}, {"55060891": [24, 3, 224]}, {"55060895": [8]}, {"55060900": [60, 2, 128, 29, 36, 66, 132, 160, 148, 66]}, {"55060911": [164, 52, 8]}, {"55060916": [52, 137]}, {"55060920": [148, 170]}, {"55060924": [52, 1]}, {"55060927": [10, 21, 65]}, {"55060931": [14]}, {"55060936": [148, 171]}, {"55060939": [28, 52, 1]}, {"55060943": [16, 20, 65]}, {"55060947": [8]}, {"55060952": [49, 108, 15, 224, 52, 1, 14, 160, 21, 129]}, {"55060963": [4]}, {"55060968": [36, 2, 255, 255, 16]}, {"55060975": [21]}, {"55060980": [52, 8]}, {"55060983": [1, 49, 105]}, {"55060987": [31, 52, 1]}, {"55060991": [21, 21, 65]}, {"55060995": [12]}, {"55061000": [52, 1]}, {"55061003": [62, 16, 129]}, {"55061007": [7]}, {"55061012": [52, 1]}, {"55061015": [66, 16, 129]}, {"55061019": [4]}, {"55061024": [36, 2, 255, 255, 16]}, {"55061031": [7]}, {"55061036": [52, 8]}, {"55061039": [2, 144, 169, 1, 65]}, {"55061045": [2, 18]}, {"55061049": [72, 16, 37]}, {"55061053": [2, 18]}, {"55061057": [73, 16, 37, 3, 224]}, {"55061063": [8]}, {"55061068": [36, 2, 255, 255, 60, 8, 128, 64, 37, 8, 15, 252, 37, 8]}, {"55061083": [4, 141, 9]}, {"55061088": [17, 32]}, {"55061091": [5]}, {"55061097": [9, 82, 2, 21, 68, 255, 250]}, {"55061108": [49, 34]}, {"55061111": [255, 3, 224]}, {"55061115": [8]}, {"55061120": [39, 189, 255, 224, 175, 176]}, {"55061127": [16, 175, 177]}, {"55061131": [20, 175, 191]}, {"55061135": [24, 52, 130]}, {"55061140": [52, 80]}, {"55061144": [38, 8, 255, 128, 5]}, {"55061151": [18]}, {"55061156": [60, 17, 128, 64, 38, 49, 32, 32, 52, 9]}, {"55061167": [16, 1, 9]}, {"55061171": [24]}, {"55061174": [64, 18, 2, 40, 136, 33, 60, 4, 128, 18, 36, 132, 165, 208, 54, 5]}, {"55061192": [142, 40]}, {"55061195": [12, 1]}, {"55061198": [248, 9]}, {"55061204": [20, 80, 255, 239]}, {"55061212": [54, 35]}, {"55061216": [16]}, {"55061219": [2]}, {"55061224": [52, 3]}, {"55061228": [143, 176]}, {"55061231": [16, 143, 177]}, {"55061235": [20, 143, 191]}, {"55061239": [24, 39, 189]}, {"55061243": [32, 3, 224]}, {"55061247": [8]}, {"55061252": [140, 136, 29, 44, 52, 9]}, {"55061259": [1]}, {"55061261": [9, 78]}, {"55061264": [1, 9, 16, 36, 16, 64]}, {"55061271": [36]}, {"55061276": [148, 202, 2, 220, 60, 11, 128, 18, 37, 107, 165, 208, 148, 140]}, {"55061291": [164, 52, 1]}, {"55061295": [61, 17, 129]}, {"55061299": [10]}, {"55061305": [138, 96, 33, 145, 141, 29, 40, 21, 160]}, {"55061315": [25]}, {"55061320": [52, 13]}, {"55061323": [1, 161, 141, 29, 40, 37, 74]}, {"55061331": [3, 16]}, {"55061335": [9]}, {"55061340": [52, 12]}, {"55061343": [1, 1, 76, 96, 4, 145, 109, 14, 242, 1, 172, 112, 36, 21, 192]}, {"55061359": [14]}, {"55061364": [1, 172, 112, 37, 161, 110, 14, 242, 1, 41, 72, 39, 1, 9, 64, 36, 172, 136, 29, 44, 60, 8, 128, 64, 37, 8, 20, 1, 1, 10, 64, 33, 129, 8]}, {"55061400": [60, 9, 128, 64, 37, 41, 32, 16, 161, 40]}, {"55061412": [52, 2]}, {"55061416": [3, 224]}, {"55061419": [8]}, {"55061424": [60, 8, 128, 64, 37, 8, 20]}, {"55061432": [129, 8]}, {"55061436": [60, 9, 128, 64, 37, 41, 32, 16, 161, 40]}, {"55061448": [3, 224]}, {"55061451": [8]}, {"55061456": [175, 164]}, {"55061459": [104, 175, 165]}, {"55061463": [108, 175, 166]}, {"55061467": [112, 175, 167]}, {"55061471": [116, 39, 189, 255, 232, 175, 163]}, {"55061479": [16, 175, 191]}, {"55061483": [20, 60, 8, 128, 64, 37, 8, 32, 16, 129, 8]}, {"55061496": [17]}, {"55061499": [14]}, {"55061504": [60, 9, 128, 30, 37, 41, 137, 132, 52, 10]}, {"55061515": [1, 165, 42]}, {"55061520": [60, 9, 128, 65, 52, 10]}, {"55061527": [1, 173, 42, 1, 48, 60, 10, 128, 30, 37, 74, 170, 48, 161, 72, 4, 36, 173, 73, 4, 40, 12, 16, 10, 33]}, {"55061556": [143, 163]}, {"55061559": [16, 143, 191]}, {"55061563": [20, 39, 189]}, {"55061567": [24, 143, 164]}, {"55061571": [104, 143, 165]}, {"55061575": [108, 143, 166]}, {"55061579": [112, 143, 167]}, {"55061583": [116, 132, 110, 19, 196, 3, 224]}, {"55061591": [8]}, {"55061596": [147, 25]}, {"55061599": [116, 52, 1]}, {"55061603": [255, 23, 33]}, {"55061607": [2]}, {"55061612": [52, 25]}, {"55061615": [44, 3, 224]}, {"55061619": [8, 167, 185]}, {"55061623": [154, 147, 44]}, {"55061627": [116, 52, 1]}, {"55061631": [255, 21, 129]}, {"55061635": [2]}, {"55061640": [52, 12]}, {"55061643": [44, 3, 224]}, {"55061647": [8]}, {"55061652": [145, 174]}, {"55061655": [116, 52, 1]}, {"55061659": [255, 21, 193]}, {"55061663": [2]}, {"55061668": [52, 14]}, {"55061671": [44, 3, 224]}, {"55061675": [8, 167, 174]}, {"55061679": [154, 145, 207]}, {"55061683": [116, 52, 1]}, {"55061687": [255, 21, 225]}, {"55061691": [2]}, {"55061696": [52, 15]}, {"55061699": [44, 3, 224]}, {"55061703": [8, 167, 175]}, {"55061707": [154, 60, 8, 128, 64, 37, 8, 32, 20, 142, 9]}, {"55061719": [104, 173, 9]}, {"55061724": [142, 9]}, {"55061727": [108, 173, 9]}, {"55061731": [4, 150, 9]}, {"55061735": [112, 165, 9]}, {"55061739": [8, 150, 9]}, {"55061743": [156, 165, 9]}, {"55061747": [10, 3, 224]}, {"55061751": [8, 142, 14]}, {"55061755": [4, 39, 189, 255, 224, 175, 176]}, {"55061763": [16, 175, 177]}, {"55061767": [20, 175, 191]}, {"55061771": [24, 60, 16, 128, 18, 38, 16, 165, 208, 60, 17, 128, 64, 38, 49, 32, 20, 142, 8]}, {"55061791": [4, 17]}, {"55061795": [5]}, {"55061800": [12, 16, 11, 105]}, {"55061808": [16]}, {"55061811": [3]}, {"55061816": [12, 16, 11, 124]}, {"55061824": [12, 16, 11, 92, 52, 4]}, {"55061832": [12, 16, 11, 92, 52, 4]}, {"55061839": [1, 12, 16, 11, 92, 52, 4]}, {"55061847": [2, 143, 176]}, {"55061851": [16, 143, 177]}, {"55061855": [20, 143, 191]}, {"55061859": [24, 39, 189]}, {"55061863": [32, 3, 224]}, {"55061867": [8]}, {"55061872": [2, 4, 64, 33, 145, 9]}, {"55061879": [108, 52, 1]}, {"55061883": [255, 17, 33]}, {"55061887": [7]}, {"55061892": [2, 9, 72, 33, 145, 41]}, {"55061899": [116, 52, 1]}, {"55061903": [44, 17, 33]}, {"55061907": [2]}, {"55061912": [161, 9]}, {"55061915": [105, 3, 224]}, {"55061919": [8]}, {"55061924": [39, 189, 255, 232, 175, 191]}, {"55061931": [16, 142, 40]}, {"55061936": [174, 8]}, {"55061939": [64, 142, 40]}, {"55061943": [4, 174, 8]}, {"55061947": [68, 150, 40]}, {"55061951": [8, 166, 8]}, {"55061955": [72, 162]}, {"55061958": [15, 51, 146, 8]}, {"55061963": [74, 52, 1]}, {"55061967": [255, 21, 1]}, {"55061971": [3]}, {"55061976": [12, 16, 11, 138]}, {"55061984": [143, 191]}, {"55061987": [16, 39, 189]}, {"55061991": [24, 3, 224]}, {"55061995": [8]}, {"55062000": [142, 8]}, {"55062003": [64, 174, 8]}, {"55062007": [104, 142, 8]}, {"55062011": [68, 174, 8]}, {"55062015": [108, 150, 8]}, {"55062019": [72, 166, 8]}, {"55062023": [112, 146, 8]}, {"55062027": [104, 52, 1]}, {"55062031": [255, 21, 1]}, {"55062035": [3]}, {"55062040": [52, 8]}, {"55062043": [1, 162, 8, 15, 51, 3, 224]}, {"55062051": [8]}, {"55062056": [39, 189, 255, 232, 175, 191]}, {"55062063": [16, 150, 8]}, {"55062067": [156, 49, 8]}, {"55062071": [64, 17]}, {"55062075": [5]}, {"55062080": [150, 8]}, {"55062083": [112, 49, 8, 255, 15, 53, 8]}, {"55062091": [48, 166, 8]}, {"55062095": [112, 146, 40]}, {"55062099": [1, 162, 8]}, {"55062103": [105, 150, 40]}, {"55062107": [2, 166, 8]}, {"55062111": [106, 142, 40]}, {"55062115": [4, 174, 8]}, {"55062119": [108, 12, 16, 11, 164, 52, 4]}, {"55062128": [12, 16, 11, 164, 52, 4]}, {"55062135": [1, 12, 16, 11, 164, 52, 4]}, {"55062143": [2, 143, 191]}, {"55062147": [16, 39, 189]}, {"55062151": [24, 3, 224]}, {"55062155": [8]}, {"55062160": [2, 4, 64, 33, 60, 9, 128, 64, 37, 41, 47, 60, 145, 10]}, {"55062175": [108, 52, 1]}, {"55062179": [255, 17, 65]}, {"55062183": [5]}, {"55062188": [1, 42, 72, 33, 145, 41]}, {"55062196": [21, 32]}, {"55062199": [28]}, {"55062204": [60, 9, 128, 64, 37, 41, 47, 47, 37, 41]}, {"55062215": [1, 145, 42]}, {"55062220": [17, 64]}, {"55062223": [19]}, {"55062228": [2, 10, 88, 33, 145, 107]}, {"55062235": [116, 52, 1]}, {"55062239": [255, 17, 97, 255, 248]}, {"55062248": [146, 12]}, {"55062251": [108, 17, 138, 255, 245]}, {"55062260": [146, 12]}, {"55062263": [109, 17, 138, 255, 242]}, {"55062272": [146, 12]}, {"55062275": [110, 17, 138, 255, 239]}, {"55062284": [161, 11]}, {"55062287": [105, 161, 10]}, {"55062291": [108, 16]}, {"55062295": [4]}, {"55062300": [52, 9]}, {"55062303": [255, 161, 9]}, {"55062307": [105, 161, 9]}, {"55062311": [108, 3, 224]}, {"55062315": [8]}, {"55062320": [7, 9, 15, 2, 3, 1, 13, 11]}, {"55062333": [1, 1, 1, 1, 1]}, {"55062339": [1, 1, 1, 1, 1]}, {"55062345": [1]}, {"55062347": [1, 1, 1, 1, 1, 1, 1, 1]}, {"55062357": [51, 8, 33, 32, 15]}, {"55062363": [71, 21, 234]}, {"55062367": [14, 60, 2, 128, 18, 140, 66, 165, 212, 142, 111]}, {"55062379": [164]}, {"55062381": [15, 122, 3, 20, 64]}, {"55062387": [5, 52, 2, 72, 48, 21, 226]}, {"55062395": [7]}, {"55062400": [36, 25]}, {"55062403": [3, 16]}, {"55062407": [4, 52, 2, 99, 17, 21, 226]}, {"55062415": [2]}, {"55062420": [36, 25]}, {"55062423": [3, 3, 224]}, {"55062427": [8]}, {"55062432": [141, 173, 138, 160, 52, 2, 128]}, {"55062440": [16, 77]}, {"55062443": [2]}, {"55062448": [16]}, {"55062451": [9, 60, 15, 128, 30, 37, 239, 132, 160, 129, 226, 28, 191, 48, 66]}, {"55062467": [1, 16, 64]}, {"55062471": [2]}, {"55062476": [16]}, {"55062479": [2, 52, 2]}, {"55062483": [1, 161, 226, 28, 191, 3, 224]}, {"55062491": [8]}, {"55062497": [51, 8, 33, 60, 2, 128, 18, 140, 66, 165, 212, 142, 111]}, {"55062511": [164]}, {"55062513": [15, 122, 3, 20, 64]}, {"55062519": [5, 52, 2, 72, 48, 21, 226]}, {"55062527": [7]}, {"55062532": [36, 25]}, {"55062535": [3, 16]}, {"55062539": [4, 52, 2, 99, 17, 21, 226]}, {"55062547": [2]}, {"55062552": [36, 25]}, {"55062555": [3, 3, 224]}, {"55062559": [8]}] \ No newline at end of file diff --git a/data/mqu.json b/data/mqu.json new file mode 100644 index 000000000..7e186e154 --- /dev/null +++ b/data/mqu.json @@ -0,0 +1,38464 @@ +[ + { + "File": { + "Name": "Scene 0", + "Start": "02499000", + "End": "024A6A10", + "RemapStart": null + }, + "Id": 0, + "TActors": [ + "01FF 00FF 002E FE39 0190 01C7 6000 003F", + "06FF 05FF 002E FA01 FD08 042E 4000 01C9", + "04FF 03FF 002E FFB5 FC90 0244 8000 01D5", + "08FF 07FF 002E F68C FD08 FE3B 2000 003F", + "0BFF 09FF 002E FC80 F8A8 FC3C 105B 007F", + "02FF 01FF 002E FC58 0190 03A8 6000 008C", + "00FF 0AFF 002E FDD0 0320 0000 C000 007F", + "07FF 06FF 002E F8C1 FD08 0302 0000 007F", + "05FF 04FF 002E FEB1 FC90 03C0 4000 0099", + "00FF 03FF 0023 0000 FEC0 0000 C000 00BF", + "03FF 09FF 0023 FD85 FBB4 0000 C000 00BF", + "07FF 03FF 0023 FBE1 FCCC 0000 4000 013F" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 0, Room 0", + "Start": "024A7000", + "End": "024BC2F0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "000E", + "00A4", + "012B", + "00B7", + "015C", + "000D", + "0168", + "0164", + "0170", + "012F" + ], + "Actors": [ + "00C7 FFB9 0320 00FC 0000 0000 0000 0001", + "00C7 FFA8 0000 FE95 0000 0000 0000 0001", + "0013 FFCA 0106 FE73 4000 4AAB 0000 0003", + "0013 FE28 035C FFD8 0000 BB06 0000 0003", + "0095 005F 0085 FECC 4000 F49F 0000 0000", + "0125 0188 0000 FF62 0000 DDDE 0000 FF01", + "0125 0164 0000 FF15 0000 DDDE 0000 FF01", + "0125 0134 0000 FEDD 0000 DDDE 0000 FF01", + "0125 008F 0133 FE6F 0000 0000 0000 FF01", + "0125 0051 0125 FE60 0000 0000 0000 FF01", + "0055 FF3D 0320 FF3D 0000 9F4A 0000 0000", + "0055 0100 0320 FFBB 0000 0000 0000 0000", + "011B 0000 FFE8 0000 0028 0006 0000 8001", + "011B FE5F 0190 01AB 0000 0000 0000 0103", + "011B FDE9 0320 0000 0000 0000 0000 0103", + "011B 0076 0000 FEBB 0014 0000 0000 1F02", + "011B 01D1 0168 0072 001C 0000 0000 1F02", + "011B 011A 0168 0168 0014 0000 0000 1F02", + "0015 FFEA 010E FFA8 0000 0000 0000 2403", + "0095 0116 0168 014C 0000 A000 0000 8102", + "0125 FFF5 0000 FEA8 0000 0000 0000 FF02", + "0125 FF61 0000 FED2 0000 0000 0000 FF02", + "002B 0192 0168 00C5 0000 B333 0000 0006", + "002B 0141 03D5 011D 0000 A000 0000 0008", + "005E FF67 0000 0002 0000 0000 0000 03E7", + "005E 0190 0168 0079 0000 B555 0000 03E7", + "005E FE16 0320 FFDC 0000 CAAB 0000 03E7", + "012A FEC9 0320 FEC9 0000 E000 0000 2700", + "01A0 0117 0168 014D 0000 6000 0000 FFFF", + "000A 014D 0168 00FD 0000 20B6 0000 0823", + "000F 0000 0000 0000 0000 4000 0000 0FC5", + "000F FE15 0320 FFFF 0000 4000 0000 19CA", + "000F FE7C 0190 0185 0000 6000 0000 1FD6" + ] + }, + { + "File": { + "Name": "Scene 0, Room 1", + "Start": "024BD000", + "End": "024C1150", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "004A", + "000E", + "00A4", + "012B", + "00B7", + "015C" + ], + "Actors": [ + "0125 FD7D 0190 031E 0000 0000 0000 FF01", + "0125 FD72 0190 0246 0000 0000 0000 FF01", + "0125 FCEC 0190 02BE 0000 0000 0000 FF01", + "0055 FD5C 0190 02B1 0000 0000 0000 0001", + "0015 FDAE 0190 0348 0000 0000 0000 2303", + "0125 FDC4 0190 02D7 0000 0000 0000 FF02", + "0125 FDC1 0190 0273 0000 0000 0000 FF02", + "0125 FD20 0190 031B 0000 0000 0000 FF02", + "0125 FD0F 0190 0266 0000 0000 0000 FF02", + "002B FD2C 0190 0394 0000 0000 0000 0006", + "002B FC89 0190 02DB 0000 0000 0000 0006", + "012A FC68 021E 0396 0000 6000 0000 0C02" + ] + }, + { + "File": { + "Name": "Scene 0, Room 2", + "Start": "024C2000", + "End": "024C7E30", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "004A", + "000E", + "00A4", + "012B", + "00B7", + "015C", + "011D", + "0163", + "0190", + "00A8" + ], + "Actors": [ + "0095 FB63 017D 0577 4000 5F4A 0000 0000", + "0095 FA8D 0191 04A3 4000 6000 0000 0000", + "0037 FB17 02EC 04E1 0000 616C 0000 0000", + "0125 FC14 0118 04BE 0000 C71C 0000 FF01", + "0125 FC07 0118 04ED 0000 C71C 0000 FF01", + "0125 FB34 0118 03EC 0000 0000 0000 FF01", + "0125 FB01 0118 0400 0000 0000 0000 FF01", + "011B FA8E 0118 04A4 0000 0000 0000 1F02", + "011B FB5E 0163 0576 0000 0000 0000 1F02", + "011B FB68 01E0 05CD 0000 0000 0000 1F02", + "012C FB42 0186 04B8 0000 E000 0000 0080", + "0015 FB98 0290 0623 0000 0000 0000 2203", + "0095 FBDF 0302 0670 4000 A000 0000 8108", + "002B FAE6 0118 045D 0000 0000 0000 0006", + "002B FABD 01E0 054B 0000 0000 0000 0006", + "01D1 FB48 0223 056E 0000 E000 0000 39FF", + "01D1 FB72 0223 0544 0000 E000 0000 39FF", + "01D1 FB73 0223 0598 0000 E000 0000 39FF", + "01D1 FB9D 0223 056E 0000 E000 0000 39FF", + "0173 FBD7 024E 0432 0005 0022 0001 3F04", + "0127 FB97 0290 05BD 0000 A000 0000 0003", + "0127 FB61 0290 05F2 0000 A000 0000 0004", + "0127 FB2B 0290 0616 0000 A000 0000 0008", + "000A FA91 01E0 056F 0000 E000 0000 0801", + "000F FBE9 0265 0435 0CCD E5B0 0EEF 1FFF", + "0051 FBD6 0230 042A 0000 E000 0000 0121" + ] + }, + { + "File": { + "Name": "Scene 0, Room 3", + "Start": "024C8000", + "End": "024DC1A0", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "000E", + "00A4", + "012B", + "00B7", + "015C", + "000D", + "0168", + "0164", + "0170", + "012F" + ], + "Actors": [ + "00C7 001F FCB3 FF2C 0000 7E94 0000 0001", + "0125 FFD9 FC90 0076 0000 0000 0000 FF01", + "0125 0005 FC90 0077 0000 0000 0000 FF01", + "0125 FCD9 FCD6 FF1C 0000 0000 0000 FF01", + "0125 FD04 FCCC 0118 0000 E000 0000 FF01", + "0125 FCDB FCCC 00ED 0000 E000 0000 FF01", + "0055 FF7B FCB3 FEE2 0000 0000 0000 0000", + "0055 FF97 FC90 0085 0000 8000 0000 0000", + "0055 FE38 FCCF FFD6 0000 0000 0000 0001", + "011B FDA8 FCCC FEDD 0014 0011 000A 3208", + "017D FE93 FC77 FEDE 0000 0000 0001 FF10", + "0125 FFF9 FCB3 FEB8 0000 0000 0000 FF02", + "0125 FFF1 FCB3 FEFB 0000 0000 0000 FF02", + "005E FF9A FC90 00F4 0000 E000 0000 03C2", + "012A FF9A FCB3 FE66 0000 0000 0000 0200", + "012A 0040 FC90 00FF 0000 0000 0000 1400", + "0195 FDCE FCCC 014C 0000 0000 0000 0004", + "012A FFB4 FD29 0227 0000 8000 0000 1502", + "000A 0035 FDC1 FEEA 0000 8000 0014 8524", + "000F FD85 FCCC 0000 0000 4000 0000 0FC6", + "000F 002D FC8C 00F5 FBBC B8E4 0000 1FCB" + ] + }, + { + "File": { + "Name": "Scene 0, Room 4", + "Start": "024DD000", + "End": "024E1BD0", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "004A", + "000E", + "00A4", + "012B", + "00B7", + "0170" + ], + "Actors": [ + "0125 0050 FC90 0318 0000 0000 0000 FF01", + "0125 0032 FC90 02EE 0000 0000 0000 FF01", + "0125 FF37 FC90 02ED 0000 0000 0000 FF01", + "0125 FF1D FC90 0316 0000 0000 0000 FF01", + "0060 FFB6 FC90 0416 0000 8000 0000 FF00", + "002B FF43 FC90 041B 0000 0000 0000 0006", + "002B 002F FC90 041C 0000 0000 0000 0006", + "002B FFB3 FD7F 03D0 0000 0000 0000 0008", + "005E FEE7 FC90 0371 0000 0000 0000 1099", + "005E FEE6 FC90 0411 0000 0000 0000 1099", + "0173 FEE7 FCCC 0371 0002 001A 0000 3F06", + "0173 FEE6 FCCC 0411 0002 001A 0000 3F06" + ] + }, + { + "File": { + "Name": "Scene 0, Room 5", + "Start": "024E2000", + "End": "024EA320", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "004A", + "000E", + "00A4", + "012B", + "00B7", + "000D", + "0170", + "0190", + "00A8", + "00A2" + ], + "Actors": [ + "00C7 FB1E FC90 0382 0000 0000 0000 0001", + "0037 FABD FCDA 0437 0000 4000 0000 0000", + "0125 FAE3 FC9A 0346 0000 0000 0000 FF01", + "0125 FAB0 FC9A 0346 0000 0000 0000 FF01", + "0125 FDE6 FC90 038B 0000 0000 0000 FF02", + "0125 FE11 FC90 038A 0000 0000 0000 FF02", + "0125 FE2E FC90 0361 0000 0000 0000 FF02", + "002B FC6B FDE2 0428 0000 0000 0000 0009", + "01D1 FAAB FC90 042E 0000 0000 0000 B9FF", + "005E FDF0 FC90 03D8 0000 0000 0000 03FE", + "005E FB77 FC90 047B 0000 0000 0000 1089", + "005E FB78 FC90 03E1 0000 0000 0000 1089", + "012A FDF1 FC90 045A 0000 0000 0000 3E20", + "000A FAA0 FC90 0436 0000 C000 0000 5AA0", + "000A FE84 FC90 0405 0000 4000 0000 5905", + "0050 FCBD FC77 041A 0000 4000 0000 FF00", + "0051 FCBD FCA4 041A 0000 4000 0000 00FF", + "0050 FCBD FC6D 041A 0000 0000 0000 FF01" + ] + }, + { + "File": { + "Name": "Scene 0, Room 6", + "Start": "024EB000", + "End": "024EFEC0", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "004A", + "000E", + "00A4", + "012B", + "00B7", + "000D", + "0170" + ], + "Actors": [ + "0013 F81D FE0B 04C9 0000 6000 0000 0003", + "0125 F8FD FD08 0333 0000 0000 0000 FF01", + "0125 F882 FD08 0332 0000 0000 0000 FF01", + "0060 F8C9 FD08 042A 0000 4000 0000 FF00", + "002B F909 FD08 047A 0000 0000 0000 0007", + "002B F869 FD08 0471 0000 0000 0000 0007", + "002B F909 FD08 03DF 0000 0000 0000 0007", + "002B F863 FD08 03E0 0000 0000 0000 0007", + "002B F8C2 FDEB 04FE 0000 0000 0000 0009", + "002B F8BB FDF4 0366 0000 0000 0000 0009", + "002B F8C0 FE43 042C 0000 0000 0000 0008", + "002B F813 FE16 042F 0000 0000 0000 0008" + ] + }, + { + "File": { + "Name": "Scene 0, Room 7", + "Start": "024F0000", + "End": "024F8910", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "00A4", + "012B", + "00B7", + "015C", + "000D", + "0168", + "00A8", + "0190", + "00A2" + ], + "Actors": [ + "00C7 F959 FD08 0144 0000 5A50 0000 0001", + "0013 F857 FD43 000A 0000 0000 0000 0003", + "0013 F8AE FD44 005F 0000 0000 0000 0003", + "0013 F803 FD44 0061 0000 0000 0000 0003", + "0013 F85A FD44 00B9 0000 0000 0000 0003", + "0125 F893 FD08 025C 0000 0000 0000 FF01", + "0055 FA0E FCF7 0001 0000 C000 0000 0000", + "0055 F73C FD08 FEF5 0000 2000 0000 0000", + "0095 F82E FEE8 005B 0000 0000 0000 8104", + "0112 F71F FD1C 0082 0000 0000 0000 193F", + "0112 F7DD FD1C FFA9 0000 0000 0000 193F", + "0112 F913 FD1C 012A 0000 0000 0000 193F", + "0112 F93A FD1C FF60 0000 0000 0000 193F", + "0125 F759 FD08 0038 0000 0000 0000 FF02", + "0125 F78B FD08 015E 0000 0000 0000 FF02", + "0125 F95C FD08 00C4 0000 0000 0000 FF02", + "0125 F972 FD08 FF88 0000 0000 0000 FF02", + "01D1 F7A2 FD08 005D 0000 0000 0000 39FF", + "01D1 F7DB FD43 00D9 0000 2000 0000 39FF", + "01D1 F84C FD85 0122 0000 0000 0000 39FF", + "01D1 F8CA FDCC 00F2 0000 6000 0000 39FF", + "01D1 F8FA FE13 0073 0000 0000 0000 39FF", + "005E F857 FD08 0005 0000 0000 0000 03F8", + "005E F85B FD08 00B5 0000 0000 0000 03F8", + "005E F803 FD08 005B 0000 0000 0000 03F8", + "005E F8AD FD08 0059 0000 0000 0000 03F8", + "012A F859 FD08 005A 0000 0000 0000 3820", + "009D F718 FCF9 0081 0000 4000 0000 0000", + "009D F715 FCF9 FFEC 0000 4000 0000 0000", + "009D F7E1 FCF9 0115 0000 0000 0000 0000", + "009D F8ED FCF9 FFE9 0000 0000 0000 0000", + "009D F916 FCF9 011A 0000 0000 0000 0000", + "009D F9A4 FCF9 00B4 0000 C000 0000 0000", + "009D F945 FCF9 FF4F 0000 E222 0000 0000", + "009D F7DC FCF9 FF98 0000 0000 0000 0000", + "000F FAB5 FCCC 0003 0000 C000 0000 1FC7", + "000F F707 FD08 FEB9 0000 2000 0000 1FCF" + ] + }, + { + "File": { + "Name": "Scene 0, Room 8", + "Start": "024F9000", + "End": "024F9D00", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "0164", + "000E", + "00A4", + "012B", + "00B7", + "015C" + ], + "Actors": [ + "0125 F554 F8E6 FD5E 0000 0000 0000 FF01", + "0125 F647 F8E2 FD0F 0000 0000 0000 FF01", + "0055 F58D FD08 FD41 0000 2000 0000 0001", + "0095 F563 FD8E FD16 0000 2000 0000 8101", + "0125 F607 FD08 FE4F 0000 0000 0000 FF02", + "0125 F6A5 FD08 FDB5 0000 0000 0000 FF02", + "0125 F56C FD08 FDF6 0000 0000 0000 FF02", + "002B F63C FD08 FD5D 0000 0000 0000 0007", + "002B F5A5 FD08 FE03 0000 0000 0000 0007", + "002B F5F1 FD08 FD12 0000 0000 0000 0007", + "002B F561 FD08 FDA2 0000 0000 0000 0007" + ] + }, + { + "File": { + "Name": "Scene 0, Room 9", + "Start": "024FA000", + "End": "025038A0", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "000E", + "00A4", + "012B", + "00B7", + "015C", + "000D", + "0168", + "0164", + "0170" + ], + "Actors": [ + "0125 FEF4 F8A8 FD7B 0000 0000 0000 FF01", + "0125 FEF0 F8A8 FDBD 0000 0000 0000 FF01", + "0125 FEF0 F8A8 FDFB 0000 0000 0000 FF01", + "0192 FE8F F8A8 FC78 0000 0000 0000 0001", + "0192 FC4D F8A8 FD0B 0000 0000 0000 0002", + "0192 FD6C F8A8 FC49 0000 0000 0000 9C03", + "0015 FC8B F862 FF47 0000 0000 0000 2E03", + "0015 FCCC F858 FFB4 0000 0000 0000 3003", + "0015 FE9E F869 FF32 0000 0000 0000 3103" + ] + }, + { + "File": { + "Name": "Scene 0, Room 10", + "Start": "02504000", + "End": "02508D80", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "0164", + "000E", + "00A4", + "012B", + "00B7", + "0170" + ], + "Actors": [ + "0125 FA5D 0348 00A7 0000 727D 0000 FF01", + "0125 FA15 0348 008C 0000 7333 0000 FF01", + "0125 FD84 0320 00A1 0000 0000 0000 FF01", + "0125 FD4B 0320 00B6 0000 0000 0000 FF01", + "0055 FCA6 02D0 00BA 0000 BF4A 0000 0000", + "0015 FB73 0334 0145 0000 0000 0000 2603", + "002B FB10 02D0 0093 0000 0000 0000 0007", + "002B FA77 0348 FFA3 0000 0B61 0000 0007", + "002B FA72 0348 0046 0000 0000 0000 0006", + "002B FB7C 03E0 01C5 0000 0000 0000 0008", + "002B FBE7 03CF FEF0 0000 0000 0000 0008", + "002B FC0A 03E8 0140 0000 8000 0000 0008", + "005E FD73 0320 FF97 0000 C000 0000 2400", + "005E FBD5 02D0 FFFB 0000 C000 0000 1053", + "0173 FBD5 030C FFFB 0002 0014 0000 3F06", + "012A FD1D 0320 FF6D 0000 0000 0000 3D00", + "01A0 FCDB 02D0 FFFE 0000 4000 0000 FFFF", + "01A0 FCDB 02D0 FFC2 0000 4000 0000 FFFF", + "000A FA2D 049B 0001 0000 C000 0013 8522", + "000A FBC6 0334 0183 0000 0000 0000 10A6", + "0050 FBC8 0258 0000 0000 0000 0000 3D02" + ] + }, + { + "File": { + "Name": "Scene 0, Room 11", + "Start": "02509000", + "End": "02510170", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "0036", + "001E", + "0024", + "0039", + "0164", + "000E", + "00A4", + "012B", + "00B7" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": true, + "Polys": [ + { + "Id": 459, + "Type": 11, + "Flags": 0 + }, + { + "Id": 460, + "Type": 11, + "Flags": 0 + }, + { + "Id": 461, + "Type": 12, + "Flags": 0 + }, + { + "Id": 462, + "Type": 12, + "Flags": 0 + }, + { + "Id": 570, + "Type": 13, + "Flags": 1 + }, + { + "Id": 571, + "Type": 13, + "Flags": 1 + }, + { + "Id": 572, + "Type": 14, + "Flags": 1 + }, + { + "Id": 573, + "Type": 14, + "Flags": 1 + }, + { + "Id": 574, + "Type": 15, + "Flags": 0 + }, + { + "Id": 575, + "Type": 15, + "Flags": 0 + }, + { + "Id": 576, + "Type": 15, + "Flags": 0 + }, + { + "Id": 577, + "Type": 15, + "Flags": 0 + }, + { + "Id": 578, + "Type": 15, + "Flags": 0 + }, + { + "Id": 579, + "Type": 15, + "Flags": 0 + }, + { + "Id": 580, + "Type": 15, + "Flags": 0 + }, + { + "Id": 581, + "Type": 15, + "Flags": 0 + }, + { + "Id": 582, + "Type": 15, + "Flags": 0 + }, + { + "Id": 583, + "Type": 15, + "Flags": 0 + }, + { + "Id": 584, + "Type": 15, + "Flags": 0 + }, + { + "Id": 585, + "Type": 15, + "Flags": 0 + }, + { + "Id": 586, + "Type": 15, + "Flags": 0 + }, + { + "Id": 587, + "Type": 15, + "Flags": 0 + }, + { + "Id": 588, + "Type": 15, + "Flags": 0 + }, + { + "Id": 589, + "Type": 15, + "Flags": 0 + }, + { + "Id": 590, + "Type": 15, + "Flags": 0 + }, + { + "Id": 591, + "Type": 15, + "Flags": 0 + }, + { + "Id": 592, + "Type": 15, + "Flags": 0 + }, + { + "Id": 593, + "Type": 15, + "Flags": 0 + }, + { + "Id": 594, + "Type": 15, + "Flags": 0 + }, + { + "Id": 595, + "Type": 15, + "Flags": 0 + }, + { + "Id": 596, + "Type": 15, + "Flags": 0 + }, + { + "Id": 597, + "Type": 15, + "Flags": 0 + }, + { + "Id": 598, + "Type": 15, + "Flags": 0 + }, + { + "Id": 599, + "Type": 15, + "Flags": 0 + }, + { + "Id": 600, + "Type": 15, + "Flags": 0 + }, + { + "Id": 601, + "Type": 15, + "Flags": 0 + }, + { + "Id": 602, + "Type": 15, + "Flags": 0 + }, + { + "Id": 603, + "Type": 15, + "Flags": 0 + }, + { + "Id": 604, + "Type": 15, + "Flags": 0 + }, + { + "Id": 605, + "Type": 15, + "Flags": 0 + }, + { + "Id": 678, + "Type": 16, + "Flags": 0 + }, + { + "Id": 679, + "Type": 16, + "Flags": 0 + }, + { + "Id": 680, + "Type": 17, + "Flags": 0 + }, + { + "Id": 681, + "Type": 17, + "Flags": 0 + }, + { + "Id": 682, + "Type": 17, + "Flags": 0 + }, + { + "Id": 683, + "Type": 17, + "Flags": 0 + }, + { + "Id": 684, + "Type": 16, + "Flags": 0 + }, + { + "Id": 685, + "Type": 16, + "Flags": 0 + }, + { + "Id": 688, + "Type": 17, + "Flags": 0 + }, + { + "Id": 689, + "Type": 17, + "Flags": 0 + }, + { + "Id": 690, + "Type": 17, + "Flags": 0 + }, + { + "Id": 691, + "Type": 17, + "Flags": 0 + }, + { + "Id": 700, + "Type": 18, + "Flags": 0 + }, + { + "Id": 701, + "Type": 18, + "Flags": 0 + }, + { + "Id": 726, + "Type": 16, + "Flags": 0 + }, + { + "Id": 727, + "Type": 16, + "Flags": 0 + }, + { + "Id": 754, + "Type": 18, + "Flags": 0 + }, + { + "Id": 755, + "Type": 18, + "Flags": 0 + }, + { + "Id": 756, + "Type": 18, + "Flags": 0 + }, + { + "Id": 763, + "Type": 18, + "Flags": 0 + }, + { + "Id": 764, + "Type": 18, + "Flags": 0 + }, + { + "Id": 811, + "Type": 19, + "Flags": 0 + }, + { + "Id": 812, + "Type": 19, + "Flags": 0 + }, + { + "Id": 813, + "Type": 17, + "Flags": 0 + }, + { + "Id": 814, + "Type": 17, + "Flags": 0 + }, + { + "Id": 819, + "Type": 19, + "Flags": 0 + }, + { + "Id": 820, + "Type": 19, + "Flags": 0 + }, + { + "Id": 824, + "Type": 15, + "Flags": 0 + }, + { + "Id": 825, + "Type": 15, + "Flags": 0 + }, + { + "Id": 826, + "Type": 15, + "Flags": 0 + }, + { + "Id": 827, + "Type": 15, + "Flags": 0 + }, + { + "Id": 828, + "Type": 15, + "Flags": 0 + }, + { + "Id": 829, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1161, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1173, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1174, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1175, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1176, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1177, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1194, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1195, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1196, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1197, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1202, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1203, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1204, + "Type": 23, + "Flags": 0 + }, + { + "Id": 1205, + "Type": 23, + "Flags": 0 + }, + { + "Id": 1206, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1207, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1208, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1209, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1210, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1211, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1212, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1213, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1214, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1215, + "Type": 15, + "Flags": 0 + }, + { + "Id": 1216, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1217, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1300, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1301, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1306, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1307, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1328, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1329, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1330, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1331, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1332, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1333, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1334, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1335, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1336, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1337, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1338, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1339, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1421, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1422, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1479, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1480, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1481, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1482, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1483, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1484, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1485, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1486, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1487, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1488, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1489, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1520, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1521, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1522, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1523, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1536, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1537, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1538, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1539, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1540, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1541, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1548, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1549, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1550, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1551, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1566, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1567, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1568, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1569, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1570, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1571, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1572, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1573, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1574, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1579, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1580, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1581, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1582, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1583, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1589, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1590, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1591, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1592, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1593, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1594, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1595, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1596, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1601, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1602, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1603, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1610, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1611, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1612, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1619, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1620, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1661, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1662, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1663, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1664, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1679, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1680, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1759, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1760, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1761, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1762, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1763, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1764, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1809, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1810, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1890, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1891, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1906, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1907, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1920, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1921, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1930, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1931, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1932, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1933, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1934, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1935, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1936, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1937, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1938, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1939, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1940, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1941, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1942, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1943, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1944, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1945, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1946, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1947, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1948, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1949, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1954, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1955, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1956, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1957, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1958, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1959, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1960, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1961, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1962, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1963, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1964, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1977, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1978, + "Type": 16, + "Flags": 0 + }, + { + "Id": 2021, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2022, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2023, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2024, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2025, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2026, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2027, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2028, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2029, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2030, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2031, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2032, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2033, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2034, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2035, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2036, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2037, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2038, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2039, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2040, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2041, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2042, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2043, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2044, + "Type": 28, + "Flags": 0 + }, + { + "Id": 2166, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2167, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2168, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2169, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2170, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2171, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2172, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2173, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2174, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2197, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2198, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2199, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2200, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2201, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2202, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2203, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2204, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2205, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2206, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2207, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2208, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2209, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2210, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2218, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2219, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2220, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2257, + "Type": 16, + "Flags": 0 + }, + { + "Id": 2258, + "Type": 16, + "Flags": 0 + }, + { + "Id": 2289, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2290, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2293, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2294, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2295, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2296, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2297, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2298, + "Type": 18, + "Flags": 0 + }, + { + "Id": 2310, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2311, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2312, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2313, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2314, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2315, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2316, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2317, + "Type": 30, + "Flags": 0 + }, + { + "Id": 2318, + "Type": 30, + "Flags": 0 + }, + { + "Id": 2319, + "Type": 30, + "Flags": 0 + }, + { + "Id": 2320, + "Type": 30, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 11, + "High": 49159, + "Low": 30720 + }, + { + "Id": 12, + "High": 49158, + "Low": 30720 + }, + { + "Id": 13, + "High": 4194309, + "Low": 145354 + }, + { + "Id": 14, + "High": 6291461, + "Low": 14282 + }, + { + "Id": 15, + "High": 8388613, + "Low": 145354 + }, + { + "Id": 16, + "High": 5, + "Low": 12288 + }, + { + "Id": 17, + "High": 7, + "Low": 20480 + }, + { + "Id": 18, + "High": 6, + "Low": 20480 + }, + { + "Id": 19, + "High": 8, + "Low": 20480 + }, + { + "Id": 20, + "High": 2, + "Low": 30722 + }, + { + "Id": 21, + "High": 2, + "Low": 12290 + }, + { + "Id": 22, + "High": 10485765, + "Low": 14282 + }, + { + "Id": 23, + "High": 10485763, + "Low": 14282 + }, + { + "Id": 24, + "High": 10485764, + "Low": 14282 + }, + { + "Id": 25, + "High": 5, + "Low": 20480 + }, + { + "Id": 26, + "High": 10, + "Low": 20480 + }, + { + "Id": 27, + "High": 10, + "Low": 12288 + }, + { + "Id": 28, + "High": 7, + "Low": 16384 + }, + { + "Id": 29, + "High": 7, + "Low": 14272 + }, + { + "Id": 30, + "High": 517, + "Low": 14304 + } + ], + "Cams": [ + { + "Data": 1572867, + "PositionIndex": 0 + }, + { + "Data": 1572867, + "PositionIndex": 1 + }, + { + "Data": 1966086, + "PositionIndex": 2 + }, + { + "Data": 1441795, + "PositionIndex": 3 + }, + { + "Data": 1441795, + "PositionIndex": 4 + }, + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 4259840, + "PositionIndex": -1 + }, + { + "Data": 327680, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 2, + "x": 40, + "y": -33 + }, + { + "Flag": 6, + "x": 49, + "y": -42 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 48, + "y": -63 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 3, + "x": 84, + "y": -39 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 3, + "IconPoints": [ + { + "Flag": 0, + "x": 46, + "y": -59 + }, + { + "Flag": 4, + "x": 77, + "y": -26 + }, + { + "Flag": 5, + "x": 65, + "y": -61 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 55, + "y": 0 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 3, + "x": 71, + "y": 50 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 64, + "y": 62 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 4, + "x": 76, + "y": 37 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 0, + "x": 46, + "y": 50 + }, + { + "Flag": 5, + "x": 76, + "y": 52 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 50, + "y": 23 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 2, + "x": 46, + "y": 50 + }, + { + "Flag": 6, + "x": 58, + "y": 60 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 1", + "Start": "01F12000", + "End": "01F27140", + "RemapStart": null + }, + "Id": 1, + "TActors": [ + "00FF 01FF 0023 0474 0000 FEC0 4000 003F", + "00FF 09FF 0023 0474 0213 FEC0 4000 003F", + "00FF 09FF 0023 0474 0213 FC68 4000 003F", + "07FF 08FF 0023 026C 004C F520 4000 003F", + "07FF 08FF 0023 0251 004C F11A 4000 003F", + "09FF 0CFF 0023 0924 0213 FC68 4000 003F", + "09FF 0AFF 0023 0924 0213 FEC0 4000 003F", + "07FF 00FF 002E 0000 004C F84E 0000 003F", + "04FF 03FF 002E 0AE3 0064 F680 2AAB 0085", + "01FF 03FF 002E 0DE8 0064 FB04 8000 0085", + "0AFF 03FF 002E 10F3 0213 FDA8 8000 0086", + "0CFF 03FF 002E 0EC4 0213 FC68 4000 0086", + "01FF 0BFF 002E 0A00 0000 0078 0000 003F", + "08FF 0EFF 002E 05C1 004C EF7B 8000 007F", + "0DFF 04FF 002E 0981 0064 F4B2 0000 01DE", + "02FF 0FFF 002E F858 0000 FD1C 0000 003F", + "06FF 09FF 002E 0730 019B FA38 0000 01E7", + "05FF 02FF 002E F858 0213 FD24 8000 00A5", + "00FF 05FF 002E F9F4 0213 FEC0 C000 007F", + "01FF 01FF 002E 0DE8 0064 FDD0 0000 00B6", + "10FF 07FF 002E FE98 0010 F520 4000 00A0", + "02FF 00FF 002E FCB8 0000 FA10 4000 0083", + "00FF 04FF 002E 05B4 0050 FC68 4000 009B" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 1, Room 0", + "Start": "01F28000", + "End": "01F438A0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "002B", + "018A", + "0031", + "000E", + "0038", + "0168", + "011B", + "0163", + "0024", + "0188", + "00A4", + "0036", + "001F", + "000D", + "0170" + ], + "Actors": [ + "01B9 FC37 0000 FC6C 0000 4000 0000 3E14", + "0058 FE5C FF4C FB64 0000 0000 0000 00FF", + "0058 0000 FF4C FCF4 0000 0000 0000 00FF", + "0058 01A4 FF4C FB64 0000 0000 0000 000A", + "0059 0000 0000 0014 0000 0000 0000 0007", + "0059 0334 0000 FA10 0000 C000 0000 A000", + "0059 FCCC 0000 FC68 0000 4000 0000 A01D", + "0059 0334 0000 FEC0 0000 C000 0000 A01F", + "003F 0000 00C4 F92A 0000 0000 0000 001A", + "011B 0010 FF67 FC05 0096 0000 0032 0C15", + "0112 FFD8 0000 0014 0000 0000 0000 3FD8", + "0112 0000 0000 0014 0000 0000 0000 3FD8", + "0112 0028 0000 0014 0000 0000 0000 3FD8", + "012A FC97 0213 F9FC 0000 4000 0000 0300", + "012A 01AD FF60 F94B 0000 0000 0000 0A00", + "0185 0242 0238 FC5F 0000 4000 0000 0338", + "0195 FC7E 0000 FEE7 0000 4000 0000 0003", + "0195 FC43 0000 FEA4 0000 4000 0000 0001", + "004C FEDB 0014 0133 0000 0000 0000 FFFF", + "004C FFFE 0000 FB6E 0000 0000 0000 FFFF", + "004C 0122 0014 0133 0000 0000 0000 FFFF", + "004C 0352 0213 FC65 0000 0000 0000 FFFF", + "0127 01B0 FF60 F949 0000 0000 0000 000E", + "0127 FE4D FF60 F948 0000 0000 0000 0011", + "0127 030F 0213 FC65 0000 4000 0000 0015", + "0127 0322 0213 FC34 0000 C000 0000 0015", + "0127 0327 0213 FC96 0000 0000 0000 0015", + "000A 03B6 0000 FA11 0000 4000 0000 0820", + "000A 0365 0050 FC68 0000 C000 0000 0644", + "005E FD03 0000 FA83 0000 0000 0000 03C3" + ] + }, + { + "File": { + "Name": "Scene 1, Room 1", + "Start": "01F44000", + "End": "01F4DB00", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "002B", + "018A", + "0031", + "000E", + "0038", + "0168", + "011B", + "0163", + "0024", + "0188", + "00A4", + "0036", + "001F", + "000D", + "0170" + ], + "Actors": [ + "012B 085C FF61 FE97 0000 0000 0000 0001", + "012B 085C FF61 FE20 0000 0000 0000 1201", + "0037 0C9B 0160 FE70 0000 C16C 0000 0001", + "0059 0A00 0000 FF95 0000 8000 0000 A001", + "0013 0D2D 00E7 FEA4 0000 0000 0000 0000", + "002F 0DC1 0064 FC7E 0000 093F 0000 FFFF", + "002F 0E06 0064 FBC2 0000 F1C7 0000 FFFF", + "0111 06BF 0000 FF69 0000 0000 0000 4400", + "0111 0717 0000 FF66 0000 0000 0000 4601", + "0111 0D72 0028 FE2B 0000 0000 0000 5000", + "0111 0E62 0028 FE2E 0000 0000 0000 5210", + "004C 085D 00A0 FD9B 0000 0000 0000 FFFF", + "004C 09A1 0000 FE6D 0000 0000 0000 FFFF", + "004C 0B2F 00A9 FF35 4000 671C 0000 FFFF", + "004C 0B43 00EA FF41 4000 671C 0000 FFFF", + "004C 0B46 0125 FF43 438E 671C 0000 FFFF", + "004C 0B4F 0154 FEEE 8000 0000 0000 FFFF", + "004C 0B5A 006B FF4F 4000 671C 0000 FFFF", + "004C 0B5D 0154 FF2A 8000 0000 0000 FFFF", + "004C 0B7A 0154 FE99 8000 0000 0000 FFFF", + "004C 0B8E 0154 FE3B 8000 0000 0000 FFFF", + "004C 0B90 0154 FEE0 8000 0000 0000 FFFF", + "004C 0BA2 0138 FE03 4000 11C7 0000 FFFF", + "004C 0BAE 0154 FE71 8000 0000 0000 FFFF", + "0127 09A0 0000 FE6E 0000 0000 0000 0008", + "0127 0B7E 00F0 FE11 0000 0000 0000 8012", + "012A 0B7E 0104 FE0C 0000 11C7 0000 3602" + ] + }, + { + "File": { + "Name": "Scene 1, Room 2", + "Start": "01F4E000", + "End": "01F55DA0", + "RemapStart": "1F4DCD0" + }, + "Id": 2, + "Objects": [ + "002B", + "018A", + "0031", + "00A4", + "011B", + "0170", + "0024", + "008B", + "0168", + "0039" + ], + "Actors": [ + "012B F85B FF9F F8F8 0000 0000 0000 2200", + "00C7 F893 0000 FC6B 0000 0000 0000 0001", + "0037 F779 02D0 FBA6 0000 C000 0000 0000", + "0037 F930 02D0 FBA6 0000 4000 0000 0000", + "0059 F858 0000 FBF0 0000 8000 0000 A002", + "005C F858 01E0 F894 0000 C000 0000 000B", + "011B F858 0014 FAE9 001E 0024 0000 BF14", + "008A F71B 0000 FAAE 0000 0000 0000 0401", + "008A F993 0000 FAAE 0000 0000 0000 0401", + "005E F7DF 0000 FBAC 0000 0000 0000 2400", + "0117 F71B 0000 FAAE 0000 0000 0000 1165", + "0117 F773 0000 F8D6 0000 0000 0000 1165", + "0117 F695 017C F8D4 0000 0000 0000 1165", + "0117 F88D 0273 FB25 0000 0000 0000 1165", + "0117 FA18 0213 FBC5 0000 0000 0000 1165", + "0117 F93B 0000 FA4B 0000 0000 0000 0165", + "0111 F6A9 0000 F8F4 0000 0000 0000 6603", + "0111 F6C7 0000 FB77 0000 0000 0000 6802", + "0111 FA0B 0000 F8F8 0000 0000 0000 6A02", + "0111 F9EA 0000 FB6F 0000 0000 0000 6C03", + "0195 F857 01EA F844 0000 0000 0000 0004", + "004C F7EA 0014 F97F 0000 0000 0000 FFFF", + "004C F7EA 0014 F9BB 0000 0000 0000 FFFF", + "004C F7EA 0014 F9F7 0000 0000 0000 FFFF", + "004C F7EA 0014 FA33 0000 0000 0000 FFFF", + "004C F7EA 0014 FA6F 0000 0000 0000 FFFF", + "004C F7EA 0014 FAAB 0000 0000 0000 FFFF", + "004C F7EA 0014 FAE7 0000 0000 0000 FFFF", + "004C F808 0037 FC34 4000 4000 0000 FFFF", + "004C F821 0014 FAE7 0000 0000 0000 FFFF", + "004C F891 0014 FAE7 0000 0000 0000 FFFF", + "004C F8CC 0014 F97F 0000 0000 0000 FFFF", + "004C F8CC 0014 F9BB 0000 0000 0000 FFFF", + "004C F8CC 0014 F9F7 0000 0000 0000 FFFF", + "004C F8CC 0014 FA33 0000 0000 0000 FFFF", + "004C F8CC 0014 FA6F 0000 0000 0000 FFFF", + "004C F8CC 0014 FAAB 0000 0000 0000 FFFF", + "004C F8CC 0014 FAE7 0000 0000 0000 FFFF", + "01A0 F695 017C F8D4 0000 0000 0000 FFFF", + "01A0 F696 0213 FBC4 0000 0000 0000 FFFF", + "01A0 F772 0000 F8D5 0000 0000 0000 FFFF", + "01A0 F93E 0000 F8D4 0000 0000 0000 FFFF", + "01A0 FA19 0213 FBC4 0000 0000 0000 FFFF", + "01A0 FA1A 017C F8D3 0000 0000 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 1, Room 3", + "Start": "01F56000", + "End": "01F63DC0", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "002B", + "001B", + "0163", + "00A4", + "0024", + "015C" + ], + "Actors": [ + "003B 0F0B 0028 FA0A 0000 0000 0000 0006", + "0025 0F81 0064 F78F 0000 0000 0000 0500", + "0025 0B0D 0064 F857 0000 0000 0000 0501", + "0025 10A5 0213 FBE1 0000 0000 0000 0600", + "0025 115A 0213 FA96 0000 0000 0000 0601", + "0015 10AA 0064 F9D9 0000 ACCD 0000 1803", + "0095 0DF3 0213 F845 0000 0000 0000 8204", + "0111 0F1D 0213 FCD5 0000 0000 0000 5403", + "0111 0F1B 0213 FC37 0000 0000 0000 5603", + "0111 124F 0213 FBD1 0000 0000 0000 5801", + "0111 1255 0213 FB56 0000 0000 0000 5A01", + "0127 0EB0 01D7 FADA 0000 0000 0000 00FF", + "0127 0ED7 01D7 FA99 0000 0000 0000 00FF", + "0127 0EF8 01D7 FA63 0000 0000 0000 00FF", + "0127 0F3A 01D7 FA45 0000 0000 0000 00FF", + "0127 0F7D 01D7 FA3F 0000 0000 0000 00FF", + "0127 0FBC 01D7 FA40 0000 0000 0000 00FF", + "0127 0FE3 0213 FA31 0000 0000 0000 00FF", + "0127 0FFB 0213 FA1A 0000 0000 0000 00FF", + "0127 1025 0213 F9E7 0000 0000 0000 00FF", + "0127 1042 0213 F9D3 0000 0000 0000 00FF", + "0127 1052 01D7 F9BE 0000 0000 0000 00FF", + "0127 107B 01D7 F98D 0000 0000 0000 00FF" + ] + }, + { + "File": { + "Name": "Scene 1, Room 4", + "Start": "01F64000", + "End": "01F6D850", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "002B", + "0031", + "0163", + "00A2", + "0009", + "0170" + ], + "Actors": [ + "000D 06AA 0078 F9C1 0000 45B0 0000 0000", + "000D 06C1 0078 FCA6 0000 0000 0000 0000", + "000D 081F 0078 FB46 0000 BC72 0000 0000", + "0112 06E1 0156 FC2A 0000 0000 0003 18DB", + "0112 07FE 013A F894 0000 0000 0003 18DE", + "0111 0734 0050 F8B5 0000 0000 0000 5C03", + "0111 08E0 0050 F75B 0000 0000 0000 5E00", + "0111 08C0 0050 FAA7 0000 0000 0000 6201", + "0111 05FF 0050 FAED 0000 0000 0000 6403", + "004C 06C7 012D FBD9 5555 C000 0000 FFFF", + "004C 06CE 011B FBA5 5555 B777 0000 FFFF", + "004C 06D4 012D FC01 5555 DC72 0000 FFFF", + "004C 06F3 00F2 FB84 5555 A38E 0000 FFFF", + "004C 0718 00B5 FB77 4000 8000 0000 FFFF", + "004C 0742 007F FB78 4000 8000 0000 FFFF", + "004C 07E1 00B3 F82A 4000 3111 0000 FFFF", + "004C 07E8 011F F836 471C 31C7 0000 FFFF", + "004C 07EB 007F F805 4000 2AAB 0000 FFFF", + "004C 07EC 00F9 F814 5555 3111 0000 FFFF", + "004C 07F8 0128 F87D 471C 51C7 0000 FFFF", + "004C 06F3 0050 FD27 0000 0000 0000 FFFF", + "004C 08B0 0064 F64C 0000 0000 0000 FFFF", + "01A0 08B8 0050 FB3B 0000 C000 0000 FFFF", + "01A0 08B8 0050 FB77 0000 C000 0000 FFFF", + "01A0 08DB 0050 F8A4 0000 C000 0000 FFFF", + "01A0 08DB 0050 F8E0 0000 C000 0000 FFFF", + "01A0 0600 0050 FA55 0000 C000 0000 FFFF", + "01A0 0600 0050 FA91 0000 C000 0000 FFFF", + "01A0 0722 0050 FD18 0000 0000 0000 FFFF", + "01A0 075E 0050 FD18 0000 0000 0000 FFFF", + "009D 06DD 0165 FC11 ACCD 6000 0000 0000", + "009D 07F6 0158 F87B BA50 D27D 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 1, Room 5", + "Start": "01F6E000", + "End": "01F73EE0", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "002B", + "0031", + "000C", + "00A4", + "000D", + "000E", + "012B" + ], + "Actors": [ + "0125 F74A 0213 FDD4 0000 0000 0000 0301", + "0125 F756 0213 FFC8 0000 0000 0000 0301", + "0125 F93D 0213 FFD3 0000 0000 0000 0301", + "0125 F947 0213 FDBD 0000 0000 0000 0301", + "0012 F788 0213 FE98 0000 EE39 0000 FFFF", + "0012 F8E1 0213 FF7F 0000 616C 0000 FFFF", + "0012 F8E7 0213 FE40 0000 B05B 0000 FFFF", + "004C F85B 0277 FEBE 0000 0000 0000 FFFF", + "000A F858 0213 FFE4 0000 0000 0000 1805" + ] + }, + { + "File": { + "Name": "Scene 1, Room 6", + "Start": "01F74000", + "End": "01F76400", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "002B", + "0024", + "0177", + "001E", + "0170", + "000E" + ], + "Actors": [ + "0095 080D 019B F911 0000 8000 0000 8210", + "002B 06B2 0303 F97C 0000 0000 0000 0008", + "002B 06D0 0303 F914 0000 0000 0000 0008", + "002B 072F 0303 F8C2 0000 0000 0000 0008", + "002B 0795 0303 F918 0000 0000 0000 0008", + "002B 07B6 0303 F982 0000 0000 0000 0008", + "01A0 0659 019B F90B 0000 4000 0000 FFFF", + "01A0 0659 019B F947 0000 4000 0000 FFFF", + "01A0 0713 019B F848 0000 0000 0000 FFFF", + "01A0 074F 019B F848 0000 0000 0000 FFFF", + "01A0 0807 019B F912 0000 4000 0000 FFFF", + "01A0 0807 019B F94E 0000 4000 0000 FFFF", + "000A 070F 019B F952 0000 8000 0000 7522" + ] + }, + { + "File": { + "Name": "Scene 1, Room 7", + "Start": "01F77000", + "End": "01F7E6D0", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "002B", + "001F", + "001B", + "0038", + "015C", + "0024", + "0031", + "00A2", + "0154", + "0179", + "012B" + ], + "Actors": [ + "002F FF35 0010 F48F 0000 0000 0000 FFFF", + "002F 0016 0010 F466 0000 2666 0000 FFFF", + "0112 FFC4 004C F762 0000 0000 0000 3FF0", + "0112 FFEC 004C F762 0000 0000 0000 3FF0", + "0112 0014 004C F762 0000 0000 0000 3FF0", + "0112 003C 004C F762 0000 0000 0000 3FF0", + "0111 0102 0010 F411 0000 0000 0000 7A04", + "0111 FEF7 0010 F63D 0000 0000 0000 7C03", + "012A FFFF 007E F36C 0000 0000 0000 2000", + "009D 0000 007E F374 0000 0000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 1, Room 8", + "Start": "01F7F000", + "End": "01F88400", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "002B", + "001F", + "001B", + "0038", + "015C", + "0024", + "0031", + "00A2", + "0154", + "0179", + "012B" + ], + "Actors": [ + "0054 050A 0010 F09A 0000 4000 0000 FFFF", + "0054 051D 0010 F0C4 0000 4000 0000 FFFF", + "0054 0540 0010 F0E1 0000 4000 0000 FFFF", + "0054 0525 0010 F103 0000 4000 0000 FFFF", + "0054 0541 0010 F128 0000 4000 0000 FFFF", + "0054 051D 0010 F148 0000 4000 0000 FFFF", + "0054 053B 0010 F160 0000 4000 0000 FFFF", + "01B4 04A9 0042 F0FF 4000 C000 0000 FF01", + "01B4 04F9 0010 F0FF 4000 4000 0000 1901", + "0125 06E5 0010 F09C 0000 0000 0000 FF01", + "0049 0677 0010 F196 0000 0000 0000 2FFC", + "0049 06B0 0010 F194 0000 0000 0000 2FFC", + "0049 06EA 0010 F193 0000 0000 0000 2FFC", + "002F 0530 004C F324 0000 349F 0000 FFFF", + "002F 06AB 004C F340 0000 D777 0000 FFFF", + "0025 0616 0010 F22C 0000 0000 0000 FFFF", + "0095 0611 00C4 F194 0000 0000 0000 8201", + "012A 0452 0094 F082 4000 0000 0000 1903", + "012A 06AD 0010 F133 0000 0000 0000 3C03", + "0111 03ED 004C F181 0000 0000 0000 4003", + "0111 042A 004C F181 0000 0000 0000 4212", + "0111 06DE 004C F386 0000 0000 0000 6E04", + "0111 04C7 004C F383 0000 0000 0000 7804", + "0185 06AE 0045 F132 0000 0000 002C FFFF", + "004C 04FC 0057 F087 4000 0000 0000 FFFF", + "004C 04D8 009B F085 4000 0000 0000 FFFF", + "004C 04AF 00D8 F084 4000 0000 0000 FFFF", + "004C 0487 00C4 F0AF 0000 0000 0000 FFFF", + "004C 046D 009E F0AF 4000 C000 0000 FFFF", + "009D 0509 0010 F259 0000 0000 0000 0000", + "009D 06B3 0010 F25A 0000 0000 0000 0000", + "009D 05DE 0010 F259 0000 0000 0000 0000", + "009D 065E 0010 F0D9 0000 C000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 1, Room 9", + "Start": "01F89000", + "End": "01F94550", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "002B", + "018A", + "0031", + "000E", + "0038", + "0168", + "011B", + "0163", + "0024", + "0188", + "00A4", + "0036", + "001F", + "000D", + "0170" + ], + "Actors": [ + "0125 06B1 019B FB22 0000 0000 0000 FF01", + "00FF 0654 015F FD8A 0000 0000 0000 FF40", + "00FF 06CC 015F FE3E 0000 0000 0000 FF40", + "00FF 06CC 015F FEF2 0000 0000 0000 FF40", + "00FF 07EE 015F FEC0 0000 0000 0000 FF40", + "0015 07A3 015F FDAC 0000 0000 0000 3003", + "005E 04E0 0213 FEA0 0000 0000 0000 2400", + "005E 0727 01D7 FF0F 0000 0000 0000 03E7", + "005E 062D 019B FF24 0000 0000 0000 10E7", + "005E 062E 019B FE93 0000 0000 0000 10E7", + "005E 062E 019B FE15 0000 0000 0000 10E7", + "0111 0723 024F FDB5 0000 0000 0000 4C01", + "0111 05FC 024F FB37 0000 0000 0000 4E03", + "000A 0672 024F FDFA 0000 0000 0000 59A3" + ] + }, + { + "File": { + "Name": "Scene 1, Room 10", + "Start": "01F95000", + "End": "01F9CE50", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "002B", + "018A", + "0031", + "000E", + "0038", + "0168", + "011B", + "0163", + "0024", + "0188", + "00A4", + "0036", + "001F", + "000D", + "0170" + ], + "Actors": [ + "0013 0E1F 0245 FEF8 0000 C000 0000 0003", + "0013 0FF8 027F FF06 0000 8E39 0000 0003", + "0013 1011 0247 FE74 0000 07D2 0000 0003", + "0037 0A5F 028B FEBF 0000 C000 0000 0000", + "0037 0CAC 028B FEC2 0000 C000 0000 0000", + "0037 0F00 028B FEBF 0000 C0B6 0000 0000", + "0125 0C75 019B FE1B 0000 0000 0000 FF01", + "0059 10E9 0213 FDFB 0000 F555 0000 A009", + "002F 0BBF 019B FE38 0000 DD28 0000 FFFF", + "002F 0BE8 019B FF52 0000 B6C1 0000 FFFF", + "002F 0BFB 019B FE4B 0000 D8E4 0000 FFFF", + "00FF 0A96 019B FE52 0000 0000 0000 FF40", + "00FF 0B86 0213 FEC0 0000 0000 0000 FF41", + "005E 0E28 0213 FEFA 0000 0000 0000 03E8", + "005E 09FC 0213 FE8E 0000 0000 0000 10A8", + "005E 0ADC 0213 FEF7 0000 0000 0000 10A8", + "0111 0C7B 019B FF65 0000 0000 0000 7210", + "0111 0A90 019B FE1D 0000 0000 0000 7410", + "004C 1028 0242 FE5F 4000 0E39 0000 FFFF", + "000F 0A2A 0213 FEC0 0000 C000 0000 1FD4" + ] + }, + { + "File": { + "Name": "Scene 1, Room 11", + "Start": "01F9D000", + "End": "01F9F080", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "002B", + "0168" + ], + "Actors": [ + "0195 09FD 0000 01BE 0000 8000 0000 0007" + ] + }, + { + "File": { + "Name": "Scene 1, Room 12", + "Start": "01FA0000", + "End": "01FA8730", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "002B", + "018A", + "0031", + "000E", + "0038", + "0168", + "011B", + "0163", + "0024", + "0188", + "00A4", + "0036", + "001F", + "000D", + "0170" + ], + "Actors": [ + "0013 0C11 024F FDA7 0000 8000 0000 0003", + "0013 0D1D 01F3 FBC4 0000 C000 0000 0003", + "0049 0C28 0213 FC67 0000 0000 0000 2FF9", + "0049 0B6E 0213 FC69 0000 0000 0000 2FFA", + "012A 0A99 019B FCE5 0000 0000 0000 3903", + "0111 0CFF 019B FCDB 0000 0000 0000 7610", + "0111 0CFE 019B FD0F 0000 0000 0000 7801", + "012A 0AB3 019B FBDC 0000 0000 0000 3A00", + "004C 0C10 0227 FD6E 0000 0000 0000 FFFF", + "0127 0AB1 019B FBDE 0000 0000 0000 8004", + "01A0 0AD8 019B FCD6 0000 4000 0000 FFFF", + "01A0 0C77 019B FC7F 0000 0000 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 1, Room 13", + "Start": "01FA9000", + "End": "01FAB480", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "002B", + "00A4", + "0024", + "000D", + "015C", + "004A", + "012B" + ], + "Actors": [ + "0125 0A36 0064 F2C5 0000 0000 0000 FF01", + "0125 0A54 0064 F2D8 0000 0000 0000 FF01", + "0060 0915 0064 F38C 0000 0000 0000 FF00", + "0060 09F2 0064 F38C 0000 0000 0000 FF00", + "0013 0980 0145 F312 0000 0000 0000 0000", + "0095 0895 01B8 F2C2 0000 4000 0000 8202" + ] + }, + { + "File": { + "Name": "Scene 1, Room 14", + "Start": "01FAC000", + "End": "01FAE490", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "002B", + "012B", + "00A2", + "000E", + "0009" + ], + "Actors": [ + "0125 0505 004C EDAB 0000 0000 0000 FF01", + "000D 05C0 004C EE8D 0000 0000 0000 0000", + "0111 067F 004C EF29 0000 0000 0000 7004", + "0111 0670 004C EDAA 0000 0000 0000 7E04", + "009D 05C2 004C EE32 0000 0000 0000 0000", + "000A 05C1 004C EE21 0000 8000 0000 5541" + ] + }, + { + "File": { + "Name": "Scene 1, Room 15", + "Start": "01FAF000", + "End": "01FB1850", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "002B", + "0190", + "0024", + "015C", + "00A8" + ], + "Actors": [ + "0095 F793 0027 FF1E 0000 8000 0000 0000", + "0037 F7F4 0168 FE40 0000 8000 0000 0000", + "0037 F85A 0168 FF08 0000 8000 0000 0000", + "0037 F922 0168 FEA0 0000 8000 0000 0000", + "0095 F920 0000 FF02 0000 8000 0000 8208", + "01D1 F792 0000 FE2A 0000 0000 0000 88FF", + "01D1 F792 0000 FE8E 0000 0000 0000 88FF", + "01D1 F792 0000 FEF2 0000 0000 0000 88FF", + "01D1 F7F6 0000 FEF2 0000 0000 0000 88FF", + "01D1 F7F6 0000 FE8E 0000 0000 0000 88FF", + "01D1 F7F6 0000 FE2A 0000 0000 0000 88FF", + "01D1 F85A 0000 FEF2 0000 0000 0000 88FF", + "01D1 F85A 0000 FE8E 0000 0000 0000 88FF", + "01D1 F85A 0000 FE2A 0000 0000 0000 88FF", + "01D1 F8BE 0000 FEF2 0000 0000 0000 88FF", + "01D1 F8BE 0000 FE8E 0000 0000 0000 88FF", + "01D1 F8BE 0000 FE2A 0000 0000 0000 88FF", + "01D1 F922 0000 FE8E 0000 0000 0000 88FF", + "01D1 F922 0000 FE2A 0000 0000 0000 88FF", + "01D1 F922 0000 FEF2 0000 0000 0000 88FF" + ] + }, + { + "File": { + "Name": "Scene 1, Room 16", + "Start": "01FB2000", + "End": "01FB7550", + "RemapStart": null + }, + "Id": 16, + "Objects": [ + "002B", + "001F", + "001B", + "0059", + "0038", + "0179", + "00A4", + "015C", + "0024" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": true, + "Polys": [ + { + "Id": 778, + "Type": 14, + "Flags": 0 + }, + { + "Id": 779, + "Type": 14, + "Flags": 0 + }, + { + "Id": 798, + "Type": 15, + "Flags": 0 + }, + { + "Id": 799, + "Type": 15, + "Flags": 0 + }, + { + "Id": 800, + "Type": 15, + "Flags": 0 + }, + { + "Id": 801, + "Type": 15, + "Flags": 0 + }, + { + "Id": 802, + "Type": 15, + "Flags": 0 + }, + { + "Id": 803, + "Type": 15, + "Flags": 0 + }, + { + "Id": 804, + "Type": 15, + "Flags": 0 + }, + { + "Id": 805, + "Type": 15, + "Flags": 0 + }, + { + "Id": 806, + "Type": 15, + "Flags": 0 + }, + { + "Id": 807, + "Type": 15, + "Flags": 0 + }, + { + "Id": 808, + "Type": 15, + "Flags": 0 + }, + { + "Id": 809, + "Type": 15, + "Flags": 0 + }, + { + "Id": 810, + "Type": 15, + "Flags": 0 + }, + { + "Id": 811, + "Type": 15, + "Flags": 0 + }, + { + "Id": 812, + "Type": 15, + "Flags": 0 + }, + { + "Id": 813, + "Type": 15, + "Flags": 0 + }, + { + "Id": 814, + "Type": 15, + "Flags": 0 + }, + { + "Id": 815, + "Type": 15, + "Flags": 0 + }, + { + "Id": 816, + "Type": 16, + "Flags": 0 + }, + { + "Id": 820, + "Type": 15, + "Flags": 0 + }, + { + "Id": 821, + "Type": 15, + "Flags": 0 + }, + { + "Id": 822, + "Type": 17, + "Flags": 0 + }, + { + "Id": 848, + "Type": 18, + "Flags": 0 + }, + { + "Id": 849, + "Type": 18, + "Flags": 0 + }, + { + "Id": 978, + "Type": 19, + "Flags": 0 + }, + { + "Id": 999, + "Type": 14, + "Flags": 0 + }, + { + "Id": 1000, + "Type": 14, + "Flags": 0 + }, + { + "Id": 1043, + "Type": 14, + "Flags": 0 + }, + { + "Id": 1044, + "Type": 14, + "Flags": 0 + }, + { + "Id": 1069, + "Type": 14, + "Flags": 0 + }, + { + "Id": 1070, + "Type": 14, + "Flags": 0 + }, + { + "Id": 1199, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1200, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1245, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1246, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1247, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1248, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1249, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1250, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1251, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1252, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1300, + "Type": 23, + "Flags": 0 + }, + { + "Id": 1301, + "Type": 23, + "Flags": 0 + }, + { + "Id": 1308, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1309, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1310, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1311, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1312, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1313, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1314, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1315, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1316, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1317, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1318, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1319, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1320, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1321, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1322, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1323, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1324, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1325, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1326, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1327, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1328, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1329, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1332, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1333, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1340, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1341, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1387, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1388, + "Type": 26, + "Flags": 0 + }, + { + "Id": 1389, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1390, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1397, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1398, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1409, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1410, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1411, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1412, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1415, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1416, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1431, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1432, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1433, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1434, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1455, + "Type": 29, + "Flags": 0 + }, + { + "Id": 1456, + "Type": 29, + "Flags": 0 + }, + { + "Id": 1470, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1471, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1472, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1473, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1476, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1477, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1478, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1486, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1487, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1488, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1491, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1492, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1493, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1494, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1495, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1496, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1513, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1514, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1515, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1516, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1517, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1518, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1521, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1522, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1523, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1531, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1532, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1533, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1538, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1539, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1540, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1541, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1550, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1551, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1552, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1553, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1554, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1563, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1564, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1565, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1566, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1567, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1568, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1569, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1605, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1606, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1607, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1608, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1609, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1610, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1611, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1612, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1613, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1614, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1615, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1616, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1617, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1618, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1619, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1620, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1621, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1622, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1623, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1624, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1625, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1626, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1627, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1628, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1629, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1630, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1631, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1632, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1633, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1634, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1635, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1636, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1637, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1638, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1639, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1640, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1641, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1642, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1643, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1644, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1645, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1646, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1647, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1648, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1649, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1650, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1651, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1652, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1653, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1654, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1655, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1656, + "Type": 29, + "Flags": 0 + }, + { + "Id": 1657, + "Type": 29, + "Flags": 0 + }, + { + "Id": 1680, + "Type": 35, + "Flags": 0 + }, + { + "Id": 1681, + "Type": 35, + "Flags": 0 + }, + { + "Id": 1682, + "Type": 35, + "Flags": 0 + }, + { + "Id": 1683, + "Type": 35, + "Flags": 0 + }, + { + "Id": 1684, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1722, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1723, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1724, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1725, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1740, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1741, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1742, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1743, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1763, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1764, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1765, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1766, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1787, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1788, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1791, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1792, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1797, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1798, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1801, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1802, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1803, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1804, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1805, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1806, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1807, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1808, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1836, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1837, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1838, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1839, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1840, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1841, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1842, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1843, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1871, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1872, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1873, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1874, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1875, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1876, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1877, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1892, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1893, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1894, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1915, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1916, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1927, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1928, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1929, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1930, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1931, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1932, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1933, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1934, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1965, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1966, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1967, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1968, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1969, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1970, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1971, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1972, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1973, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1974, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1975, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1976, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1977, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1978, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1979, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1980, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2037, + "Type": 37, + "Flags": 0 + }, + { + "Id": 2038, + "Type": 37, + "Flags": 0 + }, + { + "Id": 2041, + "Type": 37, + "Flags": 0 + }, + { + "Id": 2042, + "Type": 37, + "Flags": 0 + }, + { + "Id": 2059, + "Type": 39, + "Flags": 0 + }, + { + "Id": 2060, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2061, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2062, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2063, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2064, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2065, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2066, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2067, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2068, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2069, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2070, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2071, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2072, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2073, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2074, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2075, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2076, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2077, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2078, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2079, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2080, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2081, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2082, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2083, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2084, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2085, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2086, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2087, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2088, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2089, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2090, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2091, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2092, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2093, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2094, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2095, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2096, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2097, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2098, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2099, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2100, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2101, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2102, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2103, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2104, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2105, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2106, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2107, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2108, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2109, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2110, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2111, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2112, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2113, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2114, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2115, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2116, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2117, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2118, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2119, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2120, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2121, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2122, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2123, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2124, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2125, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2126, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2127, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2128, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2129, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2130, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2131, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2132, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2133, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2134, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2135, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2136, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2144, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2145, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2146, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2147, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2148, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2149, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2150, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2151, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2152, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2153, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2193, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2194, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2195, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2196, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2200, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2201, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2202, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2203, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2204, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2205, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2206, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2207, + "Type": 35, + "Flags": 0 + }, + { + "Id": 2216, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2217, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2218, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2219, + "Type": 24, + "Flags": 0 + }, + { + "Id": 2242, + "Type": 40, + "Flags": 0 + }, + { + "Id": 2243, + "Type": 40, + "Flags": 0 + }, + { + "Id": 2470, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2471, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2480, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2481, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2531, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2532, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2533, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2534, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2535, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2536, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2537, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2538, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2539, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2550, + "Type": 25, + "Flags": 0 + }, + { + "Id": 2551, + "Type": 25, + "Flags": 0 + }, + { + "Id": 2566, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2567, + "Type": 41, + "Flags": 0 + }, + { + "Id": 2568, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2569, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2576, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2577, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2578, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2579, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2580, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2581, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2582, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2583, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2584, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2585, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2586, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2587, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2588, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2589, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2590, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2591, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2592, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2593, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2594, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2595, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2596, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2597, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2598, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2599, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2600, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2601, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2602, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2603, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2604, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2605, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2606, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2607, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2608, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2609, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2610, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2611, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2612, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2613, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2614, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2615, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2616, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2617, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2618, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2619, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2620, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2621, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2622, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2623, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2624, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2625, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2626, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2627, + "Type": 38, + "Flags": 0 + }, + { + "Id": 2628, + "Type": 37, + "Flags": 0 + }, + { + "Id": 2629, + "Type": 37, + "Flags": 0 + }, + { + "Id": 2630, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2631, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2632, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2633, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2642, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2643, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2644, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2645, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2646, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2647, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2648, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2649, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2650, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2651, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2652, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2653, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2654, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2655, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2656, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2657, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2702, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2703, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2704, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2705, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2706, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2707, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2708, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2709, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2736, + "Type": 42, + "Flags": 1 + }, + { + "Id": 2737, + "Type": 42, + "Flags": 1 + }, + { + "Id": 2738, + "Type": 21, + "Flags": 1 + }, + { + "Id": 2739, + "Type": 21, + "Flags": 1 + }, + { + "Id": 2762, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2763, + "Type": 32, + "Flags": 0 + }, + { + "Id": 2764, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2765, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2766, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2767, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2768, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2769, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2770, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2771, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2772, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2773, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2774, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2775, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2776, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2777, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2778, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2779, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2780, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2781, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2834, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2835, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2848, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2849, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2856, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2857, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2862, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2863, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2864, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2865, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2866, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2867, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2868, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2869, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2870, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2871, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2872, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2873, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2905, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2908, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2909, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2914, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2915, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2916, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2917, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2918, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2919, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2922, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2923, + "Type": 29, + "Flags": 0 + }, + { + "Id": 2924, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2925, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2926, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2927, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2928, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2929, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2960, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2961, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2967, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2968, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2969, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2970, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2971, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2972, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2974, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2975, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2976, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2977, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2978, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2979, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2993, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2994, + "Type": 44, + "Flags": 0 + }, + { + "Id": 3010, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3011, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3022, + "Type": 48, + "Flags": 0 + }, + { + "Id": 3023, + "Type": 48, + "Flags": 0 + }, + { + "Id": 3026, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3027, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3030, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3031, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3036, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3037, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3046, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3047, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3054, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3055, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3056, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3057, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3058, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3059, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3060, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3061, + "Type": 46, + "Flags": 0 + }, + { + "Id": 3105, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3106, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3107, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3108, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3114, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3115, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3138, + "Type": 14, + "Flags": 0 + }, + { + "Id": 3139, + "Type": 14, + "Flags": 0 + }, + { + "Id": 3163, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3164, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3169, + "Type": 51, + "Flags": 0 + }, + { + "Id": 3170, + "Type": 51, + "Flags": 0 + }, + { + "Id": 3188, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3189, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3190, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3227, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3228, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3229, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3230, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3231, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3239, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3240, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3241, + "Type": 52, + "Flags": 0 + }, + { + "Id": 3242, + "Type": 52, + "Flags": 0 + }, + { + "Id": 3315, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3316, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3317, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3318, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3319, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3320, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3321, + "Type": 42, + "Flags": 1 + }, + { + "Id": 3322, + "Type": 42, + "Flags": 1 + }, + { + "Id": 3323, + "Type": 21, + "Flags": 1 + }, + { + "Id": 3324, + "Type": 21, + "Flags": 1 + }, + { + "Id": 3325, + "Type": 42, + "Flags": 1 + }, + { + "Id": 3326, + "Type": 42, + "Flags": 1 + }, + { + "Id": 3327, + "Type": 21, + "Flags": 1 + }, + { + "Id": 3328, + "Type": 21, + "Flags": 1 + }, + { + "Id": 3329, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3330, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3331, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3332, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3333, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3334, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3360, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3361, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3362, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3363, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3379, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3380, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3381, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3382, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3391, + "Type": 30, + "Flags": 0 + }, + { + "Id": 3392, + "Type": 30, + "Flags": 0 + }, + { + "Id": 3417, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3418, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3419, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3420, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3421, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3422, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3423, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3424, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3429, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3430, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3437, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3438, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3455, + "Type": 32, + "Flags": 0 + }, + { + "Id": 3456, + "Type": 32, + "Flags": 0 + }, + { + "Id": 3499, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3500, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3501, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3502, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3503, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3504, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3505, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3506, + "Type": 47, + "Flags": 0 + }, + { + "Id": 3507, + "Type": 30, + "Flags": 0 + }, + { + "Id": 3508, + "Type": 30, + "Flags": 0 + }, + { + "Id": 3529, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3530, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3531, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3532, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3543, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3544, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3545, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3552, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3553, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3560, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3561, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3566, + "Type": 53, + "Flags": 0 + }, + { + "Id": 3569, + "Type": 29, + "Flags": 0 + }, + { + "Id": 3570, + "Type": 29, + "Flags": 0 + }, + { + "Id": 3605, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3606, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3611, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3612, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3623, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3624, + "Type": 28, + "Flags": 0 + }, + { + "Id": 3635, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3636, + "Type": 43, + "Flags": 0 + }, + { + "Id": 3659, + "Type": 32, + "Flags": 0 + }, + { + "Id": 3660, + "Type": 32, + "Flags": 0 + }, + { + "Id": 3661, + "Type": 54, + "Flags": 0 + }, + { + "Id": 3662, + "Type": 54, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 10, + "High": 1, + "Low": 14272 + }, + { + "Id": 12, + "High": 2, + "Low": 30656 + }, + { + "Id": 13, + "High": 2, + "Low": 14272 + }, + { + "Id": 14, + "High": 3, + "Low": 14272 + }, + { + "Id": 15, + "High": 16385, + "Low": 30663 + }, + { + "Id": 16, + "High": 16384, + "Low": 22464 + }, + { + "Id": 17, + "High": 16384, + "Low": 22471 + }, + { + "Id": 18, + "High": 1, + "Low": 30666 + }, + { + "Id": 19, + "High": 3, + "Low": 30656 + }, + { + "Id": 20, + "High": 258, + "Low": 800704 + }, + { + "Id": 21, + "High": 4194304, + "Low": 151690 + }, + { + "Id": 22, + "High": 6291456, + "Low": 20618 + }, + { + "Id": 23, + "High": 2, + "Low": 12362 + }, + { + "Id": 24, + "High": 1, + "Low": 20544 + }, + { + "Id": 25, + "High": 2, + "Low": 12352 + }, + { + "Id": 26, + "High": 1, + "Low": 12352 + }, + { + "Id": 27, + "High": 2, + "Low": 20544 + }, + { + "Id": 28, + "High": 2, + "Low": 12416 + }, + { + "Id": 29, + "High": 0, + "Low": 20610 + }, + { + "Id": 30, + "High": 2, + "Low": 20618 + }, + { + "Id": 31, + "High": 2, + "Low": 20610 + }, + { + "Id": 32, + "High": 1, + "Low": 20608 + }, + { + "Id": 33, + "High": 8388608, + "Low": 20618 + }, + { + "Id": 34, + "High": 0, + "Low": 20618 + }, + { + "Id": 35, + "High": 16385, + "Low": 20736 + }, + { + "Id": 36, + "High": 16384, + "Low": 20736 + }, + { + "Id": 37, + "High": 0, + "Low": 20544 + }, + { + "Id": 38, + "High": 1, + "Low": 20546 + }, + { + "Id": 39, + "High": 16385, + "Low": 20743 + }, + { + "Id": 40, + "High": 3, + "Low": 20544 + }, + { + "Id": 41, + "High": 2, + "Low": 12354 + }, + { + "Id": 42, + "High": 6291456, + "Low": 151690 + }, + { + "Id": 43, + "High": 1, + "Low": 12416 + }, + { + "Id": 44, + "High": 1, + "Low": 12418 + }, + { + "Id": 45, + "High": 0, + "Low": 12418 + }, + { + "Id": 46, + "High": 2, + "Low": 12418 + }, + { + "Id": 47, + "High": 2, + "Low": 20608 + }, + { + "Id": 48, + "High": 0, + "Low": 12416 + }, + { + "Id": 49, + "High": 3, + "Low": 22464 + }, + { + "Id": 50, + "High": 1, + "Low": 22464 + }, + { + "Id": 51, + "High": 2, + "Low": 14282 + }, + { + "Id": 52, + "High": 4, + "Low": 22464 + }, + { + "Id": 53, + "High": 3, + "Low": 20608 + }, + { + "Id": 54, + "High": 512, + "Low": 12448 + } + ], + "Cams": [ + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 3, + "IconPoints": [ + { + "Flag": 2, + "x": 55, + "y": -36 + }, + { + "Flag": 3, + "x": 54, + "y": -51 + }, + { + "Flag": 5, + "x": 13, + "y": -61 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 3, + "IconPoints": [ + { + "Flag": 0, + "x": 47, + "y": -40 + }, + { + "Flag": 1, + "x": 51, + "y": -3 + }, + { + "Flag": 4, + "x": 47, + "y": -47 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 23, + "y": -25 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 0, + "x": 69, + "y": 14 + }, + { + "Flag": 4, + "x": 69, + "y": 30 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 5, + "x": 54, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 69, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 37, + "y": 49 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 3, + "x": 59, + "y": 53 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 68, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 2", + "Start": "0273E000", + "End": "027537C0", + "RemapStart": null + }, + "Id": 2, + "TActors": [ + "0FFF 05FF 002E 0550 FF10 F7B9 0000 0094", + "01FF 00FF 002E 0000 FF10 FB99 0000 0095", + "02FF 01FF 002E 0000 FEFC F675 0000 0099", + "04FF 06FF 002E FAB0 00A0 F714 8000 00A0", + "07FF 02FF 002E 0000 FEFC F071 0000 0093", + "07FF 0CFF 002E FD6C FEFC EBC1 8000 003F", + "08FF 07FF 002E 0000 FEFC EB49 0000 008D", + "07FF 0BFF 002E 0294 FEFC EBC1 8000 0081", + "01FF 04FF 002E FD94 00A0 F959 C000 0092", + "05FF 01FF 002E 026C FF10 F959 C000 003F", + "0AFF 07FF 002E FBDC FEFC EDB5 4000 003F", + "09FF 07FF 002E 0424 FEFC EDB5 C000 003F", + "0EFF 03FF 002E 01CC FBF7 F369 C000 00BC", + "03FF 0DFF 002E FDBB FBF7 F54A DD28 00BB", + "0EFF 01FF 002E 0139 FB7F F959 C000 003F", + "02FF 03FF 0023 FFD8 FD82 F3F5 4000 00BF", + "02FF 03FF 0023 0028 FD82 F305 4000 00BF", + "02FF 03FF 0023 FEFC FD82 F2B5 4000 00BF", + "02FF 03FF 0023 FED4 FD82 F4D1 4000 00BF", + "02FF 03FF 0023 00DC FD82 F37D 4000 00BF", + "02FF 03FF 0023 FFC4 FD82 F229 4000 00BF", + "03FF 06FF 002E FC17 FC59 F2F1 C000 009F" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 2, Room 0", + "Start": "02754000", + "End": "02758070", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0096", + "018B", + "012B", + "000E", + "0163", + "0007", + "0012", + "013A", + "0190", + "00A8", + "0031" + ], + "Actors": [ + "000E FFFE FEB6 FF20 0000 0000 0000 FF00", + "0125 00D5 FEB6 FE72 0000 0000 0000 FF01", + "0125 FF25 FEAC FFC3 0000 0000 0000 FF01", + "01C6 00E8 FF2D FDC3 0000 E666 0000 0000", + "01C6 FF20 FF2D FDBB 0000 199A 0000 0000", + "00E6 FFFE FEAB FECF 0000 0000 0000 3D02", + "0127 FFFF FEAC FED8 0000 0000 0000 0000", + "002D FF25 FF10 FE68 0000 0000 0000 FFFF", + "002D FEF7 FF9D FE99 0000 0000 0000 FFFF", + "002D FF05 FF42 FEF5 0000 0000 0000 FFFF", + "0173 00C5 FF4A FDF1 0000 0019 0001 3F00", + "0173 FF35 FF4A FDE7 0000 0016 0001 3F00", + "000A 00C8 FF10 FF10 0000 4000 0018 8045", + "0112 FF37 FF44 FDE6 0000 0000 0004 1915", + "0112 00C7 FF44 FDF4 0000 0000 0004 1918", + "0111 FF49 FEB6 FE3F 0000 0000 0000 7804", + "0111 00CA FEAC FFC2 0000 0000 0000 640C", + "000A 0000 FEAC FF91 0000 0000 003D B823" + ] + }, + { + "File": { + "Name": "Scene 2, Room 1", + "Start": "02759000", + "End": "0275EE90", + "RemapStart": "27581B0" + }, + "Id": 1, + "Objects": [ + "0096", + "018B", + "012B", + "000E", + "0021", + "0026", + "00D5", + "00AC", + "00B7", + "0059", + "013A" + ], + "Actors": [ + "0015 FE7A F9EF F961 0000 0000 0000 0100", + "0015 FE19 FA2E F95B 0000 0000 0000 0200", + "0015 FDDB FA80 F953 0000 0000 0000 0300", + "0034 0092 FD3C F904 0000 0000 0000 FFFF", + "0034 FF7A FFB8 F9B2 0000 0000 0000 FFFF", + "00B6 FF54 FEAC F9EF 0000 238E 0000 01FF", + "00B6 FF17 FEB6 F955 0000 0000 0000 01FF", + "00B6 FF4F FEAC F8BE 0000 E4FA 0000 01FF", + "0015 FF27 FEBA F9AC 0000 0000 0000 2703", + "0015 FF32 FEB2 F8FB 0000 0000 0000 2803", + "01C6 FEF2 F9F0 F954 DBBC 6666 EE39 0000", + "01C6 0115 FF06 F8DC 0000 D1C7 0000 0000", + "00C8 0000 FCFD F959 0000 0000 0000 FF01", + "00E6 FED2 F9F0 F967 0000 0000 0000 0F03", + "00E6 FD9C FB2E F8D4 0000 0000 0000 1902", + "00C8 0078 0050 F9D1 0000 0000 0000 1D03", + "018C FF89 FB22 F965 0000 0000 0000 0000", + "0173 00D8 FF27 F8F7 0000 0005 0001 3F00", + "000A 00BF FB2F F907 0000 9111 0000 5042", + "0112 00D8 FF22 F8F7 0000 D1C7 0004 1904", + "015F 0155 FB2F F958 0005 0005 0005 15C6", + "0111 FD4F FB2F F8F8 0000 0000 0000 7208", + "0111 FD4B FB2F F9B2 0000 0000 0000 740C", + "011B 01E4 FEC0 F959 001E 000C 0000 3631", + "000A FD6C FB2F F952 0000 C000 000F B800", + "000A 0161 FF24 F98B 0000 0000 0004 8907", + "00DF 01E4 FEC0 F959 0000 C000 0000 0B80" + ] + }, + { + "File": { + "Name": "Scene 2, Room 2", + "Start": "0275F000", + "End": "027681D0", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0096", + "00A3", + "018B", + "012B", + "0021", + "0012", + "000E", + "0163", + "013A", + "0031", + "00AC", + "0024", + "015C", + "00D5" + ], + "Actors": [ + "0125 FF40 FEAC F377 0000 0000 0000 FF01", + "0125 015E FEAC F232 0000 0000 0000 FF01", + "0034 FFC3 FF60 F33D 0000 0000 0000 FFFF", + "0034 FEFB FF45 F406 0000 0000 0000 FFFF", + "00B6 0000 FE70 F17D 0000 0000 0000 00FF", + "01C6 00EB FF66 F555 0B61 749F 0000 0000", + "00A1 00D8 FEAC F400 0000 0000 0000 0202", + "0127 00F5 FF48 F518 0000 0000 0000 0006", + "0127 015E FEAC F233 0000 0000 0000 0008", + "0127 FF40 FEAC F375 0000 0000 0000 0009", + "0127 00DC FF4A F51A 0000 C93F 0000 0011", + "0127 0112 FF4D F51A 0000 BB06 0000 001A", + "0173 00F8 FF61 F51F 0000 0014 0001 3F00", + "0112 00F8 FF5B F52D 0000 0000 0004 1953" + ] + }, + { + "File": { + "Name": "Scene 2, Room 3", + "Start": "02769000", + "End": "02770160", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0096", + "00A3", + "018B", + "012B", + "0021", + "0012", + "000E", + "0163", + "013A", + "0031", + "00AC", + "0024", + "015C", + "00D5" + ], + "Actors": [ + "0125 0131 FB4A F267 0000 0000 0000 FF01", + "0125 00E7 FB49 F209 0000 0000 0000 FF01", + "0125 FFA5 FB4A F501 0000 0000 0000 FF01", + "0034 FFF6 FB8A F2FE 0000 0000 0000 FFFF", + "01C6 FE81 FC51 F3A9 0000 4444 0000 0000", + "01C6 FED8 FC8B F212 0000 02D8 0000 0000", + "00A1 00DE FBA7 F33A 0000 0000 0000 0203", + "00E6 002C FBA6 F1F4 0000 0000 0000 3C00", + "00E6 FFF1 FB4C F2FE 0000 0000 0000 3A02", + "015F FFF4 FA88 F307 0000 0000 0003 0EBF", + "002D 001A FBCE F268 0000 0000 0000 FFFF", + "000A 010E FCBF F233 0000 5E94 0003 8048", + "000A FF6B FD04 F4F0 0000 F27D 0007 8064", + "0112 FEDF FC84 F236 0000 0000 0004 1983", + "0112 FEE6 FC96 F22B 0000 0000 0004 1983", + "0112 FED2 FC98 F238 0000 0000 0004 1983", + "0112 FE97 FC4D F3AF 0000 0000 0004 1987", + "0112 FEA0 FC59 F3A5 0000 0000 0004 1987", + "0112 FE94 FC4B F39F 0000 0000 0004 1987", + "011B FDD0 FC09 F2F4 001E 000D 0000 382F", + "011B FDED FBA7 F51F 001E 000C 0000 3731", + "00DF FDED FC09 F51F 0000 6000 0000 0B80", + "00DF FDD0 FC09 F2F4 0000 4000 0000 0C81" + ] + }, + { + "File": { + "Name": "Scene 2, Room 4", + "Start": "02771000", + "End": "02775050", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "0096", + "012B", + "011C", + "00D4", + "001B", + "00AC", + "011D", + "018B", + "00CB", + "00DC" + ], + "Actors": [ + "012D FA9B FFEF F7BD 0000 0000 0000 3DC1", + "012D FAC3 FFEF F7BD 0000 0000 0000 3DC1", + "012D FB2B FFAF F9CF 0000 4000 4000 3DC1", + "012D FB03 FFAF F9CE 4000 0000 0000 3DC1", + "0125 FBBF FFD8 FA2F 0000 0000 0000 FF01", + "00B6 FAB7 FFEC F934 0000 0000 0000 00FF", + "00B6 FBA7 FFD8 F951 0000 0000 0000 00FF", + "0025 FB33 0278 FA5A 0000 0000 0000 FFFF", + "01C6 FADC 0100 FB45 0000 80B6 0000 0000", + "01C6 FB17 FF94 F9F0 0000 0000 0000 0000", + "00E6 FCD3 004F F955 0000 0000 0000 1200", + "0110 FAC3 FFF4 F7BC 0000 0000 0000 FFFF", + "0110 FA9B FFF4 F7BD 0000 0000 0000 FFFF", + "0112 FADD 010F FB15 0000 0000 0004 19BD" + ] + }, + { + "File": { + "Name": "Scene 2, Room 5", + "Start": "02776000", + "End": "0277C020", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0096", + "00D4", + "018B", + "011C", + "000E", + "012B", + "00DC", + "00CB", + "015C", + "0024" + ], + "Actors": [ + "012D 05AF FF60 FB7C 0000 0000 0000 3DC1", + "012D 05AF FF05 FB7C 0000 0000 0000 3EC1", + "0125 05C5 FE48 FAAA 0000 0000 0000 FF01", + "0125 069B FE48 F9D8 0000 0000 0000 FF01", + "00DD 0541 0183 FA58 0000 0000 0000 FFFF", + "00DD 066A 01E0 F96A 0000 0000 0000 FFFF", + "01C6 05B0 FF0E FB7C 0000 8000 0000 0000", + "01C6 076A FF65 F968 0000 C000 0000 0000", + "0095 0570 002A F973 5DDE 2222 0000 8302", + "0112 05B2 FF1E FB38 0000 0000 0004 193E", + "0112 0726 FF7A F968 0000 0000 0004 1968", + "0112 05AB FF78 FB2F 0000 0000 0004 1AFD", + "012A 05B0 FFC4 FB5C 0000 0000 0000 1403", + "0111 0519 FEDA F82B 0000 0000 0000 6212", + "000A 050D FF82 F876 0000 BF4A 0028 852A" + ] + }, + { + "File": { + "Name": "Scene 2, Room 6", + "Start": "0277D000", + "End": "02781240", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0096", + "00A3", + "015F", + "0012", + "0021", + "0056", + "0026", + "0090", + "00AD", + "012B", + "018B" + ], + "Actors": [ + "0063 FAA9 019B F646 0000 0000 0000 FFFF", + "01C6 F94F 00CF F2E7 0000 4000 0000 0000", + "00A1 FAB0 FC2C F2F2 0000 4000 0000 0004", + "00C8 FAB0 FBFF F2F1 0000 C000 0000 1F00", + "0125 FBC2 0050 F2EE 0000 0000 0000 FF01", + "0125 FAB0 0050 F1EA 0000 0000 0000 FF01", + "008B FAB0 FC4C F2F1 0000 4000 0000 1015", + "0112 F99F 00E1 F2E9 0000 0000 0004 1920", + "0173 FAB0 FC5E F2F1 0006 0003 0000 3F3A" + ] + }, + { + "File": { + "Name": "Scene 2, Room 7", + "Start": "02782000", + "End": "02785520", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "0096", + "0022", + "00D5", + "0012", + "0056", + "0036", + "012B", + "0163", + "001B" + ], + "Actors": [ + "0025 0000 FEAC ED12 0000 0000 0000 FFFF", + "00A1 0006 FEAC EEFE 0000 8000 0000 0206", + "00E6 0001 FEAB EBC6 0000 0000 0000 0D00", + "0127 FFDB FEAC EBCB 0000 0000 0000 001C", + "0127 001F FEAC EBC7 0000 5BBC 0000 001C", + "0110 FD66 FEAC EDC1 0000 0000 0000 FFFF", + "0110 FE00 FEAC EE10 0000 0000 0000 FFFF", + "000F 033B FEAC EDB1 0000 C000 0000 1FD6", + "011B FCB8 FEAC EDB3 001E 000B 0000 3432", + "011B FD71 FEAC ECA5 001E 000B 0000 3532", + "00DF FD71 FEAC ECA5 0000 0000 0000 0A82", + "00DF FCB8 FEAC EDB3 0000 4000 0000 0A82" + ] + }, + { + "File": { + "Name": "Scene 2, Room 8", + "Start": "02786000", + "End": "02789880", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "0096", + "00A3", + "00D5", + "000E" + ], + "Actors": [ + "0187 FF8F FEAC E9DB 0000 0000 0000 2FFF", + "00DE 0001 0014 E957 0000 0000 0000 0B00" + ] + }, + { + "File": { + "Name": "Scene 2, Room 9", + "Start": "0278A000", + "End": "0278DC70", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "0096", + "00A3", + "00D5", + "000E" + ], + "Actors": [ + "0187 0607 FEAC ED23 0000 0000 0000 2BFF", + "00DE 0619 0014 EDB9 0000 C000 0000 0A02" + ] + }, + { + "File": { + "Name": "Scene 2, Room 10", + "Start": "0278E000", + "End": "02791830", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "0096", + "00A3", + "00D5" + ], + "Actors": [ + "0187 F9EA 0021 EDC8 0000 0000 0000 33FF", + "00DE F9E6 0014 EDB5 0000 4000 0000 0C01" + ] + }, + { + "File": { + "Name": "Scene 2, Room 11", + "Start": "02792000", + "End": "02795800", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "0096", + "00A3", + "000E", + "018B", + "00A8", + "0190", + "00D4", + "012B", + "011C", + "00CB", + "00DC", + "0090", + "00A4" + ], + "Actors": [ + "012D 03A5 012E E9DB 0000 0000 0000 25C1", + "012D 03A5 012E EA03 0000 0000 0000 25C1", + "012D 0182 012D E9DB 0000 0000 0000 27C1", + "012D 0182 012D EA02 0000 0000 0000 27C1", + "0125 028C FEAC E9C9 0000 0000 0000 FF01", + "00DD 03EB 00E0 E9F1 0000 C000 0000 FFFF", + "00DD 0144 00CF E9EC 0000 0000 0000 FFFF", + "01C6 014E FF36 E9F3 0000 5333 0000 0000", + "01C6 03DC FF17 E9DF 0000 CD83 0000 0000", + "005E 0316 FEAC EB04 0AAB 8000 0000 03C1", + "0187 0274 FFC4 EAA4 0000 0000 0000 07FF", + "01D1 03EB 006F E9EF 0000 0000 0000 80FF", + "01D1 03EB 00CA EA48 0000 0000 0000 80FF", + "01D1 0446 00CA E9EE 0000 0000 0000 80FF", + "01D1 03EA 00C9 E993 0000 0000 0000 80FF", + "01D1 013F 00CA E994 0000 0000 0000 80FF", + "01D1 00E6 00CA E9ED 0000 0000 0000 80FF", + "01D1 013F 00CA EA46 0000 0000 0000 80FF", + "01D1 013F 006C E9ED 0000 0000 0000 80FF", + "0112 03AD FF1B E9F2 0000 0000 0004 18E5", + "0112 03B2 FF21 E9FE 0000 0000 0004 18E5", + "0112 03B2 FF21 E9E5 0000 0000 0004 18E5", + "0112 017B FF38 E9E5 0000 0000 0004 19A7", + "0112 0178 FF43 E9EC 0000 0000 0004 19A7", + "0112 0179 FF44 E9DA 0000 0000 0004 19A7", + "000A 0297 FEAC E8D3 0000 8000 0000 70E9", + "0111 0264 FEC6 E8D4 0000 0000 0000 7A08", + "0112 028D FEAC E9C8 0000 0000 0003 1AFF", + "0112 028C FEAC E9C8 0000 0000 0003 1AFF", + "0112 028D FEAC E9C7 0000 0000 0003 1AFF", + "0111 02CE FEAC E8D7 0000 0000 0000 7E0B" + ] + }, + { + "File": { + "Name": "Scene 2, Room 12", + "Start": "02796000", + "End": "02799CD0", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "0096", + "00A3", + "0190", + "00A8", + "013A", + "012B", + "0024", + "015C", + "0163", + "0022", + "0012" + ], + "Actors": [ + "0095 FC89 FECB E8E8 0000 2000 0000 0000", + "0035 FDD9 FEAC E988 0000 0000 0000 FFFF", + "0035 FD02 FEAC E986 0000 0000 0000 FFFF", + "0035 FD6A FEAC EA4D 0000 0000 0000 FFFF", + "00E6 FD71 FEAB E9CC 0000 038E 0000 3D02", + "01D1 FE14 FF28 E9D0 0000 0000 0000 38FF", + "015F FD71 FDDB E9CD 0000 0000 0003 0F7F", + "0127 FE65 FF96 E9CE 0000 0000 0000 000E", + "0127 FC8B FEAC E8ED 0000 0000 0000 0010", + "002D FDEE FFC9 E92F 0000 0000 0000 FFFF", + "002D FCC6 FF58 EA37 0000 0000 0000 FFFF", + "0095 FE71 FFC5 E9C6 9E94 4EEF 0000 8304" + ] + }, + { + "File": { + "Name": "Scene 2, Room 13", + "Start": "0279A000", + "End": "0279CB50", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "0096", + "00A3", + "0026", + "000D", + "011C", + "0036", + "0024", + "015C" + ], + "Actors": [ + "012D FBEC FB0F F6E4 0000 1D28 0000 05C1", + "0013 FBE1 FBA7 F796 0000 0000 0000 8003", + "0013 FAEC FC32 F6AA 0000 3DDE 0000 8003", + "0013 FBBA FC33 F5B3 0000 1BBC 0000 8003", + "00E6 FB98 FB2E F62A 0000 0000 0000 3B02", + "018C FC25 FB4D F5D4 0000 E38E 0000 0000", + "018C FC99 FB75 F6F4 0000 A38E 0000 0000", + "0187 FC20 FB2F F6B6 0000 0000 0000 17FF", + "000F FB85 FBA7 F73D 0000 5DDE 0000 1FFE", + "000F FB83 FBA7 F73E 0000 DDDE 0000 1FFE", + "0095 FB43 FBEF F772 C000 DDDE 0000 8308" + ] + }, + { + "File": { + "Name": "Scene 2, Room 14", + "Start": "0279D000", + "End": "027A31E0", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "0096", + "000E", + "0026", + "001B", + "0190", + "00A8", + "012B", + "00D4", + "00CB", + "00DC", + "015C", + "0024", + "0090", + "0059", + "013A" + ], + "Actors": [ + "003A 0438 FAFD F72B 0000 8000 0000 000A", + "003A 039B FAF3 F6CD 0000 0000 0000 000A", + "0125 04CC FB57 F5A9 0000 0000 0000 FF01", + "00DD 04DE FAF3 F65A 0000 0000 0000 FFFF", + "0025 03A0 FB7F F370 0000 C7D2 0000 FFFF", + "00E6 04D8 FAF2 F6B1 0000 0000 0000 3902", + "00C8 044C FAFD F6B1 0000 0000 0000 3902", + "01D1 03AD FAF3 F5FC 0000 0000 0000 B8FF", + "000A 0508 FB57 F5B1 0000 0000 0000 5041", + "0095 03AC FAF3 F5E8 0000 0000 0000 8301", + "0111 02B9 FC73 F6F2 0000 0000 0000 6604", + "015F 044A FB36 F91C 0005 0005 0005 15C6", + "015F 024C FBCF F6AF 0005 0005 0002 15C6", + "000A 02BB FBCF F6B8 0000 C000 0000 10C6", + "0111 02BB FBE9 F673 0000 0000 0000 6808" + ] + }, + { + "File": { + "Name": "Scene 2, Room 15", + "Start": "027A4000", + "End": "027A66E0", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "0096", + "00A3", + "0007", + "0012", + "0021", + "0056", + "0026", + "00AC" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": true, + "Polys": [ + { + "Id": 69, + "Type": 2, + "Flags": 0 + }, + { + "Id": 77, + "Type": 2, + "Flags": 0 + }, + { + "Id": 78, + "Type": 3, + "Flags": 0 + }, + { + "Id": 79, + "Type": 3, + "Flags": 0 + }, + { + "Id": 81, + "Type": 2, + "Flags": 0 + }, + { + "Id": 82, + "Type": 2, + "Flags": 0 + }, + { + "Id": 83, + "Type": 2, + "Flags": 0 + }, + { + "Id": 84, + "Type": 2, + "Flags": 0 + }, + { + "Id": 85, + "Type": 2, + "Flags": 0 + }, + { + "Id": 86, + "Type": 2, + "Flags": 0 + }, + { + "Id": 95, + "Type": 3, + "Flags": 0 + }, + { + "Id": 97, + "Type": 2, + "Flags": 0 + }, + { + "Id": 98, + "Type": 2, + "Flags": 0 + }, + { + "Id": 100, + "Type": 3, + "Flags": 0 + }, + { + "Id": 109, + "Type": 2, + "Flags": 0 + }, + { + "Id": 110, + "Type": 2, + "Flags": 0 + }, + { + "Id": 111, + "Type": 2, + "Flags": 0 + }, + { + "Id": 112, + "Type": 2, + "Flags": 0 + }, + { + "Id": 113, + "Type": 2, + "Flags": 0 + }, + { + "Id": 114, + "Type": 2, + "Flags": 0 + }, + { + "Id": 116, + "Type": 3, + "Flags": 0 + }, + { + "Id": 117, + "Type": 3, + "Flags": 0 + }, + { + "Id": 118, + "Type": 2, + "Flags": 0 + }, + { + "Id": 126, + "Type": 2, + "Flags": 0 + }, + { + "Id": 130, + "Type": 3, + "Flags": 0 + }, + { + "Id": 132, + "Type": 3, + "Flags": 0 + }, + { + "Id": 143, + "Type": 3, + "Flags": 0 + }, + { + "Id": 144, + "Type": 3, + "Flags": 0 + }, + { + "Id": 145, + "Type": 4, + "Flags": 0 + }, + { + "Id": 146, + "Type": 4, + "Flags": 0 + }, + { + "Id": 157, + "Type": 4, + "Flags": 0 + }, + { + "Id": 158, + "Type": 4, + "Flags": 0 + }, + { + "Id": 159, + "Type": 4, + "Flags": 0 + }, + { + "Id": 160, + "Type": 4, + "Flags": 0 + }, + { + "Id": 161, + "Type": 2, + "Flags": 0 + }, + { + "Id": 162, + "Type": 2, + "Flags": 0 + }, + { + "Id": 167, + "Type": 3, + "Flags": 0 + }, + { + "Id": 173, + "Type": 2, + "Flags": 0 + }, + { + "Id": 174, + "Type": 2, + "Flags": 0 + }, + { + "Id": 175, + "Type": 3, + "Flags": 0 + }, + { + "Id": 176, + "Type": 3, + "Flags": 0 + }, + { + "Id": 177, + "Type": 3, + "Flags": 0 + }, + { + "Id": 183, + "Type": 3, + "Flags": 0 + }, + { + "Id": 184, + "Type": 3, + "Flags": 0 + }, + { + "Id": 185, + "Type": 2, + "Flags": 0 + }, + { + "Id": 186, + "Type": 2, + "Flags": 0 + }, + { + "Id": 187, + "Type": 2, + "Flags": 0 + }, + { + "Id": 188, + "Type": 2, + "Flags": 0 + }, + { + "Id": 197, + "Type": 2, + "Flags": 0 + }, + { + "Id": 198, + "Type": 2, + "Flags": 0 + }, + { + "Id": 199, + "Type": 2, + "Flags": 0 + }, + { + "Id": 200, + "Type": 2, + "Flags": 0 + }, + { + "Id": 201, + "Type": 2, + "Flags": 0 + }, + { + "Id": 202, + "Type": 2, + "Flags": 0 + }, + { + "Id": 203, + "Type": 2, + "Flags": 0 + }, + { + "Id": 204, + "Type": 2, + "Flags": 0 + }, + { + "Id": 271, + "Type": 2, + "Flags": 0 + }, + { + "Id": 272, + "Type": 2, + "Flags": 0 + }, + { + "Id": 273, + "Type": 2, + "Flags": 0 + }, + { + "Id": 274, + "Type": 2, + "Flags": 0 + }, + { + "Id": 275, + "Type": 2, + "Flags": 0 + }, + { + "Id": 276, + "Type": 2, + "Flags": 0 + }, + { + "Id": 277, + "Type": 2, + "Flags": 0 + }, + { + "Id": 278, + "Type": 2, + "Flags": 0 + }, + { + "Id": 287, + "Type": 2, + "Flags": 0 + }, + { + "Id": 288, + "Type": 2, + "Flags": 0 + }, + { + "Id": 289, + "Type": 2, + "Flags": 0 + }, + { + "Id": 290, + "Type": 2, + "Flags": 0 + }, + { + "Id": 291, + "Type": 3, + "Flags": 0 + }, + { + "Id": 292, + "Type": 3, + "Flags": 0 + }, + { + "Id": 298, + "Type": 3, + "Flags": 0 + }, + { + "Id": 299, + "Type": 3, + "Flags": 0 + }, + { + "Id": 300, + "Type": 3, + "Flags": 0 + }, + { + "Id": 301, + "Type": 2, + "Flags": 0 + }, + { + "Id": 302, + "Type": 2, + "Flags": 0 + }, + { + "Id": 308, + "Type": 3, + "Flags": 0 + }, + { + "Id": 313, + "Type": 5, + "Flags": 0 + }, + { + "Id": 314, + "Type": 5, + "Flags": 0 + }, + { + "Id": 317, + "Type": 6, + "Flags": 0 + }, + { + "Id": 318, + "Type": 6, + "Flags": 0 + }, + { + "Id": 321, + "Type": 5, + "Flags": 0 + }, + { + "Id": 322, + "Type": 5, + "Flags": 0 + }, + { + "Id": 323, + "Type": 7, + "Flags": 0 + }, + { + "Id": 324, + "Type": 7, + "Flags": 0 + }, + { + "Id": 325, + "Type": 2, + "Flags": 0 + }, + { + "Id": 326, + "Type": 2, + "Flags": 0 + }, + { + "Id": 327, + "Type": 2, + "Flags": 0 + }, + { + "Id": 328, + "Type": 2, + "Flags": 0 + }, + { + "Id": 329, + "Type": 2, + "Flags": 0 + }, + { + "Id": 330, + "Type": 2, + "Flags": 0 + }, + { + "Id": 331, + "Type": 2, + "Flags": 0 + }, + { + "Id": 332, + "Type": 2, + "Flags": 0 + }, + { + "Id": 333, + "Type": 2, + "Flags": 0 + }, + { + "Id": 334, + "Type": 3, + "Flags": 0 + }, + { + "Id": 335, + "Type": 3, + "Flags": 0 + }, + { + "Id": 336, + "Type": 3, + "Flags": 0 + }, + { + "Id": 337, + "Type": 3, + "Flags": 0 + }, + { + "Id": 338, + "Type": 3, + "Flags": 0 + }, + { + "Id": 339, + "Type": 2, + "Flags": 0 + }, + { + "Id": 340, + "Type": 2, + "Flags": 0 + }, + { + "Id": 341, + "Type": 2, + "Flags": 0 + }, + { + "Id": 342, + "Type": 2, + "Flags": 0 + }, + { + "Id": 343, + "Type": 2, + "Flags": 0 + }, + { + "Id": 344, + "Type": 2, + "Flags": 0 + }, + { + "Id": 345, + "Type": 3, + "Flags": 0 + }, + { + "Id": 346, + "Type": 3, + "Flags": 0 + }, + { + "Id": 347, + "Type": 8, + "Flags": 0 + }, + { + "Id": 348, + "Type": 8, + "Flags": 0 + }, + { + "Id": 349, + "Type": 9, + "Flags": 0 + }, + { + "Id": 350, + "Type": 2, + "Flags": 0 + }, + { + "Id": 351, + "Type": 2, + "Flags": 0 + }, + { + "Id": 352, + "Type": 10, + "Flags": 0 + }, + { + "Id": 353, + "Type": 10, + "Flags": 0 + }, + { + "Id": 354, + "Type": 10, + "Flags": 0 + }, + { + "Id": 355, + "Type": 10, + "Flags": 0 + }, + { + "Id": 356, + "Type": 10, + "Flags": 0 + }, + { + "Id": 357, + "Type": 10, + "Flags": 0 + }, + { + "Id": 358, + "Type": 10, + "Flags": 0 + }, + { + "Id": 359, + "Type": 10, + "Flags": 0 + }, + { + "Id": 360, + "Type": 10, + "Flags": 0 + }, + { + "Id": 361, + "Type": 10, + "Flags": 0 + }, + { + "Id": 362, + "Type": 10, + "Flags": 0 + }, + { + "Id": 363, + "Type": 10, + "Flags": 0 + }, + { + "Id": 364, + "Type": 10, + "Flags": 0 + }, + { + "Id": 365, + "Type": 10, + "Flags": 0 + }, + { + "Id": 366, + "Type": 10, + "Flags": 0 + }, + { + "Id": 367, + "Type": 10, + "Flags": 0 + }, + { + "Id": 368, + "Type": 10, + "Flags": 0 + }, + { + "Id": 369, + "Type": 10, + "Flags": 0 + }, + { + "Id": 370, + "Type": 10, + "Flags": 0 + }, + { + "Id": 371, + "Type": 10, + "Flags": 0 + }, + { + "Id": 372, + "Type": 10, + "Flags": 0 + }, + { + "Id": 373, + "Type": 10, + "Flags": 0 + }, + { + "Id": 374, + "Type": 10, + "Flags": 0 + }, + { + "Id": 375, + "Type": 10, + "Flags": 0 + }, + { + "Id": 376, + "Type": 10, + "Flags": 0 + }, + { + "Id": 377, + "Type": 10, + "Flags": 0 + }, + { + "Id": 378, + "Type": 10, + "Flags": 0 + }, + { + "Id": 379, + "Type": 10, + "Flags": 0 + }, + { + "Id": 380, + "Type": 10, + "Flags": 0 + }, + { + "Id": 381, + "Type": 10, + "Flags": 0 + }, + { + "Id": 382, + "Type": 10, + "Flags": 0 + }, + { + "Id": 383, + "Type": 10, + "Flags": 0 + }, + { + "Id": 384, + "Type": 10, + "Flags": 0 + }, + { + "Id": 385, + "Type": 10, + "Flags": 0 + }, + { + "Id": 386, + "Type": 10, + "Flags": 0 + }, + { + "Id": 387, + "Type": 10, + "Flags": 0 + }, + { + "Id": 388, + "Type": 10, + "Flags": 0 + }, + { + "Id": 389, + "Type": 10, + "Flags": 0 + }, + { + "Id": 390, + "Type": 10, + "Flags": 0 + }, + { + "Id": 391, + "Type": 10, + "Flags": 0 + }, + { + "Id": 418, + "Type": 5, + "Flags": 0 + }, + { + "Id": 421, + "Type": 5, + "Flags": 0 + }, + { + "Id": 433, + "Type": 2, + "Flags": 0 + }, + { + "Id": 434, + "Type": 2, + "Flags": 0 + }, + { + "Id": 456, + "Type": 11, + "Flags": 0 + }, + { + "Id": 457, + "Type": 11, + "Flags": 0 + }, + { + "Id": 458, + "Type": 11, + "Flags": 0 + }, + { + "Id": 508, + "Type": 11, + "Flags": 0 + }, + { + "Id": 509, + "Type": 11, + "Flags": 0 + }, + { + "Id": 510, + "Type": 11, + "Flags": 0 + }, + { + "Id": 511, + "Type": 11, + "Flags": 0 + }, + { + "Id": 512, + "Type": 11, + "Flags": 0 + }, + { + "Id": 538, + "Type": 5, + "Flags": 0 + }, + { + "Id": 539, + "Type": 5, + "Flags": 0 + }, + { + "Id": 540, + "Type": 5, + "Flags": 0 + }, + { + "Id": 551, + "Type": 5, + "Flags": 0 + }, + { + "Id": 552, + "Type": 5, + "Flags": 0 + }, + { + "Id": 571, + "Type": 12, + "Flags": 0 + }, + { + "Id": 573, + "Type": 12, + "Flags": 0 + }, + { + "Id": 577, + "Type": 12, + "Flags": 0 + }, + { + "Id": 578, + "Type": 12, + "Flags": 0 + }, + { + "Id": 579, + "Type": 12, + "Flags": 0 + }, + { + "Id": 589, + "Type": 7, + "Flags": 0 + }, + { + "Id": 590, + "Type": 7, + "Flags": 0 + }, + { + "Id": 591, + "Type": 12, + "Flags": 0 + }, + { + "Id": 592, + "Type": 7, + "Flags": 0 + }, + { + "Id": 593, + "Type": 7, + "Flags": 0 + }, + { + "Id": 594, + "Type": 7, + "Flags": 0 + }, + { + "Id": 595, + "Type": 7, + "Flags": 0 + }, + { + "Id": 626, + "Type": 11, + "Flags": 0 + }, + { + "Id": 627, + "Type": 11, + "Flags": 0 + }, + { + "Id": 636, + "Type": 11, + "Flags": 0 + }, + { + "Id": 637, + "Type": 11, + "Flags": 0 + }, + { + "Id": 638, + "Type": 11, + "Flags": 0 + }, + { + "Id": 639, + "Type": 11, + "Flags": 0 + }, + { + "Id": 646, + "Type": 6, + "Flags": 0 + }, + { + "Id": 647, + "Type": 6, + "Flags": 0 + }, + { + "Id": 648, + "Type": 6, + "Flags": 0 + }, + { + "Id": 649, + "Type": 6, + "Flags": 0 + }, + { + "Id": 650, + "Type": 6, + "Flags": 0 + }, + { + "Id": 661, + "Type": 6, + "Flags": 0 + }, + { + "Id": 662, + "Type": 6, + "Flags": 0 + }, + { + "Id": 712, + "Type": 7, + "Flags": 0 + }, + { + "Id": 713, + "Type": 7, + "Flags": 0 + }, + { + "Id": 724, + "Type": 7, + "Flags": 0 + }, + { + "Id": 725, + "Type": 7, + "Flags": 0 + }, + { + "Id": 726, + "Type": 7, + "Flags": 0 + }, + { + "Id": 727, + "Type": 7, + "Flags": 0 + }, + { + "Id": 752, + "Type": 2, + "Flags": 0 + }, + { + "Id": 753, + "Type": 2, + "Flags": 0 + }, + { + "Id": 754, + "Type": 2, + "Flags": 0 + }, + { + "Id": 759, + "Type": 2, + "Flags": 0 + }, + { + "Id": 760, + "Type": 2, + "Flags": 0 + }, + { + "Id": 771, + "Type": 3, + "Flags": 0 + }, + { + "Id": 772, + "Type": 3, + "Flags": 0 + }, + { + "Id": 773, + "Type": 3, + "Flags": 0 + }, + { + "Id": 774, + "Type": 3, + "Flags": 0 + }, + { + "Id": 775, + "Type": 3, + "Flags": 0 + }, + { + "Id": 776, + "Type": 2, + "Flags": 0 + }, + { + "Id": 779, + "Type": 2, + "Flags": 0 + }, + { + "Id": 780, + "Type": 2, + "Flags": 0 + }, + { + "Id": 782, + "Type": 2, + "Flags": 0 + }, + { + "Id": 783, + "Type": 2, + "Flags": 0 + }, + { + "Id": 830, + "Type": 2, + "Flags": 0 + }, + { + "Id": 831, + "Type": 2, + "Flags": 0 + }, + { + "Id": 839, + "Type": 12, + "Flags": 0 + }, + { + "Id": 840, + "Type": 12, + "Flags": 0 + }, + { + "Id": 841, + "Type": 13, + "Flags": 0 + }, + { + "Id": 842, + "Type": 13, + "Flags": 0 + }, + { + "Id": 843, + "Type": 13, + "Flags": 0 + }, + { + "Id": 844, + "Type": 13, + "Flags": 0 + }, + { + "Id": 852, + "Type": 13, + "Flags": 0 + }, + { + "Id": 853, + "Type": 13, + "Flags": 0 + }, + { + "Id": 874, + "Type": 12, + "Flags": 0 + }, + { + "Id": 875, + "Type": 12, + "Flags": 0 + }, + { + "Id": 882, + "Type": 12, + "Flags": 0 + }, + { + "Id": 883, + "Type": 12, + "Flags": 0 + }, + { + "Id": 888, + "Type": 2, + "Flags": 0 + }, + { + "Id": 889, + "Type": 2, + "Flags": 0 + }, + { + "Id": 894, + "Type": 6, + "Flags": 0 + }, + { + "Id": 896, + "Type": 11, + "Flags": 0 + }, + { + "Id": 897, + "Type": 11, + "Flags": 0 + }, + { + "Id": 898, + "Type": 11, + "Flags": 0 + }, + { + "Id": 899, + "Type": 11, + "Flags": 0 + }, + { + "Id": 900, + "Type": 11, + "Flags": 0 + }, + { + "Id": 901, + "Type": 11, + "Flags": 0 + }, + { + "Id": 902, + "Type": 11, + "Flags": 0 + }, + { + "Id": 903, + "Type": 11, + "Flags": 0 + }, + { + "Id": 904, + "Type": 11, + "Flags": 0 + }, + { + "Id": 905, + "Type": 11, + "Flags": 0 + }, + { + "Id": 906, + "Type": 11, + "Flags": 0 + }, + { + "Id": 907, + "Type": 11, + "Flags": 0 + }, + { + "Id": 908, + "Type": 11, + "Flags": 0 + }, + { + "Id": 909, + "Type": 11, + "Flags": 0 + }, + { + "Id": 910, + "Type": 11, + "Flags": 0 + }, + { + "Id": 911, + "Type": 11, + "Flags": 0 + }, + { + "Id": 912, + "Type": 11, + "Flags": 0 + }, + { + "Id": 913, + "Type": 11, + "Flags": 0 + }, + { + "Id": 914, + "Type": 11, + "Flags": 0 + }, + { + "Id": 915, + "Type": 11, + "Flags": 0 + }, + { + "Id": 916, + "Type": 11, + "Flags": 0 + }, + { + "Id": 917, + "Type": 11, + "Flags": 0 + }, + { + "Id": 918, + "Type": 11, + "Flags": 0 + }, + { + "Id": 919, + "Type": 11, + "Flags": 0 + }, + { + "Id": 920, + "Type": 11, + "Flags": 0 + }, + { + "Id": 921, + "Type": 11, + "Flags": 0 + }, + { + "Id": 922, + "Type": 11, + "Flags": 0 + }, + { + "Id": 923, + "Type": 11, + "Flags": 0 + }, + { + "Id": 924, + "Type": 11, + "Flags": 0 + }, + { + "Id": 925, + "Type": 11, + "Flags": 0 + }, + { + "Id": 926, + "Type": 11, + "Flags": 0 + }, + { + "Id": 927, + "Type": 11, + "Flags": 0 + }, + { + "Id": 928, + "Type": 11, + "Flags": 0 + }, + { + "Id": 929, + "Type": 11, + "Flags": 0 + }, + { + "Id": 930, + "Type": 11, + "Flags": 0 + }, + { + "Id": 931, + "Type": 11, + "Flags": 0 + }, + { + "Id": 932, + "Type": 11, + "Flags": 0 + }, + { + "Id": 933, + "Type": 11, + "Flags": 0 + }, + { + "Id": 934, + "Type": 11, + "Flags": 0 + }, + { + "Id": 935, + "Type": 11, + "Flags": 0 + }, + { + "Id": 936, + "Type": 11, + "Flags": 0 + }, + { + "Id": 937, + "Type": 11, + "Flags": 0 + }, + { + "Id": 938, + "Type": 11, + "Flags": 0 + }, + { + "Id": 939, + "Type": 11, + "Flags": 0 + }, + { + "Id": 940, + "Type": 11, + "Flags": 0 + }, + { + "Id": 941, + "Type": 14, + "Flags": 0 + }, + { + "Id": 942, + "Type": 11, + "Flags": 0 + }, + { + "Id": 943, + "Type": 14, + "Flags": 0 + }, + { + "Id": 944, + "Type": 11, + "Flags": 0 + }, + { + "Id": 945, + "Type": 11, + "Flags": 0 + }, + { + "Id": 946, + "Type": 11, + "Flags": 0 + }, + { + "Id": 947, + "Type": 11, + "Flags": 0 + }, + { + "Id": 948, + "Type": 14, + "Flags": 0 + }, + { + "Id": 949, + "Type": 11, + "Flags": 0 + }, + { + "Id": 950, + "Type": 14, + "Flags": 0 + }, + { + "Id": 951, + "Type": 11, + "Flags": 0 + }, + { + "Id": 952, + "Type": 14, + "Flags": 0 + }, + { + "Id": 953, + "Type": 14, + "Flags": 0 + }, + { + "Id": 958, + "Type": 15, + "Flags": 0 + }, + { + "Id": 959, + "Type": 15, + "Flags": 0 + }, + { + "Id": 960, + "Type": 15, + "Flags": 0 + }, + { + "Id": 961, + "Type": 15, + "Flags": 0 + }, + { + "Id": 962, + "Type": 15, + "Flags": 0 + }, + { + "Id": 963, + "Type": 15, + "Flags": 0 + }, + { + "Id": 964, + "Type": 15, + "Flags": 0 + }, + { + "Id": 965, + "Type": 15, + "Flags": 0 + }, + { + "Id": 966, + "Type": 15, + "Flags": 0 + }, + { + "Id": 967, + "Type": 15, + "Flags": 0 + }, + { + "Id": 968, + "Type": 15, + "Flags": 0 + }, + { + "Id": 969, + "Type": 15, + "Flags": 0 + }, + { + "Id": 970, + "Type": 15, + "Flags": 0 + }, + { + "Id": 971, + "Type": 15, + "Flags": 0 + }, + { + "Id": 972, + "Type": 15, + "Flags": 0 + }, + { + "Id": 973, + "Type": 15, + "Flags": 0 + }, + { + "Id": 974, + "Type": 15, + "Flags": 0 + }, + { + "Id": 975, + "Type": 15, + "Flags": 0 + }, + { + "Id": 976, + "Type": 15, + "Flags": 0 + }, + { + "Id": 977, + "Type": 15, + "Flags": 0 + }, + { + "Id": 984, + "Type": 16, + "Flags": 0 + }, + { + "Id": 985, + "Type": 17, + "Flags": 0 + }, + { + "Id": 986, + "Type": 18, + "Flags": 0 + }, + { + "Id": 987, + "Type": 19, + "Flags": 0 + }, + { + "Id": 988, + "Type": 20, + "Flags": 0 + }, + { + "Id": 989, + "Type": 21, + "Flags": 0 + }, + { + "Id": 990, + "Type": 22, + "Flags": 0 + }, + { + "Id": 991, + "Type": 23, + "Flags": 0 + }, + { + "Id": 992, + "Type": 24, + "Flags": 0 + }, + { + "Id": 993, + "Type": 25, + "Flags": 0 + }, + { + "Id": 994, + "Type": 26, + "Flags": 0 + }, + { + "Id": 995, + "Type": 27, + "Flags": 0 + }, + { + "Id": 996, + "Type": 28, + "Flags": 0 + }, + { + "Id": 997, + "Type": 29, + "Flags": 0 + }, + { + "Id": 998, + "Type": 30, + "Flags": 0 + }, + { + "Id": 999, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1000, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1001, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1002, + "Type": 29, + "Flags": 0 + }, + { + "Id": 1003, + "Type": 28, + "Flags": 0 + }, + { + "Id": 1004, + "Type": 32, + "Flags": 0 + }, + { + "Id": 1005, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1006, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1007, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1008, + "Type": 23, + "Flags": 0 + }, + { + "Id": 1009, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1010, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1011, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1012, + "Type": 19, + "Flags": 0 + }, + { + "Id": 1013, + "Type": 18, + "Flags": 0 + }, + { + "Id": 1014, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1015, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1016, + "Type": 18, + "Flags": 0 + }, + { + "Id": 1017, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1018, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1019, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1020, + "Type": 19, + "Flags": 0 + }, + { + "Id": 1021, + "Type": 35, + "Flags": 0 + }, + { + "Id": 1022, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1023, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1024, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1025, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1026, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1027, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1028, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1029, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1030, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1031, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1032, + "Type": 16, + "Flags": 0 + }, + { + "Id": 1033, + "Type": 17, + "Flags": 0 + }, + { + "Id": 1034, + "Type": 18, + "Flags": 0 + }, + { + "Id": 1035, + "Type": 19, + "Flags": 0 + }, + { + "Id": 1036, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1037, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1038, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1039, + "Type": 23, + "Flags": 0 + }, + { + "Id": 1040, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1041, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1042, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1043, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1044, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1045, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1046, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1047, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1048, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1049, + "Type": 25, + "Flags": 0 + }, + { + "Id": 1050, + "Type": 24, + "Flags": 0 + }, + { + "Id": 1051, + "Type": 27, + "Flags": 0 + }, + { + "Id": 1052, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1053, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1054, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1055, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1056, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1057, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1058, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1059, + "Type": 19, + "Flags": 0 + }, + { + "Id": 1060, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1061, + "Type": 18, + "Flags": 0 + }, + { + "Id": 1062, + "Type": 35, + "Flags": 0 + }, + { + "Id": 1063, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1089, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1090, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1091, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1111, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1112, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1113, + "Type": 44, + "Flags": 0 + }, + { + "Id": 1114, + "Type": 44, + "Flags": 0 + }, + { + "Id": 1115, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1117, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1118, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1119, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1120, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1121, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1122, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1123, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1124, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1125, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1126, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1127, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1128, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1129, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1130, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1131, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1132, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1133, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1134, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1135, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1136, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1137, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1138, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1139, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1140, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1141, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1142, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1143, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1144, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1145, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1146, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1147, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1148, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1149, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1150, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1151, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1152, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1153, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1154, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1155, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1156, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1157, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1158, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1159, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1160, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1161, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1162, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1163, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1164, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1165, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1166, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1167, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1168, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1169, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1170, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1171, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1172, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1173, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1174, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1175, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1176, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1177, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1178, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1179, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1180, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1181, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1182, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1183, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1184, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1185, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1186, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1187, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1188, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1189, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1190, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1191, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1192, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1193, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1194, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1195, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1196, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1197, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1198, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1199, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1200, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1201, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1202, + "Type": 46, + "Flags": 0 + }, + { + "Id": 1215, + "Type": 47, + "Flags": 0 + }, + { + "Id": 1216, + "Type": 47, + "Flags": 0 + }, + { + "Id": 1218, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1219, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1220, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1222, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1223, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1224, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1225, + "Type": 47, + "Flags": 0 + }, + { + "Id": 1226, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1227, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1231, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1245, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1248, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1249, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1254, + "Type": 49, + "Flags": 0 + }, + { + "Id": 1255, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1256, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1257, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1258, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1263, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1264, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1265, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1266, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1267, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1330, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1340, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1341, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1342, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1343, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1344, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1349, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1350, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1450, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1451, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1453, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1454, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1455, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1456, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1457, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1458, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1469, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1470, + "Type": 48, + "Flags": 0 + }, + { + "Id": 1473, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1474, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1475, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1476, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1477, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1478, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1479, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1480, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1481, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1482, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1483, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1484, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1485, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1486, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1487, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1488, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1489, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1490, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1491, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1492, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1493, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1494, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1495, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1496, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1497, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1498, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1499, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1505, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1506, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1508, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1509, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1510, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1511, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1513, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1521, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1522, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1523, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1524, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1525, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1526, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1527, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1528, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1529, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1542, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1543, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1544, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1545, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1546, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1547, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1548, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1549, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1550, + "Type": 12, + "Flags": 0 + }, + { + "Id": 1551, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1552, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1557, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1616, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1617, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1624, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1625, + "Type": 13, + "Flags": 0 + }, + { + "Id": 1817, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1818, + "Type": 11, + "Flags": 0 + }, + { + "Id": 1822, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1823, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1824, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1825, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1826, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1827, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1828, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1829, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1830, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1831, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1832, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1833, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1836, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1837, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1839, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1840, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1841, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1842, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1843, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1847, + "Type": 50, + "Flags": 1 + }, + { + "Id": 1848, + "Type": 51, + "Flags": 1 + }, + { + "Id": 1849, + "Type": 51, + "Flags": 1 + }, + { + "Id": 1850, + "Type": 51, + "Flags": 1 + }, + { + "Id": 1851, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1852, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1853, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1854, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1855, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1856, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1857, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1858, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1859, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1860, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1861, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1862, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1863, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1864, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1865, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1866, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1867, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1868, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1869, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1870, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1872, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1873, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1878, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1879, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1880, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1889, + "Type": 52, + "Flags": 0 + }, + { + "Id": 1890, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1912, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1913, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1914, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1926, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1929, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1942, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1943, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1944, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1945, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1946, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1947, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1948, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1949, + "Type": 10, + "Flags": 0 + }, + { + "Id": 1951, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1952, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1955, + "Type": 50, + "Flags": 0 + }, + { + "Id": 1956, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2024, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2025, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2026, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2027, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2064, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2065, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2068, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2069, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2076, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2077, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2079, + "Type": 52, + "Flags": 0 + }, + { + "Id": 2080, + "Type": 52, + "Flags": 0 + }, + { + "Id": 2081, + "Type": 52, + "Flags": 0 + }, + { + "Id": 2082, + "Type": 10, + "Flags": 0 + }, + { + "Id": 2083, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2084, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2089, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2090, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2217, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2218, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2219, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2340, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2341, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2342, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2343, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2344, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2345, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2446, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2447, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2448, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2449, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2460, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2461, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2462, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2463, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2464, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2465, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2476, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2477, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2478, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2479, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2490, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2491, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2492, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2493, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2494, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2495, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2496, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2497, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2508, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2509, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2510, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2511, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2522, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2523, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2524, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2525, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2526, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2527, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2528, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2529, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2538, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2539, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2540, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2541, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2542, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2543, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2552, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2553, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2554, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2555, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2556, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2557, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2558, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2559, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2568, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2569, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2570, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2571, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2580, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2581, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2582, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2583, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2588, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2589, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2598, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2599, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2600, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2601, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2606, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2607, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2608, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2609, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2614, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2615, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2616, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2617, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2632, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2633, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2634, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2635, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2644, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2645, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2646, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2647, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2652, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2653, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2654, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2655, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2656, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2657, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2680, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2681, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2682, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2683, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2684, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2685, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2686, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2687, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2688, + "Type": 55, + "Flags": 0 + }, + { + "Id": 2689, + "Type": 55, + "Flags": 0 + }, + { + "Id": 2690, + "Type": 55, + "Flags": 0 + }, + { + "Id": 2691, + "Type": 55, + "Flags": 0 + }, + { + "Id": 2692, + "Type": 55, + "Flags": 0 + }, + { + "Id": 2706, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2707, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2708, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2709, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2710, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2711, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2712, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2713, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2722, + "Type": 56, + "Flags": 0 + }, + { + "Id": 2723, + "Type": 56, + "Flags": 0 + }, + { + "Id": 2724, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2725, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2735, + "Type": 57, + "Flags": 0 + }, + { + "Id": 2736, + "Type": 57, + "Flags": 0 + }, + { + "Id": 2737, + "Type": 57, + "Flags": 0 + }, + { + "Id": 2738, + "Type": 57, + "Flags": 0 + }, + { + "Id": 2739, + "Type": 57, + "Flags": 0 + }, + { + "Id": 2740, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2741, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2742, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2743, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2744, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2745, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2746, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2747, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2770, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2771, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2772, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2773, + "Type": 58, + "Flags": 0 + }, + { + "Id": 2774, + "Type": 58, + "Flags": 0 + }, + { + "Id": 2775, + "Type": 58, + "Flags": 0 + }, + { + "Id": 2780, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2781, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2782, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2783, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2792, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2793, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2794, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2795, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2800, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2801, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2802, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2803, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2804, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2805, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2806, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2807, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2808, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2809, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2810, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2811, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2812, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2813, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2814, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2815, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2816, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2817, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2818, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2819, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2820, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2821, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2822, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2823, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2824, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2825, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2826, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2827, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2828, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2829, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2830, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2831, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2832, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2833, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2834, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2835, + "Type": 1, + "Flags": 0 + }, + { + "Id": 2852, + "Type": 60, + "Flags": 0 + }, + { + "Id": 2853, + "Type": 60, + "Flags": 0 + }, + { + "Id": 2854, + "Type": 6, + "Flags": 0 + }, + { + "Id": 2855, + "Type": 6, + "Flags": 0 + }, + { + "Id": 2858, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2859, + "Type": 60, + "Flags": 0 + }, + { + "Id": 2862, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2863, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2864, + "Type": 7, + "Flags": 0 + }, + { + "Id": 2865, + "Type": 60, + "Flags": 0 + }, + { + "Id": 2870, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2871, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2872, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2873, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2874, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2875, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2876, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2877, + "Type": 59, + "Flags": 0 + }, + { + "Id": 2878, + "Type": 11, + "Flags": 0 + }, + { + "Id": 2879, + "Type": 11, + "Flags": 0 + }, + { + "Id": 2880, + "Type": 11, + "Flags": 0 + }, + { + "Id": 2881, + "Type": 11, + "Flags": 0 + }, + { + "Id": 2882, + "Type": 11, + "Flags": 0 + }, + { + "Id": 2883, + "Type": 11, + "Flags": 0 + }, + { + "Id": 2884, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2885, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2886, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2887, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2888, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2889, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2890, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2891, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2892, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2893, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2894, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2895, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2896, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2897, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2930, + "Type": 61, + "Flags": 0 + }, + { + "Id": 2931, + "Type": 61, + "Flags": 0 + }, + { + "Id": 2932, + "Type": 6, + "Flags": 0 + }, + { + "Id": 2933, + "Type": 6, + "Flags": 0 + }, + { + "Id": 2936, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2937, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2940, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2941, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2942, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2943, + "Type": 12, + "Flags": 0 + }, + { + "Id": 2948, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2949, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2950, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2951, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2952, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2953, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2954, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2955, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2956, + "Type": 62, + "Flags": 0 + }, + { + "Id": 2957, + "Type": 62, + "Flags": 0 + }, + { + "Id": 2958, + "Type": 62, + "Flags": 0 + }, + { + "Id": 2959, + "Type": 62, + "Flags": 0 + }, + { + "Id": 2960, + "Type": 62, + "Flags": 0 + }, + { + "Id": 2961, + "Type": 62, + "Flags": 0 + }, + { + "Id": 2962, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2963, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2964, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2965, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2966, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2967, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2968, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2969, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2970, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2971, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2972, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2973, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2974, + "Type": 15, + "Flags": 0 + }, + { + "Id": 2975, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3008, + "Type": 60, + "Flags": 0 + }, + { + "Id": 3009, + "Type": 60, + "Flags": 0 + }, + { + "Id": 3010, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3011, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3014, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3015, + "Type": 60, + "Flags": 0 + }, + { + "Id": 3018, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3019, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3020, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3021, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3026, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3027, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3028, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3029, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3030, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3031, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3032, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3033, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3034, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3035, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3036, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3037, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3038, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3039, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3040, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3041, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3042, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3043, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3044, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3045, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3046, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3047, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3048, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3049, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3050, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3051, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3052, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3053, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3054, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3055, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3056, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3057, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3058, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3059, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3060, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3061, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3062, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3063, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3064, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3065, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3066, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3067, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3068, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3069, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3076, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3077, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3078, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3079, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3080, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3081, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3082, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3083, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3084, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3085, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3086, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3087, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3088, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3089, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3090, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3091, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3092, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3093, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3094, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3095, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3096, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3097, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3098, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3099, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3100, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3101, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3102, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3103, + "Type": 1, + "Flags": 0 + }, + { + "Id": 3104, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3105, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3106, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3107, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3108, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3109, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3110, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3111, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3112, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3113, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3114, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3115, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3116, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3117, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3118, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3119, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3120, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3121, + "Type": 59, + "Flags": 0 + }, + { + "Id": 3122, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3123, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3124, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3125, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3126, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3127, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3128, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3129, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3130, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3131, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3164, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3165, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3166, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3167, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3170, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3171, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3174, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3175, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3176, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3177, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3182, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3183, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3184, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3185, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3186, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3187, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3188, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3189, + "Type": 15, + "Flags": 0 + }, + { + "Id": 3222, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3223, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3225, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3226, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3227, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3228, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3229, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3230, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3231, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3233, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3276, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3277, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3278, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3279, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3304, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3305, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3306, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3307, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3308, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3309, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3310, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3311, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3312, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3313, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3314, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3315, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3316, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3317, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3328, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3329, + "Type": 45, + "Flags": 0 + }, + { + "Id": 3527, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3529, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3531, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3533, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3534, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3535, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3536, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3537, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3538, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3539, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3540, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3541, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3542, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3543, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3544, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3545, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3546, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3547, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3548, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3607, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3608, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3609, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3610, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3621, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3622, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3637, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3638, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3639, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3640, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3641, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3646, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3647, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3652, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3653, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3658, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3659, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3664, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3665, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3680, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3681, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3682, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3683, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3684, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3685, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3686, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3687, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3688, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3689, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3690, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3699, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3700, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3705, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3706, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3711, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3712, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3724, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3725, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3726, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3756, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3757, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3770, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3772, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3773, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3784, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3785, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3790, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3791, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3796, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3797, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3806, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3807, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3808, + "Type": 12, + "Flags": 0 + }, + { + "Id": 3809, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3810, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3811, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3812, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3813, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3814, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3815, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3816, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3831, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3832, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3837, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3838, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3843, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3844, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3850, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3851, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3852, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3863, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3864, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3865, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3866, + "Type": 7, + "Flags": 0 + }, + { + "Id": 3871, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3872, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3873, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3874, + "Type": 11, + "Flags": 0 + }, + { + "Id": 3883, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3884, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3895, + "Type": 50, + "Flags": 0 + }, + { + "Id": 3896, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3897, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3898, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3899, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3900, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3901, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3902, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3913, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3914, + "Type": 6, + "Flags": 0 + }, + { + "Id": 3964, + "Type": 64, + "Flags": 0 + }, + { + "Id": 3965, + "Type": 64, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 2, + "High": -2147418112, + "Low": 12291 + }, + { + "Id": 3, + "High": -2147418110, + "Low": 12291 + }, + { + "Id": 4, + "High": -2147418111, + "Low": 12291 + }, + { + "Id": 5, + "High": -2147418109, + "Low": 30723 + }, + { + "Id": 6, + "High": 65539, + "Low": 12291 + }, + { + "Id": 7, + "High": 65539, + "Low": 30723 + }, + { + "Id": 8, + "High": -2147417856, + "Low": 12291 + }, + { + "Id": 9, + "High": -2147417855, + "Low": 12291 + }, + { + "Id": 10, + "High": 0, + "Low": 12291 + }, + { + "Id": 11, + "High": 65538, + "Low": 12291 + }, + { + "Id": 12, + "High": 65537, + "Low": 30723 + }, + { + "Id": 13, + "High": 65538, + "Low": 30723 + }, + { + "Id": 14, + "High": 604045314, + "Low": 12291 + }, + { + "Id": 15, + "High": 65536, + "Low": 143363 + }, + { + "Id": 16, + "High": 604045314, + "Low": 9187331 + }, + { + "Id": 17, + "High": 604045314, + "Low": 126627843 + }, + { + "Id": 18, + "High": 604045314, + "Low": 798723 + }, + { + "Id": 19, + "High": 604045314, + "Low": 17575939 + }, + { + "Id": 20, + "High": 604045314, + "Low": 25964547 + }, + { + "Id": 21, + "High": 604045314, + "Low": 34353155 + }, + { + "Id": 22, + "High": 604045314, + "Low": 40644611 + }, + { + "Id": 23, + "High": 604045314, + "Low": 118239235 + }, + { + "Id": 24, + "High": 604045314, + "Low": 107753475 + }, + { + "Id": 25, + "High": 604045314, + "Low": 101462019 + }, + { + "Id": 26, + "High": 604045314, + "Low": 93065219 + }, + { + "Id": 27, + "High": 604045314, + "Low": 84684803 + }, + { + "Id": 28, + "High": 604045314, + "Low": 76288003 + }, + { + "Id": 29, + "High": 604045314, + "Low": 67899395 + }, + { + "Id": 30, + "High": 604045314, + "Low": 59510787 + }, + { + "Id": 31, + "High": 604045314, + "Low": 51122179 + }, + { + "Id": 32, + "High": 604045314, + "Low": 84676611 + }, + { + "Id": 33, + "High": 604045314, + "Low": 93073411 + }, + { + "Id": 34, + "High": 604045314, + "Low": 67907587 + }, + { + "Id": 35, + "High": 604045314, + "Low": 7090179 + }, + { + "Id": 36, + "High": 604045314, + "Low": 124530691 + }, + { + "Id": 37, + "High": 604045314, + "Low": 116142083 + }, + { + "Id": 38, + "High": 604045314, + "Low": 90976259 + }, + { + "Id": 39, + "High": 604045314, + "Low": 76296195 + }, + { + "Id": 40, + "High": 604045314, + "Low": 59518979 + }, + { + "Id": 41, + "High": 604045314, + "Low": 49033219 + }, + { + "Id": 42, + "High": 604045314, + "Low": 42741763 + }, + { + "Id": 43, + "High": 604045314, + "Low": 51130371 + }, + { + "Id": 44, + "High": 65536, + "Low": 4099 + }, + { + "Id": 45, + "High": 8454144, + "Low": 12291 + }, + { + "Id": 46, + "High": 2162688, + "Low": 12291 + }, + { + "Id": 47, + "High": 49154, + "Low": 30723 + }, + { + "Id": 48, + "High": 49154, + "Low": 12291 + }, + { + "Id": 49, + "High": 2146306, + "Low": 12291 + }, + { + "Id": 50, + "High": 65536, + "Low": 30723 + }, + { + "Id": 51, + "High": -2147483648, + "Low": 12291 + }, + { + "Id": 52, + "High": 0, + "Low": 30723 + }, + { + "Id": 53, + "High": 65537, + "Low": 34109443 + }, + { + "Id": 54, + "High": 65537, + "Low": 67663875 + }, + { + "Id": 55, + "High": 65536, + "Low": 90732547 + }, + { + "Id": 56, + "High": 65536, + "Low": 67663875 + }, + { + "Id": 57, + "High": 65536, + "Low": 42498051 + }, + { + "Id": 58, + "High": 65537, + "Low": 101218307 + }, + { + "Id": 59, + "High": 65537, + "Low": 143363 + }, + { + "Id": 60, + "High": 65539, + "Low": 4099 + }, + { + "Id": 61, + "High": 65537, + "Low": 4099 + }, + { + "Id": 62, + "High": 65540, + "Low": 12291 + }, + { + "Id": 63, + "High": 65541, + "Low": 30723 + }, + { + "Id": 64, + "High": 512, + "Low": 12323 + } + ], + "Cams": [ + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 3997696, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 5, + "IconPoints": [ + { + "Flag": 3, + "x": 48, + "y": -68 + }, + { + "Flag": 5, + "x": 50, + "y": -66 + }, + { + "Flag": 7, + "x": 55, + "y": -50 + }, + { + "Flag": 9, + "x": 58, + "y": 1 + }, + { + "Flag": 10, + "x": 62, + "y": -45 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 65, + "y": -37 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 6, + "IconPoints": [ + { + "Flag": 0, + "x": 37, + "y": -49 + }, + { + "Flag": 1, + "x": 65, + "y": -38 + }, + { + "Flag": 2, + "x": 52, + "y": -48 + }, + { + "Flag": 4, + "x": 46, + "y": -36 + }, + { + "Flag": 6, + "x": 59, + "y": -41 + }, + { + "Flag": 8, + "x": 52, + "y": -26 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 3, + "x": 66, + "y": 50 + }, + { + "Flag": 5, + "x": 72, + "y": 47 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 7, + "x": 72, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 4, + "x": 64, + "y": 62 + }, + { + "Flag": 8, + "x": 79, + "y": 38 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 10, + "x": 64, + "y": 45 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 67, + "y": 32 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 9, + "x": 68, + "y": 45 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 1, + "x": 79, + "y": 33 + }, + { + "Flag": 6, + "x": 61, + "y": 41 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 0, + "x": 48, + "y": 57 + }, + { + "Flag": 2, + "x": 77, + "y": 55 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 3", + "Start": "023CF000", + "End": "023E4F90", + "RemapStart": null + }, + "Id": 3, + "TActors": [ + "01FF 00FF 0009 0077 0167 003C 0000 003F", + "04FF 02FF 0009 0077 01D3 F62C 0000 003F", + "0BFF 05FF 002E FAA9 017F FA60 4000 007F", + "07FF 0FFF 002E 067F 020B F4C4 8000 0099", + "0BFF 08FF 0009 FA22 020B F8B8 8000 003F", + "14FF 0DFF 002E 0676 04CC F308 C000 02C0", + "0DFF 06FF 002E 01F3 033B F308 C000 0095", + "0CFF 06FF 002E FE83 033B F308 4000 0095", + "04FF 06FF 002E 0077 01D3 F43E 8000 007F", + "08FF 0AFF 002E FF87 0320 F506 4000 003F", + "07FF 0AFF 002E 0167 0320 F506 C000 003F", + "08FF 15FF 002E F995 020B F516 8000 007F", + "08FF 12FF 002E F92F 020B F802 C000 007F", + "03FF 10FF 002E 0645 01CF FA60 4000 007F", + "02FF 05FF 002E FD07 017F FA60 C000 007F", + "08FF 02FF 002E FD63 00F3 F74C 2000 00A5", + "07FF 02FF 002E 038B 00F3 F74C E0B6 00AA", + "03FF 02FF 0009 03E7 01CF FA60 C000 003F", + "07FF 09FF 0023 04F1 FFB3 F920 0000 00BF", + "08FF 09FF 0023 FBFA FFB2 F920 0000 00BF", + "02FF 11FF 0023 0077 002D F9E2 0000 009B", + "14FF 0FFF 0023 084C 032D F28B 0000 00BF", + "13FF 15FF 0023 F91F 02AB F308 8000 00BF", + "02FF 01FF 0009 0077 017F FDBC 0000 0086", + "10FF 0FFF 0009 07C7 0193 F8E4 8000 0083", + "13FF 0BFF 002E F91F 04CC F8E4 0000 02C2", + "13FF 0CFF 002E FA78 04CC F308 4000 02C1", + "0EFF 14FF 002E 07CF 04CC F8E4 8000 02C4", + "16FF 11FF 002E 0077 FCF5 F503 0000 0154" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 3, Room 0", + "Start": "023E5000", + "End": "023F2BC0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "015C" + ], + "Actors": [ + "0095 01C3 038D 0217 0000 C000 0000 0000", + "0095 01C3 027F 0236 0000 C000 0000 0000", + "0095 01C3 045F 026D 0000 C000 0000 0000", + "0095 01C3 0311 027B 0000 C000 0000 0000", + "0095 01C3 01ED 02A4 0000 C000 0000 0000", + "0037 0069 03FD 01F8 0000 671C 0000 0000", + "000A 018C 047F 0194 0000 4000 000D 8843", + "012A FF58 035C 0243 0000 505B 0000 0D00" + ] + }, + { + "File": { + "Name": "Scene 3, Room 1", + "Start": "023F3000", + "End": "023F8B60", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0190", + "00A8" + ], + "Actors": [ + "0037 0077 0209 FE85 0000 0000 0000 0000", + "0037 0077 01C6 FEFA 0000 0000 0000 0000", + "0037 0077 0201 FF75 0000 0000 0000 0000", + "0095 0048 0243 FDD3 0000 0000 0000 8402" + ] + }, + { + "File": { + "Name": "Scene 3, Room 2", + "Start": "023F9000", + "End": "02408A30", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0007", + "0039", + "00B7", + "015C", + "0190", + "00A8", + "0099" + ], + "Actors": [ + "0173 FFEA 0166 F957 0002 001D 0000 3F8C", + "0173 0106 0166 F959 0002 001F 0000 3F8C", + "0173 FFE9 0166 FA77 0002 001E 0000 3F8C", + "0173 0106 0166 FA77 0002 0020 0000 3F8C", + "0087 0077 00E9 F9E2 0000 0000 0000 001B", + "0105 FFEA 011D F958 0000 0000 0000 001C", + "0105 FFEA 011D FA78 0000 0000 0000 011D", + "0105 0107 011D F958 0000 0000 0000 021E", + "0105 0107 011D FA78 0000 0000 0000 031F", + "0111 02A3 0139 FC23 0000 9F4A 0000 400F", + "0111 FE53 0139 FC2B 0000 6000 0000 420F", + "0111 02D0 0139 FBF3 0000 9F4A 0000 4403", + "0111 FE23 0139 FBF6 0000 6000 0000 4603", + "0111 0276 0139 FC51 0000 9F4A 0000 4809", + "0111 FE80 0139 FC57 0000 6000 0000 4A09", + "012A FE66 0221 F852 0000 2000 0000 2502", + "012A 028A 0221 F852 0000 E000 0000 2A02", + "0173 FFE9 0166 F957 0002 005D 0000 2C8D", + "0173 FFE9 0166 FA73 0002 005E 0000 2D8D", + "0173 0108 0166 F957 0002 005F 0000 2E8D", + "0173 0106 0166 FA77 0002 0060 0000 2F8D" + ] + }, + { + "File": { + "Name": "Scene 3, Room 3", + "Start": "02409000", + "End": "0240CA10", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024" + ], + "Actors": [ + "0008 062F 0206 FA27 0000 C000 0000 83F0", + "0008 062F 0206 FA2F 0000 C000 0000 83F0", + "0008 062F 0206 FA91 0000 C000 0000 83F0", + "0008 062F 0206 FA99 0000 C000 0000 83F0" + ] + }, + { + "File": { + "Name": "Scene 3, Room 4", + "Start": "0240D000", + "End": "024102B0", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0190", + "00A8" + ], + "Actors": [ + "0173 0078 0208 F4C6 0000 0021 0001 3F05", + "01D1 0078 01D4 F484 0000 0000 0000 B820" + ] + }, + { + "File": { + "Name": "Scene 3, Room 5", + "Start": "02411000", + "End": "024145E0", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0032" + ], + "Actors": [ + "0008 FAC0 01B6 FA27 0000 4000 0000 83F0", + "0008 FAC0 01B6 FA2F 0000 4000 0000 83F0", + "0008 FAC0 01B6 FA91 0000 4000 0000 83F0", + "0008 FAC0 01B6 FA99 0000 4000 0000 83F0", + "0002 FC18 017F FA60 0000 4000 0000 FFFF", + "0187 FCC2 017F FA60 0000 0000 0000 4FFF" + ] + }, + { + "File": { + "Name": "Scene 3, Room 6", + "Start": "02415000", + "End": "0241E4C0", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0032", + "0190", + "00A8", + "0183" + ], + "Actors": [ + "01AF 0000 01D3 F2F4 0000 0E39 0000 FF00", + "01AF 00FA 01D3 F2F4 0000 F1C7 0000 FF00", + "000A 0077 01D3 F290 0000 8000 0000 7840", + "000A 0077 033B F290 0000 8000 0015 B08C", + "0086 00D1 033B F308 0000 0000 0000 1500", + "01D1 0078 01D4 F3F8 0000 8000 0000 B820", + "0111 005A 01D3 F201 0000 0000 0000 6203", + "0111 008E 01D3 F201 0000 0000 0000 6412", + "0111 00CE 033B F1D1 0000 0000 0000 6603", + "0111 0020 033B F43C 0000 8000 0000 6803", + "0111 001E 033B F1D1 0000 0000 0000 6A03", + "0111 00CA 033B F43C 0000 8000 0000 6C03" + ] + }, + { + "File": { + "Name": "Scene 3, Room 7", + "Start": "0241F000", + "End": "02432000", + "RemapStart": "241E5A0" + }, + "Id": 7, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "0036", + "0039", + "011C", + "00B7", + "015C", + "0190", + "00A8" + ], + "Actors": [ + "012D 021B 03DC F506 0000 4000 0000 FFC2", + "012D 03F7 0211 F6DE 0000 6000 0000 FFC2", + "0095 02C0 0389 F42F 0000 0000 0000 0000", + "0055 0604 0143 F5A0 0000 160B 0000 0000", + "0055 0446 00CB F5F1 0000 DF4A 0000 0001", + "0055 0464 00C4 F815 0000 25B0 0000 0001", + "0095 03FD 0212 F6D8 0000 6000 0000 8401", + "000A 05F0 0143 F545 0000 8000 0000 5841", + "000A 038D 0320 F3F3 0000 8000 0000 5845", + "000A 04B5 FF14 F920 0000 C000 0000 5849", + "01D1 0280 01EA F4A8 0000 0000 0000 2822", + "01D1 0280 0186 F588 0000 2000 0000 A823", + "01D1 06C5 017F F618 0000 0000 0000 3924", + "00E4 04F1 00AE F920 0000 0000 0000 0026", + "012A 04F3 0064 F8D0 0000 0000 0000 2602", + "01D1 06C5 0143 F5DC 0000 0000 0000 B927", + "01D1 06C5 01CF F596 0000 0000 0000 B928", + "01D1 0308 0186 F611 0000 2000 0000 2829" + ] + }, + { + "File": { + "Name": "Scene 3, Room 8", + "Start": "02432000", + "End": "02449B70", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "0036", + "0039", + "0007", + "00B7", + "015C" + ], + "Actors": [ + "000E FC5A 00BC F496 0000 293F 0000 FF00", + "000E FC0E 00BC F5A0 0000 1D28 0000 FF00", + "000E FACE 00BC F651 0000 3333 0000 FF00", + "0095 FECF 0301 F47E 0000 C000 0000 0000", + "0095 FECF 014D F49D 0000 C000 0000 0000", + "0095 FECF 026E F4BF 0000 C000 0000 0000", + "0037 FEB7 0370 F506 0000 C000 0000 0000", + "0095 FB6E 01A8 F9A7 0000 705B 0000 8404", + "000F FEC3 034D F4E3 438E C000 0000 0FE1", + "00E4 FBFD 00AE F920 0000 0000 0000 0026", + "0015 FB9C 01F8 F4D9 0000 0000 0000 2D03", + "0015 FB7B 01F8 F512 0000 0000 0000 2E03", + "0015 FB60 01F8 F548 0000 0000 0000 2F03" + ] + }, + { + "File": { + "Name": "Scene 3, Room 9", + "Start": "0244A000", + "End": "02454190", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0007", + "0039", + "00B7" + ], + "Actors": [ + "0095 FBAD FF06 F894 0000 4000 0000 8408", + "000A 04B5 FF14 F920 0000 C000 0000 5849", + "00E4 0077 FEE6 F8E4 0000 0000 0000 0026", + "012A 04F3 0064 F8D0 0000 0000 0000 2602", + "0015 0073 FF14 F925 0000 0000 0000 3803", + "0015 000F FF14 F925 0000 0000 0000 3903", + "0015 00D7 FF14 F925 0000 0000 0000 3A03" + ] + }, + { + "File": { + "Name": "Scene 3, Room 10", + "Start": "02455000", + "End": "0245A3E0", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "0036", + "0039" + ], + "Actors": [ + "0037 0030 038D F501 0000 293F 0000 0001", + "005E 0078 0320 F57D 0000 8000 0000 2400", + "000F FFB4 0320 F505 0000 3555 0000 1FE1" + ] + }, + { + "File": { + "Name": "Scene 3, Room 11", + "Start": "0245B000", + "End": "02465BD0", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "005C", + "006F", + "00B7", + "011C" + ], + "Actors": [ + "012D FA22 02AB F8F7 4000 0000 0000 FFC2", + "0069 FA16 04EF F946 0000 E9F5 0000 FFFF", + "0069 F944 04EF FACC 0000 F3E9 0000 FFFF", + "00FF F851 026F FB14 0000 4000 0000 0542", + "00FF F851 026F FC04 0000 4000 0000 0542", + "00FF F711 025B FC04 0000 0000 0000 0546", + "0139 F711 025B FC04 0000 0000 0000 0005", + "00FF F879 034B FB8C 0000 4000 0000 0702", + "00FF F8F1 034B FB8C 0000 4000 0000 0702", + "00FF F9B9 0337 FB8C 0000 0000 0000 0706", + "0139 F9B9 0337 FB8C 0000 0000 0000 0007", + "011B F781 026F FB16 0014 0029 0000 088F", + "012D F941 026F FACA 0000 8000 0000 0FC1", + "012D FA5C 03FF FB50 0000 8000 0000 0FC1", + "01B4 F9D7 02AB FAC4 0000 0000 0000 0F01", + "01B4 FA63 02E7 FAC4 0000 0000 0000 0F01", + "012A FA5C 03FF FB8B 0000 C000 0000 0F03", + "0095 FA74 017F FC22 0000 C000 0000 8410", + "01B4 FA22 028C F95B C000 0000 0000 1301", + "01B4 FA22 0228 F95B C000 0000 0000 1301", + "012A FA22 020B F933 0000 0000 0000 1313", + "0068 F91F 04FE F439 0000 0000 0000 7F13" + ] + }, + { + "File": { + "Name": "Scene 3, Room 12", + "Start": "02466000", + "End": "0246E3E0", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "005C", + "006F", + "0099" + ], + "Actors": [ + "0173 FE52 0371 F2B2 0002 001E 0000 3F94", + "0173 FE52 0371 F2B2 0002 005E 0000 0A95", + "000A FE36 033B F259 0000 4000 0000 182D", + "0093 FD3D 051C F2CC 0000 C000 0000 021D", + "0105 FE51 033B F2AE 0000 0000 0000 011D" + ] + }, + { + "File": { + "Name": "Scene 3, Room 13", + "Start": "0246F000", + "End": "02477AB0", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0070", + "0071", + "0099" + ], + "Actors": [ + "0173 0225 0371 F2B2 0002 001F 0000 3F94", + "0173 0225 0371 F2B2 0002 005F 0000 0B95", + "000A 023F 033B F256 0000 C000 0000 180F", + "0093 0339 051C F2CC 0000 4000 0000 031E", + "0105 0225 033B F2AE 0000 0000 0000 021E", + "0111 033E 033B F1C9 0000 0000 0000 4C03", + "0111 03AD 033B F1C8 0000 0000 0000 4E09", + "0111 0373 033B F1C8 0000 0000 0000 5009" + ] + }, + { + "File": { + "Name": "Scene 3, Room 14", + "Start": "02478000", + "End": "0247DBB0", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0070", + "0071", + "0179" + ], + "Actors": [ + "00E3 07CF 0422 FAD6 0000 0000 0000 FF00", + "0173 05EF 0549 FAD6 0003 0019 0000 3F97", + "0068 07CF 04FE F439 0000 0000 0000 FF18", + "012A 05EF 0549 FAD6 0000 4000 0000 1892", + "01B4 07D0 04FE F90C 4000 0000 0000 3801", + "005E 07F5 04BF FAD6 0000 C000 0000 03F8", + "012A 07C8 04CC FAD6 0000 4000 0000 3820", + "0110 0908 0445 FC96 0000 0000 0000 3808", + "0110 093C 0445 FC97 0000 0000 0000 3908", + "0110 063F 04CC FAD6 0000 4000 0000 3A03" + ] + }, + { + "File": { + "Name": "Scene 3, Room 15", + "Start": "0247E000", + "End": "02480690", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024" + ], + "Actors": [ + "0037 0728 02C6 F446 0000 8000 0000 0000", + "0037 0816 02C3 F44A 0000 8000 0000 0000", + "0037 0815 02C6 F537 0000 8000 0000 0000", + "0037 0725 02C6 F58B 0000 8000 0000 0000", + "0037 0866 02C3 F5DD 0000 8000 0000 0000", + "0037 077A 02C6 F6C3 0000 8000 0000 0000", + "0037 07CA 02C8 F768 0000 8000 0000 0000", + "0089 07C7 02AB F628 0000 8000 0000 FFFF", + "000A 0867 02F2 F628 0000 0000 000E 8926", + "011B 07C0 0193 F405 0032 002C 0014 4998", + "012A 0728 0193 F7B8 0000 0000 0000 0E00", + "012A 0817 0193 F769 0000 0000 0000 1900" + ] + }, + { + "File": { + "Name": "Scene 3, Room 16", + "Start": "02481000", + "End": "02485FA0", + "RemapStart": "2480760" + }, + "Id": 16, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0099" + ], + "Actors": [ + "0173 06B8 020E FAC1 0002 0020 0000 3F94", + "0173 06B8 020E FAC1 0002 0060 0000 0C95", + "0093 07ED 0373 FA42 0000 4000 0000 011F", + "0093 0933 025B FA60 0000 C000 0000 041F", + "0105 06B5 01CF FAC4 0000 4000 0000 031F", + "0093 0829 0373 FA06 0000 4000 0000 001F", + "0111 066F 01CF FA07 0000 0000 0000 5603", + "0111 066D 01CF F9CC 0000 0000 0000 5809" + ] + }, + { + "File": { + "Name": "Scene 3, Room 17", + "Start": "02486000", + "End": "0248F150", + "RemapStart": null + }, + "Id": 17, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "015C", + "00B0" + ], + "Actors": [ + "0037 FEA6 FD30 FBB1 0000 6000 0000 0000", + "0037 FEDE FD30 FB75 0000 6000 0000 0001", + "0088 0077 FCF5 F9E2 0000 8000 0000 FFFF", + "000A FE8C FCF5 F7F0 0000 A000 0000 592B", + "00E3 0077 FCF5 FBFB 0000 8000 0000 1001", + "012A 031D FCF5 F9E2 0000 C000 0000 1000", + "00E3 0077 FCF5 F7C9 0000 0000 0000 1101", + "012A 0077 FDC6 FC0F 0000 0000 0000 1102", + "012A 0266 FD80 F9E2 8000 C000 0000 1203", + "00E3 0291 FCF5 F9E2 0000 C000 0000 1201", + "0087 0077 FCF5 F9E2 0000 0000 0000 001B", + "0111 FE33 FCF5 FBB9 0000 6000 0000 7003", + "0111 FEA1 FCF5 FC2D 0000 6000 0000 7203", + "0111 FE7D FCF5 FC06 0000 6000 0000 740B", + "0111 FE58 FCF5 FBDF 0000 6000 0000 7608" + ] + }, + { + "File": { + "Name": "Scene 3, Room 18", + "Start": "02490000", + "End": "02491340", + "RemapStart": null + }, + "Id": 18, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "000B", + "0098" + ], + "Actors": [ + "0090 F83D 01F7 F8CE 0000 53E9 0000 7F00", + "000A F7F4 01F7 F804 0000 C000 0000 7842" + ] + }, + { + "File": { + "Name": "Scene 3, Room 19", + "Start": "02492000", + "End": "02492510", + "RemapStart": null + }, + "Id": 19, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "005C", + "006F", + "000B" + ], + "Actors": [ + "0011 F91D 05BB F30A 0000 0000 0000 0001", + "0173 F9F0 0595 F274 0000 0014 0000 3F92", + "0068 F91F 04FE F439 0000 0000 0000 3F13", + "011B F913 04B6 F3C9 0000 0000 0000 1691" + ] + }, + { + "File": { + "Name": "Scene 3, Room 20", + "Start": "02493000", + "End": "02494300", + "RemapStart": null + }, + "Id": 20, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0070", + "0071", + "000B" + ], + "Actors": [ + "0069 07CE 04FC F639 0000 8000 0000 01FC", + "0069 07D1 04F5 F78B 0000 8000 0000 01FC", + "0011 07CE 05C0 F302 0000 C0B6 0000 0001", + "011B 071A 04CC F309 0000 0000 0000 1791", + "0068 07CF 04FE F439 0000 0000 0000 BF18" + ] + }, + { + "File": { + "Name": "Scene 3, Room 21", + "Start": "02495000", + "End": "02496780", + "RemapStart": null + }, + "Id": 21, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "0179", + "005C", + "006F", + "000B" + ], + "Actors": [ + "008E F996 020B F48A 0000 8000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 3, Room 22", + "Start": "02497000", + "End": "02498DE0", + "RemapStart": null + }, + "Id": 22, + "Objects": [ + "0073", + "0072", + "000E", + "00A4", + "005D", + "0024", + "015C", + "00B0" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [], + "PolyTypes": [], + "Cams": [ + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 327680, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 6, + "IconPoints": [ + { + "Flag": 3, + "x": 53, + "y": -64 + }, + { + "Flag": 5, + "x": 65, + "y": -9 + }, + { + "Flag": 12, + "x": 49, + "y": -1 + }, + { + "Flag": 13, + "x": 40, + "y": 0 + }, + { + "Flag": 14, + "x": 18, + "y": -2 + }, + { + "Flag": 15, + "x": 59, + "y": 0 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 4, + "IconPoints": [ + { + "Flag": 0, + "x": 49, + "y": -1 + }, + { + "Flag": 1, + "x": 71, + "y": -13 + }, + { + "Flag": 2, + "x": 11, + "y": -25 + }, + { + "Flag": 6, + "x": 84, + "y": -16 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 9, + "x": 65, + "y": -30 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 11, + "x": 41, + "y": -24 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 50, + "y": -11 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 0, + "x": 72, + "y": 57 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 1, + "x": 69, + "y": 39 + }, + { + "Flag": 9, + "x": 62, + "y": 65 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 9, + "x": 71, + "y": 59 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 13, + "x": 80, + "y": 53 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 15, + "x": 49, + "y": 50 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 6, + "x": 65, + "y": 53 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 11, + "x": 39, + "y": 35 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 53, + "y": 5 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 65, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 14, + "x": 64, + "y": 31 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 3, + "x": 75, + "y": 53 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 12, + "x": 69, + "y": 52 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 5, + "x": 58, + "y": 27 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 4", + "Start": "022D8000", + "End": "022F2970", + "RemapStart": null + }, + "Id": 4, + "TActors": [ + "05FF 04FF 0023 0820 0992 FD80 4000 00BF", + "0AFF 02FF 0023 FC04 07C6 0000 0000 00BF", + "06FF 01FF 0023 0618 076C 0000 8000 007F", + "08FF 06FF 0023 0618 0ED8 0000 8000 007F", + "0DFF 0BFF 0023 F90C 0ED8 0000 8000 007F", + "09FF 10FF 002E 0154 0B7C 00BE 4000 009F", + "04FF 15FF 0009 0BFE 080C 0000 4000 003F", + "0AFF 09FF 0009 FDD0 0B7C 00BE 4000 003F", + "0AFF 0BFF 002E F90C 0AF0 FEB6 0000 0099", + "0BFF 0AFF 0009 F90C 0AF0 014A 0000 003F", + "0DFF 0CFF 0009 F6BE 1130 0014 C000 0098", + "0CFF 18FF 0009 F576 0FA0 009F C000 003F", + "13FF 01FF 002E 0618 00F0 FA10 0000 00A9", + "14FF 0100 0009 0618 0064 F9E8 0000 003F", + "15FF 01FF 0009 0A8C 00C8 0000 C000 009E", + "16FF 01FF 0009 0618 00C8 062C 8000 003F", + "02FF 00FF 002E FE5C 00C8 0000 4000 00A8", + "00FF 11FF 002E FEE8 0000 008C 8000 007F", + "17FF 05FF 002E 06F4 0AF0 FA24 0000 00BE", + "10FF 06FF 002E 062C 0AF0 014A 8000 00BF", + "10FF 06FF 002E 04CE 0AF0 003C 4000 00BF", + "06FF 05FF 002E 060E 0AF0 FEB6 8000 00BF", + "05FF 07FF 0009 062C 0FA0 FDB2 0000 003F", + "08FF 07FF 002E 062C 1130 FDB2 8000 00B5", + "0BFF 0AFF 0009 FA56 0BA4 0000 4000 003F", + "11FF 03FF 002E FEE8 0000 FC7C 8000 007F", + "0AFF 18FF 002E F593 0B18 FF69 E000 007F", + "05FF 04FF 0009 0A14 0AF0 0000 C000 003F", + "10FF 05FF 0009 05B4 0B7C FD8A 4000 009A", + "03FF 12FF 002E 0000 0000 FB28 4000 007F", + "0AFF 0EFF 002E FB5C 0E60 FF3B A0B6 01FD", + "0EFF 0DFF 0009 F6EE 1054 FD03 E000 009B", + "12FF 0FFF 002E 00EE 0000 FC94 0000 007F", + "19FF 0AFF 0009 FBDE 0AF0 FC76 E000 003F", + "0FFF 00FF 0009 0118 0000 008C 0000 0097", + "1AFF 02FF 002E F9E8 00C8 0000 4000 0154", + "01FF 00FF 0009 01A4 00C8 0000 C000 003F" + ], + "Paths": [ + { + "Points": [ + [ + -310, + 0, + -318 + ], + [ + -309, + 0, + -127 + ] + ] + }, + { + "Points": [ + [ + 1879, + 100, + -1883 + ], + [ + 1685, + 100, + -1881 + ] + ] + }, + { + "Points": [ + [ + 1536, + 200, + 2035 + ], + [ + 1536, + 200, + 1860 + ] + ] + }, + { + "Points": [ + [ + 1462, + 2800, + -1817 + ], + [ + 1658, + 2800, + -1815 + ] + ] + } + ], + "Rooms": [ + { + "File": { + "Name": "Scene 4, Room 0", + "Start": "022F3000", + "End": "022FA2C0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "002C", + "000E", + "00A4", + "018E" + ], + "Actors": [ + "0040 0172 0140 0000 0000 C000 0000 0601", + "0040 0172 0104 0000 0000 C000 0000 0C00", + "0040 0172 00C8 0000 0000 C000 0000 0D00", + "000C 0000 0004 0220 0000 0000 0000 00FF", + "0008 006A 00F6 FF6F 0000 0000 0000 0284", + "005E FF7C 00A0 014C 0000 0000 0000 1128", + "005E FF9A 00C7 FF6F 0000 0000 0000 1128", + "005E 0003 00DB FF74 0000 0000 0000 1128", + "005E 0083 00A0 0149 0000 0000 0000 1128", + "0111 FE9B 0000 03BD 0000 0000 0000 560F", + "0111 0164 0001 03BF 0000 0000 0000 580F" + ] + }, + { + "File": { + "Name": "Scene 4, Room 1", + "Start": "022FB000", + "End": "023079E0", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "002C", + "011C", + "00A4", + "000E", + "0024", + "015C" + ], + "Actors": [ + "012D 049C 0000 0086 0000 0000 0000 2AC1", + "012D 05C5 00F0 FAAA 0000 0000 0000 2AC1", + "012D 06A8 0000 FF2A 0000 0000 0000 2AC1", + "012D 06A9 0000 0399 0000 0000 0000 2AC1", + "008D 04E2 0000 0492 0000 0000 0000 00FF", + "008D 07FA 0000 0492 0000 8000 0000 00FF", + "0046 066B 0000 0431 0000 4000 0000 0001", + "0046 079A 0000 023B 0000 0000 0000 0001", + "0046 07AE 0000 FE67 0000 4000 0000 0001", + "00CF 0618 00C8 05DC 0000 8000 0000 0701", + "0043 073A 0000 FD1A 0000 0000 0000 FF01", + "0046 0514 0000 035B 0000 0000 0000 0000", + "0046 061E 0000 FC5F 0000 C000 0000 0000", + "0046 079A 0000 037B 0000 C000 0000 0000", + "005E 05EF 00F0 FA37 0000 0000 0000 10A9", + "005E 0864 016E FCBA 0000 0000 0000 10A9", + "005E 0631 00C8 0514 0000 0000 0000 106A", + "0111 066E 0068 FB14 0000 0000 0000 4009", + "0111 08B2 0190 FCD7 0000 0000 0000 420F", + "0111 0662 00C8 05C3 0000 0000 0000 440F" + ] + }, + { + "File": { + "Name": "Scene 4, Room 2", + "Start": "02308000", + "End": "02317FD0", + "RemapStart": "2307B30" + }, + "Id": 2, + "Objects": [ + "002C", + "000E", + "00A4", + "0170", + "009D", + "00B0", + "011C", + "0190", + "00A8", + "0024", + "015C" + ], + "Actors": [ + "003B FC6A 0000 FFD5 0000 0000 0000 0006", + "012D FB35 008C FE16 0000 0000 0000 FFC0", + "0098 FA71 00C8 0000 0000 4000 0000 FFFF", + "0041 FC04 0BB8 0000 0000 4000 0000 000E", + "006F FAD5 00C8 0329 0000 8000 0000 0800", + "005E FAD8 00C8 0184 0000 4000 0000 10C8", + "005E FB35 00C8 FE16 0000 0000 0000 10C8", + "005E FB97 016D FD78 0000 0000 0000 10C8", + "0111 FA6E 00C8 FD39 0000 0000 0000 5A0E", + "0111 FA6F 00C8 FD6C 0000 0000 0000 5C0A", + "01A0 FA4F 00C8 FDEA 0000 4000 0000 FFFF", + "01A0 FA4F 00C8 FE5F 0000 4000 0000 FFFF", + "01A0 FB45 012C FCF9 0000 0000 0000 FFFF", + "01A0 FB4B 00C8 02C5 0000 4000 0000 FFFF", + "01A0 FB4B 00C8 0301 0000 4000 0000 FFFF", + "01A0 FB96 0190 FD72 0000 0000 0000 FFFF", + "000A FAF9 00C8 03C5 0000 4000 0000 5847" + ] + }, + { + "File": { + "Name": "Scene 4, Room 3", + "Start": "02318000", + "End": "0231A4E0", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "002C", + "00A4", + "000E", + "009E" + ], + "Actors": [ + "0099 FE97 0050 FAEC 0000 0000 0000 FFFF", + "0049 FE97 0050 FAEC 0000 0000 0000 0FFF", + "000A FE97 0050 FAEC 0000 0000 0000 11A0" + ] + }, + { + "File": { + "Name": "Scene 4, Room 4", + "Start": "0231B000", + "End": "02322890", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "002C", + "000E", + "011C", + "00A4", + "001B", + "0170", + "0190", + "00A8", + "0024" + ], + "Actors": [ + "012D 0893 08D4 016A 0000 0000 0000 2BC1", + "012D 098A 0B6E 0004 4000 0000 0000 FFC2", + "012A 088E 0820 FFC7 0000 C000 0000 0401", + "0025 092F 09D8 FFE6 0000 0000 0000 FFFF", + "006F 0950 0820 0000 0000 4000 0000 0401", + "006F 0A10 0820 0000 0000 C000 0000 0401", + "0112 09D8 0802 0156 0000 0000 0002 18BF", + "0112 09D8 0802 0156 0000 0000 0002 193F", + "0112 09D8 0802 0156 0000 0000 0002 19BF", + "005E 0923 08E8 02BF 0000 0000 0000 106B", + "01A0 07EE 0820 0037 0000 0000 0000 FFFF", + "01A0 082A 0820 0037 0000 0000 0000 FFFF", + "01A0 0857 0820 FFC2 0000 4000 0000 FFFF", + "01A0 0866 0820 0037 0000 0000 0000 FFFF", + "01A0 088D 0820 FFC8 0000 0000 0000 FFFF", + "01A0 08C9 0820 FFC8 0000 0000 0000 FFFF", + "000A 09AA 0820 FFCE 0000 8000 0000 080B" + ] + }, + { + "File": { + "Name": "Scene 4, Room 5", + "Start": "02323000", + "End": "0232D230", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "002C", + "000E", + "011C", + "00A4", + "001B", + "0170", + "0190", + "00A8", + "0024" + ], + "Actors": [ + "012D 0617 0C80 FEA6 0000 0000 0000 2CC1", + "012D 07E4 0B7C FE22 0000 0000 0000 2CC1", + "012D 085C 0AB5 FB64 0000 0000 0000 2CC1", + "012D 08D4 0AB4 FB64 0000 0000 0000 2CC1", + "012D 098F 0B7C FE9F 0000 0000 0000 2CC1", + "012D 098F 0B7C 0154 0000 0000 0000 2CC1", + "0095 08E5 0B38 FB9B 0000 C000 0000 0000", + "012A 0895 0AF0 FBA2 0000 0000 0000 2C01", + "0025 06F1 0AF0 0231 0000 0000 0000 FFFF", + "0025 076C 0AF0 FCBD 0000 0000 0000 FFFF", + "0025 0885 0AF0 FFB9 0000 0000 0000 FFFF", + "0025 08D7 0AF0 0207 0000 0000 0000 FFFF", + "004E 062C 0C76 FCEA 0000 0000 0000 FFFF", + "00CF 0820 0B7C FD80 0000 4000 0000 0000", + "00CF 0708 0AF0 FB50 0000 0000 0000 2D02", + "00CF 07A8 0AF0 FB50 0000 0000 0000 2D02", + "00CF 0898 0AF0 FBF0 0000 0000 0000 2E02", + "006F 0887 0AF0 042D 0000 8000 0000 0302", + "006F 06E4 0B7C 04B9 0000 8000 0000 0A02", + "0112 0AC5 0B2E 0001 0000 0000 0006 1ABF", + "01D1 0761 0BC9 FE2A 0000 0000 0000 10FF", + "012A 084B 0AE6 0481 0000 0000 0000 0303", + "012A 06E2 0B7C 04CC 0000 0000 0000 0A03", + "012A 073F 0AF0 FA55 0000 0000 0000 3E20", + "01A0 06AE 0B7C 0538 0000 0000 0000 FFFF", + "01A0 06AE 0B7C 0508 0000 0000 0000 FFFF", + "01A0 0719 0B7C 0532 0000 4000 0000 FFFF", + "01A0 084C 0AF0 0482 0000 4000 0000 FFFF", + "01A0 08B6 0AF0 04AB 0000 0000 0000 FFFF", + "01A0 08B6 0AF0 047B 0000 0000 0000 FFFF", + "000A 08B4 0AF0 04A6 0000 4000 0000 5CC3", + "000A 0712 0B7C 0532 0000 4000 0000 5CE6", + "0110 06A3 0BB2 0534 0000 0000 0000 FFFF", + "0110 06A3 0BB2 050A 0000 0000 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 4, Room 6", + "Start": "0232E000", + "End": "02334FA0", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "002C", + "011C", + "00A4", + "000E", + "0024", + "015C" + ], + "Actors": [ + "012D 060D 0BA0 FED0 0000 0000 0000 FFC2", + "0111 06DC 0AF0 FF65 0000 0000 0000 7212", + "0111 071B 0AF0 FFAE 0000 0000 0000 7409", + "0111 06FD 0AF0 FF86 0000 0000 0000 760B" + ] + }, + { + "File": { + "Name": "Scene 4, Room 7", + "Start": "02335000", + "End": "023389E0", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "002C", + "0025", + "011C" + ], + "Actors": [ + "012D 05B4 1098 FCA7 0000 0000 0000 FFC2", + "012D 062A 1250 FD3A 4000 0000 0000 FFC2", + "0038 053E 0FA0 FD5D 0000 0000 0000 FFFF", + "0038 05BE 1054 FD68 0000 8000 0000 FFFF", + "0112 0594 0FE8 FD39 0000 0000 0006 18BF", + "0112 0594 0FE8 FD39 0000 0000 0006 1AFF", + "0112 05B2 1038 FE8A 0000 0000 0006 18B5", + "0112 05B2 1038 FE8A 0000 0000 0006 1AF5", + "0173 05B1 103D FE8B 0000 0036 0001 3F00" + ] + }, + { + "File": { + "Name": "Scene 4, Room 8", + "Start": "02339000", + "End": "02342AC0", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "002C", + "011C", + "00A4", + "000E", + "0024", + "015C" + ], + "Actors": [ + "012D 05D4 1248 FD38 0000 0000 0000 3DC1", + "012D 073C 1248 FEC8 0000 2000 0000 3DC1", + "012D 05C9 122C 014F EE39 0000 F8E4 FF40", + "012A 07D3 1248 FE25 0000 2000 0000 3D01", + "0049 0792 1248 FE77 0000 0000 0000 1378", + "00FF 0792 1248 FE75 0000 2000 0000 FF00", + "0095 0792 1248 FE76 FF4A 2000 0000 8504", + "012A 04C5 1130 FDB1 0000 0000 0000 3800" + ] + }, + { + "File": { + "Name": "Scene 4, Room 9", + "Start": "02343000", + "End": "0234B770", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "002C", + "018E" + ], + "Actors": [ + "0008 FEC9 0BAE 0077 0000 0000 0000 03F4", + "0008 FEC9 0BAE 0105 0000 8000 0000 03F4", + "0008 0058 0BAE 0078 0000 0000 0000 03F4", + "0008 0059 0BAE 0106 0000 8000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 4, Room 10", + "Start": "0234C000", + "End": "023644A0", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "002C", + "000E", + "00A4", + "0170", + "009D", + "00B0", + "011C", + "0190", + "00A8", + "0024", + "015C" + ], + "Actors": [ + "0041 FB3C 0E74 0000 0000 0000 0000 0110", + "0041 FC04 0BB8 0000 0000 4000 0000 000E", + "000C F8D5 0AF0 FD65 00B6 49F5 0000 00FF", + "000C F85A 0AF0 FB9D 0000 4000 0000 00FF", + "000C F8F8 0AF0 FCE3 FF4A 1DDE 0000 00FF", + "000C F770 0AF0 0210 FF4A 6000 0000 00FF", + "000C F7D7 0AF0 FCBD 0000 2000 0000 00FF", + "000C F83B 0AF0 FDDA 0000 3555 0000 00FF", + "000C FBF1 0AF0 FD85 0000 6000 0000 00FF", + "000C F9C0 0AF0 FDC2 0000 2000 0000 00FF", + "000C F892 0AF0 02A8 0000 0000 0000 00FF", + "000C F897 0AF0 01B8 0000 4000 0000 00FF", + "000C F897 0AF0 03E8 0000 0000 0000 00FF", + "000C F8E5 0AF0 02FB 0000 4000 0000 00FF", + "000C F8E6 0AF0 0399 0000 4000 0000 00FF", + "000C F835 0AF0 FC39 0000 2AAB 0000 00FF", + "000C F932 0AF0 02A8 0000 0000 0000 00FF", + "000C F984 0AF0 0392 0000 4000 0000 00FF", + "000C F987 0AF0 FE48 0000 4000 0000 00FF", + "000C F987 0AF0 01B8 0000 4000 0000 00FF", + "000C F987 0AF0 0258 0000 4000 0000 00FF", + "000C F98A 0AF0 0445 0000 4000 0000 00FF", + "000C F955 0AF0 FCE1 0000 DF4A 0000 00FF", + "000C FA23 0AF0 FEC3 0000 2000 0000 00FF", + "000C FA31 0AF0 FD4E 0000 2000 0000 00FF", + "000C FA38 0AF0 0129 0000 6000 0000 00FF", + "000C FA97 0AF0 FE59 0000 2000 0000 00FF", + "000C FAB2 0AF0 FC5F 0000 5555 0000 00FF", + "000C F769 0AF0 FD2F 0000 2000 0000 00FF", + "000C FAC5 0AF0 0227 0000 2000 0000 00FF", + "000C FB0C 0AF0 FDF1 0000 1777 0000 00FF", + "000C FB36 0AF0 0227 0000 6000 0000 00FF", + "000C FB86 0AF0 FD8A 0000 2000 0000 00FF", + "000C FB9B 0AF0 0343 FF4A 6000 0000 00FF", + "000C FCDA 0AF0 FDFE 0000 2000 0000 00FF", + "000C FC68 0AF0 FDFB 0000 6000 0000 00FF", + "000C F895 0AF0 FDA2 0000 F777 0000 00FF", + "000C F7D8 0AF0 FE12 0000 76C1 0000 00FF", + "000C F9B3 0AF0 FD53 0000 DF4A 0000 00FF", + "000C F757 0AF0 FDB0 0000 599A 0000 00FF", + "008D F702 0B18 FDFD 0000 6000 0000 0039", + "0095 FAEC 0EB8 004A 4000 6000 0000 8502", + "0112 F640 0BF7 FEB7 0000 0000 0006 1AFF", + "01D1 FCE6 0AF0 0003 0000 0000 0000 9837", + "01D6 FAC5 0B91 FF15 0000 0000 0000 1836", + "01D6 FC9E 0AF0 FD9A 0000 2000 0000 9836", + "0173 FCE8 0AF0 0004 0003 0000 0000 3FA5", + "0111 F757 0B18 FF5D 0000 0000 0000 4604", + "0111 F59F 0B18 FDB1 0000 0000 0000 4803", + "0111 F8C7 0AF0 FBA6 0000 0000 0000 4A03", + "0111 F7C2 0AF0 FD7A 0000 0000 0000 4C04", + "0111 F6F1 0AF0 0346 0000 0000 0000 4E12", + "0111 F713 0AF0 0323 0000 0000 0000 500B", + "012A F74F 0AF0 FC3A 0000 2000 0000 3900" + ] + }, + { + "File": { + "Name": "Scene 4, Room 11", + "Start": "02365000", + "End": "023687C0", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "002C", + "00A4", + "000E", + "011C", + "0024", + "015C", + "0154" + ], + "Actors": [ + "012D F82E 0B69 0062 0000 4000 0000 FFC0", + "012D F9E6 0B68 0066 0000 C000 0000 FFC0", + "012A F84A 0BA4 FF85 0000 4000 0000 1901", + "000C F976 0BA4 0000 0000 C000 0000 00FF", + "000C F976 0BA4 FF74 0000 C000 0000 00FF", + "000C F976 0BA4 FEE8 0000 C000 0000 00FF", + "000C F976 0BA4 008C 0000 C000 0000 00FF", + "000C F976 0BA4 0118 0000 C000 0000 00FF", + "008D F89C 0B54 0001 0000 C000 0000 00FF", + "00CF F9E6 0AF0 FFFD 0000 C000 0000 0B02", + "0095 FA35 0B1C FFFE C000 4000 0000 8508" + ] + }, + { + "File": { + "Name": "Scene 4, Room 12", + "Start": "02369000", + "End": "0236BB80", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "002C", + "0025", + "005D", + "000D", + "0085", + "00A4", + "005F" + ], + "Actors": [ + "0112 F64E 1035 0099 0000 0000 0006 1AFF" + ] + }, + { + "File": { + "Name": "Scene 4, Room 13", + "Start": "0236C000", + "End": "02378BE0", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "002C", + "00A4", + "000E", + "011C", + "0024", + "015C", + "0154" + ], + "Actors": [ + "012D F688 11E4 FFCF 0000 0000 0000 3CC1", + "012D F70D 1130 FF02 0000 A000 0000 3CC1", + "01C9 F8F6 120C 0237 0000 638E 0009 18FF", + "0041 F6DB 1144 FED4 0000 E000 0000 0211", + "0049 F77C 1248 017C 0000 4000 0000 117A", + "0008 F704 1293 017C 0000 4000 0000 03F5", + "0008 F77C 1293 0104 0000 4000 0000 03F5", + "0008 F77C 1293 01F4 0000 4000 0000 03F5", + "0008 F7F4 1293 017C 0000 4000 0000 03F5", + "012A F6AA 1130 FF00 0000 0000 0000 3C03", + "012A FA34 1130 012C 0000 2000 0000 3A00", + "000A F77C 1248 017C 0000 E000 0000 5845" + ] + }, + { + "File": { + "Name": "Scene 4, Room 14", + "Start": "02379000", + "End": "0237B260", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "002C", + "00A4", + "000E", + "0032" + ], + "Actors": [ + "0071 F8A4 1068 FC84 0000 A000 0000 0F00", + "0112 FAC9 0F5A FEA8 0000 0000 0006 1AFD", + "0002 F81B 1054 FC05 0000 0000 0000 FFFF", + "0002 F9A7 1018 FD8D 0000 0000 0000 0003", + "0173 FAC8 0F5F FEA9 0000 003E 0001 3F00" + ] + }, + { + "File": { + "Name": "Scene 4, Room 15", + "Start": "0237C000", + "End": "0237D1D0", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "002C", + "0032", + "000D" + ], + "Actors": [ + "0013 00CA 0040 FFFA 0000 4000 0000 0003", + "0183 0064 0000 FDD9 0000 0000 0000 FF40", + "0002 0066 0000 FDAA 0000 0000 0000 FFFF", + "0002 011B 0000 FEC0 0000 0000 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 4, Room 16", + "Start": "0237E000", + "End": "02389970", + "RemapStart": null + }, + "Id": 16, + "Objects": [ + "002C", + "00A4", + "000E", + "011C", + "0170" + ], + "Actors": [ + "0112 020B 0B2F 00F6 0000 0000 0006 1AFF", + "005E 04C4 0D2A FFCE E38E 4000 0000 03FC", + "005E 035E 0B59 FF52 0000 0000 0000 03FC", + "005E 025C 0B59 FF3E 0000 0000 0000 03FC", + "005E 04C4 0CDA FFCE E38E 4000 0000 105F", + "0111 05D5 0AF0 0182 0000 0000 0000 5209", + "0111 05A5 0AF0 01BD 0000 0000 0000 5409", + "012A 04AF 0AF0 FF64 0000 2000 0000 3C20", + "01A0 04BA 0B7C 00A3 0000 E000 0000 FFFF", + "01A0 03E7 0ADC FE6E 0000 4000 0000 FFFF", + "01A0 0581 0AF0 FB68 0000 0000 0000 FFFF", + "01A0 0180 0B7C 015F 0000 4000 0000 FFFF", + "01A0 057F 0B18 FD0C 0000 4000 0000 FFFF", + "0110 04F3 0B7C 00C8 0000 2000 0000 FFFF", + "0110 04BA 0BB3 00A3 0000 1E94 0000 FFFF", + "0110 02AD 0ADC 00B7 0000 0000 0000 FFFF", + "0110 057D 0AF0 FC31 0000 0000 0000 FFFF", + "0110 01CC 0B7C 0172 0000 0000 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 4, Room 17", + "Start": "0238A000", + "End": "02393140", + "RemapStart": null + }, + "Id": 17, + "Objects": [ + "002C", + "00C9", + "000E", + "00D4", + "00F2" + ], + "Actors": [ + "011B FEE8 0000 FDBC 0000 0000 0000 12A9", + "012A FEE8 0000 FDBC 0000 0000 0000 0901", + "00DD FEE6 0082 FF70 0000 0000 0000 FFFF", + "006F FEE8 0000 FE20 0000 8000 0000 0900", + "006F FEED 0000 FEE8 0000 0000 0000 0900", + "01AE FECA 0000 FEC2 0000 0000 0000 2403", + "0008 FE9D 0032 FDBC 0000 0000 0000 03F4", + "0008 FE9D 0032 FF4C 0000 0000 0000 03F4", + "0008 FF33 0032 FDBC 0000 0000 0000 03F4", + "0008 FF33 0032 FF4C 0000 0000 0000 03F4", + "000A FF24 0000 FF24 0000 4000 0000 7542", + "000A FF10 0000 FE8E 0000 0000 0000 082C" + ] + }, + { + "File": { + "Name": "Scene 4, Room 18", + "Start": "02394000", + "End": "02397B80", + "RemapStart": null + }, + "Id": 18, + "Objects": [ + "002C", + "005F", + "0106", + "016C" + ], + "Actors": [ + "0113 0152 0014 FA54 0000 0000 0000 FF01", + "006B 00FA FFF8 FAF0 0000 0000 0000 FFFF", + "006B 01AE FFF8 FAF0 0000 0000 0000 FFFF", + "006B 0154 FFF8 FB40 0000 0000 0000 0007", + "006B 01AE FFF8 FB90 0000 0000 0000 000D", + "006B 00FA FFF8 FB90 0000 0000 0000 0011", + "0169 0151 0014 FA3A 0000 C000 0000 0001", + "0183 0153 0014 F9E5 0000 0000 0000 FF40", + "0111 00BB 0014 FA57 0000 0000 0000 5E12", + "0111 00BC 0014 FA16 0000 0000 0000 6004", + "0111 01E7 0014 FA56 0000 0000 0000 6212", + "0111 01E6 0014 FA15 0000 0000 0000 6404", + "0111 0026 0000 FB65 0000 0000 0000 6604", + "0111 002A 0000 FAEE 0000 0000 0000 6804", + "0111 0208 0000 FC51 0000 0000 0000 6A12", + "0111 0023 0000 FC4E 0000 0000 0000 6C12" + ] + }, + { + "File": { + "Name": "Scene 4, Room 19", + "Start": "02398000", + "End": "0239C1E0", + "RemapStart": null + }, + "Id": 19, + "Objects": [ + "002C", + "00A4", + "005F", + "000E", + "011C" + ], + "Actors": [ + "006B 0442 00E8 F8DA 0000 0000 0000 FFFF", + "006B 0442 00E8 F98E 0000 0000 0000 0003", + "006B 0492 00E8 F934 0000 0000 0000 0007", + "006B 04E2 00E8 F8DA 0000 0000 0000 0009", + "006B 04E2 00E8 F98E 0000 0000 0000 000D", + "006B 0532 00E8 F934 0000 0000 0000 0011", + "006B 0582 00E8 F8DA 0000 0000 0000 0015", + "006B 0582 00E8 F98E 0000 0000 0000 0019", + "008D 03C6 00A0 F933 0000 4000 0000 00FF", + "0112 032E 0138 F931 0000 0000 0006 1AFE", + "0112 0330 0136 F933 0000 0000 0001 1AFE", + "005E 04E8 00F0 F935 0000 0000 0000 2400", + "005E 036E 0104 F95D 0000 0000 0000 2400", + "0111 034D 0104 F9C9 0000 0000 0000 6E12", + "0111 0385 0104 F9C7 0000 0000 0000 700F", + "000A 0358 0104 F8D8 0000 C000 0000 27E4" + ] + }, + { + "File": { + "Name": "Scene 4, Room 20", + "Start": "0239D000", + "End": "023A3D10", + "RemapStart": null + }, + "Id": 20, + "Objects": [ + "002C", + "000E", + "00A4", + "00C9", + "0024", + "015C" + ], + "Actors": [ + "012A 06F5 0064 F8BE 0000 C000 0000 0101", + "006F 0730 0064 F8C4 0000 C000 0000 0100", + "0095 07E7 0098 F8B8 0000 C000 0000 8501", + "01AE 0757 0064 F8A5 0000 C000 0000 0423", + "0008 06CC 0098 F871 0000 C000 0000 03F5", + "0008 06CC 0098 F907 0000 C000 0000 03F5" + ] + }, + { + "File": { + "Name": "Scene 4, Room 21", + "Start": "023A4000", + "End": "023AC4C0", + "RemapStart": null + }, + "Id": 21, + "Objects": [ + "002C", + "00A4", + "00B7" + ], + "Actors": [ + "0043 0CEE 0078 0000 0000 0000 0000 2F00", + "0049 0CEE 0078 0000 0000 0000 0000 3FFF", + "0015 0D94 0280 FEB5 0000 0000 0000 2F03", + "0015 0CEB 01B8 00B4 0000 0000 0000 3003", + "0015 0DAE 0280 0140 0000 4000 0000 3403", + "005E 0CEB 01B8 FF57 0000 0000 0000 2400" + ] + }, + { + "File": { + "Name": "Scene 4, Room 22", + "Start": "023AD000", + "End": "023B3B00", + "RemapStart": null + }, + "Id": 22, + "Objects": [ + "002C", + "000E", + "00A4", + "00C9", + "00D4" + ], + "Actors": [ + "006F 0616 00C8 07D0 0000 8000 0000 0200", + "01AE 0600 00C8 07F3 0000 8000 0000 0843", + "0008 0663 00FA 076C 0000 8000 0000 03F5", + "005E 05C9 00C4 076D 0000 0000 0000 1042", + "000A 0640 00C8 0852 0000 4000 0000 5841" + ] + }, + { + "File": { + "Name": "Scene 4, Room 23", + "Start": "023B4000", + "End": "023BAD20", + "RemapStart": null + }, + "Id": 23, + "Objects": [ + "002C", + "0025", + "005D", + "000D", + "0085", + "00A4", + "005F", + "000E", + "00C9" + ], + "Actors": [ + "006F 05DC 0AF0 F900 0000 4000 0000 0500", + "01AE 05B6 0AF0 F8E7 0000 4000 0000 1463", + "0008 0640 0B24 F8AD 0000 4000 0000 03F5", + "0008 0640 0B24 F943 0000 4000 0000 03F5", + "012A 0640 0AF0 F8F8 0000 4000 0000 0500", + "000A 0550 0AF0 F8C6 0000 8000 0000 5848" + ] + }, + { + "File": { + "Name": "Scene 4, Room 24", + "Start": "023BB000", + "End": "023C0540", + "RemapStart": null + }, + "Id": 24, + "Objects": [ + "002C", + "009E", + "00AA" + ], + "Actors": [ + "0099 F490 0B68 008B 0000 0000 0000 FFFF", + "0047 F490 0B18 008B 0000 4000 0000 FFFF", + "0049 F490 0B68 008B 0000 4000 0000 0FFF", + "0015 F48F 0B18 0089 0000 0000 0000 1C11" + ] + }, + { + "File": { + "Name": "Scene 4, Room 25", + "Start": "023C1000", + "End": "023C7AE0", + "RemapStart": null + }, + "Id": 25, + "Objects": [ + "002C", + "0024", + "015C", + "001B" + ], + "Actors": [ + "0025 FCC8 0AF0 FB8A 0000 E000 0000 FFFF", + "0095 FD8E 0B36 FAC6 0000 E000 0000 8510", + "0008 FC8E 0B23 FB61 0000 2000 0000 03F5", + "0008 FCF3 0B27 FBC8 0000 A000 0000 03F5" + ] + }, + { + "File": { + "Name": "Scene 4, Room 26", + "Start": "023C8000", + "End": "023CE8A0", + "RemapStart": null + }, + "Id": 26, + "Objects": [ + "002C", + "000E", + "00A4", + "0170", + "009D", + "00B0", + "011C", + "0190", + "00A8", + "0024", + "015C" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [ + { + "Id": 1054, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1055, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1056, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1057, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1058, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1059, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1060, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1061, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1062, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1063, + "Type": 0, + "Flags": 5 + }, + { + "Id": 1291, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1292, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1293, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1294, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1295, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1296, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1297, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1298, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1301, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1302, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1303, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1304, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1305, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1306, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1309, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1310, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1311, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1312, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1313, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1314, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1315, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1316, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1317, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1318, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1319, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1320, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1321, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1322, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1325, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1326, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1329, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1330, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1331, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1332, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1335, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1336, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1337, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1338, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1339, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1340, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1341, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1342, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1343, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1344, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1345, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1346, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1347, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1348, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1349, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1350, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1351, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1352, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1353, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1354, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1355, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1356, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1357, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1358, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1359, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1360, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1361, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1362, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1363, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1364, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1365, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1366, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1367, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1368, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1369, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1374, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1375, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1376, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1377, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1378, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1379, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1380, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1381, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1382, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1383, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1384, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1385, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1386, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1387, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1388, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1393, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1394, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1395, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1396, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1397, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1398, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1401, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1402, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1403, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1404, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1405, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1406, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1407, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1408, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1417, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1418, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1419, + "Type": 37, + "Flags": 0 + }, + { + "Id": 1420, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1421, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1422, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1425, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1426, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1427, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1428, + "Type": 38, + "Flags": 0 + }, + { + "Id": 1433, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1434, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1435, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1436, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1439, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1440, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1441, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1442, + "Type": 36, + "Flags": 0 + }, + { + "Id": 1443, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1444, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1445, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1446, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1447, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1448, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1449, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1452, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1453, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1454, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1455, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1456, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1459, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1460, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1461, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1462, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1463, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1464, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1466, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1467, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1468, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1469, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1470, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1471, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1472, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1473, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1474, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1475, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1476, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1477, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1478, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1479, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1480, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1481, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1482, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1483, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1491, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1492, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1493, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1494, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1496, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1497, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1501, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1502, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1503, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1504, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1505, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1506, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1508, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1509, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1512, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1513, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1523, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1525, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1526, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1527, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1528, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1529, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1530, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1531, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1532, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1533, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1534, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1535, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1536, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1537, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1538, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1539, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1540, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1541, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1542, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1543, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1544, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1545, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1546, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1547, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1551, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1554, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1555, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1556, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1557, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1558, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1559, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1560, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1561, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1562, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1563, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1564, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1565, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1568, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1569, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1570, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1571, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1572, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1573, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1574, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1575, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1576, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1577, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1578, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1579, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1580, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1581, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1582, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1583, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1584, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1585, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1586, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1587, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1588, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1589, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1592, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1593, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1594, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1595, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1596, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1597, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1598, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1599, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1600, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1601, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1604, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1605, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1606, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1607, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1608, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1609, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1610, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1611, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1617, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1618, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1619, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1620, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1621, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1622, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1623, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1624, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1625, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1626, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1627, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1628, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1631, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1632, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1633, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1634, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1635, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1638, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1640, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1641, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1642, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1643, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1644, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1645, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1646, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1647, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1648, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1649, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1652, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1653, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1654, + "Type": 34, + "Flags": 0 + }, + { + "Id": 1655, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1656, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1659, + "Type": 31, + "Flags": 1 + }, + { + "Id": 1660, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1661, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1662, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1663, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1664, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1671, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1672, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1675, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1676, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1677, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1678, + "Type": 33, + "Flags": 1 + }, + { + "Id": 1679, + "Type": 31, + "Flags": 0 + }, + { + "Id": 1680, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1681, + "Type": 33, + "Flags": 0 + }, + { + "Id": 1694, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1695, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1699, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1700, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1701, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1702, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1703, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1704, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1705, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1706, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1707, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1708, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1709, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1710, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1711, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1712, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1713, + "Type": 44, + "Flags": 1 + }, + { + "Id": 1714, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1715, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1717, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1725, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1733, + "Type": 44, + "Flags": 0 + }, + { + "Id": 1739, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1740, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1741, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1742, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1743, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1746, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1747, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1748, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1749, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1752, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1753, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1765, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1766, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1773, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1774, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1781, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1785, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1786, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1795, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1796, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1799, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1800, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1801, + "Type": 43, + "Flags": 0 + }, + { + "Id": 1806, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1807, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1810, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1811, + "Type": 42, + "Flags": 0 + }, + { + "Id": 1919, + "Type": 45, + "Flags": 0 + }, + { + "Id": 1968, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2156, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2157, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2158, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2159, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2315, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2316, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2324, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2325, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2326, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2327, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2328, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2329, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2330, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2331, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2332, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2333, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2334, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2335, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2336, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2337, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2338, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2339, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2340, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2341, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2342, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2343, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2344, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2345, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2346, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2347, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2348, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2349, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2350, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2351, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2352, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2353, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2354, + "Type": 37, + "Flags": 1 + }, + { + "Id": 2355, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2356, + "Type": 38, + "Flags": 1 + }, + { + "Id": 2371, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2372, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2373, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2378, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2382, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2383, + "Type": 48, + "Flags": 1 + }, + { + "Id": 2384, + "Type": 48, + "Flags": 1 + }, + { + "Id": 2385, + "Type": 48, + "Flags": 1 + }, + { + "Id": 2386, + "Type": 48, + "Flags": 1 + }, + { + "Id": 2391, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2392, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2393, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2394, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2395, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2396, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2399, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2401, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2405, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2433, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2434, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2438, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2610, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2611, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2612, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2613, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2614, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2615, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2616, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2730, + "Type": 49, + "Flags": 0 + }, + { + "Id": 2731, + "Type": 49, + "Flags": 0 + }, + { + "Id": 3498, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3499, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3500, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3744, + "Type": 51, + "Flags": 0 + }, + { + "Id": 3767, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3768, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3769, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3770, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3771, + "Type": 50, + "Flags": 1 + }, + { + "Id": 3772, + "Type": 50, + "Flags": 1 + }, + { + "Id": 4187, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4188, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4189, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4190, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4191, + "Type": 40, + "Flags": 0 + }, + { + "Id": 4192, + "Type": 40, + "Flags": 0 + }, + { + "Id": 4193, + "Type": 40, + "Flags": 0 + }, + { + "Id": 4194, + "Type": 40, + "Flags": 0 + }, + { + "Id": 4195, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4196, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4197, + "Type": 40, + "Flags": 0 + }, + { + "Id": 4198, + "Type": 40, + "Flags": 0 + }, + { + "Id": 4199, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4200, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4213, + "Type": 52, + "Flags": 0 + }, + { + "Id": 4214, + "Type": 52, + "Flags": 0 + }, + { + "Id": 4215, + "Type": 52, + "Flags": 0 + }, + { + "Id": 4216, + "Type": 52, + "Flags": 0 + }, + { + "Id": 4217, + "Type": 52, + "Flags": 0 + }, + { + "Id": 4218, + "Type": 52, + "Flags": 0 + }, + { + "Id": 4223, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4224, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4225, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4226, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4227, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4228, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4229, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4230, + "Type": 46, + "Flags": 0 + }, + { + "Id": 4241, + "Type": 34, + "Flags": 0 + }, + { + "Id": 4242, + "Type": 34, + "Flags": 0 + }, + { + "Id": 4243, + "Type": 53, + "Flags": 0 + }, + { + "Id": 4244, + "Type": 53, + "Flags": 0 + }, + { + "Id": 4245, + "Type": 53, + "Flags": 0 + }, + { + "Id": 4246, + "Type": 53, + "Flags": 0 + }, + { + "Id": 4247, + "Type": 53, + "Flags": 0 + }, + { + "Id": 4249, + "Type": 34, + "Flags": 0 + }, + { + "Id": 4264, + "Type": 54, + "Flags": 4 + }, + { + "Id": 4265, + "Type": 54, + "Flags": 4 + }, + { + "Id": 4266, + "Type": 54, + "Flags": 4 + }, + { + "Id": 4276, + "Type": 55, + "Flags": 0 + }, + { + "Id": 4277, + "Type": 55, + "Flags": 0 + }, + { + "Id": 4278, + "Type": 38, + "Flags": 0 + }, + { + "Id": 4279, + "Type": 38, + "Flags": 0 + }, + { + "Id": 4280, + "Type": 38, + "Flags": 0 + }, + { + "Id": 4281, + "Type": 38, + "Flags": 0 + }, + { + "Id": 4282, + "Type": 55, + "Flags": 0 + }, + { + "Id": 4283, + "Type": 55, + "Flags": 0 + }, + { + "Id": 4284, + "Type": 55, + "Flags": 0 + }, + { + "Id": 4285, + "Type": 38, + "Flags": 0 + }, + { + "Id": 4291, + "Type": 56, + "Flags": 0 + }, + { + "Id": 4356, + "Type": 57, + "Flags": 0 + }, + { + "Id": 4357, + "Type": 57, + "Flags": 0 + }, + { + "Id": 4374, + "Type": 58, + "Flags": 0 + }, + { + "Id": 4375, + "Type": 58, + "Flags": 0 + }, + { + "Id": 4376, + "Type": 59, + "Flags": 0 + }, + { + "Id": 4377, + "Type": 59, + "Flags": 0 + }, + { + "Id": 4380, + "Type": 60, + "Flags": 4 + }, + { + "Id": 4381, + "Type": 60, + "Flags": 4 + }, + { + "Id": 4382, + "Type": 60, + "Flags": 4 + }, + { + "Id": 4383, + "Type": 60, + "Flags": 4 + }, + { + "Id": 4384, + "Type": 61, + "Flags": 1 + }, + { + "Id": 4385, + "Type": 61, + "Flags": 1 + }, + { + "Id": 4386, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4387, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4388, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4389, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4390, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4391, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4392, + "Type": 63, + "Flags": 5 + }, + { + "Id": 4393, + "Type": 63, + "Flags": 5 + }, + { + "Id": 4394, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4395, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4396, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4397, + "Type": 62, + "Flags": 5 + }, + { + "Id": 4398, + "Type": 63, + "Flags": 5 + }, + { + "Id": 4399, + "Type": 63, + "Flags": 5 + }, + { + "Id": 4404, + "Type": 60, + "Flags": 4 + }, + { + "Id": 4405, + "Type": 60, + "Flags": 4 + }, + { + "Id": 4408, + "Type": 64, + "Flags": 4 + }, + { + "Id": 4409, + "Type": 64, + "Flags": 4 + }, + { + "Id": 4410, + "Type": 54, + "Flags": 4 + }, + { + "Id": 4411, + "Type": 54, + "Flags": 4 + }, + { + "Id": 4414, + "Type": 64, + "Flags": 4 + }, + { + "Id": 4415, + "Type": 64, + "Flags": 4 + }, + { + "Id": 4643, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4644, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4652, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4653, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4654, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4655, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4656, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4657, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4658, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4659, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4660, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4661, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4709, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4710, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4711, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4712, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4713, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4714, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4715, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4716, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4717, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4718, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4719, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4720, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4721, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4722, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4723, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4724, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4725, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4726, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4727, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4728, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4737, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4738, + "Type": 36, + "Flags": 0 + }, + { + "Id": 4853, + "Type": 66, + "Flags": 0 + }, + { + "Id": 4854, + "Type": 66, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 34, + "High": 5, + "Low": 20480 + }, + { + "Id": 35, + "High": 2146309, + "Low": 2050 + }, + { + "Id": 36, + "High": 2146306, + "Low": 2050 + }, + { + "Id": 37, + "High": 49154, + "Low": 20482 + }, + { + "Id": 38, + "High": 49154, + "Low": 2050 + }, + { + "Id": 39, + "High": 604028933, + "Low": 2050 + }, + { + "Id": 40, + "High": 2146306, + "Low": 20482 + }, + { + "Id": 41, + "High": 402653189, + "Low": 20482 + }, + { + "Id": 42, + "High": 2, + "Low": 40962 + }, + { + "Id": 43, + "High": 5, + "Low": 40962 + }, + { + "Id": 44, + "High": 4, + "Low": 40962 + }, + { + "Id": 45, + "High": 4, + "Low": 30736 + }, + { + "Id": 46, + "High": 4, + "Low": 20480 + }, + { + "Id": 47, + "High": 606126085, + "Low": 20482 + }, + { + "Id": 48, + "High": 606126082, + "Low": 20482 + }, + { + "Id": 49, + "High": 1, + "Low": 2050 + }, + { + "Id": 50, + "High": 6, + "Low": 20482 + }, + { + "Id": 51, + "High": 4, + "Low": 30727 + }, + { + "Id": 52, + "High": 604028931, + "Low": 20482 + }, + { + "Id": 53, + "High": 5, + "Low": 20496 + }, + { + "Id": 54, + "High": 2, + "Low": 151554 + }, + { + "Id": 55, + "High": 49154, + "Low": 12290 + }, + { + "Id": 56, + "High": 2, + "Low": 20480 + }, + { + "Id": 57, + "High": 5, + "Low": 20506 + }, + { + "Id": 58, + "High": 5, + "Low": 20490 + }, + { + "Id": 59, + "High": 24581, + "Low": 20482 + }, + { + "Id": 60, + "High": 2, + "Low": 143362 + }, + { + "Id": 61, + "High": 402653186, + "Low": 20482 + }, + { + "Id": 62, + "High": 8388610, + "Low": 151554 + }, + { + "Id": 63, + "High": 8388610, + "Low": 143362 + }, + { + "Id": 64, + "High": 4, + "Low": 151554 + }, + { + "Id": 65, + "High": 604028931, + "Low": 2050 + }, + { + "Id": 66, + "High": 517, + "Low": 2082 + } + ], + "Cams": [ + { + "Data": 1835011, + "PositionIndex": 0 + }, + { + "Data": 1441795, + "PositionIndex": 1 + }, + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 5, + "x": 24, + "y": -40 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 3, + "IconPoints": [ + { + "Flag": 3, + "x": 75, + "y": -47 + }, + { + "Flag": 6, + "x": 72, + "y": -51 + }, + { + "Flag": 8, + "x": 65, + "y": -12 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 11, + "x": 78, + "y": -35 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 5, + "IconPoints": [ + { + "Flag": 1, + "x": 67, + "y": -58 + }, + { + "Flag": 2, + "x": 48, + "y": -30 + }, + { + "Flag": 4, + "x": 63, + "y": -14 + }, + { + "Flag": 7, + "x": 36, + "y": -45 + }, + { + "Flag": 12, + "x": 47, + "y": -26 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 26, + "y": -34 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 7, + "x": 53, + "y": 70 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 40, + "y": 47 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 11, + "x": 57, + "y": 48 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 3, + "x": 67, + "y": 73 + }, + { + "Flag": 6, + "x": 58, + "y": 76 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 2, + "x": 78, + "y": 62 + }, + { + "Flag": 12, + "x": 77, + "y": 58 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 4, + "x": 60, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 72, + "y": 68 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 8, + "x": 66, + "y": 57 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 5, + "x": 51, + "y": 61 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 5", + "Start": "025B8000", + "End": "025CDCF0", + "RemapStart": null + }, + "Id": 5, + "TActors": [ + "00FF 11FF 0023 0294 0000 0000 0000 01BF", + "04FF 00FF 0023 0294 01CC FE98 0000 01BF", + "00FF 14FF 0023 0294 030C 0000 0000 01BF", + "00FF 03FF 0023 FE98 0000 026C C000 01BF", + "14FF 00FF 0023 0000 01CC 02BC C000 01BF", + "02FF 01FF 0023 FF4C FE0C 00A0 8000 01BF", + "15FF 08FF 0023 F9E8 0104 F6FA 0000 01BF", + "09FF 00FF 0023 FB8C FEFC FE52 0000 01BF", + "05FF 00FF 0009 FCB8 030C FF4C 4000 0095", + "0CFF 00FF 002E FF4C 0000 F902 0000 003F", + "05FF 06FF 002E F510 02F8 FF4C C000 007F", + "0CFF 0EFF 002E FF4C 0000 F39E 8000 0068", + "0EFF 0FFF 002E FD58 0078 F1AA C000 01E6", + "13FF 11FF 002E 0492 030C 00B4 C000 01F7", + "01FF 00FF 002E FF4C 0050 0014 0000 003F", + "01FF 00FF 002E FF4C 01CC FE84 8000 003F", + "0BFF 00FF 0009 FF4C 0334 FB28 0000 003F", + "0AFF 00FF 002E FCB8 01CC FF4C 4000 00BB", + "06FF 0DFF 002E F3D0 0424 F984 8000 007F", + "07FF 0DFF 002E F3D0 0424 F18C 0000 007F", + "09FF 08FF 002E FB8C 003C F93E 8000 009B", + "0CFF 10FF 002E FB00 006C F57E 8000 007F", + "0FFF 0CFF 0009 FC90 0078 F57E 0000 0082", + "12FF 11FF 002E 0492 0000 00B4 C000 00BE", + "0AFF 00FF 002E FCB8 035C 0122 4000 00BF", + "16FF 0BFF 002E FF4C 0406 F7F4 0000 0154", + "07FF 15FF 0023 F3D0 0334 EF84 0000 00BF" + ], + "Paths": [ + { + "Points": [ + [ + -2561, + 621, + -186 + ], + [ + -2058, + 121, + -204 + ], + [ + -1797, + 114, + -186 + ], + [ + -1307, + 725, + -186 + ] + ] + }, + { + "Points": [ + [ + -1554, + 428, + -180 + ], + [ + -1784, + 145, + -180 + ], + [ + -1554, + 428, + -180 + ] + ] + } + ], + "Rooms": [ + { + "File": { + "Name": "Scene 5, Room 0", + "Start": "025CE000", + "End": "025E3C80", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0059", + "00A4", + "000E", + "011C", + "0190", + "00A8" + ], + "Actors": [ + "012D FF4D 0087 FBBA 0000 8000 0000 FFC2", + "012D FDA2 03A6 0165 0000 8000 0000 FFC2", + "012D FDFF 01B7 FF49 0000 C000 0000 FFC2", + "012D 0099 02F7 FF46 0000 4000 0000 FFC2", + "012D 0183 02F7 FF4D 0000 C000 0000 FFC2", + "012D FBE2 00BB FF24 4000 0000 0000 FFC2", + "0064 FCF4 030C FF4C 0000 0000 0000 1FFF", + "0064 FF50 0334 FBE4 0000 0000 0000 3FFF", + "0065 FF4C 02FD FF4C 0000 0000 0000 FF00", + "0185 FD4E 03A0 0156 0000 8000 0000 857F", + "012D FF9C 0000 01CD 0000 0000 0000 0EC1", + "012D FEFB 0000 FC68 0000 0000 0000 0EC1", + "01BB FF4D 0000 0204 0000 8000 0000 0FCE", + "01BB FF4D FF4C FBC4 0000 0000 0000 0FCE", + "01BB FCA2 003C FF49 0000 4000 0000 0FCE", + "012A FC65 003C FF4C 0000 0000 0000 0E00", + "0064 FF4C 030C 0064 0000 0000 0000 0FD9", + "012E FD4E 035C 0156 0000 8000 0000 1C9E", + "012D 003C 0000 FF4A 0000 0000 0000 1FC1", + "01BB FF4D 01CC 01E1 0000 8000 0000 00F9", + "012A FF27 01CC 019F 0000 0000 0000 3900", + "01BB 01E3 030C FF4D 0000 C000 0000 00FA", + "012A 0206 030C FF71 0000 0000 0000 3A00", + "012A FE2C 01CC FF49 0000 0000 0000 3B20" + ] + }, + { + "File": { + "Name": "Scene 5, Room 1", + "Start": "025E4000", + "End": "025EE160", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "0059", + "00A4", + "000E", + "011C", + "0190", + "00A8", + "0170" + ], + "Actors": [ + "0064 FF4C 030C FFC4 0000 0000 0000 2FFF", + "0065 FF4C 02FD FF4C 0000 0000 0000 FF00", + "0185 FED4 01B0 FFF9 0000 8000 0000 857F", + "01A0 FF2E 02BC FEB0 0000 0000 0000 FFFF", + "01A0 FF6A 02BB FEB0 0000 0000 0000 FFFF", + "01D6 FF4B 0325 FF4D 0000 0000 0000 1106", + "01D6 FF4B 03D4 FF4D 0000 0000 0000 9106", + "005E FE8E 03CF FE8E 2000 2000 0000 110A", + "005E 000A 03CF FE8E 2000 E000 0000 110A", + "005E FE8E 03CF 000A 2000 6000 0000 110A", + "005E 000A 03CF 000A 2000 A000 0000 110A", + "01BB FF4D FFBF FF9E 4000 0000 0000 1FCA", + "012E FED4 017C FFF9 0000 8000 0000 1C9D" + ] + }, + { + "File": { + "Name": "Scene 5, Room 2", + "Start": "025EF000", + "End": "025F4B90", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0059", + "00A4", + "000E", + "011C", + "0170", + "011D", + "00E5" + ], + "Actors": [ + "012D 0206 FFCB 0257 4000 0000 0000 FFC2", + "00EC 01AF FEBD 00FB 0000 0000 0000 0000", + "012C 01A2 FE48 013D 4000 0000 0000 FFFC", + "012C 00B3 FE48 013E 0000 C000 4000 FFFC", + "012C 0101 FE48 01E0 0000 0000 4000 FFFC", + "012C 0012 FE07 00F0 0000 8000 4000 FFFC", + "012C 0101 FE48 0168 0000 0000 4000 FFFC", + "012C 003B FE48 013E 0000 C000 4000 FFFC", + "012C 0036 FDF4 00F0 0000 8000 4000 FFFC", + "01A0 0019 FE0C 0246 0000 4000 0000 FFFF", + "01A0 0019 FE0C 020A 0000 4000 0000 FFFF", + "01A0 005B FE0C 027C 0000 0000 0000 FFFF", + "01A0 0066 FE0C 00CC 0000 0000 0000 FFFF", + "01A0 0097 FE0C 027C 0000 0000 0000 FFFF", + "01A0 001F FE0C 027C 0000 0000 0000 FFFF", + "01A0 00A2 FE0C 00CC 0000 0000 0000 FFFF", + "01A0 00D7 FE0C 016E 0000 4000 0000 FFFF", + "01A0 00D7 FE0C 01AA 0000 4000 0000 FFFF", + "01A0 01C7 FE0C 016D 0000 4000 0000 FFFF", + "01A0 01C7 FE0C 01A9 0000 4000 0000 FFFF", + "01A0 00DE FE0C 00CC 0000 0000 0000 FFFF", + "01A0 00D7 FE0C 01E6 0000 4000 0000 FFFF", + "01A0 012B FE0C 01E5 0000 4000 0000 FFFF", + "000A 0294 FF92 0258 0000 4000 0023 8846", + "0112 02A4 FF5D 0257 0000 0000 0006 18A3", + "012A 00DC FDFD 00C9 0000 0000 0000 3903", + "01BB 016A FE95 00F5 C000 C000 0000 1FF9", + "012A 0011 FDFD 00C9 0000 0000 0000 3A03", + "01BB 01AC FE95 0293 C000 0000 0000 1FFA" + ] + }, + { + "File": { + "Name": "Scene 5, Room 3", + "Start": "025F5000", + "End": "025FB710", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0059", + "00A4", + "0024", + "011C", + "0170", + "0154", + "015C", + "0032" + ], + "Actors": [ + "012D FBB6 0000 035C 0000 0000 0000 FFC0", + "012D FE27 0064 035A 0000 C000 0000 FFC2", + "012D FAE5 00C6 035D 0000 4000 0000 FFC2", + "0112 F6F5 018B 035E 0000 0000 0007 1AFF", + "0065 003C 02FD 032A 0000 0000 0000 FF00", + "0002 F819 012C 02FD 0000 0000 0000 0003", + "0002 F819 012C 03C6 0000 0000 0000 0003", + "01A0 F9DD 0000 02E8 0000 0000 0000 FFFF", + "01A0 F9DD 0000 03CF 0000 0000 0000 FFFF", + "01A0 F9DD 0000 0318 0000 0000 0000 FFFF", + "01A0 FA19 0000 03CF 0000 0000 0000 FFFF", + "01A0 FC21 0000 03D0 0000 0000 0000 FFFF", + "01A0 FC1E 0000 02E8 0000 0000 0000 FFFF", + "01A0 F72C 0140 02E8 0000 0000 0000 FFFF", + "01A0 F768 0140 02E7 0000 0000 0000 FFFF", + "01A0 F779 0140 03D1 0000 0000 0000 FFFF", + "01C9 F8DE 012C 0363 0000 4000 0005 18CB", + "0095 F752 0208 035F 8000 0000 0000 8610", + "0065 F95C 007D 032A 0000 0000 0000 1A02", + "0111 F6F6 0140 0302 0000 4000 0000 4204", + "0111 F6F6 0140 0328 0000 4000 0000 4804", + "005E FC4F 01AD 035C 0000 0000 2000 10E7", + "005E FC4F 0173 0379 0000 0000 2000 10E7", + "005E FC4F 0173 033A 0000 0000 2000 10E7", + "01BB F7AA 0140 035B 0000 4000 0000 1FE7", + "0111 F6F7 0140 03B0 0000 4000 0000 5209", + "0111 F6F7 0140 0389 0000 4000 0000 6A09" + ] + }, + { + "File": { + "Name": "Scene 5, Room 4", + "Start": "025FC000", + "End": "02601FE0", + "RemapStart": "25FB8D0" + }, + "Id": 4, + "Objects": [ + "0059", + "00A4", + "000E", + "011C", + "0170" + ], + "Actors": [ + "005E 0483 0320 FCC7 0000 0000 0000 2400", + "0065 0514 02FD FF4C 0000 4000 0000 FF00", + "01A0 04B5 0320 FBF4 0000 0000 0000 FFFF", + "01A0 04F1 0320 FBF4 0000 0000 0000 FFFF", + "01A0 055E 0320 FBF4 0000 0000 0000 FFFF", + "01A0 0600 0320 FC66 0000 4000 0000 FFFF", + "01A0 0600 0320 FCCB 0000 4000 0000 FFFF", + "01A0 0600 0320 FD38 0000 4000 0000 FFFF", + "01A0 059A 0320 FBF4 0000 0000 0000 FFFF", + "0110 0504 0320 FD93 0000 0000 0000 FFFF", + "0110 0571 0320 FD93 0000 0000 0000 FFFF", + "0110 053D 0320 FD93 0000 0000 0000 FFFF", + "0110 05BE 0320 FD92 0000 0000 0000 FFFF", + "0111 04C6 0320 FD97 0000 0000 0000 4003", + "0111 0462 0320 FD97 0000 0000 0000 4E03", + "0111 0494 0320 FD97 0000 0000 0000 5003" + ] + }, + { + "File": { + "Name": "Scene 5, Room 5", + "Start": "02602000", + "End": "0260C5F0", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0059", + "013B", + "013A", + "011C", + "00B5", + "00E5", + "0016", + "0012", + "0026", + "000D", + "0024", + "015C" + ], + "Actors": [ + "003B F87A 00DD 005E 0000 0000 0000 0000", + "012D FB2F 03B1 FF4C 4000 4000 0000 FFC2", + "0112 F5F8 0335 FE9E 0000 0000 0006 183F", + "0112 F5F3 0344 FE95 0000 0000 0006 193F", + "0112 F5F5 0339 FE9B 0000 0000 0006 1ABF", + "0173 F5F4 033A FFFE 0006 003E 001E 3F00", + "0064 F9EE 01A9 FF4C 0000 C000 0000 7180", + "012D F5FF 0259 FF4C 0000 0000 0000 3DC1", + "012D F5FF 01F5 FF4C 0000 0000 0000 3DC1", + "0112 F5F5 0336 0009 FF4A 0000 0006 1AFD", + "0112 F5F4 032D FFFE 0000 0000 0006 1AFD", + "0112 F5F2 033D FFF4 0000 0000 0006 1AFD", + "012D F701 00F4 FED2 0000 0000 0000 3EC1", + "012D F768 008B FE7B 0000 0000 0000 3EC1", + "012D F779 007B 001E 0000 0000 0000 3EC1", + "012D F6E0 0114 001A 0000 0000 0000 3EC1", + "012D F79F 0053 FF37 0000 0000 0000 3EC1", + "012D F69B 0158 FF8C 0000 0000 0000 3EC1", + "012A FB24 03E3 FF4C 0000 0000 4000 3E03" + ] + }, + { + "File": { + "Name": "Scene 5, Room 6", + "Start": "0260D000", + "End": "026182C0", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0059", + "0125", + "011C", + "0032" + ], + "Actors": [ + "012D F502 0328 FF0A 0000 C000 0000 FFC2", + "0183 F42D 0424 FA20 0000 0000 0000 FF40", + "0002 F3D6 0230 FE82 0000 416C 0000 FFFF", + "0002 F375 0230 FE39 0000 416C 0000 FFFF", + "0002 F373 0230 FE9D 0000 416C 0000 FFFF", + "0183 F369 0424 FA23 0000 0000 0000 FF41", + "0183 F3A4 02F8 FDE4 0000 0000 0000 FF40", + "0111 F38C 0424 F9A4 0000 0000 0000 560E", + "0111 F410 0424 F9A6 0000 0000 0000 580E", + "0111 F254 0320 FD11 0000 0000 0000 5A0C", + "0111 F254 0320 FD52 0000 0000 0000 5C12", + "0111 F254 0320 FCD6 0000 0000 0000 6012", + "0064 F3E4 02AD FCBE 0000 C000 0000 5FC3", + "0064 F2CA 02AD FF4C 0000 4000 0000 5FC3", + "0064 F39B 0389 FC25 0000 0000 0000 5FC3", + "0187 F3D3 03FC FC11 0000 0000 0000 0FFF", + "0065 F3A6 0251 FDE4 0000 0000 0000 3203", + "0064 F1DC 02D5 FDE6 0000 0000 0000 5FF2" + ] + }, + { + "File": { + "Name": "Scene 5, Room 7", + "Start": "02619000", + "End": "0261E550", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "0059", + "0125", + "013B", + "013A", + "00B5", + "00E5", + "0016", + "0012", + "0026", + "011C", + "000E", + "0090", + "0190", + "00A8" + ], + "Actors": [ + "0112 F3D2 048B EF25 0000 0000 0006 18A5", + "01BB F3D0 041F EFAC C000 0000 0000 0FE5", + "0111 F400 0438 F048 0000 0000 0000 640A", + "0111 F39F 0438 F049 0000 0000 0000 6612" + ] + }, + { + "File": { + "Name": "Scene 5, Room 8", + "Start": "0261F000", + "End": "0262CCD0", + "RemapStart": "0261EF00" + }, + "Id": 8, + "Objects": [ + "0059", + "0170", + "011C", + "011D", + "00A4" + ], + "Actors": [ + "012D F802 00E3 F863 4000 0000 0000 FFC2", + "012D F983 FFCB F861 4000 0000 0000 FFC2", + "012D FB52 00CF F8C4 4000 0000 0000 FFC2", + "012D F9E8 00EE F793 0000 0000 0000 FFC2", + "0112 FA3A FF7C F8DD 0000 0000 0006 18BF", + "0112 F75D 0073 F864 0000 0000 0006 18BF", + "0112 FA39 FF7C F8C5 0000 0000 0006 1AFF", + "00D4 FA74 0032 F862 0000 0000 0000 00FF", + "01A0 F76C 003C F846 0000 4000 0000 FFFF", + "01A0 F76C 003C F882 0000 4000 0000 FFFF", + "01A0 FB7F 003C F87A 0000 0000 0000 FFFF", + "01A0 FBBC 003C F87A 0000 0000 0000 FFFF", + "01A0 F833 FF24 F84C 0000 4000 0000 FFFF", + "01A0 F833 FF24 F888 0000 4000 0000 FFFF", + "01A0 F90E FF24 F82A 0000 0000 0000 FFFF", + "01A0 F94A FF24 F82A 0000 0000 0000 FFFF", + "0110 F75E 006C F839 0000 0000 0000 FFFF", + "0110 F75E 006C F889 0000 0000 0000 FFFF", + "0110 F75E 006C F860 0000 0000 0000 FFFF", + "005E F8B6 0088 F805 1555 E000 0000 109B", + "005E F8B5 0088 F8C0 1555 A000 0000 109B" + ] + }, + { + "File": { + "Name": "Scene 5, Room 9", + "Start": "0262D000", + "End": "02634FE0", + "RemapStart": "262CD30" + }, + "Id": 9, + "Objects": [ + "0059", + "013A", + "011C", + "00A4", + "000E", + "0170" + ], + "Actors": [ + "012D FB8C 0027 FA68 0000 0000 0000 FFC2", + "01A0 FBD3 FEFC FA86 0000 0000 0000 FFFF", + "01A0 FB17 003C F9E1 0000 0000 0000 FFFF", + "01A0 FAEF FEFC FAEC 0000 4000 0000 FFFF", + "01A0 FC27 FEFC FACB 0000 4000 0000 FFFF", + "01A0 FAF7 FEFC FB4B 0000 0000 0000 FFFF", + "000A FB8B 003C FC05 0000 0000 0000 27E5", + "005E FB4F 003C FC03 0000 0000 0000 1093", + "005E FBC8 003C FC03 0000 0000 0000 1093", + "01BB FB8C 003C FBB4 0000 8000 0000 0FD3", + "01BB FB14 003C FBB4 0000 8000 0000 0FD3", + "01BB FC04 003C FBB4 0000 8000 0000 0FD3", + "01BB FB14 00B4 FBB4 0000 8000 0000 0FD3", + "01BB FB8C 00B4 FBB4 0000 8000 0000 0FD3", + "01BB FC04 00B4 FBB4 0000 8000 0000 0FD3", + "0111 FBF7 003C F9DF 0000 0000 0000 680E", + "012A FAE5 003C FA82 0000 0000 0000 3E03", + "015F FB8C FEDE FB0F 0000 0000 0000 0FBF" + ] + }, + { + "File": { + "Name": "Scene 5, Room 10", + "Start": "02635000", + "End": "0263AFB0", + "RemapStart": "2634E40" + }, + "Id": 10, + "Objects": [ + "0059", + "0170", + "011C", + "000E", + "0024", + "015C", + "001B" + ], + "Actors": [ + "0025 FC00 043C 0079 0000 0000 0000 FFFF", + "0112 FC02 0219 010D 0000 0000 0006 1B3F", + "0065 FC0E 02FD 001E 0000 0000 0000 FF00", + "01A0 FBB1 01CC FEC5 0000 0000 0000 FFFF", + "01A0 FB82 01CC FF73 0000 0000 0000 FFFF", + "01A0 FC4F 01CC FEC5 0000 0000 0000 FFFF", + "01A0 FB7B 01CC FF23 0000 4000 0000 FFFF", + "01A0 FB83 01CC 00AD 0000 0000 0000 FFFF", + "01A0 FB82 035C 0038 0000 0000 0000 FFFF", + "01A0 FC8C 035C 0041 0000 4000 0000 FFFF", + "01A0 FC84 01CC FFA5 0000 0000 0000 FFFF", + "0110 FB72 01CC 0061 0000 0000 0000 FFFF", + "0110 FC20 035C 017E 0000 0000 0000 FFFF", + "0095 FB7E 035C 003A 0000 4000 0000 8604", + "012D FC07 035C 0018 0000 0000 0000 24C1", + "012D FBFD 0190 00CB 0000 0000 0000 24C1", + "012A FC85 01B4 FFA7 0000 0000 0000 2403", + "0111 FC23 01CC 00FF 0000 0000 0000 7003", + "0111 FBFE 01CC 0101 0000 0000 0000 7203", + "0111 FBDA 01CC 0100 0000 0000 0000 7403" + ] + }, + { + "File": { + "Name": "Scene 5, Room 11", + "Start": "0263B000", + "End": "0263F9B0", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "0059", + "013B", + "013A", + "011C", + "00B5", + "00E5", + "0016", + "0012", + "0026", + "00B0", + "0090", + "0085" + ], + "Actors": [ + "0112 FF99 0360 FB0F 0000 0000 0006 18BF", + "0112 FEFE 035F FB10 0000 0000 0006 1AFF", + "0080 FFA3 039C F97D 0000 C000 ED83 0F10", + "0080 FEE8 03DC F8FD 0000 C000 ED83 0F10", + "0080 FEF2 035B F9FD 0000 4000 127D 0F10", + "012D FEE7 0406 F81C 0000 0000 0000 3EC1", + "012D FFAE 0406 F81C 0000 0000 0000 3EC1", + "012D FEE8 0334 FB00 0000 0000 0000 3EC1", + "012D FFB0 0334 FB00 0000 0000 0000 3EC1", + "012A FF4E 04FB F7E3 4000 0000 0000 3E03" + ] + }, + { + "File": { + "Name": "Scene 5, Room 12", + "Start": "02640000", + "End": "02646D90", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "0059", + "013B", + "011C", + "0154", + "00A4", + "0170", + "0024", + "015C" + ], + "Actors": [ + "012D FF4A 00CF F60A 4000 0000 0000 FFC2", + "012D FC1A 00F7 F740 4000 0000 0000 FFC2", + "012D FAFF 00EB F5F0 4000 0000 0000 FFC2", + "0160 FE0C FF60 F4CA 0000 0000 0000 0000", + "0160 008C FF60 F74A 0000 0000 0000 0000", + "01BB FE98 0064 F470 8000 0000 0000 0FFF", + "01BB FF10 0064 F470 8000 0000 0000 0FFF", + "01BB FF88 0064 F470 8000 0000 0000 0FFF", + "01BB 0000 0064 F470 8000 0000 0000 0FFF", + "01A0 FE7A 0000 F3CA 0000 0000 0000 FFFF", + "01A0 FED1 0000 F3CA 0000 0000 0000 FFFF", + "01A0 FFA9 0000 F3CA 0000 0000 0000 FFFF", + "01A0 FFF9 0000 F3CA 0000 0000 0000 FFFF", + "01A0 FE8D 0000 F7E3 0000 0000 0000 FFFF", + "01A0 FFF5 0000 F7E5 0000 0000 0000 FFFF", + "01A0 007E FF60 F64B 0000 0000 0000 FFFF", + "01A0 FF89 FF60 F64F 0000 0000 0000 FFFF", + "01A0 FF05 FF60 F555 0000 0000 0000 FFFF", + "01A0 000B FF60 F54F 0000 0000 0000 FFFF", + "01A0 FE0E FF60 F59B 0000 0000 0000 FFFF", + "01A0 FE39 FF60 F6A6 0000 0000 0000 FFFF", + "0095 FE76 0000 F3C8 0000 4000 0000 8608", + "01C9 FD46 003C F722 0000 0000 0005 18CC" + ] + }, + { + "File": { + "Name": "Scene 5, Room 13", + "Start": "02647000", + "End": "02647A00", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "0059", + "0125", + "013B", + "013A", + "0020" + ], + "Actors": [ + "0136 F3D0 0410 F588 0000 4000 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 5, Room 14", + "Start": "02648000", + "End": "0264EE60", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "0059", + "011C", + "000E", + "0170", + "000C" + ], + "Actors": [ + "012D FE55 FFEB F1A6 0000 4000 0000 FFC2", + "0012 FF5A FF60 F34B 0000 C16C 0000 FFFF", + "0012 FF17 FED4 F1EE 0000 C0B6 0000 FFFF", + "0012 FF52 FED4 F179 0000 0000 0000 FFFF", + "0012 FF71 FED4 F1F1 0000 C0B6 0000 FFFF", + "0012 FFDA FF60 F332 0000 DA50 0000 FFFF", + "0012 FF41 FED4 F22E 0000 0000 0000 FFFF", + "0012 FF52 FEF8 F13B 0000 D3E9 0000 FFFF", + "01A0 0024 FEC0 F18C 0000 4000 0000 FFFF", + "01A0 FEF1 FED4 F10E 0000 0000 0000 FFFF", + "01A0 FE73 FF60 F116 0000 4000 0000 FFFF", + "01A0 001E FF60 F371 0000 0000 0000 FFFF", + "01A0 FFAB FED4 F27C 0000 4000 0000 FFFF", + "0065 FF4B FEDE F29A 0000 0000 0000 1804", + "0111 001C FF60 F117 0000 0000 0000 7604", + "0111 FFE4 FF60 F117 0000 0000 0000 7804" + ] + }, + { + "File": { + "Name": "Scene 5, Room 15", + "Start": "0264F000", + "End": "02656430", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "0059", + "013B", + "013A", + "011C", + "00B5", + "00E5", + "0016", + "0012", + "0026", + "000E", + "00A4", + "0090" + ], + "Actors": [ + "0112 FC2D 0095 F3DA 0000 0000 0000 10FF", + "0112 FC94 0099 F2EF 0000 0000 0000 11FF", + "005E FD53 00C8 F366 0000 0000 2000 1126", + "005E FBCD 00C8 F366 0000 0000 E000 1126", + "005E FC5A 0078 F492 0000 0000 0000 1126", + "005E FC5C 0078 F232 0000 0000 0000 1126", + "012A FD34 0078 F46E 0000 0000 0000 3803", + "015F FC2C FF10 F3E0 0000 0000 0000 0E3F", + "015F FC90 FF10 F2F0 0000 0000 0000 0E3F", + "015F FCCC FF10 F390 0000 0000 0000 0E3F" + ] + }, + { + "File": { + "Name": "Scene 5, Room 16", + "Start": "02657000", + "End": "0265AAD0", + "RemapStart": null + }, + "Id": 16, + "Objects": [ + "0059", + "000E", + "0032", + "0170", + "00AA" + ], + "Actors": [ + "0112 FAFA 00A5 F40C 0000 0000 0006 18BF", + "0002 FAFB 006C F456 0000 0000 0000 FFFF", + "01A0 FA64 006C F4C5 0000 4000 0000 FFFF", + "01A0 FA65 006C F489 0000 4000 0000 FFFF", + "01A0 FB9B 006C F492 0000 4000 0000 FFFF", + "01A0 FB9B 006C F4CE 0000 4000 0000 FFFF", + "01A0 FA64 006C F532 0000 4000 0000 FFFF", + "0015 FA60 006C F534 0000 0000 0000 0111", + "0111 FA77 006C F42F 0000 0000 0000 7A12", + "0111 FB82 006C F429 0000 0000 0000 7C0E" + ] + }, + { + "File": { + "Name": "Scene 5, Room 17", + "Start": "0265B000", + "End": "02663A20", + "RemapStart": null + }, + "Id": 17, + "Objects": [ + "0059", + "000E", + "011C", + "00A4", + "00CA", + "0190", + "00A8" + ], + "Actors": [ + "01D1 03D4 0168 0083 0000 4000 0000 08FF", + "005E 03DA 0000 0062 0000 0000 0000 2400", + "0065 03E3 02FD 00B4 0000 0000 0000 FF00", + "0173 064C 0214 00B3 0000 0018 0001 3F00", + "0185 03E7 035B 0152 0000 8000 0000 853F", + "000A 0565 01CC 00BB 0000 4000 0017 B120", + "00D2 03CD 0000 00B4 0000 C000 0000 1004", + "0112 064E 020A 00B3 0000 0000 0006 18D7", + "012E 03E7 030C 0152 0000 8000 0000 1C9C", + "012D 041C 0190 00B5 0000 0000 0000 1FC1", + "012D 035C 0000 0104 0000 0000 0000 1FC1", + "012D 035C 0000 0063 0000 0000 0000 1FC1", + "012D 035C 030C 0106 0000 0000 0000 1FC1", + "0111 0463 0000 003E 0000 4000 0000 4A0E", + "0111 0463 0000 0125 0000 4000 0000 4C0E", + "005E 034A 0384 0017 1C72 2000 0000 1137", + "005E 047B 0384 0017 1C72 E000 0000 1137", + "005E 034B 0384 0151 1C72 6000 0000 1137", + "005E 047C 0384 0152 1C72 A000 0000 1137", + "005E 0474 0014 001E 0000 C000 0000 10BE", + "005E 0474 0014 014A 0000 C000 0000 10BE" + ] + }, + { + "File": { + "Name": "Scene 5, Room 18", + "Start": "02664000", + "End": "026680C0", + "RemapStart": null + }, + "Id": 18, + "Objects": [ + "0059", + "000E", + "011C", + "00E5", + "001B" + ], + "Actors": [ + "00EC 0630 0000 00B2 0000 0000 0000 0000", + "0025 06B8 014F 011B 0000 0000 0000 FFFF", + "0025 06B5 014F 0054 0000 0000 0000 FFFF", + "0112 071E 004B 00B6 0000 0000 0006 1ABF", + "0065 0546 02FD 00B4 0000 C000 0000 FF00", + "0173 071F 0057 00B3 0000 0000 0001 3F00", + "000A 066E 0000 00AC 0000 4000 0000 1801", + "012D 04BA FFC4 0104 0000 0000 0000 1FC1", + "012D 04BA FFC4 0064 0000 0000 0000 1FC1", + "0187 05D4 0000 00F8 0000 0000 0000 7FFF" + ] + }, + { + "File": { + "Name": "Scene 5, Room 19", + "Start": "02669000", + "End": "0266C930", + "RemapStart": null + }, + "Id": 19, + "Objects": [ + "0059", + "000E", + "011C", + "0032" + ], + "Actors": [ + "0002 0612 030C 010C 0000 0000 0000 FFFF", + "0002 0615 030C 006B 0000 0000 0000 FFFF", + "0002 05CE 030C 00C0 0000 0000 0000 FFFF", + "0173 071D 0360 00B5 0000 000A 0001 3F00", + "000A 05E4 0310 00B6 0000 C000 0009 B822", + "0112 071E 0356 00B5 0000 0000 0006 1AC9" + ] + }, + { + "File": { + "Name": "Scene 5, Room 20", + "Start": "0266D000", + "End": "02673740", + "RemapStart": null + }, + "Id": 20, + "Objects": [ + "0059", + "000E", + "011C", + "0170", + "001B", + "0024", + "015C", + "00A4" + ], + "Actors": [ + "0025 028D 02C2 03B9 0000 8000 0000 FFFF", + "0025 0292 03E0 00B8 0000 0000 0000 FFFF", + "0112 0293 0218 040A 0000 0000 0006 197F", + "0065 026C 02FD 0334 0000 0000 0000 FF00", + "01A0 0330 01C6 01FE 0000 C000 0000 FFFF", + "01A0 0330 01C6 023A 0000 C000 0000 FFFF", + "01A0 020D 01D6 03BA 0000 4000 0000 FFFF", + "01A0 020C 01D6 0347 0000 4000 0000 FFFF", + "01A0 031B 01D6 032A 0000 4000 0000 FFFF", + "01A0 031B 01D6 0366 0000 4000 0000 FFFF", + "01A0 02AE 01D6 03F8 0000 0000 0000 FFFF", + "01A0 010E 01CC 01F8 0000 0000 0000 FFFF", + "01A0 01B5 01CC 0240 0000 0000 0000 FFFF", + "01A0 02BA 01CC 018F 0000 4000 0000 FFFF", + "0095 0334 01C6 021C 0000 4000 0000 8601", + "005E 02E6 01C6 01F4 0000 0000 0000 1062", + "01BB 02D1 01CC 021A 0000 C000 0000 0FE2", + "0111 0200 01CC 0243 0000 0000 0000 4402", + "0111 025A 01D6 03FE 0000 0000 0000 4609", + "0111 0315 01D6 03B3 0000 0000 0000 540E", + "0111 0300 01C6 0235 0000 0000 0000 6E03", + "0111 02FF 01C6 0205 0000 0000 0000 7E03" + ] + }, + { + "File": { + "Name": "Scene 5, Room 21", + "Start": "02674000", + "End": "0267B4A0", + "RemapStart": null + }, + "Id": 21, + "Objects": [ + "0059", + "013B", + "011C", + "0024", + "015C" + ], + "Actors": [ + "012D F516 0131 F0C8 0000 0000 0000 FFC0", + "012D F432 00AF F3B3 0000 0000 0000 FFC0", + "012D F681 00AF F31E 0000 0000 0000 FFC0", + "012D F472 00AF F61A 0000 0000 0000 FFC0", + "012D F60D 00AF F553 0000 0000 0000 FFC0", + "012D F802 00AF F432 0000 0000 0000 FFC0", + "012D F95A 00A1 F588 0000 0000 0000 FFC0", + "012D F7A2 0175 F687 0000 8000 0000 FFC2", + "012D F8A7 018C F53B 8000 8000 0000 FFC2", + "0160 F536 00C3 EEE6 0000 0000 0000 0000", + "0160 F600 006E F632 0000 0000 0000 0000", + "0160 F718 006E F2C2 0000 0000 0000 0000", + "0160 F7DF 006E F521 0000 0000 0000 0000", + "0160 F8A6 006E F639 0000 0000 0000 0000", + "0160 F91D 006E F4F7 0000 0000 0000 0000", + "0095 F5FB 01F9 F554 0000 0000 582E 8602", + "011B F4BB 017C F008 0028 0000 0000 47AB", + "011B F4D2 017C EEFA 0028 0000 0000 47AB", + "0111 F74E 0104 F649 0000 0000 0000 5E09", + "0111 F778 0104 F668 0000 0000 0000 6212" + ] + }, + { + "File": { + "Name": "Scene 5, Room 22", + "Start": "0267C000", + "End": "026850F0", + "RemapStart": null + }, + "Id": 22, + "Objects": [ + "0059", + "013B", + "013A", + "011C", + "00B5", + "00E5", + "0016", + "0012", + "0026", + "00B0" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [], + "PolyTypes": [], + "Cams": [ + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 327680, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 88, + "y": -60 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 62, + "y": -23 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 0, + "x": 88, + "y": -60 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 1, + "x": 88, + "y": -60 + }, + { + "Flag": 5, + "x": 49, + "y": -43 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 6, + "x": 75, + "y": -65 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 6, + "x": 81, + "y": 68 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 5, + "x": 75, + "y": 55 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 77, + "y": 40 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 74, + "y": 61 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 73, + "y": 65 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 0, + "x": 73, + "y": 63 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 6", + "Start": "02ADE000", + "End": "02AF7B40", + "RemapStart": null + }, + "Id": 6, + "TActors": [ + "19FF 18FF 002E 0140 06C5 FCC2 4000 00B5", + "1AFF 19FF 002E FF38 06C5 FCC2 4000 0093", + "0FFF 05FF 002E 030C 01E0 FCAE C000 0086", + "0FFF 00FF 002E 0424 0000 FDB6 0000 003F", + "0DFF 00FF 002E 055C 001E FDD1 D555 02C3", + "00FF 0EFF 002E 02EC 001E FDD1 AAAB 00B1", + "0BFF 14FF 002E 0528 03EB 05C2 4000 005A", + "0BFF 0AFF 002E FBDC 03EB 05C2 C000 0059", + "09FF 08FF 002E F95C 034B 01D6 8000 00A4", + "04FF 01FF 002E FBDC 0028 FBAA 0000 02DE", + "03FF 01FF 002E FAA4 001E FDD1 2AAB 007F", + "02FF 01FF 002E FD14 001E FDD1 D555 007F", + "16FF 18FF 002E 02A8 0661 FC72 0000 02C1", + "18FF 17FF 002E 02A8 0607 FE41 0000 0080", + "17FF 11FF 002E 0424 034B 0096 4000 02DC", + "15FF 12FF 002E 0762 034B FE66 0000 0096", + "14FF 13FF 002E 07A8 03EB 0496 8000 007F", + "13FF 12FF 002E 07A8 034B 01D6 8000 00AF", + "12FF 11FF 002E 06A4 034B 0096 C000 00AC", + "10FF 11FF 002E 0424 034B FF2E 4000 007F", + "10FF 05FF 002E 02BC 032D FDC6 8000 02DB", + "0AFF 09FF 002E F95C 03EB 0496 8000 02D5", + "07FF 08FF 002E FC54 034B FF2E C000 00A4", + "06FF 05FF 002E 003C 019D FD76 8000 0087", + "05FF 04FF 002E FD6C 01E0 FCAE C000 02D2", + "07FF 05FF 002E FDBC 032D FDC6 8000 0088", + "03FF 1BFF 002E FA65 001E FAD1 6000 007F", + "1BFF 02FF 002E FCCD 001E FA4A 1F4A 007F", + "0CFF 0DFF 002E 0621 FF7E F9BD 0000 0082", + "00FF 01FF 0023 FD8D FFCE FFFF C000 003F", + "1CFF 05FF 002E 003C 03EF F8EA 0000 0154", + "06FF 00FF 0023 0000 0179 FFC3 8000 00BF", + "19FF 05FF 0023 003C 05D0 FBBE 8000 00BF" + ], + "Paths": [ + { + "Points": [ + [ + -486, + -50, + -1 + ], + [ + -403, + -50, + -44 + ] + ] + }, + { + "Points": [ + [ + 1466, + -80, + -1423 + ], + [ + 1466, + -80, + -743 + ] + ] + }, + { + "Points": [ + [ + 1673, + -80, + -743 + ], + [ + 1673, + -80, + -1423 + ] + ] + }, + { + "Points": [ + [ + -555, + 1776, + -675 + ], + [ + -449, + 1823, + -717 + ], + [ + -440, + 1772, + -805 + ], + [ + -463, + 1818, + -902 + ], + [ + -565, + 1781, + -934 + ], + [ + -652, + 1827, + -906 + ], + [ + -685, + 1772, + -809 + ], + [ + -662, + 1823, + -722 + ], + [ + -555, + 1776, + -675 + ] + ] + }, + { + "Points": [ + [ + -565, + 1827, + -498 + ], + [ + -685, + 1767, + -442 + ], + [ + -740, + 1836, + -304 + ], + [ + -699, + 1762, + -179 + ], + [ + -551, + 1818, + -110 + ], + [ + -422, + 1758, + -170 + ], + [ + -366, + 1832, + -304 + ], + [ + -417, + 1758, + -452 + ], + [ + -565, + 1827, + -498 + ] + ] + } + ], + "Rooms": [ + { + "File": { + "Name": "Scene 6, Room 0", + "Start": "02AF8000", + "End": "02B08F40", + "RemapStart": "2AF7C00" + }, + "Id": 0, + "Objects": [ + "00F1", + "016D", + "0163", + "000E", + "013A", + "011E", + "011C", + "0025", + "00B3", + "00B7" + ], + "Actors": [ + "012D 0000 01BA FF94 0000 0000 0000 FFC2", + "0127 FF60 FF6A 010E 0000 0000 0000 000B", + "0127 0000 0118 FFC4 0000 0000 0000 800C", + "0127 015E FFFF 00DC 0000 0E39 0000 800E", + "0127 00A0 FF6A 010E 0000 0000 0000 0010", + "0127 042E 0001 FEDE 0000 0000 0000 001D", + "012A 042E 0001 FEDE 0000 0000 0000 2301", + "012A 015C 0019 00CD 0000 8000 0000 2502", + "012A FF36 0107 0324 C000 0000 0000 2603", + "0117 03F8 FFCE FFB7 0000 0000 0000 1FF7", + "0117 00A0 FF6A 010C 0000 0000 0000 1FF7", + "0117 FF60 FF6A 010E 0000 0000 0000 1FF7", + "0117 03C7 0000 FDDD 0000 0000 0000 1FF7", + "0117 02E8 FFCE 0004 0000 0000 0000 1FF7", + "00C3 FE12 FFCE FFFF 0000 4000 0000 0006", + "000A FF83 FFCE 0021 0000 8000 0000 507A", + "000A 007D 006F FF4F 0000 8000 0026 807F", + "0111 FF01 FF6A 02E6 0000 0000 0000 4203", + "0111 0132 FF6A 02AA 0000 0000 0000 6403", + "0111 FED7 FF6A 02AF 0000 0000 0000 6204", + "0117 0055 FFCE 005A 0000 0000 0000 0177", + "0111 0104 FF6A 02DF 0000 0000 0000 440E", + "015F 02E6 FF01 FFFF 000A 0005 0007 18D7", + "0185 012E FFCD 0136 0000 EAAB 0016 083F", + "0185 FEE6 FFCD 0138 0000 1555 0016 087F", + "000A 0084 006F 0021 0000 8000 0037 885B", + "000A FF79 006F FF4F 0000 8000 0025 885E" + ] + }, + { + "File": { + "Name": "Scene 6, Room 1", + "Start": "02B09000", + "End": "02B12300", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "00F1", + "016D", + "0163", + "000E", + "013A", + "011E", + "011C", + "0025", + "00B3", + "00B7" + ], + "Actors": [ + "0038 FB83 0000 FF24 0000 0000 0000 FFFF", + "0038 FC36 0000 FEA6 0000 0000 0000 FFFF", + "0013 FB7C 0048 FE0B 0000 1555 0000 0000", + "0013 FC3B 0048 FE0B 0000 EAAB 0000 0000", + "0127 FBDC 0000 FD58 0000 0000 0000 8005", + "012A FC37 0028 FC51 0000 0000 0000 0D01", + "0049 FB7C 0000 FDDF 0000 0000 0000 2FF8", + "0049 FC3B 0000 FDDF 0000 0000 0000 2FF8", + "0049 FB18 0000 FF23 0000 0000 0000 2FF8", + "0049 FCA4 0000 FF20 0000 0000 0000 2FF8", + "012A FBDC 00A9 FDD2 0000 0000 0000 3802", + "0111 FC82 FFCE FFCE 0000 0000 0000 4004", + "000A FBDE 00A7 FF8C 0000 0000 000D 885D", + "0015 FB81 0000 FDE9 0000 0000 0000 2C03", + "0015 FC30 0000 FDE9 0000 0000 0000 2E03" + ] + }, + { + "File": { + "Name": "Scene 6, Room 2", + "Start": "02B13000", + "End": "02B18C10", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "00F1", + "016D", + "0163", + "0098", + "00A2", + "0179" + ], + "Actors": [ + "0090 FE0A 001E FD22 0000 0000 0000 7FFE", + "0090 FE5C 001E FACB 0000 C000 0000 7FFE", + "0090 FE5F 001E FB8B 0000 C000 0000 7FFE", + "009D FDB6 001E FD67 0000 0000 0000 0000", + "009D FE65 001E FD67 0000 0000 0000 0000", + "00FD FDB1 0020 FBE3 0000 8000 0000 0021", + "012A FE64 001E FD66 0000 0000 0000 2100", + "0127 FDAF 001E FAC4 0000 0000 0000 0028", + "01B4 FDB5 0050 FC50 0000 0000 0000 3601", + "012A FDAE 0046 FA93 0000 2000 0000 3602", + "0127 FCEE 0077 FC5E 0000 0000 0000 003C", + "0127 FE5B FFAA FBF4 0000 0000 0000 003D", + "0111 FE82 001E FB18 0000 0000 0000 6803", + "0111 FE83 001E FB49 0000 0000 0000 660E" + ] + }, + { + "File": { + "Name": "Scene 6, Room 3", + "Start": "02B19000", + "End": "02B1CB50", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "00F1", + "016D", + "000E", + "00D6", + "000D", + "00A4", + "0114", + "00A2" + ], + "Actors": [ + "0013 F8F2 00BC FC63 0000 4000 0000 0003", + "0013 FAD0 0000 FC7A 0000 C000 0000 0003", + "0013 FA39 0051 FB8E 0000 0000 0000 0003", + "0013 F932 007A FDD5 0000 560B 0000 0003", + "0013 F9DD FFAA FBE2 0000 0000 0000 0003", + "005E F980 001E FB7B 0000 0000 0000 2400", + "005E FA39 001E FB7B 0000 0000 0000 2400", + "005E F980 001E FD38 0000 0000 0000 2400", + "005E FA39 001E FD38 0000 0000 0000 2400", + "009D F9A6 001E FAC6 0000 4000 0000 0000", + "00FD F9DF 001E FBE3 0000 0000 0000 002A", + "012A F9A4 001E FAC8 0000 0000 0000 2A00", + "00F6 F9E3 001E FD1C 0000 0000 0000 0002", + "000A F9E3 001E FD1B 0000 8000 0000 0820", + "000A F9DB 001E FB9A 0000 0000 0000 7848" + ] + }, + { + "File": { + "Name": "Scene 6, Room 4", + "Start": "02B1D000", + "End": "02B24270", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "00F1", + "016D", + "00AB", + "012A", + "000E", + "001F", + "0059", + "008B", + "000D", + "00D4", + "00CB", + "00DC", + "00F2" + ], + "Actors": [ + "002F FBD3 01EB FCE3 0000 5555 0000 FFFF", + "002F FBEA 01F3 FD2B 0000 6444 0000 FFFF", + "002F FD1D 01E0 FC02 0000 E38E 0000 FFFF", + "002F FCD0 01E0 FBAF 0000 ECCD 0000 FFFF", + "00DD FBDE 0100 FB13 0000 0000 0000 FFFF", + "0150 FC67 01E0 FC87 C000 C000 0000 0F00", + "0159 FB78 02AE FC90 0000 0000 0000 000F", + "012A FBDE 0028 FB0E 0000 0000 0000 3E43", + "012A FBDA 01E3 FB76 0000 0000 0000 3E43", + "01BB FC18 00EC FB0A 4000 C000 0000 0FFE", + "000A FD11 01E0 FBB9 0000 5C72 0000 7066", + "008A FCD1 01E0 FCF8 0000 8000 0000 0A00", + "0111 FBF5 0028 FB28 0000 0000 0000 460E", + "0185 FC68 01E0 FC8C 0000 0000 000B 04BF", + "000A FC2A 02BF FD7D 0000 4000 000F 884C" + ] + }, + { + "File": { + "Name": "Scene 6, Room 5", + "Start": "02B25000", + "End": "02B3CF40", + "RemapStart": "2B24380" + }, + "Id": 5, + "Objects": [ + "00F1", + "016D", + "00AB", + "00B0", + "00A4", + "012A", + "000E", + "0154", + "0190", + "00A8", + "016C", + "000B", + "0170" + ], + "Actors": [ + "0011 0042 0161 FB5C 0000 0000 0000 0001", + "008E 01DA 02F2 FD30 0000 C4FA 0000 0000", + "0158 003C 070A FBB2 0000 0000 0000 0000", + "015A 003C 0421 FA02 0000 0000 0000 FFFF", + "0169 003C 014D FC14 0000 0000 0000 0000", + "0169 FE34 032D FC36 0000 0000 0000 0000", + "0169 0244 032D FC36 0000 0000 0000 0000", + "0169 0244 014D FA56 0000 0000 0000 0000", + "0169 FE34 014D FA56 0000 0000 0000 0000", + "005E FF80 0287 FCB6 0000 0000 0000 2400", + "005E 00F4 0287 FCB1 0000 0000 0000 2400", + "01A0 023A 014D F9EA 0000 0000 0000 FFFF", + "01A0 01FE 014D F9EA 0000 0000 0000 FFFF", + "0110 FEF1 01F4 FC29 0000 0000 0000 FFFF", + "0156 003C 0487 FA63 0000 0000 0000 0004", + "012A 003C 0258 FD62 0000 8000 0000 0782", + "012A FEBA 029B FB2E 0000 0000 0000 0820", + "0157 003C 03CD FBBE 0000 0000 0000 0017", + "011D FDD1 032D F9F9 0000 0000 0000 FFE5", + "011D 029F 014D FB65 0000 0000 0000 FFE8", + "0011 01AA 0411 FB2B 0000 0000 0000 3302", + "012A FEBE 01B9 FA17 0000 C000 0000 3402", + "011D FF76 0287 FD1B 0000 0000 0000 FFF6", + "01D6 FDE6 02C9 FB96 0000 0000 0000 3838", + "01D6 FED9 0190 FC15 0000 0000 0000 B838", + "012E 01BD 02A2 FB0F 0000 0000 0000 1CB3", + "01D1 FE2A 01B8 FC04 0000 0000 0000 19FF", + "005E FE34 01ED FA56 0000 0000 0000 10C6", + "005E 0244 01ED FA56 0000 0000 0000 10C6", + "005E 003C 01ED FC14 0000 0000 0000 10C6", + "0111 027F 014D FB38 0000 0000 0000 4E03", + "01C9 02A1 01E0 FC41 0000 8000 0005 017F", + "0111 FDF7 032D F9D8 0000 0000 0000 4C08", + "0111 FDAD 032D F9D8 0000 0000 0000 480E", + "0111 FDD1 014D FB47 0000 0000 0000 6A0F", + "0111 02C0 014D FB38 0000 0000 0000 5210", + "0173 003B 0444 FA7E 0006 0005 0000 3C24", + "0185 01BD 02A2 FB0F 0000 0000 000B 8AF3", + "000A 003C 0164 FB3C 0000 8000 0034 B803", + "000A 020E 0502 F9C0 0000 8000 0033 888F", + "000A 02AC 032D F9FF 0000 0000 0000 6902", + "011B 003D 03C7 FBBE 001E 0000 0064 2791" + ] + }, + { + "File": { + "Name": "Scene 6, Room 6", + "Start": "02B3D000", + "End": "02B41800", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "00F1", + "016D", + "0163", + "000E", + "013A", + "011E", + "011C", + "0025", + "00B3", + "00B7" + ], + "Actors": [ + "00FF 021C 00D5 FE33 0000 0000 0000 09C7", + "012D 0000 01BA FF94 0000 0000 0000 FFC2", + "00FF 021C 019D FEFB 0000 0000 0000 09C3", + "0139 021C 00D5 FE33 0000 0000 0000 0009", + "01D5 021C 019D FEFB 0000 0000 0000 0009", + "012A 021C 015B FDD1 0000 0000 0000 0A02", + "00FF 021C 00D5 FFC3 0000 0000 0000 3FC3", + "000A 003A 022C FE65 0000 0000 000A 885C" + ] + }, + { + "File": { + "Name": "Scene 6, Room 7", + "Start": "02B42000", + "End": "02B47510", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "00F1", + "016D", + "002C" + ], + "Actors": [ + "0045 FD5A 0337 FEA5 0000 2444 0000 0000", + "0008 FCE0 0378 FED6 0000 0000 0000 03F4", + "0008 FCE0 0375 FF89 0000 0000 0000 03F4", + "0008 FD64 035A FE52 0000 0000 0000 03F4", + "0008 FDBC 036B FF2E 0000 0000 0000 03F4", + "0008 FE14 035B FE52 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 6, Room 8", + "Start": "02B48000", + "End": "02B50070", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "00F1", + "016D", + "00AB", + "012A", + "000E", + "005D", + "000B", + "0024", + "015C", + "011C", + "0179" + ], + "Actors": [ + "012D FAC2 04B3 0010 4000 0000 0000 FFC2", + "01B4 FB85 0462 0190 0000 0000 0000 FF01", + "0069 FB4F 034B 0079 0000 9777 0000 FFFE", + "0069 FA09 034B FF19 0000 53E9 0000 FFFE", + "0069 F9B2 034B 0101 0000 B333 0000 FFFE", + "0150 FA95 034B FF74 0000 0000 0000 2421", + "00B7 F960 034B FF4D 0000 0000 0000 0001", + "0150 FAD1 034B FF74 0000 0000 0000 2B21", + "0049 F919 034B 0046 0000 4000 0000 2FF8", + "0049 FA63 034B 008C 0000 0000 0000 2FF8", + "0049 FB03 034B FE84 0000 0000 0000 2FF8", + "0049 FB03 034B FEC0 0000 0000 0000 2FF8", + "0049 F97D 034B 0046 0000 4000 0000 2FF8", + "0049 FA63 034B 00FA 0000 0000 0000 2FF8", + "0049 FA63 034B 0168 0000 0000 0000 2FF8", + "012A FAB8 039B FFAB 0000 0000 0000 3803", + "01B4 FAC1 0442 000B 0000 0000 0000 3901", + "0150 FA95 034B FFD8 0000 0000 0000 3921", + "0011 FA27 034B FF99 0000 0000 0000 3A02", + "0150 F9CD 034B 0078 0000 0000 0000 3A21", + "0011 FA0E 034B 00B8 0000 0000 0000 3B02", + "0150 F969 034B FE70 0000 0000 0000 3B21", + "0111 FB04 039B 01B0 0000 0000 0000 5603", + "0095 FB9A 0462 01A5 0000 0000 0000 8701", + "0111 F99D 039B FE42 0000 0000 0000 5410", + "000A FBC8 046C FE3E 0000 4000 002B 8901" + ] + }, + { + "File": { + "Name": "Scene 6, Room 9", + "Start": "02B51000", + "End": "02B56DF0", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "00F1", + "016D", + "002C", + "0024" + ], + "Actors": [ + "0037 F95C 0463 0342 0000 8000 0000 0001", + "0008 F8F9 03CD 0336 0000 0000 0000 03F4", + "0008 F8F9 037E 024E 0000 0000 0000 03F4", + "0008 F8FA 041D 041E 0000 0000 0000 03F4", + "0008 F9BC 041D 041D 0000 0000 0000 03F4", + "0008 F9BC 03CB 0337 0000 0000 0000 03F4", + "0008 F9BD 037B 024F 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 6, Room 10", + "Start": "02B57000", + "End": "02B5F1A0", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "00F1", + "016D", + "016C", + "0106" + ], + "Actors": [ + "0008 F88E 0417 0537 0000 0000 0000 03F4", + "0008 F88E 0417 064F 0000 0000 0000 03F4", + "0008 F952 0412 06CE 0000 0000 0000 03F4", + "0008 FAF6 0411 06CE 0000 0000 0000 03F4", + "0008 FB00 0411 04BA 0000 0000 0000 03F4", + "0113 FB1E 03EB 05C4 0000 C000 0000 1901", + "0169 FB41 03EB 05C2 0000 8000 0000 0001", + "0169 F8E4 03EB 054A 0000 4000 0000 0000", + "0169 F8E4 03EB 063A 0000 4000 0000 0000", + "0169 F9D4 03EB 054A 0000 4000 0000 0000", + "0169 F9D4 03EB 063A 0000 4000 0000 0000", + "0169 FAC4 03EB 054A 0000 4000 0000 0000", + "0169 FAC4 03EB 063A 0000 4000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 6, Room 11", + "Start": "02B60000", + "End": "02B61010", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "00F1", + "016D", + "016C", + "0106" + ], + "Actors": [] + }, + { + "File": { + "Name": "Scene 6, Room 12", + "Start": "02B62000", + "End": "02B64060", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "00F1", + "016D", + "000E", + "0024", + "015C", + "007C" + ], + "Actors": [ + "0037 05E5 0046 F8C5 0000 0000 0000 0000", + "0037 06A3 0046 F88E 0000 0000 0000 0000", + "0037 05BA 0046 F84D 0000 0000 0000 0000", + "0037 06B9 0046 F90B 0000 0000 0000 0000", + "0037 062C 0046 F822 0000 0000 0000 0002", + "0037 0657 0046 F8E5 0000 0000 0000 0001", + "0037 0621 0046 F879 0000 0000 0000 0001", + "0037 0627 0046 F92C 0000 0000 0000 0001", + "0037 05A4 0046 F91B 0000 0000 0000 0001", + "0095 06C7 0000 F966 4000 A000 0000 8708", + "000A 0625 FF7E F828 0000 8000 0000 5AA7" + ] + }, + { + "File": { + "Name": "Scene 6, Room 13", + "Start": "02B65000", + "End": "02B6A850", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "00F1", + "016D", + "011F", + "0059", + "0190", + "00A8", + "00F0", + "012A", + "011F", + "0030" + ], + "Actors": [ + "0107 0517 007B FAB8 0000 0000 0000 00FF", + "004B 0621 FF7E FA53 0000 0000 0000 0000", + "0130 05BA FFB0 FA71 0000 0000 0000 0301", + "0130 0689 FFB0 FD19 0000 0000 0000 0302", + "0150 0533 0085 FCD2 0000 4000 0000 0300", + "01BB 0523 FFDF FBC5 0000 4000 0000 0FF8", + "01BB 0721 FFDF FB3E 0000 C000 0000 0FF9", + "01BB 0523 FFDF FCD3 0000 4000 0000 0FFA", + "01BB 0523 FFDF FAB7 0000 4000 0000 0FFB", + "012A 0621 001E FD9F 0000 0000 0000 3C01", + "01BB 0721 FFDF FC4D 0000 C000 0000 0FFC", + "01D1 072C 00A9 FC4C 0000 0000 0000 81FF", + "012E 04E1 FFDF FAB7 0000 0000 0000 1C7A", + "012E 04E1 FFDF FBC5 0000 0000 0000 1C82", + "012E 04E1 FFDF FCD3 0000 0000 0000 1CF9", + "012E 0760 FFDF FC4D 0000 0000 0000 1D3B", + "012E 0760 FFDF FB3E 0000 0000 0000 1D78" + ] + }, + { + "File": { + "Name": "Scene 6, Room 14", + "Start": "02B6B000", + "End": "02B6FC90", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "00F1", + "016D", + "0017", + "000E", + "0024", + "015C" + ], + "Actors": [ + "00A7 0264 FF61 FBB8 0000 0000 0000 0041", + "012E 0175 001E FC98 0000 0000 0000 1CB1", + "0095 0205 010E FC15 8000 0000 0000 8702", + "0185 0175 001E FC98 0000 00B6 000B 8AF1", + "000A 0166 001E FA90 0000 8000 0000 7AA4" + ] + }, + { + "File": { + "Name": "Scene 6, Room 15", + "Start": "02B70000", + "End": "02B78470", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "00F1", + "016D", + "00AB", + "012A", + "0032", + "000B", + "0059", + "0085" + ], + "Actors": [ + "0002 0489 01E0 FC09 0000 DA50 0000 0002", + "0002 048B 01E0 FD5A 0000 B333 0000 0002", + "0011 0480 01E0 FC96 0000 0000 0000 0000", + "0008 04C9 0035 FC50 0000 0000 0000 03F4", + "0008 04C9 0035 FD13 0000 0000 0000 03F4", + "01BB 0460 01D1 FAF6 4000 C000 0000 0FD1", + "0187 047A 027D FB16 0000 0000 0000 47FF", + "0011 03D0 01E0 FC72 0000 0000 0000 3A02", + "0150 054B 0212 FCB4 0000 C000 0000 3A30", + "0011 046A 01E0 FCD4 0000 0000 0000 3B02", + "0150 0549 0212 FD56 0000 C000 0000 3B30", + "0011 044E 01E0 FC57 0000 0000 0000 3D02", + "0150 054B 0212 FC0A 0000 C000 0000 3D30", + "00B7 0417 01E0 FC03 0000 0000 0000 0002", + "0111 04B4 0000 FC72 0000 0000 0000 6E03", + "0111 04B4 0000 FBFC 0000 0000 0000 7003", + "0080 04C4 0000 FD13 0000 C000 0000 0410", + "0080 03FC 0000 FC50 0000 4000 0000 0410", + "011B 0335 01E0 FCAE 0064 0012 0004 3291" + ] + }, + { + "File": { + "Name": "Scene 6, Room 16", + "Start": "02B79000", + "End": "02B7F190", + "RemapStart": null + }, + "Id": 16, + "Objects": [ + "00F1", + "016D", + "002C", + "011C", + "016C" + ], + "Actors": [ + "012D 037B 0410 FF2A 4000 0000 0000 FFC2", + "012D 02BC 03F7 FE62 4000 0000 0000 FFC2", + "0049 02B7 0337 FF34 0000 0000 0000 2FFF", + "0049 0344 0337 FEA7 0000 0000 0000 2FFF", + "000C 0300 0337 FEEA 0000 2000 0000 00FF", + "0008 0264 0358 FE52 0000 0000 0000 03F4", + "0008 0314 0358 FE52 0000 0000 0000 03F4", + "0008 0398 0376 FED6 0000 0000 0000 03F4", + "0008 0398 0373 FF89 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 6, Room 17", + "Start": "02B80000", + "End": "02B89610", + "RemapStart": null + }, + "Id": 17, + "Objects": [ + "00F1", + "016D", + "000E", + "008B", + "0190", + "00A8" + ], + "Actors": [ + "0110 0566 043B 00BE 0000 C000 0000 FFFF", + "012A 05B7 034B FEDD 0000 0000 0000 2C20", + "01D6 0566 0374 00BD 0000 0000 0000 1839", + "01D6 0566 03D8 00BD 0000 0000 0000 9839", + "01D6 0566 02E7 00BD 0000 0000 0000 183A", + "01D6 05BB 034B FEE7 0000 0000 0000 983A", + "008A 0510 034B 0037 0000 4000 0000 0400", + "008A 05BD 034B 0037 0000 8000 0000 0400", + "008A 05B9 034B FF8B 0000 C000 0000 0400", + "008A 050D 034B FF91 0000 0000 0000 0401", + "000A 066D 034B FF89 0000 4000 0000 7979" + ] + }, + { + "File": { + "Name": "Scene 6, Room 18", + "Start": "02B8A000", + "End": "02B8FCB0", + "RemapStart": null + }, + "Id": 18, + "Objects": [ + "00F1", + "016D", + "00AB", + "012A", + "0190", + "00A8", + "001B", + "000E", + "0114" + ], + "Actors": [ + "0025 0782 048B FFB6 0000 E9F5 0000 FFFE", + "0025 07FB 048B 00F3 0000 A71C 0000 FFFE", + "0183 07F8 034B FF24 0000 0000 0000 FF40", + "0150 0893 03E0 FF26 0000 C000 0000 1600", + "00B7 07F8 034B FF24 0000 0000 0000 0003", + "0173 0821 0360 005B 0000 0030 0001 3F00", + "01D6 0762 034B FEAC 0000 0000 0000 1838", + "01D6 07F8 034B FF24 0000 0000 0000 9838", + "0112 0820 034B 005B 0000 0000 0002 192F", + "0112 0820 034B 005B 0000 0000 0000 192F", + "000A 0820 034B 005B 0000 4000 0000 5F98" + ] + }, + { + "File": { + "Name": "Scene 6, Room 19", + "Start": "02B90000", + "End": "02B95DE0", + "RemapStart": null + }, + "Id": 19, + "Objects": [ + "00F1", + "016D", + "000E", + "000B" + ], + "Actors": [ + "008E 07A7 03EA 041B 0000 8000 0000 8000", + "0008 0745 0419 041F 0000 0000 0000 03F4", + "0008 0745 03CE 0337 0000 0000 0000 03F4", + "0008 0745 037A 024E 0000 0000 0000 03F4", + "0008 0808 041A 041F 0000 0000 0000 03F4", + "0008 0808 03CB 0337 0000 0000 0000 03F4", + "0008 0809 0379 024F 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 6, Room 20", + "Start": "02B96000", + "End": "02B9E1C0", + "RemapStart": null + }, + "Id": 20, + "Objects": [ + "00F1", + "016D", + "016C", + "0106" + ], + "Actors": [ + "0008 0605 0416 04BB 0000 0000 0000 03F4", + "0008 060F 0416 06CC 0000 0000 0000 03F4", + "0008 07B3 0416 06CD 0000 0000 0000 03F4", + "0008 0877 0417 064E 0000 0000 0000 03F4", + "0008 0878 0416 0537 0000 0000 0000 03F4", + "0113 05EB 03EB 05C1 0000 4000 0000 1A01", + "0169 05C3 03EB 05C2 0000 0000 0000 0001", + "0169 0640 03EB 054A 0000 C000 0000 0000", + "0169 0640 03EB 063A 0000 C000 0000 0000", + "0169 0730 03EB 054A 0000 C000 0000 0000", + "0169 0730 03EB 063A 0000 C000 0000 0000", + "0169 0820 03EB 054A 0000 C000 0000 0000", + "0169 0820 03EB 063A 0000 C000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 6, Room 21", + "Start": "02B9F000", + "End": "02BA3650", + "RemapStart": null + }, + "Id": 21, + "Objects": [ + "00F1", + "016D", + "000E", + "0098" + ], + "Actors": [ + "0090 0761 0369 FD84 0000 0000 0000 7FFE", + "0008 06F2 038F FD59 0000 0000 0000 03F4", + "0008 07D1 038F FD59 0000 0000 0000 03F4", + "000A 0763 0369 FD57 0000 8000 0000 27E5" + ] + }, + { + "File": { + "Name": "Scene 6, Room 22", + "Start": "02BA4000", + "End": "02BA70D0", + "RemapStart": null + }, + "Id": 22, + "Objects": [ + "00F1", + "016D", + "015C", + "0024", + "0106", + "016C" + ], + "Actors": [ + "0113 02A9 0661 FADB 0000 0000 0000 FF02", + "0169 02AA 0661 F9C7 0000 C000 0000 0001", + "0169 02DC 0661 F995 0000 0000 0000 0001", + "0169 0278 0661 F995 0000 8000 0000 0001", + "0169 01B3 0661 FAF0 0000 4000 0000 0001", + "0169 01E5 0661 FB22 0000 0000 0000 0001", + "0169 01B3 0661 FB54 0000 C000 0000 0001", + "0169 039D 0661 FAF0 0000 4000 0000 0001", + "0169 039D 0661 FB54 0000 C000 0000 0001", + "0169 036B 0661 FB22 0000 8000 0000 0001", + "0095 019A 06C9 FB22 4000 4000 0000 8704", + "0095 02A9 06AC F97C 4000 0000 0000 8710" + ] + }, + { + "File": { + "Name": "Scene 6, Room 23", + "Start": "02BA8000", + "End": "02BB1190", + "RemapStart": null + }, + "Id": 23, + "Objects": [ + "00F1", + "016D", + "00B7", + "00A4", + "000D", + "0025" + ], + "Actors": [ + "0095 02A9 04B0 FFA9 4000 0000 0000 0000", + "0038 0298 0607 FF1E 0000 182E 0000 FFFF", + "0013 0242 0686 00B9 0000 4889 0000 0000", + "0013 031C 0548 00DB 0000 A666 0000 0000", + "0013 0223 04B1 0006 0000 2CCD 0000 0000", + "0013 0316 0673 FF3E 0000 E000 0000 0000", + "00FA 02A8 04DB FFA9 0000 0000 0000 0000", + "00FA 02A8 053F FFA9 0000 0000 0000 0000", + "00FA 02A8 0413 FFA9 0000 0000 0000 0000", + "00FA 02A8 03AF FFA9 0000 0000 0000 0000", + "0117 02D3 03D1 FFB5 0000 0000 0000 1FC0", + "0117 0246 0435 FFB5 0000 0000 0000 1FC0", + "0117 02F2 050C FFB5 0000 0000 0000 1FC0", + "0117 0284 0570 FFB5 0000 0000 0000 1FC0", + "0117 02A9 049D FFB5 0000 0000 0000 1FC0", + "0111 033D 034B 00FA 0000 0000 0000 0203", + "0111 0213 034B 00F9 0000 0000 0000 0403", + "005E 0243 0387 0021 0000 0000 0000 03C0", + "005E 0243 0643 FEDF 0000 0000 0000 03C0", + "005E 030C 0387 0021 0000 0000 0000 03C0", + "005E 030C 0643 FEE2 0000 0000 0000 03C0", + "0117 02BF 034B 00A0 0000 0000 0000 0140" + ] + }, + { + "File": { + "Name": "Scene 6, Room 24", + "Start": "02BB2000", + "End": "02BB84B0", + "RemapStart": null + }, + "Id": 24, + "Objects": [ + "00F1", + "016D" + ], + "Actors": [ + "0008 024E 068F FC95 0000 0000 0000 03F4", + "0008 0302 068F FC92 0000 0000 0000 03F4", + "012E 02A7 0661 FCD0 0000 0000 0000 1CB5", + "0111 030D 06C5 FCB7 0000 0000 0000 7403", + "0111 024B 06C5 FCB4 0000 0000 0000 7204", + "0185 02A7 0661 FCD0 0000 0000 000B 8AF5" + ] + }, + { + "File": { + "Name": "Scene 6, Room 25", + "Start": "02BB9000", + "End": "02BCEB70", + "RemapStart": null + }, + "Id": 25, + "Objects": [ + "00F1", + "016D", + "00AB", + "00B0", + "00A4", + "012A", + "000E", + "0154", + "0190", + "00A8", + "016C", + "000B", + "0170" + ], + "Actors": [ + "0158 003C 070A FBB2 0000 0000 0000 0000", + "01A0 010E 064D FB5E 0000 0000 0000 FFFF", + "01A0 FF6A 064D FB5E 0000 0000 0000 FFFF", + "01A0 010E 064D FB8E 0000 0000 0000 FFFF", + "01A0 FF6A 064D FB8E 0000 0000 0000 FFFF", + "012A FF6D 064D FB5E 0000 0000 0000 1301", + "0150 003C 0675 FC84 0000 8000 0000 1700", + "0157 003C 064D FBBE 0000 0000 0000 0017", + "0112 FF59 06C5 FCC2 0000 0000 0000 3FE9", + "0111 00F4 06C5 FC83 0000 0000 0000 7803", + "0111 FF86 06C5 FD1B 0000 0000 0000 7A03", + "0111 00FA 06C5 FD1B 0000 0000 0000 7C03", + "0111 FF85 06C5 FC84 0000 0000 0000 760F" + ] + }, + { + "File": { + "Name": "Scene 6, Room 26", + "Start": "02BCF000", + "End": "02BDBB20", + "RemapStart": null + }, + "Id": 26, + "Objects": [ + "00F1", + "016D", + "00AB", + "001B", + "005D", + "000E", + "012A", + "0025" + ], + "Actors": [ + "0038 FDDF 06CF FCC2 0000 8000 0000 FFFF", + "0025 FFE8 0797 FED0 0000 C000 0000 FFFE", + "0158 003C 070A FBB2 0000 0000 0000 0000", + "00B7 FDD2 06CF FECE 0000 0000 0000 0004", + "0049 003C 06CF FECB 0000 0000 0000 2FED", + "0150 FDD1 0765 FD74 0000 8000 0000 2D00", + "0069 FDD5 06F0 FD5D 0000 0000 0000 30FB", + "0069 0235 0723 FE0E 0000 0000 0000 40FB", + "000A 0030 06CF FDD1 0000 4000 0000 6852" + ] + }, + { + "File": { + "Name": "Scene 6, Room 27", + "Start": "02BDC000", + "End": "02BE16C0", + "RemapStart": null + }, + "Id": 27, + "Objects": [ + "00F1", + "016D", + "0069", + "0032" + ], + "Actors": [ + "0049 FBA4 FFEC FA73 0000 0000 0000 0FFF", + "0049 FB15 FFEC FA22 0000 0000 0000 0FFF", + "0049 FB1F FFEC F88F 0000 0000 0000 0FFF", + "0049 FCA3 FFEC F895 0000 0000 0000 0FFF", + "0049 FC24 FFEC F84D 0000 0000 0000 0FFF", + "0049 FB8F FFEC F852 0000 0000 0000 0FFF", + "0049 FC38 FFEC FA6F 0000 0000 0000 0FFF", + "0002 FBE3 0096 F8F9 0000 0000 0000 0003", + "00AF FBE1 001E F970 0000 0000 0000 0002", + "0111 FB72 001E F875 0000 0000 0000 5C03", + "0111 FC41 001E F876 0000 0000 0000 5E03", + "0111 FCAB 001E F8D3 0000 0000 0000 6010", + "0111 FB1E 001E F8C4 0000 0000 0000 5A12" + ] + }, + { + "File": { + "Name": "Scene 6, Room 28", + "Start": "02BE2000", + "End": "02BEAA20", + "RemapStart": null + }, + "Id": 28, + "Objects": [ + "00F1", + "016D", + "00AB", + "00B0", + "00A4", + "012A", + "000E", + "0154", + "0190", + "00A8", + "016C", + "000B", + "0170" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [ + { + "Id": 3109, + "Type": 8, + "Flags": 0 + }, + { + "Id": 3110, + "Type": 8, + "Flags": 0 + }, + { + "Id": 3111, + "Type": 60, + "Flags": 0 + }, + { + "Id": 3112, + "Type": 60, + "Flags": 0 + }, + { + "Id": 3551, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3552, + "Type": 61, + "Flags": 0 + }, + { + "Id": 3553, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3554, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3555, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3556, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3557, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3558, + "Type": 63, + "Flags": 0 + }, + { + "Id": 3559, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3560, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3561, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3562, + "Type": 62, + "Flags": 0 + }, + { + "Id": 3563, + "Type": 64, + "Flags": 0 + }, + { + "Id": 3564, + "Type": 64, + "Flags": 0 + }, + { + "Id": 3729, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3730, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3731, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3732, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3733, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3734, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3735, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3736, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3737, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3738, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3739, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3740, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3741, + "Type": 65, + "Flags": 0 + }, + { + "Id": 3742, + "Type": 65, + "Flags": 0 + }, + { + "Id": 4133, + "Type": 66, + "Flags": 0 + }, + { + "Id": 4134, + "Type": 66, + "Flags": 0 + }, + { + "Id": 4212, + "Type": 8, + "Flags": 0 + }, + { + "Id": 4213, + "Type": 8, + "Flags": 0 + }, + { + "Id": 4348, + "Type": 67, + "Flags": 0 + }, + { + "Id": 4349, + "Type": 67, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 3, + "High": 49164, + "Low": 30733 + }, + { + "Id": 8, + "High": 805306379, + "Low": 12290 + }, + { + "Id": 60, + "High": 15, + "Low": 12301 + }, + { + "Id": 61, + "High": 11, + "Low": 20493 + }, + { + "Id": 62, + "High": 16395, + "Low": 134232002 + }, + { + "Id": 63, + "High": 16395, + "Low": 134238210 + }, + { + "Id": 64, + "High": 16395, + "Low": 134230018 + }, + { + "Id": 65, + "High": 49163, + "Low": 12290 + }, + { + "Id": 66, + "High": 11, + "Low": 12289 + }, + { + "Id": 67, + "High": 523, + "Low": 12322 + } + ], + "Cams": [ + { + "Data": 1966086, + "PositionIndex": 0 + }, + { + "Data": 1441795, + "PositionIndex": 1 + }, + { + "Data": 1441795, + "PositionIndex": 2 + }, + { + "Data": 1966086, + "PositionIndex": 3 + }, + { + "Data": 1441795, + "PositionIndex": 4 + }, + { + "Data": 1441795, + "PositionIndex": 5 + }, + { + "Data": 1638403, + "PositionIndex": 6 + }, + { + "Data": 1638403, + "PositionIndex": 7 + }, + { + "Data": 1638403, + "PositionIndex": 8 + }, + { + "Data": 1638403, + "PositionIndex": 9 + }, + { + "Data": 1638403, + "PositionIndex": 10 + }, + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + }, + { + "Data": 131072, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 18, + "x": 46, + "y": -30 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 5, + "IconPoints": [ + { + "Flag": 1, + "x": 23, + "y": -33 + }, + { + "Flag": 2, + "x": 56, + "y": -11 + }, + { + "Flag": 5, + "x": 83, + "y": -25 + }, + { + "Flag": 24, + "x": 84, + "y": -39 + }, + { + "Flag": 25, + "x": 74, + "y": -37 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 47, + "y": 0 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 5, + "IconPoints": [ + { + "Flag": 3, + "x": 46, + "y": -20 + }, + { + "Flag": 6, + "x": 28, + "y": -19 + }, + { + "Flag": 12, + "x": 25, + "y": -25 + }, + { + "Flag": 15, + "x": 50, + "y": -13 + }, + { + "Flag": 28, + "x": 48, + "y": -29 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 9, + "IconPoints": [ + { + "Flag": 0, + "x": 14, + "y": -24 + }, + { + "Flag": 4, + "x": 55, + "y": -14 + }, + { + "Flag": 7, + "x": 78, + "y": -2 + }, + { + "Flag": 8, + "x": 14, + "y": -16 + }, + { + "Flag": 26, + "x": 42, + "y": -43 + }, + { + "Flag": 27, + "x": 50, + "y": -43 + }, + { + "Flag": 29, + "x": 25, + "y": -35 + }, + { + "Flag": 30, + "x": 42, + "y": -36 + }, + { + "Flag": 31, + "x": 50, + "y": -36 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 4, + "IconPoints": [ + { + "Flag": 26, + "x": 27, + "y": 35 + }, + { + "Flag": 27, + "x": 36, + "y": 35 + }, + { + "Flag": 30, + "x": 27, + "y": 28 + }, + { + "Flag": 31, + "x": 36, + "y": 28 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 29, + "x": 67, + "y": 63 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 0, + "x": 71, + "y": 62 + }, + { + "Flag": 8, + "x": 71, + "y": 48 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 3, + "x": 56, + "y": 54 + }, + { + "Flag": 15, + "x": 69, + "y": 42 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 28, + "x": 60, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 76, + "y": 40 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 7, + "x": 70, + "y": 53 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 4, + "x": 68, + "y": 42 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 25, + "x": 78, + "y": 58 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 24, + "x": 78, + "y": 58 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 5, + "x": 71, + "y": 55 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 18, + "x": 75, + "y": 54 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 6, + "x": 78, + "y": 55 + }, + { + "Flag": 12, + "x": 70, + "y": 70 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 76, + "y": 37 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 57, + "y": 23 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 7", + "Start": "027A7000", + "End": "027BF3C0", + "RemapStart": null + }, + "Id": 7, + "TActors": [ + "00FF 04FF 002E F7FA FFC1 FE6B C000 007F", + "00FF 01FF 002E FCE6 FFC1 FD53 8000 007F", + "00FF 02FF 0009 FFA2 FFC1 FF47 4000 0099", + "03FF 15FF 0009 F54A FAAD FF14 8000 003F", + "08FF 05FF 0009 0EFF FDE1 0037 C000 0096", + "05FF 06FF 002E 0D1E FDE1 FE56 8000 007F", + "05FF 07FF 002E 0D1E FDE1 0218 0000 007F", + "10FF 09FF 0009 1246 FB89 09FB 0000 003F", + "0BFF 09FF 0009 09AE FAC1 05C2 0000 0097", + "12FF 0BFF 0009 09AE FB4D 031A 0000 0098", + "0EFF 0BFF 002E 07BA FAC1 043C 4000 01C8", + "0FFF 0CFF 0009 EC59 FAAD F9CE C000 003F", + "0FFF 0DFF 002E EF2E FAAD F6F9 8000 02DB", + "0FFF 11FF 002E EF2E FAAD FCA2 0000 003F", + "0FFF 15FF 002E F202 FAAD F9CE 4000 009A", + "14FF 12FF 0009 1124 FAAD FD7A 0000 003F", + "12FF 13FF 0009 1278 FAAD FF82 4000 003F", + "15FF 14FF 0009 1124 FAAD FA82 0000 0095", + "0AFF 09FF 0023 05BF FAC1 0E1F 8000 013F", + "05FF 02FF 0023 08E4 FED1 0037 C000 013F", + "08FF 09FF 0023 0FB2 FC29 0554 C000 013F", + "16FF 03FF 002E F54A FAAD 034C 8000 0154", + "06FF 15FF 0023 0F8F FCF1 FB36 C000 00BF" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 7, Room 0", + "Start": "027C0000", + "End": "027CB0C0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0190", + "00A8", + "0179" + ], + "Actors": [ + "01B4 F8D3 0008 FE6B 4000 4000 0000 0701", + "01B4 F8D3 FFA4 FE6B 4000 4000 0000 0701", + "01D1 FB97 FF71 FF47 0000 4000 0000 B80D", + "01D1 FB97 FFD5 FF47 0000 4000 0000 B80E", + "0111 FBEB FFC1 FF7E 0000 4000 0000 7003", + "0111 FBEB FFC1 FF10 0000 4000 0000 7203", + "011D F9B9 FFC1 003C 0000 8000 0000 03FB", + "011D FD1D FFC1 003C 0000 8000 0000 03FC", + "011D FA26 FFC1 003C 0000 8000 0000 03FD", + "011D FCB0 FFC1 003C 0000 8000 0000 03FE", + "012A F9ED 0005 005F 0000 8000 0000 0712", + "011C F911 0005 005F 0000 8000 0000 0000", + "011C FAC9 0005 005F 0000 8000 0000 0000", + "00AE F8D6 FFC1 FE6B 0000 C000 0000 0003", + "00AE FB06 FFC1 FF47 0000 C000 0000 0003", + "00AE FBCE FFC1 FF47 0000 C000 0000 0003", + "00AE FCE6 FFC1 FE2F 0000 0000 0000 0003", + "00AE FDFE FFC1 FF47 0000 C000 0000 0003" + ] + }, + { + "File": { + "Name": "Scene 7, Room 1", + "Start": "027CC000", + "End": "027CDAC0", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0190", + "00A8", + "0098" + ], + "Actors": [ + "0090 FCA7 FFC1 FCA2 0000 60B6 0000 7F02", + "0090 FCC4 FFC1 FC55 0000 25B0 0000 7F02", + "0090 FD04 FFC1 FCAB 0000 9A50 0000 7F02", + "0090 FD19 FFC1 FC3E 0000 D8E4 0000 7F02", + "0111 FD6F FFC1 FC4B 0000 0000 0000 4E03", + "0111 FD37 FFC1 FC08 0000 0000 0000 5803", + "000A FCE6 FFC1 FC18 0000 8000 0000 1801" + ] + }, + { + "File": { + "Name": "Scene 7, Room 2", + "Start": "027CE000", + "End": "027D8910", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "011C", + "0179" + ], + "Actors": [ + "01B4 0420 FFC1 0037 0000 4000 0000 0501", + "005E 0565 004B FFBF 0AAB C000 0000 1085", + "005E 0565 004B 00AF 0AAB C000 0000 1085", + "00AE 0146 FFC1 FF47 0000 4000 0000 0004", + "00AE 0146 FFC1 0127 0000 4000 0000 0004", + "00AE 0D1E FDE1 0037 0000 C000 0000 0006", + "00F7 029A FFC1 0037 0000 0000 0000 0B00", + "00BE 013C 0011 FF47 0000 4000 0000 0201", + "00F7 029A FFC1 0037 0000 0000 0000 0B01", + "00F7 01C8 0011 0037 0000 0000 0000 0B03", + "00F7 0231 0011 FF81 0000 D555 0000 0B03", + "00F7 0303 0011 FF81 0000 AAAB 0000 0B03", + "00F7 0231 0011 00ED 0000 2AAB 0000 0B03", + "00F7 0303 0011 00ED 0000 5555 0000 0B03", + "00F7 058D FFC1 0037 0000 0000 0000 0B02", + "0110 016E 0150 0072 0000 0000 0000 3009", + "0110 016B FFC1 FFF9 0000 0000 0000 310E", + "0110 016B FFC1 FFC2 0000 0000 0000 3904", + "0110 016D 0150 0034 0000 0000 0000 3A03" + ] + }, + { + "File": { + "Name": "Scene 7, Room 3", + "Start": "027D9000", + "End": "027DB940", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "00B0", + "005D", + "0024", + "015C" + ], + "Actors": [ + "0095 F3E9 FA87 020F 4000 0000 0000 8804", + "00AE F54A FAAD 0135 0000 0000 0000 0005" + ] + }, + { + "File": { + "Name": "Scene 7, Room 4", + "Start": "027DC000", + "End": "027DDC40", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0190", + "00A8", + "0179", + "00A6" + ], + "Actors": [ + "00A5 F61A FFC1 FEA6 0000 0000 0000 FFFF", + "00A5 F620 FFC1 FE11 0000 0000 0000 FFFF", + "00A5 F678 FFC1 FDCE 0000 0000 0000 FFFF", + "00A5 F688 FFC1 FEED 0000 0000 0000 FFFF", + "00A5 F6DB FFC1 FEB1 0000 0000 0000 FFFF", + "00A5 F6E1 FFC1 FE1C 0000 0000 0000 FFFF", + "00A4 F688 FFC1 FE63 0000 0000 0000 FFFF", + "000A F562 FFC1 FE64 0000 C000 0001 15E7" + ] + }, + { + "File": { + "Name": "Scene 7, Room 5", + "Start": "027DE000", + "End": "027E3A60", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "008B" + ], + "Actors": [ + "008A 0D1E FDE1 0037 0000 C000 0000 0700", + "00AE 0D1E FDE1 0037 0000 C000 0000 0006", + "00BE 0E14 FE31 0037 0000 C000 0000 1E01", + "0183 0D1E FDE1 0037 0000 0000 0000 FF41" + ] + }, + { + "File": { + "Name": "Scene 7, Room 6", + "Start": "027E4000", + "End": "027EB570", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0031", + "011C", + "0032", + "0024", + "015C", + "0154", + "00A8", + "0190", + "00B7" + ], + "Actors": [ + "0037 0B68 FE31 FC3F 0000 4000 0000 0000", + "0037 0DE6 FE31 FAA1 0000 0000 0000 0000", + "0037 0EC2 FE31 FB36 0000 C000 0000 0000", + "0037 0F32 FE31 FCEE 0000 C000 0000 0001", + "0117 0AFA FDE1 FC3F 0000 0000 0000 1FC1", + "0117 0BBF FE59 FB3A 0000 0000 0000 1FC1", + "0117 0CAB FDE1 FBDB 0000 0000 0000 1FC1", + "0117 0D47 FDE1 FCBA 0000 0000 0000 1FC1", + "0117 0DE6 FDE1 FA2E 0000 0000 0000 1FC1", + "0117 0D1F FE14 FC4D 0000 0000 0000 0141", + "0173 0FE1 FE20 FB35 0000 FFA6 0000 2181", + "0187 0D1E FDE1 FE2E 0000 0000 0000 1FFF", + "00AE 0F8A FDE1 FB36 0000 0000 0000 0007", + "00AF 0EB8 FDE1 FCEE 0000 4000 0000 0103", + "00B1 0D1E FDE1 FC4E 0000 0000 0000 0000", + "000A 0F98 FDE1 FCEE 0000 4000 0000 0822" + ] + }, + { + "File": { + "Name": "Scene 7, Room 7", + "Start": "027EC000", + "End": "027EDAB0", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0098", + "000D" + ], + "Actors": [ + "0090 0C8C FDE1 02D6 0000 8000 0000 7FFE", + "0090 0DAA FDE1 02D1 0000 8000 0000 7FFE", + "005E 0CEE FDE1 033E 0000 8000 0000 2400", + "005E 0D50 FDE1 033B 0000 8000 0000 2400", + "0187 0D1E FDE1 0260 0000 0000 0000 1FFF", + "000A 0D22 FDE1 0375 0000 0000 0000 7843" + ] + }, + { + "File": { + "Name": "Scene 7, Room 8", + "Start": "027EE000", + "End": "027F3060", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "008B", + "0024", + "0085", + "011C" + ], + "Actors": [ + "012D 10A2 FD69 01A8 4000 0000 0000 FFC2", + "0037 10A2 FDBC 00FD 0000 4000 0000 0001", + "008A 1322 FD69 00FD 0000 8000 0000 0400", + "008A 10A2 FC29 035E 0000 8000 0000 0700", + "0080 115F FCED 0128 0000 8000 F333 0210", + "0080 11F0 FD1E 00D8 0000 0000 0CCD 0210", + "00BC 10A2 FCBD 0266 0000 0000 0000 0000", + "00BC 10A2 FCBD 045A 0000 0000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 7, Room 9", + "Start": "027F4000", + "End": "02800B60", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "008B", + "0085", + "005D", + "012F", + "011C", + "0179", + "0031" + ], + "Actors": [ + "012D 083E FCC4 0D2C 20B6 305B 0000 FFC2", + "01B4 0B18 FAE9 0D07 0000 0000 0000 0F01", + "01B4 0BD3 FB1F 0D07 0000 0000 0000 0F01", + "01B4 0C8E FB55 0D07 0000 0000 0000 0F01", + "01B4 0D48 FB89 0D07 0000 0000 0000 0F01", + "0069 0EB7 FB6E 0C33 0000 8000 0000 FFFE", + "008A 0E5E FB89 0CE9 0000 8000 0000 0700", + "008A 0EFE FB89 0CE9 0000 8000 0000 0700", + "0080 083E FAC1 0D2C 0000 0000 0000 1220", + "0080 083E FAC1 0D2C 0000 0000 0000 1620", + "008A 083E FAC1 0D2C 0000 4000 0000 0501", + "012A 0677 FAC1 0D2C 0000 4000 0000 0903", + "0141 0B4D FAC1 0A91 0000 127D 0000 0027", + "0117 07B2 FAC1 0D2C 0000 0000 0000 1FD1", + "0117 083E FBBC 0D2C 0000 0000 0000 1FD1", + "0117 083E FC36 0D2C 0000 0000 0000 1FD1", + "0117 0853 FAC1 0BD6 0000 0000 0000 1FD1", + "0117 08CA FAC1 0D2C 0000 0000 0000 1FD1", + "0117 0727 FB56 0D32 0000 0000 0000 0151", + "004C 0EAE FB89 0D0E 0000 0000 0000 FFFF", + "012A 11A6 FB4D 0D2E 0000 BF4A 0000 0F82", + "00BC 0B7D FB55 0A55 0000 0000 0000 0000", + "00BC 0EAE FCBD 09F0 0000 0000 0000 0000", + "00BC 0EAE FCBD 0874 0000 0000 0000 0005", + "00BC 0EAE FC1D 0BD0 0000 0000 0000 0005", + "00AF 06AF FAC1 0D2C 0000 C000 0000 0903", + "00AF 0A92 FAC1 07DE 0000 0000 0000 0000", + "00AE 0F56 FB17 0B48 0000 0000 0000 0008", + "000A 083E FCF8 0E87 0000 0000 0011 892F", + "0183 0EAE FB89 0D0E 0000 0000 0000 FF41" + ] + }, + { + "File": { + "Name": "Scene 7, Room 10", + "Start": "02801000", + "End": "028087A0", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "012F", + "0024", + "015C", + "0085" + ], + "Actors": [ + "00FF 03C1 FAC1 0E65 0000 0000 0000 FF02", + "0095 0302 FB08 0FE2 C000 4000 0000 8802", + "0141 046C FAC1 1007 0000 8000 0000 0026", + "0111 0266 FAC1 0DFB 0000 0000 0000 4803", + "0111 031E FAC1 0DF6 0000 0000 0000 4A04", + "0111 0495 FB61 0E7B 0000 0000 0000 5603", + "0111 0495 FB61 0E15 0000 0000 0000 5A03", + "012A 02E2 FB61 0FE3 0000 0000 0000 0400", + "0080 0277 FAC1 0E88 0000 4000 0000 0210", + "00AE 03C1 FAC1 0EAB 0000 0000 0000 0009", + "00BC 01FF FB89 0F0F 0000 0000 0000 0001", + "00BC 02C7 FB89 0F0F 0000 0000 0000 0001", + "000A 0453 FC00 0E4B 0000 4000 0004 8844", + "000A 01F9 FAC1 0E49 0000 4000 0000 5945", + "000A 00E0 FB61 0FF0 0000 C000 0000 5886" + ] + }, + { + "File": { + "Name": "Scene 7, Room 11", + "Start": "02809000", + "End": "0280CD40", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0098", + "0179", + "011C" + ], + "Actors": [ + "012D 09AE FC79 04B0 4000 0000 0000 FFC2", + "012D 09AE FC79 057C 4000 0000 0000 FFC2", + "01B4 097C FBED 0360 0000 0000 0000 0801", + "01B4 097C FBED 03C4 0000 0000 0000 0801", + "01B4 09AE FB61 04B0 0000 0000 0000 0801", + "01B4 09AE FB61 057C 0000 0000 0000 0801", + "01B4 09E0 FBED 0360 0000 0000 0000 0801", + "01B4 09E0 FBED 03C4 0000 0000 0000 0801", + "0090 0849 FAC1 049F 0000 1555 0000 0102", + "0090 0B17 FAC1 04C1 0000 EAAB 0000 0102", + "0117 07FA FB4D 0351 0000 0000 0000 1FC8", + "0117 0857 FB37 0511 0000 0000 0000 1FC8", + "0117 08CE FB4D 03DC 0000 0000 0000 1FC8", + "0117 09AE FC31 037D 0000 0000 0000 1FC8", + "0117 09AE FAC1 04B8 0000 0000 0000 1FC8", + "0117 09AE FBB4 04B0 0000 0000 0000 1FC8", + "0117 09AE FBB4 057C 0000 0000 0000 1FC8", + "0117 0A91 FACF 0441 0000 0000 0000 1FC8", + "0117 0AAA FB4D 036C 0000 0000 0000 1FC8", + "0117 0B7C FB0F 042D 0000 0000 0000 1FC8", + "0117 09AE FAC1 0434 0000 0000 0000 0288", + "00AE 09AE FAC1 046E 0000 0000 0000 000C", + "000A 09AE FAC1 03F4 0000 8000 0000 7889" + ] + }, + { + "File": { + "Name": "Scene 7, Room 12", + "Start": "0280D000", + "End": "02812720", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "005D", + "00D4", + "00AA", + "00CD", + "000D", + "0024", + "015C", + "0031" + ], + "Actors": [ + "0015 E91E FAAD F9BB 0000 0000 0000 0611", + "0112 EC3B FBE6 F9CD 0000 C000 0001 19F8", + "0008 E87D FC59 FB1A 0000 0000 0000 03F7", + "0008 E87E FC56 F883 0000 0000 0000 03F7", + "0008 EBBE FBD1 F87D 0000 0000 0000 03F7", + "0008 EBC3 FBD1 FB16 0000 0000 0000 03F7", + "004C E818 FBB1 F91D 0000 0000 0000 FFFF", + "004C E818 FBB1 FA8A 0000 0000 0000 FFFF", + "00BB EA00 FAC1 F94F 0000 D555 0000 00FF", + "00BB EA00 FAC1 FA4A 0000 2AAB 0000 00FF", + "00BB EADA FAC1 F9CD 0000 8000 0000 00FF", + "00AF EA49 FAAD F9CD 0000 8000 0000 0002" + ] + }, + { + "File": { + "Name": "Scene 7, Room 13", + "Start": "02813000", + "End": "02813FB0", + "RemapStart": "2812800" + }, + "Id": 13, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "000D", + "0024" + ], + "Actors": [ + "0013 EFC0 FACB F583 0000 0000 0000 0003", + "0013 EE98 FAD0 F582 0000 0000 0000 0003", + "0013 EF91 FB2A F6E0 0000 8000 0000 0003", + "0013 EEA5 FADB F6DD 0000 8000 0000 0003", + "0037 F07B FB4D F5F6 0000 0000 0000 0002", + "0037 F03D FB4D F5BB 0000 C000 0000 0002", + "0037 EDE6 FB4D F63D 0000 0000 0000 0002", + "0037 F07D FB4D F67B 0000 0000 0000 0002", + "0111 EF31 FAAD F59F 0000 0000 0000 4C0E", + "00BC EE48 FAAD F631 0000 C000 0000 0003", + "00BC F014 FAAD F631 0000 C000 0000 0002", + "000A F07B FAAD F5BD 0000 8000 0000 27EB", + "000A EDE4 FAAD F5B8 0000 8000 0000 588A" + ] + }, + { + "File": { + "Name": "Scene 7, Room 14", + "Start": "02814000", + "End": "02819940", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0032" + ], + "Actors": [ + "0008 04A2 FC66 052D 0000 0000 0000 03F7", + "0008 04A3 FC66 034A 0000 0000 0000 03F7", + "0008 0762 FBF6 034E 0000 0000 0000 03F7", + "0008 0762 FBF6 052A 0000 0000 0000 03F7", + "0002 045A FBC5 0439 0000 4000 0000 0003", + "0002 05D1 FAD5 043B 0000 4000 0000 0003", + "000A 04E4 FBC5 043B 0000 4000 0000 79D0" + ] + }, + { + "File": { + "Name": "Scene 7, Room 15", + "Start": "0281A000", + "End": "02821270", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "005D", + "00D4", + "00CB", + "00DC", + "00F2" + ], + "Actors": [ + "0069 EE15 FAAD F894 0000 6222 0000 FFFF", + "0069 F04A FAAD FB05 0000 E000 0000 FFFF", + "00DD EE69 FAAD F9CF 0000 4000 0000 FFFF", + "0008 EDAB FB00 F84A 0000 0000 0000 03F7", + "0008 EDAB FB00 FB50 0000 0000 0000 03F7", + "0008 F0B2 FB00 F84A 0000 0000 0000 03F7", + "0008 F0B4 FB00 FB50 0000 0000 0000 03F7", + "00AE EF2E FAAD F9CE 0000 0000 0000 000A" + ] + }, + { + "File": { + "Name": "Scene 7, Room 16", + "Start": "02822000", + "End": "02824880", + "RemapStart": null + }, + "Id": 16, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "000D", + "00D4", + "00DC", + "00F2", + "00CB", + "0190", + "00A8", + "00B7" + ], + "Actors": [ + "0013 1377 FC38 0A9A 0000 8000 0000 0003", + "0013 13E1 FC31 0611 0000 0000 0000 0003", + "0013 163E FC5A 09D8 0000 9555 0000 0003", + "00DD 1605 FB89 0856 0000 C000 0000 FFFF", + "0015 162C FBFC 061D 0000 0000 0000 2003", + "0015 163F FBFC 0635 0000 0000 0000 2103", + "01D1 1625 FB89 0631 0000 0000 0002 380A", + "01D1 1624 FB89 0A7D 0000 0000 0000 3812", + "0117 13E1 FB89 0801 0000 0000 0000 1FC3", + "0117 1426 FB89 090B 0000 0000 0000 1FC3", + "0117 1461 FB89 073C 0000 0000 0000 1FC3", + "0117 1496 FB89 0995 0000 0000 0000 1FC3", + "0117 151C FB89 07B9 0000 0000 0000 1FC3", + "0117 155A FB89 08C3 0000 0000 0000 1FC3", + "0117 1571 FB89 09AC 0000 0000 0000 1FC3", + "0117 15E1 FB89 076A 0000 0000 0000 1FC3", + "0117 1605 FB89 0856 0000 0000 0000 1FC3", + "0117 1623 FBED 0A7E 0000 0000 0000 1FC3", + "0117 1376 FB89 085A 0000 0000 0000 0283", + "00AF 1664 FB89 0856 0000 4000 0000 0303", + "00B1 14C6 FB89 0857 0000 C000 0000 0001", + "000A 1736 FB89 088C 0000 4000 0000 6856", + "000A 1735 FB89 081F 0000 4000 0000 588C" + ] + }, + { + "File": { + "Name": "Scene 7, Room 17", + "Start": "02825000", + "End": "02827CD0", + "RemapStart": null + }, + "Id": 17, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "000B", + "00A6", + "0031", + "012F" + ], + "Actors": [ + "00A4 EF30 FAAD FE36 0000 8000 0000 FFFF", + "0111 EE21 FAAD FCD5 0000 0000 0000 660B", + "0111 F03C FAAD FCD5 0000 0000 0000 680A", + "004C EE50 FAAD FE96 0000 216C 0000 FFFF", + "004C EE64 FAAD FD4A 0000 27D2 0000 FFFF", + "004C EE86 FAAD FE63 0000 D1C7 0000 FFFF", + "004C EE98 FAAD FD9E 0000 DD28 0000 FFFF", + "004C EED2 FAAD FE52 0000 6C17 0000 FFFF", + "004C EEFA FAAD FD44 0000 F99A 0000 FFFF", + "004C EF5D FAAD FD78 0000 149F 0000 FFFF", + "004C EF99 FAAD FEB9 0000 1555 0000 FFFF", + "004C EFB5 FAAD FE02 0000 1777 0000 FFFF", + "004C EFD1 FAAD FE86 0000 A16C 0000 FFFF", + "004C EFD5 FAAD FCF2 0000 22D8 0000 FFFF", + "004C EFEE FAAD FD3B 0000 B8E4 0000 FFFF", + "004C EFF7 FAAD FE35 0000 E444 0000 FFFF", + "000A EF2F FAAD FE95 0000 0000 0000 794D" + ] + }, + { + "File": { + "Name": "Scene 7, Room 18", + "Start": "02828000", + "End": "02835280", + "RemapStart": null + }, + "Id": 18, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "000D", + "0024", + "0085" + ], + "Actors": [ + "0037 0BA9 FC0D 002C 0000 0000 0000 0001", + "0080 0A37 FB4D 0137 0000 0000 0000 0110", + "0080 0B20 FB4D 018C 0000 8000 0000 0210", + "00AE 1124 FAAD FE6A 0000 0000 0000 000B", + "00BC 0BAC FB82 FF5B 0000 0000 0000 0004", + "00BC 0BD2 FB82 0162 0000 C000 0000 0004", + "00BC 0E02 FB82 FF82 0000 C000 0000 0004", + "00BC 0F94 FAE2 0070 0000 8000 0000 0004", + "00BC 105C FAE2 FE93 0000 0000 0000 0004", + "00BC 1124 FAE2 0070 0000 8000 0000 0004" + ] + }, + { + "File": { + "Name": "Scene 7, Room 19", + "Start": "02836000", + "End": "02838D20", + "RemapStart": null + }, + "Id": 19, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0098", + "0024", + "015C" + ], + "Actors": [ + "0090 1376 FAAD FF9E 0000 44FA 0000 7F01", + "0090 138C FAAD FF2B 0000 1A50 0000 7F01", + "0090 13A2 FAAD FFCB 0000 5B06 0000 7F01", + "0090 13C5 FAAD FF5C 0000 305B 0000 7F01", + "0095 13F4 FB5D FF82 4000 C000 0000 8801", + "0183 1343 FAAD FF81 0000 0000 0000 FF40", + "0173 13ED FB37 FF82 0000 FFA6 0000 2228", + "000A 13D0 FAAD FFED 0000 4000 0000 6855" + ] + }, + { + "File": { + "Name": "Scene 7, Room 20", + "Start": "02839000", + "End": "0283AE20", + "RemapStart": null + }, + "Id": 20, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "008D", + "0098", + "0024", + "015C" + ], + "Actors": [ + "0090 109D FAAD FBD2 0000 1555 0000 7FFE", + "0090 11AF FAAD FBC7 0000 EAAB 0000 7FFE", + "0095 1063 FAAD FAED 0000 1C72 0000 8808", + "0111 107E FAAD FC6C 0000 0000 0000 5C01", + "0111 11C5 FAAD FC66 0000 0000 0000 640C", + "011D 1086 FAAD FB64 0000 0000 0000 00F6", + "011D 11C3 FAAD FB61 0000 0000 0000 03F7", + "00BE 106F FAC7 FAE1 0000 0000 0000 1302", + "00BE 11D9 FAC7 FD19 0000 8000 0000 1C02", + "000A 11E7 FAAD FD0D 0000 4000 0000 6934", + "000A 1129 FAAD FBCC 0000 8000 0000 7888" + ] + }, + { + "File": { + "Name": "Scene 7, Room 21", + "Start": "0283B000", + "End": "028464B0", + "RemapStart": null + }, + "Id": 21, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "0031", + "011C", + "0032", + "0024", + "015C", + "0154", + "00A8", + "0190", + "00B7" + ], + "Actors": [ + "012D F22A FC15 FC83 0000 4000 0000 0CC1", + "012D F34A FAAD FC8A 0000 0000 0000 0CC1", + "012E 123E FB78 F82B 0000 C000 0001 1CB8", + "0095 0F26 FC4A FA29 0000 4000 0000 0000", + "0037 0F47 FB9D FA32 0000 4000 0000 0002", + "01C9 0F84 FBED F9A0 0000 4000 0003 0539", + "00FF 0F62 FAAD FA32 0000 0000 0000 1D02", + "00FF 117E FA9E F9CE 0000 0000 0000 1DC6", + "0139 117E FA9E F9CE 0000 0000 0000 001D", + "0015 0F83 FBED F94C 0000 0000 0000 2203", + "0015 0F82 FBED F9E8 0000 0000 0000 2303", + "0015 F26F FC15 FC61 0000 0000 0000 3903", + "0015 F271 FC15 FC8C 0000 0000 0000 3A03", + "0015 F3A4 FB4F FD7A 0000 0000 0000 3C03", + "0095 F7FF FA35 FA75 4000 0000 0000 8810", + "01D1 F39E FAAD FD12 0000 0000 0002 B8FF", + "0002 04B9 FC32 F842 0000 0000 0000 0003", + "0002 0ABA FC21 F825 0000 0000 0000 0003", + "0173 F55C FAF3 FDAC 0006 0011 001E 2084", + "0111 F6A0 FAAD FA42 0000 0000 0000 7009", + "0111 F74A FAAD FA42 0000 0000 0000 7609", + "0111 F4D5 FAAD FE0F 0000 0000 0000 7A0A", + "0111 F5C0 FAAD FE14 0000 0000 0000 7C0E", + "012A F230 FC15 FC53 0000 0000 0000 1A00", + "004C F6EF FAAD FCFE 0000 8000 0000 FFFF", + "004C F70D FAAD FC93 0000 8000 0000 FFFF", + "004C F722 FAAD FD19 0000 8000 0000 FFFF", + "004C F736 FAAD FCBD 0000 8000 0000 FFFF", + "004C F74B FAAD FCF3 0000 8000 0000 FFFF", + "012A F39B FAD0 FD44 0000 8000 0000 0C02", + "00BE F72F FAD5 FD45 0000 0000 0000 1000", + "00B0 1282 FA8D F82A 0000 0000 0000 3800", + "000A 0F5A FB4D FAAA 0000 C000 0000 684E" + ] + }, + { + "File": { + "Name": "Scene 7, Room 22", + "Start": "02847000", + "End": "028499A0", + "RemapStart": null + }, + "Id": 22, + "Objects": [ + "0069", + "0187", + "000E", + "00A4", + "00B0" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [], + "PolyTypes": [], + "Cams": [ + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + }, + { + "Data": 131072, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 1, + "x": 41, + "y": -17 + }, + { + "Flag": 7, + "x": 27, + "y": -24 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 2, + "x": 81, + "y": -20 + }, + { + "Flag": 3, + "x": 74, + "y": -37 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 12, + "x": 96, + "y": -51 + }, + { + "Flag": 16, + "x": 46, + "y": -42 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 12, + "IconPoints": [ + { + "Flag": 4, + "x": 43, + "y": -66 + }, + { + "Flag": 5, + "x": 37, + "y": -66 + }, + { + "Flag": 6, + "x": 33, + "y": -72 + }, + { + "Flag": 8, + "x": 85, + "y": -18 + }, + { + "Flag": 9, + "x": 61, + "y": -42 + }, + { + "Flag": 10, + "x": 15, + "y": -4 + }, + { + "Flag": 11, + "x": 25, + "y": -4 + }, + { + "Flag": 13, + "x": 19, + "y": -29 + }, + { + "Flag": 14, + "x": 78, + "y": -15 + }, + { + "Flag": 15, + "x": 60, + "y": -70 + }, + { + "Flag": 21, + "x": 92, + "y": -29 + }, + { + "Flag": 20, + "x": 87, + "y": -20 + } + ] + }, + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 31, + "y": -45 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 77, + "y": 64 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 1, + "Count": 1, + "IconPoints": [ + { + "Flag": -1, + "x": 77, + "y": 76 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 7, + "x": 76, + "y": 65 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 2, + "x": 83, + "y": 67 + }, + { + "Flag": 14, + "x": 84, + "y": 59 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 3, + "x": 76, + "y": 67 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 3, + "IconPoints": [ + { + "Flag": 4, + "x": 78, + "y": 62 + }, + { + "Flag": 5, + "x": 74, + "y": 62 + }, + { + "Flag": 6, + "x": 71, + "y": 68 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 9, + "x": 77, + "y": 64 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 10, + "x": 71, + "y": 65 + }, + { + "Flag": 11, + "x": 80, + "y": 65 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 16, + "x": 73, + "y": 64 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 12, + "x": 87, + "y": 64 + }, + { + "Flag": 22, + "x": 87, + "y": 68 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 13, + "x": 77, + "y": 66 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 21, + "x": 78, + "y": 66 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 8, + "x": 76, + "y": 66 + }, + { + "Flag": 20, + "x": 78, + "y": 68 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 14, + "x": 77, + "y": 62 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 15, + "x": 56, + "y": 67 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 16, + "x": 73, + "y": 64 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 14, + "x": 77, + "y": 62 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 8", + "Start": "032C6000", + "End": "032D2560", + "RemapStart": null + }, + "Id": 8, + "TActors": [ + "01FF 00FF 002E FC86 0000 FF9C 0000 009F", + "03FF 00FF 002E 0366 0000 FCA4 0000 02D5", + "03FF 00FF 002E 0474 0000 FA74 8000 00BB", + "05FF 00FF 002E 01C2 0000 FC7C 0000 008A", + "06FF 00FF 002E FE66 0000 FC7C 0000 008C", + "00FF 02FF 002E F9DE 0000 FD1C C000 02D4", + "00FF 04FF 002E 0384 FFEC 00D2 4000 0056", + "00FF 01FF 0023 FECA FEE8 FDE4 0000 00BF", + "00FF 01FF 0023 FC7C FEE8 FA24 0000 00BF", + "00FF 01FF 0023 0000 FF10 FD1C 0000 00BF", + "05FF 01FF 0023 0172 FEE8 FB82 0000 00BF", + "00FF 01FF 0023 0280 FEE8 FA10 0000 00BF", + "03FF 01FF 0023 044C FEE8 FB28 C000 00BF", + "03FF 01FF 0023 0384 FEE8 FBB4 C000 00BF", + "03FF 01FF 0023 0410 FEE8 FC7C C000 00BF" + ], + "Paths": [ + { + "Points": [ + [ + 847, + -391, + -1432 + ], + [ + 565, + -654, + -1240 + ], + [ + 123, + -664, + -1109 + ], + [ + -41, + -645, + -634 + ], + [ + -8, + -654, + -282 + ], + [ + 75, + -645, + 29 + ] + ] + }, + { + "Points": [ + [ + 1286, + -391, + -1123 + ], + [ + 1066, + -673, + -1077 + ], + [ + 834, + -654, + -841 + ], + [ + 443, + -645, + -757 + ], + [ + 249, + -654, + -459 + ], + [ + 107, + -664, + -158 + ] + ] + } + ], + "Rooms": [ + { + "File": { + "Name": "Scene 8, Room 0", + "Start": "032D3000", + "End": "032E85F0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "008D", + "0187", + "000E", + "00A4", + "0098", + "0024", + "015C", + "0059", + "0163", + "000B", + "00AA", + "011F", + "0090", + "00B7" + ], + "Actors": [ + "0095 0455 0048 FD27 0000 C000 0000 0000", + "0095 0456 0068 FCEC 0000 C000 0000 0000", + "0037 FEC9 00A0 FE67 0000 C000 0000 0001", + "0011 FFFE 0000 FD1A 0000 0000 0000 0001", + "0090 001D 0000 0254 0000 DC72 0000 7F02", + "0112 FD92 0062 F9EF 0000 0000 0004 18BF", + "0112 FD92 0062 F9EF 0000 0000 0004 18BF", + "0112 027F 0060 F9EE 0000 0000 0004 18BF", + "0112 FD92 0062 F9EF 0000 0000 0004 19FF", + "0112 027F 0061 F9EC 0000 0000 0004 19FF", + "0112 FD92 0062 F9EF 0000 0000 0004 1AFF", + "0112 027F 0061 F9ED 0000 0000 0004 1AFF", + "0112 027F 0061 F9EE 0000 0000 0004 1AFF", + "0183 0153 0000 FE4B 0000 0000 0000 FF40", + "012A 0064 0058 F967 2EEF CAAB 0000 0303", + "00D7 0000 0000 FD1C 0000 0000 0000 0003", + "000A 0001 0000 FCE1 0000 0000 0000 0823", + "01BB 020F 0000 FF49 0000 4000 0000 0FC5", + "012A FE84 0056 FF61 0000 C000 0000 0502", + "0127 FDE3 0000 FE6C 0000 0000 0000 0006", + "0127 FDF7 0000 FE9F 0000 0000 0000 0007", + "01BB 0002 FFF6 FD44 C000 0000 0000 0FC8", + "012A 0452 0000 FCD0 0000 0000 0000 0800", + "01BB FC7C FFF6 F9E8 4000 0000 0000 0FC9", + "012A 015B 0074 FEC0 4000 8000 0000 0A03", + "005E 017B 0000 FCB6 0000 0000 0000 03CA", + "0127 FE8E 0032 FF60 0000 0000 0000 000B", + "005E FEC6 0000 FCBE 0000 0000 0000 03CC", + "012A FF34 0000 FDE0 0000 0000 0000 0C00", + "012E 000A FFF6 FA08 0000 8000 0001 1C8D", + "01BB FE0C 0000 FD1C 0000 C000 0000 0FCD", + "01BB 0000 0000 FB00 0000 8000 0000 0FCD", + "01BB 0000 0000 FED4 0000 0000 0000 0FCD", + "01BB 021C 0000 FD1C 0000 4000 0000 0FCD", + "0185 000A 0000 FA22 0000 0000 000B 8ACD", + "011B 0003 0000 FD4C 0032 0000 0004 2091", + "0015 FFAD FF24 FEA2 0000 0000 0000 2103", + "0015 FFAD FF24 FEEE 0000 0000 0000 2203", + "00BE 0427 0018 FCF0 0000 C000 0000 2502", + "00BE FFC0 000A 03D7 0000 4000 0000 2602", + "0111 0153 0000 FE87 0000 0000 0000 4E09", + "00BE 00CA 0018 0155 0000 8000 0000 2702", + "0111 01A0 0000 FE87 0000 0000 0000 500B", + "00BE FBC8 0018 FA3B 0000 0000 0000 2802", + "0111 010D 0000 FE88 0000 0000 0000 5203", + "00BE FF38 0018 FF3B 0000 0000 0000 2902", + "0111 01A5 0000 FF52 0000 0000 0000 5412", + "00BE FA1D 0010 FCB0 0000 0000 0000 2A02", + "00BE 0345 0000 012C 0000 8000 0000 2B02", + "00BE FFC3 FFB3 F99A 0000 0000 0000 2C02", + "00BE FB74 FF4E FD7C 0000 8000 0000 2D02", + "0173 FC38 003B 0057 0002 0000 0000 2E26", + "0173 FFBE 003E 01BB 0004 0000 0001 2F26", + "012A 04E2 0074 FA31 C000 4000 0000 3B03" + ] + }, + { + "File": { + "Name": "Scene 8, Room 1", + "Start": "032E9000", + "End": "032F42D0", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "008D", + "0187", + "000E", + "00A4", + "0098", + "0024", + "015C", + "0059", + "0163", + "000B", + "00AA", + "011F", + "0090", + "00B7" + ], + "Actors": [ + "003B FECA FD20 FF5F 0000 0000 0000 0008", + "0037 FC82 FDF8 FB73 0000 1333 0000 0002", + "0037 FD15 FDF8 FC38 0000 1A50 0000 0002", + "0037 FD3F FDE9 FD00 0000 13E9 0000 0002", + "0011 FFE6 FD92 FEBC 0000 0000 0000 0000", + "0090 0238 FD30 005A 0000 2C17 0000 7F02", + "0090 025B FD30 0022 0000 305B 0000 7F02", + "0090 0276 FD30 0080 0000 E889 0000 7F02", + "0090 028B FD30 00AD 0000 A5B0 0000 7F02", + "0090 02CC FD30 00A7 0000 9555 0000 7F02", + "0008 FDAC FD6E FEA2 0000 0000 0000 03F7", + "0008 FDAD FD6E FF06 0000 0000 0000 03F7", + "0008 0000 FD30 0009 0000 0000 0000 03F7", + "0008 012B FD30 FFC0 0000 0000 0000 03F7", + "0008 01AB FD30 00BC 0000 0000 0000 03F7", + "0008 02B5 FD30 FFEF 0000 0000 0000 03F7", + "0008 02F6 FD30 0059 0000 0000 0000 03F7", + "0183 027F FD30 FA4E 0000 0000 0000 FF40", + "0130 0352 FE6F FA65 0000 0000 0001 0D00", + "0130 0504 FE5C FB9E 0000 0000 0001 0D01", + "0095 FC76 FD30 FA29 0000 0000 0000 8901", + "000A 02D4 FD30 0021 0000 582E 000E B141", + "012A 0061 FDD0 FCF3 0000 F111 0000 0E00", + "011B 0004 FDD0 FD12 001E 0000 0004 2091", + "011B FECB FD25 FDDF 001E 0000 0004 2091", + "011B 0171 FD30 FB82 001E 0000 0004 2091", + "011B 0281 FD30 FA13 001E 0000 0004 2091", + "0015 043B FD30 FB6A 0000 0000 0000 3C03", + "0015 0414 FD30 FB39 0000 0000 0000 3D03", + "0015 045A FD30 FB39 0000 0000 0000 3E03" + ] + }, + { + "File": { + "Name": "Scene 8, Room 2", + "Start": "032F5000", + "End": "032F8190", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "008D", + "0187", + "000E", + "015C", + "0098", + "0024", + "00A4", + "0009" + ], + "Actors": [ + "0090 F927 0000 FD1E 0000 4000 0000 7FFE", + "000D F6DB 0032 FD91 0000 0000 0000 0000", + "005E F7DB 0000 FC40 0000 0000 0000 2400", + "0095 F612 0000 FC6A 0000 0000 0000 8904", + "005E F8A3 0000 FC40 0000 0000 0000 100F", + "00BD F84E 0028 FCE0 0000 8000 0000 010F", + "005E F7DB 0000 FDF8 0000 0000 0000 1010", + "00BD F7B8 0028 FD58 0000 0000 0000 0110", + "005E F713 0000 FC40 0000 0000 0000 1011", + "00BD F6BE 0028 FCE0 0000 8000 0000 0111", + "0015 F867 000A FCA1 0000 0000 0000 2003", + "0015 F7A1 000A FD93 0000 0000 0000 2303" + ] + }, + { + "File": { + "Name": "Scene 8, Room 3", + "Start": "032F9000", + "End": "032FAC60", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "008D", + "0187", + "000E", + "00A4", + "0098", + "0024", + "015C", + "0059", + "0163", + "000B", + "00AA", + "011F", + "0090", + "00B7" + ], + "Actors": [ + "0011 03EC 00B1 FBD6 0000 0000 0000 0000", + "008E 03E6 0000 FC11 0000 6AAB 0000 0000", + "01BB 02E4 FFF6 FB50 4000 4000 0000 0FFF", + "01BB 02E4 FFF6 FBC8 4000 4000 0000 0FFF", + "01BB 0370 FFF6 FC5E 4000 4000 0000 0FFF", + "01BB 03AC FFF6 FB3C 4000 4000 0000 0FFF", + "01BB 03D4 FFF6 FB50 4000 C000 0000 0FFF", + "01BB 03D4 FFF6 FBC8 4000 C000 0000 0FFF", + "01BB 0460 FFF6 FC5E 4000 C000 0000 0FFF", + "01BB 049C FFF6 FB3C 4000 C000 0000 0FFF", + "011B 0473 0000 FAA9 001E 0000 0004 2291", + "011B 0364 0000 FC80 001E 0000 0004 2291" + ] + }, + { + "File": { + "Name": "Scene 8, Room 4", + "Start": "032FB000", + "End": "032FD450", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "008D", + "0187", + "000E", + "00A6", + "012B" + ], + "Actors": [ + "0125 05B2 FFEC FF7E 0000 0000 0000 FF01", + "0125 05D4 FFEC FFCF 0000 0000 0000 FF01", + "0125 05F9 FFEC 0002 0000 0000 0000 FF01", + "0125 0644 FFEC 0003 0000 0000 0000 FF01", + "00A5 0464 FFEC 003A 0000 C000 0000 FFFF", + "00A5 0464 FFEC 0173 0000 C000 0000 FFFF", + "00A5 059D FFEC 0036 0000 C000 0000 FFFF", + "00A5 059D FFEC 0170 0000 C000 0000 FFFF", + "00A4 04FC FFF0 00D1 0000 C000 0000 FFFF", + "0015 0644 FFEC FFA8 0000 0000 0000 0211", + "000A 0524 FFEC 0079 0000 C000 0000 1802", + "00BE 062C 0000 FFA6 0000 C000 0000 2102" + ] + }, + { + "File": { + "Name": "Scene 8, Room 5", + "Start": "032FE000", + "End": "03300960", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "008D", + "0187", + "000E", + "00A4", + "0098", + "0024", + "015C", + "0059", + "0163", + "000B", + "00AA", + "011F", + "0090", + "00B7" + ], + "Actors": [ + "0112 00A0 0061 FB05 0000 0000 0004 18BF", + "0112 00A0 0061 FB05 0000 0000 0004 18BF", + "0112 00A0 0061 FB05 0000 0000 0004 19FF", + "0112 00A0 0061 FB05 0000 0000 0004 1AFF", + "00AE 017C 0000 FB32 0000 0000 0000 0002", + "0015 008C 0000 FB3E 0000 0000 0000 0111", + "0111 0120 0000 FB28 0000 0000 0000 4803", + "0111 01B6 0000 FB2E 0000 0000 0000 4A03", + "0111 01BC 0000 FBA6 0000 0000 0000 4C03" + ] + }, + { + "File": { + "Name": "Scene 8, Room 6", + "Start": "03301000", + "End": "03303E80", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "008D", + "0187", + "00A2", + "000D", + "0024", + "00AA", + "015C" + ], + "Actors": [ + "0013 FE98 0023 FBB1 0000 4000 0000 8003", + "0013 FEB3 001A FB92 0000 0000 0000 8003", + "0013 FED9 001F FBAC 0000 C000 0000 8003", + "0037 FE52 0000 FBB5 0000 0000 0000 0002", + "0037 FEB4 0000 FC1B 0000 0000 0000 0002", + "009D FEB7 0000 FBC3 0000 0000 0000 0000", + "0095 FEB6 0000 FBB9 0000 0000 0000 8902" + ] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [ + { + "Id": 6, + "Type": 1, + "Flags": 0 + }, + { + "Id": 10, + "Type": 1, + "Flags": 0 + }, + { + "Id": 16, + "Type": 2, + "Flags": 0 + }, + { + "Id": 17, + "Type": 2, + "Flags": 0 + }, + { + "Id": 18, + "Type": 2, + "Flags": 0 + }, + { + "Id": 19, + "Type": 2, + "Flags": 0 + }, + { + "Id": 20, + "Type": 2, + "Flags": 0 + }, + { + "Id": 21, + "Type": 2, + "Flags": 0 + }, + { + "Id": 22, + "Type": 3, + "Flags": 0 + }, + { + "Id": 23, + "Type": 3, + "Flags": 0 + }, + { + "Id": 24, + "Type": 3, + "Flags": 0 + }, + { + "Id": 25, + "Type": 3, + "Flags": 0 + }, + { + "Id": 26, + "Type": 3, + "Flags": 0 + }, + { + "Id": 27, + "Type": 3, + "Flags": 0 + }, + { + "Id": 28, + "Type": 3, + "Flags": 0 + }, + { + "Id": 29, + "Type": 4, + "Flags": 0 + }, + { + "Id": 30, + "Type": 4, + "Flags": 0 + }, + { + "Id": 31, + "Type": 4, + "Flags": 0 + }, + { + "Id": 32, + "Type": 4, + "Flags": 0 + }, + { + "Id": 33, + "Type": 4, + "Flags": 0 + }, + { + "Id": 34, + "Type": 4, + "Flags": 0 + }, + { + "Id": 35, + "Type": 5, + "Flags": 0 + }, + { + "Id": 36, + "Type": 5, + "Flags": 0 + }, + { + "Id": 37, + "Type": 6, + "Flags": 0 + }, + { + "Id": 38, + "Type": 6, + "Flags": 0 + }, + { + "Id": 39, + "Type": 7, + "Flags": 0 + }, + { + "Id": 40, + "Type": 7, + "Flags": 0 + }, + { + "Id": 41, + "Type": 8, + "Flags": 0 + }, + { + "Id": 42, + "Type": 8, + "Flags": 0 + }, + { + "Id": 43, + "Type": 7, + "Flags": 0 + }, + { + "Id": 44, + "Type": 7, + "Flags": 0 + }, + { + "Id": 45, + "Type": 9, + "Flags": 0 + }, + { + "Id": 46, + "Type": 9, + "Flags": 0 + }, + { + "Id": 47, + "Type": 10, + "Flags": 0 + }, + { + "Id": 48, + "Type": 10, + "Flags": 0 + }, + { + "Id": 49, + "Type": 11, + "Flags": 0 + }, + { + "Id": 50, + "Type": 11, + "Flags": 0 + }, + { + "Id": 51, + "Type": 8, + "Flags": 0 + }, + { + "Id": 52, + "Type": 8, + "Flags": 0 + }, + { + "Id": 53, + "Type": 7, + "Flags": 0 + }, + { + "Id": 54, + "Type": 7, + "Flags": 0 + }, + { + "Id": 55, + "Type": 12, + "Flags": 0 + }, + { + "Id": 56, + "Type": 12, + "Flags": 0 + }, + { + "Id": 57, + "Type": 7, + "Flags": 0 + }, + { + "Id": 58, + "Type": 7, + "Flags": 0 + }, + { + "Id": 59, + "Type": 5, + "Flags": 0 + }, + { + "Id": 60, + "Type": 5, + "Flags": 0 + }, + { + "Id": 61, + "Type": 13, + "Flags": 0 + }, + { + "Id": 62, + "Type": 13, + "Flags": 0 + }, + { + "Id": 63, + "Type": 14, + "Flags": 0 + }, + { + "Id": 64, + "Type": 14, + "Flags": 0 + }, + { + "Id": 65, + "Type": 5, + "Flags": 0 + }, + { + "Id": 66, + "Type": 5, + "Flags": 0 + }, + { + "Id": 67, + "Type": 15, + "Flags": 0 + }, + { + "Id": 68, + "Type": 15, + "Flags": 0 + }, + { + "Id": 69, + "Type": 16, + "Flags": 0 + }, + { + "Id": 70, + "Type": 16, + "Flags": 0 + }, + { + "Id": 71, + "Type": 5, + "Flags": 0 + }, + { + "Id": 72, + "Type": 5, + "Flags": 0 + }, + { + "Id": 73, + "Type": 5, + "Flags": 0 + }, + { + "Id": 74, + "Type": 5, + "Flags": 0 + }, + { + "Id": 75, + "Type": 17, + "Flags": 0 + }, + { + "Id": 76, + "Type": 17, + "Flags": 0 + }, + { + "Id": 77, + "Type": 6, + "Flags": 0 + }, + { + "Id": 78, + "Type": 6, + "Flags": 0 + }, + { + "Id": 79, + "Type": 5, + "Flags": 0 + }, + { + "Id": 80, + "Type": 5, + "Flags": 0 + }, + { + "Id": 81, + "Type": 5, + "Flags": 0 + }, + { + "Id": 82, + "Type": 5, + "Flags": 0 + }, + { + "Id": 83, + "Type": 7, + "Flags": 0 + }, + { + "Id": 84, + "Type": 7, + "Flags": 0 + }, + { + "Id": 85, + "Type": 7, + "Flags": 0 + }, + { + "Id": 86, + "Type": 7, + "Flags": 0 + }, + { + "Id": 87, + "Type": 7, + "Flags": 0 + }, + { + "Id": 88, + "Type": 7, + "Flags": 0 + }, + { + "Id": 89, + "Type": 7, + "Flags": 0 + }, + { + "Id": 90, + "Type": 7, + "Flags": 0 + }, + { + "Id": 91, + "Type": 7, + "Flags": 0 + }, + { + "Id": 92, + "Type": 7, + "Flags": 0 + }, + { + "Id": 93, + "Type": 7, + "Flags": 0 + }, + { + "Id": 94, + "Type": 7, + "Flags": 0 + }, + { + "Id": 95, + "Type": 7, + "Flags": 0 + }, + { + "Id": 96, + "Type": 7, + "Flags": 0 + }, + { + "Id": 97, + "Type": 18, + "Flags": 1 + }, + { + "Id": 98, + "Type": 18, + "Flags": 1 + }, + { + "Id": 99, + "Type": 19, + "Flags": 1 + }, + { + "Id": 100, + "Type": 19, + "Flags": 1 + }, + { + "Id": 101, + "Type": 7, + "Flags": 0 + }, + { + "Id": 102, + "Type": 7, + "Flags": 0 + }, + { + "Id": 103, + "Type": 7, + "Flags": 0 + }, + { + "Id": 104, + "Type": 7, + "Flags": 0 + }, + { + "Id": 105, + "Type": 7, + "Flags": 0 + }, + { + "Id": 106, + "Type": 7, + "Flags": 0 + }, + { + "Id": 107, + "Type": 7, + "Flags": 0 + }, + { + "Id": 108, + "Type": 7, + "Flags": 0 + }, + { + "Id": 109, + "Type": 7, + "Flags": 0 + }, + { + "Id": 110, + "Type": 7, + "Flags": 0 + }, + { + "Id": 111, + "Type": 7, + "Flags": 0 + }, + { + "Id": 112, + "Type": 7, + "Flags": 0 + }, + { + "Id": 113, + "Type": 7, + "Flags": 0 + }, + { + "Id": 114, + "Type": 7, + "Flags": 0 + }, + { + "Id": 115, + "Type": 7, + "Flags": 0 + }, + { + "Id": 116, + "Type": 7, + "Flags": 0 + }, + { + "Id": 117, + "Type": 7, + "Flags": 0 + }, + { + "Id": 118, + "Type": 7, + "Flags": 0 + }, + { + "Id": 119, + "Type": 7, + "Flags": 0 + }, + { + "Id": 120, + "Type": 7, + "Flags": 0 + }, + { + "Id": 121, + "Type": 7, + "Flags": 0 + }, + { + "Id": 122, + "Type": 7, + "Flags": 0 + }, + { + "Id": 123, + "Type": 7, + "Flags": 1 + }, + { + "Id": 124, + "Type": 7, + "Flags": 1 + }, + { + "Id": 125, + "Type": 7, + "Flags": 1 + }, + { + "Id": 126, + "Type": 7, + "Flags": 1 + }, + { + "Id": 127, + "Type": 7, + "Flags": 1 + }, + { + "Id": 128, + "Type": 7, + "Flags": 1 + }, + { + "Id": 129, + "Type": 7, + "Flags": 1 + }, + { + "Id": 130, + "Type": 7, + "Flags": 1 + }, + { + "Id": 131, + "Type": 7, + "Flags": 0 + }, + { + "Id": 132, + "Type": 7, + "Flags": 0 + }, + { + "Id": 133, + "Type": 7, + "Flags": 0 + }, + { + "Id": 134, + "Type": 7, + "Flags": 0 + }, + { + "Id": 135, + "Type": 7, + "Flags": 1 + }, + { + "Id": 136, + "Type": 7, + "Flags": 1 + }, + { + "Id": 137, + "Type": 7, + "Flags": 1 + }, + { + "Id": 138, + "Type": 7, + "Flags": 1 + }, + { + "Id": 139, + "Type": 7, + "Flags": 1 + }, + { + "Id": 140, + "Type": 7, + "Flags": 1 + }, + { + "Id": 141, + "Type": 7, + "Flags": 1 + }, + { + "Id": 142, + "Type": 7, + "Flags": 1 + }, + { + "Id": 143, + "Type": 7, + "Flags": 1 + }, + { + "Id": 144, + "Type": 7, + "Flags": 1 + }, + { + "Id": 145, + "Type": 7, + "Flags": 1 + }, + { + "Id": 146, + "Type": 7, + "Flags": 1 + }, + { + "Id": 147, + "Type": 7, + "Flags": 1 + }, + { + "Id": 148, + "Type": 7, + "Flags": 1 + }, + { + "Id": 149, + "Type": 7, + "Flags": 1 + }, + { + "Id": 150, + "Type": 7, + "Flags": 1 + }, + { + "Id": 151, + "Type": 7, + "Flags": 1 + }, + { + "Id": 152, + "Type": 7, + "Flags": 1 + }, + { + "Id": 153, + "Type": 7, + "Flags": 1 + }, + { + "Id": 154, + "Type": 7, + "Flags": 1 + }, + { + "Id": 155, + "Type": 7, + "Flags": 0 + }, + { + "Id": 156, + "Type": 7, + "Flags": 0 + }, + { + "Id": 157, + "Type": 7, + "Flags": 0 + }, + { + "Id": 158, + "Type": 7, + "Flags": 0 + }, + { + "Id": 159, + "Type": 7, + "Flags": 1 + }, + { + "Id": 160, + "Type": 7, + "Flags": 1 + }, + { + "Id": 161, + "Type": 7, + "Flags": 1 + }, + { + "Id": 162, + "Type": 7, + "Flags": 1 + }, + { + "Id": 163, + "Type": 7, + "Flags": 0 + }, + { + "Id": 164, + "Type": 7, + "Flags": 0 + }, + { + "Id": 165, + "Type": 7, + "Flags": 1 + }, + { + "Id": 166, + "Type": 7, + "Flags": 1 + }, + { + "Id": 167, + "Type": 20, + "Flags": 0 + }, + { + "Id": 168, + "Type": 20, + "Flags": 0 + }, + { + "Id": 169, + "Type": 20, + "Flags": 0 + }, + { + "Id": 170, + "Type": 20, + "Flags": 0 + }, + { + "Id": 171, + "Type": 20, + "Flags": 0 + }, + { + "Id": 172, + "Type": 20, + "Flags": 0 + }, + { + "Id": 173, + "Type": 20, + "Flags": 0 + }, + { + "Id": 174, + "Type": 20, + "Flags": 0 + }, + { + "Id": 175, + "Type": 20, + "Flags": 0 + }, + { + "Id": 176, + "Type": 20, + "Flags": 0 + }, + { + "Id": 177, + "Type": 20, + "Flags": 0 + }, + { + "Id": 178, + "Type": 20, + "Flags": 0 + }, + { + "Id": 179, + "Type": 20, + "Flags": 0 + }, + { + "Id": 180, + "Type": 20, + "Flags": 0 + }, + { + "Id": 181, + "Type": 20, + "Flags": 0 + }, + { + "Id": 182, + "Type": 20, + "Flags": 0 + }, + { + "Id": 183, + "Type": 20, + "Flags": 0 + }, + { + "Id": 184, + "Type": 20, + "Flags": 0 + }, + { + "Id": 185, + "Type": 20, + "Flags": 0 + }, + { + "Id": 186, + "Type": 20, + "Flags": 0 + }, + { + "Id": 187, + "Type": 20, + "Flags": 0 + }, + { + "Id": 188, + "Type": 20, + "Flags": 0 + }, + { + "Id": 189, + "Type": 20, + "Flags": 0 + }, + { + "Id": 190, + "Type": 20, + "Flags": 0 + }, + { + "Id": 191, + "Type": 20, + "Flags": 0 + }, + { + "Id": 192, + "Type": 20, + "Flags": 0 + }, + { + "Id": 193, + "Type": 20, + "Flags": 0 + }, + { + "Id": 194, + "Type": 20, + "Flags": 0 + }, + { + "Id": 195, + "Type": 20, + "Flags": 0 + }, + { + "Id": 196, + "Type": 20, + "Flags": 0 + }, + { + "Id": 197, + "Type": 20, + "Flags": 0 + }, + { + "Id": 198, + "Type": 20, + "Flags": 0 + }, + { + "Id": 199, + "Type": 7, + "Flags": 0 + }, + { + "Id": 200, + "Type": 7, + "Flags": 0 + }, + { + "Id": 201, + "Type": 7, + "Flags": 0 + }, + { + "Id": 202, + "Type": 7, + "Flags": 0 + }, + { + "Id": 203, + "Type": 7, + "Flags": 0 + }, + { + "Id": 204, + "Type": 7, + "Flags": 0 + }, + { + "Id": 205, + "Type": 7, + "Flags": 0 + }, + { + "Id": 206, + "Type": 21, + "Flags": 0 + }, + { + "Id": 207, + "Type": 8, + "Flags": 0 + }, + { + "Id": 208, + "Type": 8, + "Flags": 0 + }, + { + "Id": 209, + "Type": 7, + "Flags": 0 + }, + { + "Id": 210, + "Type": 7, + "Flags": 0 + }, + { + "Id": 211, + "Type": 7, + "Flags": 0 + }, + { + "Id": 212, + "Type": 7, + "Flags": 0 + }, + { + "Id": 213, + "Type": 7, + "Flags": 0 + }, + { + "Id": 214, + "Type": 7, + "Flags": 0 + }, + { + "Id": 215, + "Type": 7, + "Flags": 0 + }, + { + "Id": 216, + "Type": 7, + "Flags": 0 + }, + { + "Id": 217, + "Type": 7, + "Flags": 0 + }, + { + "Id": 218, + "Type": 7, + "Flags": 0 + }, + { + "Id": 219, + "Type": 7, + "Flags": 0 + }, + { + "Id": 220, + "Type": 7, + "Flags": 0 + }, + { + "Id": 221, + "Type": 22, + "Flags": 0 + }, + { + "Id": 222, + "Type": 22, + "Flags": 0 + }, + { + "Id": 223, + "Type": 22, + "Flags": 0 + }, + { + "Id": 224, + "Type": 22, + "Flags": 0 + }, + { + "Id": 225, + "Type": 7, + "Flags": 0 + }, + { + "Id": 226, + "Type": 7, + "Flags": 0 + }, + { + "Id": 227, + "Type": 7, + "Flags": 0 + }, + { + "Id": 228, + "Type": 7, + "Flags": 0 + }, + { + "Id": 229, + "Type": 7, + "Flags": 0 + }, + { + "Id": 230, + "Type": 7, + "Flags": 0 + }, + { + "Id": 231, + "Type": 7, + "Flags": 0 + }, + { + "Id": 232, + "Type": 7, + "Flags": 0 + }, + { + "Id": 233, + "Type": 22, + "Flags": 0 + }, + { + "Id": 234, + "Type": 22, + "Flags": 0 + }, + { + "Id": 235, + "Type": 7, + "Flags": 0 + }, + { + "Id": 236, + "Type": 7, + "Flags": 0 + }, + { + "Id": 237, + "Type": 7, + "Flags": 0 + }, + { + "Id": 238, + "Type": 7, + "Flags": 0 + }, + { + "Id": 239, + "Type": 7, + "Flags": 0 + }, + { + "Id": 240, + "Type": 7, + "Flags": 0 + }, + { + "Id": 241, + "Type": 7, + "Flags": 0 + }, + { + "Id": 242, + "Type": 7, + "Flags": 0 + }, + { + "Id": 243, + "Type": 7, + "Flags": 0 + }, + { + "Id": 244, + "Type": 7, + "Flags": 0 + }, + { + "Id": 245, + "Type": 7, + "Flags": 0 + }, + { + "Id": 246, + "Type": 7, + "Flags": 0 + }, + { + "Id": 247, + "Type": 7, + "Flags": 0 + }, + { + "Id": 248, + "Type": 7, + "Flags": 0 + }, + { + "Id": 249, + "Type": 22, + "Flags": 0 + }, + { + "Id": 250, + "Type": 22, + "Flags": 0 + }, + { + "Id": 251, + "Type": 7, + "Flags": 0 + }, + { + "Id": 252, + "Type": 7, + "Flags": 0 + }, + { + "Id": 253, + "Type": 7, + "Flags": 0 + }, + { + "Id": 254, + "Type": 7, + "Flags": 0 + }, + { + "Id": 255, + "Type": 7, + "Flags": 0 + }, + { + "Id": 256, + "Type": 7, + "Flags": 0 + }, + { + "Id": 257, + "Type": 7, + "Flags": 0 + }, + { + "Id": 258, + "Type": 7, + "Flags": 0 + }, + { + "Id": 259, + "Type": 7, + "Flags": 0 + }, + { + "Id": 260, + "Type": 7, + "Flags": 0 + }, + { + "Id": 261, + "Type": 7, + "Flags": 0 + }, + { + "Id": 262, + "Type": 7, + "Flags": 0 + }, + { + "Id": 263, + "Type": 23, + "Flags": 0 + }, + { + "Id": 264, + "Type": 23, + "Flags": 0 + }, + { + "Id": 265, + "Type": 24, + "Flags": 0 + }, + { + "Id": 266, + "Type": 24, + "Flags": 0 + }, + { + "Id": 267, + "Type": 23, + "Flags": 0 + }, + { + "Id": 268, + "Type": 23, + "Flags": 0 + }, + { + "Id": 269, + "Type": 24, + "Flags": 0 + }, + { + "Id": 270, + "Type": 24, + "Flags": 0 + }, + { + "Id": 271, + "Type": 23, + "Flags": 0 + }, + { + "Id": 272, + "Type": 23, + "Flags": 0 + }, + { + "Id": 273, + "Type": 7, + "Flags": 0 + }, + { + "Id": 274, + "Type": 7, + "Flags": 0 + }, + { + "Id": 275, + "Type": 7, + "Flags": 0 + }, + { + "Id": 276, + "Type": 7, + "Flags": 0 + }, + { + "Id": 277, + "Type": 7, + "Flags": 0 + }, + { + "Id": 278, + "Type": 7, + "Flags": 0 + }, + { + "Id": 279, + "Type": 7, + "Flags": 0 + }, + { + "Id": 280, + "Type": 7, + "Flags": 0 + }, + { + "Id": 281, + "Type": 7, + "Flags": 0 + }, + { + "Id": 282, + "Type": 7, + "Flags": 0 + }, + { + "Id": 283, + "Type": 23, + "Flags": 0 + }, + { + "Id": 284, + "Type": 23, + "Flags": 0 + }, + { + "Id": 285, + "Type": 25, + "Flags": 0 + }, + { + "Id": 286, + "Type": 25, + "Flags": 0 + }, + { + "Id": 287, + "Type": 7, + "Flags": 0 + }, + { + "Id": 288, + "Type": 7, + "Flags": 0 + }, + { + "Id": 289, + "Type": 7, + "Flags": 0 + }, + { + "Id": 290, + "Type": 7, + "Flags": 0 + }, + { + "Id": 291, + "Type": 25, + "Flags": 0 + }, + { + "Id": 292, + "Type": 25, + "Flags": 0 + }, + { + "Id": 293, + "Type": 23, + "Flags": 0 + }, + { + "Id": 294, + "Type": 23, + "Flags": 0 + }, + { + "Id": 295, + "Type": 23, + "Flags": 0 + }, + { + "Id": 296, + "Type": 23, + "Flags": 0 + }, + { + "Id": 297, + "Type": 24, + "Flags": 0 + }, + { + "Id": 298, + "Type": 24, + "Flags": 0 + }, + { + "Id": 299, + "Type": 7, + "Flags": 0 + }, + { + "Id": 300, + "Type": 7, + "Flags": 0 + }, + { + "Id": 301, + "Type": 23, + "Flags": 0 + }, + { + "Id": 302, + "Type": 23, + "Flags": 0 + }, + { + "Id": 303, + "Type": 7, + "Flags": 0 + }, + { + "Id": 304, + "Type": 7, + "Flags": 0 + }, + { + "Id": 305, + "Type": 7, + "Flags": 0 + }, + { + "Id": 306, + "Type": 7, + "Flags": 0 + }, + { + "Id": 307, + "Type": 7, + "Flags": 0 + }, + { + "Id": 308, + "Type": 7, + "Flags": 0 + }, + { + "Id": 309, + "Type": 7, + "Flags": 0 + }, + { + "Id": 310, + "Type": 7, + "Flags": 0 + }, + { + "Id": 311, + "Type": 7, + "Flags": 0 + }, + { + "Id": 312, + "Type": 7, + "Flags": 0 + }, + { + "Id": 313, + "Type": 7, + "Flags": 0 + }, + { + "Id": 314, + "Type": 7, + "Flags": 0 + }, + { + "Id": 315, + "Type": 7, + "Flags": 0 + }, + { + "Id": 316, + "Type": 7, + "Flags": 0 + }, + { + "Id": 317, + "Type": 7, + "Flags": 0 + }, + { + "Id": 318, + "Type": 7, + "Flags": 0 + }, + { + "Id": 319, + "Type": 7, + "Flags": 0 + }, + { + "Id": 320, + "Type": 7, + "Flags": 0 + }, + { + "Id": 321, + "Type": 23, + "Flags": 0 + }, + { + "Id": 322, + "Type": 23, + "Flags": 0 + }, + { + "Id": 323, + "Type": 25, + "Flags": 0 + }, + { + "Id": 324, + "Type": 25, + "Flags": 0 + }, + { + "Id": 325, + "Type": 23, + "Flags": 0 + }, + { + "Id": 326, + "Type": 23, + "Flags": 0 + }, + { + "Id": 327, + "Type": 25, + "Flags": 0 + }, + { + "Id": 328, + "Type": 25, + "Flags": 0 + }, + { + "Id": 329, + "Type": 23, + "Flags": 0 + }, + { + "Id": 330, + "Type": 23, + "Flags": 0 + }, + { + "Id": 331, + "Type": 23, + "Flags": 0 + }, + { + "Id": 332, + "Type": 23, + "Flags": 0 + }, + { + "Id": 333, + "Type": 26, + "Flags": 0 + }, + { + "Id": 334, + "Type": 26, + "Flags": 0 + }, + { + "Id": 335, + "Type": 7, + "Flags": 0 + }, + { + "Id": 336, + "Type": 7, + "Flags": 0 + }, + { + "Id": 337, + "Type": 7, + "Flags": 0 + }, + { + "Id": 338, + "Type": 7, + "Flags": 0 + }, + { + "Id": 339, + "Type": 26, + "Flags": 0 + }, + { + "Id": 340, + "Type": 26, + "Flags": 0 + }, + { + "Id": 341, + "Type": 23, + "Flags": 0 + }, + { + "Id": 342, + "Type": 23, + "Flags": 0 + }, + { + "Id": 343, + "Type": 7, + "Flags": 0 + }, + { + "Id": 344, + "Type": 7, + "Flags": 0 + }, + { + "Id": 345, + "Type": 7, + "Flags": 0 + }, + { + "Id": 346, + "Type": 7, + "Flags": 0 + }, + { + "Id": 347, + "Type": 7, + "Flags": 0 + }, + { + "Id": 348, + "Type": 7, + "Flags": 0 + }, + { + "Id": 349, + "Type": 7, + "Flags": 0 + }, + { + "Id": 350, + "Type": 7, + "Flags": 0 + }, + { + "Id": 351, + "Type": 8, + "Flags": 0 + }, + { + "Id": 352, + "Type": 8, + "Flags": 0 + }, + { + "Id": 353, + "Type": 7, + "Flags": 0 + }, + { + "Id": 354, + "Type": 7, + "Flags": 0 + }, + { + "Id": 355, + "Type": 7, + "Flags": 0 + }, + { + "Id": 356, + "Type": 7, + "Flags": 0 + }, + { + "Id": 357, + "Type": 7, + "Flags": 0 + }, + { + "Id": 358, + "Type": 7, + "Flags": 0 + }, + { + "Id": 359, + "Type": 7, + "Flags": 0 + }, + { + "Id": 360, + "Type": 7, + "Flags": 0 + }, + { + "Id": 361, + "Type": 8, + "Flags": 0 + }, + { + "Id": 362, + "Type": 8, + "Flags": 0 + }, + { + "Id": 363, + "Type": 7, + "Flags": 0 + }, + { + "Id": 364, + "Type": 7, + "Flags": 0 + }, + { + "Id": 365, + "Type": 7, + "Flags": 0 + }, + { + "Id": 366, + "Type": 7, + "Flags": 0 + }, + { + "Id": 367, + "Type": 7, + "Flags": 0 + }, + { + "Id": 368, + "Type": 7, + "Flags": 0 + }, + { + "Id": 369, + "Type": 8, + "Flags": 0 + }, + { + "Id": 370, + "Type": 8, + "Flags": 0 + }, + { + "Id": 371, + "Type": 27, + "Flags": 0 + }, + { + "Id": 372, + "Type": 27, + "Flags": 0 + }, + { + "Id": 373, + "Type": 7, + "Flags": 0 + }, + { + "Id": 374, + "Type": 7, + "Flags": 0 + }, + { + "Id": 375, + "Type": 7, + "Flags": 0 + }, + { + "Id": 376, + "Type": 7, + "Flags": 0 + }, + { + "Id": 377, + "Type": 24, + "Flags": 0 + }, + { + "Id": 378, + "Type": 24, + "Flags": 0 + }, + { + "Id": 379, + "Type": 7, + "Flags": 0 + }, + { + "Id": 380, + "Type": 7, + "Flags": 0 + }, + { + "Id": 381, + "Type": 7, + "Flags": 0 + }, + { + "Id": 382, + "Type": 7, + "Flags": 0 + }, + { + "Id": 383, + "Type": 7, + "Flags": 0 + }, + { + "Id": 384, + "Type": 7, + "Flags": 0 + }, + { + "Id": 385, + "Type": 7, + "Flags": 0 + }, + { + "Id": 386, + "Type": 7, + "Flags": 0 + }, + { + "Id": 387, + "Type": 7, + "Flags": 0 + }, + { + "Id": 388, + "Type": 7, + "Flags": 0 + }, + { + "Id": 389, + "Type": 7, + "Flags": 0 + }, + { + "Id": 390, + "Type": 7, + "Flags": 0 + }, + { + "Id": 391, + "Type": 7, + "Flags": 0 + }, + { + "Id": 392, + "Type": 7, + "Flags": 0 + }, + { + "Id": 393, + "Type": 28, + "Flags": 1 + }, + { + "Id": 394, + "Type": 28, + "Flags": 1 + }, + { + "Id": 395, + "Type": 28, + "Flags": 1 + }, + { + "Id": 396, + "Type": 28, + "Flags": 1 + }, + { + "Id": 397, + "Type": 28, + "Flags": 1 + }, + { + "Id": 398, + "Type": 28, + "Flags": 1 + }, + { + "Id": 399, + "Type": 28, + "Flags": 1 + }, + { + "Id": 400, + "Type": 28, + "Flags": 1 + }, + { + "Id": 401, + "Type": 29, + "Flags": 1 + }, + { + "Id": 402, + "Type": 29, + "Flags": 1 + }, + { + "Id": 403, + "Type": 28, + "Flags": 1 + }, + { + "Id": 404, + "Type": 28, + "Flags": 1 + }, + { + "Id": 405, + "Type": 7, + "Flags": 0 + }, + { + "Id": 406, + "Type": 7, + "Flags": 0 + }, + { + "Id": 407, + "Type": 7, + "Flags": 0 + }, + { + "Id": 408, + "Type": 7, + "Flags": 0 + }, + { + "Id": 409, + "Type": 7, + "Flags": 0 + }, + { + "Id": 410, + "Type": 7, + "Flags": 0 + }, + { + "Id": 411, + "Type": 7, + "Flags": 0 + }, + { + "Id": 412, + "Type": 7, + "Flags": 0 + }, + { + "Id": 413, + "Type": 7, + "Flags": 0 + }, + { + "Id": 414, + "Type": 7, + "Flags": 0 + }, + { + "Id": 415, + "Type": 7, + "Flags": 0 + }, + { + "Id": 416, + "Type": 7, + "Flags": 0 + }, + { + "Id": 417, + "Type": 7, + "Flags": 0 + }, + { + "Id": 418, + "Type": 7, + "Flags": 0 + }, + { + "Id": 419, + "Type": 7, + "Flags": 0 + }, + { + "Id": 420, + "Type": 7, + "Flags": 0 + }, + { + "Id": 421, + "Type": 7, + "Flags": 0 + }, + { + "Id": 422, + "Type": 7, + "Flags": 0 + }, + { + "Id": 423, + "Type": 7, + "Flags": 0 + }, + { + "Id": 424, + "Type": 7, + "Flags": 0 + }, + { + "Id": 425, + "Type": 7, + "Flags": 0 + }, + { + "Id": 426, + "Type": 7, + "Flags": 0 + }, + { + "Id": 427, + "Type": 7, + "Flags": 0 + }, + { + "Id": 428, + "Type": 7, + "Flags": 0 + }, + { + "Id": 429, + "Type": 7, + "Flags": 0 + }, + { + "Id": 430, + "Type": 7, + "Flags": 0 + }, + { + "Id": 431, + "Type": 7, + "Flags": 0 + }, + { + "Id": 432, + "Type": 7, + "Flags": 0 + }, + { + "Id": 433, + "Type": 7, + "Flags": 0 + }, + { + "Id": 434, + "Type": 7, + "Flags": 0 + }, + { + "Id": 435, + "Type": 7, + "Flags": 0 + }, + { + "Id": 436, + "Type": 7, + "Flags": 0 + }, + { + "Id": 437, + "Type": 7, + "Flags": 0 + }, + { + "Id": 438, + "Type": 7, + "Flags": 0 + }, + { + "Id": 439, + "Type": 7, + "Flags": 0 + }, + { + "Id": 440, + "Type": 7, + "Flags": 0 + }, + { + "Id": 441, + "Type": 7, + "Flags": 0 + }, + { + "Id": 442, + "Type": 7, + "Flags": 0 + }, + { + "Id": 443, + "Type": 7, + "Flags": 0 + }, + { + "Id": 444, + "Type": 7, + "Flags": 0 + }, + { + "Id": 445, + "Type": 7, + "Flags": 0 + }, + { + "Id": 446, + "Type": 7, + "Flags": 0 + }, + { + "Id": 447, + "Type": 7, + "Flags": 0 + }, + { + "Id": 448, + "Type": 7, + "Flags": 0 + }, + { + "Id": 449, + "Type": 7, + "Flags": 0 + }, + { + "Id": 450, + "Type": 7, + "Flags": 0 + }, + { + "Id": 451, + "Type": 7, + "Flags": 0 + }, + { + "Id": 452, + "Type": 7, + "Flags": 0 + }, + { + "Id": 453, + "Type": 7, + "Flags": 0 + }, + { + "Id": 454, + "Type": 7, + "Flags": 0 + }, + { + "Id": 455, + "Type": 7, + "Flags": 0 + }, + { + "Id": 456, + "Type": 7, + "Flags": 0 + }, + { + "Id": 457, + "Type": 7, + "Flags": 0 + }, + { + "Id": 458, + "Type": 7, + "Flags": 0 + }, + { + "Id": 459, + "Type": 7, + "Flags": 0 + }, + { + "Id": 460, + "Type": 7, + "Flags": 0 + }, + { + "Id": 461, + "Type": 7, + "Flags": 0 + }, + { + "Id": 462, + "Type": 7, + "Flags": 0 + }, + { + "Id": 463, + "Type": 7, + "Flags": 0 + }, + { + "Id": 464, + "Type": 7, + "Flags": 0 + }, + { + "Id": 465, + "Type": 7, + "Flags": 0 + }, + { + "Id": 466, + "Type": 7, + "Flags": 0 + }, + { + "Id": 467, + "Type": 7, + "Flags": 0 + }, + { + "Id": 468, + "Type": 7, + "Flags": 0 + }, + { + "Id": 469, + "Type": 7, + "Flags": 0 + }, + { + "Id": 470, + "Type": 7, + "Flags": 0 + }, + { + "Id": 471, + "Type": 7, + "Flags": 0 + }, + { + "Id": 472, + "Type": 7, + "Flags": 0 + }, + { + "Id": 473, + "Type": 7, + "Flags": 0 + }, + { + "Id": 474, + "Type": 7, + "Flags": 0 + }, + { + "Id": 475, + "Type": 7, + "Flags": 0 + }, + { + "Id": 476, + "Type": 7, + "Flags": 0 + }, + { + "Id": 477, + "Type": 7, + "Flags": 0 + }, + { + "Id": 478, + "Type": 7, + "Flags": 0 + }, + { + "Id": 479, + "Type": 7, + "Flags": 0 + }, + { + "Id": 480, + "Type": 7, + "Flags": 0 + }, + { + "Id": 481, + "Type": 7, + "Flags": 0 + }, + { + "Id": 482, + "Type": 7, + "Flags": 0 + }, + { + "Id": 483, + "Type": 7, + "Flags": 0 + }, + { + "Id": 484, + "Type": 7, + "Flags": 0 + }, + { + "Id": 485, + "Type": 7, + "Flags": 0 + }, + { + "Id": 486, + "Type": 7, + "Flags": 0 + }, + { + "Id": 487, + "Type": 7, + "Flags": 0 + }, + { + "Id": 488, + "Type": 7, + "Flags": 0 + }, + { + "Id": 489, + "Type": 7, + "Flags": 0 + }, + { + "Id": 490, + "Type": 7, + "Flags": 0 + }, + { + "Id": 491, + "Type": 7, + "Flags": 0 + }, + { + "Id": 492, + "Type": 7, + "Flags": 0 + }, + { + "Id": 493, + "Type": 7, + "Flags": 0 + }, + { + "Id": 494, + "Type": 7, + "Flags": 0 + }, + { + "Id": 495, + "Type": 7, + "Flags": 0 + }, + { + "Id": 496, + "Type": 7, + "Flags": 0 + }, + { + "Id": 497, + "Type": 7, + "Flags": 0 + }, + { + "Id": 498, + "Type": 7, + "Flags": 0 + }, + { + "Id": 499, + "Type": 7, + "Flags": 0 + }, + { + "Id": 500, + "Type": 7, + "Flags": 0 + }, + { + "Id": 501, + "Type": 7, + "Flags": 0 + }, + { + "Id": 502, + "Type": 7, + "Flags": 0 + }, + { + "Id": 503, + "Type": 7, + "Flags": 0 + }, + { + "Id": 504, + "Type": 7, + "Flags": 0 + }, + { + "Id": 505, + "Type": 7, + "Flags": 0 + }, + { + "Id": 506, + "Type": 7, + "Flags": 0 + }, + { + "Id": 507, + "Type": 7, + "Flags": 0 + }, + { + "Id": 508, + "Type": 7, + "Flags": 0 + }, + { + "Id": 509, + "Type": 7, + "Flags": 0 + }, + { + "Id": 510, + "Type": 7, + "Flags": 0 + }, + { + "Id": 511, + "Type": 7, + "Flags": 0 + }, + { + "Id": 512, + "Type": 7, + "Flags": 0 + }, + { + "Id": 513, + "Type": 7, + "Flags": 0 + }, + { + "Id": 514, + "Type": 7, + "Flags": 0 + }, + { + "Id": 515, + "Type": 7, + "Flags": 0 + }, + { + "Id": 516, + "Type": 7, + "Flags": 0 + }, + { + "Id": 517, + "Type": 7, + "Flags": 0 + }, + { + "Id": 518, + "Type": 7, + "Flags": 0 + }, + { + "Id": 519, + "Type": 7, + "Flags": 0 + }, + { + "Id": 520, + "Type": 7, + "Flags": 0 + }, + { + "Id": 521, + "Type": 7, + "Flags": 0 + }, + { + "Id": 522, + "Type": 7, + "Flags": 0 + }, + { + "Id": 523, + "Type": 7, + "Flags": 0 + }, + { + "Id": 524, + "Type": 7, + "Flags": 0 + }, + { + "Id": 525, + "Type": 7, + "Flags": 0 + }, + { + "Id": 526, + "Type": 7, + "Flags": 0 + }, + { + "Id": 527, + "Type": 7, + "Flags": 0 + }, + { + "Id": 528, + "Type": 7, + "Flags": 0 + }, + { + "Id": 529, + "Type": 7, + "Flags": 0 + }, + { + "Id": 530, + "Type": 7, + "Flags": 0 + }, + { + "Id": 531, + "Type": 7, + "Flags": 0 + }, + { + "Id": 532, + "Type": 7, + "Flags": 0 + }, + { + "Id": 533, + "Type": 7, + "Flags": 0 + }, + { + "Id": 534, + "Type": 7, + "Flags": 0 + }, + { + "Id": 535, + "Type": 7, + "Flags": 0 + }, + { + "Id": 536, + "Type": 7, + "Flags": 0 + }, + { + "Id": 537, + "Type": 7, + "Flags": 0 + }, + { + "Id": 538, + "Type": 7, + "Flags": 0 + }, + { + "Id": 539, + "Type": 7, + "Flags": 0 + }, + { + "Id": 540, + "Type": 7, + "Flags": 0 + }, + { + "Id": 541, + "Type": 8, + "Flags": 0 + }, + { + "Id": 542, + "Type": 8, + "Flags": 0 + }, + { + "Id": 543, + "Type": 7, + "Flags": 0 + }, + { + "Id": 544, + "Type": 7, + "Flags": 0 + }, + { + "Id": 545, + "Type": 7, + "Flags": 0 + }, + { + "Id": 546, + "Type": 7, + "Flags": 0 + }, + { + "Id": 547, + "Type": 7, + "Flags": 0 + }, + { + "Id": 548, + "Type": 7, + "Flags": 0 + }, + { + "Id": 549, + "Type": 7, + "Flags": 0 + }, + { + "Id": 550, + "Type": 7, + "Flags": 0 + }, + { + "Id": 551, + "Type": 7, + "Flags": 0 + }, + { + "Id": 552, + "Type": 7, + "Flags": 0 + }, + { + "Id": 553, + "Type": 7, + "Flags": 0 + }, + { + "Id": 554, + "Type": 7, + "Flags": 0 + }, + { + "Id": 555, + "Type": 8, + "Flags": 0 + }, + { + "Id": 556, + "Type": 8, + "Flags": 0 + }, + { + "Id": 557, + "Type": 8, + "Flags": 0 + }, + { + "Id": 558, + "Type": 8, + "Flags": 0 + }, + { + "Id": 559, + "Type": 7, + "Flags": 0 + }, + { + "Id": 560, + "Type": 7, + "Flags": 0 + }, + { + "Id": 561, + "Type": 7, + "Flags": 0 + }, + { + "Id": 562, + "Type": 30, + "Flags": 0 + }, + { + "Id": 563, + "Type": 7, + "Flags": 0 + }, + { + "Id": 564, + "Type": 7, + "Flags": 0 + }, + { + "Id": 565, + "Type": 7, + "Flags": 0 + }, + { + "Id": 566, + "Type": 7, + "Flags": 0 + }, + { + "Id": 567, + "Type": 31, + "Flags": 0 + }, + { + "Id": 568, + "Type": 31, + "Flags": 0 + }, + { + "Id": 569, + "Type": 7, + "Flags": 0 + }, + { + "Id": 570, + "Type": 7, + "Flags": 0 + }, + { + "Id": 571, + "Type": 8, + "Flags": 0 + }, + { + "Id": 572, + "Type": 8, + "Flags": 0 + }, + { + "Id": 573, + "Type": 30, + "Flags": 0 + }, + { + "Id": 574, + "Type": 30, + "Flags": 0 + }, + { + "Id": 575, + "Type": 27, + "Flags": 0 + }, + { + "Id": 576, + "Type": 7, + "Flags": 0 + }, + { + "Id": 577, + "Type": 7, + "Flags": 0 + }, + { + "Id": 578, + "Type": 8, + "Flags": 0 + }, + { + "Id": 579, + "Type": 8, + "Flags": 0 + }, + { + "Id": 580, + "Type": 8, + "Flags": 0 + }, + { + "Id": 581, + "Type": 22, + "Flags": 0 + }, + { + "Id": 582, + "Type": 22, + "Flags": 0 + }, + { + "Id": 583, + "Type": 22, + "Flags": 0 + }, + { + "Id": 584, + "Type": 22, + "Flags": 0 + }, + { + "Id": 585, + "Type": 32, + "Flags": 0 + }, + { + "Id": 586, + "Type": 33, + "Flags": 0 + }, + { + "Id": 587, + "Type": 7, + "Flags": 0 + }, + { + "Id": 588, + "Type": 7, + "Flags": 0 + }, + { + "Id": 589, + "Type": 7, + "Flags": 0 + }, + { + "Id": 590, + "Type": 7, + "Flags": 0 + }, + { + "Id": 591, + "Type": 7, + "Flags": 0 + }, + { + "Id": 592, + "Type": 27, + "Flags": 0 + }, + { + "Id": 593, + "Type": 27, + "Flags": 0 + }, + { + "Id": 594, + "Type": 8, + "Flags": 0 + }, + { + "Id": 595, + "Type": 7, + "Flags": 0 + }, + { + "Id": 596, + "Type": 22, + "Flags": 0 + }, + { + "Id": 597, + "Type": 22, + "Flags": 0 + }, + { + "Id": 598, + "Type": 22, + "Flags": 0 + }, + { + "Id": 599, + "Type": 7, + "Flags": 0 + }, + { + "Id": 600, + "Type": 34, + "Flags": 0 + }, + { + "Id": 601, + "Type": 27, + "Flags": 0 + }, + { + "Id": 602, + "Type": 7, + "Flags": 0 + }, + { + "Id": 603, + "Type": 7, + "Flags": 0 + }, + { + "Id": 604, + "Type": 27, + "Flags": 0 + }, + { + "Id": 605, + "Type": 27, + "Flags": 0 + }, + { + "Id": 606, + "Type": 27, + "Flags": 0 + }, + { + "Id": 607, + "Type": 27, + "Flags": 0 + }, + { + "Id": 608, + "Type": 27, + "Flags": 0 + }, + { + "Id": 609, + "Type": 27, + "Flags": 0 + }, + { + "Id": 610, + "Type": 8, + "Flags": 0 + }, + { + "Id": 611, + "Type": 8, + "Flags": 0 + }, + { + "Id": 612, + "Type": 7, + "Flags": 0 + }, + { + "Id": 613, + "Type": 7, + "Flags": 0 + }, + { + "Id": 614, + "Type": 7, + "Flags": 0 + }, + { + "Id": 615, + "Type": 7, + "Flags": 0 + }, + { + "Id": 616, + "Type": 7, + "Flags": 0 + }, + { + "Id": 617, + "Type": 7, + "Flags": 0 + }, + { + "Id": 618, + "Type": 27, + "Flags": 0 + }, + { + "Id": 619, + "Type": 27, + "Flags": 0 + }, + { + "Id": 620, + "Type": 35, + "Flags": 0 + }, + { + "Id": 621, + "Type": 35, + "Flags": 0 + }, + { + "Id": 622, + "Type": 22, + "Flags": 0 + }, + { + "Id": 623, + "Type": 22, + "Flags": 0 + }, + { + "Id": 624, + "Type": 27, + "Flags": 0 + }, + { + "Id": 625, + "Type": 22, + "Flags": 0 + }, + { + "Id": 626, + "Type": 34, + "Flags": 0 + }, + { + "Id": 627, + "Type": 34, + "Flags": 0 + }, + { + "Id": 628, + "Type": 22, + "Flags": 0 + }, + { + "Id": 629, + "Type": 7, + "Flags": 0 + }, + { + "Id": 630, + "Type": 7, + "Flags": 0 + }, + { + "Id": 631, + "Type": 22, + "Flags": 0 + }, + { + "Id": 632, + "Type": 22, + "Flags": 0 + }, + { + "Id": 633, + "Type": 7, + "Flags": 0 + }, + { + "Id": 634, + "Type": 8, + "Flags": 0 + }, + { + "Id": 635, + "Type": 8, + "Flags": 0 + }, + { + "Id": 636, + "Type": 7, + "Flags": 0 + }, + { + "Id": 637, + "Type": 7, + "Flags": 0 + }, + { + "Id": 638, + "Type": 7, + "Flags": 0 + }, + { + "Id": 639, + "Type": 7, + "Flags": 0 + }, + { + "Id": 640, + "Type": 7, + "Flags": 0 + }, + { + "Id": 641, + "Type": 7, + "Flags": 0 + }, + { + "Id": 642, + "Type": 7, + "Flags": 0 + }, + { + "Id": 643, + "Type": 7, + "Flags": 0 + }, + { + "Id": 644, + "Type": 7, + "Flags": 0 + }, + { + "Id": 645, + "Type": 7, + "Flags": 0 + }, + { + "Id": 646, + "Type": 22, + "Flags": 0 + }, + { + "Id": 647, + "Type": 22, + "Flags": 0 + }, + { + "Id": 648, + "Type": 8, + "Flags": 0 + }, + { + "Id": 649, + "Type": 35, + "Flags": 0 + }, + { + "Id": 650, + "Type": 27, + "Flags": 0 + }, + { + "Id": 651, + "Type": 22, + "Flags": 0 + }, + { + "Id": 652, + "Type": 22, + "Flags": 0 + }, + { + "Id": 653, + "Type": 22, + "Flags": 0 + }, + { + "Id": 654, + "Type": 22, + "Flags": 0 + }, + { + "Id": 655, + "Type": 8, + "Flags": 0 + }, + { + "Id": 656, + "Type": 8, + "Flags": 0 + }, + { + "Id": 657, + "Type": 22, + "Flags": 0 + }, + { + "Id": 658, + "Type": 22, + "Flags": 0 + }, + { + "Id": 659, + "Type": 7, + "Flags": 0 + }, + { + "Id": 660, + "Type": 7, + "Flags": 0 + }, + { + "Id": 661, + "Type": 7, + "Flags": 0 + }, + { + "Id": 662, + "Type": 7, + "Flags": 0 + }, + { + "Id": 663, + "Type": 8, + "Flags": 0 + }, + { + "Id": 664, + "Type": 8, + "Flags": 0 + }, + { + "Id": 665, + "Type": 8, + "Flags": 0 + }, + { + "Id": 666, + "Type": 8, + "Flags": 0 + }, + { + "Id": 667, + "Type": 7, + "Flags": 0 + }, + { + "Id": 668, + "Type": 7, + "Flags": 0 + }, + { + "Id": 669, + "Type": 7, + "Flags": 0 + }, + { + "Id": 670, + "Type": 7, + "Flags": 0 + }, + { + "Id": 671, + "Type": 7, + "Flags": 0 + }, + { + "Id": 672, + "Type": 7, + "Flags": 0 + }, + { + "Id": 673, + "Type": 8, + "Flags": 0 + }, + { + "Id": 674, + "Type": 8, + "Flags": 0 + }, + { + "Id": 675, + "Type": 22, + "Flags": 0 + }, + { + "Id": 676, + "Type": 22, + "Flags": 0 + }, + { + "Id": 677, + "Type": 8, + "Flags": 0 + }, + { + "Id": 678, + "Type": 8, + "Flags": 0 + }, + { + "Id": 679, + "Type": 27, + "Flags": 0 + }, + { + "Id": 680, + "Type": 27, + "Flags": 0 + }, + { + "Id": 681, + "Type": 8, + "Flags": 0 + }, + { + "Id": 682, + "Type": 8, + "Flags": 0 + }, + { + "Id": 683, + "Type": 7, + "Flags": 0 + }, + { + "Id": 684, + "Type": 7, + "Flags": 0 + }, + { + "Id": 685, + "Type": 7, + "Flags": 0 + }, + { + "Id": 686, + "Type": 7, + "Flags": 0 + }, + { + "Id": 687, + "Type": 7, + "Flags": 0 + }, + { + "Id": 688, + "Type": 7, + "Flags": 0 + }, + { + "Id": 689, + "Type": 8, + "Flags": 0 + }, + { + "Id": 690, + "Type": 8, + "Flags": 0 + }, + { + "Id": 691, + "Type": 8, + "Flags": 0 + }, + { + "Id": 692, + "Type": 8, + "Flags": 0 + }, + { + "Id": 693, + "Type": 7, + "Flags": 0 + }, + { + "Id": 694, + "Type": 22, + "Flags": 0 + }, + { + "Id": 695, + "Type": 8, + "Flags": 0 + }, + { + "Id": 696, + "Type": 7, + "Flags": 0 + }, + { + "Id": 697, + "Type": 7, + "Flags": 0 + }, + { + "Id": 698, + "Type": 8, + "Flags": 0 + }, + { + "Id": 699, + "Type": 8, + "Flags": 0 + }, + { + "Id": 700, + "Type": 7, + "Flags": 0 + }, + { + "Id": 701, + "Type": 7, + "Flags": 0 + }, + { + "Id": 702, + "Type": 7, + "Flags": 0 + }, + { + "Id": 703, + "Type": 22, + "Flags": 0 + }, + { + "Id": 704, + "Type": 22, + "Flags": 0 + }, + { + "Id": 705, + "Type": 27, + "Flags": 0 + }, + { + "Id": 706, + "Type": 27, + "Flags": 0 + }, + { + "Id": 707, + "Type": 27, + "Flags": 0 + }, + { + "Id": 708, + "Type": 7, + "Flags": 0 + }, + { + "Id": 709, + "Type": 7, + "Flags": 0 + }, + { + "Id": 710, + "Type": 7, + "Flags": 0 + }, + { + "Id": 711, + "Type": 7, + "Flags": 0 + }, + { + "Id": 712, + "Type": 7, + "Flags": 0 + }, + { + "Id": 713, + "Type": 7, + "Flags": 0 + }, + { + "Id": 714, + "Type": 8, + "Flags": 0 + }, + { + "Id": 715, + "Type": 8, + "Flags": 0 + }, + { + "Id": 716, + "Type": 22, + "Flags": 0 + }, + { + "Id": 717, + "Type": 22, + "Flags": 0 + }, + { + "Id": 718, + "Type": 7, + "Flags": 0 + }, + { + "Id": 719, + "Type": 7, + "Flags": 0 + }, + { + "Id": 720, + "Type": 22, + "Flags": 0 + }, + { + "Id": 721, + "Type": 22, + "Flags": 0 + }, + { + "Id": 722, + "Type": 7, + "Flags": 0 + }, + { + "Id": 723, + "Type": 7, + "Flags": 0 + }, + { + "Id": 724, + "Type": 22, + "Flags": 0 + }, + { + "Id": 725, + "Type": 22, + "Flags": 0 + }, + { + "Id": 726, + "Type": 7, + "Flags": 0 + }, + { + "Id": 727, + "Type": 7, + "Flags": 0 + }, + { + "Id": 728, + "Type": 8, + "Flags": 0 + }, + { + "Id": 729, + "Type": 8, + "Flags": 0 + }, + { + "Id": 730, + "Type": 8, + "Flags": 0 + }, + { + "Id": 731, + "Type": 7, + "Flags": 0 + }, + { + "Id": 732, + "Type": 7, + "Flags": 0 + }, + { + "Id": 733, + "Type": 7, + "Flags": 0 + }, + { + "Id": 734, + "Type": 7, + "Flags": 0 + }, + { + "Id": 735, + "Type": 8, + "Flags": 0 + }, + { + "Id": 736, + "Type": 8, + "Flags": 0 + }, + { + "Id": 737, + "Type": 22, + "Flags": 0 + }, + { + "Id": 738, + "Type": 22, + "Flags": 0 + }, + { + "Id": 739, + "Type": 27, + "Flags": 0 + }, + { + "Id": 740, + "Type": 8, + "Flags": 0 + }, + { + "Id": 741, + "Type": 8, + "Flags": 0 + }, + { + "Id": 742, + "Type": 8, + "Flags": 0 + }, + { + "Id": 743, + "Type": 8, + "Flags": 0 + }, + { + "Id": 744, + "Type": 8, + "Flags": 0 + }, + { + "Id": 745, + "Type": 8, + "Flags": 0 + }, + { + "Id": 746, + "Type": 7, + "Flags": 0 + }, + { + "Id": 747, + "Type": 7, + "Flags": 0 + }, + { + "Id": 748, + "Type": 7, + "Flags": 0 + }, + { + "Id": 749, + "Type": 7, + "Flags": 0 + }, + { + "Id": 750, + "Type": 22, + "Flags": 0 + }, + { + "Id": 751, + "Type": 22, + "Flags": 0 + }, + { + "Id": 752, + "Type": 22, + "Flags": 0 + }, + { + "Id": 753, + "Type": 22, + "Flags": 0 + }, + { + "Id": 754, + "Type": 27, + "Flags": 0 + }, + { + "Id": 755, + "Type": 27, + "Flags": 0 + }, + { + "Id": 756, + "Type": 27, + "Flags": 0 + }, + { + "Id": 757, + "Type": 7, + "Flags": 0 + }, + { + "Id": 758, + "Type": 7, + "Flags": 0 + }, + { + "Id": 759, + "Type": 7, + "Flags": 0 + }, + { + "Id": 760, + "Type": 8, + "Flags": 0 + }, + { + "Id": 761, + "Type": 22, + "Flags": 0 + }, + { + "Id": 762, + "Type": 22, + "Flags": 0 + }, + { + "Id": 763, + "Type": 22, + "Flags": 0 + }, + { + "Id": 764, + "Type": 22, + "Flags": 0 + }, + { + "Id": 765, + "Type": 27, + "Flags": 0 + }, + { + "Id": 766, + "Type": 27, + "Flags": 0 + }, + { + "Id": 767, + "Type": 27, + "Flags": 0 + }, + { + "Id": 768, + "Type": 27, + "Flags": 0 + }, + { + "Id": 769, + "Type": 27, + "Flags": 0 + }, + { + "Id": 770, + "Type": 27, + "Flags": 0 + }, + { + "Id": 771, + "Type": 27, + "Flags": 0 + }, + { + "Id": 772, + "Type": 7, + "Flags": 0 + }, + { + "Id": 773, + "Type": 7, + "Flags": 0 + }, + { + "Id": 774, + "Type": 34, + "Flags": 0 + }, + { + "Id": 775, + "Type": 34, + "Flags": 0 + }, + { + "Id": 776, + "Type": 36, + "Flags": 0 + }, + { + "Id": 777, + "Type": 36, + "Flags": 0 + }, + { + "Id": 778, + "Type": 8, + "Flags": 0 + }, + { + "Id": 779, + "Type": 27, + "Flags": 0 + }, + { + "Id": 780, + "Type": 1, + "Flags": 0 + }, + { + "Id": 781, + "Type": 1, + "Flags": 0 + }, + { + "Id": 782, + "Type": 7, + "Flags": 0 + }, + { + "Id": 783, + "Type": 7, + "Flags": 0 + }, + { + "Id": 784, + "Type": 7, + "Flags": 0 + }, + { + "Id": 785, + "Type": 7, + "Flags": 0 + }, + { + "Id": 786, + "Type": 8, + "Flags": 0 + }, + { + "Id": 787, + "Type": 8, + "Flags": 0 + }, + { + "Id": 788, + "Type": 22, + "Flags": 0 + }, + { + "Id": 789, + "Type": 22, + "Flags": 0 + }, + { + "Id": 790, + "Type": 8, + "Flags": 0 + }, + { + "Id": 791, + "Type": 8, + "Flags": 0 + }, + { + "Id": 792, + "Type": 7, + "Flags": 0 + }, + { + "Id": 793, + "Type": 7, + "Flags": 0 + }, + { + "Id": 794, + "Type": 8, + "Flags": 0 + }, + { + "Id": 795, + "Type": 8, + "Flags": 0 + }, + { + "Id": 796, + "Type": 8, + "Flags": 0 + }, + { + "Id": 797, + "Type": 8, + "Flags": 0 + }, + { + "Id": 798, + "Type": 7, + "Flags": 0 + }, + { + "Id": 799, + "Type": 7, + "Flags": 0 + }, + { + "Id": 800, + "Type": 36, + "Flags": 0 + }, + { + "Id": 801, + "Type": 36, + "Flags": 0 + }, + { + "Id": 802, + "Type": 8, + "Flags": 0 + }, + { + "Id": 803, + "Type": 8, + "Flags": 0 + }, + { + "Id": 804, + "Type": 34, + "Flags": 0 + }, + { + "Id": 805, + "Type": 34, + "Flags": 0 + }, + { + "Id": 806, + "Type": 22, + "Flags": 0 + }, + { + "Id": 807, + "Type": 22, + "Flags": 0 + }, + { + "Id": 808, + "Type": 22, + "Flags": 0 + }, + { + "Id": 809, + "Type": 22, + "Flags": 0 + }, + { + "Id": 810, + "Type": 22, + "Flags": 0 + }, + { + "Id": 811, + "Type": 34, + "Flags": 0 + }, + { + "Id": 812, + "Type": 34, + "Flags": 0 + }, + { + "Id": 813, + "Type": 34, + "Flags": 0 + }, + { + "Id": 814, + "Type": 27, + "Flags": 0 + }, + { + "Id": 815, + "Type": 27, + "Flags": 0 + }, + { + "Id": 816, + "Type": 8, + "Flags": 0 + }, + { + "Id": 817, + "Type": 8, + "Flags": 0 + }, + { + "Id": 818, + "Type": 7, + "Flags": 0 + }, + { + "Id": 819, + "Type": 8, + "Flags": 0 + }, + { + "Id": 820, + "Type": 36, + "Flags": 0 + }, + { + "Id": 821, + "Type": 36, + "Flags": 0 + }, + { + "Id": 822, + "Type": 36, + "Flags": 0 + }, + { + "Id": 823, + "Type": 36, + "Flags": 0 + }, + { + "Id": 824, + "Type": 8, + "Flags": 0 + }, + { + "Id": 825, + "Type": 7, + "Flags": 0 + }, + { + "Id": 826, + "Type": 27, + "Flags": 0 + }, + { + "Id": 827, + "Type": 27, + "Flags": 0 + }, + { + "Id": 828, + "Type": 27, + "Flags": 0 + }, + { + "Id": 829, + "Type": 8, + "Flags": 0 + }, + { + "Id": 830, + "Type": 8, + "Flags": 0 + }, + { + "Id": 831, + "Type": 8, + "Flags": 0 + }, + { + "Id": 832, + "Type": 8, + "Flags": 0 + }, + { + "Id": 833, + "Type": 8, + "Flags": 0 + }, + { + "Id": 834, + "Type": 27, + "Flags": 0 + }, + { + "Id": 835, + "Type": 27, + "Flags": 0 + }, + { + "Id": 836, + "Type": 27, + "Flags": 0 + }, + { + "Id": 837, + "Type": 2, + "Flags": 0 + }, + { + "Id": 838, + "Type": 2, + "Flags": 0 + }, + { + "Id": 839, + "Type": 34, + "Flags": 0 + }, + { + "Id": 840, + "Type": 34, + "Flags": 0 + }, + { + "Id": 841, + "Type": 8, + "Flags": 0 + }, + { + "Id": 842, + "Type": 7, + "Flags": 0 + }, + { + "Id": 843, + "Type": 7, + "Flags": 0 + }, + { + "Id": 844, + "Type": 7, + "Flags": 0 + }, + { + "Id": 845, + "Type": 36, + "Flags": 0 + }, + { + "Id": 846, + "Type": 36, + "Flags": 0 + }, + { + "Id": 847, + "Type": 8, + "Flags": 0 + }, + { + "Id": 848, + "Type": 8, + "Flags": 0 + }, + { + "Id": 849, + "Type": 8, + "Flags": 0 + }, + { + "Id": 850, + "Type": 8, + "Flags": 0 + }, + { + "Id": 851, + "Type": 7, + "Flags": 0 + }, + { + "Id": 852, + "Type": 7, + "Flags": 0 + }, + { + "Id": 853, + "Type": 22, + "Flags": 0 + }, + { + "Id": 854, + "Type": 22, + "Flags": 0 + }, + { + "Id": 855, + "Type": 22, + "Flags": 0 + }, + { + "Id": 856, + "Type": 22, + "Flags": 0 + }, + { + "Id": 857, + "Type": 22, + "Flags": 0 + }, + { + "Id": 858, + "Type": 22, + "Flags": 0 + }, + { + "Id": 859, + "Type": 22, + "Flags": 0 + }, + { + "Id": 860, + "Type": 22, + "Flags": 0 + }, + { + "Id": 861, + "Type": 22, + "Flags": 0 + }, + { + "Id": 862, + "Type": 22, + "Flags": 0 + }, + { + "Id": 863, + "Type": 22, + "Flags": 0 + }, + { + "Id": 864, + "Type": 22, + "Flags": 0 + }, + { + "Id": 865, + "Type": 22, + "Flags": 0 + }, + { + "Id": 866, + "Type": 22, + "Flags": 0 + }, + { + "Id": 867, + "Type": 22, + "Flags": 0 + }, + { + "Id": 868, + "Type": 7, + "Flags": 0 + }, + { + "Id": 869, + "Type": 7, + "Flags": 0 + }, + { + "Id": 870, + "Type": 7, + "Flags": 0 + }, + { + "Id": 871, + "Type": 7, + "Flags": 0 + }, + { + "Id": 872, + "Type": 7, + "Flags": 0 + }, + { + "Id": 873, + "Type": 7, + "Flags": 0 + }, + { + "Id": 874, + "Type": 7, + "Flags": 0 + }, + { + "Id": 875, + "Type": 7, + "Flags": 0 + }, + { + "Id": 876, + "Type": 7, + "Flags": 0 + }, + { + "Id": 877, + "Type": 7, + "Flags": 0 + }, + { + "Id": 878, + "Type": 7, + "Flags": 0 + }, + { + "Id": 879, + "Type": 7, + "Flags": 0 + }, + { + "Id": 880, + "Type": 7, + "Flags": 0 + }, + { + "Id": 881, + "Type": 7, + "Flags": 0 + }, + { + "Id": 882, + "Type": 7, + "Flags": 0 + }, + { + "Id": 883, + "Type": 7, + "Flags": 0 + }, + { + "Id": 884, + "Type": 7, + "Flags": 0 + }, + { + "Id": 885, + "Type": 7, + "Flags": 0 + }, + { + "Id": 886, + "Type": 7, + "Flags": 0 + }, + { + "Id": 887, + "Type": 7, + "Flags": 0 + }, + { + "Id": 888, + "Type": 8, + "Flags": 0 + }, + { + "Id": 889, + "Type": 8, + "Flags": 0 + }, + { + "Id": 890, + "Type": 8, + "Flags": 0 + }, + { + "Id": 891, + "Type": 8, + "Flags": 0 + }, + { + "Id": 892, + "Type": 8, + "Flags": 0 + }, + { + "Id": 893, + "Type": 8, + "Flags": 0 + }, + { + "Id": 894, + "Type": 7, + "Flags": 0 + }, + { + "Id": 895, + "Type": 7, + "Flags": 0 + }, + { + "Id": 896, + "Type": 7, + "Flags": 0 + }, + { + "Id": 897, + "Type": 7, + "Flags": 0 + }, + { + "Id": 898, + "Type": 7, + "Flags": 0 + }, + { + "Id": 899, + "Type": 7, + "Flags": 0 + }, + { + "Id": 900, + "Type": 8, + "Flags": 0 + }, + { + "Id": 901, + "Type": 8, + "Flags": 0 + }, + { + "Id": 902, + "Type": 7, + "Flags": 0 + }, + { + "Id": 903, + "Type": 7, + "Flags": 0 + }, + { + "Id": 904, + "Type": 7, + "Flags": 0 + }, + { + "Id": 905, + "Type": 7, + "Flags": 0 + }, + { + "Id": 906, + "Type": 7, + "Flags": 0 + }, + { + "Id": 907, + "Type": 7, + "Flags": 0 + }, + { + "Id": 908, + "Type": 7, + "Flags": 0 + }, + { + "Id": 909, + "Type": 7, + "Flags": 0 + }, + { + "Id": 910, + "Type": 7, + "Flags": 0 + }, + { + "Id": 911, + "Type": 7, + "Flags": 0 + }, + { + "Id": 912, + "Type": 25, + "Flags": 0 + }, + { + "Id": 913, + "Type": 25, + "Flags": 0 + }, + { + "Id": 916, + "Type": 25, + "Flags": 0 + }, + { + "Id": 917, + "Type": 25, + "Flags": 0 + }, + { + "Id": 918, + "Type": 22, + "Flags": 0 + }, + { + "Id": 919, + "Type": 22, + "Flags": 0 + }, + { + "Id": 920, + "Type": 7, + "Flags": 0 + }, + { + "Id": 921, + "Type": 7, + "Flags": 0 + }, + { + "Id": 922, + "Type": 7, + "Flags": 0 + }, + { + "Id": 923, + "Type": 7, + "Flags": 0 + }, + { + "Id": 924, + "Type": 8, + "Flags": 0 + }, + { + "Id": 925, + "Type": 8, + "Flags": 0 + }, + { + "Id": 926, + "Type": 22, + "Flags": 0 + }, + { + "Id": 927, + "Type": 22, + "Flags": 0 + }, + { + "Id": 928, + "Type": 7, + "Flags": 0 + }, + { + "Id": 929, + "Type": 7, + "Flags": 0 + }, + { + "Id": 930, + "Type": 7, + "Flags": 0 + }, + { + "Id": 931, + "Type": 7, + "Flags": 0 + }, + { + "Id": 932, + "Type": 22, + "Flags": 0 + }, + { + "Id": 933, + "Type": 22, + "Flags": 0 + }, + { + "Id": 934, + "Type": 7, + "Flags": 0 + }, + { + "Id": 935, + "Type": 7, + "Flags": 0 + }, + { + "Id": 936, + "Type": 7, + "Flags": 0 + }, + { + "Id": 937, + "Type": 7, + "Flags": 0 + }, + { + "Id": 938, + "Type": 8, + "Flags": 0 + }, + { + "Id": 939, + "Type": 8, + "Flags": 0 + }, + { + "Id": 940, + "Type": 7, + "Flags": 0 + }, + { + "Id": 941, + "Type": 7, + "Flags": 0 + }, + { + "Id": 942, + "Type": 7, + "Flags": 0 + }, + { + "Id": 943, + "Type": 7, + "Flags": 0 + }, + { + "Id": 944, + "Type": 36, + "Flags": 0 + }, + { + "Id": 945, + "Type": 36, + "Flags": 0 + }, + { + "Id": 946, + "Type": 22, + "Flags": 0 + }, + { + "Id": 947, + "Type": 22, + "Flags": 0 + }, + { + "Id": 948, + "Type": 22, + "Flags": 0 + }, + { + "Id": 949, + "Type": 22, + "Flags": 0 + }, + { + "Id": 952, + "Type": 33, + "Flags": 0 + }, + { + "Id": 953, + "Type": 33, + "Flags": 0 + }, + { + "Id": 954, + "Type": 33, + "Flags": 0 + }, + { + "Id": 955, + "Type": 33, + "Flags": 0 + }, + { + "Id": 960, + "Type": 33, + "Flags": 0 + }, + { + "Id": 961, + "Type": 33, + "Flags": 0 + }, + { + "Id": 962, + "Type": 33, + "Flags": 0 + }, + { + "Id": 963, + "Type": 33, + "Flags": 0 + }, + { + "Id": 964, + "Type": 29, + "Flags": 1 + }, + { + "Id": 965, + "Type": 29, + "Flags": 1 + }, + { + "Id": 966, + "Type": 29, + "Flags": 1 + }, + { + "Id": 967, + "Type": 29, + "Flags": 1 + }, + { + "Id": 968, + "Type": 28, + "Flags": 1 + }, + { + "Id": 969, + "Type": 28, + "Flags": 1 + }, + { + "Id": 970, + "Type": 28, + "Flags": 1 + }, + { + "Id": 971, + "Type": 28, + "Flags": 1 + }, + { + "Id": 972, + "Type": 28, + "Flags": 1 + }, + { + "Id": 973, + "Type": 28, + "Flags": 1 + }, + { + "Id": 988, + "Type": 8, + "Flags": 0 + }, + { + "Id": 989, + "Type": 8, + "Flags": 0 + }, + { + "Id": 990, + "Type": 22, + "Flags": 0 + }, + { + "Id": 991, + "Type": 22, + "Flags": 0 + }, + { + "Id": 992, + "Type": 8, + "Flags": 0 + }, + { + "Id": 993, + "Type": 8, + "Flags": 0 + }, + { + "Id": 998, + "Type": 8, + "Flags": 0 + }, + { + "Id": 999, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1000, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1001, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1002, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1003, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1004, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1005, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1006, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1007, + "Type": 22, + "Flags": 0 + }, + { + "Id": 1008, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1009, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1010, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1011, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1012, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1013, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1014, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1015, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1016, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1017, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1018, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1019, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1020, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1021, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1022, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1023, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1028, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1029, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1284, + "Type": 27, + "Flags": 1 + }, + { + "Id": 1285, + "Type": 27, + "Flags": 1 + }, + { + "Id": 1332, + "Type": 24, + "Flags": 1 + }, + { + "Id": 1449, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1450, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1453, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1454, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1455, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1456, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1457, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1458, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1459, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1460, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1461, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1462, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1463, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1464, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1465, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1466, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1467, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1468, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1469, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1470, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1473, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1474, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1475, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1476, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1477, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1478, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1479, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1480, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1481, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1482, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1483, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1484, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1495, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1496, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1497, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1498, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1499, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1500, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1501, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1502, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1503, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1504, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1515, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1516, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1517, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1518, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1519, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1520, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1521, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1522, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1523, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1524, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1525, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1526, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1543, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1544, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1545, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1546, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1563, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1564, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1565, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1566, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1567, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1568, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1569, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1570, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1571, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1572, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1573, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1574, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1583, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1584, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1585, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1586, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1587, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1588, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1589, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1590, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1591, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1592, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1593, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1594, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1613, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1614, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1615, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1616, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1617, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1618, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1633, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1634, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1635, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1636, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1637, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1638, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1639, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1640, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1645, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1646, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1647, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1648, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1649, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1650, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1651, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1652, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1653, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1654, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1655, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1656, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1657, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1658, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1659, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1660, + "Type": 21, + "Flags": 1 + }, + { + "Id": 1665, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1666, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1667, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1670, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1671, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1672, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1673, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1674, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1675, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1676, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1677, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1678, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1679, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1680, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1681, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1682, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1683, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1684, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1685, + "Type": 21, + "Flags": 0 + }, + { + "Id": 1724, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1725, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1726, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1727, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1728, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1729, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1730, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1731, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1732, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1733, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1734, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1735, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1736, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1737, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1738, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1739, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1740, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1741, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1742, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1743, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1744, + "Type": 7, + "Flags": 1 + }, + { + "Id": 1745, + "Type": 7, + "Flags": 1 + }, + { + "Id": 1746, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1747, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1748, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1749, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1752, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1753, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1754, + "Type": 7, + "Flags": 1 + }, + { + "Id": 1755, + "Type": 7, + "Flags": 1 + }, + { + "Id": 1756, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1757, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1758, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1759, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1760, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1761, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1762, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1763, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1764, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1765, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1766, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1767, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1768, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1769, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1770, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1771, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1772, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1773, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1774, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1775, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1776, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1777, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1778, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1779, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1780, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1781, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1782, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1783, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1784, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1785, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1786, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1787, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1788, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1789, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1790, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1791, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1792, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1793, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1899, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1900, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1901, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1902, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1903, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1904, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1905, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1906, + "Type": 4, + "Flags": 0 + }, + { + "Id": 1907, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1908, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1909, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1910, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1911, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1912, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1913, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1914, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1915, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1916, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1917, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1918, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1919, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1920, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1921, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1922, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1923, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1924, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1925, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1926, + "Type": 8, + "Flags": 0 + }, + { + "Id": 1927, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1928, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1929, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1930, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1931, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1932, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1933, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1934, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1935, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1936, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1937, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1938, + "Type": 7, + "Flags": 0 + }, + { + "Id": 1939, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1940, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1941, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1942, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1943, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1944, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1945, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1946, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1947, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1948, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1951, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1952, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1953, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1954, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1957, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1958, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1959, + "Type": 20, + "Flags": 0 + }, + { + "Id": 1960, + "Type": 20, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 1, + "High": 49161, + "Low": 12290 + }, + { + "Id": 2, + "High": 604028938, + "Low": 12290 + }, + { + "Id": 3, + "High": 49163, + "Low": 12290 + }, + { + "Id": 4, + "High": 604028939, + "Low": 12290 + }, + { + "Id": 5, + "High": 10485772, + "Low": 14274 + }, + { + "Id": 6, + "High": 10485764, + "Low": 14274 + }, + { + "Id": 7, + "High": 12, + "Low": 14274 + }, + { + "Id": 8, + "High": 12, + "Low": 12290 + }, + { + "Id": 9, + "High": 0, + "Low": 12290 + }, + { + "Id": 10, + "High": 10485761, + "Low": 12290 + }, + { + "Id": 11, + "High": 10485763, + "Low": 12290 + }, + { + "Id": 12, + "High": 1, + "Low": 12290 + }, + { + "Id": 13, + "High": 10485765, + "Low": 14274 + }, + { + "Id": 14, + "High": 10485766, + "Low": 14274 + }, + { + "Id": 15, + "High": 10485767, + "Low": 14274 + }, + { + "Id": 16, + "High": 10485768, + "Low": 14274 + }, + { + "Id": 17, + "High": 2, + "Low": 12290 + }, + { + "Id": 18, + "High": 4194316, + "Low": 145354 + }, + { + "Id": 19, + "High": 6291468, + "Low": 14282 + }, + { + "Id": 20, + "High": 2146316, + "Low": 14274 + }, + { + "Id": 21, + "High": 12, + "Low": 26562 + }, + { + "Id": 22, + "High": 11, + "Low": 12290 + }, + { + "Id": 23, + "High": 12, + "Low": 14282 + }, + { + "Id": 24, + "High": 9, + "Low": 12298 + }, + { + "Id": 25, + "High": 12, + "Low": 12298 + }, + { + "Id": 26, + "High": 10, + "Low": 12298 + }, + { + "Id": 27, + "High": 9, + "Low": 12290 + }, + { + "Id": 28, + "High": 2097164, + "Low": 14282 + }, + { + "Id": 29, + "High": 2097164, + "Low": 14274 + }, + { + "Id": 30, + "High": 49164, + "Low": 14274 + }, + { + "Id": 31, + "High": 49164, + "Low": 12290 + }, + { + "Id": 32, + "High": 8388620, + "Low": 143370 + }, + { + "Id": 33, + "High": 8388620, + "Low": 145354 + }, + { + "Id": 34, + "High": 10, + "Low": 12290 + }, + { + "Id": 35, + "High": 13, + "Low": 12290 + }, + { + "Id": 36, + "High": 14, + "Low": 12290 + } + ], + "Cams": [ + { + "Data": 1966086, + "PositionIndex": 3 + }, + { + "Data": 1966086, + "PositionIndex": 6 + }, + { + "Data": 1966086, + "PositionIndex": 0 + }, + { + "Data": 1441795, + "PositionIndex": 4 + }, + { + "Data": 1441795, + "PositionIndex": 5 + }, + { + "Data": 1441795, + "PositionIndex": 7 + }, + { + "Data": 1441795, + "PositionIndex": 8 + }, + { + "Data": 1441795, + "PositionIndex": 2 + }, + { + "Data": 1441795, + "PositionIndex": 1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 131072, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 2, + "IconPoints": [ + { + "Flag": 2, + "x": 84, + "y": -38 + }, + { + "Flag": 3, + "x": 57, + "y": -18 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 72, + "y": -32 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 3, + "x": 60, + "y": 18 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 73, + "y": 61 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 74, + "y": 66 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 9", + "Start": "02BEB000", + "End": "02BFC610", + "RemapStart": null + }, + "Id": 9, + "TActors": [ + "01FF 0AFF 0023 FD66 009B 059A AFA5 013F", + "03FF 08FF 0023 0386 00AC FCF7 1F4A 013F", + "02FF 03FF 0023 0032 0014 0102 44FA 013F", + "01FF 02FF 0023 FF8B 0006 025C C000 013F", + "01FF 00FF 0023 009A 0007 076B 4000 013F", + "03FF 04FF 0023 FF05 0009 FE95 C000 013F", + "04FF 05FF 0023 FE4F 001A FC3D 9E94 013F", + "06FF 05FF 0023 FAC7 0084 FFAF 9C72 013F", + "08FF 09FF 0023 0383 00AC F9E8 CD83 013F", + "03FF 0BFF 0023 02FC FFE5 001B EAAB 013F", + "07FF 0AFF 002E FC9E 0050 04C0 20B6 003F", + "06FF 07FF 002E FAC4 0118 02D9 2000 0054" + ], + "Paths": [ + { + "Points": [ + [ + 603, + 206, + 1826 + ], + [ + 553, + 32, + 1882 + ], + [ + 511, + 32, + 2001 + ], + [ + 560, + 32, + 2154 + ], + [ + 192, + 32, + 2575 + ], + [ + -31, + 32, + 2587 + ] + ] + }, + { + "Points": [ + [ + 298, + 498, + -134 + ], + [ + 302, + 55, + 60 + ], + [ + 255, + 55, + 211 + ], + [ + -7, + 55, + 265 + ], + [ + -327, + 55, + 322 + ] + ] + }, + { + "Points": [ + [ + -638, + 452, + -1163 + ], + [ + -453, + 63, + -974 + ], + [ + -359, + 51, + -824 + ], + [ + -382, + 63, + -671 + ], + [ + -500, + 85, + -545 + ], + [ + -445, + 70, + -356 + ] + ] + }, + { + "Points": [ + [ + 1475, + 702, + -1248 + ], + [ + 1308, + 231, + -911 + ], + [ + 1080, + 231, + -644 + ] + ] + }, + { + "Points": [ + [ + 900, + 700, + -1694 + ], + [ + 1062, + 230, + -1560 + ], + [ + 1059, + 230, + -1483 + ], + [ + 1056, + 230, + -1402 + ], + [ + 969, + 230, + -1236 + ], + [ + 962, + 230, + -1166 + ], + [ + 955, + 230, + -1101 + ], + [ + 1024, + 230, + -996 + ], + [ + 1024, + 230, + -954 + ], + [ + 1024, + 230, + -954 + ] + ] + } + ], + "Rooms": [ + { + "File": { + "Name": "Scene 9, Room 0", + "Start": "02BFD000", + "End": "02C05660", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "01C7 0144 0003 08E8 0000 0000 0000 0000", + "01C7 011F 0003 092A 0000 0000 0000 0000", + "0130 0258 0004 0725 0000 0000 0001 0D00", + "0111 00F8 000A 08EF 0000 0000 0000 4003", + "0112 00C3 0002 0A2D 0000 0000 0000 3FE8", + "0112 00A8 0002 09E5 0000 0000 0000 3FE8" + ] + }, + { + "File": { + "Name": "Scene 9, Room 1", + "Start": "02C06000", + "End": "02C12540", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "0121 0004 FFF6 0422 0000 0000 0000 0000", + "001B FF7C FFF6 04E4 0000 0000 0000 FFFE", + "001B 008C FFF6 04E8 0000 0000 0000 FFFE", + "01C7 00CC 01A4 038E 0000 0000 0000 0001", + "01C7 010C 01A4 03D4 0000 0000 0000 0001", + "0111 0033 000B 02CE 0000 0000 0000 4A03", + "0111 0034 000A 0300 0000 0000 0000 4C03", + "012A 0140 0062 0374 1111 F333 02D8 2813", + "01B4 FFCD 0033 0348 4000 0000 0000 2801", + "01B4 0031 0033 0348 4000 0000 0000 2801", + "01B4 0031 0097 0348 4000 0000 0000 2801", + "01B4 FFCD 0097 0348 4000 0000 0000 2801" + ] + }, + { + "File": { + "Name": "Scene 9, Room 2", + "Start": "02C13000", + "End": "02C18AF0", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "01C7 FEE0 000C 0192 0000 0000 0000 0000", + "01C7 FF2C 000D 018E 0000 0000 0000 0000", + "01C7 FEA1 000B 01A7 0000 0000 0000 0000", + "01C7 FEFE 000B 01CD 0000 0000 0000 0000", + "0130 012A 01C3 0040 0000 0000 0001 0D01", + "01C7 FFED 000D 00C1 0000 0000 0000 0000" + ] + }, + { + "File": { + "Name": "Scene 9, Room 3", + "Start": "02C19000", + "End": "02C21080", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "01C7 0280 0000 FEC8 0000 0000 0000 0000", + "01C7 0266 0000 FEDC 0000 0000 0000 0000", + "01C7 0255 0000 FF00 0000 0000 0000 0000", + "01C7 0256 0000 FF2B 0000 0000 0000 0000", + "01C7 025F 0000 FF56 0000 0000 0000 0000", + "01AF 010F 0000 FE6F 0000 0000 0000 FF01", + "0121 FFDD 0000 FE67 0000 3BBC 0000 FFFF", + "0121 021D 0000 FE09 0000 E2D8 0000 FFFF", + "01C8 02B3 0007 FF27 0000 AE39 0000 0500", + "00EF FF7A 0000 FE32 0000 0000 0000 0021", + "00EF FF87 0000 FE5E 0000 0000 0000 0022", + "00EF FF72 0000 FE87 0000 0000 0000 0023", + "0111 01B1 0000 FD24 0000 0000 0000 4E12", + "0111 0239 0000 FF51 0000 0000 0000 5001", + "00EF 0241 00AC FCCE 0000 0000 0000 0029", + "0111 0209 0000 FF7D 0000 0000 0000 5203", + "00EF 0266 00AC FCFE 0000 0000 0000 002A", + "00EF 0290 00AC FD2E 0000 0000 0000 002B", + "0111 008A 0000 FD60 0000 0000 0000 5812" + ] + }, + { + "File": { + "Name": "Scene 9, Room 4", + "Start": "02C22000", + "End": "02C29670", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "01C7 FEFB 001F FCB8 0000 0000 0000 0000", + "0130 FD82 01C1 FB75 0000 0000 0001 0D02", + "0112 FE70 0013 FE48 0000 0000 0000 3FE6", + "0112 FE49 0013 FE65 0000 0000 0000 3FE6", + "0112 FE1E 0014 FE7E 0000 0000 0000 3FE6" + ] + }, + { + "File": { + "Name": "Scene 9, Room 5", + "Start": "02C2A000", + "End": "02C32890", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "00F0 F86A 0096 FD4E 0000 0000 0000 FFFF", + "01D1 F8EE 0000 FD49 0000 0000 0000 11FF", + "01C9 FB6E 0077 FAA2 0000 0000 0009 18FF", + "01AF F9E4 0029 FC43 0000 4000 0000 FF01", + "01AF FB7C 003D FD55 0000 40B6 0000 FF01", + "0013 F941 0155 FD14 0000 4000 0000 0004", + "0013 F947 0155 FD7F 0000 4000 0000 0004", + "0095 FB80 00B9 F987 0000 2889 0000 8A01", + "0095 FA8E 0000 FF17 0000 8000 0000 8A04", + "012A FD2E 00DB FCB3 8000 0000 0000 2613", + "01B4 FA47 0032 FF06 0000 0000 4000 2601", + "01B4 FAAC 0032 FF06 0000 0000 4000 2601", + "01B4 FA8E 0064 FF06 0000 0000 0000 2601", + "01B4 FA8E 0032 FEFC 4000 0000 0000 2601", + "00EF FA62 0078 FF65 0000 0000 0000 002D", + "00EF FA96 0078 FF61 0000 0000 0000 002E", + "00EF FAC9 0078 FF61 0000 0000 0000 002F", + "01C7 FD05 00AE FC80 0000 0000 0000 0002" + ] + }, + { + "File": { + "Name": "Scene 9, Room 6", + "Start": "02C33000", + "End": "02C37260", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "01C7 FA31 0162 0239 0000 0000 0000 0001", + "01C7 F9D1 0193 0261 0000 0000 0000 0001", + "01C7 FA0C 01BB 0146 0000 0000 0000 0001", + "0013 F9DB 0175 01FA 0000 A222 0000 0004", + "0013 FACE 015C 009F 0000 3333 0000 0004", + "0111 FAB8 0111 027F 0000 0000 0000 5412", + "0111 FA8C 010B 0254 0000 0000 0000 560E" + ] + }, + { + "File": { + "Name": "Scene 9, Room 7", + "Start": "02C38000", + "End": "02C3D8F0", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "006B", + "008A", + "000E", + "0090", + "0032" + ], + "Actors": [ + "01C8 FC80 0116 0498 C000 2000 0000 FF02", + "0048 FBAC 0122 0294 0000 0000 0000 0008", + "000A FC13 0118 042C 0000 216C 0000 15C2", + "0002 FBB8 011A 03C4 0000 9A50 0000 FFFF" + ] + }, + { + "File": { + "Name": "Scene 9, Room 8", + "Start": "02C3E000", + "End": "02C3F950", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "0121 0455 00AC FB43 0000 0000 0000 0000", + "0121 04C3 00AC FBCC 0000 0000 0000 0000", + "0130 05BE 02C3 FB25 0000 0000 0001 0D03", + "0130 0381 02AF F969 0000 0000 0001 0D04", + "0112 0432 00AC FD2E 0000 0000 0000 3FE7", + "0112 0456 00AC FD70 0000 0000 0000 3FE7" + ] + }, + { + "File": { + "Name": "Scene 9, Room 9", + "Start": "02C40000", + "End": "02C48650", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "0121 0358 00B6 F695 0000 0000 0000 0000", + "0121 0129 0106 F60F 0000 0EEF 0000 0000", + "00F0 025A 00E2 F65C 0000 0000 0000 FFFF", + "01D1 010C 0070 F7EF 0000 0000 0000 10FF", + "01D1 0115 0070 F76C 0000 0CCD 0000 10FF", + "0121 02C8 0016 F6FF 0000 0000 0000 FFFF", + "01C7 02E6 0016 F660 0000 0000 0000 0000", + "01C7 030F 0016 F66B 0000 0000 0000 0000", + "01C7 0387 0016 F6CF 0000 0000 0000 0000", + "01C7 03A1 0016 F701 0000 0000 0000 0000", + "0111 0386 0016 F560 0000 0000 0000 6E0B", + "0111 01C3 0016 F55A 0000 0000 0000 6C0B", + "000A 0113 0106 F5D0 0000 8EEF 0000 0800", + "0015 04AC 00B7 F749 0000 0000 0000 0106", + "0095 0178 00D5 F800 0000 0000 0000 8A02", + "012A 0294 FFCB F754 0000 0000 0000 2713", + "01B4 04A8 00DE F744 0000 1C72 0000 2701", + "01B4 04A8 0106 F744 0000 1C72 0000 2701", + "00EF 0178 00D5 F800 0000 0000 0000 003B" + ] + }, + { + "File": { + "Name": "Scene 9, Room 10", + "Start": "02C49000", + "End": "02C4D3E0", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [] + }, + { + "File": { + "Name": "Scene 9, Room 11", + "Start": "02C4E000", + "End": "02C53900", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "006B", + "0016", + "011F", + "0114", + "0179", + "0024", + "015C", + "0190", + "00A8", + "0183", + "000E", + "0154", + "000D" + ], + "Actors": [ + "00EF 04B1 FFB9 0288 0000 0000 0000 02FF", + "00F0 05D3 FFEA 019D 0000 0000 0000 FFFF", + "01C7 0541 FFB9 0104 0000 0000 0000 0000", + "01C7 055F FFB9 0123 0000 0000 0000 0000", + "01C7 0540 FFB9 014C 0000 0000 0000 0000", + "01C7 052D FFB9 0171 0000 0000 0000 0000", + "01C7 0529 FFB9 019A 0000 0000 0000 0000", + "01C7 052F FFB9 01BA 0000 0000 0000 0000", + "01C7 0536 FFB9 01D9 0000 0000 0000 0000", + "01C7 047D FFB9 0040 0000 0000 0000 0000", + "01C7 0492 FFB9 0061 0000 0000 0000 0000", + "01AF 04DE FFB9 016B 0000 0000 0000 FF00", + "01AF 04D9 FFB9 0075 0000 0000 0000 FF00", + "0095 0463 001D 004F 0000 1D28 0000 0000", + "000A 04B2 FFB9 0289 0000 0000 0003 B821", + "012A 045A FFA8 0068 0000 0000 0000 0303", + "011B 05D4 FFC3 019E 0014 0000 0014 4689" + ] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [ + { + "Id": 678, + "Type": 0, + "Flags": 1 + }, + { + "Id": 679, + "Type": 0, + "Flags": 1 + }, + { + "Id": 680, + "Type": 0, + "Flags": 1 + }, + { + "Id": 681, + "Type": 0, + "Flags": 1 + }, + { + "Id": 682, + "Type": 0, + "Flags": 1 + }, + { + "Id": 683, + "Type": 0, + "Flags": 1 + }, + { + "Id": 684, + "Type": 0, + "Flags": 1 + }, + { + "Id": 685, + "Type": 0, + "Flags": 1 + }, + { + "Id": 686, + "Type": 0, + "Flags": 1 + }, + { + "Id": 687, + "Type": 0, + "Flags": 1 + }, + { + "Id": 688, + "Type": 0, + "Flags": 1 + }, + { + "Id": 689, + "Type": 0, + "Flags": 1 + }, + { + "Id": 690, + "Type": 0, + "Flags": 1 + }, + { + "Id": 691, + "Type": 0, + "Flags": 1 + }, + { + "Id": 692, + "Type": 0, + "Flags": 1 + }, + { + "Id": 693, + "Type": 0, + "Flags": 1 + }, + { + "Id": 694, + "Type": 0, + "Flags": 1 + }, + { + "Id": 695, + "Type": 0, + "Flags": 1 + }, + { + "Id": 696, + "Type": 0, + "Flags": 1 + }, + { + "Id": 697, + "Type": 0, + "Flags": 1 + }, + { + "Id": 1490, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1491, + "Type": 30, + "Flags": 0 + }, + { + "Id": 1598, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1599, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1600, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1601, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1602, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1603, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1606, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1607, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1608, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1609, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1610, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1611, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1614, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1615, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1616, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1617, + "Type": 39, + "Flags": 0 + }, + { + "Id": 1622, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1623, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1624, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1625, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1626, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1627, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1628, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1629, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1630, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1631, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1632, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1633, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1634, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1635, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1636, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1637, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1638, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1639, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1640, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1641, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1642, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1643, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1644, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1645, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1646, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1647, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1648, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1649, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1650, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1651, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1652, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1653, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1654, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1655, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1656, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1657, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1658, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1659, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1660, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1661, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1662, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1663, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1664, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1665, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1666, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1667, + "Type": 41, + "Flags": 0 + }, + { + "Id": 1686, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1687, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1688, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1689, + "Type": 40, + "Flags": 0 + }, + { + "Id": 1693, + "Type": 42, + "Flags": 1 + }, + { + "Id": 1733, + "Type": 42, + "Flags": 1 + }, + { + "Id": 2002, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2022, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2023, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2024, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2056, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2057, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2066, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2067, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2071, + "Type": 43, + "Flags": 0 + }, + { + "Id": 2082, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2083, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2088, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2089, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2090, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2091, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2092, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2093, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2094, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2095, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2096, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2097, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2098, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2103, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2104, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2113, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2114, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2115, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2116, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2117, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2118, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2119, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2120, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2121, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2122, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2123, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2124, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2125, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2126, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2127, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2128, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2129, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2130, + "Type": 46, + "Flags": 0 + }, + { + "Id": 2131, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2132, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2133, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2134, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2135, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2136, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2137, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2138, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2139, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2140, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2141, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2142, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2143, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2144, + "Type": 47, + "Flags": 0 + }, + { + "Id": 2304, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2305, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2306, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2307, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2308, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2309, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2310, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2311, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2312, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2313, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2314, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2315, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2316, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2317, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2318, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2319, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2320, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2321, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2322, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2323, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2324, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2325, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2326, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2327, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2328, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2329, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2330, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2331, + "Type": 45, + "Flags": 0 + }, + { + "Id": 2332, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2333, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2337, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2338, + "Type": 48, + "Flags": 0 + }, + { + "Id": 2341, + "Type": 49, + "Flags": 0 + }, + { + "Id": 2342, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2343, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2344, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2345, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2346, + "Type": 50, + "Flags": 0 + }, + { + "Id": 2384, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2385, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2386, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2387, + "Type": 44, + "Flags": 0 + }, + { + "Id": 2475, + "Type": 51, + "Flags": 0 + }, + { + "Id": 2487, + "Type": 52, + "Flags": 0 + }, + { + "Id": 2488, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2489, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2490, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2491, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2492, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2493, + "Type": 53, + "Flags": 0 + }, + { + "Id": 2573, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2574, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2575, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2576, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2577, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2578, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2579, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2580, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2593, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2594, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2595, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2665, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2666, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2667, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2668, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2669, + "Type": 54, + "Flags": 0 + }, + { + "Id": 2670, + "Type": 54, + "Flags": 0 + } + ], + "PolyTypes": [ + { + "Id": 0, + "High": 0, + "Low": 18376 + }, + { + "Id": 1, + "High": 1, + "Low": 16402 + }, + { + "Id": 2, + "High": 49153, + "Low": 51272 + }, + { + "Id": 3, + "High": 49153, + "Low": 16386 + }, + { + "Id": 4, + "High": 49153, + "Low": 16392 + }, + { + "Id": 5, + "High": 49154, + "Low": 16392 + }, + { + "Id": 6, + "High": 49153, + "Low": 16402 + }, + { + "Id": 7, + "High": 1, + "Low": 16386 + }, + { + "Id": 8, + "High": 49409, + "Low": 802818 + }, + { + "Id": 9, + "High": 0, + "Low": 16392 + }, + { + "Id": 10, + "High": 1, + "Low": 16408 + }, + { + "Id": 11, + "High": 40963, + "Low": 51340 + }, + { + "Id": 12, + "High": 3, + "Low": 51352 + }, + { + "Id": 13, + "High": 3, + "Low": 16536 + }, + { + "Id": 14, + "High": 3, + "Low": 51336 + }, + { + "Id": 15, + "High": 3, + "Low": 16520 + }, + { + "Id": 16, + "High": 2, + "Low": 16392 + }, + { + "Id": 17, + "High": 2, + "Low": 51272 + }, + { + "Id": 18, + "High": 2, + "Low": 16456 + }, + { + "Id": 19, + "High": 40962, + "Low": 16396 + }, + { + "Id": 20, + "High": 2, + "Low": 16520 + }, + { + "Id": 21, + "High": 2, + "Low": 51336 + }, + { + "Id": 22, + "High": 40962, + "Low": 16460 + }, + { + "Id": 23, + "High": 2, + "Low": 51464 + }, + { + "Id": 24, + "High": 2, + "Low": 16648 + }, + { + "Id": 25, + "High": 2, + "Low": 16408 + }, + { + "Id": 26, + "High": 0, + "Low": 18392 + }, + { + "Id": 27, + "High": 3, + "Low": 16642 + }, + { + "Id": 28, + "High": 3, + "Low": 51458 + }, + { + "Id": 30, + "High": 49154, + "Low": 51464 + }, + { + "Id": 31, + "High": 0, + "Low": 51464 + }, + { + "Id": 32, + "High": 40961, + "Low": 51468 + }, + { + "Id": 33, + "High": 2097152, + "Low": 18376 + }, + { + "Id": 34, + "High": 2097152, + "Low": 51458 + }, + { + "Id": 35, + "High": 0, + "Low": 16520 + }, + { + "Id": 36, + "High": 805306370, + "Low": 51464 + }, + { + "Id": 37, + "High": 805306370, + "Low": 51468 + }, + { + "Id": 38, + "High": 49154, + "Low": 16456 + }, + { + "Id": 39, + "High": 0, + "Low": 16584 + }, + { + "Id": 41, + "High": 2, + "Low": 51400 + }, + { + "Id": 42, + "High": 0, + "Low": 53192 + }, + { + "Id": 43, + "High": 2, + "Low": 18376 + }, + { + "Id": 44, + "High": 49154, + "Low": 51336 + }, + { + "Id": 45, + "High": 3, + "Low": 51340 + }, + { + "Id": 46, + "High": 2097155, + "Low": 51340 + }, + { + "Id": 47, + "High": 2097152, + "Low": 16520 + }, + { + "Id": 48, + "High": 49154, + "Low": 51272 + }, + { + "Id": 49, + "High": 40962, + "Low": 51336 + }, + { + "Id": 50, + "High": 40962, + "Low": 51340 + }, + { + "Id": 51, + "High": 2, + "Low": 51352 + }, + { + "Id": 52, + "High": 2, + "Low": 16472 + }, + { + "Id": 53, + "High": 2, + "Low": 51276 + }, + { + "Id": 54, + "High": 2, + "Low": 51330 + } + ], + "Cams": [ + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [ + { + "Icons": [ + { + "Icon": 0, + "Count": 3, + "IconPoints": [ + { + "Flag": 0, + "x": 66, + "y": -2 + }, + { + "Flag": 1, + "x": 77, + "y": -46 + }, + { + "Flag": 2, + "x": 27, + "y": -45 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ], + "Minimaps": [ + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 2, + "x": 71, + "y": 59 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 0, + "x": 48, + "y": 36 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + }, + { + "Icons": [ + { + "Icon": 0, + "Count": 1, + "IconPoints": [ + { + "Flag": 1, + "x": 73, + "y": 67 + } + ] + }, + { + "Icon": -1, + "Count": 0, + "IconPoints": [] + }, + { + "Icon": 0, + "Count": 0, + "IconPoints": [] + } + ] + } + ] + }, + { + "File": { + "Name": "Scene 10", + "Start": "02EE3000", + "End": "02EF37B0", + "RemapStart": null + }, + "Id": 10, + "TActors": [ + "0303 02FF 002E 0000 012C 01FA 8000 008A", + "0505 04FF 002E FE06 0230 0000 4000 007F", + "0101 00FF 002E 01FA 0028 0000 C000 007F", + "0700 00FF 002E FE70 0000 0000 4000 007F", + "0102 02FF 002E 0000 0104 FE70 0000 008A", + "0304 04FF 002E 0190 0208 0000 C000 007F", + "08FF 05FF 002E 0000 0320 01F4 0000 0154", + "0606 08FF 002E 01F4 0320 0000 C000 0154", + "09FF 06FF 002E 0000 05F0 01F4 0000 0154" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 10, Room 0", + "Start": "02EF4000", + "End": "02EFBED0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0139", + "00A4", + "0085", + "000D", + "001B" + ], + "Actors": [ + "003B FFF3 0000 001D 0000 0000 0000 00FF", + "0025 001A 0000 FF7B 0000 C000 0000 FFFE", + "0025 0023 0000 0077 0000 C000 0000 FFFE", + "0008 00E8 0078 00ED 0000 0000 0000 03F4", + "0008 00F0 0078 FF14 0000 0000 0000 03F4", + "0008 FF14 0078 FF13 0000 0000 0000 03F4", + "0008 FF15 0078 00EF 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 10, Room 1", + "Start": "02EFC000", + "End": "02F03770", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "0139", + "00A4", + "0085", + "000D", + "001B" + ], + "Actors": [ + "0008 0285 00B4 FEA6 0000 0000 0000 03F4", + "0008 01C2 00F0 FDE6 0000 0000 0000 03F4", + "0008 01EB 00B4 FF02 0000 0000 0000 03F4", + "0008 016A 00F0 FE82 0000 0000 0000 03F4", + "0008 FFAC 0154 FDF9 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 10, Room 2", + "Start": "02F04000", + "End": "02F0B850", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0139", + "00A4", + "0085", + "000D", + "001B", + "0032", + "000E" + ], + "Actors": [ + "003B 00AE 0104 001D 0000 0000 0000 00FE", + "0008 00EA 0176 00ED 0000 0000 0000 03F4", + "0008 00F0 0176 FF12 0000 0000 0000 03F4", + "0008 FF13 0176 FF12 0000 0000 0000 03F4", + "0008 FF15 0176 00EF 0000 0000 0000 03F4", + "0002 FF49 0104 FFF4 0000 8000 0000 FFFF", + "0002 00A1 0104 FFF9 0000 8000 0000 FFFF", + "0049 0002 0104 FFFF 0000 0000 0000 6FCA", + "0187 FFA2 0104 FFF5 0000 0000 0000 2BFF", + "000A FFFF 0104 FFFF 0000 0000 0000 27EB" + ] + }, + { + "File": { + "Name": "Scene 10, Room 3", + "Start": "02F0C000", + "End": "02F13730", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0139", + "00A4", + "0085", + "000D", + "001B", + "0032", + "000E" + ], + "Actors": [ + "003B 0025 012C 026E 0000 0000 0000 00FD", + "0008 0159 01B8 0284 0000 0000 0000 03F4", + "0008 00FF 01B8 01EA 0000 0000 0000 03F4", + "0008 0219 01F4 01C3 0000 0000 0000 03F4", + "0008 0181 01F4 0169 0000 0000 0000 03F4", + "0008 0208 0258 FFAC 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 10, Room 4", + "Start": "02F14000", + "End": "02F1D0D0", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "0139", + "00A4", + "0085", + "000D", + "0106", + "000E" + ], + "Actors": [ + "003B 0025 0208 FF86 0000 0000 0000 00FC", + "0113 FEDD 0208 0025 0000 4000 0000 FF02", + "0113 FEDE 0208 FFE0 0000 4000 0000 FF03", + "0008 00EA 0276 00EE 0000 0000 0000 03F4", + "0008 00F1 0276 FF14 0000 0000 0000 03F4", + "0008 FF14 0276 FF14 0000 0000 0000 03F4", + "0008 FF16 0276 00EE 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 10, Room 5", + "Start": "02F1E000", + "End": "02F26B10", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0139", + "00B0" + ], + "Actors": [ + "003B FD76 0230 0010 0000 0000 0000 00FB", + "0008 FD7C 02D0 01BE 0000 0000 0000 03F4", + "0008 FE16 02D0 0163 0000 0000 0000 03F4", + "0008 FE95 030C 01E4 0000 0000 0000 03F4", + "0008 FE3D 030C 027F 0000 0000 0000 03F4" + ] + }, + { + "File": { + "Name": "Scene 10, Room 6", + "Start": "02F27000", + "End": "02F30BA0", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0139", + "00B0" + ], + "Actors": [ + "003B 0012 05F0 0335 0000 0000 0000 00F9" + ] + }, + { + "File": { + "Name": "Scene 10, Room 7", + "Start": "02F31000", + "End": "02F3B7A0", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "0139", + "00A4", + "0085", + "000D", + "001B", + "00B0" + ], + "Actors": [ + "003B 0143 FF24 027F 0000 0000 0000 00FF", + "0013 0053 008C 023C 0000 0000 0000 0000", + "0013 00E1 008C 028A 0000 0000 0000 0000", + "0013 016D 008C 023F 0000 0000 0000 0000", + "0013 FEA0 001B 01DD 0000 0000 0000 0000", + "0013 FDF9 00A0 0007 0000 0000 0000 0000", + "0013 FDEC 004E 0168 0000 0000 0000 0000", + "0013 FF53 FFDB 0291 0000 0000 0000 0000", + "005E 008D FF24 01CC 0000 0000 0000 2400", + "005E 0126 FF24 01CD 0000 0000 0000 2400", + "005E FDB5 0000 FFBC 0000 0000 0000 2400", + "005E FE3A 0000 FFBC 0000 0000 0000 2400" + ] + }, + { + "File": { + "Name": "Scene 10, Room 8", + "Start": "02F3C000", + "End": "02F42BE0", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "0139", + "00B0" + ], + "Actors": [ + "003B FFF9 030C 00C5 0000 0000 0000 00FA", + "0111 FE5A 0320 FEFE 0000 0000 0000 400E", + "0111 FE82 0320 FED4 0000 0000 0000 4203", + "0111 FEAA 0320 FEAB 0000 0000 0000 440F", + "0111 FED6 0320 FE81 0000 0000 0000 460F", + "0111 FEFF 0320 FE58 0000 0000 0000 4803", + "0111 FE82 0320 FEFD 0000 0000 0000 4A09", + "0111 FEAA 0320 FED4 0000 0000 0000 4C09", + "0111 FED3 0320 FEAB 0000 0000 0000 4E03", + "0111 FEFE 0320 FE81 0000 0000 0000 503F", + "0111 01A2 0320 FEFB 0000 0000 0000 523F", + "0111 0179 0320 FED3 0000 0000 0000 5409", + "0111 0152 0320 FEAC 0000 0000 0000 5609", + "0111 012C 0320 FE84 0000 0000 0000 5803", + "0111 0104 0320 FE5C 0000 0000 0000 5A03", + "0111 017A 0320 FEFB 0000 0000 0000 5C03", + "0111 0151 0320 FED4 0000 0000 0000 5E3F", + "0111 012B 0320 FEAC 0000 0000 0000 603F", + "0111 0104 0320 FE84 0000 0000 0000 6209" + ] + }, + { + "File": { + "Name": "Scene 10, Room 9", + "Start": "02F43000", + "End": "02F48920", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "0139", + "00B0" + ], + "Actors": [] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [], + "PolyTypes": [], + "Cams": [ + { + "Data": 2097155, + "PositionIndex": 0 + }, + { + "Data": 2097155, + "PositionIndex": 1 + }, + { + "Data": 2097155, + "PositionIndex": 2 + }, + { + "Data": 2097155, + "PositionIndex": 3 + }, + { + "Data": 2097155, + "PositionIndex": 4 + }, + { + "Data": 2097155, + "PositionIndex": 5 + }, + { + "Data": 2097155, + "PositionIndex": 6 + }, + { + "Data": 0, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [], + "Minimaps": [] + }, + { + "File": { + "Name": "Scene 11", + "Start": "02875000", + "End": "02886530", + "RemapStart": null + }, + "Id": 11, + "TActors": [ + "06FF 08FF 0023 0320 FFB0 FA10 C000 003F", + "02FF 01FF 002E F9D4 FFB0 FD94 0000 009F", + "03FF 02FF 002E F9D5 00A0 F789 0000 009C", + "0AFF 03FF 002E F9D7 009F F257 0000 007F", + "08FF 00FF 002E FFC4 FFB0 FBB4 0000 003F", + "07FF 00FF 002E 035C FFB0 FF4C C000 009A", + "01FF 00FF 002E FC2C FFB0 FF4C 4000 0098", + "04FF 03FF 002E FCF7 00EF F545 C000 007F", + "04FF 05FF 002E 0337 FFAF F544 4000 0099", + "06FF 05FF 002E 05A3 FFAF F698 8000 0099", + "09FF 06FF 002E 0782 FF10 FA48 C000 008C", + "06FF 07FF 002E 05C8 FFB1 FDA8 0000 009E", + "08FF 04FF 002E FFB2 00EF F7F4 8000 0084", + "08FF 08FF 002E FDE4 FFB0 FB50 4000 003F", + "08FF 08FF 002E FF24 FFB0 FAB0 4000 003F", + "08FF 08FF 002E 0064 FFB0 FAB0 C000 0080", + "08FF 08FF 002E 01F4 FFB0 FB00 0000 003F", + "08FF 08FF 002E FED4 FFB0 F9C0 0000 003F", + "08FF 08FF 002E FD94 FFB0 F880 0000 003F", + "08FF 08FF 002E FFC4 FFB0 F8D0 C000 02DD", + "08FF 08FF 002E 00B4 FFB0 F880 8000 02D4", + "08FF 08FF 002E 0064 FFB0 F970 4000 02D7" + ], + "Paths": [], + "Rooms": [ + { + "File": { + "Name": "Scene 11, Room 0", + "Start": "02887000", + "End": "02896F90", + "RemapStart": "2886530" + }, + "Id": 0, + "Objects": [ + "004D", + "00A4", + "000E", + "0090", + "00B9", + "0177", + "012F" + ], + "Actors": [ + "000A 009D FFEC FE70 0000 6000 0000 5D47", + "000A FEE8 FFEC FE70 0000 A000 0000 5953", + "005E FF60 FFE8 FF38 0000 0000 0000 1098", + "005E 0028 FFE8 FF38 0000 0000 0000 1098", + "012A FFC4 0118 FFFA 0000 8000 0000 1A02", + "0111 FEBC FFEC FF4F 0000 0000 0000 7603", + "0111 FEBC FFEC FFB8 0000 0000 0000 780F", + "0111 00C5 FFEC FF4D 0000 0000 0000 7A0E", + "0111 00C7 FFEC FFB1 0000 0000 0000 7C03" + ] + }, + { + "File": { + "Name": "Scene 11, Room 1", + "Start": "02897000", + "End": "028A0290", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "004D", + "000E", + "0090", + "0106", + "0183" + ], + "Actors": [ + "0113 F9A3 FFA6 FFED 0000 4E39 0000 FF03", + "000A F976 0078 FE12 0000 8000 001F 89A0", + "0187 F9BA FFA6 FF85 0000 0000 0000 7C3C" + ] + }, + { + "File": { + "Name": "Scene 11, Room 2", + "Start": "028A1000", + "End": "028A5F80", + "RemapStart": "28a0350" + }, + "Id": 2, + "Objects": [ + "004D", + "002C", + "011F", + "000E", + "0090", + "018E", + "011C", + "000B", + "006B", + "0114" + ], + "Actors": [ + "0121 F8A5 FFB0 FC3D 0000 8000 0000 0000", + "01C7 FB40 0140 F813 0000 0000 0000 0002", + "01C7 FB11 0140 F814 0000 0000 0000 0002", + "01C7 FB70 0140 F814 0000 0000 0000 0002", + "01C7 FB19 0111 FB07 0000 0000 0000 0002", + "01C7 FB62 00D8 FB63 0000 0000 0000 0002", + "01C7 FB21 00A0 FBB8 0000 0000 0000 0002", + "01C7 F8A4 0078 FC00 0000 0000 0000 0002", + "01C7 FB13 0066 FC17 0000 0000 0000 0002", + "01C7 FB61 00A0 F7AC 0000 0000 0000 0000", + "01C7 FB4B 00A0 F7E0 0000 0000 0000 0000", + "01C7 FB6E 00A0 F7E0 0000 0000 0000 0000", + "01C7 FB0F 00A0 F7ED 0000 0000 0000 0000", + "01C7 FB2D 00A0 F7FA 0000 0000 0000 0000", + "000C F9D9 00A0 F907 0000 0000 0000 00FF", + "000C F91D 0062 F9BF 0000 C000 0000 00FF", + "000C FA88 FFB0 FC19 0000 C000 0000 00FF", + "0011 F9CB FFB0 FACF 0000 0000 0000 0001", + "012D F9D6 0166 F997 4000 0000 0000 FFC2", + "012D FB3E 0168 F99C 4000 0000 0000 FFC2", + "012D F9D4 0166 FC12 4000 0000 0000 FFC2", + "0011 F9D5 00C1 F9F5 0000 4000 0000 1102", + "0187 F9F2 FFB0 FCAF 0000 0000 0000 705A", + "0117 F9D4 FFB0 FCDC 0000 8000 0000 015C", + "0117 FB23 00A0 F7C0 0000 0000 0000 1FDC", + "0117 F9FA 0035 FA45 0000 0000 0000 1FDC", + "0117 FA38 00C8 FC18 0000 0000 0000 1FDC", + "0117 F8A2 FFB0 FC44 0000 0000 0000 1FDC", + "0117 FB13 FF90 FC65 0000 0000 0000 1FDC", + "012D FA11 00A0 F894 0000 0000 0000 1CC1" + ] + }, + { + "File": { + "Name": "Scene 11, Room 3", + "Start": "028A6000", + "End": "028ADC20", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "004D", + "000E", + "0090", + "0190", + "00A8", + "00A4", + "0032", + "0024", + "006B" + ], + "Actors": [ + "01CD FB7B 0117 F545 0000 C000 0000 0000", + "00F0 F962 00B4 F4D4 0000 4000 0000 FFFF", + "005E F962 0077 F4D4 0000 0000 0000 03FF", + "01D1 FB49 009F F548 0000 4000 0006 38FF", + "0002 FA8C 009F F5CD 0000 0000 0000 0002", + "0002 FA1F 009F F51C 0000 0000 0000 0002", + "0037 F9BC 01C1 F64D 0000 0000 0000 0001", + "0037 FB31 01C1 F54F 0000 C000 0000 0001", + "0037 F9E6 01C1 F551 0000 0D83 0000 0001", + "0187 FA03 0117 F5F4 0000 0000 0000 0C3C", + "0139 F9D7 FFD7 F347 0000 0000 0000 000B", + "00FF F9D7 FFD7 F347 0000 0000 0000 0BC7", + "00FF F9D7 009F F40F 0000 0000 0000 0BC3", + "00EF FCA0 00EF F547 0000 C000 0000 030F", + "000A FACD 009F F4D6 0000 8000 0000 7951" + ] + }, + { + "File": { + "Name": "Scene 11, Room 4", + "Start": "028AE000", + "End": "028B8150", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "004D", + "000E", + "0090", + "000D", + "011C", + "017F", + "002C" + ], + "Actors": [ + "012D FFB7 0044 F545 0000 11C7 0000 FFC0", + "012D FF59 00EF F757 0000 0000 0000 FFC0", + "000A FFBF 0180 F31F 0000 8000 0015 8063", + "012A FFC7 FF69 F48D 0000 0000 0000 0403", + "0112 FFB6 00A7 F546 0000 0000 0001 1093", + "0062 FF9C 0002 F50D FC72 905B 0000 0015", + "0062 FFF2 000B F52A FC72 4FA5 0000 0015", + "0062 FF79 0028 F55C F555 D05B 0000 0015", + "0062 FFCA FFF0 F57C FC72 105B 0000 0015", + "0061 FFB3 FF5F F545 0000 0000 0000 0015", + "0049 FFC7 FF69 F48E 0000 0000 0000 3FFE", + "0049 FF3C FF69 F4BE 0000 0000 0000 3FFE", + "0049 003D FF69 F4C6 0000 0000 0000 3FFE", + "0049 FF06 FF69 F540 0000 0000 0000 3FFE", + "0049 0068 FF69 F54F 0000 0000 0000 3FFE", + "0049 FF30 FF69 F5C6 0000 0000 0000 3FFE", + "0049 002B FF69 F5CD 0000 0000 0000 3FFE", + "0049 FFB0 FF69 F5FB 0000 0000 0000 3FFE" + ] + }, + { + "File": { + "Name": "Scene 11, Room 5", + "Start": "028B9000", + "End": "028BE0E0", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "004D", + "000E", + "0090", + "00B7", + "0106", + "0025" + ], + "Actors": [ + "0113 0562 FFBF F53A 0000 C000 0000 FF02", + "0038 05E6 FFAF F487 0000 0000 0000 FFFF", + "0038 0532 FFAF F5F2 0000 705B 0000 FFFF", + "000A 05A6 0064 F544 0000 C000 0038 884E", + "012A 06C9 FF9C F4CD 0000 0000 0000 1000", + "0049 05A6 FFBF F546 0000 0000 0000 2FD0", + "000A 05A1 FFAF F427 0000 8000 0000 7952", + "0187 05A8 FFBF F542 0000 0000 0000 643C", + "012A 05A3 006E F6B4 C000 0000 0000 3803" + ] + }, + { + "File": { + "Name": "Scene 11, Room 6", + "Start": "028BF000", + "End": "028C6F40", + "RemapStart": "28BE190" + }, + "Id": 6, + "Objects": [ + "004D", + "002B", + "005D", + "011C", + "00A4", + "000E", + "0179", + "0170", + "000B" + ], + "Actors": [ + "005E 0595 FF11 FBD7 0000 0000 0000 2400", + "0069 054B FEDD F887 0000 0000 0000 FFFE", + "0069 0678 FEDD F9CE 0000 0000 0000 FFFE", + "0069 0579 FECC FA97 0000 0000 0000 FFFE", + "012A 05E3 FFAF F781 0000 0000 0000 0001", + "012D 041A FFB1 FA10 0000 0000 0000 00C1", + "0117 05D4 FF2A F9EA 0000 0000 0000 018C", + "0117 0618 FF11 F8BB 0000 0000 0000 1FCC", + "0117 046E FF11 F8CF 0000 0000 0000 1FCC", + "0117 057C FF11 F98B 0000 0000 0000 1FCC", + "0117 0618 FF11 FA9C 0000 0000 0000 1FCC", + "0117 043B FF11 FAA2 0000 0000 0000 1FCC", + "0117 0525 FF11 FB25 0000 0000 0000 1FCC", + "012D 0536 FE7B F8B8 0000 0000 0000 0CC1", + "012D 04D1 FE7B F98B 0000 0000 0000 0CC1", + "012D 0641 FE7A F99C 0000 0000 0000 0CC1", + "005E 071D FF10 FA19 0000 0000 0000 107F", + "0049 0619 FF11 F8BE 0000 0000 0000 207F", + "0049 046F FF11 F8CE 0000 0000 0000 207F", + "0049 057E FF11 F98A 0000 0000 0000 207F", + "0049 0619 FF11 FA9C 0000 0000 0000 207F", + "0049 043D FF11 FAA6 0000 0000 0000 207F", + "0049 0523 FF11 FB23 0000 0000 0000 207F" + ] + }, + { + "File": { + "Name": "Scene 11, Room 7", + "Start": "028C7000", + "End": "028CF330", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "004D", + "000E", + "0090", + "0038", + "000C", + "001B" + ], + "Actors": [ + "0025 058E FFB9 FEC6 0000 D8E4 0000 FFFE", + "0025 0644 FFBB FF7C 0000 CFA5 0000 FFFE", + "0025 04CC FFB0 FF3A 0000 CC17 0000 FFFF", + "0012 063F FFB0 FE7C 0000 BE94 0000 FFFF", + "0012 060E FFB0 0023 0000 B555 0000 FFFF", + "0054 04A7 FFEC 0061 0000 6000 0000 FFFF", + "000A 05C9 0078 FF45 0000 8000 001E 8841", + "0187 0611 FFC5 FF55 0000 0000 0000 783C", + "0112 05C9 0070 FDD0 0000 0000 0001 1AE7" + ] + }, + { + "File": { + "Name": "Scene 11, Room 8", + "Start": "028D0000", + "End": "028D8210", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "004D", + "002B", + "005D", + "011C", + "00A4", + "000E", + "0179", + "0170", + "000B" + ], + "Actors": [ + "01CD FEE9 0078 FB64 0000 0000 0000 0001", + "01A0 FFC5 FFB0 F9C2 0000 0000 0000 FFFF", + "0008 0038 00EF F8E9 0000 0000 0000 03F8", + "0008 FF56 00EF F8E9 0000 0000 0000 03F8", + "005E FF63 00C8 FB63 0000 0000 0000 2400", + "005E 0026 00C8 FB63 0000 0000 0000 2400", + "012A FFC4 FFB0 F9C2 0000 0000 0000 0101", + "0112 01F4 FFB0 FAD5 0000 8000 0000 3FC2", + "000A 003A 00F0 F88B 0000 0000 0001 BB24", + "000A 00B6 FFB0 FA11 0000 C000 0000 5885", + "000A FD7F FFB0 F9FE 0000 8000 0000 5986", + "000A 0153 FFB0 F971 0000 0000 0000 5E48", + "000A FED5 FFB0 F82F 0000 C000 0000 5E49", + "000A FE48 FFB0 F81C 0000 8000 0000 59CA", + "000A FFEB 00C9 FB29 0000 4000 0000 5AAB" + ] + }, + { + "File": { + "Name": "Scene 11, Room 9", + "Start": "028D9000", + "End": "028DC8F0", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "004D", + "000E", + "0090", + "00B5", + "0021", + "0059", + "013B", + "011C", + "0026", + "0036", + "0056", + "000B" + ], + "Actors": [ + "018C 08E5 FE47 FA7C 0000 2CCD 0000 0000", + "018C 091A FEA8 FA32 0000 EFA5 0000 0000", + "00D4 0901 FDD5 FA4D 0000 0000 0000 00FF", + "0063 0900 FFD9 FA47 0000 0000 0000 FFFF", + "00C5 08D0 FC40 FA1C 0000 20B6 0000 FFFF", + "012D 0903 FD64 F95A 0000 0000 0000 FFC2", + "012D 09EF FD61 FA46 0000 C000 0000 FFC2", + "012D 0811 FD61 FA48 0000 4000 0000 FFC2", + "012D 0903 FD61 FB38 0000 8000 0000 FFC2", + "000A 0887 FF94 F9D0 0000 C000 001B 884D", + "0117 083D FF66 F9E8 0000 0000 0000 00DB", + "0117 0995 FC86 F9B4 0000 0000 0000 1FDB", + "0117 08FE FCE3 FA48 0000 0000 0000 1FDB", + "0117 0870 FC7C FADD 0000 0000 0000 1FDB", + "000F 08FC FF0B FA47 0000 0000 0000 0FF9" + ] + }, + { + "File": { + "Name": "Scene 11, Room 10", + "Start": "028DD000", + "End": "028E2C60", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "004D", + "000E", + "0090", + "00E5", + "0114" + ], + "Actors": [ + "0121 F9C3 009F F05F 0000 0000 0000 0000", + "0121 F978 00D2 F046 0000 0C17 0000 0000", + "00EC FA3D 008B F099 0000 0000 0000 0000", + "00EC F97A 008B F107 0000 0000 0000 0000", + "00EC FA29 008B F191 0000 0000 0000 0000", + "000A F979 00D2 F043 0000 93E9 0000 7AA2" + ] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [], + "PolyTypes": [], + "Cams": [ + { + "Data": 1572867, + "PositionIndex": 0 + }, + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [], + "Minimaps": [] + }, + { + "File": { + "Name": "Scene 13", + "Start": "0318E000", + "End": "031AF7C0", + "RemapStart": null + }, + "Id": 13, + "TActors": [ + "10FF 01FF 0023 0000 FF10 012A 8000 003F", + "0BFF 0AFF 0023 F1C9 FF2E FCB8 4000 003F", + "01FF 00FF 002E 0000 0096 0251 0000 007F", + "09FF 09FF 002E F881 FF10 FCB8 4000 007F", + "03FF 02FF 002E 0930 FF06 FCB8 C000 02D6", + "0AFF 08FF 002E F499 FF10 FCB8 4000 02D4", + "06FF 05FF 002E 0487 006E 048F 9555 007F", + "07FF 06FF 002E 06F3 006E 08C1 9555 00B8", + "01FF 05FF 002E 0268 0096 00E3 1555 003F", + "02FF 01FF 002E 04D0 FF10 FCB8 C000 003F", + "01FF 09FF 002E FAD9 FF10 FCB8 C000 003F", + "01FF 0EFF 002E FD98 0096 F88D 9555 003F", + "0CFF 01FF 002E 0268 0096 F88D EAAB 003F", + "04FF 03FF 002E 0DA4 FF10 FCB8 C000 0082", + "0DFF 0CFF 002E 0844 00D2 EE67 EAAB 008B", + "0FFF 0EFF 002E F860 0099 F0EB 1555 0081", + "01FF 11FF 002E FD98 0096 00E3 EAAB 003F", + "12FF 11FF 002E FB1B 0096 02B3 2AAB 008F", + "13FF 12FF 002E FAF0 0096 057D 6AAB 008E", + "08FF 09FF 002E F72F FF10 FCB8 4000 02D5", + "12FF 12FF 002E F993 0096 02B2 6AAB 0088" + ], + "Paths": [ + { + "Points": [ + [ + -27, + 190, + 1079 + ], + [ + -27, + 302, + 1376 + ], + [ + -27, + 412, + 1771 + ], + [ + -27, + 311, + 1374 + ], + [ + -27, + 197, + 1091 + ] + ] + }, + { + "Points": [ + [ + 34, + 242, + 1079 + ], + [ + 34, + 280, + 1246 + ], + [ + 34, + 338, + 1504 + ], + [ + 33, + 366, + 1777 + ], + [ + 35, + 335, + 1504 + ], + [ + 33, + 307, + 1373 + ], + [ + 34, + 287, + 1246 + ], + [ + 34, + 242, + 1094 + ] + ] + }, + { + "Points": [ + [ + -2603, + -270, + -1010 + ], + [ + -2558, + -270, + -994 + ], + [ + -2521, + -270, + -964 + ], + [ + -2493, + -270, + -930 + ], + [ + -2476, + -270, + -887 + ], + [ + -2469, + -270, + -843 + ], + [ + -2472, + -270, + -796 + ], + [ + -2489, + -270, + -754 + ], + [ + -2518, + -270, + -716 + ], + [ + -2555, + -270, + -687 + ], + [ + -2600, + -270, + -666 + ], + [ + -2647, + -270, + -661 + ], + [ + -2694, + -270, + -666 + ], + [ + -2738, + -270, + -683 + ], + [ + -2775, + -270, + -711 + ], + [ + -2802, + -270, + -746 + ], + [ + -2820, + -270, + -792 + ], + [ + -2827, + -270, + -839 + ], + [ + -2820, + -270, + -886 + ], + [ + -2801, + -270, + -931 + ], + [ + -2774, + -270, + -967 + ], + [ + -2737, + -270, + -995 + ], + [ + -2694, + -270, + -1009 + ], + [ + -2647, + -270, + -1014 + ], + [ + -2603, + -270, + -1010 + ] + ] + }, + { + "Points": [ + [ + 860, + 247, + -2283 + ], + [ + 920, + 182, + -2242 + ], + [ + 914, + 84, + -2241 + ], + [ + 860, + 54, + -2274 + ], + [ + 806, + 94, + -2310 + ], + [ + 803, + 185, + -2313 + ], + [ + 860, + 235, + -2284 + ] + ] + }, + { + "Points": [ + [ + -1513, + 176, + 569 + ], + [ + -1511, + 268, + 571 + ] + ] + }, + { + "Points": [ + [ + -1684, + 283, + 854 + ], + [ + -1682, + 194, + 856 + ] + ] + } + ], + "Rooms": [ + { + "File": { + "Name": "Scene 13, Room 0", + "Start": "031B0000", + "End": "031B91C0", + "RemapStart": null + }, + "Id": 0, + "Objects": [ + "0179", + "005D", + "0106", + "0038", + "0085", + "00A4" + ], + "Actors": [ + "0054 FF91 00D2 0318 0000 0000 0000 FFFF", + "0054 006D 00D2 0318 0000 0000 0000 FFFF", + "0113 0003 0096 02B2 0000 0000 0000 FF02", + "0008 005A 0173 073E 0000 0000 0000 03F5", + "0008 FFA5 0118 05AD 0000 0000 0000 03F5", + "0008 FFA7 0173 073D 0000 0000 0000 03F5", + "0008 005A 0118 05AE 0000 0000 0000 03F5", + "005E FF66 010E 027A 0000 0000 0000 2400", + "005E 0095 010E 0278 0000 0000 0000 2400", + "0069 FFE5 00BE 0437 0000 0000 0000 00FB", + "0069 0022 00F2 0436 0000 0000 0000 11FB", + "0080 0046 0096 0319 0000 C000 0000 0310" + ] + }, + { + "File": { + "Name": "Scene 13, Room 1", + "Start": "031BA000", + "End": "031D69B0", + "RemapStart": null + }, + "Id": 1, + "Objects": [ + "0179", + "000E", + "009A", + "0168", + "004A" + ], + "Actors": [ + "01B6 0000 FF10 0062 0000 8000 0000 0002", + "01A7 0000 FF10 FCB8 0000 0000 0000 0000", + "0097 0000 FF10 FCB8 0000 0000 0000 0005", + "0092 FB44 FF10 FCB8 0000 4000 0000 0401", + "0112 FDA3 0096 00AE 0000 0000 0000 3FF7", + "0112 FDC2 0096 00B9 0000 0000 0000 3FF7" + ] + }, + { + "File": { + "Name": "Scene 13, Room 2", + "Start": "031D7000", + "End": "031DE7E0", + "RemapStart": null + }, + "Id": 2, + "Objects": [ + "0179", + "006B", + "000E", + "0085", + "00E5", + "013A", + "00A6", + "0114", + "00B7" + ], + "Actors": [ + "00A5 07A7 FF06 FDDF 0000 982E 0000 FFFF", + "0121 0714 FF06 FD69 0000 8666 0000 FFFF", + "0121 0766 FF06 FCBA 0000 DA50 0000 FFFF", + "0121 078C FF06 FBAE 0000 F8E4 0000 FFFF", + "01C7 07C0 FF06 FDC9 0000 0000 0000 0000", + "01C7 0790 FF06 FDD9 0000 0000 0000 0000", + "01C7 077C FF06 FE01 0000 0000 0000 0000", + "01C7 07FC FF06 FDB1 0000 0000 0000 0000", + "01C7 07A8 FF06 FB9D 0000 0000 0000 0000", + "01C7 07D8 FF06 FBA5 0000 0000 0000 0000", + "01C7 074C FF06 FB69 0000 0000 0000 0000", + "01C7 0774 FF06 FB81 0000 0000 0000 0000", + "01C7 0806 003C FD65 0000 0000 0000 0002", + "01C7 0791 003C FD6E 0000 0000 0000 0002", + "01C7 0748 003C FDC8 0000 0000 0000 0002", + "01C7 07D2 003C FBD4 0000 0000 0000 0002", + "01C7 0762 003C FBD4 0000 0000 0000 0002", + "01C7 06FF 003C FB8B 0000 0000 0000 0002", + "00F0 06C4 FF24 FCB8 0000 0000 0000 FFFF", + "00EF 06DA FF06 FB80 0000 0000 0000 00FF", + "00EF 06CF FF06 FDEF 0000 0000 0000 00FF", + "00EF 0830 FF06 FC0D 0000 0000 0000 00FF", + "000A 06D9 FF06 FB81 0000 8E39 0000 59C1", + "00EF 08A1 FF13 FC87 0000 0000 0000 000D", + "00EF 0896 FF0E FCB3 0000 0000 0000 000D", + "00EF 0892 FF12 FCE3 0000 0000 0000 000D", + "00EF 0898 FF15 FD0D 0000 0000 0000 000D", + "012A 07B5 FF06 FDF9 0000 0000 0000 3C03", + "015F 06C6 FF06 FCB7 0004 0006 0005 1F0B", + "0015 06CF FF06 FDF0 0000 0000 0000 3F03" + ] + }, + { + "File": { + "Name": "Scene 13, Room 3", + "Start": "031DF000", + "End": "031E8990", + "RemapStart": null + }, + "Id": 3, + "Objects": [ + "0179", + "006B", + "0114", + "000D", + "000E", + "0090" + ], + "Actors": [ + "0013 0B4C FFDE FD6D 0000 2889 0000 0004", + "01B7 0BD8 FEC0 FC7C 0000 4000 0000 0000", + "01B7 0AE8 FEC0 FC04 0000 4000 0000 0000", + "0013 0B01 FEE0 FDB3 0000 84FA 0000 0003", + "0013 0B9F FEE2 FD4C 0000 C38E 0000 8003", + "0013 0BC3 FFA1 FBFA 0000 25B0 0000 0000", + "00EF 0B5A FF88 FA36 0000 0000 0000 00FF", + "0117 0AC5 FE5C FD03 0000 0000 0000 1142", + "0117 0B60 FF25 FC35 0000 0000 0000 1142", + "0117 0B59 FF88 FA3A 0000 0000 0000 1142", + "0117 0CB5 FEC6 FD77 0000 0000 0000 1142", + "0117 0B59 FEC0 FB11 0000 0000 0000 1142", + "0117 0A16 FEC0 FCDE 0000 0000 0000 0142", + "00EF 0D2A FF10 FC4A 0000 C000 0000 0006", + "00EF 0D2A FF10 FC87 0000 C000 0000 0006", + "00EF 0D2A FF10 FCBE 0000 C000 0000 0006", + "00EF 0D2A FF10 FCF8 0000 C000 0000 0006", + "00EF 0D2A FF10 FD27 0000 C000 0000 0006" + ] + }, + { + "File": { + "Name": "Scene 13, Room 4", + "Start": "031E9000", + "End": "031F0C90", + "RemapStart": null + }, + "Id": 4, + "Objects": [ + "0179", + "006B", + "00ED", + "00CA", + "00BA", + "0075" + ], + "Actors": [ + "01A7 0F7A FF2E FCB8 0000 C000 0000 0001", + "00D2 0F7A FFA6 FCB8 2000 C000 0000 0002", + "0008 0F08 FF3B FD2C 0000 0000 0000 03FE", + "0008 0F09 FF3B FC4B 0000 0000 0000 03FE", + "0111 0DD8 FF10 FC5D 0000 0000 0000 7203", + "0111 0DD5 FF10 FD0D 0000 0000 0000 7409" + ] + }, + { + "File": { + "Name": "Scene 13, Room 5", + "Start": "031F1000", + "End": "031F8540", + "RemapStart": null + }, + "Id": 5, + "Objects": [ + "0179", + "00AA", + "0069", + "0032", + "00A4" + ], + "Actors": [ + "005E 0435 0136 0493 0000 9555 0000 2400", + "0002 03FA 006E 0277 0000 BA50 0000 FFFF", + "0002 02F5 006E 0318 0000 3777 0000 FFFF", + "00BC 0476 015E 0470 0000 9555 0000 0004", + "0015 04B2 0136 044C 0000 0000 0000 0111" + ] + }, + { + "File": { + "Name": "Scene 13, Room 6", + "Start": "031F9000", + "End": "03208BF0", + "RemapStart": null + }, + "Id": 6, + "Objects": [ + "0179", + "0069", + "011C", + "0190", + "00A8", + "0038", + "008B", + "000E", + "0090" + ], + "Actors": [ + "012D 0508 001E 0755 0000 1555 0000 FFC2", + "0054 0666 0032 05D1 0000 D555 0000 FFFF", + "01B4 058F FFB9 084C 0000 1555 0000 FF01", + "0054 058F 015E 084C 0000 1555 0000 0000", + "00BC 0783 00AB 082C 0000 9555 0000 0004", + "00BC 0629 009F 08F4 0000 9555 0000 0004", + "00BC 0550 00A4 045C 0000 1555 0000 0004", + "00BC 03F6 00A4 0524 0000 1555 0000 0004", + "008A 04DF 0032 06ED 0000 1555 0000 0500", + "008A 0718 FFCE 0777 0000 4000 0000 0500", + "008A 064F 0032 0616 0000 0000 0000 0501", + "008A 05F6 0032 070B 0000 2AAB 0000 0501", + "008A 0669 001E 07DB 0000 5555 0000 0501", + "008A 0601 0076 08AB 0000 6AAB 0000 0501", + "000A 04DB 00DC 04B6 0000 5555 0005 8942", + "000A 0699 0096 0627 0000 5555 0007 8023", + "012A 03E5 0097 0505 0000 1555 0000 0502", + "012A 0796 0097 084D 0000 9555 0000 0782", + "012A 058F FFB9 084C 0000 1555 0000 3820", + "01D6 058F 0097 084C 0000 1555 0000 183A", + "01D6 058F 00FA 084C 0000 1555 0000 983A" + ] + }, + { + "File": { + "Name": "Scene 13, Room 7", + "Start": "03209000", + "End": "03210C90", + "RemapStart": null + }, + "Id": 7, + "Objects": [ + "0179", + "0069", + "00ED", + "00BA", + "00BC", + "0075" + ], + "Actors": [ + "01A7 07DE 008C 0A58 0000 9555 0000 0006", + "00C9 07DE 0104 0A5E 2000 9555 0000 0002", + "0008 0807 0096 09C0 0000 0000 0000 03FB", + "0008 0743 0096 0A32 0000 0000 0000 03FB", + "0111 0751 006E 08CC 0000 0000 0000 6A03", + "0111 06BE 006E 0916 0000 0000 0000 6C0F" + ] + }, + { + "File": { + "Name": "Scene 13, Room 8", + "Start": "03211000", + "End": "0321A070", + "RemapStart": null + }, + "Id": 8, + "Objects": [ + "0179", + "002C", + "008B", + "011C", + "00B7", + "011F" + ], + "Actors": [ + "012D F5AC 0028 FCB9 4000 0000 0000 FFC2", + "000C F623 FEF2 FC38 0000 1C72 0000 00FF", + "000C F621 FEF2 FD2F 0000 638E 0000 00FF", + "008A F5AB FF88 FCB9 0000 8000 0000 0501", + "0130 F57A FEF2 FC0E 0000 51C7 0000 0C02", + "0015 F5A1 FF10 FDDB 0000 0000 0000 3D03", + "0015 F636 FF10 FBB8 0000 0000 0000 3E03" + ] + }, + { + "File": { + "Name": "Scene 13, Room 9", + "Start": "0321B000", + "End": "03226890", + "RemapStart": null + }, + "Id": 9, + "Objects": [ + "0179", + "000E", + "0090", + "001B", + "0025" + ], + "Actors": [ + "0008 F7F9 FF5A FC30 0000 0000 0000 83F0", + "0008 F810 FF5A FC30 0000 0000 0000 83F0", + "0008 F805 FF5A FC3B 0000 0000 0000 83F0", + "0008 F7AC FF5B FC3B 0000 0000 0000 83F0", + "0008 F7B7 FF5B FC30 0000 0000 0000 83F0", + "0008 F7A1 FF5B FC30 0000 0000 0000 83F0", + "0038 F90F FF10 FC28 0000 2B61 0000 FFFF", + "0038 F9EE FF10 FD66 0000 CFA5 0000 FFFF", + "0025 F957 FF10 FD30 0000 4C17 0000 FFFE", + "000A F7D5 FF7E FC40 0000 8000 0011 8904", + "012E F77D FF14 FCB6 0000 4000 0001 1C91", + "0112 F74B FF10 FCBB 0000 0000 0000 3FF6" + ] + }, + { + "File": { + "Name": "Scene 13, Room 10", + "Start": "03227000", + "End": "0322DB70", + "RemapStart": null + }, + "Id": 10, + "Objects": [ + "0179", + "001B", + "00ED", + "00BA", + "00A7", + "0075", + "0024" + ], + "Actors": [ + "01B6 F269 FF2E FCB8 0000 4000 0000 0000", + "0008 F334 FF38 FD28 0000 0000 0000 03FA", + "0008 F333 FF38 FC47 0000 0000 0000 03FA", + "0095 F334 FF3C FD3E 0000 0000 0000 0000", + "01B4 F25E FF60 FCE7 4000 4000 0000 3601", + "01B4 F25E FF60 FC83 4000 4000 0000 3601", + "01B4 F25E FFC4 FCE7 4000 4000 0000 3601", + "01B4 F25E FFC4 FC83 4000 4000 0000 3601", + "012A F333 FF18 FC48 0000 0000 0000 3613" + ] + }, + { + "File": { + "Name": "Scene 13, Room 11", + "Start": "0322E000", + "End": "03234950", + "RemapStart": null + }, + "Id": 11, + "Objects": [ + "0179", + "001B", + "00ED", + "00BA", + "00A7", + "0075", + "0024" + ], + "Actors": [ + "01A7 EFCB FF4C FCB8 0000 4000 0000 0002", + "00A6 EFCC FFC4 FCB9 2000 4000 0000 0002", + "0008 F03E FF56 FC4C 0000 0000 0000 03FA", + "0008 F03B FF56 FD29 0000 0000 0000 03FA", + "0111 F0FE FF2E FD09 0000 0000 0000 760E", + "0111 F0FB FF2E FC5B 0000 0000 0000 7803" + ] + }, + { + "File": { + "Name": "Scene 13, Room 12", + "Start": "03235000", + "End": "03240370", + "RemapStart": null + }, + "Id": 12, + "Objects": [ + "0179", + "000E", + "0090", + "0069", + "0031", + "005D", + "008B", + "00A4" + ], + "Actors": [ + "01B4 0624 0096 F125 0000 EAAB 0000 0000", + "005E 0232 0096 F806 0000 1555 0000 2400", + "004C 0512 0096 F728 0000 0000 0000 FFFF", + "00BC 072C 00FC F03A 0000 0889 0000 0000", + "00AF 0500 0096 F57C 0000 2AAB 0000 0000", + "0069 035C 00E8 F716 0000 0000 0000 33FB", + "008A 05FA 0096 EFEA 0000 0000 0000 0500", + "008A 04FE 0096 F3DA 0000 EAAB 0000 0501", + "008A 0632 0096 F19C 0000 0000 0000 0501", + "008A 067F 0096 F1BB 0000 8000 0000 0501", + "000A 0213 00FA F62A 0000 AAAB 0009 8940", + "000A 06DD 01CE F1F5 0000 6AAB 000C 8845", + "0112 0511 0096 F727 0000 0000 0003 1809", + "0117 052A 0096 F72A 0000 0000 0000 1FCB", + "0117 04FF 0096 F3D9 0000 0000 0000 1FCB", + "0117 05F9 0096 EFEB 0000 0000 0000 1FCB", + "0117 0725 0098 F019 0000 0000 0000 1FCB", + "0117 044C 0096 F606 0000 0000 0000 1FCB", + "0117 0281 0096 F827 0000 0000 0000 014B", + "012A 05A3 003F F300 0000 6AAB 0000 0C02", + "01B4 05F6 0096 F27E 0000 EAAB 0000 3D01", + "005E 0505 0064 F354 0000 EAAB 0000 107D" + ] + }, + { + "File": { + "Name": "Scene 13, Room 13", + "Start": "03241000", + "End": "03248D40", + "RemapStart": null + }, + "Id": 13, + "Objects": [ + "0179", + "00F1", + "016D", + "00BA", + "00ED", + "0087", + "0075" + ], + "Actors": [ + "01A7 092F 00F0 ECD0 0000 EAAB 0000 0004", + "00A9 092E 0168 ECD4 2000 EAAB 0000 0002", + "0008 0956 00FA ED6A 0000 0000 0000 03FD", + "0008 0893 00FA ECFD 0000 0000 0000 03FD", + "0111 0819 00D2 EE10 0000 0000 0000 640E", + "0111 08A9 00D2 EE5C 0000 0000 0000 7009" + ] + }, + { + "File": { + "Name": "Scene 13, Room 14", + "Start": "03249000", + "End": "032531A0", + "RemapStart": null + }, + "Id": 14, + "Objects": [ + "0179", + "002C", + "0025", + "005D", + "011C", + "009A", + "008B" + ], + "Actors": [ + "012D F9D5 0098 F495 0000 1555 0000 FFC0", + "0038 FA4C 0097 F652 0000 DC72 0000 FFFF", + "0038 FA20 0097 F6DB 0000 24FA 0000 FFFF", + "0046 FB7C 0014 F244 0000 9555 0000 0001", + "0046 FCE9 0014 F74B 0000 D555 0000 0001", + "0046 F8D6 0014 F644 0000 9555 0000 0001", + "0043 FD53 0014 F47E 0000 1555 0000 FF01", + "0043 FAD1 0014 F550 0000 1555 0000 FF01", + "0043 F96F 0014 F36E 0000 1555 0000 FF01", + "0046 FDE3 0014 F58A 0000 1555 0000 0000", + "0046 FC54 0014 F511 0000 1555 0000 0000", + "0046 FCDE 0014 F607 0000 1555 0000 0000", + "0046 FA80 0014 F2CE 0000 1555 0000 0000", + "0046 F83F 0014 F400 0000 1555 0000 0000", + "0092 FC31 003D F158 0000 1555 0000 FF00", + "0092 FA97 003B F749 0000 9555 0000 FF00", + "008A FC6D 0098 F1C1 0000 0000 0000 0500", + "012D F8ED 0099 F10E 0000 1555 0000 01C1", + "0117 FC36 0098 F15D 0000 0000 0000 1FC1", + "0117 F89D 00DE F53F 0000 0000 0000 1FC1", + "0117 F804 00F4 F2E6 0000 0000 0000 1FC1", + "0117 FD52 0280 F47F 0000 0000 0000 1FC1", + "0117 F989 0078 F7AB 0000 0000 0000 1FC1", + "0117 FD8E 0096 F832 0000 0000 0000 0141" + ] + }, + { + "File": { + "Name": "Scene 13, Room 15", + "Start": "03254000", + "End": "0325BD40", + "RemapStart": null + }, + "Id": 15, + "Objects": [ + "0179", + "002C", + "00BA", + "00ED", + "009D", + "0075" + ], + "Actors": [ + "01A7 F775 00B7 EF54 0000 1555 0000 0003", + "00A8 F775 012F EF58 2000 1555 0000 0002", + "0008 F80F 00C1 EF7B 0000 0000 0000 03FC", + "0008 F74A 00C1 EFEC 0000 0000 0000 03FC", + "0111 F882 0099 F08B 0000 0000 0000 6E03", + "0111 F7FC 0099 F0D0 0000 0000 0000 700F" + ] + }, + { + "File": { + "Name": "Scene 13, Room 16", + "Start": "0325C000", + "End": "0325EE20", + "RemapStart": null + }, + "Id": 16, + "Objects": [ + "0179", + "000E", + "009A", + "0168", + "004A" + ], + "Actors": [ + "0195 FF3F FF10 02B6 0000 349F 0000 0000", + "0195 005C FF10 03C9 0000 9555 0000 0005", + "0195 FF43 FF10 0361 0000 5555 0000 0007", + "0195 FFAC FF10 03CA 0000 6AAB 0000 0006", + "0195 00D2 FF10 0366 0000 AAAB 0000 0008", + "0018 FFFF FF72 02F9 0000 0000 0000 0004" + ] + }, + { + "File": { + "Name": "Scene 13, Room 17", + "Start": "0325F000", + "End": "032676A0", + "RemapStart": null + }, + "Id": 17, + "Objects": [ + "0179", + "016C", + "0106", + "0025", + "000D" + ], + "Actors": [ + "0008 FD5C 0100 039A 00B6 AAAB 0000 83F0", + "0008 FD67 00FF 0386 0000 AB61 0000 83F0", + "0008 FD58 00FF 038A FF4A AAAB 0000 83F0", + "0008 FE24 0100 023F FF4A AAAB 0000 83F0", + "0008 FE2F 00FF 022C 00B6 AAAB 0000 83F0", + "0008 FE20 00FF 0230 0000 AB61 0000 83F0", + "0008 FC25 00FF 0118 0000 2B61 0000 83F0", + "0008 FC30 00FF 0104 00B6 2AAB 0000 83F0", + "0008 FC34 00FF 0114 0000 2B61 0000 83F0", + "0038 FC68 0096 01BF 0000 0000 0000 FFFF", + "0013 FD83 0124 0214 0000 CCCD 0000 0000", + "0013 FC21 010F 02C8 0000 9A50 0000 0000", + "0113 FC4F 019B 0336 0000 6AAB 0000 FF03", + "0169 FCEB 0096 0244 0000 0AAB 0000 0001", + "0169 FCB9 0096 0227 0000 4E39 0000 0001", + "0169 FCCD 0096 0274 0000 CAAB 0000 0001", + "0169 FC9D 0096 0258 0000 8AAB 0000 0001", + "012A FCC2 0096 024C 0000 1555 0000 0F01", + "01B4 FC50 019A 0337 0000 0000 0000 3701", + "012A FD8E 0141 00F4 0000 EAAB 0000 3712" + ] + }, + { + "File": { + "Name": "Scene 13, Room 18", + "Start": "03268000", + "End": "03274670", + "RemapStart": null + }, + "Id": 18, + "Objects": [ + "0179", + "012A", + "00AB", + "000E", + "0090", + "00A4", + "0163", + "000B", + "000E", + "0090", + "0098", + "005D" + ], + "Actors": [ + "0008 F8FA 00D7 0363 0000 2B61 0000 83F0", + "0008 F8F5 00D7 0354 FF4A 2AAB 0000 83F0", + "0008 F8EA 00D7 0367 0000 2B61 0000 83F0", + "0008 F9E0 00D7 01D5 FF4A 2AAB 0000 83F0", + "0008 F9DB 00D7 01C5 00B6 2AAB 0000 83F0", + "0008 F9D0 00D7 01D9 FF4A 2AAB 0000 83F0", + "0090 FA6B 0096 0415 0000 AAAB 0000 7FFE", + "0090 FBBE 0096 041D 0000 EAAB 0000 7F02", + "0090 FB65 0096 04AA 0000 CD83 0000 7F01", + "0069 FA17 00BE 0237 0000 3333 0000 42FB", + "0069 F96D 010E 0356 0000 693F 0000 52FB", + "000A FABA 0096 04DC 0000 C71C 003C B6C6", + "000A FB96 00FA 0564 0000 0AAB 003E 8907", + "012A F9D0 0172 034F 8000 0000 0000 0803", + "000A FC0D 00FA 047F 0000 4AAB 003D 8848", + "000A FB35 00FA 0400 0000 8AAB 0038 8909", + "01B5 FB69 01C1 04AC 0000 2AAB 0000 0A01", + "01B5 FB69 0096 04AC 0000 2AAB 0000 0A02", + "01B5 FB69 0186 04AC 0000 2AAB 0000 0A00", + "000A F9CE 0096 021F 0000 AAAB 0000 506A", + "0150 FAF8 0145 056E 0000 6AAB 0000 0E00", + "000A F901 0096 037E 0000 AAAB 0000 6954", + "0112 FAFC 0096 029F 0000 0000 0000 3FF7", + "0150 FB33 0136 03E9 0000 0AAB 0000 3830", + "0011 FB4F 0096 04D5 0000 0000 0000 3902", + "0150 FABA 0154 0447 0000 2AAB 0000 3930", + "0150 FBCF 010E 03FE 0000 EAAB 0000 3A30", + "0150 FC1A 010E 050D 0000 AAAB 0000 3B30", + "0150 FA9F 0136 04E2 0000 47D2 0000 3C30", + "0150 FC2A 0136 0475 0000 CAAB 0000 3D30", + "0150 FBA5 0136 0578 0000 8E39 0000 3E30" + ] + }, + { + "File": { + "Name": "Scene 13, Room 19", + "Start": "03275000", + "End": "0327CD40", + "RemapStart": null + }, + "Id": 19, + "Objects": [ + "0179", + "0072", + "0073", + "00BA", + "00ED", + "00B3", + "0075" + ], + "Actors": [ + "01A7 FA05 00B4 0714 0000 6AAB 0000 0005", + "00C3 FA05 012C 0714 2000 6AAB 0000 0002", + "0008 FA9E 00C1 06F1 0000 0000 0000 03F9", + "0008 F9DA 00C1 067E 0000 0000 0000 03F9", + "0111 FA86 0096 0586 0000 0000 0000 660C", + "0111 FB18 0096 05DC 0000 0000 0000 680F" + ] + } + ], + "ColDelta": { + "IsLarger": false, + "Polys": [ + { + "Id": 2403, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2404, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2405, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2406, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2407, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2408, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2409, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2410, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2473, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2474, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2475, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2476, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2477, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2478, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2479, + "Type": 57, + "Flags": 4 + }, + { + "Id": 2480, + "Type": 57, + "Flags": 4 + } + ], + "PolyTypes": [], + "Cams": [ + { + "Data": 1572867, + "PositionIndex": 0 + }, + { + "Data": 1572867, + "PositionIndex": 1 + }, + { + "Data": 1572867, + "PositionIndex": 2 + }, + { + "Data": 1572867, + "PositionIndex": 3 + }, + { + "Data": 0, + "PositionIndex": -1 + }, + { + "Data": 196608, + "PositionIndex": -1 + }, + { + "Data": 262144, + "PositionIndex": -1 + }, + { + "Data": 65536, + "PositionIndex": -1 + }, + { + "Data": 4063232, + "PositionIndex": -1 + }, + { + "Data": 3801088, + "PositionIndex": -1 + } + ] + }, + "Floormaps": [], + "Minimaps": [] + } +] \ No newline at end of file diff --git a/data/rom_patch.txt b/data/rom_patch.txt new file mode 100644 index 000000000..ec8353bd9 --- /dev/null +++ b/data/rom_patch.txt @@ -0,0 +1,13185 @@ +11,45 +12,ae +13,5b +14,97 +15,db +16,41 +17,31 +d261,48 +d262,0 +d265,48 +d266,50 +d267,0 +d269,48 +d26a,0 +d271,4b +d272,30 +d275,4b +d276,e0 +d277,0 +d279,4b +d27a,30 +89e813,0 +89e814,0 +89e81e,0 +89e81f,0 +89e850,0 +89e851,0 +89e852,0 +89e853,0 +89e854,0 +89e855,0 +89e858,0 +89e859,0 +89e85d,0 +89e85e,0 +89e85f,0 +89e86b,0 +89e86c,0 +89e86d,0 +89e86e,0 +89e86f,0 +89e870,0 +89e871,0 +89e890,0 +89e891,0 +89e892,0 +89e893,0 +89e894,0 +89e895,0 +89e897,0 +89e898,0 +89e899,0 +89e89a,0 +89e89d,0 +89e89e,0 +89e89f,0 +89e8a0,0 +89e8a5,0 +89e8a6,0 +89e8aa,0 +89e8ab,0 +89e8ac,0 +89e8ad,0 +89e8ae,0 +89e8af,0 +89e8b0,0 +89e8b1,0 +89e8d0,0 +89e8d1,0 +89e8d2,0 +89e8d3,0 +89e8d4,0 +89e8d5,0 +89e8d7,0 +89e8d8,0 +89e8d9,0 +89e8da,0 +89e8db,0 +89e8dc,0 +89e8dd,0 +89e8de,0 +89e8df,0 +89e8e0,0 +89e8e1,0 +89e8e2,0 +89e8e3,0 +89e8e4,0 +89e8e5,0 +89e8e6,0 +89e8e7,0 +89e8ea,0 +89e8eb,0 +89e8ec,0 +89e8ed,0 +89e8ee,0 +89e8ef,0 +89e8f0,0 +89e8f1,0 +89e90f,0 +89e910,0 +89e911,0 +89e912,0 +89e913,0 +89e914,0 +89e915,0 +89e916,0 +89e917,0 +89e918,0 +89e919,0 +89e91a,0 +89e91b,0 +89e91c,0 +89e91d,0 +89e91e,0 +89e91f,0 +89e920,0 +89e921,0 +89e922,0 +89e923,0 +89e924,0 +89e925,0 +89e926,0 +89e927,0 +89e928,0 +89e92a,0 +89e92b,0 +89e92c,0 +89e92d,0 +89e92e,0 +89e92f,0 +89e930,0 +89e931,0 +89e94f,0 +89e950,0 +89e951,0 +89e952,0 +89e953,0 +89e954,0 +89e955,0 +89e956,0 +89e957,0 +89e958,0 +89e959,0 +89e95a,0 +89e95b,0 +89e95c,0 +89e95d,0 +89e95e,0 +89e95f,0 +89e960,0 +89e961,0 +89e962,0 +89e963,0 +89e964,0 +89e965,0 +89e966,0 +89e967,0 +89e968,0 +89e969,0 +89e96a,0 +89e96b,0 +89e96c,0 +89e96d,0 +89e96e,0 +89e96f,0 +89e970,0 +89e971,0 +89e98e,0 +89e98f,0 +89e990,0 +89e991,0 +89e992,0 +89e993,0 +89e994,0 +89e995,0 +89e996,0 +89e997,0 +89e998,0 +89e999,0 +89e99a,0 +89e99b,0 +89e99c,0 +89e99d,0 +89e99e,0 +89e99f,0 +89e9a0,0 +89e9a1,0 +89e9a2,0 +89e9a3,0 +89e9a4,0 +89e9a5,0 +89e9a6,0 +89e9a7,0 +89e9a8,0 +89e9a9,0 +89e9aa,0 +89e9ab,0 +89e9ac,0 +89e9ad,0 +89e9ae,0 +89e9af,0 +89e9b0,0 +89e9b1,0 +89e9ce,0 +89e9cf,0 +89e9d0,0 +89e9d1,0 +89e9d2,0 +89e9d3,0 +89e9d4,0 +89e9d5,0 +89e9d6,0 +89e9d7,0 +89e9d8,0 +89e9dc,0 +89e9dd,0 +89e9de,0 +89e9df,0 +89e9e0,0 +89e9e1,0 +89e9e3,0 +89e9e4,0 +89e9e5,0 +89e9e6,0 +89e9e7,0 +89e9e8,0 +89e9e9,0 +89e9ea,0 +89e9eb,0 +89e9ec,0 +89e9ed,0 +89e9ee,0 +89e9ef,0 +89e9f0,0 +89e9f1,0 +89ea0e,0 +89ea0f,0 +89ea10,0 +89ea11,0 +89ea12,0 +89ea13,0 +89ea14,0 +89ea15,0 +89ea16,0 +89ea17,0 +89ea18,0 +89ea1c,0 +89ea1d,0 +89ea1e,0 +89ea1f,0 +89ea20,0 +89ea21,0 +89ea23,0 +89ea24,0 +89ea25,0 +89ea26,0 +89ea27,0 +89ea28,0 +89ea29,0 +89ea2a,0 +89ea2b,0 +89ea2c,0 +89ea2d,0 +89ea2e,0 +89ea2f,0 +89ea30,0 +89ea31,0 +89ea4e,0 +89ea4f,0 +89ea50,0 +89ea51,0 +89ea52,0 +89ea53,0 +89ea54,0 +89ea55,0 +89ea56,0 +89ea57,0 +89ea58,0 +89ea5c,0 +89ea5d,0 +89ea5e,0 +89ea5f,0 +89ea60,0 +89ea61,0 +89ea63,0 +89ea64,0 +89ea65,0 +89ea66,0 +89ea67,0 +89ea68,0 +89ea69,0 +89ea6a,0 +89ea6b,0 +89ea6c,0 +89ea6d,0 +89ea6e,0 +89ea6f,0 +89ea70,0 +89ea71,0 +89ea8f,0 +89ea90,0 +89ea91,0 +89ea92,0 +89ea93,0 +89ea94,0 +89ea95,0 +89ea96,0 +89ea97,0 +89ea98,0 +89ea99,0 +89ea9a,0 +89ea9b,0 +89ea9c,0 +89ea9d,0 +89ea9e,0 +89ea9f,0 +89eaa0,0 +89eaa1,0 +89eaa2,0 +89eaa3,0 +89eaa4,0 +89eaa5,0 +89eaa6,0 +89eaa7,0 +89eaa8,0 +89eaa9,0 +89eaaa,0 +89eaab,0 +89eaac,0 +89eaad,0 +89eaae,0 +89eaaf,0 +89eab0,0 +89eab1,0 +89eace,0 +89eacf,0 +89ead0,0 +89ead1,0 +89ead2,0 +89ead3,0 +89ead6,0 +89ead7,0 +89ead8,0 +89ead9,0 +89eada,0 +89eadb,0 +89eadc,0 +89eadd,0 +89eade,0 +89eadf,0 +89eae0,0 +89eae1,0 +89eae2,0 +89eae3,0 +89eae4,0 +89eae5,0 +89eae6,0 +89eae7,0 +89eae8,0 +89eae9,0 +89eaea,0 +89eaeb,0 +89eaec,0 +89eaed,0 +89eaee,0 +89eaef,0 +89eaf0,0 +89eaf1,0 +89eb0e,0 +89eb0f,0 +89eb10,0 +89eb11,0 +89eb12,0 +89eb13,0 +89eb16,0 +89eb17,0 +89eb18,0 +89eb19,0 +89eb1a,0 +89eb1b,0 +89eb1c,0 +89eb1d,0 +89eb1e,0 +89eb1f,0 +89eb20,0 +89eb21,0 +89eb22,0 +89eb23,0 +89eb24,0 +89eb25,0 +89eb26,0 +89eb27,0 +89eb28,0 +89eb29,0 +89eb2a,0 +89eb2b,0 +89eb2c,0 +89eb2d,0 +89eb2e,0 +89eb2f,0 +89eb30,0 +89eb31,0 +89eb4e,0 +89eb4f,0 +89eb50,0 +89eb51,0 +89eb52,0 +89eb56,0 +89eb57,0 +89eb58,0 +89eb59,0 +89eb5a,0 +89eb5b,0 +89eb5c,0 +89eb5d,0 +89eb5e,0 +89eb5f,0 +89eb60,0 +89eb61,0 +89eb62,0 +89eb63,0 +89eb64,0 +89eb65,0 +89eb66,0 +89eb67,0 +89eb68,0 +89eb69,0 +89eb6a,0 +89eb6b,0 +89eb6c,0 +89eb6d,0 +89eb6e,0 +89eb6f,0 +89eb70,0 +89eb71,0 +89eb8e,0 +89eb8f,0 +89eb90,0 +89eb91,0 +89eb96,0 +89eb97,0 +89eb98,0 +89eb9d,0 +89eb9e,0 +89eb9f,0 +89eba0,0 +89eba1,0 +89eba3,0 +89eba4,0 +89eba5,0 +89eba6,0 +89eba7,0 +89eba8,0 +89ebaa,0 +89ebab,0 +89ebac,0 +89ebad,0 +89ebae,0 +89ebaf,0 +89ebb0,0 +89ebb1,0 +89ebce,0 +89ebcf,0 +89ebd6,0 +89ebd7,0 +89ebd8,0 +89ebea,0 +89ebeb,0 +89ebec,0 +89ebed,0 +89ebee,0 +89ebef,0 +89ebf0,0 +a98c30,c +a98c31,10 +a98c32,a +a98c33,e8 +a9e838,8 +a9e839,10 +a9e83a,e +a9e83b,0 +ac9abc,c +ac9abd,10 +ac9abe,c +ac9abf,5 +ac9ac1,0 +ac9ac2,0 +ac9ac3,0 +acce88,c +acce89,10 +acce8a,b +acce8b,f6 +acce8c,0 +acce8d,0 +acce8e,0 +acce8f,0 +acce90,0 +acce91,0 +acce94,0 +acce97,0 +acce98,0 +acce99,0 +acce9b,0 +ae5764,8 +ae5765,10 +ae5766,d +ae5767,28 +ae5768,0 +ae5769,0 +ae576a,0 +ae576b,0 +ae59e0,8 +ae59e1,10 +ae59e2,d +ae59e3,36 +ae5df0,c +ae5df1,10 +ae5df2,d +ae5df3,df +ae5df8,c +ae5df9,10 +ae5dfa,c +ae5dfb,0 +ae5e04,0 +ae5e05,0 +ae5e07,0 +ae6e48,c +ae6e49,10 +ae6e4a,b +ae6e4b,fb +ae6e4c,1 +ae6e4d,f +ae6e4e,c0 +ae6e4f,21 +b06400,82 +b06402,e +b06403,de +b0640c,31 +b0640d,f8 +b0640e,0 +b0640f,2 +b06c2c,c +b06c2d,10 +b06c2e,e +b06c2f,28 +b06c31,28 +b06c33,20 +b16b50,c +b16b51,10 +b16b52,c +b16b53,ac +b16b54,0 +b16b56,0 +b16b57,0 +b16b60,c +b16b61,10 +b16b62,c +b16b63,db +b16b64,0 +b16b65,0 +b16b66,0 +b16b67,0 +b17bb4,af +b17bb5,bf +b17bb6,0 +b17bb7,1c +b17bb8,af +b17bb9,a4 +b17bba,1 +b17bbb,40 +b17bbc,3c +b17bbd,4 +b17bbe,80 +b17bbf,40 +b17bc0,3c +b17bc1,5 +b17bc2,3 +b17bc3,48 +b17bc4,c +b17bc5,0 +b17bc6,3 +b17bc7,7c +b17bc8,34 +b17bc9,6 +b17bca,50 +b17bcb,0 +b17bcc,c +b17bcd,10 +b17bce,0 +b17bd0,0 +b17bd1,0 +b17bd2,0 +b17bd3,0 +b51694,c +b51695,10 +b51696,e +b51697,3b +b516c4,c +b516c5,10 +b516c6,e +b516c7,42 +b52784,c +b52785,10 +b52786,e +b52787,5c +b52788,0 +b52789,0 +b5278b,0 +b5278d,bf +b5278f,3c +b5293c,10 +b5293d,0 +b5293f,18 +b54b38,c +b54b39,10 +b54b3a,d +b54b3b,ef +b54e5c,c +b54e5d,10 +b54e5e,d +b54e5f,cc +b55a65,10 +b55a66,e +b55a67,15 +baed6c,0 +baed6d,0 +baed6f,0 +baf738,c +baf739,10 +baf73a,18 +baf73b,da +baf73d,4 +baf740,8f +baf741,b0 +baf743,18 +baf744,8f +baf745,bf +baf746,0 +baf747,1c +baf748,3 +baf749,e0 +baf74a,0 +baf74b,8 +baf74c,27 +baf74d,bd +baf74e,0 +baf74f,88 +baf750,0 +baf751,0 +baf753,0 +baf754,0 +baf755,0 +baf756,0 +baf757,0 +baf758,0 +baf759,0 +baf75a,0 +baf75c,0 +baf75d,0 +baf75e,0 +baf75f,0 +baf760,0 +baf761,0 +baf763,0 +baf764,0 +baf765,0 +baf766,0 +baf767,0 +baf768,0 +baf769,0 +baf76a,0 +baf76b,0 +baf76c,0 +baf76d,0 +baf76e,0 +baf76f,0 +baf770,0 +baf771,0 +baf772,0 +baf773,0 +baf775,0 +baf776,0 +baf777,0 +baf778,0 +baf779,0 +baf77a,0 +baf77b,0 +baf77d,0 +baf77e,0 +baf77f,0 +baf780,0 +baf781,0 +baf782,0 +baf783,0 +baf784,0 +baf785,0 +baf788,0 +baf789,0 +baf78b,0 +baf78c,0 +baf78d,0 +baf78f,0 +baf790,0 +baf791,0 +baf793,0 +baf794,0 +baf795,0 +baf797,0 +bb5eac,0 +bb5ead,0 +bb5eae,0 +bb5eaf,0 +bb5eb0,0 +bb5eb1,0 +bb5eb2,0 +bb5eb3,0 +bb5fd4,0 +bb5fd5,0 +bb5fd6,0 +bb5fd7,0 +bb5fd8,0 +bb5fd9,0 +bb5fda,0 +bb5fdb,0 +bb6134,0 +bb6135,0 +bb6136,0 +bb6137,0 +bb6138,0 +bb6139,0 +bb613a,0 +bb613b,0 +bb61e0,0 +bb61e1,0 +bb61e2,0 +bb61e3,0 +bb61e4,0 +bb61e5,0 +bb61e6,0 +bb61e7,0 +bb6688,c +bb6689,10 +bb668a,c +bb668b,ea +bb668c,0 +bb668d,0 +bb668f,0 +bb67c4,c +bb67c5,10 +bb67c6,c +bb67c7,ea +bb67c8,1 +bb67c9,82 +bb67ca,60 +bb67cb,21 +bb77b4,0 +bb77b5,0 +bb77b7,0 +bb7894,0 +bb7895,0 +bb7897,0 +bb7ba0,0 +bb7ba1,0 +bb7ba3,0 +bb7bfc,0 +bb7bfd,0 +bb7bff,0 +bb7c88,c +bb7c89,10 +bb7c8a,c +bb7c8b,e4 +bb7c8c,1 +bb7c8d,cf +bb7c8e,88 +bb7c8f,21 +bb7d10,c +bb7d11,10 +bb7d12,c +bb7d13,e4 +bb7d14,0 +bb7d15,0 +bb7d17,0 +bc088c,c +bc088d,10 +bc088e,c +bc088f,f7 +bc0890,0 +bc0891,0 +bc0892,0 +bc0893,0 +bcecbc,8 +bcecbd,10 +bcecbe,a +bcecbf,b0 +bcecc1,0 +bcecc2,0 +bcecc3,0 +bcecc4,0 +bcecc5,0 +bcecc7,0 +bcecc8,0 +bcecc9,0 +bcecca,0 +bceccb,0 +bceccc,0 +bceccd,0 +bcecce,0 +bceccf,0 +bcecd0,0 +bcecd1,0 +bcecd3,0 +bda0a1,10 +bda0a2,a +bda0a3,31 +bda0d8,c +bda0d9,10 +bda0da,a +bda0db,8e +bda0e4,0 +bda0e5,0 +bda0e7,0 +bda264,c +bda265,10 +bda266,a +bda267,92 +bda270,0 +bda271,0 +bda273,0 +be9ac0,c +be9ac1,10 +be9ac2,a +be9ac3,bc +be9ad8,c +be9ad9,10 +be9ada,a +be9adb,c5 +be9ae4,0 +be9ae5,0 +be9bde,83 +be9bdf,83 +c004ec,8 +c004ed,10 +c004ee,c +c004ef,51 +c0067f,64 +c018a0,c +c018a1,10 +c018a2,c +c018a3,66 +c6c7a8,c +c6c7a9,10 +c6c7aa,c +c6c7ab,76 +c6c920,c +c6c921,10 +c6c922,c +c6c923,76 +c892dc,34 +c892dd,e +c892de,0 +c892df,1 +c8931c,34 +c8931d,a +c8931e,0 +c8931f,1 +c89745,10 +c89746,b +c89747,cb +c89868,92 +c89869,e +c8986a,1d +c8986b,28 +c898a4,92 +c898a5,19 +c898a6,1d +c898a7,29 +c898c8,92 +c898c9,a +c898ca,1d +c898cb,2a +cb6875,10 +cb6876,d +cb6877,22 +d12f78,34 +d12f79,f +d12f7b,0 +d74964,10 +d74965,0 +d7e140,34 +d7e141,e +d7e142,0 +d7e143,1 +d7e144,80 +d7e146,e +d7e147,de +d7e160,84 +d7e161,88 +d7e163,a4 +d7e164,34 +d7e165,1 +d7e167,63 +d7e168,14 +d7e169,28 +d7e16b,3 +d7e16c,34 +d7e16d,2 +d7e16e,20 +d7e16f,49 +d7e170,10 +d7e171,0 +d7e172,0 +d7e173,6 +d7e174,0 +d7e177,0 +d7e178,94 +d7e179,69 +d7e17a,e +d7e17b,d6 +d7e17c,31 +d7e17d,29 +d7e17e,0 +d7e17f,4 +d7e180,15 +d7e181,20 +d7e183,2 +d7e184,34 +d7e185,2 +d7e186,20 +d7e187,44 +d7e188,34 +d7e189,2 +d7e18a,20 +d7e18b,43 +d7e18c,8f +d7e18d,bf +d7e18f,14 +d7e190,27 +d7e191,bd +d7e192,0 +d7e193,18 +d7e194,3 +d7e195,e0 +d7e197,8 +d7e198,0 +d7e199,0 +d7e19a,0 +d7e19b,0 +d7e398,94 +d7e399,89 +d7e39a,e +d7e39b,d6 +d7e39c,31 +d7e39d,28 +d7e39f,10 +d7e3a0,31 +d7e3a1,29 +d7e3a3,4 +d7e3a4,1 +d7e3a5,9 +d7e3a6,40 +d7e3a7,25 +d7e3a8,34 +d7e3a9,9 +d7e3ab,14 +d7e3ac,34 +d7e3ad,1 +d7e3ae,0 +d7e3af,5f +d7e3b0,14 +d7e3b1,23 +d7e3b3,6 +d7e3b4,0 +d7e3b5,0 +d7e3b7,0 +d7e3b8,11 +d7e3b9,9 +d7e3bb,4 +d7e3bc,0 +d7e3bd,0 +d7e3be,0 +d7e3bf,0 +d7e3c0,34 +d7e3c1,2 +d7e3c2,0 +d7e3c3,1 +d7e3c4,3 +d7e3c5,e0 +d7e3c7,8 +d7e3c8,0 +d7e3c9,0 +d7e3cb,0 +d7e3cc,14 +d7e3cd,c2 +d7e3cf,9 +d7e3d0,34 +d7e3d1,1 +d7e3d3,63 +d7e3d4,14 +d7e3d5,23 +d7e3d7,7 +d7e3d8,8c +d7e3d9,8a +d7e3db,10 +d7e3dc,15 +d7e3dd,40 +d7e3df,5 +d7e3e0,0 +d7e3e1,0 +d7e3e2,0 +d7e3e3,0 +d7e3e4,15 +d7e3e5,9 +d7e3e7,3 +d7e3e8,34 +d7e3e9,2 +d7e3eb,1 +d7e3ec,3 +d7e3ed,e0 +d7e3ef,8 +d7e3f0,0 +d7e3f1,0 +d7e3f2,0 +d7e3f3,0 +d7e3f4,34 +d7e3f5,2 +d7e3f6,0 +d7e3f7,0 +d7e3f8,3 +d7e3f9,e0 +d7e3fa,0 +d7e3fb,8 +d7e3fc,0 +d7e3fd,0 +d7e3ff,0 +d7e76c,8f +d7e76d,b8 +d7e76e,0 +d7e76f,44 +d7e778,87 +d7e779,18 +d7e77b,a4 +d7e77c,80 +d7e77d,49 +d7e77e,e +d7e77f,de +d7e784,34 +d7e786,0 +d7e787,1 +d7e788,2 +d7e789,0 +d7e78a,20 +d7e78b,21 +d7e798,15 +d7e79b,2 +d7e79c,34 +d7e79d,19 +d7e79e,0 +d7e79f,5f +d7e7a0,17 +d7e7a1,38 +d7e7a2,0 +d7e7a3,5 +d7e7a4,ae +d7e7a5,b +d7e7a6,1 +d7e7a7,80 +d7e890,0 +d7e891,0 +d7e893,0 +d7e8a0,10 +d7e8a1,0 +d7e8a3,7 +d7e8a4,31 +d7e8a5,4a +d7e8a7,4 +d7e8b0,0 +d7e8b3,0 +d7e8b4,0 +d7e8b5,0 +d7e8b7,0 +d7e8c0,34 +d7e8c1,b +d7e8c2,0 +d7e8c3,14 +d7e8c8,1 +d7e8c9,4b +d7e8ca,50 +d7e8cb,25 +d7e8cc,15 +d7e8cd,4b +d7e8cf,14 +d7e8d4,34 +d7e8d5,e +d7e8d6,0 +d7e8d7,1 +d7e8d8,80 +d7e8da,e +d7e8db,de +d7e8e0,57 +d7e8e3,f +d7ebbc,c +d7ebbd,10 +d7ebbe,c +d7ec1c,0 +d7ec1d,0 +d7ec1f,0 +d7ec20,34 +d7ec23,5 +db13d3,76 +db532c,c +db532d,10 +db532e,c +db532f,18 +df264f,76 +df7cb0,c +df7cb1,10 +df7cb2,c +df7cb3,96 +e09f68,80 +e09f6a,e +e09f6b,de +e09f74,31 +e09f75,f8 +e09f76,0 +e09f77,4 +e09fb0,c +e09fb1,10 +e09fb2,c +e09fb3,10 +e29388,8 +e29389,10 +e2938a,c +e2938b,2f +e2a044,c +e2a045,10 +e2a046,c +e2a047,38 +e2b0b5,10 +e2b0b6,c +e2b0b7,40 +e2f093,34 +e9e1d8,34 +e9e1d9,9 +e9e1da,40 +e9e1db,0 +e9e1f0,34 +e9e1f2,5b +e9e1f3,8 +e9e200,34 +e9e202,0 +e9e203,a +e9e20d,a9 +ebb85c,c +ebb85d,10 +ebb85e,c +ebb85f,81 +ebb865,40 +ebb867,12 +ebb86c,10 +ebb86d,0 +ebb86e,0 +ebb86f,14 +ec68bc,8f +ec68bd,ad +ec68be,0 +ec68bf,2c +ec68c0,34 +ec68c1,c +ec68c2,0 +ec68c3,a +ec68c4,a5 +ec68c5,ac +ec68c6,1 +ec68c7,10 +ec68c8,c +ec68c9,10 +ec68ca,a +ec68cb,4e +ec68cc,2 +ec68cd,0 +ec68ce,28 +ec68cf,21 +ec68d0,0 +ec68d1,0 +ec68d2,0 +ec68d3,0 +ec68d4,0 +ec68d5,0 +ec68d7,0 +ec68da,0 +ec68db,0 +ec68dc,0 +ec68dd,0 +ec68de,0 +ec68df,0 +ec68e0,0 +ec68e1,0 +ec68e2,0 +ec68e3,0 +ec69ad,ad +ec69af,2c +ec69b0,34 +ec69b1,c +ec69b2,0 +ec69b3,a +ec69b4,a5 +ec69b5,ac +ec69b6,1 +ec69b7,10 +ec69b8,c +ec69b9,10 +ec69ba,a +ec69bb,4e +ec69bc,2 +ec69bd,0 +ec69be,28 +ec69bf,21 +ec69c0,0 +ec69c1,0 +ec69c3,0 +ec69c4,0 +ec69c5,0 +ec69c6,0 +ec69c7,0 +ec69c8,0 +ec69c9,0 +ec69cb,0 +ec69cc,0 +ec69cd,0 +ec69ce,0 +ec69cf,0 +ec69d2,0 +ec69d3,0 +ec9ce7,7a +3480000,27 +3480001,bd +3480002,ff +3480003,e8 +3480004,af +3480005,bf +3480007,10 +3480008,3c +3480009,4 +348000a,80 +348000b,40 +348000c,24 +348000d,84 +348000e,50 +3480010,3c +3480011,5 +3480012,3 +3480013,4b +3480014,24 +3480015,a5 +3480016,30 +3480018,34 +3480019,6 +348001a,b0 +348001c,c +348001e,3 +348001f,7c +3480024,c +3480025,10 +3480026,16 +3480027,f5 +348002c,3c +348002d,2 +348002e,80 +348002f,12 +3480030,24 +3480031,42 +3480032,d2 +3480033,a0 +3480034,24 +3480035,e +3480036,1 +3480037,40 +3480038,3c +3480039,1 +348003a,80 +348003b,10 +348003c,ac +348003d,2e +348003e,e5 +3480040,8f +3480041,bf +3480043,10 +3480044,27 +3480045,bd +3480047,18 +3480048,3 +3480049,e0 +348004b,8 +3481c03,df +3481c04,df +3481c05,df +3481c06,df +3481c07,df +3481c08,df +3481c09,df +3481c0a,df +3481c0b,df +3481c0c,df +3481c0d,df +3481c0e,df +3481c0f,df +3481c10,df +3481c11,df +3481c12,df +3481c13,df +3481c14,df +3481c15,df +3481c16,df +3481c17,df +3481c18,df +3481c19,df +3481c1a,df +3481c1b,df +3481c1c,df +3481c1d,df +3481c1e,df +3481c1f,df +3481c20,df +3481c21,df +3481c22,df +3481c23,df +3481c24,df +3481c25,df +3481c26,df +3481c27,df +3481c28,df +3481c29,df +3481c2a,df +3481c2b,df +3481c2c,df +3481c2d,df +3481c2e,df +3481c2f,df +3481c30,df +3481c31,df +3481c32,df +3481c33,df +3481c34,df +3481c35,df +3481c36,df +3481c37,df +3481c38,df +3481c39,df +3481c3a,df +3481c3b,df +3481c3c,df +3481c3d,df +3481c3e,df +3481c3f,df +3481c40,df +3481c41,df +3481c42,df +3481c43,df +3481c44,df +3481c45,df +3481c46,df +3481c47,df +3481c48,df +3481c49,df +3481c4a,df +3481c4b,df +3481c4c,df +3481c4d,df +3481c4e,df +3481c4f,df +3481c50,df +3481c51,df +3481c52,df +3481c53,df +3481c54,df +3481c55,df +3481c56,df +3481c57,df +3481c58,df +3481c59,df +3481c5a,df +3481c5b,df +3481c5c,df +3481c5d,df +3481c5e,df +3481c5f,df +3481c60,df +3481c61,df +3481c62,df +3481c63,df +3481c64,df +3481c65,df +3481c66,df +3481c67,df +3481c68,df +3481c69,df +3481c6a,df +3481c6b,df +3481c6c,df +3481c6d,df +3481c6e,df +3481c6f,df +3481c70,df +3481c71,df +3481c72,df +3481c73,df +3481c74,df +3481c75,df +3481c76,df +3481c77,df +3481c78,df +3481c79,df +3481c7a,df +3481c7b,df +3481c7c,df +3481c7d,df +3481c7e,df +3481c7f,df +3481c80,df +3481c81,df +3481c82,df +3481c83,df +3481c84,df +3481c85,df +3481c86,df +3481c87,df +3481c88,df +3481c89,df +3481c8a,df +3481c8b,df +3481c8c,df +3481c8d,df +3481c8e,df +3481c8f,df +3481c90,df +3481c91,df +3481c92,df +3481c93,df +3481c94,df +3481c95,df +3481c96,df +3481c97,df +3481c98,df +3481c99,df +3481c9a,df +3481c9b,df +3481c9c,df +3481c9d,df +3481c9e,df +3481c9f,df +3481ca0,df +3481ca1,df +3481ca2,df +3481ca3,df +3481ca4,df +3481ca5,df +3481ca6,df +3481ca7,df +3481ca8,df +3481ca9,df +3481caa,df +3481cab,df +3481cac,df +3481cad,df +3481cae,df +3481caf,df +3481cb0,df +3481cb1,df +3481cb2,df +3481cb3,df +3481cb4,df +3481cb5,df +3481cb6,df +3481cb7,df +3481cb8,df +3481cb9,df +3481cba,df +3481cbb,df +3481cbc,df +3481cbd,df +3481cbe,df +3481cbf,df +3481cc0,df +3481cc1,df +3481cc2,df +3481cc3,df +3481cc4,df +3481cc5,df +3481cc6,df +3481cc7,df +3481cc8,df +3481cc9,df +3481cca,df +3481ccb,df +3481ccc,df +3481ccd,df +3481cce,df +3481ccf,df +3481cd0,df +3481cd1,df +3481cd2,df +3481cd3,df +3481cd4,df +3481cd5,df +3481cd6,df +3481cd7,df +3481cd8,df +3481cd9,df +3481cda,df +3481cdb,df +3481cdc,df +3481cdd,df +3481cde,df +3481cdf,df +3481ce0,df +3481ce1,df +3481ce2,df +3481ce3,df +3481ce4,df +3481ce5,df +3481ce6,df +3481ce7,df +3481ce8,df +3481ce9,df +3481cea,df +3481ceb,df +3481cec,df +3481ced,df +3481cee,df +3481cef,df +3481cf0,df +3481cf1,df +3481cf2,df +3481cf3,df +3481cf4,df +3481cf5,df +3481cf6,df +3481cf7,df +3481cf8,df +3481cf9,df +3481cfa,df +3481cfb,df +3481cfc,df +3481cfd,df +3481cfe,df +3481cff,df +3481d00,df +3481d01,df +3481d02,df +3481d03,5a +3481d04,3b +3481d05,5d +3481d06,5c +3481d07,5e +3481d08,51 +3481d09,52 +3481d0a,53 +3482050,ff +3482051,ff +3482052,ff +3482053,ff +3482054,ff +3482055,ff +3482056,ff +3482057,ff +3482058,80 +3482059,40 +348205a,27 +348205b,50 +348205c,80 +348205d,40 +348205e,25 +348205f,98 +3482060,ff +3482061,ff +3482062,ff +3482063,ff +3482064,ff +3482065,ff +3482066,ff +3482067,ff +3482068,80 +3482069,40 +348206a,27 +348206b,50 +348206c,80 +348206d,40 +348206e,25 +348206f,b4 +3482070,ff +3482071,ff +3482072,ff +3482073,ff +3482074,ff +3482075,ff +3482076,ff +3482077,ff +3482078,80 +3482079,40 +348207a,27 +348207b,50 +348207c,80 +348207d,40 +348207e,25 +348207f,dc +3482080,ff +3482081,ff +3482082,ff +3482083,ff +3482084,ff +3482085,ff +3482086,ff +3482087,ff +3482088,80 +3482089,40 +348208a,27 +348208b,50 +348208c,80 +348208d,40 +348208e,26 +348208f,4 +3482090,ff +3482091,ff +3482092,ff +3482093,ff +3482094,ff +3482095,ff +3482096,ff +3482097,ff +3482098,80 +3482099,40 +348209a,27 +348209b,50 +348209c,80 +348209d,40 +348209e,26 +348209f,2c +34820a0,53 +34820a1,41 +34820a2,23 +34820a3,f8 +34820a5,d1 +34820a6,ff +34820a7,ff +34820a8,80 +34820a9,40 +34820aa,26 +34820ab,7c +34820ac,80 +34820ad,40 +34820ae,26 +34820af,54 +34820b0,ff +34820b1,ff +34820b2,ff +34820b3,ff +34820b4,ff +34820b5,ff +34820b6,ff +34820b7,ff +34820b8,80 +34820b9,40 +34820ba,27 +34820bb,50 +34820bc,80 +34820bd,40 +34820be,26 +34820bf,90 +34820c0,ff +34820c1,ff +34820c2,ff +34820c3,ff +34820c4,ff +34820c5,ff +34820c6,ff +34820c7,ff +34820c8,80 +34820c9,40 +34820ca,27 +34820cb,50 +34820cc,80 +34820cd,40 +34820ce,26 +34820cf,ac +34820d0,ff +34820d1,ff +34820d2,ff +34820d3,ff +34820d4,ff +34820d5,ff +34820d6,ff +34820d7,ff +34820d8,80 +34820d9,40 +34820da,27 +34820db,50 +34820dc,80 +34820dd,40 +34820de,26 +34820df,c8 +34820e0,53 +34820e1,41 +34820e2,38 +34820e3,43 +34820e5,eb +34820e6,15 +34820e7,ff +34820e8,80 +34820e9,40 +34820ea,27 +34820eb,68 +34820ec,80 +34820ed,40 +34820ee,25 +34820ef,90 +34820f0,53 +34820f1,41 +34820f2,37 +34820f3,44 +34820f5,eb +34820f6,16 +34820f7,ff +34820f8,80 +34820f9,40 +34820fa,27 +34820fb,68 +34820fc,80 +34820fd,40 +34820fe,25 +34820ff,90 +3482100,53 +3482101,41 +3482102,39 +3482103,45 +3482105,eb +3482106,17 +3482107,ff +3482108,80 +3482109,40 +348210a,27 +348210b,68 +348210c,80 +348210d,40 +348210e,25 +348210f,90 +3482110,53 +3482111,41 +3482112,6b +3482113,46 +3482114,1 +3482115,77 +3482116,18 +3482117,ff +3482118,80 +3482119,40 +348211a,27 +348211b,68 +348211c,80 +348211d,40 +348211e,25 +348211f,90 +3482120,53 +3482121,41 +3482122,3f +3482123,47 +3482125,f4 +3482126,19 +3482127,ff +3482128,80 +3482129,40 +348212a,27 +348212b,68 +348212c,80 +348212d,40 +348212e,25 +348212f,90 +3482130,53 +3482131,41 +3482132,67 +3482133,5d +3482134,1 +3482135,73 +3482136,1c +3482137,ff +3482138,80 +3482139,40 +348213a,27 +348213b,68 +348213c,80 +348213d,40 +348213e,25 +348213f,90 +3482140,53 +3482141,41 +3482142,68 +3482143,7a +3482144,1 +3482145,74 +3482146,1d +3482147,ff +3482148,80 +3482149,40 +348214a,27 +348214b,68 +348214c,80 +348214d,40 +348214e,25 +348214f,90 +3482150,53 +3482151,41 +3482152,70 +3482153,f9 +3482154,1 +3482155,76 +3482156,1e +3482157,ff +3482158,80 +3482159,40 +348215a,27 +348215b,68 +348215c,80 +348215d,40 +348215e,25 +348215f,90 +3482160,53 +3482161,41 +3482162,6a +3482163,97 +3482164,1 +3482165,76 +3482166,20 +3482167,ff +3482168,80 +3482169,40 +348216a,27 +348216b,68 +348216c,80 +348216d,40 +348216e,25 +348216f,90 +3482170,53 +3482171,41 +3482172,a +3482173,6 +3482175,b9 +3482176,1 +3482177,3 +3482178,80 +3482179,40 +348217a,27 +348217b,a4 +348217c,80 +348217d,40 +348217e,25 +348217f,90 +3482180,53 +3482181,41 +3482182,a +3482183,1c +3482185,b9 +3482186,1 +3482187,4 +3482188,80 +3482189,40 +348218a,27 +348218b,a4 +348218c,80 +348218d,40 +348218e,25 +348218f,90 +3482190,53 +3482191,41 +3482192,a +3482193,1d +3482195,b9 +3482196,1 +3482197,5 +3482198,80 +3482199,40 +348219a,27 +348219b,a4 +348219c,80 +348219d,40 +348219e,25 +348219f,90 +34821a0,53 +34821a1,41 +34821a2,a +34821a3,1e +34821a5,b9 +34821a6,1 +34821a7,6 +34821a8,80 +34821a9,40 +34821aa,27 +34821ab,a4 +34821ac,80 +34821ad,40 +34821ae,25 +34821af,90 +34821b0,53 +34821b1,41 +34821b2,a +34821b3,2a +34821b5,b9 +34821b6,1 +34821b7,7 +34821b8,80 +34821b9,40 +34821ba,27 +34821bb,a4 +34821bc,80 +34821bd,40 +34821be,25 +34821bf,90 +34821c0,53 +34821c1,41 +34821c2,a +34821c3,61 +34821c5,b9 +34821c6,1 +34821c7,a +34821c8,80 +34821c9,40 +34821ca,27 +34821cb,a4 +34821cc,80 +34821cd,40 +34821ce,25 +34821cf,90 +34821d0,4d +34821d1,41 +34821d2,f5 +34821d3,62 +34821d5,b8 +34821d6,2 +34821d8,80 +34821d9,40 +34821da,27 +34821db,a4 +34821dc,80 +34821dd,40 +34821de,25 +34821df,90 +34821e0,4d +34821e1,41 +34821e2,f5 +34821e3,63 +34821e5,b8 +34821e6,2 +34821e7,1 +34821e8,80 +34821e9,40 +34821ea,27 +34821eb,a4 +34821ec,80 +34821ed,40 +34821ee,25 +34821ef,90 +34821f0,4d +34821f1,41 +34821f2,f5 +34821f3,64 +34821f5,b8 +34821f6,2 +34821f7,2 +34821f8,80 +34821f9,40 +34821fa,27 +34821fb,a4 +34821fc,80 +34821fd,40 +34821fe,25 +34821ff,90 +3482200,4d +3482201,41 +3482202,f5 +3482203,65 +3482205,b8 +3482206,2 +3482207,3 +3482208,80 +3482209,40 +348220a,27 +348220b,a4 +348220c,80 +348220d,40 +348220e,25 +348220f,90 +3482210,4d +3482211,41 +3482212,f5 +3482213,7c +3482215,b8 +3482216,2 +3482217,4 +3482218,80 +3482219,40 +348221a,27 +348221b,a4 +348221c,80 +348221d,40 +348221e,25 +348221f,90 +3482220,4d +3482221,41 +3482222,f5 +3482223,7d +3482225,b8 +3482226,2 +3482227,5 +3482228,80 +3482229,40 +348222a,27 +348222b,a4 +348222c,80 +348222d,40 +348222e,25 +348222f,90 +3482230,4d +3482231,41 +3482232,f5 +3482233,7e +3482235,b8 +3482236,2 +3482237,6 +3482238,80 +3482239,40 +348223a,27 +348223b,a4 +348223c,80 +348223d,40 +348223e,25 +348223f,90 +3482240,4d +3482241,41 +3482242,f5 +3482243,7f +3482245,b8 +3482246,2 +3482247,7 +3482248,80 +3482249,40 +348224a,27 +348224b,a4 +348224c,80 +348224d,40 +348224e,25 +348224f,90 +3482250,4d +3482251,41 +3482252,f5 +3482253,a2 +3482255,b8 +3482256,2 +3482257,8 +3482258,80 +3482259,40 +348225a,27 +348225b,a4 +348225c,80 +348225d,40 +348225e,25 +348225f,90 +3482260,4d +3482261,41 +3482262,f5 +3482263,87 +3482265,b8 +3482266,2 +3482267,9 +3482268,80 +3482269,40 +348226a,27 +348226b,a4 +348226c,80 +348226d,40 +348226e,25 +348226f,90 +3482270,4d +3482271,41 +3482272,e4 +3482273,88 +3482275,c8 +3482276,4 +3482278,80 +3482279,40 +348227a,27 +348227b,a4 +348227c,80 +348227d,40 +348227e,25 +348227f,90 +3482280,4d +3482281,41 +3482282,e4 +3482283,89 +3482285,c8 +3482286,4 +3482287,1 +3482288,80 +3482289,40 +348228a,27 +348228b,a4 +348228c,80 +348228d,40 +348228e,25 +348228f,90 +3482290,4d +3482291,41 +3482292,e4 +3482293,8a +3482295,c8 +3482296,4 +3482297,2 +3482298,80 +3482299,40 +348229a,27 +348229b,a4 +348229c,80 +348229d,40 +348229e,25 +348229f,90 +34822a0,4d +34822a1,41 +34822a2,e4 +34822a3,8b +34822a5,c8 +34822a6,4 +34822a7,3 +34822a8,80 +34822a9,40 +34822aa,27 +34822ab,a4 +34822ac,80 +34822ad,40 +34822ae,25 +34822af,90 +34822b0,4d +34822b1,41 +34822b2,e4 +34822b3,8c +34822b5,c8 +34822b6,4 +34822b7,4 +34822b8,80 +34822b9,40 +34822ba,27 +34822bb,a4 +34822bc,80 +34822bd,40 +34822be,25 +34822bf,90 +34822c0,4d +34822c1,41 +34822c2,e4 +34822c3,8e +34822c5,c8 +34822c6,4 +34822c7,5 +34822c8,80 +34822c9,40 +34822ca,27 +34822cb,a4 +34822cc,80 +34822cd,40 +34822ce,25 +34822cf,90 +34822d0,4d +34822d1,41 +34822d2,e4 +34822d3,8f +34822d5,c8 +34822d6,4 +34822d7,6 +34822d8,80 +34822d9,40 +34822da,27 +34822db,a4 +34822dc,80 +34822dd,40 +34822de,25 +34822df,90 +34822e0,4d +34822e1,41 +34822e2,e4 +34822e3,a3 +34822e5,c8 +34822e6,4 +34822e7,7 +34822e8,80 +34822e9,40 +34822ea,27 +34822eb,a4 +34822ec,80 +34822ed,40 +34822ee,25 +34822ef,90 +34822f0,4d +34822f1,41 +34822f2,e4 +34822f3,a5 +34822f5,c8 +34822f6,4 +34822f7,8 +34822f8,80 +34822f9,40 +34822fa,27 +34822fb,a4 +34822fc,80 +34822fd,40 +34822fe,25 +34822ff,90 +3482300,4d +3482301,41 +3482302,e4 +3482303,92 +3482305,c8 +3482306,4 +3482307,9 +3482308,80 +3482309,40 +348230a,27 +348230b,a4 +348230c,80 +348230d,40 +348230e,25 +348230f,90 +3482310,53 +3482311,41 +3482312,2 +3482313,93 +3482315,aa +3482316,3 +3482317,ff +3482318,80 +3482319,40 +348231a,27 +348231b,c0 +348231c,80 +348231d,40 +348231e,25 +348231f,90 +3482320,53 +3482321,41 +3482322,2 +3482323,94 +3482325,aa +3482326,4 +3482327,ff +3482328,80 +3482329,40 +348232a,27 +348232b,c0 +348232c,80 +348232d,40 +348232e,25 +348232f,90 +3482330,53 +3482331,41 +3482332,2 +3482333,95 +3482335,aa +3482336,5 +3482337,ff +3482338,80 +3482339,40 +348233a,27 +348233b,c0 +348233c,80 +348233d,40 +348233e,25 +348233f,90 +3482340,53 +3482341,41 +3482342,2 +3482343,a6 +3482345,aa +3482346,6 +3482347,ff +3482348,80 +3482349,40 +348234a,27 +348234b,c0 +348234c,80 +348234d,40 +348234e,25 +348234f,90 +3482350,53 +3482351,41 +3482352,2 +3482353,a9 +3482355,aa +3482356,7 +3482357,ff +3482358,80 +3482359,40 +348235a,27 +348235b,c0 +348235c,80 +348235d,40 +348235e,25 +348235f,90 +3482360,53 +3482361,41 +3482362,2 +3482363,9b +3482365,aa +3482366,8 +3482367,ff +3482368,80 +3482369,40 +348236a,27 +348236b,c0 +348236c,80 +348236d,40 +348236e,25 +348236f,90 +3482370,53 +3482371,41 +3482372,2 +3482373,9f +3482375,aa +3482376,b +3482377,ff +3482378,80 +3482379,40 +348237a,27 +348237b,c0 +348237c,80 +348237d,40 +348237e,25 +348237f,90 +3482380,53 +3482381,41 +3482382,2 +3482383,a0 +3482385,aa +3482386,c +3482387,ff +3482388,80 +3482389,40 +348238a,27 +348238b,c0 +348238c,80 +348238d,40 +348238e,25 +348238f,90 +3482390,53 +3482391,41 +3482392,2 +3482393,a1 +3482395,aa +3482396,d +3482397,ff +3482398,80 +3482399,40 +348239a,27 +348239b,c0 +348239c,80 +348239d,40 +348239e,25 +348239f,90 +34823a0,53 +34823a1,3d +34823a2,43 +34823a3,c +34823a5,f8 +34823a6,ff +34823a7,ff +34823a8,80 +34823a9,40 +34823aa,27 +34823ab,58 +34823ac,80 +34823ad,40 +34823ae,25 +34823af,90 +34823b0,4d +34823b1,83 +34823b2,f7 +34823b3,55 +34823b5,b7 +34823b6,ff +34823b7,ff +34823b8,80 +34823b9,40 +34823ba,27 +34823bb,50 +34823bc,80 +34823bd,40 +34823be,25 +34823bf,90 +34823c0,4d +34823c1,92 +34823c2,db +34823c3,e6 +34823c5,d8 +34823c6,ff +34823c7,ff +34823c8,80 +34823c9,40 +34823ca,27 +34823cb,50 +34823cc,80 +34823cd,40 +34823ce,26 +34823cf,fc +34823d0,4d +34823d1,93 +34823d2,da +34823d3,e6 +34823d5,d8 +34823d6,ff +34823d7,ff +34823d8,80 +34823d9,40 +34823da,27 +34823db,50 +34823dc,80 +34823dd,40 +34823de,26 +34823df,fc +34823e0,4d +34823e1,94 +34823e2,d9 +34823e3,e6 +34823e5,d8 +34823e6,ff +34823e7,ff +34823e8,80 +34823e9,40 +34823ea,27 +34823eb,50 +34823ec,80 +34823ed,40 +34823ee,26 +34823ef,fc +34823f0,4d +34823f1,8e +34823f2,e0 +34823f3,32 +34823f5,ce +34823f6,ff +34823f7,ff +34823f8,80 +34823f9,40 +34823fa,27 +34823fb,50 +34823fc,80 +34823fd,40 +34823fe,27 +34823ff,18 +3482400,4d +3482401,8f +3482402,e0 +3482403,32 +3482405,ce +3482406,ff +3482407,ff +3482408,80 +3482409,40 +348240a,27 +348240b,50 +348240c,80 +348240d,40 +348240e,27 +348240f,18 +3482410,4d +3482411,90 +3482412,e0 +3482413,32 +3482415,ce +3482416,ff +3482417,ff +3482418,80 +3482419,40 +348241a,27 +348241b,50 +348241c,80 +348241d,40 +348241e,27 +348241f,18 +3482420,4d +3482421,8c +3482422,ee +3482423,34 +3482425,bb +3482426,ff +3482427,ff +3482428,80 +3482429,40 +348242a,27 +348242b,50 +348242c,80 +348242d,40 +348242e,25 +348242f,90 +3482430,4d +3482431,8d +3482432,ee +3482433,34 +3482435,bb +3482436,ff +3482437,ff +3482438,80 +3482439,40 +348243a,27 +348243b,50 +348243c,80 +348243d,40 +348243e,25 +348243f,90 +3482440,53 +3482441,41 +3482442,13 +3482443,e9 +3482445,bd +3482446,ff +3482447,ff +3482448,80 +3482449,40 +348244a,27 +348244b,e8 +348244c,80 +348244d,40 +348244e,25 +348244f,90 +3482450,53 +3482451,41 +3482452,1e +3482453,e4 +3482455,cd +3482456,ff +3482457,ff +3482458,80 +3482459,40 +348245a,28 +348245b,8 +348245c,80 +348245d,40 +348245e,26 +348245f,e4 +3482460,53 +3482461,41 +3482462,1f +3482463,e8 +3482465,cd +3482466,ff +3482467,ff +3482468,80 +3482469,40 +348246a,28 +348246b,28 +348246c,80 +348246d,40 +348246e,25 +348246f,90 +3482470,ff +3482471,ff +3482472,ff +3482473,ff +3482474,ff +3482475,ff +3482476,ff +3482477,ff +3482478,80 +3482479,40 +348247a,27 +348247b,50 +348247c,80 +348247d,40 +348247e,28 +348247f,50 +3482480,53 +3482481,41 +3482482,46 +3482483,4a +3482484,1 +3482485,e +3482486,ff +3482487,ff +3482488,80 +3482489,40 +348248a,28 +348248b,98 +348248c,80 +348248d,40 +348248e,28 +348248f,7c +3482490,53 +3482491,41 +3482492,3 +3482493,b0 +3482495,b6 +3482496,6 +3482497,ff +3482498,80 +3482499,40 +348249a,28 +348249b,a8 +348249c,80 +348249d,40 +348249e,25 +348249f,90 +34824a0,53 +34824a1,41 +34824a2,4 +34824a3,b1 +34824a5,b6 +34824a6,7 +34824a7,ff +34824a8,80 +34824a9,40 +34824aa,28 +34824ab,a8 +34824ac,80 +34824ad,40 +34824ae,25 +34824af,90 +34824b0,53 +34824b1,41 +34824b2,5 +34824b3,b2 +34824b5,b6 +34824b6,8 +34824b7,ff +34824b8,80 +34824b9,40 +34824ba,28 +34824bb,a8 +34824bc,80 +34824bd,40 +34824be,25 +34824bf,90 +34824c0,53 +34824c1,41 +34824c2,6 +34824c3,b3 +34824c5,b6 +34824c6,9 +34824c7,ff +34824c8,80 +34824c9,40 +34824ca,28 +34824cb,a8 +34824cc,80 +34824cd,40 +34824ce,25 +34824cf,90 +34824d0,53 +34824d1,41 +34824d2,7 +34824d3,b6 +34824d5,b6 +34824d6,a +34824d7,ff +34824d8,80 +34824d9,40 +34824da,28 +34824db,a8 +34824dc,80 +34824dd,40 +34824de,25 +34824df,90 +34824e0,53 +34824e1,41 +34824e2,8 +34824e3,b7 +34824e5,b6 +34824e6,b +34824e7,ff +34824e8,80 +34824e9,40 +34824ea,28 +34824eb,a8 +34824ec,80 +34824ed,40 +34824ee,25 +34824ef,90 +34824f0,53 +34824f1,41 +34824f2,4 +34824f3,b8 +34824f5,b6 +34824f6,c +34824f7,ff +34824f8,80 +34824f9,40 +34824fa,28 +34824fb,a8 +34824fc,80 +34824fd,40 +34824fe,25 +34824ff,90 +3482500,53 +3482501,41 +3482502,6 +3482503,b9 +3482505,b6 +3482506,d +3482507,ff +3482508,80 +3482509,40 +348250a,28 +348250b,a8 +348250c,80 +348250d,40 +348250e,25 +348250f,90 +3482510,53 +3482511,41 +3482512,3 +3482513,ba +3482515,b6 +3482516,e +3482517,ff +3482518,80 +3482519,40 +348251a,28 +348251b,a8 +348251c,80 +348251d,40 +348251e,25 +348251f,90 +3482520,53 +3482521,41 +3482522,8 +3482523,bb +3482525,b6 +3482526,f +3482527,ff +3482528,80 +3482529,40 +348252a,28 +348252b,a8 +348252c,80 +348252d,40 +348252e,25 +348252f,90 +3482530,53 +3482531,41 +3482532,5 +3482533,bc +3482535,b6 +3482536,10 +3482537,ff +3482538,80 +3482539,40 +348253a,28 +348253b,a8 +348253c,80 +348253d,40 +348253e,25 +348253f,90 +3482540,53 +3482541,41 +3482542,7 +3482543,bd +3482545,b6 +3482546,11 +3482547,ff +3482548,80 +3482549,40 +348254a,28 +348254b,a8 +348254c,80 +348254d,40 +348254e,25 +348254f,90 +3482550,4d +3482552,e5 +3482553,37 +3482555,c7 +3482556,ff +3482557,ff +3482558,80 +3482559,40 +348255a,27 +348255b,50 +348255c,80 +348255d,40 +348255e,25 +348255f,90 +3482560,4d +3482561,95 +3482562,b8 +3482563,dc +3482564,1 +3482565,19 +3482566,ff +3482567,ff +3482568,80 +3482569,40 +348256a,27 +348256b,50 +348256c,80 +348256d,40 +348256e,27 +348256f,34 +3482570,77 +3482571,3e +3482572,e3 +3482573,4c +3482575,cb +3482576,ff +3482577,ff +3482578,80 +3482579,40 +348257a,27 +348257b,50 +348257c,80 +348257d,40 +348257e,25 +348257f,90 +3482580,77 +3482581,3f +3482582,d4 +3482583,4d +3482585,dc +3482586,ff +3482587,ff +3482588,80 +3482589,40 +348258a,27 +348258b,50 +348258c,80 +348258d,40 +348258e,25 +348258f,90 +3482590,3 +3482591,e0 +3482593,8 +3482594,34 +3482595,a2 +3482598,90 +3482599,88 +348259b,7d +348259c,34 +348259d,1 +348259f,ff +34825a0,11 +34825a1,1 +34825a3,2 +34825a4,34 +34825a5,2 +34825a7,8 +34825a8,34 +34825a9,2 +34825ab,9 +34825ac,3 +34825ad,e0 +34825af,8 +34825b4,90 +34825b5,88 +34825b7,a3 +34825b8,31 +34825b9,8 +34825bb,c0 +34825bc,11 +34825bf,5 +34825c0,34 +34825c1,2 +34825c3,54 +34825c4,34 +34825c5,1 +34825c7,40 +34825c8,11 +34825c9,1 +34825cb,2 +34825cc,34 +34825cd,2 +34825cf,35 +34825d0,34 +34825d1,2 +34825d3,36 +34825d4,3 +34825d5,e0 +34825d7,8 +34825dc,90 +34825dd,88 +34825df,a3 +34825e0,31 +34825e1,8 +34825e3,18 +34825e4,11 +34825e7,5 +34825e8,34 +34825e9,2 +34825eb,32 +34825ec,34 +34825ed,1 +34825ef,8 +34825f0,11 +34825f1,1 +34825f3,2 +34825f4,34 +34825f5,2 +34825f7,33 +34825f8,34 +34825f9,2 +34825fb,34 +34825fc,3 +34825fd,e0 +34825ff,8 +3482604,90 +3482605,88 +3482607,a3 +3482608,31 +3482609,8 +348260b,3 +348260c,11 +348260f,5 +3482610,34 +3482611,2 +3482613,4 +3482614,34 +3482615,1 +3482617,1 +3482618,11 +3482619,1 +348261b,2 +348261c,34 +348261d,2 +348261f,30 +3482620,34 +3482621,2 +3482623,31 +3482624,3 +3482625,e0 +3482627,8 +348262c,90 +348262d,88 +348262f,a2 +3482630,31 +3482631,8 +3482633,c0 +3482634,11 +3482637,5 +3482638,34 +3482639,2 +348263b,5 +348263c,34 +348263d,1 +348263f,40 +3482640,11 +3482641,1 +3482643,2 +3482644,34 +3482645,2 +3482647,60 +3482648,34 +3482649,2 +348264b,7b +348264c,3 +348264d,e0 +348264f,8 +3482654,90 +3482655,88 +3482657,a2 +3482658,31 +3482659,8 +348265b,30 +348265c,11 +348265f,5 +3482660,34 +3482661,2 +3482663,45 +3482664,34 +3482665,9 +3482667,10 +3482668,11 +3482669,9 +348266b,2 +348266c,34 +348266d,2 +348266f,46 +3482670,34 +3482671,a2 +3482674,3 +3482675,e0 +3482677,8 +348267c,90 +348267d,88 +348267f,a2 +3482680,35 +3482681,8 +3482683,30 +3482684,a0 +3482685,88 +3482687,a2 +3482688,3 +3482689,e0 +348268b,8 +3482690,90 +3482691,88 +3482693,a2 +3482694,31 +3482695,8 +3482697,6 +3482698,11 +348269b,2 +348269c,34 +348269d,2 +348269f,37 +34826a0,34 +34826a1,2 +34826a3,38 +34826a4,3 +34826a5,e0 +34826a7,8 +34826ac,90 +34826ad,88 +34826af,a1 +34826b0,31 +34826b1,8 +34826b3,20 +34826b4,11 +34826b7,2 +34826b8,34 +34826b9,2 +34826bb,79 +34826bc,34 +34826bd,2 +34826bf,7a +34826c0,3 +34826c1,e0 +34826c3,8 +34826c8,90 +34826c9,88 +34826cb,a1 +34826cc,31 +34826cd,8 +34826cf,4 +34826d0,11 +34826d3,2 +34826d4,34 +34826d5,2 +34826d7,77 +34826d8,34 +34826d9,2 +34826db,78 +34826dc,3 +34826dd,e0 +34826df,8 +34826e4,90 +34826e5,88 +34826e7,32 +34826e8,11 +34826eb,2 +34826ec,34 +34826ed,2 +34826ef,c0 +34826f0,34 +34826f1,2 +34826f3,c1 +34826f4,3 +34826f5,e0 +34826f7,8 +34826fc,90 +34826fd,88 +34826ff,a3 +3482700,31 +3482701,8 +3482703,3 +3482704,11 +3482707,2 +3482708,34 +3482709,2 +348270b,4d +348270c,34 +348270d,a2 +3482710,3 +3482711,e0 +3482713,8 +3482718,90 +3482719,88 +348271b,a3 +348271c,31 +348271d,8 +348271f,18 +3482720,11 +3482723,2 +3482724,34 +3482725,2 +3482727,4d +3482728,34 +3482729,a2 +348272c,3 +348272d,e0 +348272f,8 +3482734,90 +3482735,88 +3482737,a2 +3482738,31 +3482739,8 +348273b,c0 +348273c,11 +348273f,2 +3482740,34 +3482741,2 +3482743,4d +3482744,34 +3482745,a2 +3482748,3 +3482749,e0 +348274b,8 +3482750,3 +3482751,e0 +3482753,8 +3482758,34 +3482759,8 +348275b,1 +348275c,a0 +348275d,88 +348275f,3e +3482760,3 +3482761,e0 +3482763,8 +3482768,24 +3482769,88 +348276b,86 +348276c,24 +348276d,9 +348276e,ff +348276f,ff +3482770,25 +3482771,29 +3482773,1 +3482774,34 +3482775,1 +3482777,3 +3482779,29 +348277a,8 +348277b,2a +348277c,14 +348277d,20 +348277f,7 +3482784,1 +3482785,9 +3482786,50 +3482787,21 +3482788,91 +3482789,4b +348278c,34 +348278d,1 +348278f,ff +3482790,15 +3482791,61 +3482792,ff +3482793,f7 +3482798,a1 +3482799,45 +348279c,3 +348279d,e0 +348279f,8 +34827a4,24 +34827a5,88 +34827a7,a8 +34827a8,1 +34827a9,6 +34827aa,40 +34827ab,21 +34827ac,91 +34827ad,9 +34827b0,1 +34827b1,25 +34827b2,48 +34827b3,25 +34827b4,a1 +34827b5,9 +34827b8,3 +34827b9,e0 +34827bb,8 +34827c0,24 +34827c1,88 +34827c3,bc +34827c4,1 +34827c5,5 +34827c6,40 +34827c7,21 +34827c8,81 +34827c9,9 +34827cc,5 +34827cd,21 +34827cf,2 +34827d4,34 +34827d5,9 +34827d8,25 +34827d9,29 +34827db,1 +34827dc,a1 +34827dd,9 +34827e0,3 +34827e1,e0 +34827e3,8 +34827e8,34 +34827e9,8 +34827eb,1 +34827ec,a0 +34827ed,88 +34827ef,3d +34827f0,34 +34827f1,8 +34827f3,14 +34827f4,a0 +34827f5,88 +34827f7,cf +34827f8,34 +34827f9,8 +34827fa,1 +34827fb,40 +34827fc,a4 +34827fd,88 +34827fe,14 +34827ff,24 +3482800,3 +3482801,e0 +3482803,8 +3482808,34 +3482809,8 +348280b,1 +348280c,a0 +348280d,88 +348280f,32 +3482810,a0 +3482811,88 +3482813,3a +3482814,34 +3482815,8 +3482817,30 +3482818,a4 +3482819,88 +348281a,13 +348281b,f4 +348281c,a0 +348281d,88 +348281f,33 +3482820,3 +3482821,e0 +3482823,8 +3482828,34 +3482829,8 +348282b,2 +348282c,a0 +348282d,88 +348282f,32 +3482830,34 +3482831,8 +3482833,1 +3482834,a0 +3482835,88 +3482837,3a +3482838,a0 +3482839,88 +348283b,3c +348283c,34 +348283d,8 +348283f,60 +3482840,a4 +3482841,88 +3482842,13 +3482843,f4 +3482844,a0 +3482845,88 +3482847,33 +3482848,3 +3482849,e0 +348284b,8 +3482850,90 +3482851,88 +3482853,7c +3482854,34 +3482855,1 +3482857,ff +3482858,11 +3482859,1 +348285b,6 +348285c,34 +348285d,2 +348285f,6b +3482860,90 +3482861,88 +3482863,94 +3482864,2d +3482865,8 +3482867,6 +3482868,11 +348286b,2 +348286c,34 +348286d,2 +348286f,6a +3482870,34 +3482871,2 +3482873,3 +3482874,3 +3482875,e0 +3482877,8 +348287c,90 +348287d,88 +348287f,7b +3482880,34 +3482881,1 +3482883,ff +3482884,11 +3482885,1 +3482887,2 +3482888,34 +3482889,a2 +348288c,34 +348288d,2 +348288f,c +3482890,3 +3482891,e0 +3482893,8 +3482898,34 +3482899,8 +348289b,7 +348289c,a0 +348289d,88 +348289f,7b +34828a0,3 +34828a1,e0 +34828a3,8 +34828a8,34 +34828a9,8 +34828ab,1 +34828ad,a8 +34828ae,40 +34828af,4 +34828b0,8c +34828b1,89 +34828b3,a4 +34828b4,1 +34828b5,28 +34828b6,48 +34828b7,25 +34828b8,ac +34828b9,89 +34828bb,a4 +34828bc,3 +34828bd,e0 +34828bf,8 +34828c4,30 +34828c5,84 +34828c7,ff +34828c8,3c +34828c9,8 +34828ca,80 +34828cb,12 +34828cc,25 +34828cd,8 +34828ce,a5 +34828cf,d0 +34828d0,34 +34828d1,1 +34828d3,8c +34828d4,10 +34828d5,81 +34828d7,16 +34828d8,91 +34828d9,2 +34828db,75 +34828dc,34 +34828dd,1 +34828df,8d +34828e0,10 +34828e1,81 +34828e3,13 +34828e4,91 +34828e5,2 +34828e7,75 +34828e8,10 +34828e9,80 +34828eb,11 +34828ec,91 +34828ed,2 +34828ef,74 +34828f0,34 +34828f1,1 +34828f3,8a +34828f4,10 +34828f5,81 +34828f7,e +34828f8,91 +34828f9,2 +34828fb,74 +34828fc,34 +34828fd,1 +34828ff,8b +3482900,10 +3482901,81 +3482903,b +3482904,91 +3482905,2 +3482907,74 +3482908,34 +3482909,1 +348290b,58 +348290c,10 +348290d,81 +348290f,8 +3482910,34 +3482911,2 +3482914,34 +3482915,1 +3482917,78 +3482918,10 +3482919,81 +348291b,5 +348291c,34 +348291d,2 +3482920,34 +3482921,1 +3482923,79 +3482924,10 +3482925,81 +3482927,2 +3482928,34 +3482929,2 +348292c,34 +348292d,2 +348292f,ff +3482930,3 +3482931,e0 +3482933,8 +3482938,27 +3482939,bd +348293a,ff +348293b,e0 +348293c,af +348293d,bf +348293f,10 +3482940,af +3482941,b0 +3482943,14 +3482944,c +3482945,10 +3482946,b +3482947,2f +348294c,4 +348294d,41 +348294f,2 +3482954,34 +3482955,2 +3482957,5b +3482959,40 +348295a,20 +348295b,21 +348295c,c +348295d,10 +348295e,b +348295f,aa +3482964,10 +3482965,60 +3482967,1a +3482968,af +3482969,a3 +348296b,1c +348296c,90 +348296d,65 +348296f,3 +3482970,2 +3482971,20 +3482972,20 +3482973,21 +3482974,c +3482975,3 +3482976,73 +3482977,85 +348297a,30 +348297b,21 +348297c,8f +348297d,a3 +348297f,1c +3482980,3c +3482981,8 +3482982,80 +3482983,40 +3482984,25 +3482985,8 +3482986,20 +3482988,85 +3482989,9 +348298b,2 +348298c,11 +348298d,20 +348298f,3 +3482990,34 +3482991,a +3482993,1 +3482994,10 +3482997,23 +3482998,a5 +3482999,a +348299c,3c +348299d,4 +348299e,80 +348299f,12 +34829a0,24 +34829a1,84 +34829a2,a5 +34829a3,d0 +34829a4,90 +34829a5,65 +34829a7,6 +34829a8,90 +34829a9,66 +34829ab,7 +34829ac,8c +34829ad,69 +34829af,8 +34829b0,1 +34829b1,20 +34829b2,f8 +34829b3,9 +34829b8,8f +34829b9,a3 +34829bb,1c +34829bc,90 +34829bd,65 +34829bf,1 +34829c0,c +34829c1,1 +34829c2,bf +34829c3,73 +34829c4,2 +34829c5,20 +34829c6,20 +34829c7,21 +34829c8,10 +34829cb,16 +34829d0,3c +34829d1,9 +34829d2,80 +34829d3,3b +34829d4,25 +34829d5,29 +34829d6,9e +34829d7,7e +34829d8,34 +34829d9,a +34829db,6 +34829dd,4a +34829df,18 +34829e2,50 +34829e3,12 +34829e4,1 +34829e5,2a +34829e6,80 +34829e7,21 +34829e8,2 +34829e9,20 +34829ea,20 +34829eb,21 +34829ec,92 +34829ed,5 +34829ef,3 +34829f0,c +34829f1,3 +34829f2,73 +34829f3,85 +34829f6,30 +34829f7,21 +34829f8,82 +34829f9,5 +34829fc,3c +34829fd,8 +34829fe,80 +34829ff,40 +3482a00,25 +3482a01,8 +3482a02,20 +3482a04,85 +3482a05,9 +3482a07,2 +3482a08,11 +3482a09,20 +3482a0b,3 +3482a0c,34 +3482a0d,a +3482a0f,1 +3482a10,a5 +3482a11,a +3482a14,34 +3482a15,5 +3482a17,41 +3482a18,c +3482a19,1 +3482a1a,bf +3482a1b,73 +3482a1c,2 +3482a1d,20 +3482a1e,20 +3482a1f,21 +3482a20,92 +3482a21,5 +3482a23,3 +3482a24,8f +3482a25,bf +3482a27,10 +3482a28,8f +3482a29,b0 +3482a2b,14 +3482a2c,27 +3482a2d,bd +3482a2f,20 +3482a30,3 +3482a31,e0 +3482a33,8 +3482a38,8f +3482a39,a6 +3482a3b,30 +3482a3c,84 +3482a3d,c5 +3482a3f,4 +3482a40,8 +3482a41,10 +3482a42,a +3482a43,96 +3482a48,8f +3482a49,b9 +3482a4b,2c +3482a4c,87 +3482a4d,25 +3482a4f,4 +3482a50,8 +3482a51,10 +3482a52,a +3482a53,96 +3482a58,3c +3482a59,a +3482a5a,80 +3482a5b,40 +3482a5c,25 +3482a5d,4a +3482a5e,20 +3482a5f,8 +3482a60,8d +3482a61,4b +3482a63,c +3482a64,11 +3482a65,60 +3482a67,2 +3482a6c,95 +3482a6d,45 +3482a6f,4 +3482a70,3c +3482a71,a +3482a72,80 +3482a73,1e +3482a74,25 +3482a75,4a +3482a76,89 +3482a77,84 +3482a78,a5 +3482a79,40 +3482a7c,3c +3482a7d,9 +3482a7e,80 +3482a7f,40 +3482a80,25 +3482a81,29 +3482a82,20 +3482a83,18 +3482a84,81 +3482a85,2a +3482a87,3 +3482a88,5 +3482a89,40 +3482a8b,b +3482a8c,1 +3482a8d,2a +3482a8e,48 +3482a8f,20 +3482a90,81 +3482a91,28 +3482a94,34 +3482a95,a +3482a97,7f +3482a98,15 +3482a99,a +3482a9b,6 +3482aa0,3c +3482aa1,a +3482aa2,80 +3482aa3,12 +3482aa4,25 +3482aa5,4a +3482aa6,a5 +3482aa7,d0 +3482aa8,85 +3482aa9,48 +3482aab,90 +3482aac,21 +3482aad,8 +3482aaf,1 +3482ab0,a5 +3482ab1,48 +3482ab3,90 +3482ab4,a1 +3482ab5,20 +3482ab8,3 +3482ab9,e0 +3482abb,8 +3482ac0,3c +3482ac1,8 +3482ac2,80 +3482ac3,40 +3482ac4,25 +3482ac5,8 +3482ac6,20 +3482ac7,8 +3482ac8,8d +3482ac9,9 +3482acb,c +3482acc,11 +3482acd,20 +3482acf,2 +3482ad4,81 +3482ad5,3 +3482ad7,2 +3482ad9,3 +3482ada,f +3482adb,c3 +3482add,61 +3482ade,40 +3482adf,26 +3482ae0,1 +3482ae1,1 +3482ae2,40 +3482ae3,23 +3482ae4,a0 +3482ae5,88 +3482ae6,8 +3482ae7,52 +3482ae8,3 +3482ae9,e0 +3482aeb,8 +3482af0,90 +3482af1,45 +3482af3,3 +3482af4,3c +3482af5,8 +3482af6,80 +3482af7,40 +3482af8,25 +3482af9,8 +3482afa,20 +3482afb,8 +3482afc,8d +3482afd,9 +3482aff,c +3482b00,11 +3482b01,20 +3482b03,2 +3482b08,91 +3482b09,5 +3482b0b,3 +3482b0c,3 +3482b0d,e0 +3482b0f,8 +3482b14,8f +3482b15,a2 +3482b17,24 +3482b18,90 +3482b19,45 +3482b1c,3c +3482b1d,8 +3482b1e,80 +3482b1f,40 +3482b20,25 +3482b21,8 +3482b22,20 +3482b24,85 +3482b25,9 +3482b27,2 +3482b28,11 +3482b29,20 +3482b2b,4 +3482b2c,34 +3482b2d,a +3482b2f,1 +3482b30,a5 +3482b31,a +3482b34,10 +3482b37,18 +3482b38,34 +3482b39,5 +3482b3b,41 +3482b3c,3c +3482b3d,8 +3482b3e,80 +3482b3f,40 +3482b40,25 +3482b41,8 +3482b42,20 +3482b43,8 +3482b44,8d +3482b45,9 +3482b47,c +3482b48,11 +3482b49,20 +3482b4b,13 +3482b50,91 +3482b51,5 +3482b53,1 +3482b54,af +3482b55,a4 +3482b58,af +3482b59,a5 +3482b5b,4 +3482b5c,af +3482b5d,a6 +3482b5f,8 +3482b60,27 +3482b61,bd +3482b62,ff +3482b63,e8 +3482b64,af +3482b65,bf +3482b67,10 +3482b68,3c +3482b69,4 +3482b6a,80 +3482b6b,12 +3482b6c,24 +3482b6d,84 +3482b6e,a5 +3482b6f,d0 +3482b70,91 +3482b71,5 +3482b73,6 +3482b74,91 +3482b75,6 +3482b77,7 +3482b78,8d +3482b79,9 +3482b7b,8 +3482b7c,1 +3482b7d,20 +3482b7e,f8 +3482b7f,9 +3482b84,8f +3482b85,bf +3482b87,10 +3482b88,27 +3482b89,bd +3482b8b,18 +3482b8c,8f +3482b8d,a4 +3482b90,8f +3482b91,a5 +3482b93,4 +3482b94,8f +3482b95,a6 +3482b97,8 +3482b98,3 +3482b99,e0 +3482b9b,8 +3482ba0,a0 +3482ba1,e6 +3482ba2,4 +3482ba3,24 +3482ba4,27 +3482ba5,bd +3482ba6,ff +3482ba7,e0 +3482ba8,af +3482ba9,a2 +3482bab,10 +3482bac,af +3482bad,a3 +3482baf,14 +3482bb0,af +3482bb1,bf +3482bb3,18 +3482bb4,c +3482bb5,10 +3482bb6,a +3482bb7,f5 +3482bbc,8f +3482bbd,a2 +3482bbf,10 +3482bc0,8f +3482bc1,a3 +3482bc3,14 +3482bc4,8f +3482bc5,bf +3482bc7,18 +3482bc8,27 +3482bc9,bd +3482bcb,20 +3482bcc,3 +3482bcd,e0 +3482bcf,8 +3482bd4,27 +3482bd5,bd +3482bd6,ff +3482bd7,e8 +3482bd8,af +3482bd9,bf +3482bdb,10 +3482bdc,3c +3482bdd,8 +3482bde,80 +3482bdf,40 +3482be0,25 +3482be1,8 +3482be2,20 +3482be3,8 +3482be4,ad +3482be8,ad +3482beb,4 +3482bec,ad +3482bef,8 +3482bf0,ad +3482bf3,c +3482bf4,3c +3482bf5,8 +3482bf6,80 +3482bf7,1e +3482bf8,25 +3482bf9,8 +3482bfa,aa +3482bfb,30 +3482bfc,81 +3482bfd,9 +3482bfe,4 +3482bff,24 +3482c00,11 +3482c01,20 +3482c03,2a +3482c09,9 +3482c0a,f +3482c0b,c3 +3482c0c,1 +3482c0d,21 +3482c0e,20 +3482c0f,26 +3482c11,81 +3482c12,20 +3482c13,23 +3482c14,8d +3482c15,5 +3482c16,4 +3482c17,28 +3482c18,c +3482c19,10 +3482c1a,b +3482c1b,2f +3482c20,4 +3482c21,40 +3482c23,22 +3482c28,34 +3482c29,44 +3482c2c,c +3482c2d,10 +3482c2e,b +3482c2f,aa +3482c34,10 +3482c35,60 +3482c37,c +3482c3c,3c +3482c3d,8 +3482c3e,80 +3482c3f,40 +3482c40,25 +3482c41,8 +3482c42,20 +3482c43,8 +3482c44,8c +3482c45,69 +3482c48,ad +3482c49,9 +3482c4c,8c +3482c4d,69 +3482c4f,4 +3482c50,ad +3482c51,9 +3482c53,4 +3482c54,8c +3482c55,69 +3482c57,8 +3482c58,ad +3482c59,9 +3482c5b,8 +3482c5c,34 +3482c5d,9 +3482c5f,1 +3482c60,ad +3482c61,9 +3482c63,c +3482c64,90 +3482c65,62 +3482c68,3c +3482c69,8 +3482c6a,80 +3482c6b,1e +3482c6c,25 +3482c6d,8 +3482c6e,aa +3482c6f,30 +3482c70,8d +3482c71,9 +3482c72,4 +3482c73,28 +3482c74,95 +3482c75,2a +3482c78,34 +3482c79,1 +3482c7b,a +3482c7c,15 +3482c7d,41 +3482c7f,6 +3482c84,95 +3482c85,2a +3482c87,1c +3482c88,31 +3482c89,4a +3482c8a,f0 +3482c8b,1f +3482c8d,2 +3482c8e,59 +3482c8f,40 +3482c90,1 +3482c91,4b +3482c92,50 +3482c93,25 +3482c94,a5 +3482c95,2a +3482c97,1c +3482c98,81 +3482c99,9 +3482c9a,4 +3482c9b,24 +3482c9c,5 +3482c9d,21 +3482c9f,2 +3482ca5,2 +3482ca6,10 +3482ca7,23 +3482ca8,a1 +3482ca9,2 +3482caa,4 +3482cab,24 +3482cac,8f +3482cad,bf +3482caf,10 +3482cb0,27 +3482cb1,bd +3482cb3,18 +3482cb4,3 +3482cb5,e0 +3482cb7,8 +3482cbc,27 +3482cbd,bd +3482cbe,ff +3482cbf,e8 +3482cc0,af +3482cc1,bf +3482cc3,10 +3482cc4,c +3482cc5,10 +3482cc6,b +3482cc7,3d +3482ccc,24 +3482ccd,1 +3482cce,ff +3482ccf,ff +3482cd0,10 +3482cd1,41 +3482cd3,4 +3482cd8,34 +3482cd9,44 +3482cdc,c +3482cdd,10 +3482cde,b +3482cdf,7b +3482ce4,8f +3482ce5,bf +3482ce7,10 +3482ce8,27 +3482ce9,bd +3482ceb,18 +3482cec,3 +3482ced,e0 +3482cef,8 +3482cf4,3c +3482cf5,2 +3482cf6,80 +3482cf7,1d +3482cf8,24 +3482cf9,42 +3482cfa,84 +3482cfb,a0 +3482cfc,94 +3482cfd,42 +3482cff,a4 +3482d00,34 +3482d01,8 +3482d04,34 +3482d05,89 +3482d08,94 +3482d09,aa +3482d0c,34 +3482d0d,1 +3482d0e,1 +3482d0f,9c +3482d10,15 +3482d11,41 +3482d13,8 +3482d18,34 +3482d19,8 +3482d1b,3 +3482d1c,94 +3482d1d,ab +3482d1f,1c +3482d20,31 +3482d21,69 +3482d23,ff +3482d24,31 +3482d25,62 +3482d26,1f +3482d29,2 +3482d2a,12 +3482d2b,2 +3482d2c,10 +3482d2f,1f +3482d34,34 +3482d35,1 +3482d37,a +3482d38,15 +3482d39,41 +3482d3b,e +3482d40,94 +3482d41,ab +3482d43,1c +3482d44,34 +3482d45,1 +3482d47,10 +3482d48,14 +3482d49,41 +3482d4b,8 +3482d50,31 +3482d51,6c +3482d52,f +3482d53,e0 +3482d54,34 +3482d55,1 +3482d56,e +3482d57,a0 +3482d58,15 +3482d59,81 +3482d5b,4 +3482d60,24 +3482d61,2 +3482d62,ff +3482d63,ff +3482d64,10 +3482d67,1f +3482d6c,34 +3482d6d,8 +3482d6f,1 +3482d70,31 +3482d71,69 +3482d73,1f +3482d74,34 +3482d75,1 +3482d77,15 +3482d78,15 +3482d79,41 +3482d7b,c +3482d80,34 +3482d81,1 +3482d83,3e +3482d84,10 +3482d85,81 +3482d87,7 +3482d8c,34 +3482d8d,1 +3482d8f,42 +3482d90,10 +3482d91,81 +3482d93,4 +3482d98,24 +3482d99,2 +3482d9a,ff +3482d9b,ff +3482d9c,10 +3482d9f,11 +3482da4,34 +3482da5,8 +3482da7,2 +3482da8,90 +3482da9,a9 +3482daa,1 +3482dab,41 +3482dac,34 +3482dad,1 +3482dae,1 +3482daf,1a +3482db0,15 +3482db1,41 +3482db3,8 +3482db8,34 +3482db9,1 +3482dbb,3e +3482dbc,14 +3482dbd,41 +3482dbf,5 +3482dc4,34 +3482dc5,8 +3482dc7,4 +3482dc8,3c +3482dc9,b +3482dca,80 +3482dcb,12 +3482dcc,25 +3482dcd,6b +3482dce,a5 +3482dcf,d0 +3482dd0,81 +3482dd1,62 +3482dd2,13 +3482dd3,97 +3482dd5,2 +3482dd6,12 +3482dd9,48 +3482dda,10 +3482ddb,25 +3482ddd,2 +3482dde,12 +3482de1,49 +3482de2,10 +3482de3,25 +3482de4,3 +3482de5,e0 +3482de7,8 +3482dec,24 +3482ded,2 +3482dee,ff +3482def,ff +3482df0,3c +3482df1,8 +3482df2,80 +3482df3,40 +3482df4,25 +3482df5,8 +3482df6,1c +3482df8,91 +3482df9,9 +3482dfc,3c +3482dfd,8 +3482dfe,80 +3482dff,40 +3482e00,25 +3482e01,8 +3482e02,1c +3482e03,2 +3482e04,a1 +3482e05,9 +3482e08,30 +3482e09,89 +3482e0b,ff +3482e0c,34 +3482e0d,1 +3482e0f,7f +3482e10,15 +3482e11,21 +3482e13,7 +3482e18,3c +3482e19,8 +3482e1a,80 +3482e1b,40 +3482e1c,25 +3482e1d,8 +3482e1e,1c +3482e20,91 +3482e21,b +3482e24,91 +3482e25,2 +3482e27,1 +3482e28,10 +3482e2b,10 +3482e30,3c +3482e31,8 +3482e32,80 +3482e33,40 +3482e34,25 +3482e35,8 +3482e36,f +3482e37,fc +3482e38,25 +3482e39,8 +3482e3b,4 +3482e3c,8d +3482e3d,9 +3482e40,11 +3482e41,20 +3482e43,17 +3482e49,9 +3482e4a,52 +3482e4b,2 +3482e4c,31 +3482e4d,4b +3482e4e,f8 +3482e51,b +3482e52,5a +3482e53,c2 +3482e54,3c +3482e55,c +3482e56,ff +3482e57,ff +3482e58,35 +3482e59,8c +3482e5a,7 +3482e5b,ff +3482e5c,1 +3482e5d,4c +3482e5e,50 +3482e5f,24 +3482e60,15 +3482e61,44 +3482e62,ff +3482e63,f5 +3482e68,31 +3482e69,22 +3482e6b,ff +3482e6c,3c +3482e6d,8 +3482e6e,80 +3482e6f,40 +3482e70,25 +3482e71,8 +3482e72,1c +3482e73,2 +3482e74,a1 +3482e75,b +3482e78,3c +3482e79,9 +3482e7a,80 +3482e7b,40 +3482e7c,25 +3482e7d,29 +3482e7e,20 +3482e80,3c +3482e81,c +3482e82,80 +3482e83,40 +3482e84,25 +3482e85,8c +3482e86,1c +3482e88,91 +3482e89,8c +3482e8c,11 +3482e8d,6c +3482e8f,4 +3482e90,a5 +3482e91,20 +3482e93,2 +3482e94,a1 +3482e95,2b +3482e97,2 +3482e98,a1 +3482e99,22 +3482e9b,3 +3482e9c,ad +3482e9d,24 +3482e9f,4 +3482ea0,3 +3482ea1,e0 +3482ea3,8 +3482ea8,27 +3482ea9,bd +3482eaa,ff +3482eab,e0 +3482eac,af +3482ead,b0 +3482eaf,10 +3482eb0,af +3482eb1,b1 +3482eb3,14 +3482eb4,af +3482eb5,bf +3482eb7,18 +3482eb8,34 +3482eb9,82 +3482ebc,34 +3482ebd,50 +3482ec0,26 +3482ec1,8 +3482ec2,ff +3482ec3,80 +3482ec4,5 +3482ec7,12 +3482ecc,3c +3482ecd,11 +3482ece,80 +3482ecf,40 +3482ed0,26 +3482ed1,31 +3482ed2,20 +3482ed3,50 +3482ed4,34 +3482ed5,9 +3482ed7,10 +3482ed8,1 +3482ed9,9 +3482edb,18 +3482ede,40 +3482edf,12 +3482ee0,2 +3482ee1,28 +3482ee2,88 +3482ee3,21 +3482ee4,3c +3482ee5,4 +3482ee6,80 +3482ee7,12 +3482ee8,24 +3482ee9,84 +3482eea,a5 +3482eeb,d0 +3482eec,36 +3482eed,5 +3482ef0,8e +3482ef1,28 +3482ef3,c +3482ef4,1 +3482ef6,f8 +3482ef7,9 +3482efc,14 +3482efd,50 +3482efe,ff +3482eff,ef +3482f04,36 +3482f05,23 +3482f08,10 +3482f0b,2 +3482f10,34 +3482f11,3 +3482f14,8f +3482f15,b0 +3482f17,10 +3482f18,8f +3482f19,b1 +3482f1b,14 +3482f1c,8f +3482f1d,bf +3482f1f,18 +3482f20,27 +3482f21,bd +3482f23,20 +3482f24,3 +3482f25,e0 +3482f27,8 +3482f2c,8c +3482f2d,88 +3482f2e,1d +3482f2f,2c +3482f30,34 +3482f31,9 +3482f33,1 +3482f35,9 +3482f36,4e +3482f38,1 +3482f39,9 +3482f3a,10 +3482f3b,24 +3482f3c,10 +3482f3d,40 +3482f3f,24 +3482f44,94 +3482f45,ca +3482f46,2 +3482f47,dc +3482f48,3c +3482f49,b +3482f4a,80 +3482f4b,12 +3482f4c,25 +3482f4d,6b +3482f4e,a5 +3482f4f,d0 +3482f50,94 +3482f51,8c +3482f53,a4 +3482f54,34 +3482f55,1 +3482f57,3d +3482f58,11 +3482f59,81 +3482f5b,a +3482f61,8a +3482f62,60 +3482f63,21 +3482f64,91 +3482f65,8d +3482f66,1d +3482f67,28 +3482f68,15 +3482f69,a0 +3482f6b,19 +3482f70,34 +3482f71,d +3482f73,1 +3482f74,a1 +3482f75,8d +3482f76,1d +3482f77,28 +3482f78,25 +3482f79,4a +3482f7b,3 +3482f7c,10 +3482f7f,9 +3482f84,34 +3482f85,c +3482f87,1 +3482f88,1 +3482f89,4c +3482f8a,60 +3482f8b,4 +3482f8c,91 +3482f8d,6d +3482f8e,e +3482f8f,f2 +3482f90,1 +3482f91,ac +3482f92,70 +3482f93,24 +3482f94,15 +3482f95,c0 +3482f97,e +3482f9c,1 +3482f9d,ac +3482f9e,70 +3482f9f,25 +3482fa0,a1 +3482fa1,6e +3482fa2,e +3482fa3,f2 +3482fa4,1 +3482fa5,29 +3482fa6,48 +3482fa7,27 +3482fa8,1 +3482fa9,9 +3482faa,40 +3482fab,24 +3482fac,ac +3482fad,88 +3482fae,1d +3482faf,2c +3482fb0,3c +3482fb1,8 +3482fb2,80 +3482fb3,40 +3482fb4,25 +3482fb5,8 +3482fb6,1d +3482fb7,5 +3482fb8,1 +3482fb9,a +3482fba,40 +3482fbb,21 +3482fbc,81 +3482fbd,8 +3482fc0,3c +3482fc1,9 +3482fc2,80 +3482fc3,40 +3482fc4,25 +3482fc5,29 +3482fc6,20 +3482fc7,18 +3482fc8,a1 +3482fc9,28 +3482fcc,34 +3482fcd,2 +3482fd0,3 +3482fd1,e0 +3482fd3,8 +3482fd8,3c +3482fd9,8 +3482fda,80 +3482fdb,40 +3482fdc,25 +3482fdd,8 +3482fde,1d +3482fdf,3 +3482fe0,81 +3482fe1,8 +3482fe4,10 +3482fe7,22 +3482fec,3c +3482fed,8 +3482fee,80 +3482fef,40 +3482ff0,25 +3482ff1,8 +3482ff2,1d +3482ff3,4 +3482ff4,81 +3482ff5,8 +3482ff8,10 +3482ffb,1d +3483000,34 +3483001,2 +3483003,ff +3483004,20 +3483005,e8 +3483006,ff +3483007,a6 +3483008,21 +3483009,8 +348300b,61 +348300c,10 +348300f,18 +3483014,34 +3483015,8 +3483017,64 +3483018,10 +348301b,15 +3483020,3c +3483021,1 +3483022,80 +3483023,12 +3483024,24 +3483025,21 +3483026,a5 +3483027,d0 +3483028,80 +3483029,28 +348302a,e +348302b,de +348302c,35 +348302d,8 +348302f,1 +3483030,a0 +3483031,28 +3483032,e +3483033,de +3483034,34 +3483035,8 +3483037,68 +3483038,10 +348303b,d +3483040,3c +3483041,1 +3483042,80 +3483043,12 +3483044,24 +3483045,21 +3483046,a5 +3483047,d0 +3483048,80 +3483049,28 +348304a,e +348304b,de +348304c,35 +348304d,8 +348304f,4 +3483050,a0 +3483051,28 +3483052,e +3483053,de +3483054,34 +3483055,8 +3483057,6a +3483058,10 +348305b,5 +3483060,34 +3483061,5 +3483063,3 +3483064,34 +3483065,8 +3483067,6b +3483068,10 +348306b,1 +3483070,3c +3483071,9 +3483072,80 +3483073,40 +3483074,25 +3483075,29 +3483076,20 +3483077,18 +3483078,3c +3483079,a +348307a,80 +348307b,40 +348307c,25 +348307d,4a +348307e,20 +348307f,1b +3483080,81 +3483081,2c +3483084,11 +3483085,88 +3483087,b +3483088,21 +3483089,29 +348308b,1 +348308c,15 +348308d,2a +348308e,ff +348308f,fc +3483094,3c +3483095,9 +3483096,80 +3483097,40 +3483098,25 +3483099,29 +348309a,20 +348309b,17 +348309c,21 +348309d,29 +348309f,1 +34830a0,11 +34830a1,2a +34830a3,4 +34830a4,81 +34830a5,2c +34830a8,15 +34830a9,80 +34830aa,ff +34830ab,fc +34830b0,a1 +34830b1,28 +34830b4,3 +34830b5,e0 +34830b7,8 +34830bd,60 +34830be,78 +34830bf,21 +34830c0,81 +34830c1,ec +34830c2,e +34830c3,df +34830c4,31 +34830c5,8e +34830c7,80 +34830c8,11 +34830c9,c0 +34830cb,3 +34830cc,34 +34830cd,3 +34830cf,5 +34830d0,3 +34830d1,e0 +34830d3,8 +34830d4,34 +34830d5,2 +34830d7,2 +34830d8,3 +34830d9,e0 +34830db,8 +34830dd,60 +34830de,10 +34830df,21 +34830e0,85 +34830e1,c2 +34830e3,a4 +34830e4,3c +34830e5,8 +34830e6,80 +34830e7,12 +34830e8,25 +34830e9,8 +34830ea,a5 +34830eb,d0 +34830ec,81 +34830ed,9 +34830ee,e +34830ef,df +34830f0,35 +34830f1,29 +34830f3,80 +34830f4,a1 +34830f5,9 +34830f6,e +34830f7,df +34830f8,3 +34830f9,e0 +34830fb,8 +3483100,27 +3483101,bd +3483102,ff +3483103,f0 +3483104,af +3483105,bf +3483107,4 +3483108,c +3483109,3 +348310a,58 +348310b,86 +3483110,3c +3483111,c +3483112,80 +3483113,12 +3483114,25 +3483115,8c +3483116,a5 +3483117,d0 +3483118,85 +3483119,8d +348311a,f +348311b,2e +348311c,8d +348311d,98 +348311f,4 +3483120,13 +3483123,2 +3483124,34 +3483125,e +3483127,1 +3483128,34 +3483129,e +348312b,2 +348312c,1 +348312d,ae +348312e,68 +348312f,25 +3483130,a5 +3483131,8d +3483132,f +3483133,2e +3483134,8f +3483135,bf +3483137,4 +3483138,27 +3483139,bd +348313b,10 +348313c,3 +348313d,e0 +348313f,8 +3483144,84 +3483145,8e +3483147,1c +3483148,21 +3483149,cd +348314a,ff +348314b,ce +348314c,5 +348314d,a0 +348314f,10 +3483150,34 +3483151,2 +3483154,31 +3483155,a9 +3483157,7 +3483158,34 +3483159,a +348315b,1 +348315c,1 +348315d,2a +348315e,50 +348315f,4 +3483161,d +3483162,48 +3483163,c2 +3483164,3c +3483165,c +3483166,80 +3483167,12 +3483168,25 +3483169,8c +348316a,a5 +348316b,d0 +348316c,1 +348316d,89 +348316e,60 +348316f,20 +3483170,81 +3483171,8b +3483172,5 +3483173,b4 +3483174,1 +3483175,6a +3483176,58 +3483177,24 +3483178,34 +3483179,2 +348317c,11 +348317d,60 +348317f,4 +3483184,34 +3483185,d +3483187,26 +3483188,a4 +3483189,8d +348318b,1c +348318c,34 +348318d,2 +348318f,1 +3483190,3 +3483191,e0 +3483193,8 +3483198,84 +3483199,ae +348319b,1c +348319c,21 +348319d,cd +348319e,ff +348319f,ce +34831a0,5 +34831a1,a0 +34831a3,b +34831a4,34 +34831a5,2 +34831a8,31 +34831a9,a9 +34831ab,7 +34831ac,34 +34831ad,a +34831af,1 +34831b0,1 +34831b1,2a +34831b2,50 +34831b3,4 +34831b5,d +34831b6,48 +34831b7,c2 +34831b8,3c +34831b9,c +34831ba,80 +34831bb,12 +34831bc,25 +34831bd,8c +34831be,a5 +34831bf,d0 +34831c0,1 +34831c1,89 +34831c2,60 +34831c3,20 +34831c4,81 +34831c5,8b +34831c6,5 +34831c7,b4 +34831c8,1 +34831c9,6a +34831ca,58 +34831cb,25 +34831cc,a1 +34831cd,8b +34831ce,5 +34831cf,b4 +34831d0,3 +34831d1,e0 +34831d3,8 +34831d8,27 +34831d9,bd +34831da,ff +34831db,f0 +34831dc,af +34831dd,bf +34831df,8 +34831e0,28 +34831e1,81 +34831e3,32 +34831e4,10 +34831e5,20 +34831e7,3 +34831e9,80 +34831ea,10 +34831eb,21 +34831ec,3 +34831ed,20 +34831ee,f8 +34831ef,9 +34831f4,8f +34831f5,bf +34831f7,8 +34831f8,27 +34831f9,bd +34831fb,10 +34831fc,3 +34831fd,e0 +34831ff,8 +3483204,3c +3483205,8 +3483206,80 +3483207,1d +3483208,25 +3483209,8 +348320a,84 +348320b,a0 +348320c,3c +348320d,9 +348320e,80 +348320f,12 +3483210,25 +3483211,29 +3483212,a5 +3483213,d0 +3483214,85 +3483215,a +3483217,a4 +3483218,34 +3483219,1 +348321b,3e +348321c,15 +348321d,41 +348321f,2 +3483220,81 +3483221,2b +3483222,13 +3483223,97 +3483224,21 +3483225,6a +3483227,2d +3483228,86 +3483229,b +348322b,1c +348322c,21 +348322d,6b +348322f,1 +3483230,34 +3483231,c +3483233,1 +3483234,1 +3483235,6c +3483236,60 +3483237,4 +3483238,34 +3483239,1 +348323b,1c +348323c,1 +348323d,41 +348323f,18 +3483242,68 +3483243,12 +3483244,1 +3483245,2d +3483246,70 +3483247,20 +3483248,8d +3483249,cf +348324b,e4 +348324c,1 +348324d,8f +348324e,10 +348324f,24 +3483250,3 +3483251,e0 +3483253,8 +3483258,3c +3483259,8 +348325a,80 +348325b,1d +348325c,25 +348325d,8 +348325e,84 +348325f,a0 +3483260,3c +3483261,9 +3483262,80 +3483263,12 +3483264,25 +3483265,29 +3483266,a5 +3483267,d0 +3483268,85 +3483269,a +348326b,a4 +348326c,34 +348326d,1 +348326f,3e +3483270,15 +3483271,41 +3483273,2 +3483274,81 +3483275,2b +3483276,13 +3483277,97 +3483278,21 +3483279,6a +348327b,2d +348327c,84 +348327d,8b +348327f,1c +3483280,21 +3483281,6b +3483283,1 +3483284,34 +3483285,c +3483287,1 +3483288,1 +3483289,6c +348328a,60 +348328b,4 +348328c,34 +348328d,1 +348328f,1c +3483290,1 +3483291,41 +3483293,18 +3483296,68 +3483297,12 +3483298,1 +3483299,2d +348329a,70 +348329b,20 +348329c,8d +348329d,cf +348329f,e4 +34832a0,1 +34832a1,8f +34832a2,78 +34832a3,25 +34832a4,ad +34832a5,cf +34832a7,e4 +34832a8,3 +34832a9,e0 +34832ab,8 +34832b0,27 +34832b1,bd +34832b2,ff +34832b3,e8 +34832b4,af +34832b5,bf +34832b7,10 +34832b8,3c +34832b9,a +34832ba,80 +34832bb,1e +34832bc,25 +34832bd,4a +34832be,aa +34832bf,30 +34832c0,81 +34832c1,48 +34832c2,6 +34832c3,6c +34832c4,31 +34832c5,8 +34832c7,20 +34832c8,15 +34832cb,23 +34832d0,3c +34832d1,a +34832d2,80 +34832d3,1d +34832d4,25 +34832d5,4a +34832d6,84 +34832d7,a0 +34832d8,8d +34832d9,48 +34832da,7 +34832db,94 +34832dc,15 +34832df,1e +34832e0,3c +34832e1,9 +34832e2,80 +34832e3,40 +34832e4,25 +34832e5,29 +34832e6,20 +34832e7,1b +34832e8,34 +34832e9,a +34832eb,ff +34832ec,a1 +34832ed,2a +34832f0,3c +34832f1,9 +34832f2,80 +34832f3,40 +34832f4,25 +34832f5,29 +34832f6,20 +34832f7,18 +34832f8,24 +34832f9,a +34832fa,ff +34832fb,ff +34832fc,34 +34832fd,c +34832ff,3 +3483300,21 +3483301,4a +3483303,1 +3483304,11 +3483305,4c +3483307,14 +3483308,1 +3483309,2a +348330a,58 +348330b,20 +348330c,81 +348330d,68 +3483310,11 +3483312,ff +3483313,fb +3483318,3c +3483319,9 +348331a,80 +348331b,40 +348331c,25 +348331d,29 +348331e,20 +348331f,1b +3483320,a1 +3483321,2a +3483324,3c +3483325,9 +3483326,80 +3483327,1e +3483328,25 +3483329,29 +348332a,89 +348332b,84 +348332c,34 +348332d,a +348332f,1 +3483330,a5 +3483331,2a +3483334,3c +3483335,9 +3483336,80 +3483337,48 +3483338,34 +3483339,a +348333b,1 +348333c,ad +348333d,2a +348333e,1 +348333f,30 +3483340,3c +3483341,a +3483342,80 +3483343,1e +3483344,25 +3483345,4a +3483346,aa +3483347,30 +3483348,a1 +3483349,48 +348334a,4 +348334b,24 +348334c,ad +348334d,49 +348334e,4 +348334f,28 +3483350,c +3483351,10 +3483352,a +3483353,f5 +3483358,8e +3483359,19 +348335b,4 +348335c,2 +348335e,20 +348335f,25 +3483360,8f +3483361,bf +3483363,10 +3483364,3 +3483365,e0 +3483367,8 +3483368,27 +3483369,bd +348336b,18 +348336c,27 +348336d,bd +348336e,ff +348336f,e8 +3483370,af +3483371,bf +3483373,10 +3483374,c +3483375,10 +3483376,17 +348337c,3c +348337d,e +348337e,80 +348337f,12 +3483380,91 +3483381,ce +3483382,12 +3483383,12 +3483384,8f +3483385,bf +3483387,10 +3483388,3 +3483389,e0 +348338b,8 +348338c,27 +348338d,bd +348338f,18 +3483390,34 +3483391,1 +3483393,ff +3483394,15 +3483395,21 +3483397,2 +3483398,92 +3483399,22 +348339c,34 +348339d,2 +348339f,ff +34833a0,3 +34833a1,e0 +34833a3,8 +34833a4,34 +34833a5,1 +34833a7,9 +34833a8,27 +34833a9,bd +34833aa,ff +34833ab,e8 +34833ac,af +34833ad,a2 +34833af,10 +34833b0,af +34833b1,bf +34833b3,14 +34833b4,c +34833b5,10 +34833b6,d +34833b7,e +34833bc,14 +34833bd,40 +34833bf,2 +34833c0,91 +34833c1,83 +34833c4,34 +34833c5,3 +34833c7,ff +34833c8,8f +34833c9,a2 +34833cb,10 +34833cc,8f +34833cd,bf +34833cf,14 +34833d0,27 +34833d1,bd +34833d3,18 +34833d4,3 +34833d5,e0 +34833d7,8 +34833d8,34 +34833d9,1 +34833db,9 +34833dc,27 +34833dd,bd +34833de,ff +34833df,e8 +34833e0,af +34833e1,a2 +34833e3,10 +34833e4,af +34833e5,bf +34833e7,14 +34833e8,96 +34833e9,2 +34833ea,1 +34833eb,e8 +34833ec,34 +34833ed,1 +34833ef,3 +34833f0,14 +34833f1,41 +34833f3,7 +34833f8,c +34833f9,10 +34833fa,d +34833fb,e +3483400,14 +3483401,40 +3483403,7 +3483408,10 +348340b,5 +348340c,34 +348340d,3 +348340f,7a +3483410,34 +3483411,1 +3483412,1 +3483413,7a +3483414,14 +3483415,61 +3483417,2 +348341c,34 +348341d,3 +348341f,7a +3483421,3 +3483422,62 +3483423,80 +3483424,1 +3483425,8d +3483426,28 +3483427,21 +3483428,8f +3483429,a2 +348342b,10 +348342c,8f +348342d,bf +348342f,14 +3483430,3 +3483431,e0 +3483433,8 +3483434,27 +3483435,bd +3483437,18 +3483438,27 +3483439,bd +348343a,ff +348343b,e8 +348343c,af +348343d,b0 +348343f,10 +3483440,af +3483441,b1 +3483443,14 +3483444,3c +3483445,2 +3483446,80 +3483447,12 +3483448,24 +3483449,42 +348344a,a5 +348344b,d0 +348344c,94 +348344d,42 +348344f,9c +3483450,3c +3483451,10 +3483452,80 +3483453,1e +3483454,26 +3483455,10 +3483456,8c +3483458,96 +3483459,11 +348345a,2 +348345b,32 +348345d,11 +348345e,88 +348345f,80 +3483460,2 +3483461,22 +3483462,10 +3483463,6 +3483464,96 +3483465,11 +3483466,2 +3483467,28 +3483468,26 +3483469,31 +348346a,ff +348346b,ff +348346c,34 +348346d,10 +348346f,1 +3483470,2 +3483471,30 +3483472,88 +3483473,4 +3483475,51 +3483476,10 +3483477,24 +3483478,8f +3483479,b0 +348347b,10 +348347c,8f +348347d,b1 +348347f,14 +3483480,3 +3483481,e0 +3483483,8 +3483484,27 +3483485,bd +3483487,18 +3483488,3c +3483489,8 +348348a,80 +348348b,12 +348348c,25 +348348d,8 +348348e,a5 +348348f,d0 +3483490,85 +3483491,9 +3483493,9c +3483494,35 +3483495,2a +3483497,2 +3483498,3 +3483499,e0 +348349b,8 +348349c,a5 +348349d,a +348349f,9c +34834a0,3c +34834a1,5 +34834a2,80 +34834a3,12 +34834a4,24 +34834a5,a5 +34834a6,a5 +34834a7,d0 +34834a8,3c +34834a9,8 +34834aa,80 +34834ab,40 +34834ac,25 +34834ad,8 +34834ae,20 +34834af,1c +34834b0,8c +34834b1,a9 +34834b3,68 +34834b4,ad +34834b5,9 +34834b8,8c +34834b9,a9 +34834bb,6c +34834bc,ad +34834bd,9 +34834bf,4 +34834c0,94 +34834c1,a9 +34834c3,70 +34834c4,a5 +34834c5,9 +34834c7,8 +34834c8,94 +34834c9,a9 +34834cb,9c +34834cc,a5 +34834cd,9 +34834cf,a +34834d0,8 +34834d1,1 +34834d2,be +34834d3,3 +34834d8,27 +34834d9,bd +34834da,ff +34834db,e0 +34834dc,af +34834dd,b0 +34834df,10 +34834e0,af +34834e1,b1 +34834e3,14 +34834e4,af +34834e5,bf +34834e7,18 +34834e8,3c +34834e9,10 +34834ea,80 +34834eb,12 +34834ec,26 +34834ed,10 +34834ee,a5 +34834ef,d0 +34834f0,3c +34834f1,11 +34834f2,80 +34834f3,40 +34834f4,26 +34834f5,31 +34834f6,20 +34834f7,1c +34834f8,8e +34834f9,8 +34834fb,4 +34834fc,11 +34834ff,5 +3483504,c +3483505,10 +3483506,d +3483507,60 +348350c,10 +348350f,3 +3483514,c +3483515,10 +3483516,d +3483517,73 +348351c,c +348351d,10 +348351e,d +348351f,53 +3483520,34 +3483521,4 +3483524,c +3483525,10 +3483526,d +3483527,53 +3483528,34 +3483529,4 +348352b,1 +348352c,c +348352d,10 +348352e,d +348352f,53 +3483530,34 +3483531,4 +3483533,2 +3483534,8f +3483535,b0 +3483537,10 +3483538,8f +3483539,b1 +348353b,14 +348353c,8f +348353d,bf +348353f,18 +3483540,27 +3483541,bd +3483543,20 +3483544,3 +3483545,e0 +3483547,8 +348354c,2 +348354d,4 +348354e,40 +348354f,21 +3483550,91 +3483551,9 +3483553,6c +3483554,34 +3483555,1 +3483557,ff +3483558,11 +3483559,21 +348355b,7 +3483560,2 +3483561,9 +3483562,48 +3483563,21 +3483564,91 +3483565,29 +3483567,74 +3483568,34 +3483569,1 +348356b,2c +348356c,11 +348356d,21 +348356f,2 +3483574,a1 +3483575,9 +3483577,69 +3483578,3 +3483579,e0 +348357b,8 +3483580,27 +3483581,bd +3483582,ff +3483583,e8 +3483584,af +3483585,bf +3483587,10 +3483588,8e +3483589,28 +348358c,ae +348358d,8 +348358f,40 +3483590,8e +3483591,28 +3483593,4 +3483594,ae +3483595,8 +3483597,44 +3483598,96 +3483599,28 +348359b,8 +348359c,a6 +348359d,8 +348359f,48 +34835a0,a2 +34835a2,f +34835a3,33 +34835a4,92 +34835a5,8 +34835a7,4a +34835a8,34 +34835a9,1 +34835ab,ff +34835ac,15 +34835ad,1 +34835af,3 +34835b4,c +34835b5,10 +34835b6,d +34835b7,81 +34835bc,8f +34835bd,bf +34835bf,10 +34835c0,27 +34835c1,bd +34835c3,18 +34835c4,3 +34835c5,e0 +34835c7,8 +34835cc,8e +34835cd,8 +34835cf,40 +34835d0,ae +34835d1,8 +34835d3,68 +34835d4,8e +34835d5,8 +34835d7,44 +34835d8,ae +34835d9,8 +34835db,6c +34835dc,96 +34835dd,8 +34835df,48 +34835e0,a6 +34835e1,8 +34835e3,70 +34835e4,92 +34835e5,8 +34835e7,68 +34835e8,34 +34835e9,1 +34835eb,ff +34835ec,15 +34835ed,1 +34835ef,3 +34835f4,34 +34835f5,8 +34835f7,1 +34835f8,a2 +34835f9,8 +34835fa,f +34835fb,33 +34835fc,3 +34835fd,e0 +34835ff,8 +3483604,27 +3483605,bd +3483606,ff +3483607,e8 +3483608,af +3483609,bf +348360b,10 +348360c,96 +348360d,8 +348360f,9c +3483610,31 +3483611,8 +3483613,40 +3483614,11 +3483617,5 +348361c,96 +348361d,8 +348361f,70 +3483620,31 +3483621,8 +3483622,ff +3483623,f +3483624,35 +3483625,8 +3483627,30 +3483628,a6 +3483629,8 +348362b,70 +348362c,92 +348362d,28 +348362f,1 +3483630,a2 +3483631,8 +3483633,69 +3483634,96 +3483635,28 +3483637,2 +3483638,a6 +3483639,8 +348363b,6a +348363c,8e +348363d,28 +348363f,4 +3483640,ae +3483641,8 +3483643,6c +3483644,c +3483645,10 +3483646,d +3483647,9b +3483648,34 +3483649,4 +348364c,c +348364d,10 +348364e,d +348364f,9b +3483650,34 +3483651,4 +3483653,1 +3483654,c +3483655,10 +3483656,d +3483657,9b +3483658,34 +3483659,4 +348365b,2 +348365c,8f +348365d,bf +348365f,10 +3483660,27 +3483661,bd +3483663,18 +3483664,3 +3483665,e0 +3483667,8 +348366c,2 +348366d,4 +348366e,40 +348366f,21 +3483670,3c +3483671,9 +3483672,80 +3483673,40 +3483674,25 +3483675,29 +3483676,37 +3483677,18 +3483678,91 +3483679,a +348367b,6c +348367c,34 +348367d,1 +348367f,ff +3483680,11 +3483681,41 +3483683,5 +3483688,1 +3483689,2a +348368a,48 +348368b,21 +348368c,91 +348368d,29 +3483690,15 +3483691,20 +3483693,1c +3483698,3c +3483699,9 +348369a,80 +348369b,40 +348369c,25 +348369d,29 +348369e,37 +348369f,b +34836a0,25 +34836a1,29 +34836a3,1 +34836a4,91 +34836a5,2a +34836a8,11 +34836a9,40 +34836ab,13 +34836b0,2 +34836b1,a +34836b2,58 +34836b3,21 +34836b4,91 +34836b5,6b +34836b7,74 +34836b8,34 +34836b9,1 +34836bb,ff +34836bc,11 +34836bd,61 +34836be,ff +34836bf,f8 +34836c4,92 +34836c5,c +34836c7,6c +34836c8,11 +34836c9,8a +34836ca,ff +34836cb,f5 +34836d0,92 +34836d1,c +34836d3,6d +34836d4,11 +34836d5,8a +34836d6,ff +34836d7,f2 +34836dc,92 +34836dd,c +34836df,6e +34836e0,11 +34836e1,8a +34836e2,ff +34836e3,ef +34836e8,a1 +34836e9,b +34836eb,69 +34836ec,a1 +34836ed,a +34836ef,6c +34836f0,10 +34836f3,4 +34836f8,34 +34836f9,9 +34836fb,ff +34836fc,a1 +34836fd,9 +34836ff,69 +3483700,a1 +3483701,9 +3483703,6c +3483704,3 +3483705,e0 +3483707,8 +348370c,7 +348370d,9 +348370e,f +348370f,2 +3483710,3 +3483711,1 +3483712,d +3483713,b +3483719,1 +348371a,1 +348371b,1 +348371c,1 +348371d,1 +348371f,1 +3483720,1 +3483721,1 +3483722,1 +3483723,1 +3483725,1 +3483727,1 +3483728,1 +3483729,1 +348372a,1 +348372b,1 +348372c,1 +348372d,1 +348372e,1 +3483731,33 +3483732,8 +3483733,21 +3483734,20 +3483735,f +3483737,47 +3483738,15 +3483739,ea +348373b,e +348373c,3c +348373d,2 +348373e,80 +348373f,12 +3483740,8c +3483741,42 +3483742,a5 +3483743,d4 +3483744,8e +3483745,6f +3483747,a4 +3483749,f +348374a,7a +348374b,3 +348374c,14 +348374d,40 +348374f,5 +3483750,34 +3483751,2 +3483752,48 +3483753,30 +3483754,15 +3483755,e2 +3483757,7 +348375c,24 +348375d,19 +348375f,3 +3483760,10 +3483763,4 +3483764,34 +3483765,2 +3483766,63 +3483767,11 +3483768,15 +3483769,e2 +348376b,2 +3483770,24 +3483771,19 +3483773,3 +3483774,3 +3483775,e0 +3483777,8 +348377c,8d +348377d,ad +348377e,8a +348377f,a0 +3483780,34 +3483781,2 +3483782,80 +3483784,10 +3483785,4d +3483787,2 +348378c,10 +348378f,9 +3483790,3c +3483791,f +3483792,80 +3483793,1e +3483794,25 +3483795,ef +3483796,84 +3483797,a0 +3483798,81 +3483799,e2 +348379a,1c +348379b,bf +348379c,30 +348379d,42 +348379f,1 +34837a0,10 +34837a1,40 +34837a3,2 +34837a8,10 +34837ab,2 +34837ac,34 +34837ad,2 +34837af,1 +34837b0,a1 +34837b1,e2 +34837b2,1c +34837b3,bf +34837b4,3 +34837b5,e0 +34837b7,8 +34837bd,33 +34837be,8 +34837bf,21 +34837c0,3c +34837c1,2 +34837c2,80 +34837c3,12 +34837c4,8c +34837c5,42 +34837c6,a5 +34837c7,d4 +34837c8,8e +34837c9,6f +34837cb,a4 +34837cd,f +34837ce,7a +34837cf,3 +34837d0,14 +34837d1,40 +34837d3,5 +34837d4,34 +34837d5,2 +34837d6,48 +34837d7,30 +34837d8,15 +34837d9,e2 +34837db,7 +34837e0,24 +34837e1,19 +34837e3,3 +34837e4,10 +34837e7,4 +34837e8,34 +34837e9,2 +34837ea,63 +34837eb,11 +34837ec,15 +34837ed,e2 +34837ef,2 +34837f4,24 +34837f5,19 +34837f7,3 +34837f8,3 +34837f9,e0 +34837fb,8 +3483800,34 +3483801,1 +3483803,18 +3483804,14 +3483805,81 +3483807,11 +348380c,14 +348380d,40 +348380f,f +3483814,3c +3483815,a +3483816,80 +3483817,12 +3483818,25 +3483819,4a +348381a,a5 +348381b,d0 +348381c,81 +348381d,48 +348381f,a6 +3483820,31 +3483821,8 +3483823,20 +3483824,11 +3483827,9 +3483828,34 +3483829,2 +348382c,34 +348382d,2 +348382f,1 +3483830,81 +3483831,48 +3483833,7b +3483834,34 +3483835,9 +3483837,7 +3483838,11 +3483839,9 +348383b,4 +348383c,34 +348383d,a +348383f,8 +3483840,11 +3483841,a +3483843,2 +3483848,34 +3483849,2 +348384c,3 +348384d,e0 +348384f,8 +3483854,80 +3483855,a8 +3483858,25 +3483859,9 +348385b,1 +348385c,15 +348385d,20 +348385f,e +3483864,27 +3483865,bd +3483866,ff +3483867,e8 +3483868,af +3483869,bf +348386b,14 +348386c,af +348386d,a4 +348386f,18 +3483870,af +3483871,a5 +3483873,1c +3483875,5 +3483876,20 +3483877,25 +3483878,24 +3483879,a5 +348387b,8 +348387c,c +348387d,1 +348387e,5c +348387f,c +3483880,24 +3483881,c6 +3483882,ff +3483883,f8 +3483884,8f +3483885,a4 +3483887,18 +3483888,8f +3483889,a5 +348388b,1c +348388c,34 +348388d,6 +348388f,80 +3483890,8f +3483891,bf +3483893,14 +3483894,27 +3483895,bd +3483897,18 +3483898,8 +3483899,1 +348389a,5c +348389b,c +34838a0,a2 +34838a1,25 +34838a3,21 +34838a4,3c +34838a5,10 +34838a6,80 +34838a7,40 +34838a8,26 +34838a9,10 +34838aa,17 +34838ab,fc +34838ac,26 +34838ad,10 +34838af,4 +34838b0,8e +34838b1,a +34838b4,11 +34838b5,40 +34838b7,b +34838bd,a +34838be,7c +34838bf,2 +34838c0,1 +34838c1,f1 +34838c2,78 +34838c3,20 +34838c4,31 +34838c5,58 +34838c6,ff +34838c9,18 +34838ca,c2 +34838cb,2 +34838cc,17 +34838cf,3 +34838d0,31 +34838d1,59 +34838d3,ff +34838d4,81 +34838d5,ea +34838d8,3 +34838d9,2a +34838da,c8 +34838db,25 +34838dc,8 +34838dd,10 +34838de,e +34838df,2b +34838e0,a1 +34838e1,f9 +34838e4,3 +34838e5,e0 +34838e7,8 +34838ec,27 +34838ed,bd +34838ee,ff +34838ef,f0 +34838f0,af +34838f1,bf +34838f3,8 +34838f4,c +34838f5,10 +34838f6,e +34838f7,49 +34838f8,22 +34838f9,64 +34838fa,ff +34838fb,ff +34838fc,34 +34838fd,4a +3483900,8f +3483901,bf +3483903,8 +3483904,27 +3483905,bd +3483907,10 +3483908,27 +3483909,bd +348390a,ff +348390b,f0 +348390c,af +348390d,bf +348390f,8 +3483910,c +3483911,10 +3483912,e +3483913,49 +3483914,36 +3483915,44 +3483918,34 +3483919,50 +348391c,8f +348391d,bf +348391f,8 +3483920,27 +3483921,bd +3483923,10 +3483924,3c +3483925,8 +3483926,80 +3483927,40 +3483928,25 +3483929,8 +348392a,1c +348392b,2 +348392c,91 +348392d,8 +3483930,15 +3483933,7 +3483938,3c +3483939,8 +348393a,80 +348393b,12 +348393c,25 +348393d,8 +348393e,a5 +348393f,d0 +3483940,1 +3483941,4 +3483942,40 +3483943,20 +3483944,91 +3483945,2 +3483947,24 +3483948,10 +348394b,7 +3483951,8 +3483952,40 +3483953,c0 +3483954,3c +3483955,2 +3483956,80 +3483957,40 +3483958,24 +3483959,42 +348395a,1c +348395b,3 +348395c,1 +348395d,2 +348395e,40 +348395f,20 +3483960,1 +3483961,4 +3483962,40 +3483963,20 +3483964,91 +3483965,2 +3483968,3 +3483969,e0 +348396b,8 +3483970,8f +3483971,b6 +3483973,30 +3483974,8f +3483975,b7 +3483977,34 +3483978,8f +3483979,be +348397b,38 +348397c,3c +348397d,8 +348397e,80 +348397f,40 +3483980,25 +3483981,8 +3483982,1c +3483983,2 +3483984,a1 +3483988,3 +3483989,e0 +348398b,8 +34b3000,27 +34b3001,bd +34b3002,ff +34b3003,e8 +34b3004,af +34b3005,bf +34b3007,14 +34b3008,c +34b3009,10 +34b300a,17 +34b300b,27 +34b300c,24 +34b300d,4 +34b300e,4 +34b3010,3c +34b3011,3 +34b3012,80 +34b3013,40 +34b3014,ac +34b3015,62 +34b3016,67 +34b3017,c +34b3018,3c +34b3019,3 +34b301a,80 +34b301b,40 +34b301c,ac +34b301d,62 +34b301e,67 +34b301f,8 +34b3020,8f +34b3021,bf +34b3023,14 +34b3024,3 +34b3025,e0 +34b3027,8 +34b3028,27 +34b3029,bd +34b302b,18 +34b302c,80 +34b302d,82 +34b3030,10 +34b3031,40 +34b3033,26 +34b3034,24 +34b3035,87 +34b3037,1 +34b3038,3c +34b3039,3 +34b303a,80 +34b303b,40 +34b303c,8c +34b303d,68 +34b303e,67 +34b303f,c +34b3040,25 +34b3041,8 +34b3042,4 +34b3044,3c +34b3045,3 +34b3046,80 +34b3047,40 +34b3048,8c +34b3049,63 +34b304a,67 +34b304b,8 +34b304d,68 +34b304e,20 +34b304f,2b +34b3050,10 +34b3051,80 +34b3053,1e +34b3054,3c +34b3055,a +34b3056,ff +34b3058,25 +34b3059,4a +34b305a,f +34b305b,ff +34b305c,30 +34b305d,c6 +34b305e,f +34b305f,ff +34b3060,24 +34b3061,b +34b3062,f0 +34b3064,3c +34b3065,9 +34b3066,80 +34b3067,40 +34b3068,10 +34b306b,7 +34b306c,25 +34b306d,29 +34b306e,66 +34b306f,68 +34b3071,68 +34b3072,20 +34b3073,2b +34b3074,54 +34b3075,80 +34b3077,5 +34b3078,a0 +34b3079,62 +34b307c,3c +34b307d,2 +34b307e,80 +34b307f,40 +34b3080,3 +34b3081,e0 +34b3083,8 +34b3084,ac +34b3085,43 +34b3086,67 +34b3087,8 +34b3088,a0 +34b3089,62 +34b308c,30 +34b308d,a2 +34b308e,f +34b308f,ff +34b3091,2 +34b3092,23 +34b3094,8c +34b3095,62 +34b3099,4a +34b309a,10 +34b309b,24 +34b309d,44 +34b309e,10 +34b309f,25 +34b30a1,4b +34b30a2,10 +34b30a3,24 +34b30a5,46 +34b30a6,10 +34b30a7,25 +34b30a8,ac +34b30a9,62 +34b30ac,95 +34b30ad,22 +34b30af,4 +34b30b1,a2 +34b30b2,28 +34b30b3,21 +34b30b4,24 +34b30b5,e7 +34b30b7,1 +34b30b8,80 +34b30b9,e2 +34b30ba,ff +34b30bb,ff +34b30bc,14 +34b30bd,40 +34b30be,ff +34b30bf,ec +34b30c0,24 +34b30c1,63 +34b30c3,4 +34b30c4,3c +34b30c5,2 +34b30c6,80 +34b30c7,40 +34b30c8,ac +34b30c9,43 +34b30ca,67 +34b30cb,8 +34b30cc,3 +34b30cd,e0 +34b30cf,8 +34b30d4,27 +34b30d5,bd +34b30d6,ff +34b30d7,b0 +34b30d8,af +34b30d9,bf +34b30db,4c +34b30dc,af +34b30dd,be +34b30df,48 +34b30e0,af +34b30e1,b7 +34b30e3,44 +34b30e4,af +34b30e5,b6 +34b30e7,40 +34b30e8,af +34b30e9,b5 +34b30eb,3c +34b30ec,af +34b30ed,b4 +34b30ef,38 +34b30f0,af +34b30f1,b3 +34b30f3,34 +34b30f4,af +34b30f5,b2 +34b30f7,30 +34b30f8,af +34b30f9,b1 +34b30fb,2c +34b30fc,af +34b30fd,b0 +34b30ff,28 +34b3101,80 +34b3102,a8 +34b3103,25 +34b3106,b0 +34b3107,25 +34b310a,90 +34b310b,25 +34b310c,3c +34b310d,14 +34b310e,80 +34b310f,40 +34b3110,26 +34b3111,94 +34b3112,66 +34b3113,68 +34b3114,3c +34b3115,1e +34b3116,80 +34b3117,40 +34b3118,3c +34b3119,13 +34b311a,80 +34b311b,40 +34b311c,3c +34b311d,17 +34b311e,38 +34b311f,e3 +34b3120,af +34b3121,b4 +34b3123,20 +34b3124,24 +34b3125,7 +34b3127,12 +34b3128,2 +34b3129,c0 +34b312a,30 +34b312b,25 +34b312c,2 +34b312d,80 +34b312e,28 +34b312f,25 +34b3130,c +34b3131,10 +34b3132,17 +34b3133,61 +34b3134,2 +34b3135,a0 +34b3136,20 +34b3137,25 +34b3138,8f +34b3139,c5 +34b313a,67 +34b313b,c +34b313c,10 +34b313f,1f +34b3140,36 +34b3141,f1 +34b3142,8e +34b3143,39 +34b3144,24 +34b3145,42 +34b3146,ff +34b3147,e0 +34b3149,51 +34b314b,18 +34b314e,18 +34b314f,10 +34b3151,3 +34b3152,18 +34b3153,83 +34b3155,2 +34b3156,27 +34b3157,c3 +34b3159,64 +34b315a,18 +34b315b,23 +34b315c,14 +34b315d,72 +34b315f,16 +34b3160,24 +34b3161,b0 +34b3163,4 +34b3164,8c +34b3165,a7 +34b3169,7 +34b316a,3b +34b316b,2 +34b316d,51 +34b316f,18 +34b3172,30 +34b3173,10 +34b3175,6 +34b3176,30 +34b3177,83 +34b3179,c4 +34b317a,30 +34b317b,23 +34b317d,6 +34b317e,18 +34b317f,c0 +34b3181,66 +34b3182,30 +34b3183,21 +34b3185,6 +34b3186,30 +34b3187,40 +34b3188,96 +34b3189,83 +34b318b,6 +34b318c,af +34b318d,a3 +34b318f,18 +34b3190,96 +34b3191,83 +34b3193,4 +34b3194,af +34b3195,a3 +34b3197,14 +34b3198,8c +34b3199,a3 +34b319c,30 +34b319d,63 +34b319e,f +34b319f,ff +34b31a0,af +34b31a1,a3 +34b31a3,10 +34b31a4,30 +34b31a5,e7 +34b31a6,f +34b31a7,ff +34b31a9,46 +34b31aa,30 +34b31ab,23 +34b31ac,8f +34b31ad,a5 +34b31af,20 +34b31b0,c +34b31b1,10 +34b31b2,17 +34b31b3,c9 +34b31b4,2 +34b31b5,a0 +34b31b6,20 +34b31b7,25 +34b31b8,2 +34b31ba,28 +34b31bb,25 +34b31bc,8e +34b31bd,62 +34b31be,67 +34b31bf,8 +34b31c1,a2 +34b31c2,10 +34b31c3,2b +34b31c4,54 +34b31c5,40 +34b31c6,ff +34b31c7,df +34b31c8,80 +34b31c9,a2 +34b31cc,26 +34b31cd,52 +34b31cf,1 +34b31d0,24 +34b31d1,2 +34b31d3,6 +34b31d4,16 +34b31d5,42 +34b31d6,ff +34b31d7,d3 +34b31d8,26 +34b31d9,d6 +34b31db,12 +34b31dc,3c +34b31dd,2 +34b31de,80 +34b31df,40 +34b31e0,8c +34b31e1,43 +34b31e2,67 +34b31e3,c +34b31e4,3c +34b31e5,2 +34b31e6,80 +34b31e7,40 +34b31e8,ac +34b31e9,43 +34b31ea,67 +34b31eb,8 +34b31ec,8f +34b31ed,bf +34b31ef,4c +34b31f0,8f +34b31f1,be +34b31f3,48 +34b31f4,8f +34b31f5,b7 +34b31f7,44 +34b31f8,8f +34b31f9,b6 +34b31fb,40 +34b31fc,8f +34b31fd,b5 +34b31ff,3c +34b3200,8f +34b3201,b4 +34b3203,38 +34b3204,8f +34b3205,b3 +34b3207,34 +34b3208,8f +34b3209,b2 +34b320b,30 +34b320c,8f +34b320d,b1 +34b320f,2c +34b3210,8f +34b3211,b0 +34b3213,28 +34b3214,3 +34b3215,e0 +34b3217,8 +34b3218,27 +34b3219,bd +34b321b,50 +34b321c,3c +34b321d,2 +34b321e,80 +34b321f,40 +34b3220,8c +34b3221,42 +34b3222,66 +34b3223,f8 +34b3224,10 +34b3225,40 +34b3226,2 +34b3227,69 +34b3228,3c +34b3229,3 +34b322a,80 +34b322b,40 +34b322c,27 +34b322d,bd +34b322e,ff +34b322f,90 +34b3230,af +34b3231,bf +34b3233,6c +34b3234,af +34b3235,be +34b3237,68 +34b3238,af +34b3239,b7 +34b323b,64 +34b323c,af +34b323d,b6 +34b323f,60 +34b3240,af +34b3241,b5 +34b3243,5c +34b3244,af +34b3245,b4 +34b3247,58 +34b3248,af +34b3249,b3 +34b324b,54 +34b324c,af +34b324d,b2 +34b324f,50 +34b3250,af +34b3251,b1 +34b3253,4c +34b3254,af +34b3255,b0 +34b3257,48 +34b3258,8c +34b3259,82 +34b325b,4 +34b325c,8c +34b325d,63 +34b325e,67 +34b325f,3c +34b3260,24 +34b3261,45 +34b3263,8 +34b3264,ac +34b3265,85 +34b3267,8 +34b3268,3c +34b3269,5 +34b326a,de +34b326c,ac +34b326d,45 +34b3270,ac +34b3271,43 +34b3273,4 +34b3274,3c +34b3275,2 +34b3276,80 +34b3277,11 +34b3278,34 +34b3279,42 +34b327a,a5 +34b327b,d0 +34b327c,94 +34b327d,54 +34b327e,f +34b327f,2e +34b3280,3c +34b3281,2 +34b3282,80 +34b3283,40 +34b3284,8c +34b3285,42 +34b3286,67 +34b3287,10 +34b3288,50 +34b3289,40 +34b328b,5 +34b328c,24 +34b328d,8 +34b328f,1 +34b3290,32 +34b3291,88 +34b3293,1 +34b3295,14 +34b3296,a0 +34b3297,42 +34b3298,10 +34b329b,2 +34b329c,32 +34b329d,94 +34b329f,1 +34b32a0,24 +34b32a1,14 +34b32a3,1 +34b32a4,3c +34b32a5,2 +34b32a6,80 +34b32a7,40 +34b32a8,8c +34b32a9,55 +34b32aa,67 +34b32ab,1c +34b32ac,12 +34b32ad,a0 +34b32af,7 +34b32b0,2 +34b32b1,a0 +34b32b2,18 +34b32b3,25 +34b32b4,3c +34b32b5,2 +34b32b6,80 +34b32b7,40 +34b32b8,94 +34b32b9,43 +34b32ba,66 +34b32bb,6c +34b32bd,3 +34b32be,10 +34b32bf,40 +34b32c1,43 +34b32c2,10 +34b32c3,21 +34b32c5,2 +34b32c6,10 +34b32c7,40 +34b32c8,24 +34b32c9,43 +34b32cb,1 +34b32cc,3c +34b32cd,2 +34b32ce,80 +34b32cf,40 +34b32d0,94 +34b32d1,42 +34b32d2,66 +34b32d3,6c +34b32d5,2 +34b32d6,10 +34b32d7,c0 +34b32d8,24 +34b32d9,42 +34b32db,57 +34b32dd,43 +34b32de,10 +34b32df,21 +34b32e0,24 +34b32e1,3 +34b32e2,1 +34b32e3,40 +34b32e5,62 +34b32e6,18 +34b32e7,23 +34b32e9,3 +34b32ea,8f +34b32eb,c2 +34b32ec,2 +34b32ed,23 +34b32ee,88 +34b32ef,21 +34b32f1,11 +34b32f2,88 +34b32f3,43 +34b32f4,26 +34b32f5,23 +34b32f7,1 +34b32f8,af +34b32f9,a3 +34b32fb,38 +34b32fc,8c +34b32fd,83 +34b32ff,8 +34b3300,24 +34b3301,65 +34b3303,8 +34b3304,ac +34b3305,85 +34b3307,8 +34b3308,3c +34b3309,5 +34b330a,fc +34b330b,ff +34b330c,34 +34b330d,a5 +34b330e,ff +34b330f,ff +34b3310,ac +34b3311,65 +34b3314,3c +34b3315,5 +34b3316,ff +34b3317,fd +34b3318,34 +34b3319,a5 +34b331a,f6 +34b331b,fb +34b331c,ac +34b331d,65 +34b331f,4 +34b3320,8c +34b3321,83 +34b3323,8 +34b3324,24 +34b3325,65 +34b3327,8 +34b3328,ac +34b3329,85 +34b332b,8 +34b332c,3c +34b332d,5 +34b332e,fa +34b3330,ac +34b3331,65 +34b3334,24 +34b3335,5 +34b3337,d0 +34b3338,ac +34b3339,65 +34b333b,4 +34b333d,51 +34b333e,10 +34b333f,21 +34b3341,2 +34b3342,13 +34b3343,80 +34b3344,3c +34b3345,3 +34b3347,ff +34b3348,34 +34b3349,63 +34b334a,f0 +34b334d,43 +34b334e,10 +34b334f,24 +34b3350,3c +34b3351,5 +34b3352,e4 +34b3354,24 +34b3355,a5 +34b3356,3 +34b3357,9c +34b3359,45 +34b335a,10 +34b335b,25 +34b335c,af +34b335d,a2 +34b335f,20 +34b3361,11 +34b3362,13 +34b3363,80 +34b3365,43 +34b3366,10 +34b3367,24 +34b3368,34 +34b3369,42 +34b336b,24 +34b336c,af +34b336d,a2 +34b336f,24 +34b3370,3c +34b3371,2 +34b3372,e1 +34b3374,af +34b3375,a2 +34b3377,28 +34b3378,af +34b3379,a0 +34b337b,2c +34b337c,3c +34b337d,2 +34b337e,f1 +34b3380,af +34b3381,a2 +34b3383,30 +34b3384,3c +34b3385,2 +34b3386,4 +34b3388,24 +34b3389,42 +34b338a,4 +34b338c,af +34b338d,a2 +34b338f,34 +34b3390,27 +34b3391,a2 +34b3393,20 +34b3394,27 +34b3395,a9 +34b3397,38 +34b3398,8c +34b3399,83 +34b339b,8 +34b339c,24 +34b339d,65 +34b339f,8 +34b33a0,ac +34b33a1,85 +34b33a3,8 +34b33a4,8c +34b33a5,47 +34b33a7,4 +34b33a8,8c +34b33a9,46 +34b33ac,ac +34b33ad,67 +34b33af,4 +34b33b0,24 +34b33b1,42 +34b33b3,8 +34b33b4,15 +34b33b5,22 +34b33b6,ff +34b33b7,f8 +34b33b8,ac +34b33b9,66 +34b33bd,80 +34b33be,80 +34b33bf,25 +34b33c0,8c +34b33c1,82 +34b33c3,8 +34b33c4,24 +34b33c5,43 +34b33c7,8 +34b33c8,ac +34b33c9,83 +34b33cb,8 +34b33cc,3c +34b33cd,3 +34b33ce,e7 +34b33d0,ac +34b33d1,43 +34b33d4,ac +34b33d5,40 +34b33d7,4 +34b33d8,8c +34b33d9,82 +34b33db,8 +34b33dc,24 +34b33dd,43 +34b33df,8 +34b33e0,ac +34b33e1,83 +34b33e3,8 +34b33e4,3c +34b33e5,3 +34b33e6,fc +34b33e7,11 +34b33e8,34 +34b33e9,63 +34b33ea,96 +34b33eb,23 +34b33ec,ac +34b33ed,43 +34b33f0,3c +34b33f1,3 +34b33f2,ff +34b33f3,2f +34b33f4,34 +34b33f5,63 +34b33f6,ff +34b33f7,ff +34b33f8,11 +34b33fb,4c +34b33fc,ac +34b33fd,43 +34b33ff,4 +34b3400,3c +34b3401,5 +34b3402,80 +34b3403,40 +34b3404,24 +34b3405,a5 +34b3406,66 +34b3407,98 +34b3408,94 +34b3409,a7 +34b340b,8 +34b340c,c +34b340d,10 +34b340e,17 +34b340f,61 +34b3412,30 +34b3413,25 +34b3414,3c +34b3415,2 +34b3416,80 +34b3417,40 +34b3418,8c +34b3419,42 +34b341a,66 +34b341b,fc +34b341c,18 +34b341d,40 +34b341f,43 +34b3420,3c +34b3421,2 +34b3422,80 +34b3423,40 +34b3424,3c +34b3425,13 +34b3426,80 +34b3427,40 +34b3428,26 +34b3429,73 +34b342a,65 +34b342b,cc +34b342e,90 +34b342f,25 +34b3430,3c +34b3431,1e +34b3432,80 +34b3433,40 +34b3434,3c +34b3435,16 +34b3436,80 +34b3437,40 +34b3438,26 +34b3439,d6 +34b343a,65 +34b343b,a8 +34b343c,24 +34b343d,42 +34b343e,65 +34b343f,b8 +34b3440,af +34b3441,a2 +34b3443,3c +34b3444,3c +34b3445,2 +34b3446,80 +34b3447,40 +34b3448,24 +34b3449,42 +34b344a,66 +34b344b,98 +34b344c,af +34b344d,a2 +34b344f,40 +34b3450,3c +34b3451,17 +34b3452,80 +34b3453,40 +34b3454,8f +34b3455,c2 +34b3456,67 +34b3457,14 +34b3458,50 +34b3459,40 +34b345b,b +34b345c,92 +34b345d,62 +34b3460,92 +34b3461,63 +34b3464,3c +34b3465,2 +34b3466,80 +34b3467,11 +34b3468,34 +34b3469,42 +34b346a,a5 +34b346b,d0 +34b346d,43 +34b346e,10 +34b346f,21 +34b3470,90 +34b3471,42 +34b3473,a8 +34b3475,2 +34b3476,10 +34b3477,42 +34b3478,30 +34b3479,42 +34b347b,1 +34b347c,50 +34b347d,40 +34b347f,27 +34b3480,26 +34b3481,52 +34b3483,1 +34b3484,92 +34b3485,62 +34b3489,56 +34b348a,10 +34b348b,21 +34b348c,80 +34b348d,46 +34b3490,28 +34b3491,c2 +34b3493,3 +34b3494,54 +34b3495,40 +34b3497,21 +34b3498,26 +34b3499,52 +34b349b,1 +34b349c,24 +34b349d,c6 +34b349e,ff +34b349f,fd +34b34a1,6 +34b34a2,18 +34b34a3,40 +34b34a5,66 +34b34a6,18 +34b34a7,21 +34b34a8,8f +34b34a9,a2 +34b34ab,3c +34b34ad,62 +34b34ae,18 +34b34af,21 +34b34b0,90 +34b34b1,62 +34b34b5,2 +34b34b6,16 +34b34b8,90 +34b34b9,64 +34b34bb,2 +34b34bd,4 +34b34be,22 +34b34c1,44 +34b34c2,10 +34b34c3,25 +34b34c4,90 +34b34c5,63 +34b34c7,1 +34b34c9,3 +34b34ca,1c +34b34cd,43 +34b34ce,10 +34b34cf,25 +34b34d0,34 +34b34d1,42 +34b34d3,ff +34b34d4,8e +34b34d5,3 +34b34d7,8 +34b34d8,24 +34b34d9,64 +34b34db,8 +34b34dc,ae +34b34dd,4 +34b34df,8 +34b34e0,3c +34b34e1,4 +34b34e2,fa +34b34e4,ac +34b34e5,64 +34b34e8,ac +34b34e9,62 +34b34eb,4 +34b34ec,24 +34b34ed,2 +34b34ef,10 +34b34f0,af +34b34f1,a2 +34b34f3,18 +34b34f4,af +34b34f5,a2 +34b34f7,14 +34b34f9,12 +34b34fa,11 +34b34fd,52 +34b34fe,10 +34b34ff,21 +34b3500,24 +34b3501,42 +34b3503,a +34b3504,af +34b3505,a2 +34b3507,10 +34b3508,8f +34b3509,a7 +34b350b,38 +34b350c,8f +34b350d,a5 +34b350f,40 +34b3510,c +34b3511,10 +34b3512,17 +34b3513,c9 +34b3514,2 +34b3516,20 +34b3517,25 +34b3518,26 +34b3519,52 +34b351b,1 +34b351c,8e +34b351d,e2 +34b351e,66 +34b351f,fc +34b3520,2 +34b3521,42 +34b3522,10 +34b3523,2a +34b3524,14 +34b3525,40 +34b3526,ff +34b3527,cb +34b3528,26 +34b3529,73 +34b352b,c +34b352c,8e +34b352d,2 +34b352f,8 +34b3530,24 +34b3531,43 +34b3533,8 +34b3534,ae +34b3535,3 +34b3537,8 +34b3538,3c +34b3539,3 +34b353a,fa +34b353c,ac +34b353d,43 +34b3540,24 +34b3541,3 +34b3542,ff +34b3543,ff +34b3544,12 +34b3545,80 +34b3547,35 +34b3548,ac +34b3549,43 +34b354b,4 +34b354c,3c +34b354d,5 +34b354e,80 +34b354f,40 +34b3550,24 +34b3551,a5 +34b3552,66 +34b3553,a8 +34b3554,94 +34b3555,a7 +34b3557,8 +34b355a,30 +34b355b,25 +34b355c,c +34b355d,10 +34b355e,17 +34b355f,61 +34b3560,2 +34b3562,20 +34b3563,25 +34b3564,3c +34b3565,2 +34b3566,80 +34b3567,40 +34b3568,8c +34b3569,42 +34b356a,66 +34b356b,fc +34b356c,18 +34b356d,40 +34b356e,1 +34b356f,95 +34b3570,3c +34b3571,2 +34b3572,80 +34b3573,40 +34b3574,3c +34b3575,13 +34b3576,80 +34b3577,40 +34b3578,26 +34b3579,73 +34b357a,65 +34b357b,cc +34b357e,90 +34b357f,25 +34b3580,3c +34b3581,17 +34b3582,80 +34b3583,40 +34b3584,3c +34b3585,14 +34b3586,80 +34b3587,40 +34b3588,26 +34b3589,94 +34b358a,65 +34b358b,a8 +34b358c,24 +34b358d,42 +34b358e,66 +34b358f,a8 +34b3590,af +34b3591,a2 +34b3593,3c +34b3594,3c +34b3595,1e +34b3596,80 +34b3597,11 +34b3598,37 +34b3599,de +34b359a,a5 +34b359b,d0 +34b359c,3c +34b359d,16 +34b359e,80 +34b359f,40 +34b35a0,8e +34b35a1,e2 +34b35a2,67 +34b35a3,14 +34b35a4,10 +34b35a5,40 +34b35a7,8 +34b35a8,92 +34b35a9,62 +34b35ac,3 +34b35ad,c2 +34b35ae,10 +34b35af,21 +34b35b0,90 +34b35b1,42 +34b35b3,a8 +34b35b5,2 +34b35b6,10 +34b35b7,42 +34b35b8,30 +34b35b9,42 +34b35bb,1 +34b35bc,50 +34b35bd,40 +34b35bf,13 +34b35c0,26 +34b35c1,52 +34b35c3,1 +34b35c4,92 +34b35c5,62 +34b35c9,54 +34b35ca,10 +34b35cb,21 +34b35cc,80 +34b35cd,46 +34b35d0,2c +34b35d1,c2 +34b35d3,3 +34b35d4,50 +34b35d5,40 +34b35d7,d +34b35d8,26 +34b35d9,52 +34b35db,1 +34b35dc,24 +34b35dd,2 +34b35df,10 +34b35e0,af +34b35e1,a2 +34b35e3,18 +34b35e4,af +34b35e5,a2 +34b35e7,14 +34b35e9,12 +34b35ea,11 +34b35ed,52 +34b35ee,10 +34b35ef,21 +34b35f0,24 +34b35f1,42 +34b35f3,a +34b35f4,af +34b35f5,a2 +34b35f7,10 +34b35f8,8f +34b35f9,a7 +34b35fb,38 +34b35fc,8f +34b35fd,a5 +34b35ff,3c +34b3600,c +34b3601,10 +34b3602,17 +34b3603,c9 +34b3604,2 +34b3606,20 +34b3607,25 +34b3608,26 +34b3609,52 +34b360b,1 +34b360c,8e +34b360d,c2 +34b360e,66 +34b360f,fc +34b3610,2 +34b3611,42 +34b3612,10 +34b3613,2a +34b3614,14 +34b3615,40 +34b3616,ff +34b3617,e2 +34b3618,26 +34b3619,73 +34b361b,c +34b361c,3c +34b361d,2 +34b361e,80 +34b361f,40 +34b3620,8c +34b3621,42 +34b3622,66 +34b3623,fc +34b3624,18 +34b3625,40 +34b3627,10 +34b3628,26 +34b3629,31 +34b362b,12 +34b362c,3c +34b362d,12 +34b362e,80 +34b362f,40 +34b3630,26 +34b3631,52 +34b3632,65 +34b3633,ce +34b3634,24 +34b3635,14 +34b3637,b +34b363a,98 +34b363b,25 +34b363c,3c +34b363d,16 +34b363e,80 +34b363f,40 +34b3640,2 +34b3641,80 +34b3642,30 +34b3643,25 +34b3644,2 +34b3645,20 +34b3646,28 +34b3647,25 +34b3648,c +34b3649,10 +34b364a,14 +34b364b,b +34b364c,2 +34b364d,40 +34b364e,20 +34b364f,25 +34b3650,26 +34b3651,73 +34b3653,1 +34b3654,26 +34b3655,52 +34b3657,c +34b3658,8e +34b3659,c2 +34b365a,66 +34b365b,fc +34b365c,2 +34b365d,62 +34b365e,10 +34b365f,2a +34b3660,14 +34b3661,40 +34b3662,ff +34b3663,f7 +34b3664,26 +34b3665,94 +34b3667,11 +34b3668,3c +34b3669,2 +34b366a,80 +34b366b,40 +34b366c,94 +34b366d,42 +34b366e,66 +34b366f,6c +34b3671,2 +34b3672,10 +34b3673,c0 +34b3674,24 +34b3675,42 +34b3677,1 +34b3679,51 +34b367a,88 +34b367b,21 +34b367c,24 +34b367d,7 +34b367f,1 +34b3680,24 +34b3681,6 +34b3683,11 +34b3684,3c +34b3685,5 +34b3686,80 +34b3687,40 +34b3688,24 +34b3689,a5 +34b368a,66 +34b368b,78 +34b368c,c +34b368d,10 +34b368e,17 +34b368f,61 +34b3690,2 +34b3692,20 +34b3693,25 +34b3694,3c +34b3695,2 +34b3696,80 +34b3697,40 +34b3698,8c +34b3699,42 +34b369a,66 +34b369b,fc +34b369c,58 +34b369d,40 +34b369f,2c +34b36a0,26 +34b36a1,3e +34b36a3,11 +34b36a4,3c +34b36a5,13 +34b36a6,80 +34b36a7,40 +34b36a8,26 +34b36a9,73 +34b36aa,65 +34b36ab,cc +34b36ae,90 +34b36af,25 +34b36b0,2 +34b36b1,60 +34b36b2,a0 +34b36b3,25 +34b36b4,3c +34b36b5,17 +34b36b6,80 +34b36b7,11 +34b36b8,36 +34b36b9,f7 +34b36ba,a5 +34b36bb,d0 +34b36bc,3c +34b36bd,16 +34b36be,80 +34b36bf,40 +34b36c1,12 +34b36c2,10 +34b36c3,40 +34b36c5,52 +34b36c6,10 +34b36c7,21 +34b36c9,2 +34b36ca,10 +34b36cb,80 +34b36cd,54 +34b36ce,10 +34b36cf,21 +34b36d0,80 +34b36d1,42 +34b36d3,1 +34b36d4,4 +34b36d5,43 +34b36d7,19 +34b36d8,26 +34b36d9,52 +34b36db,1 +34b36dc,92 +34b36dd,62 +34b36e0,2 +34b36e1,e2 +34b36e2,10 +34b36e3,21 +34b36e4,90 +34b36e5,42 +34b36e7,bc +34b36e9,2 +34b36ea,1e +34b36ed,3 +34b36ee,1e +34b36ef,3 +34b36f0,28 +34b36f1,63 +34b36f3,a +34b36f4,50 +34b36f5,60 +34b36f7,1 +34b36f8,24 +34b36f9,2 +34b36fb,9 +34b36fc,24 +34b36fd,3 +34b36fe,30 +34b3700,a7 +34b3701,a3 +34b3703,20 +34b3705,40 +34b3706,18 +34b3707,25 +34b3709,2 +34b370a,16 +34b370d,2 +34b370e,16 +34b370f,3 +34b3710,4 +34b3711,42 +34b3713,1 +34b3716,18 +34b3717,25 +34b3718,24 +34b3719,63 +34b371b,30 +34b371c,a3 +34b371d,a3 +34b371f,20 +34b3721,12 +34b3722,31 +34b3725,d2 +34b3726,30 +34b3727,21 +34b3728,24 +34b3729,c6 +34b372b,b +34b372c,2 +34b372d,20 +34b372e,28 +34b372f,25 +34b3730,c +34b3731,10 +34b3732,14 +34b3733,b +34b3734,27 +34b3735,a4 +34b3737,20 +34b3738,26 +34b3739,52 +34b373b,1 +34b373c,8e +34b373d,c2 +34b373e,66 +34b373f,fc +34b3740,2 +34b3741,42 +34b3742,10 +34b3743,2a +34b3744,14 +34b3745,40 +34b3746,ff +34b3747,de +34b3748,26 +34b3749,73 +34b374b,c +34b374c,26 +34b374d,3e +34b374f,11 +34b3750,24 +34b3751,7 +34b3753,1 +34b3754,24 +34b3755,6 +34b3757,e +34b3758,3c +34b3759,5 +34b375a,80 +34b375b,40 +34b375c,24 +34b375d,a5 +34b375e,66 +34b375f,78 +34b3760,c +34b3761,10 +34b3762,17 +34b3763,61 +34b3764,2 +34b3766,20 +34b3767,25 +34b3768,3c +34b3769,2 +34b376a,80 +34b376b,40 +34b376c,8c +34b376d,42 +34b376e,66 +34b376f,fc +34b3770,18 +34b3771,40 +34b3773,2c +34b3774,3c +34b3775,2 +34b3776,80 +34b3777,40 +34b3778,3c +34b3779,13 +34b377a,80 +34b377b,40 +34b377c,26 +34b377d,73 +34b377e,65 +34b377f,cc +34b3782,90 +34b3783,25 +34b3784,24 +34b3785,17 +34b3787,d +34b3788,2 +34b3789,60 +34b378a,a0 +34b378b,25 +34b378c,24 +34b378d,42 +34b378e,66 +34b378f,78 +34b3790,af +34b3791,a2 +34b3793,38 +34b3794,3c +34b3795,16 +34b3796,80 +34b3797,40 +34b3798,92 +34b3799,63 +34b379c,50 +34b379d,77 +34b379f,1 +34b37a0,24 +34b37a1,3 +34b37a3,a +34b37a5,12 +34b37a6,10 +34b37a7,40 +34b37a9,52 +34b37aa,10 +34b37ab,21 +34b37ad,2 +34b37ae,10 +34b37af,80 +34b37b1,54 +34b37b2,10 +34b37b3,21 +34b37b4,90 +34b37b5,42 +34b37b7,1 +34b37b8,30 +34b37b9,42 +34b37bb,40 +34b37bc,50 +34b37bd,40 +34b37bf,15 +34b37c0,26 +34b37c1,52 +34b37c3,1 +34b37c4,3c +34b37c5,2 +34b37c6,80 +34b37c7,11 +34b37c8,34 +34b37c9,42 +34b37ca,a5 +34b37cb,d0 +34b37cd,43 +34b37ce,10 +34b37cf,21 +34b37d0,90 +34b37d1,42 +34b37d3,a8 +34b37d4,30 +34b37d5,42 +34b37d7,1 +34b37d8,50 +34b37d9,40 +34b37db,e +34b37dc,26 +34b37dd,52 +34b37df,1 +34b37e0,24 +34b37e1,2 +34b37e3,10 +34b37e4,af +34b37e5,a2 +34b37e7,18 +34b37e8,af +34b37e9,a2 +34b37eb,14 +34b37ed,12 +34b37ee,11 +34b37f1,52 +34b37f2,10 +34b37f3,21 +34b37f4,24 +34b37f5,42 +34b37f7,a +34b37f8,af +34b37f9,a2 +34b37fb,10 +34b37fc,3 +34b37fd,c0 +34b37fe,38 +34b37ff,25 +34b3802,30 +34b3803,25 +34b3804,8f +34b3805,a5 +34b3807,38 +34b3808,c +34b3809,10 +34b380a,17 +34b380b,c9 +34b380c,2 +34b380e,20 +34b380f,25 +34b3810,26 +34b3811,52 +34b3813,1 +34b3814,8e +34b3815,c2 +34b3816,66 +34b3817,fc +34b3818,2 +34b3819,42 +34b381a,10 +34b381b,2a +34b381c,14 +34b381d,40 +34b381e,ff +34b381f,de +34b3820,26 +34b3821,73 +34b3823,c +34b3824,24 +34b3825,7 +34b3827,1 +34b3828,24 +34b3829,6 +34b382b,a +34b382c,3c +34b382d,5 +34b382e,80 +34b382f,40 +34b3830,24 +34b3831,a5 +34b3832,66 +34b3833,78 +34b3834,c +34b3835,10 +34b3836,17 +34b3837,61 +34b3838,2 +34b383a,20 +34b383b,25 +34b383c,3c +34b383d,2 +34b383e,80 +34b383f,40 +34b3840,8c +34b3841,42 +34b3842,66 +34b3843,fc +34b3844,58 +34b3845,40 +34b3847,28 +34b3848,26 +34b3849,3e +34b384b,22 +34b384e,90 +34b384f,25 +34b3850,3c +34b3851,13 +34b3852,80 +34b3853,40 +34b3854,26 +34b3855,73 +34b3856,65 +34b3857,cc +34b3858,3c +34b3859,16 +34b385a,80 +34b385b,11 +34b385c,3c +34b385d,17 +34b385e,80 +34b385f,40 +34b3860,26 +34b3861,f7 +34b3862,66 +34b3863,78 +34b3864,3c +34b3865,14 +34b3866,80 +34b3867,40 +34b3869,12 +34b386a,10 +34b386b,40 +34b386d,52 +34b386e,10 +34b386f,21 +34b3871,2 +34b3872,10 +34b3873,80 +34b3875,53 +34b3876,10 +34b3877,21 +34b3878,90 +34b3879,42 +34b387b,1 +34b387c,30 +34b387d,42 +34b387f,20 +34b3880,50 +34b3881,40 +34b3883,14 +34b3884,26 +34b3885,52 +34b3887,1 +34b3888,36 +34b3889,c2 +34b388a,a5 +34b388b,d0 +34b388c,8c +34b388d,42 +34b388f,a4 +34b3890,3c +34b3891,3 +34b3893,40 +34b3895,43 +34b3896,10 +34b3897,24 +34b3898,50 +34b3899,40 +34b389b,e +34b389c,26 +34b389d,52 +34b389f,1 +34b38a0,24 +34b38a1,2 +34b38a3,10 +34b38a4,af +34b38a5,a2 +34b38a7,18 +34b38a8,af +34b38a9,a2 +34b38ab,14 +34b38ad,12 +34b38ae,11 +34b38b1,52 +34b38b2,10 +34b38b3,21 +34b38b4,24 +34b38b5,42 +34b38b7,a +34b38b8,af +34b38b9,a2 +34b38bb,10 +34b38bc,3 +34b38bd,c0 +34b38be,38 +34b38bf,25 +34b38c2,30 +34b38c3,25 +34b38c4,2 +34b38c5,e0 +34b38c6,28 +34b38c7,25 +34b38c8,c +34b38c9,10 +34b38ca,17 +34b38cb,c9 +34b38cc,2 +34b38ce,20 +34b38cf,25 +34b38d0,26 +34b38d1,52 +34b38d3,1 +34b38d4,8e +34b38d5,82 +34b38d6,66 +34b38d7,fc +34b38d8,2 +34b38d9,42 +34b38da,10 +34b38db,2a +34b38dc,14 +34b38dd,40 +34b38de,ff +34b38df,e3 +34b38e1,12 +34b38e2,10 +34b38e3,40 +34b38e4,26 +34b38e5,3e +34b38e7,22 +34b38e8,24 +34b38e9,7 +34b38eb,1 +34b38ec,24 +34b38ed,6 +34b38ef,10 +34b38f0,3c +34b38f1,5 +34b38f2,80 +34b38f3,40 +34b38f4,24 +34b38f5,a5 +34b38f6,66 +34b38f7,78 +34b38f8,c +34b38f9,10 +34b38fa,17 +34b38fb,61 +34b38fc,2 +34b38fe,20 +34b38ff,25 +34b3900,3c +34b3901,2 +34b3902,80 +34b3903,40 +34b3904,8c +34b3905,42 +34b3906,66 +34b3907,fc +34b3908,18 +34b3909,40 +34b390b,2a +34b390c,3c +34b390d,13 +34b390e,80 +34b390f,40 +34b3910,26 +34b3911,73 +34b3912,65 +34b3913,cc +34b3916,90 +34b3917,25 +34b3918,2 +34b3919,60 +34b391a,a0 +34b391b,25 +34b391c,3c +34b391d,17 +34b391e,80 +34b391f,11 +34b3920,3c +34b3921,2 +34b3922,80 +34b3923,40 +34b3924,24 +34b3925,42 +34b3926,66 +34b3927,78 +34b3928,af +34b3929,a2 +34b392b,38 +34b392c,3c +34b392d,16 +34b392e,80 +34b392f,40 +34b3931,12 +34b3932,10 +34b3933,40 +34b3935,52 +34b3936,10 +34b3937,21 +34b3939,2 +34b393a,10 +34b393b,80 +34b393d,54 +34b393e,10 +34b393f,21 +34b3940,90 +34b3941,42 +34b3943,1 +34b3944,30 +34b3945,42 +34b3947,10 +34b3948,50 +34b3949,40 +34b394b,16 +34b394c,26 +34b394d,52 +34b394f,1 +34b3950,36 +34b3951,e2 +34b3952,a5 +34b3953,d0 +34b3954,92 +34b3955,63 +34b3959,43 +34b395a,10 +34b395b,21 +34b395c,90 +34b395d,42 +34b395f,a8 +34b3961,2 +34b3962,10 +34b3963,82 +34b3964,30 +34b3965,42 +34b3967,1 +34b3968,50 +34b3969,40 +34b396b,e +34b396c,26 +34b396d,52 +34b396f,1 +34b3970,24 +34b3971,2 +34b3973,10 +34b3974,af +34b3975,a2 +34b3977,18 +34b3978,af +34b3979,a2 +34b397b,14 +34b397d,12 +34b397e,11 +34b3981,52 +34b3982,10 +34b3983,21 +34b3984,24 +34b3985,42 +34b3987,a +34b3988,af +34b3989,a2 +34b398b,10 +34b398c,3 +34b398d,c0 +34b398e,38 +34b398f,25 +34b3992,30 +34b3993,25 +34b3994,8f +34b3995,a5 +34b3997,38 +34b3998,c +34b3999,10 +34b399a,17 +34b399b,c9 +34b399c,2 +34b399e,20 +34b399f,25 +34b39a0,26 +34b39a1,52 +34b39a3,1 +34b39a4,8e +34b39a5,c2 +34b39a6,66 +34b39a7,fc +34b39a8,2 +34b39a9,42 +34b39aa,10 +34b39ab,2a +34b39ac,14 +34b39ad,40 +34b39ae,ff +34b39af,e0 +34b39b0,26 +34b39b1,73 +34b39b3,c +34b39b4,26 +34b39b5,3e +34b39b7,33 +34b39b8,24 +34b39b9,7 +34b39bb,1 +34b39bc,24 +34b39bd,6 +34b39bf,f +34b39c0,3c +34b39c1,5 +34b39c2,80 +34b39c3,40 +34b39c4,24 +34b39c5,a5 +34b39c6,66 +34b39c7,78 +34b39c8,c +34b39c9,10 +34b39ca,17 +34b39cb,61 +34b39cc,2 +34b39ce,20 +34b39cf,25 +34b39d0,3c +34b39d1,2 +34b39d2,80 +34b39d3,40 +34b39d4,8c +34b39d5,42 +34b39d6,66 +34b39d7,fc +34b39d8,18 +34b39d9,40 +34b39db,60 +34b39dc,3c +34b39dd,13 +34b39de,80 +34b39df,40 +34b39e0,26 +34b39e1,73 +34b39e2,65 +34b39e3,cc +34b39e6,90 +34b39e7,25 +34b39e8,2 +34b39e9,60 +34b39ea,a0 +34b39eb,25 +34b39ec,3c +34b39ed,17 +34b39ee,80 +34b39ef,11 +34b39f0,3c +34b39f1,2 +34b39f2,80 +34b39f3,40 +34b39f4,24 +34b39f5,42 +34b39f6,66 +34b39f7,78 +34b39f8,af +34b39f9,a2 +34b39fb,38 +34b39fc,3c +34b39fd,16 +34b39fe,80 +34b39ff,40 +34b3a01,12 +34b3a02,10 +34b3a03,40 +34b3a05,52 +34b3a06,10 +34b3a07,21 +34b3a09,2 +34b3a0a,10 +34b3a0b,80 +34b3a0d,54 +34b3a0e,10 +34b3a0f,21 +34b3a10,90 +34b3a11,42 +34b3a13,1 +34b3a14,30 +34b3a15,42 +34b3a17,10 +34b3a18,50 +34b3a19,40 +34b3a1b,16 +34b3a1c,26 +34b3a1d,52 +34b3a1f,1 +34b3a20,36 +34b3a21,e2 +34b3a22,a5 +34b3a23,d0 +34b3a24,92 +34b3a25,63 +34b3a29,43 +34b3a2a,10 +34b3a2b,21 +34b3a2c,90 +34b3a2d,42 +34b3a2f,a8 +34b3a31,2 +34b3a32,10 +34b3a33,42 +34b3a34,30 +34b3a35,42 +34b3a37,1 +34b3a38,50 +34b3a39,40 +34b3a3b,e +34b3a3c,26 +34b3a3d,52 +34b3a3f,1 +34b3a40,24 +34b3a41,2 +34b3a43,10 +34b3a44,af +34b3a45,a2 +34b3a47,18 +34b3a48,af +34b3a49,a2 +34b3a4b,14 +34b3a4d,12 +34b3a4e,11 +34b3a51,52 +34b3a52,10 +34b3a53,21 +34b3a54,24 +34b3a55,42 +34b3a57,a +34b3a58,af +34b3a59,a2 +34b3a5b,10 +34b3a5c,3 +34b3a5d,c0 +34b3a5e,38 +34b3a5f,25 +34b3a62,30 +34b3a63,25 +34b3a64,8f +34b3a65,a5 +34b3a67,38 +34b3a68,c +34b3a69,10 +34b3a6a,17 +34b3a6b,c9 +34b3a6c,2 +34b3a6e,20 +34b3a6f,25 +34b3a70,26 +34b3a71,52 +34b3a73,1 +34b3a74,8e +34b3a75,c2 +34b3a76,66 +34b3a77,fc +34b3a78,2 +34b3a79,42 +34b3a7a,10 +34b3a7b,2a +34b3a7c,14 +34b3a7d,40 +34b3a7e,ff +34b3a7f,e0 +34b3a80,26 +34b3a81,73 +34b3a83,c +34b3a84,12 +34b3a85,a0 +34b3a87,35 +34b3a88,3c +34b3a89,2 +34b3a8a,80 +34b3a8b,40 +34b3a8c,8c +34b3a8d,42 +34b3a8e,66 +34b3a8f,fc +34b3a90,18 +34b3a91,40 +34b3a93,32 +34b3a94,3c +34b3a95,13 +34b3a96,80 +34b3a97,40 +34b3a98,26 +34b3a99,73 +34b3a9a,65 +34b3a9b,cc +34b3a9c,24 +34b3a9d,14 +34b3a9f,b +34b3aa2,90 +34b3aa3,25 +34b3aa4,3c +34b3aa5,17 +34b3aa6,80 +34b3aa7,40 +34b3aa8,3c +34b3aa9,16 +34b3aaa,80 +34b3aab,40 +34b3aac,26 +34b3aad,d6 +34b3aae,67 +34b3aaf,28 +34b3ab0,3c +34b3ab1,15 +34b3ab2,80 +34b3ab3,40 +34b3ab4,26 +34b3ab5,b5 +34b3ab6,65 +34b3ab7,9c +34b3ab8,3c +34b3ab9,2 +34b3aba,80 +34b3abb,40 +34b3abc,24 +34b3abd,42 +34b3abe,65 +34b3abf,a0 +34b3ac0,af +34b3ac1,a2 +34b3ac3,38 +34b3ac4,3c +34b3ac5,1e +34b3ac6,80 +34b3ac7,40 +34b3ac8,8e +34b3ac9,e2 +34b3aca,67 +34b3acb,18 +34b3acc,50 +34b3acd,40 +34b3acf,14 +34b3ad0,92 +34b3ad1,62 +34b3ad5,12 +34b3ad6,10 +34b3ad7,40 +34b3ad9,52 +34b3ada,10 +34b3adb,21 +34b3add,2 +34b3ade,10 +34b3adf,80 +34b3ae0,27 +34b3ae1,c3 +34b3ae2,65 +34b3ae3,cc +34b3ae5,43 +34b3ae6,10 +34b3ae7,21 +34b3ae8,90 +34b3ae9,42 +34b3aeb,1 +34b3aec,30 +34b3aed,42 +34b3aef,10 +34b3af0,50 +34b3af1,40 +34b3af3,b +34b3af4,92 +34b3af5,62 +34b3af8,92 +34b3af9,63 +34b3afc,3c +34b3afd,2 +34b3afe,80 +34b3aff,11 +34b3b00,34 +34b3b01,42 +34b3b02,a5 +34b3b03,d0 +34b3b05,43 +34b3b06,10 +34b3b07,21 +34b3b08,90 +34b3b09,42 +34b3b0b,a8 +34b3b0d,2 +34b3b0e,10 +34b3b0f,82 +34b3b10,30 +34b3b11,42 +34b3b13,1 +34b3b14,50 +34b3b15,40 +34b3b17,b +34b3b18,26 +34b3b19,52 +34b3b1b,1 +34b3b1c,92 +34b3b1d,62 +34b3b21,56 +34b3b22,10 +34b3b23,21 +34b3b24,90 +34b3b25,42 +34b3b28,14 +34b3b29,40 +34b3b2b,2 +34b3b2c,2 +34b3b2d,a0 +34b3b2e,20 +34b3b2f,25 +34b3b30,8f +34b3b31,a4 +34b3b33,38 +34b3b34,2 +34b3b35,80 +34b3b36,30 +34b3b37,25 +34b3b38,c +34b3b39,10 +34b3b3a,14 +34b3b3b,b +34b3b3c,26 +34b3b3d,25 +34b3b3f,44 +34b3b40,26 +34b3b41,52 +34b3b43,1 +34b3b44,26 +34b3b45,94 +34b3b47,11 +34b3b48,3c +34b3b49,2 +34b3b4a,80 +34b3b4b,40 +34b3b4c,8c +34b3b4d,42 +34b3b4e,66 +34b3b4f,fc +34b3b50,2 +34b3b51,42 +34b3b52,10 +34b3b53,2a +34b3b54,14 +34b3b55,40 +34b3b56,ff +34b3b57,dc +34b3b58,26 +34b3b59,73 +34b3b5b,c +34b3b5c,c +34b3b5d,10 +34b3b5e,14 +34b3b5f,35 +34b3b60,2 +34b3b62,20 +34b3b63,25 +34b3b64,8e +34b3b65,2 +34b3b67,8 +34b3b68,24 +34b3b69,43 +34b3b6b,8 +34b3b6c,ae +34b3b6d,3 +34b3b6f,8 +34b3b70,3c +34b3b71,3 +34b3b72,e9 +34b3b74,ac +34b3b75,43 +34b3b78,ac +34b3b79,40 +34b3b7b,4 +34b3b7c,8e +34b3b7d,2 +34b3b7f,8 +34b3b80,24 +34b3b81,43 +34b3b83,8 +34b3b84,ae +34b3b85,3 +34b3b87,8 +34b3b88,3c +34b3b89,3 +34b3b8a,df +34b3b8c,ac +34b3b8d,43 +34b3b90,ac +34b3b91,40 +34b3b93,4 +34b3b94,8f +34b3b95,bf +34b3b97,6c +34b3b98,8f +34b3b99,be +34b3b9b,68 +34b3b9c,8f +34b3b9d,b7 +34b3b9f,64 +34b3ba0,8f +34b3ba1,b6 +34b3ba3,60 +34b3ba4,8f +34b3ba5,b5 +34b3ba7,5c +34b3ba8,8f +34b3ba9,b4 +34b3bab,58 +34b3bac,8f +34b3bad,b3 +34b3baf,54 +34b3bb0,8f +34b3bb1,b2 +34b3bb3,50 +34b3bb4,8f +34b3bb5,b1 +34b3bb7,4c +34b3bb8,8f +34b3bb9,b0 +34b3bbb,48 +34b3bbc,3 +34b3bbd,e0 +34b3bbf,8 +34b3bc0,27 +34b3bc1,bd +34b3bc3,70 +34b3bc4,10 +34b3bc6,fe +34b3bc7,a8 +34b3bc8,26 +34b3bc9,31 +34b3bcb,12 +34b3bcc,3 +34b3bcd,e0 +34b3bcf,8 +34b3bd4,27 +34b3bd5,bd +34b3bd6,ff +34b3bd7,e8 +34b3bd8,af +34b3bd9,bf +34b3bdb,14 +34b3bdc,c +34b3bdd,10 +34b3bde,17 +34b3bdf,22 +34b3be4,c +34b3be5,10 +34b3be6,18 +34b3be7,7c +34b3bec,c +34b3bed,10 +34b3bee,14 +34b3bf4,8f +34b3bf5,bf +34b3bf7,14 +34b3bf8,3 +34b3bf9,e0 +34b3bfb,8 +34b3bfc,27 +34b3bfd,bd +34b3bff,18 +34b3c00,3c +34b3c01,2 +34b3c02,80 +34b3c03,1c +34b3c04,34 +34b3c05,42 +34b3c06,84 +34b3c07,a0 +34b3c08,3c +34b3c09,3 +34b3c0b,1 +34b3c0d,43 +34b3c0e,10 +34b3c0f,21 +34b3c10,94 +34b3c11,43 +34b3c12,9 +34b3c13,34 +34b3c14,24 +34b3c15,2 +34b3c17,6 +34b3c18,14 +34b3c19,62 +34b3c1b,19 +34b3c1c,3c +34b3c1d,2 +34b3c1e,80 +34b3c1f,1c +34b3c20,34 +34b3c21,42 +34b3c22,84 +34b3c23,a0 +34b3c24,3c +34b3c25,3 +34b3c27,1 +34b3c29,43 +34b3c2a,10 +34b3c2b,21 +34b3c2c,94 +34b3c2d,42 +34b3c2e,9 +34b3c2f,48 +34b3c30,14 +34b3c31,40 +34b3c33,13 +34b3c34,3c +34b3c35,2 +34b3c36,80 +34b3c37,1c +34b3c38,34 +34b3c39,42 +34b3c3a,84 +34b3c3b,a0 +34b3c3d,43 +34b3c3e,10 +34b3c3f,21 +34b3c40,94 +34b3c41,42 +34b3c42,9 +34b3c43,44 +34b3c44,14 +34b3c45,40 +34b3c47,e +34b3c48,3c +34b3c49,2 +34b3c4a,80 +34b3c4b,1c +34b3c4c,34 +34b3c4d,42 +34b3c4e,84 +34b3c4f,a0 +34b3c50,84 +34b3c51,42 +34b3c53,14 +34b3c54,4 +34b3c55,41 +34b3c57,a +34b3c58,3c +34b3c59,2 +34b3c5a,80 +34b3c5b,1c +34b3c5c,27 +34b3c5d,bd +34b3c5e,ff +34b3c5f,e8 +34b3c60,af +34b3c61,bf +34b3c63,14 +34b3c64,34 +34b3c65,42 +34b3c66,84 +34b3c67,a0 +34b3c68,8c +34b3c69,44 +34b3c6c,c +34b3c6d,10 +34b3c6e,14 +34b3c6f,87 +34b3c70,24 +34b3c71,84 +34b3c72,2 +34b3c73,a8 +34b3c74,8f +34b3c75,bf +34b3c77,14 +34b3c78,3 +34b3c79,e0 +34b3c7b,8 +34b3c7c,27 +34b3c7d,bd +34b3c7f,18 +34b3c80,3 +34b3c81,e0 +34b3c83,8 +34b3c88,3c +34b3c89,3 +34b3c8a,80 +34b3c8b,40 +34b3c8c,3c +34b3c8d,2 +34b3c8e,80 +34b3c8f,50 +34b3c90,24 +34b3c91,42 +34b3c94,3 +34b3c95,e0 +34b3c97,8 +34b3c98,ac +34b3c99,62 +34b3c9a,67 +34b3c9b,20 +34b3c9d,4 +34b3c9e,17 +34b3c9f,c3 +34b3ca1,2 +34b3ca2,1f +34b3ca3,2 +34b3ca5,83 +34b3ca6,10 +34b3ca7,21 +34b3ca8,30 +34b3ca9,42 +34b3cab,f +34b3cad,43 +34b3cae,10 +34b3caf,23 +34b3cb0,10 +34b3cb1,40 +34b3cb3,3 +34b3cb4,3c +34b3cb5,3 +34b3cb6,80 +34b3cb7,40 +34b3cb9,82 +34b3cba,20 +34b3cbb,23 +34b3cbc,24 +34b3cbd,84 +34b3cbf,10 +34b3cc0,8c +34b3cc1,62 +34b3cc2,67 +34b3cc3,20 +34b3cc5,44 +34b3cc6,20 +34b3cc7,21 +34b3cc8,3 +34b3cc9,e0 +34b3ccb,8 +34b3ccc,ac +34b3ccd,64 +34b3cce,67 +34b3ccf,20 +34b3cd0,27 +34b3cd1,bd +34b3cd2,ff +34b3cd3,e8 +34b3cd4,af +34b3cd5,bf +34b3cd7,14 +34b3cd8,af +34b3cd9,b0 +34b3cdb,10 +34b3cdd,80 +34b3cde,80 +34b3cdf,25 +34b3ce0,c +34b3ce1,10 +34b3ce2,17 +34b3ce3,27 +34b3ce4,8c +34b3ce5,84 +34b3ce7,8 +34b3ce8,ae +34b3ce9,2 +34b3cec,8e +34b3ced,6 +34b3cef,8 +34b3cf1,40 +34b3cf2,20 +34b3cf3,25 +34b3cf4,3c +34b3cf5,2 +34b3cf6,80 +34b3cf8,24 +34b3cf9,42 +34b3cfa,d +34b3cfb,f0 +34b3cfd,40 +34b3cfe,f8 +34b3cff,9 +34b3d00,8e +34b3d01,5 +34b3d03,4 +34b3d04,8f +34b3d05,bf +34b3d07,14 +34b3d08,8f +34b3d09,b0 +34b3d0b,10 +34b3d0c,3 +34b3d0d,e0 +34b3d0f,8 +34b3d10,27 +34b3d11,bd +34b3d13,18 +34b3d14,ac +34b3d15,86 +34b3d18,ac +34b3d19,85 +34b3d1b,4 +34b3d1c,ac +34b3d1d,85 +34b3d1f,8 +34b3d21,a6 +34b3d22,28 +34b3d23,21 +34b3d24,3 +34b3d25,e0 +34b3d27,8 +34b3d28,ac +34b3d29,85 +34b3d2b,c +34b3d2c,94 +34b3d2d,82 +34b3d2f,4 +34b3d30,94 +34b3d31,83 +34b3d33,6 +34b3d35,43 +34b3d37,18 +34b3d3a,10 +34b3d3b,12 +34b3d3c,90 +34b3d3d,83 +34b3d3f,c +34b3d45,43 +34b3d47,18 +34b3d4a,10 +34b3d4b,12 +34b3d4c,3 +34b3d4d,e0 +34b3d4f,8 +34b3d54,27 +34b3d55,bd +34b3d56,ff +34b3d57,e8 +34b3d58,af +34b3d59,bf +34b3d5b,14 +34b3d5c,af +34b3d5d,b0 +34b3d5f,10 +34b3d60,c +34b3d61,10 +34b3d62,17 +34b3d63,4b +34b3d65,80 +34b3d66,80 +34b3d67,25 +34b3d68,96 +34b3d69,3 +34b3d6b,8 +34b3d6d,62 +34b3d6f,18 +34b3d72,10 +34b3d73,12 +34b3d74,8f +34b3d75,bf +34b3d77,14 +34b3d78,8f +34b3d79,b0 +34b3d7b,10 +34b3d7c,3 +34b3d7d,e0 +34b3d7f,8 +34b3d80,27 +34b3d81,bd +34b3d83,18 +34b3d84,27 +34b3d85,bd +34b3d86,ff +34b3d87,98 +34b3d88,af +34b3d89,bf +34b3d8b,64 +34b3d8c,af +34b3d8d,b6 +34b3d8f,60 +34b3d90,af +34b3d91,b5 +34b3d93,5c +34b3d94,af +34b3d95,b4 +34b3d97,58 +34b3d98,af +34b3d99,b3 +34b3d9b,54 +34b3d9c,af +34b3d9d,b2 +34b3d9f,50 +34b3da0,af +34b3da1,b1 +34b3da3,4c +34b3da4,af +34b3da5,b0 +34b3da7,48 +34b3da9,80 +34b3daa,80 +34b3dab,25 +34b3dad,a0 +34b3dae,a8 +34b3daf,25 +34b3db1,c0 +34b3db2,b0 +34b3db3,25 +34b3db4,94 +34b3db5,b1 +34b3db7,4 +34b3db8,94 +34b3db9,b2 +34b3dbb,6 +34b3dbc,2 +34b3dbd,47 +34b3dbf,18 +34b3dc2,90 +34b3dc3,12 +34b3dc4,90 +34b3dc5,b4 +34b3dc7,b +34b3dc8,90 +34b3dc9,a2 +34b3dcb,a +34b3dcd,2 +34b3dce,15 +34b3dcf,40 +34b3dd0,3c +34b3dd1,13 +34b3dd3,e0 +34b3dd5,53 +34b3dd6,10 +34b3dd7,24 +34b3dd9,14 +34b3dda,9c +34b3ddb,c0 +34b3ddc,3c +34b3ddd,3 +34b3ddf,18 +34b3de0,2 +34b3de1,63 +34b3de2,98 +34b3de3,24 +34b3de5,53 +34b3de6,98 +34b3de7,25 +34b3de8,26 +34b3de9,23 +34b3dea,ff +34b3deb,ff +34b3dec,30 +34b3ded,63 +34b3dee,f +34b3def,ff +34b3df1,73 +34b3df2,18 +34b3df3,25 +34b3df4,3c +34b3df5,2 +34b3df6,fd +34b3df9,62 +34b3dfa,18 +34b3dfb,25 +34b3dfc,af +34b3dfd,a3 +34b3dff,10 +34b3e00,c +34b3e01,10 +34b3e02,17 +34b3e03,4b +34b3e05,a0 +34b3e06,20 +34b3e07,25 +34b3e09,56 +34b3e0b,18 +34b3e0e,10 +34b3e0f,12 +34b3e10,8e +34b3e11,a3 +34b3e15,62 +34b3e16,18 +34b3e17,21 +34b3e18,af +34b3e19,a3 +34b3e1b,14 +34b3e1c,2e +34b3e1d,83 +34b3e1f,2 +34b3e20,10 +34b3e21,60 +34b3e23,3 +34b3e24,24 +34b3e25,2 +34b3e27,10 +34b3e28,24 +34b3e29,2 +34b3e2b,4 +34b3e2c,2 +34b3e2d,82 +34b3e2e,10 +34b3e2f,4 +34b3e31,51 +34b3e33,18 +34b3e36,10 +34b3e37,12 +34b3e38,24 +34b3e39,43 +34b3e3b,3f +34b3e3d,3 +34b3e3e,17 +34b3e3f,c3 +34b3e40,30 +34b3e41,42 +34b3e43,3f +34b3e45,43 +34b3e46,10 +34b3e47,21 +34b3e49,2 +34b3e4a,10 +34b3e4b,c0 +34b3e4c,3c +34b3e4d,3 +34b3e4f,3 +34b3e50,34 +34b3e51,63 +34b3e52,fe +34b3e55,43 +34b3e56,10 +34b3e57,24 +34b3e59,53 +34b3e5a,10 +34b3e5b,25 +34b3e5c,3c +34b3e5d,3 +34b3e5e,f5 +34b3e61,43 +34b3e62,10 +34b3e63,25 +34b3e64,af +34b3e65,a2 +34b3e67,18 +34b3e68,3c +34b3e69,4 +34b3e6a,7 +34b3e6c,af +34b3e6d,a4 +34b3e6f,1c +34b3e70,3c +34b3e71,3 +34b3e72,e6 +34b3e74,af +34b3e75,a3 +34b3e77,20 +34b3e78,af +34b3e79,a0 +34b3e7b,24 +34b3e7c,3c +34b3e7d,3 +34b3e7e,f4 +34b3e80,af +34b3e81,a3 +34b3e83,28 +34b3e84,26 +34b3e85,23 +34b3e86,ff +34b3e87,ff +34b3e89,3 +34b3e8a,1b +34b3e8b,80 +34b3e8c,3c +34b3e8d,11 +34b3e8f,ff +34b3e90,36 +34b3e91,31 +34b3e92,f0 +34b3e95,71 +34b3e96,18 +34b3e97,24 +34b3e98,26 +34b3e99,52 +34b3e9a,ff +34b3e9b,ff +34b3e9d,12 +34b3e9e,90 +34b3e9f,80 +34b3ea0,32 +34b3ea1,52 +34b3ea2,f +34b3ea3,fc +34b3ea5,72 +34b3ea6,18 +34b3ea7,25 +34b3ea9,64 +34b3eaa,20 +34b3eab,25 +34b3eac,af +34b3ead,a4 +34b3eaf,2c +34b3eb0,3c +34b3eb1,4 +34b3eb2,e7 +34b3eb4,af +34b3eb5,a4 +34b3eb7,30 +34b3eb8,af +34b3eb9,a0 +34b3ebb,34 +34b3ebc,af +34b3ebd,a2 +34b3ebf,38 +34b3ec0,af +34b3ec1,a0 +34b3ec3,3c +34b3ec4,3c +34b3ec5,2 +34b3ec6,f2 +34b3ec8,af +34b3ec9,a2 +34b3ecb,40 +34b3ecc,af +34b3ecd,a3 +34b3ecf,44 +34b3ed0,27 +34b3ed1,a2 +34b3ed3,10 +34b3ed4,27 +34b3ed5,a6 +34b3ed7,48 +34b3ed8,8e +34b3ed9,3 +34b3edb,8 +34b3edc,24 +34b3edd,64 +34b3edf,8 +34b3ee0,ae +34b3ee1,4 +34b3ee3,8 +34b3ee4,8c +34b3ee5,45 +34b3ee7,4 +34b3ee8,8c +34b3ee9,44 +34b3eec,ac +34b3eed,65 +34b3eef,4 +34b3ef0,24 +34b3ef1,42 +34b3ef3,8 +34b3ef4,14 +34b3ef5,46 +34b3ef6,ff +34b3ef7,f8 +34b3ef8,ac +34b3ef9,64 +34b3efc,8f +34b3efd,bf +34b3eff,64 +34b3f00,8f +34b3f01,b6 +34b3f03,60 +34b3f04,8f +34b3f05,b5 +34b3f07,5c +34b3f08,8f +34b3f09,b4 +34b3f0b,58 +34b3f0c,8f +34b3f0d,b3 +34b3f0f,54 +34b3f10,8f +34b3f11,b2 +34b3f13,50 +34b3f14,8f +34b3f15,b1 +34b3f17,4c +34b3f18,8f +34b3f19,b0 +34b3f1b,48 +34b3f1c,3 +34b3f1d,e0 +34b3f1f,8 +34b3f20,27 +34b3f21,bd +34b3f23,68 +34b3f24,27 +34b3f25,bd +34b3f26,ff +34b3f27,e8 +34b3f28,8f +34b3f29,a8 +34b3f2b,28 +34b3f2c,8f +34b3f2d,a2 +34b3f2f,2c +34b3f30,8f +34b3f31,aa +34b3f33,30 +34b3f34,94 +34b3f35,a9 +34b3f37,4 +34b3f39,9 +34b3f3a,4a +34b3f3b,80 +34b3f3c,14 +34b3f3d,40 +34b3f3f,2 +34b3f40,1 +34b3f41,22 +34b3f43,1a +34b3f45,7 +34b3f47,d +34b3f4a,48 +34b3f4b,12 +34b3f4c,94 +34b3f4d,a3 +34b3f4f,6 +34b3f51,47 +34b3f52,10 +34b3f53,21 +34b3f55,2 +34b3f56,13 +34b3f57,80 +34b3f58,3c +34b3f59,b +34b3f5b,ff +34b3f5c,35 +34b3f5d,6b +34b3f5e,f0 +34b3f61,4b +34b3f62,10 +34b3f63,24 +34b3f64,1 +34b3f65,48 +34b3f66,28 +34b3f67,21 +34b3f69,5 +34b3f6a,28 +34b3f6b,80 +34b3f6c,30 +34b3f6d,a5 +34b3f6e,f +34b3f6f,ff +34b3f71,45 +34b3f72,10 +34b3f73,25 +34b3f74,3c +34b3f75,5 +34b3f76,e4 +34b3f79,45 +34b3f7a,10 +34b3f7b,25 +34b3f7c,af +34b3f7d,a2 +34b3f81,7 +34b3f82,3b +34b3f83,80 +34b3f85,eb +34b3f86,38 +34b3f87,24 +34b3f89,8 +34b3f8a,40 +34b3f8b,80 +34b3f8c,31 +34b3f8d,8 +34b3f8e,f +34b3f8f,ff +34b3f91,e8 +34b3f92,38 +34b3f93,25 +34b3f94,af +34b3f95,a7 +34b3f97,4 +34b3f98,3c +34b3f99,2 +34b3f9a,e1 +34b3f9c,af +34b3f9d,a2 +34b3f9f,8 +34b3fa1,66 +34b3fa3,18 +34b3fa6,30 +34b3fa7,12 +34b3fa9,6 +34b3faa,31 +34b3fab,40 +34b3fac,30 +34b3fad,c6 +34b3fae,ff +34b3faf,ff +34b3fb0,af +34b3fb1,a6 +34b3fb3,c +34b3fb4,3c +34b3fb5,2 +34b3fb6,f1 +34b3fb8,af +34b3fb9,a2 +34b3fbb,10 +34b3fbd,3 +34b3fbe,1a +34b3fbf,80 +34b3fc0,15 +34b3fc1,40 +34b3fc3,2 +34b3fc5,6a +34b3fc7,1a +34b3fc9,7 +34b3fcb,d +34b3fce,18 +34b3fcf,12 +34b3fd0,30 +34b3fd1,63 +34b3fd2,ff +34b3fd3,ff +34b3fd5,9 +34b3fd6,4c +34b3fd9,69 +34b3fda,18 +34b3fdb,25 +34b3fdc,af +34b3fdd,a3 +34b3fdf,14 +34b3fe0,3 +34b3fe1,a0 +34b3fe2,10 +34b3fe3,25 +34b3fe4,27 +34b3fe5,a8 +34b3fe7,18 +34b3fe8,8c +34b3fe9,83 +34b3feb,8 +34b3fec,24 +34b3fed,65 +34b3fef,8 +34b3ff0,ac +34b3ff1,85 +34b3ff3,8 +34b3ff4,8c +34b3ff5,47 +34b3ff7,4 +34b3ff8,8c +34b3ff9,46 +34b3ffc,ac +34b3ffd,67 +34b3fff,4 +34b4000,24 +34b4001,42 +34b4003,8 +34b4004,14 +34b4005,48 +34b4006,ff +34b4007,f8 +34b4008,ac +34b4009,66 +34b400c,3 +34b400d,e0 +34b400f,8 +34b4010,27 +34b4011,bd +34b4013,18 +34b4014,8c +34b4015,82 +34b4017,8 +34b4018,24 +34b4019,43 +34b401b,8 +34b401c,ac +34b401d,83 +34b401f,8 +34b4020,3c +34b4021,3 +34b4022,e7 +34b4024,ac +34b4025,43 +34b4028,ac +34b4029,40 +34b402b,4 +34b402c,8c +34b402d,82 +34b402f,8 +34b4030,24 +34b4031,43 +34b4033,8 +34b4034,ac +34b4035,83 +34b4037,8 +34b4038,3c +34b4039,3 +34b403a,d9 +34b403c,ac +34b403d,43 +34b4040,ac +34b4041,40 +34b4043,4 +34b4044,8c +34b4045,82 +34b4047,8 +34b4048,24 +34b4049,43 +34b404b,8 +34b404c,ac +34b404d,83 +34b404f,8 +34b4050,3c +34b4051,3 +34b4052,ed +34b4054,ac +34b4055,43 +34b4058,3c +34b4059,5 +34b405b,50 +34b405c,24 +34b405d,a3 +34b405e,3 +34b405f,c0 +34b4060,ac +34b4061,43 +34b4063,4 +34b4064,8c +34b4065,83 +34b4067,8 +34b4068,24 +34b4069,62 +34b406b,8 +34b406c,ac +34b406d,82 +34b406f,8 +34b4070,3c +34b4071,2 +34b4072,e3 +34b4074,24 +34b4075,46 +34b4076,1a +34b4077,1 +34b4078,ac +34b4079,66 +34b407c,24 +34b407d,6 +34b407f,30 +34b4080,ac +34b4081,66 +34b4083,4 +34b4084,8c +34b4085,83 +34b4087,8 +34b4088,24 +34b4089,66 +34b408b,8 +34b408c,ac +34b408d,86 +34b408f,8 +34b4090,24 +34b4091,46 +34b4092,18 +34b4093,1 +34b4094,ac +34b4095,66 +34b4098,24 +34b4099,6 +34b409b,c0 +34b409c,ac +34b409d,66 +34b409f,4 +34b40a0,8c +34b40a1,86 +34b40a3,8 +34b40a4,24 +34b40a5,c3 +34b40a7,8 +34b40a8,ac +34b40a9,83 +34b40ab,8 +34b40ac,3c +34b40ad,3 +34b40ae,e2 +34b40b0,24 +34b40b1,67 +34b40b2,1e +34b40b3,1 +34b40b4,ac +34b40b5,c7 +34b40b8,ac +34b40b9,c0 +34b40bb,4 +34b40bc,8c +34b40bd,86 +34b40bf,8 +34b40c0,24 +34b40c1,c7 +34b40c3,8 +34b40c4,ac +34b40c5,87 +34b40c7,8 +34b40c8,24 +34b40c9,67 +34b40ca,1d +34b40cc,ac +34b40cd,c7 +34b40d0,24 +34b40d1,7 +34b40d3,4 +34b40d4,ac +34b40d5,c7 +34b40d7,4 +34b40d8,8c +34b40d9,86 +34b40db,8 +34b40dc,24 +34b40dd,c7 +34b40df,8 +34b40e0,ac +34b40e1,87 +34b40e3,8 +34b40e4,24 +34b40e5,47 +34b40e6,17 +34b40e8,ac +34b40e9,c7 +34b40ec,ac +34b40ed,c0 +34b40ef,4 +34b40f0,8c +34b40f1,86 +34b40f3,8 +34b40f4,24 +34b40f5,c7 +34b40f7,8 +34b40f8,ac +34b40f9,87 +34b40fb,8 +34b40fc,24 +34b40fd,47 +34b40fe,14 +34b40ff,2 +34b4100,ac +34b4101,c7 +34b4104,24 +34b4105,7 +34b4106,c +34b4108,ac +34b4109,c7 +34b410b,4 +34b410c,8c +34b410d,86 +34b410f,8 +34b4110,24 +34b4111,c7 +34b4113,8 +34b4114,ac +34b4115,87 +34b4117,8 +34b4118,24 +34b4119,47 +34b411a,d +34b411b,1 +34b411c,ac +34b411d,c7 +34b4120,ac +34b4121,c0 +34b4123,4 +34b4124,8c +34b4125,86 +34b4127,8 +34b4128,24 +34b4129,c7 +34b412b,8 +34b412c,ac +34b412d,87 +34b412f,8 +34b4130,24 +34b4131,47 +34b4132,c +34b4134,ac +34b4135,c7 +34b4138,ac +34b4139,c0 +34b413b,4 +34b413c,8c +34b413d,86 +34b413f,8 +34b4140,24 +34b4141,c7 +34b4143,8 +34b4144,ac +34b4145,87 +34b4147,8 +34b4148,24 +34b4149,47 +34b414a,f +34b414c,ac +34b414d,c7 +34b4150,ac +34b4151,c0 +34b4153,4 +34b4154,8c +34b4155,86 +34b4157,8 +34b4158,24 +34b4159,c7 +34b415b,8 +34b415c,ac +34b415d,87 +34b415f,8 +34b4160,24 +34b4161,47 +34b4162,10 +34b4163,1 +34b4164,ac +34b4165,c7 +34b4168,ac +34b4169,c0 +34b416b,4 +34b416c,8c +34b416d,86 +34b416f,8 +34b4170,24 +34b4171,c7 +34b4173,8 +34b4174,ac +34b4175,87 +34b4177,8 +34b4178,24 +34b4179,47 +34b417a,8 +34b417c,ac +34b417d,c7 +34b4180,ac +34b4181,c0 +34b4183,4 +34b4184,8c +34b4185,86 +34b4187,8 +34b4188,24 +34b4189,c7 +34b418b,8 +34b418c,ac +34b418d,87 +34b418f,8 +34b4190,24 +34b4191,47 +34b4192,a +34b4193,1 +34b4194,ac +34b4195,c7 +34b4198,ac +34b4199,c0 +34b419b,4 +34b419c,8c +34b419d,86 +34b419f,8 +34b41a0,24 +34b41a1,c7 +34b41a3,8 +34b41a4,ac +34b41a5,87 +34b41a7,8 +34b41a8,24 +34b41a9,63 +34b41ab,1c +34b41ac,ac +34b41ad,c3 +34b41b0,24 +34b41b1,a5 +34b41b2,42 +34b41b3,40 +34b41b4,ac +34b41b5,c5 +34b41b7,4 +34b41b8,8c +34b41b9,83 +34b41bb,8 +34b41bc,24 +34b41bd,65 +34b41bf,8 +34b41c0,ac +34b41c1,85 +34b41c3,8 +34b41c4,24 +34b41c5,42 +34b41c6,12 +34b41c7,1 +34b41c8,ac +34b41c9,62 +34b41cc,24 +34b41cd,2 +34b41ce,20 +34b41d0,ac +34b41d1,62 +34b41d3,4 +34b41d4,8c +34b41d5,82 +34b41d7,8 +34b41d8,24 +34b41d9,43 +34b41db,8 +34b41dc,ac +34b41dd,83 +34b41df,8 +34b41e0,3c +34b41e1,3 +34b41e2,df +34b41e4,ac +34b41e5,43 +34b41e8,3 +34b41e9,e0 +34b41eb,8 +34b41ec,ac +34b41ed,40 +34b41ef,4 +34b41f0,27 +34b41f1,bd +34b41f2,ff +34b41f3,b8 +34b41f4,af +34b41f5,bf +34b41f7,44 +34b41f8,af +34b41f9,b1 +34b41fb,40 +34b41fc,af +34b41fd,b0 +34b41ff,3c +34b4200,af +34b4201,a0 +34b4203,10 +34b4204,3c +34b4205,2 +34b4206,1 +34b4207,a0 +34b4208,24 +34b4209,42 +34b420a,20 +34b420c,af +34b420d,a2 +34b420f,14 +34b4210,3c +34b4211,10 +34b4213,3 +34b4214,36 +34b4215,2 +34b4216,95 +34b4217,c0 +34b4218,af +34b4219,a2 +34b421b,18 +34b421c,c +34b421d,10 +34b421e,17 +34b421f,34 +34b4220,27 +34b4221,a4 +34b4223,10 +34b4224,af +34b4225,a0 +34b4227,1c +34b4228,3c +34b4229,2 +34b422b,84 +34b422c,24 +34b422d,42 +34b422e,60 +34b4230,af +34b4231,a2 +34b4233,20 +34b4234,34 +34b4235,2 +34b4236,b4 +34b4238,af +34b4239,a2 +34b423b,24 +34b423c,c +34b423d,10 +34b423e,17 +34b423f,34 +34b4240,27 +34b4241,a4 +34b4243,1c +34b4244,af +34b4245,a0 +34b4247,28 +34b4248,3c +34b4249,2 +34b424b,7b +34b424c,34 +34b424d,42 +34b424e,d0 +34b4250,af +34b4251,a2 +34b4253,2c +34b4254,3c +34b4255,2 +34b4257,8 +34b4258,34 +34b4259,42 +34b425a,88 +34b425b,a0 +34b425c,af +34b425d,a2 +34b425f,30 +34b4260,c +34b4261,10 +34b4262,17 +34b4263,34 +34b4264,27 +34b4265,a4 +34b4267,28 +34b4268,8f +34b4269,a2 +34b426b,10 +34b426c,26 +34b426d,10 +34b426e,a3 +34b4271,50 +34b4272,80 +34b4273,21 +34b4274,3c +34b4275,3 +34b4276,80 +34b4277,40 +34b4278,ac +34b4279,70 +34b427a,66 +34b427b,a8 +34b427c,24 +34b427d,42 +34b427e,29 +34b427f,80 +34b4280,3c +34b4281,3 +34b4282,80 +34b4283,40 +34b4284,ac +34b4285,62 +34b4286,66 +34b4287,98 +34b4288,3c +34b4289,2 +34b428a,80 +34b428b,40 +34b428c,8f +34b428d,a3 +34b428f,28 +34b4290,ac +34b4291,43 +34b4292,66 +34b4293,88 +34b4294,3c +34b4295,2 +34b4296,80 +34b4297,40 +34b4298,8f +34b4299,a3 +34b429b,1c +34b429c,ac +34b429d,43 +34b429e,66 +34b429f,78 +34b42a0,3c +34b42a1,11 +34b42a2,80 +34b42a3,40 +34b42a4,c +34b42a5,10 +34b42a6,17 +34b42a7,55 +34b42a8,26 +34b42a9,24 +34b42aa,66 +34b42ab,68 +34b42ad,40 +34b42ae,80 +34b42af,25 +34b42b0,c +34b42b1,10 +34b42b2,17 +34b42b3,27 +34b42b5,40 +34b42b6,20 +34b42b7,25 +34b42b9,10 +34b42ba,4f +34b42bb,c2 +34b42bc,1 +34b42bd,30 +34b42be,48 +34b42bf,21 +34b42c0,2a +34b42c1,10 +34b42c3,2 +34b42c4,16 +34b42c7,18 +34b42c8,ae +34b42c9,22 +34b42ca,66 +34b42cb,68 +34b42cd,9 +34b42ce,48 +34b42cf,43 +34b42d0,3c +34b42d1,3 +34b42d2,80 +34b42d3,40 +34b42d4,24 +34b42d5,63 +34b42d6,67 +34b42d7,48 +34b42da,20 +34b42db,25 +34b42de,30 +34b42df,25 +34b42e0,2 +34b42e1,20 +34b42e2,40 +34b42e3,25 +34b42e4,24 +34b42e5,7 +34b42e6,ff +34b42e7,f0 +34b42e8,8d +34b42e9,5 +34b42ea,66 +34b42eb,68 +34b42ed,a4 +34b42ee,28 +34b42ef,21 +34b42f0,90 +34b42f1,62 +34b42f5,2 +34b42f6,11 +34b42f7,2 +34b42f9,47 +34b42fa,10 +34b42fb,25 +34b42fc,a0 +34b42fd,a2 +34b4300,8d +34b4301,2 +34b4302,66 +34b4303,68 +34b4305,44 +34b4306,10 +34b4307,21 +34b4308,90 +34b4309,65 +34b430d,a7 +34b430e,28 +34b430f,25 +34b4310,a0 +34b4311,45 +34b4313,1 +34b4314,24 +34b4315,c6 +34b4317,1 +34b4318,24 +34b4319,63 +34b431b,1 +34b431d,c9 +34b431e,10 +34b431f,2a +34b4320,14 +34b4321,40 +34b4322,ff +34b4323,f1 +34b4324,24 +34b4325,84 +34b4327,2 +34b4328,c +34b4329,10 +34b432a,17 +34b432b,27 +34b432c,24 +34b432d,4 +34b432e,1 +34b4330,3c +34b4331,4 +34b4332,80 +34b4333,40 +34b4334,24 +34b4335,3 +34b4336,1 +34b4338,ac +34b4339,83 +34b433a,67 +34b433b,38 +34b433c,24 +34b433d,84 +34b433e,67 +34b433f,38 +34b4340,ac +34b4341,82 +34b4343,4 +34b4344,ac +34b4345,82 +34b4347,8 +34b4348,24 +34b4349,42 +34b434a,1 +34b434c,c +34b434d,10 +34b434e,18 +34b434f,5 +34b4350,ac +34b4351,82 +34b4353,c +34b4354,8f +34b4355,bf +34b4357,44 +34b4358,8f +34b4359,b1 +34b435b,40 +34b435c,8f +34b435d,b0 +34b435f,3c +34b4360,3 +34b4361,e0 +34b4363,8 +34b4364,27 +34b4365,bd +34b4367,48 +34b4368,27 +34b4369,bd +34b436a,ff +34b436b,98 +34b436c,af +34b436d,bf +34b436f,64 +34b4370,af +34b4371,be +34b4373,60 +34b4374,af +34b4375,b7 +34b4377,5c +34b4378,af +34b4379,b6 +34b437b,58 +34b437c,af +34b437d,b5 +34b437f,54 +34b4380,af +34b4381,b4 +34b4383,50 +34b4384,af +34b4385,b3 +34b4387,4c +34b4388,af +34b4389,b2 +34b438b,48 +34b438c,af +34b438d,b1 +34b438f,44 +34b4390,af +34b4391,b0 +34b4393,40 +34b4394,af +34b4395,a4 +34b4397,68 +34b4398,3c +34b4399,2 +34b439a,80 +34b439b,1c +34b439c,34 +34b439d,42 +34b439e,84 +34b439f,a0 +34b43a0,8c +34b43a1,50 +34b43a4,26 +34b43a5,2 +34b43a6,2 +34b43a7,b8 +34b43a8,af +34b43a9,a2 +34b43ab,38 +34b43ac,3c +34b43ad,2 +34b43ae,80 +34b43af,40 +34b43b0,8c +34b43b1,43 +34b43b2,67 +34b43b3,3c +34b43b4,8e +34b43b5,2 +34b43b6,2 +34b43b7,c0 +34b43b8,24 +34b43b9,44 +34b43bb,8 +34b43bc,ae +34b43bd,4 +34b43be,2 +34b43bf,c0 +34b43c0,3c +34b43c1,4 +34b43c2,de +34b43c4,ac +34b43c5,44 +34b43c8,ac +34b43c9,43 +34b43cb,4 +34b43cc,8e +34b43cd,2 +34b43ce,2 +34b43cf,c0 +34b43d0,24 +34b43d1,43 +34b43d3,8 +34b43d4,ae +34b43d5,3 +34b43d6,2 +34b43d7,c0 +34b43d8,3c +34b43d9,3 +34b43da,e7 +34b43dc,ac +34b43dd,43 +34b43e0,ac +34b43e1,40 +34b43e3,4 +34b43e4,8e +34b43e5,2 +34b43e6,2 +34b43e7,c0 +34b43e8,24 +34b43e9,43 +34b43eb,8 +34b43ec,ae +34b43ed,3 +34b43ee,2 +34b43ef,c0 +34b43f0,3c +34b43f1,3 +34b43f2,fc +34b43f3,11 +34b43f4,34 +34b43f5,63 +34b43f6,96 +34b43f7,23 +34b43f8,ac +34b43f9,43 +34b43fc,3c +34b43fd,3 +34b43fe,ff +34b43ff,2f +34b4400,34 +34b4401,63 +34b4402,ff +34b4403,ff +34b4404,ac +34b4405,43 +34b4407,4 +34b4408,8e +34b4409,2 +34b440a,2 +34b440b,c0 +34b440c,24 +34b440d,43 +34b440f,8 +34b4410,ae +34b4411,3 +34b4412,2 +34b4413,c0 +34b4414,3c +34b4415,3 +34b4416,fa +34b4418,ac +34b4419,43 +34b441c,24 +34b441d,3 +34b441e,ff +34b441f,ff +34b4420,ac +34b4421,43 +34b4423,4 +34b4424,3c +34b4425,2 +34b4426,80 +34b4427,40 +34b4428,8c +34b4429,52 +34b442a,67 +34b442b,24 +34b442c,24 +34b442d,11 +34b442f,54 +34b4430,3c +34b4431,16 +34b4432,80 +34b4433,40 +34b4434,26 +34b4435,d6 +34b4436,66 +34b4437,b8 +34b4438,3c +34b4439,15 +34b443a,80 +34b443b,40 +34b443c,26 +34b443d,b5 +34b443e,67 +34b4440,24 +34b4441,14 +34b4443,18 +34b4444,24 +34b4445,1e +34b4447,c +34b4448,24 +34b4449,17 +34b444b,f4 +34b444c,32 +34b444d,42 +34b444f,1f +34b4451,2 +34b4452,10 +34b4453,40 +34b4455,12 +34b4456,91 +34b4457,43 +34b4459,56 +34b445a,10 +34b445b,21 +34b445c,90 +34b445d,43 +34b4461,3 +34b4462,18 +34b4463,80 +34b4465,75 +34b4466,18 +34b4467,21 +34b4468,8c +34b4469,73 +34b446c,24 +34b446d,7 +34b446f,1 +34b4470,90 +34b4471,46 +34b4473,1 +34b4474,2 +34b4475,60 +34b4476,28 +34b4477,25 +34b4478,c +34b4479,10 +34b447a,17 +34b447b,61 +34b447c,8f +34b447d,a4 +34b447f,38 +34b4480,af +34b4481,b4 +34b4483,18 +34b4484,af +34b4485,b4 +34b4487,14 +34b4488,af +34b4489,be +34b448b,10 +34b448c,2 +34b448d,20 +34b448e,38 +34b448f,25 +34b4492,30 +34b4493,25 +34b4494,2 +34b4495,60 +34b4496,28 +34b4497,25 +34b4498,c +34b4499,10 +34b449a,17 +34b449b,c9 +34b449c,8f +34b449d,a4 +34b449f,38 +34b44a0,26 +34b44a1,31 +34b44a3,20 +34b44a4,56 +34b44a5,37 +34b44a6,ff +34b44a7,ea +34b44a8,32 +34b44a9,42 +34b44ab,1f +34b44ac,10 +34b44af,c +34b44b0,8e +34b44b1,2 +34b44b2,2 +34b44b3,c0 +34b44b4,8e +34b44b5,3 +34b44b6,2 +34b44b7,c0 +34b44b8,24 +34b44b9,64 +34b44bb,8 +34b44bc,ae +34b44bd,4 +34b44be,2 +34b44bf,c0 +34b44c0,8c +34b44c1,45 +34b44c3,4 +34b44c4,8c +34b44c5,44 +34b44c8,ac +34b44c9,65 +34b44cb,4 +34b44cc,24 +34b44cd,42 +34b44cf,8 +34b44d0,14 +34b44d1,46 +34b44d2,ff +34b44d3,f8 +34b44d4,ac +34b44d5,64 +34b44d8,10 +34b44db,25 +34b44dc,8f +34b44dd,bf +34b44df,64 +34b44e0,24 +34b44e1,43 +34b44e3,8 +34b44e4,ae +34b44e5,3 +34b44e6,2 +34b44e7,c0 +34b44e8,3c +34b44e9,3 +34b44ea,e7 +34b44ec,ac +34b44ed,43 +34b44f0,ac +34b44f1,40 +34b44f3,4 +34b44f4,8e +34b44f5,2 +34b44f6,2 +34b44f7,c0 +34b44f8,24 +34b44f9,43 +34b44fb,8 +34b44fc,ae +34b44fd,3 +34b44fe,2 +34b44ff,c0 +34b4500,3c +34b4501,3 +34b4502,fc +34b4503,ff +34b4504,34 +34b4505,63 +34b4506,ff +34b4507,ff +34b4508,ac +34b4509,43 +34b450c,3c +34b450d,3 +34b450e,ff +34b450f,fd +34b4510,34 +34b4511,63 +34b4512,f6 +34b4513,fb +34b4514,ac +34b4515,43 +34b4517,4 +34b4518,8e +34b4519,2 +34b451a,2 +34b451b,c0 +34b451c,24 +34b451d,43 +34b451f,8 +34b4520,ae +34b4521,3 +34b4522,2 +34b4523,c0 +34b4524,3c +34b4525,3 +34b4526,fa +34b4528,ac +34b4529,43 +34b452c,93 +34b452d,a3 +34b452f,6b +34b4530,ac +34b4531,43 +34b4533,4 +34b4534,3c +34b4535,2 +34b4536,e4 +34b4537,50 +34b4538,24 +34b4539,42 +34b453a,3 +34b453b,c0 +34b453c,af +34b453d,a2 +34b453f,20 +34b4540,af +34b4541,a0 +34b4543,24 +34b4544,3c +34b4545,2 +34b4546,e1 +34b4548,af +34b4549,a2 +34b454b,28 +34b454c,af +34b454d,a0 +34b454f,2c +34b4550,3c +34b4551,2 +34b4552,f1 +34b4554,af +34b4555,a2 +34b4557,30 +34b4558,3c +34b4559,2 +34b455a,4 +34b455c,24 +34b455d,42 +34b455e,4 +34b4560,af +34b4561,a2 +34b4563,34 +34b4564,27 +34b4565,a2 +34b4567,20 +34b4568,10 +34b456a,ff +34b456b,d2 +34b456c,27 +34b456d,a6 +34b456f,38 +34b4570,8f +34b4571,be +34b4573,60 +34b4574,8f +34b4575,b7 +34b4577,5c +34b4578,8f +34b4579,b6 +34b457b,58 +34b457c,8f +34b457d,b5 +34b457f,54 +34b4580,8f +34b4581,b4 +34b4583,50 +34b4584,8f +34b4585,b3 +34b4587,4c +34b4588,8f +34b4589,b2 +34b458b,48 +34b458c,8f +34b458d,b1 +34b458f,44 +34b4590,8f +34b4591,b0 +34b4593,40 +34b4594,3 +34b4595,e0 +34b4597,8 +34b4598,27 +34b4599,bd +34b459b,68 +34b459c,4d +34b459d,51 +34b45a0,4e +34b45a1,6f +34b45a2,72 +34b45a3,6d +34b45a4,61 +34b45a5,6c +34b45a9,1 +34b45aa,2 +34b45ab,3 +34b45ac,4 +34b45ad,5 +34b45ae,6 +34b45af,7 +34b45b0,ff +34b45b1,ff +34b45b2,ff +34b45b3,ff +34b45b4,ff +34b45b5,ff +34b45b9,ff +34b45bb,ff +34b45bc,3c +34b45bf,64 +34b45c0,ff +34b45c1,ff +34b45c2,82 +34b45c4,c8 +34b45c5,32 +34b45c6,ff +34b45c7,c8 +34b45c8,c8 +34b45cd,10 +34b45ce,44 +34b45cf,65 +34b45d0,6b +34b45d1,75 +34b45d8,1 +34b45d9,10 +34b45da,44 +34b45db,6f +34b45dc,64 +34b45dd,6f +34b45de,6e +34b45df,67 +34b45e0,6f +34b45e4,2 +34b45e5,10 +34b45e6,4a +34b45e7,61 +34b45e8,62 +34b45e9,75 +34b45f0,3 +34b45f1,d0 +34b45f2,46 +34b45f3,6f +34b45f4,72 +34b45f5,65 +34b45f6,73 +34b45f7,74 +34b45fc,4 +34b45fd,d0 +34b45fe,46 +34b45ff,69 +34b4600,72 +34b4601,65 +34b4608,5 +34b4609,d0 +34b460a,57 +34b460b,61 +34b460c,74 +34b460d,65 +34b460e,72 +34b4614,7 +34b4615,d0 +34b4616,53 +34b4617,68 +34b4618,61 +34b4619,64 +34b461a,6f +34b461b,77 +34b4620,6 +34b4621,d0 +34b4622,53 +34b4623,70 +34b4624,69 +34b4625,72 +34b4626,69 +34b4627,74 +34b462c,8 +34b462d,90 +34b462e,42 +34b462f,6f +34b4630,74 +34b4631,57 +34b4638,9 +34b4639,10 +34b463a,49 +34b463b,63 +34b463c,65 +34b4644,c +34b4645,a0 +34b4646,47 +34b4647,65 +34b4648,72 +34b4649,75 +34b464a,64 +34b464b,6f +34b4650,b +34b4651,80 +34b4652,47 +34b4653,54 +34b4654,47 +34b465c,d +34b465d,c0 +34b465e,47 +34b465f,61 +34b4660,6e +34b4661,6f +34b4662,6e +34b466d,8 +34b466f,e +34b4671,5f +34b4672,3 +34b4673,1 +34b4674,1 +34b467d,18 +34b467f,18 +34b4681,14 +34b4683,3 +34b4684,4 +34b468d,20 +34b468f,20 +34b4691,5a +34b4693,3 +34b4694,4 +34b469d,10 +34b469f,10 +34b46a1,6 +34b46a2,3 +34b46a3,1 +34b46a4,1 +34b46ad,10 +34b46af,10 +34b46b1,3 +34b46b3,3 +34b46b4,4 +34b46bb,1 +34b46bd,3 +34b46bf,6 +34b46c1,7 +34b46c3,9 +34b46c5,b +34b46c7,e +34b46c9,f +34b46cb,10 +34b46cd,11 +34b46cf,19 +34b46d1,1a +34b46d3,2b +34b46d5,2c +34b46d7,2e +34b46d9,30 +34b46db,32 +34b46dd,35 +34b46df,3c +34b46e1,40 +34b46e3,41 +34b46e5,46 +34b46e7,51 +34b46e9,54 +34b46ea,1 +34b46eb,9 +34b46ec,1 +34b46ed,b +34b46ee,1 +34b46ef,c +34b46f0,1 +34b46f1,e +34b46f2,1 +34b46f3,f +34b46f4,1 +34b46f5,10 +34b46f6,1 +34b46f7,13 +34b46fb,1 +34b46ff,d +34b4700,80 +34b4701,40 +34b4702,66 +34b4703,88 +34b4704,80 +34b4705,40 +34b4706,66 +34b4707,78 +34b4789,d +34b478a,b0 +34b478d,d +34b478e,b0 +34b4791,d +34b4792,b0 +34b4795,c +34b4796,b0 +34b4799,c +34b479a,b0 +34b479d,c +34b479e,a0 +34b47a5,d +34b47a6,b0 +34b47a9,d +34b47aa,b0 +34b47c1,e8 +34b47c2,ac +34b47c5,e8 +34b47c6,ac +34b47c9,e8 +34b47ca,ac +34b47cd,e8 +34b47ce,ac +34b47f5,d +34b47f6,77 +34b47f7,d0 +34b47f9,2e +34b47fa,3a +34b47fb,b0 +34b47fd,7d +34b47fe,c +34b47ff,90 +34b4800,8f +34b4801,ff +34b4802,ff +34b4803,fd +34b4805,c9 +34b4806,6e +34b4808,2 +34b4809,e4 +34b480a,ac +34b480c,ef +34b480d,ff +34b480e,ff +34b480f,f4 +34b4810,a +34b4811,b0 +34b4812,e5 +34b4814,c +34b4815,95 +34b4816,e0 +34b4818,e +34b4819,59 +34b481a,c0 +34b4831,7 +34b4832,90 +34b4834,5 +34b4835,ce +34b4836,eb +34b4837,40 +34b4838,c +34b4839,c8 +34b483a,a9 +34b483b,90 +34b483c,d +34b483d,a7 +34b483e,90 +34b4840,8 +34b4841,ec +34b4842,b4 +34b4845,4a +34b4846,dd +34b4847,a0 +34b4849,7 +34b484a,97 +34b484b,e2 +34b484c,c +34b484d,88 +34b484e,aa +34b484f,e0 +34b4850,6 +34b4851,ce +34b4852,ed +34b4853,70 +34b4855,7 +34b4856,90 +34b4859,7 +34b485a,90 +34b4868,6d +34b4869,ea +34b486c,c9 +34b486d,4d +34b486e,60 +34b4870,c9 +34b4871,4d +34b4872,60 +34b4873,33 +34b4874,6d +34b4875,eb +34b4876,6b +34b4877,c6 +34b4879,8c +34b487a,b6 +34b487c,7c +34b487d,a4 +34b487e,ce +34b487f,c4 +34b4880,31 +34b4881,9 +34b4882,c3 +34b4883,bb +34b4885,9 +34b4886,c3 +34b4887,bb +34b4889,2 +34b488a,ce +34b488b,d4 +34b48a0,4 +34b48a1,ce +34b48a2,fb +34b48a4,a +34b48a5,d5 +34b48a8,8 +34b48a9,e3 +34b48ac,9 +34b48ad,ec +34b48b0,7e +34b48b1,4d +34b48b2,b0 +34b48b3,ab +34b48b4,bb +34b48b5,5 +34b48b6,e8 +34b48b7,aa +34b48b8,bc +34b48ba,8e +34b48bb,d6 +34b48bc,7e +34b48bd,93 +34b48be,6e +34b48bf,d0 +34b48c0,8 +34b48c1,de +34b48c2,d9 +34b48c3,ea +34b48d9,c +34b48da,a0 +34b48dd,c +34b48de,a0 +34b48e1,c +34b48e2,a0 +34b48e5,c +34b48e6,a0 +34b490a,c9 +34b490d,7 +34b490e,e2 +34b4911,c +34b4912,b0 +34b4915,e +34b4916,80 +34b4919,6f +34b491a,30 +34b491d,8e +34b4921,8e +34b4925,6f +34b4926,40 +34b4929,e +34b492a,80 +34b492d,c +34b492e,b0 +34b4931,7 +34b4932,e2 +34b4936,c9 +34b4941,bb +34b4945,5e +34b4946,40 +34b4949,c +34b494a,a0 +34b494d,a +34b494e,d0 +34b4951,7 +34b4952,e1 +34b4955,6 +34b4956,f4 +34b4959,6 +34b495a,f4 +34b495d,7 +34b495e,e1 +34b4961,a +34b4962,d0 +34b4965,c +34b4966,a0 +34b4969,5e +34b496a,40 +34b496d,bb +34b4981,a +34b4982,80 +34b4984,c +34b4985,8a +34b4986,8a +34b4987,b0 +34b4988,3 +34b4989,be +34b498a,da +34b498b,10 +34b498c,3 +34b498d,be +34b498e,da +34b498f,10 +34b4990,c +34b4991,8a +34b4992,8a +34b4993,b0 +34b4995,a +34b4996,80 +34b49bd,c +34b49be,a0 +34b49c1,c +34b49c2,a0 +34b49c5,c +34b49c6,a0 +34b49c8,af +34b49c9,ff +34b49ca,ff +34b49cb,f8 +34b49cd,c +34b49ce,a0 +34b49d1,c +34b49d2,a0 +34b49d5,c +34b49d6,a0 +34b4a0d,d +34b4a0e,d0 +34b4a11,e +34b4a12,c0 +34b4a15,4f +34b4a16,80 +34b4a19,9d +34b4a3d,df +34b4a3e,fb +34b4a7d,e +34b4a7e,c0 +34b4a81,e +34b4a82,c0 +34b4a9a,b +34b4a9b,c0 +34b4a9e,4e +34b4a9f,60 +34b4aa2,bc +34b4aa5,3 +34b4aa6,e8 +34b4aa9,a +34b4aaa,d0 +34b4aad,1e +34b4aae,90 +34b4ab1,9e +34b4ab2,20 +34b4ab5,da +34b4ab8,7 +34b4ab9,e3 +34b4abc,c +34b4abd,b0 +34b4ac0,6e +34b4ac1,50 +34b4ad0,3 +34b4ad1,ce +34b4ad2,eb +34b4ad4,b +34b4ad5,d5 +34b4ad6,7e +34b4ad7,90 +34b4ad8,e +34b4ad9,90 +34b4ada,b +34b4adb,d0 +34b4adc,5f +34b4add,70 +34b4ade,9 +34b4adf,e0 +34b4ae0,6f +34b4ae1,6c +34b4ae2,b9 +34b4ae3,e0 +34b4ae4,5f +34b4ae5,70 +34b4ae6,9 +34b4ae7,e0 +34b4ae8,e +34b4ae9,90 +34b4aea,b +34b4aeb,d0 +34b4aec,b +34b4aed,d5 +34b4aee,7e +34b4aef,90 +34b4af0,3 +34b4af1,ce +34b4af2,eb +34b4b08,a +34b4b09,ff +34b4b0a,e0 +34b4b0d,8 +34b4b0e,e0 +34b4b11,8 +34b4b12,e0 +34b4b15,8 +34b4b16,e0 +34b4b19,8 +34b4b1a,e0 +34b4b1d,8 +34b4b1e,e0 +34b4b21,8 +34b4b22,e0 +34b4b25,8 +34b4b26,e0 +34b4b28,8 +34b4b29,ff +34b4b2a,ff +34b4b2b,e0 +34b4b40,8 +34b4b41,de +34b4b42,ea +34b4b44,c +34b4b45,83 +34b4b46,7e +34b4b47,90 +34b4b4a,c +34b4b4b,c0 +34b4b4e,2e +34b4b4f,a0 +34b4b52,bd +34b4b53,20 +34b4b55,b +34b4b56,d4 +34b4b59,bd +34b4b5a,40 +34b4b5c,b +34b4b5d,d4 +34b4b60,2f +34b4b61,ff +34b4b62,ff +34b4b63,d0 +34b4b78,7 +34b4b79,ce +34b4b7a,ea +34b4b7c,c +34b4b7d,83 +34b4b7e,7e +34b4b7f,90 +34b4b82,c +34b4b83,b0 +34b4b85,2 +34b4b86,7e +34b4b87,90 +34b4b89,bf +34b4b8a,fb +34b4b8d,2 +34b4b8e,7d +34b4b8f,a0 +34b4b92,a +34b4b93,d0 +34b4b94,5c +34b4b95,62 +34b4b96,7d +34b4b97,b0 +34b4b98,9 +34b4b99,de +34b4b9a,eb +34b4b9b,30 +34b4bb1,2 +34b4bb2,de +34b4bb5,b +34b4bb6,de +34b4bb9,7d +34b4bba,9e +34b4bbc,2 +34b4bbd,d7 +34b4bbe,9e +34b4bc0,b +34b4bc1,b0 +34b4bc2,9e +34b4bc4,6e +34b4bc5,40 +34b4bc6,9e +34b4bc8,9f +34b4bc9,ff +34b4bca,ff +34b4bcb,f7 +34b4bce,9e +34b4bd2,9e +34b4be8,c +34b4be9,ff +34b4bea,ff +34b4beb,50 +34b4bec,c +34b4bed,a0 +34b4bf0,c +34b4bf1,a0 +34b4bf4,c +34b4bf5,ee +34b4bf6,ea +34b4bf9,3 +34b4bfa,8e +34b4bfb,90 +34b4bfe,b +34b4bff,c0 +34b4c02,b +34b4c03,c0 +34b4c04,5c +34b4c05,63 +34b4c06,8e +34b4c07,90 +34b4c08,9 +34b4c09,de +34b4c0a,da +34b4c21,ae +34b4c22,ec +34b4c23,30 +34b4c24,a +34b4c25,e8 +34b4c26,39 +34b4c27,80 +34b4c28,e +34b4c29,90 +34b4c2c,4f +34b4c2d,ae +34b4c2e,ec +34b4c2f,40 +34b4c30,6f +34b4c31,d5 +34b4c32,5d +34b4c33,c0 +34b4c34,5f +34b4c35,90 +34b4c36,9 +34b4c37,e0 +34b4c38,e +34b4c39,90 +34b4c3a,9 +34b4c3b,e0 +34b4c3c,c +34b4c3d,d5 +34b4c3e,5d +34b4c3f,c0 +34b4c40,3 +34b4c41,ce +34b4c42,ec +34b4c43,40 +34b4c58,5f +34b4c59,ff +34b4c5a,ff +34b4c5b,d0 +34b4c5e,d +34b4c5f,a0 +34b4c62,7e +34b4c63,40 +34b4c66,cc +34b4c69,4 +34b4c6a,e8 +34b4c6d,a +34b4c6e,d0 +34b4c71,d +34b4c72,a0 +34b4c75,8e +34b4c76,40 +34b4c79,cc +34b4c90,5 +34b4c91,ce +34b4c92,ec +34b4c93,30 +34b4c94,d +34b4c95,c4 +34b4c96,5d +34b4c97,b0 +34b4c98,e +34b4c99,90 +34b4c9a,b +34b4c9b,d0 +34b4c9c,b +34b4c9d,c4 +34b4c9e,5d +34b4c9f,90 +34b4ca0,4 +34b4ca1,df +34b4ca2,fc +34b4ca3,20 +34b4ca4,1d +34b4ca5,b4 +34b4ca6,5c +34b4ca7,c0 +34b4ca8,5f +34b4ca9,60 +34b4caa,9 +34b4cab,e0 +34b4cac,2e +34b4cad,b3 +34b4cae,5c +34b4caf,d0 +34b4cb0,7 +34b4cb1,de +34b4cb2,ec +34b4cb3,50 +34b4cc8,6 +34b4cc9,de +34b4cca,eb +34b4ccc,d +34b4ccd,b3 +34b4cce,7e +34b4ccf,90 +34b4cd0,5f +34b4cd1,50 +34b4cd2,b +34b4cd3,d0 +34b4cd4,5f +34b4cd5,50 +34b4cd6,b +34b4cd7,e0 +34b4cd8,d +34b4cd9,b3 +34b4cda,7e +34b4cdb,e0 +34b4cdc,6 +34b4cdd,de +34b4cde,db +34b4cdf,e0 +34b4ce2,b +34b4ce3,c0 +34b4ce4,9 +34b4ce5,74 +34b4ce6,9e +34b4ce7,70 +34b4ce8,5 +34b4ce9,de +34b4cea,d8 +34b4d09,e +34b4d0a,c0 +34b4d0d,e +34b4d0e,c0 +34b4d1d,e +34b4d1e,c0 +34b4d21,e +34b4d22,c0 +34b4d41,e +34b4d42,c0 +34b4d45,e +34b4d46,c0 +34b4d55,d +34b4d56,d0 +34b4d59,e +34b4d5a,c0 +34b4d5d,4f +34b4d5e,80 +34b4d61,9d +34b4d7a,29 +34b4d7b,c8 +34b4d7d,7b +34b4d7e,ed +34b4d7f,93 +34b4d80,8d +34b4d81,da +34b4d82,40 +34b4d84,8d +34b4d85,da +34b4d86,40 +34b4d89,7b +34b4d8a,ec +34b4d8b,93 +34b4d8e,29 +34b4d8f,c8 +34b4db4,af +34b4db5,ff +34b4db6,ff +34b4db7,f8 +34b4dc0,af +34b4dc1,ff +34b4dc2,ff +34b4dc3,f8 +34b4de8,ac +34b4de9,81 +34b4dec,4a +34b4ded,de +34b4dee,b6 +34b4df1,6 +34b4df2,ad +34b4df3,d6 +34b4df5,6 +34b4df6,ad +34b4df7,d6 +34b4df8,4a +34b4df9,de +34b4dfa,b6 +34b4dfc,ac +34b4dfd,81 +34b4e18,4 +34b4e19,be +34b4e1a,ec +34b4e1b,30 +34b4e1c,9 +34b4e1d,a4 +34b4e1e,6e +34b4e1f,a0 +34b4e22,1d +34b4e23,a0 +34b4e25,2 +34b4e26,cd +34b4e27,30 +34b4e29,c +34b4e2a,c1 +34b4e2d,e +34b4e2e,90 +34b4e35,e +34b4e36,90 +34b4e39,e +34b4e3a,90 +34b4e50,1 +34b4e51,ae +34b4e52,ed +34b4e53,70 +34b4e54,c +34b4e55,d7 +34b4e56,39 +34b4e57,e4 +34b4e58,7e +34b4e59,20 +34b4e5b,c9 +34b4e5c,ba +34b4e5d,a +34b4e5e,ee +34b4e5f,ca +34b4e60,d7 +34b4e61,6e +34b4e62,64 +34b4e63,da +34b4e64,d6 +34b4e65,9c +34b4e67,aa +34b4e68,d7 +34b4e69,6e +34b4e6a,64 +34b4e6b,da +34b4e6c,ba +34b4e6d,a +34b4e6e,ee +34b4e6f,ca +34b4e70,6e +34b4e71,40 +34b4e74,a +34b4e75,d8 +34b4e76,30 +34b4e79,8d +34b4e7a,ee +34b4e7b,90 +34b4e89,3e +34b4e8a,d0 +34b4e8d,9d +34b4e8e,e6 +34b4e91,cb +34b4e92,cb +34b4e94,3 +34b4e95,e8 +34b4e96,ad +34b4e98,8 +34b4e99,e2 +34b4e9a,6f +34b4e9b,60 +34b4e9c,c +34b4e9d,c0 +34b4e9e,e +34b4e9f,a0 +34b4ea0,2e +34b4ea1,ff +34b4ea2,ff +34b4ea3,d0 +34b4ea4,8e +34b4ea5,50 +34b4ea6,8 +34b4ea7,f5 +34b4ea8,cd +34b4eaa,1 +34b4eab,ea +34b4ec0,e +34b4ec1,ff +34b4ec2,ec +34b4ec3,40 +34b4ec4,e +34b4ec5,90 +34b4ec6,5d +34b4ec7,c0 +34b4ec8,e +34b4ec9,90 +34b4eca,a +34b4ecb,e0 +34b4ecc,e +34b4ecd,90 +34b4ece,5d +34b4ecf,c0 +34b4ed0,e +34b4ed1,ff +34b4ed2,fd +34b4ed3,50 +34b4ed4,e +34b4ed5,90 +34b4ed6,4b +34b4ed7,d2 +34b4ed8,e +34b4ed9,90 +34b4eda,5 +34b4edb,f6 +34b4edc,e +34b4edd,90 +34b4ede,4b +34b4edf,e3 +34b4ee0,e +34b4ee1,ff +34b4ee2,ed +34b4ee3,80 +34b4ef9,9d +34b4efa,ed +34b4efb,80 +34b4efc,8 +34b4efd,e9 +34b4efe,36 +34b4eff,b0 +34b4f00,d +34b4f01,b0 +34b4f04,3f +34b4f05,90 +34b4f08,5f +34b4f09,70 +34b4f0c,1e +34b4f0d,90 +34b4f10,d +34b4f11,b0 +34b4f14,8 +34b4f15,e9 +34b4f16,47 +34b4f17,b0 +34b4f19,9d +34b4f1a,ed +34b4f1b,80 +34b4f30,5f +34b4f31,fe +34b4f32,d8 +34b4f34,5f +34b4f35,65 +34b4f36,ae +34b4f37,80 +34b4f38,5f +34b4f39,60 +34b4f3a,c +34b4f3b,d0 +34b4f3c,5f +34b4f3d,60 +34b4f3e,9 +34b4f3f,e0 +34b4f40,5f +34b4f41,60 +34b4f42,9 +34b4f43,f0 +34b4f44,5f +34b4f45,60 +34b4f46,9 +34b4f47,e0 +34b4f48,5f +34b4f49,60 +34b4f4a,c +34b4f4b,d0 +34b4f4c,5f +34b4f4d,65 +34b4f4e,ae +34b4f4f,80 +34b4f50,5f +34b4f51,fe +34b4f52,d8 +34b4f68,d +34b4f69,ff +34b4f6a,ff +34b4f6b,e0 +34b4f6c,d +34b4f6d,b0 +34b4f70,d +34b4f71,b0 +34b4f74,d +34b4f75,b0 +34b4f78,d +34b4f79,ff +34b4f7a,ff +34b4f7b,c0 +34b4f7c,d +34b4f7d,b0 +34b4f80,d +34b4f81,b0 +34b4f84,d +34b4f85,b0 +34b4f88,d +34b4f89,ff +34b4f8a,ff +34b4f8b,f0 +34b4fa0,b +34b4fa1,ff +34b4fa2,ff +34b4fa3,f4 +34b4fa4,b +34b4fa5,d0 +34b4fa8,b +34b4fa9,d0 +34b4fac,b +34b4fad,d0 +34b4fb0,b +34b4fb1,ff +34b4fb2,ff +34b4fb3,c0 +34b4fb4,b +34b4fb5,d0 +34b4fb8,b +34b4fb9,d0 +34b4fbc,b +34b4fbd,d0 +34b4fc0,b +34b4fc1,d0 +34b4fd8,1 +34b4fd9,ae +34b4fda,ed +34b4fdb,60 +34b4fdc,b +34b4fdd,e7 +34b4fde,38 +34b4fdf,a0 +34b4fe0,4e +34b4fe1,90 +34b4fe4,8f +34b4fe5,40 +34b4fe8,9f +34b4fe9,10 +34b4fea,bf +34b4feb,f2 +34b4fec,7f +34b4fed,40 +34b4fee,7 +34b4fef,f2 +34b4ff0,4e +34b4ff1,90 +34b4ff2,7 +34b4ff3,f2 +34b4ff4,b +34b4ff5,e7 +34b4ff6,39 +34b4ff7,f2 +34b4ff8,1 +34b4ff9,be +34b4ffa,ed +34b4ffb,90 +34b5010,5f +34b5011,60 +34b5012,9 +34b5013,e0 +34b5014,5f +34b5015,60 +34b5016,9 +34b5017,e0 +34b5018,5f +34b5019,60 +34b501a,9 +34b501b,e0 +34b501c,5f +34b501d,60 +34b501e,9 +34b501f,e0 +34b5020,5f +34b5021,ff +34b5022,ff +34b5023,e0 +34b5024,5f +34b5025,60 +34b5026,9 +34b5027,e0 +34b5028,5f +34b5029,60 +34b502a,9 +34b502b,e0 +34b502c,5f +34b502d,60 +34b502e,9 +34b502f,e0 +34b5030,5f +34b5031,60 +34b5032,9 +34b5033,e0 +34b5048,d +34b5049,ff +34b504a,ff +34b504b,b0 +34b504d,d +34b504e,b0 +34b5051,d +34b5052,b0 +34b5055,d +34b5056,b0 +34b5059,d +34b505a,b0 +34b505d,d +34b505e,b0 +34b5061,d +34b5062,b0 +34b5065,d +34b5066,b0 +34b5068,d +34b5069,ff +34b506a,ff +34b506b,b0 +34b5081,cf +34b5082,ff +34b5083,40 +34b5086,7f +34b5087,40 +34b508a,7f +34b508b,40 +34b508e,7f +34b508f,40 +34b5092,7f +34b5093,40 +34b5096,7f +34b5097,30 +34b5098,75 +34b509a,9e +34b509c,8d +34b509d,64 +34b509e,dc +34b50a0,2b +34b50a1,ee +34b50a2,c5 +34b50b8,5f +34b50b9,60 +34b50ba,9 +34b50bb,e7 +34b50bc,5f +34b50bd,60 +34b50be,9e +34b50bf,70 +34b50c0,5f +34b50c1,69 +34b50c2,e7 +34b50c4,5f +34b50c5,be +34b50c6,80 +34b50c8,5f +34b50c9,ed +34b50ca,b0 +34b50cc,5f +34b50cd,87 +34b50ce,e8 +34b50d0,5f +34b50d1,60 +34b50d2,ae +34b50d3,40 +34b50d4,5f +34b50d5,60 +34b50d6,1d +34b50d7,c0 +34b50d8,5f +34b50d9,60 +34b50da,6 +34b50db,ea +34b50f0,c +34b50f1,c0 +34b50f4,c +34b50f5,c0 +34b50f8,c +34b50f9,c0 +34b50fc,c +34b50fd,c0 +34b5100,c +34b5101,c0 +34b5104,c +34b5105,c0 +34b5108,c +34b5109,c0 +34b510c,c +34b510d,c0 +34b5110,c +34b5111,ff +34b5112,ff +34b5113,f7 +34b5128,af +34b5129,a0 +34b512a,c +34b512b,f8 +34b512c,ae +34b512d,d0 +34b512e,2e +34b512f,e8 +34b5130,ad +34b5131,d5 +34b5132,9b +34b5133,e8 +34b5134,ad +34b5135,aa +34b5136,c8 +34b5137,e8 +34b5138,ad +34b5139,5d +34b513a,e1 +34b513b,e8 +34b513c,ad +34b513d,d +34b513e,b0 +34b513f,e8 +34b5140,ad +34b5143,e8 +34b5144,ad +34b5147,e8 +34b5148,ad +34b514b,e8 +34b5160,5f +34b5161,c0 +34b5162,8 +34b5163,e0 +34b5164,5f +34b5165,e6 +34b5166,8 +34b5167,e0 +34b5168,5f +34b5169,cb +34b516a,8 +34b516b,e0 +34b516c,5f +34b516d,7e +34b516e,48 +34b516f,e0 +34b5170,5f +34b5171,5c +34b5172,a8 +34b5173,e0 +34b5174,5f +34b5175,57 +34b5176,e8 +34b5177,e0 +34b5178,5f +34b5179,50 +34b517a,dc +34b517b,e0 +34b517c,5f +34b517d,50 +34b517e,9e +34b517f,e0 +34b5180,5f +34b5181,50 +34b5182,2e +34b5183,e0 +34b5198,4 +34b5199,ce +34b519a,eb +34b519b,20 +34b519c,c +34b519d,d5 +34b519e,6e +34b519f,a0 +34b51a0,3e +34b51a1,80 +34b51a2,a +34b51a3,e0 +34b51a4,7f +34b51a5,50 +34b51a6,8 +34b51a7,f2 +34b51a8,7f +34b51a9,40 +34b51aa,8 +34b51ab,f4 +34b51ac,7f +34b51ad,50 +34b51ae,8 +34b51af,f2 +34b51b0,3e +34b51b1,80 +34b51b2,a +34b51b3,e0 +34b51b4,c +34b51b5,d5 +34b51b6,6e +34b51b7,b0 +34b51b8,4 +34b51b9,ce +34b51ba,eb +34b51bb,20 +34b51d0,d +34b51d1,ff +34b51d2,ed +34b51d3,60 +34b51d4,d +34b51d5,b0 +34b51d6,5c +34b51d7,e2 +34b51d8,d +34b51d9,b0 +34b51da,6 +34b51db,f6 +34b51dc,d +34b51dd,b0 +34b51de,6 +34b51df,f6 +34b51e0,d +34b51e1,b0 +34b51e2,5c +34b51e3,e2 +34b51e4,d +34b51e5,ff +34b51e6,ed +34b51e7,60 +34b51e8,d +34b51e9,b0 +34b51ec,d +34b51ed,b0 +34b51f0,d +34b51f1,b0 +34b5208,4 +34b5209,ce +34b520a,eb +34b520b,20 +34b520c,c +34b520d,d5 +34b520e,6e +34b520f,a0 +34b5210,3e +34b5211,80 +34b5212,a +34b5213,e0 +34b5214,7f +34b5215,50 +34b5216,8 +34b5217,f2 +34b5218,7f +34b5219,40 +34b521a,8 +34b521b,f4 +34b521c,7f +34b521d,50 +34b521e,8 +34b521f,f1 +34b5220,3e +34b5221,80 +34b5222,a +34b5223,d0 +34b5224,c +34b5225,d5 +34b5226,6e +34b5227,a0 +34b5228,4 +34b5229,ce +34b522a,fc +34b522b,20 +34b522e,ae +34b522f,50 +34b5232,c +34b5233,80 +34b5240,5f +34b5241,fe +34b5242,eb +34b5243,20 +34b5244,5f +34b5245,71 +34b5246,7e +34b5247,b0 +34b5248,5f +34b5249,70 +34b524a,c +34b524b,d0 +34b524c,5f +34b524d,71 +34b524e,6e +34b524f,a0 +34b5250,5f +34b5251,ff +34b5252,ea +34b5254,5f +34b5255,72 +34b5256,ae +34b5257,40 +34b5258,5f +34b5259,70 +34b525a,d +34b525b,b0 +34b525c,5f +34b525d,70 +34b525e,8 +34b525f,e5 +34b5260,5f +34b5261,70 +34b5263,db +34b5278,6 +34b5279,ce +34b527a,eb +34b527b,30 +34b527c,d +34b527d,c4 +34b527e,5a +34b527f,90 +34b5280,4f +34b5281,60 +34b5284,e +34b5285,c6 +34b5288,5 +34b5289,ce +34b528a,eb +34b528b,40 +34b528e,6c +34b528f,c0 +34b5292,8 +34b5293,e0 +34b5294,c +34b5295,73 +34b5296,5c +34b5297,d0 +34b5298,8 +34b5299,de +34b529a,ec +34b529b,50 +34b52b0,cf +34b52b1,ff +34b52b2,ff +34b52b3,fb +34b52b5,d +34b52b6,b0 +34b52b9,d +34b52ba,b0 +34b52bd,d +34b52be,b0 +34b52c1,d +34b52c2,b0 +34b52c5,d +34b52c6,b0 +34b52c9,d +34b52ca,b0 +34b52cd,d +34b52ce,b0 +34b52d1,d +34b52d2,b0 +34b52e8,4f +34b52e9,70 +34b52ea,9 +34b52eb,e0 +34b52ec,4f +34b52ed,70 +34b52ee,9 +34b52ef,e0 +34b52f0,4f +34b52f1,70 +34b52f2,9 +34b52f3,e0 +34b52f4,4f +34b52f5,70 +34b52f6,9 +34b52f7,e0 +34b52f8,4f +34b52f9,70 +34b52fa,9 +34b52fb,e0 +34b52fc,3f +34b52fd,70 +34b52fe,9 +34b52ff,e0 +34b5300,2e +34b5301,70 +34b5302,a +34b5303,d0 +34b5304,d +34b5305,c4 +34b5306,5d +34b5307,c0 +34b5308,5 +34b5309,ce +34b530a,ec +34b530b,40 +34b5320,ad +34b5322,3 +34b5323,e8 +34b5324,6f +34b5325,50 +34b5326,8 +34b5327,e3 +34b5328,e +34b5329,90 +34b532a,b +34b532b,c0 +34b532c,b +34b532d,c0 +34b532e,d +34b532f,90 +34b5330,8 +34b5331,e1 +34b5332,5e +34b5333,40 +34b5334,2 +34b5335,e7 +34b5336,ad +34b5339,cb +34b533a,ca +34b533d,9d +34b533e,e6 +34b5341,3e +34b5342,d0 +34b5358,e8 +34b535b,ad +34b535c,da +34b535f,cb +34b5360,cb +34b5363,da +34b5364,ac +34b5365,e +34b5366,c0 +34b5367,e8 +34b5368,8d +34b5369,6d +34b536a,e1 +34b536b,e5 +34b536c,6e +34b536d,9b +34b536e,d8 +34b536f,e0 +34b5370,1e +34b5371,c8 +34b5372,ac +34b5373,d0 +34b5374,d +34b5375,e3 +34b5376,7e +34b5377,c0 +34b5378,c +34b5379,d0 +34b537a,e +34b537b,a0 +34b5390,6e +34b5391,70 +34b5392,7 +34b5393,e7 +34b5394,a +34b5395,d2 +34b5396,1d +34b5397,b0 +34b5398,2 +34b5399,da +34b539a,ad +34b539b,20 +34b539d,7e +34b539e,e7 +34b53a1,3e +34b53a2,e2 +34b53a5,bd +34b53a6,da +34b53a8,7 +34b53a9,e6 +34b53aa,7e +34b53ab,60 +34b53ac,3e +34b53ad,a0 +34b53ae,b +34b53af,d0 +34b53b0,bd +34b53b1,20 +34b53b2,4 +34b53b3,e9 +34b53c8,ae +34b53c9,20 +34b53ca,5 +34b53cb,e8 +34b53cc,2d +34b53cd,a0 +34b53ce,c +34b53cf,c0 +34b53d0,7 +34b53d1,e5 +34b53d2,7e +34b53d3,50 +34b53d5,cc +34b53d6,da +34b53d9,4e +34b53da,d2 +34b53dd,d +34b53de,b0 +34b53e1,d +34b53e2,b0 +34b53e5,d +34b53e6,b0 +34b53e9,d +34b53ea,b0 +34b5400,e +34b5401,ff +34b5402,ff +34b5403,f8 +34b5406,b +34b5407,d3 +34b540a,7e +34b540b,70 +34b540d,3 +34b540e,ea +34b5411,b +34b5412,d1 +34b5415,8e +34b5416,50 +34b5418,4 +34b5419,e9 +34b541c,c +34b541d,c0 +34b5420,1f +34b5421,ff +34b5422,ff +34b5423,fa +34b5431,4f +34b5432,fc +34b5435,4f +34b5436,50 +34b5439,4f +34b543a,50 +34b543d,4f +34b543e,50 +34b5441,4f +34b5442,50 +34b5445,4f +34b5446,50 +34b5449,4f +34b544a,50 +34b544d,4f +34b544e,50 +34b5451,4f +34b5452,50 +34b5455,4f +34b5456,50 +34b5459,4f +34b545a,50 +34b545d,4f +34b545e,fc +34b5470,6e +34b5471,50 +34b5474,c +34b5475,b0 +34b5478,7 +34b5479,e3 +34b547d,da +34b5481,9e +34b5482,20 +34b5485,1e +34b5486,90 +34b5489,a +34b548a,d0 +34b548d,3 +34b548e,e8 +34b5492,bc +34b5496,4e +34b5497,60 +34b549a,b +34b549b,c0 +34b54a1,df +34b54a2,e0 +34b54a5,8 +34b54a6,e0 +34b54a9,8 +34b54aa,e0 +34b54ad,8 +34b54ae,e0 +34b54b1,8 +34b54b2,e0 +34b54b5,8 +34b54b6,e0 +34b54b9,8 +34b54ba,e0 +34b54bd,8 +34b54be,e0 +34b54c1,8 +34b54c2,e0 +34b54c5,8 +34b54c6,e0 +34b54c9,8 +34b54ca,e0 +34b54cd,df +34b54ce,e0 +34b54e1,5e +34b54e2,d2 +34b54e5,dc +34b54e6,db +34b54e8,a +34b54e9,d2 +34b54ea,5e +34b54eb,80 +34b54ec,7e +34b54ed,50 +34b54ee,7 +34b54ef,e5 +34b5544,ff +34b5545,ff +34b5546,ff +34b5547,fd +34b554c,2 +34b554d,ca +34b5551,2c +34b5552,90 +34b5590,5 +34b5591,ce +34b5592,eb +34b5593,10 +34b5594,b +34b5595,93 +34b5596,6d +34b5597,a0 +34b559a,b +34b559b,c0 +34b559c,8 +34b559d,de +34b559e,ff +34b559f,c0 +34b55a0,3e +34b55a1,93 +34b55a2,b +34b55a3,d0 +34b55a4,4f +34b55a5,82 +34b55a6,7e +34b55a7,d0 +34b55a8,a +34b55a9,ee +34b55aa,db +34b55ab,d0 +34b55b8,d +34b55b9,90 +34b55bc,d +34b55bd,90 +34b55c0,d +34b55c1,90 +34b55c4,d +34b55c5,90 +34b55c8,d +34b55c9,bd +34b55ca,ec +34b55cb,40 +34b55cc,d +34b55cd,e6 +34b55ce,5d +34b55cf,c0 +34b55d0,d +34b55d1,b0 +34b55d2,8 +34b55d3,e0 +34b55d4,d +34b55d5,a0 +34b55d6,7 +34b55d7,f2 +34b55d8,d +34b55d9,b0 +34b55da,8 +34b55db,e0 +34b55dc,d +34b55dd,e6 +34b55de,4d +34b55df,b0 +34b55e0,d +34b55e1,bd +34b55e2,ec +34b55e3,40 +34b5601,8d +34b5602,ed +34b5603,70 +34b5604,7 +34b5605,e9 +34b5606,36 +34b5607,a0 +34b5608,c +34b5609,c0 +34b560c,d +34b560d,b0 +34b5610,c +34b5611,c0 +34b5614,7 +34b5615,e9 +34b5616,36 +34b5617,a0 +34b5619,8d +34b561a,ed +34b561b,70 +34b562a,b +34b562b,c0 +34b562e,b +34b562f,c0 +34b5632,b +34b5633,c0 +34b5636,b +34b5637,c0 +34b5638,5 +34b5639,de +34b563a,dc +34b563b,c0 +34b563c,d +34b563d,c4 +34b563e,8e +34b563f,c0 +34b5640,5f +34b5641,60 +34b5642,c +34b5643,c0 +34b5644,7f +34b5645,30 +34b5646,b +34b5647,c0 +34b5648,5f +34b5649,60 +34b564a,c +34b564b,c0 +34b564c,d +34b564d,c4 +34b564e,8e +34b564f,c0 +34b5650,5 +34b5651,de +34b5652,dc +34b5653,c0 +34b5670,3 +34b5671,be +34b5672,ec +34b5673,30 +34b5674,c +34b5675,d5 +34b5676,4c +34b5677,c0 +34b5678,4f +34b5679,60 +34b567a,7 +34b567b,e0 +34b567c,6f +34b567d,ff +34b567e,ff +34b567f,f3 +34b5680,4f +34b5681,50 +34b5684,c +34b5685,c5 +34b5686,38 +34b5687,c0 +34b5688,3 +34b5689,be +34b568a,ec +34b568b,60 +34b5699,5 +34b569a,de +34b569b,d0 +34b569d,c +34b569e,b2 +34b56a1,d +34b56a2,90 +34b56a5,e +34b56a6,80 +34b56a8,d +34b56a9,ff +34b56aa,ff +34b56ab,d0 +34b56ad,e +34b56ae,80 +34b56b1,e +34b56b2,80 +34b56b5,e +34b56b6,80 +34b56b9,e +34b56ba,80 +34b56bd,e +34b56be,80 +34b56c1,e +34b56c2,80 +34b56e0,5 +34b56e1,de +34b56e2,dc +34b56e3,c0 +34b56e4,d +34b56e5,c4 +34b56e6,8e +34b56e7,c0 +34b56e8,5f +34b56e9,60 +34b56ea,c +34b56eb,c0 +34b56ec,7f +34b56ed,30 +34b56ee,b +34b56ef,c0 +34b56f0,5f +34b56f1,60 +34b56f2,c +34b56f3,c0 +34b56f4,d +34b56f5,c4 +34b56f6,8e +34b56f7,c0 +34b56f8,5 +34b56f9,de +34b56fa,dc +34b56fb,b0 +34b56fe,c +34b56ff,a0 +34b5700,9 +34b5701,94 +34b5702,7e +34b5703,60 +34b5704,4 +34b5705,ce +34b5706,e9 +34b5708,d +34b5709,a0 +34b570c,d +34b570d,a0 +34b5710,d +34b5711,a0 +34b5714,d +34b5715,a0 +34b5718,d +34b5719,bd +34b571a,ed +34b571b,40 +34b571c,d +34b571d,e6 +34b571e,5d +34b571f,a0 +34b5720,d +34b5721,b0 +34b5722,b +34b5723,c0 +34b5724,d +34b5725,a0 +34b5726,b +34b5727,c0 +34b5728,d +34b5729,a0 +34b572a,b +34b572b,c0 +34b572c,d +34b572d,a0 +34b572e,b +34b572f,c0 +34b5730,d +34b5731,a0 +34b5732,b +34b5733,c0 +34b5741,b +34b5742,c0 +34b5750,9 +34b5751,ff +34b5752,c0 +34b5755,b +34b5756,c0 +34b5759,b +34b575a,c0 +34b575d,b +34b575e,c0 +34b5761,b +34b5762,c0 +34b5765,b +34b5766,c0 +34b5768,e +34b5769,ff +34b576a,ff +34b576b,e0 +34b5779,7 +34b577a,e0 +34b5788,7 +34b5789,ff +34b578a,e0 +34b578d,7 +34b578e,e0 +34b5791,7 +34b5792,e0 +34b5795,7 +34b5796,e0 +34b5799,7 +34b579a,e0 +34b579d,7 +34b579e,e0 +34b57a1,7 +34b57a2,e0 +34b57a5,7 +34b57a6,e0 +34b57a9,1b +34b57aa,d0 +34b57ac,d +34b57ad,fe +34b57ae,70 +34b57b0,b +34b57b1,c0 +34b57b4,b +34b57b5,c0 +34b57b8,b +34b57b9,c0 +34b57bc,b +34b57bd,c0 +34b57c0,b +34b57c1,c0 +34b57c2,3d +34b57c3,c2 +34b57c4,b +34b57c5,c3 +34b57c6,db +34b57c8,b +34b57c9,dd +34b57ca,c0 +34b57cc,b +34b57cd,fc +34b57ce,e5 +34b57d0,b +34b57d1,d0 +34b57d2,cd +34b57d3,10 +34b57d4,b +34b57d5,c0 +34b57d6,3d +34b57d7,b0 +34b57d8,b +34b57d9,c0 +34b57da,7 +34b57db,e8 +34b57e8,e +34b57e9,ff +34b57ea,40 +34b57ed,5f +34b57ee,40 +34b57f1,5f +34b57f2,40 +34b57f5,5f +34b57f6,40 +34b57f9,5f +34b57fa,40 +34b57fd,5f +34b57fe,40 +34b5801,5f +34b5802,40 +34b5805,5f +34b5806,40 +34b5809,4f +34b580a,50 +34b580d,e +34b580e,a0 +34b5811,8 +34b5812,ef +34b5813,b0 +34b5830,8d +34b5831,dd +34b5832,ae +34b5833,c0 +34b5834,8e +34b5835,4d +34b5836,c5 +34b5837,e4 +34b5838,8d +34b5839,c +34b583a,b0 +34b583b,e6 +34b583c,8d +34b583d,b +34b583e,a0 +34b583f,e7 +34b5840,8d +34b5841,b +34b5842,a0 +34b5843,e7 +34b5844,8d +34b5845,b +34b5846,a0 +34b5847,e7 +34b5848,8d +34b5849,b +34b584a,a0 +34b584b,e7 +34b5868,d +34b5869,bd +34b586a,ed +34b586b,40 +34b586c,d +34b586d,e6 +34b586e,5d +34b586f,a0 +34b5870,d +34b5871,b0 +34b5872,b +34b5873,c0 +34b5874,d +34b5875,a0 +34b5876,b +34b5877,c0 +34b5878,d +34b5879,a0 +34b587a,b +34b587b,c0 +34b587c,d +34b587d,a0 +34b587e,b +34b587f,c0 +34b5880,d +34b5881,a0 +34b5882,b +34b5883,c0 +34b58a0,4 +34b58a1,ce +34b58a2,eb +34b58a3,20 +34b58a4,c +34b58a5,d5 +34b58a6,6d +34b58a7,a0 +34b58a8,1e +34b58a9,70 +34b58aa,a +34b58ab,d0 +34b58ac,5f +34b58ad,60 +34b58ae,8 +34b58af,e0 +34b58b0,1e +34b58b1,70 +34b58b2,a +34b58b3,d0 +34b58b4,c +34b58b5,d4 +34b58b6,6d +34b58b7,b0 +34b58b8,4 +34b58b9,ce +34b58ba,eb +34b58bb,20 +34b58d8,d +34b58d9,bd +34b58da,ec +34b58db,30 +34b58dc,d +34b58dd,e6 +34b58de,5d +34b58df,b0 +34b58e0,d +34b58e1,b0 +34b58e2,9 +34b58e3,e0 +34b58e4,d +34b58e5,a0 +34b58e6,7 +34b58e7,e0 +34b58e8,d +34b58e9,b0 +34b58ea,8 +34b58eb,e0 +34b58ec,d +34b58ed,e6 +34b58ee,5d +34b58ef,b0 +34b58f0,d +34b58f1,be +34b58f2,ec +34b58f3,40 +34b58f4,d +34b58f5,90 +34b58f8,d +34b58f9,90 +34b58fc,d +34b58fd,90 +34b5910,4 +34b5911,ce +34b5912,dc +34b5913,c0 +34b5914,c +34b5915,c4 +34b5916,7e +34b5917,c0 +34b5918,1e +34b5919,70 +34b591a,c +34b591b,c0 +34b591c,5f +34b591d,60 +34b591e,b +34b591f,c0 +34b5920,2e +34b5921,70 +34b5922,c +34b5923,c0 +34b5924,c +34b5925,c4 +34b5926,7e +34b5927,c0 +34b5928,5 +34b5929,ce +34b592a,db +34b592b,c0 +34b592e,a +34b592f,c0 +34b5932,a +34b5933,c0 +34b5936,a +34b5937,c0 +34b5949,cc +34b594a,de +34b594b,f9 +34b594d,ce +34b594e,83 +34b5951,cb +34b5955,ca +34b5959,ca +34b595d,ca +34b5961,ca +34b5980,4 +34b5981,ce +34b5982,ea +34b5983,10 +34b5984,b +34b5985,d4 +34b5986,5b +34b5987,60 +34b5988,b +34b5989,d4 +34b598c,3 +34b598d,bd +34b598e,db +34b598f,20 +34b5992,4d +34b5993,a0 +34b5994,b +34b5995,94 +34b5996,5e +34b5997,a0 +34b5998,5 +34b5999,ce +34b599a,eb +34b599b,20 +34b59b1,8e +34b59b5,8e +34b59b8,6f +34b59b9,ff +34b59ba,ff +34b59bb,b0 +34b59bd,8e +34b59c1,8e +34b59c5,8e +34b59c9,8e +34b59cd,6e +34b59ce,70 +34b59d1,b +34b59d2,ef +34b59d3,b0 +34b59f0,d +34b59f1,a0 +34b59f2,b +34b59f3,c0 +34b59f4,d +34b59f5,a0 +34b59f6,b +34b59f7,c0 +34b59f8,d +34b59f9,a0 +34b59fa,b +34b59fb,c0 +34b59fc,d +34b59fd,a0 +34b59fe,b +34b59ff,c0 +34b5a00,d +34b5a01,a0 +34b5a02,b +34b5a03,c0 +34b5a04,b +34b5a05,d4 +34b5a06,7e +34b5a07,c0 +34b5a08,5 +34b5a09,de +34b5a0a,db +34b5a0b,c0 +34b5a28,6e +34b5a29,30 +34b5a2a,7 +34b5a2b,e3 +34b5a2c,d +34b5a2d,90 +34b5a2e,b +34b5a2f,c0 +34b5a30,a +34b5a31,d0 +34b5a32,1e +34b5a33,80 +34b5a34,5 +34b5a35,e4 +34b5a36,8e +34b5a37,20 +34b5a39,da +34b5a3a,cb +34b5a3d,9d +34b5a3e,e7 +34b5a41,3e +34b5a42,e0 +34b5a60,e8 +34b5a63,ac +34b5a64,ca +34b5a67,ca +34b5a68,ac +34b5a69,d +34b5a6a,b0 +34b5a6b,e7 +34b5a6c,6e +34b5a6d,3d +34b5a6e,d5 +34b5a6f,e2 +34b5a70,e +34b5a71,ab +34b5a72,ca +34b5a73,d0 +34b5a74,c +34b5a75,e7 +34b5a76,9e +34b5a77,b0 +34b5a78,a +34b5a79,e1 +34b5a7a,5f +34b5a7b,80 +34b5a98,3d +34b5a99,a0 +34b5a9a,b +34b5a9b,c0 +34b5a9c,6 +34b5a9d,e6 +34b5a9e,9e +34b5a9f,40 +34b5aa1,9e +34b5aa2,e7 +34b5aa5,2e +34b5aa6,d0 +34b5aa9,cc +34b5aaa,da +34b5aac,9 +34b5aad,e4 +34b5aae,6e +34b5aaf,70 +34b5ab0,6e +34b5ab1,70 +34b5ab2,9 +34b5ab3,e4 +34b5ad0,6e +34b5ad1,50 +34b5ad2,5 +34b5ad3,e5 +34b5ad4,d +34b5ad5,a0 +34b5ad6,b +34b5ad7,d0 +34b5ad8,9 +34b5ad9,e0 +34b5ada,e +34b5adb,90 +34b5adc,3 +34b5add,e7 +34b5ade,8e +34b5adf,30 +34b5ae1,cc +34b5ae2,cc +34b5ae5,7e +34b5ae6,e7 +34b5ae9,d +34b5aea,e0 +34b5aed,d +34b5aee,a0 +34b5af1,8e +34b5af2,50 +34b5af4,d +34b5af5,ea +34b5b08,b +34b5b09,ff +34b5b0a,ff +34b5b0b,c0 +34b5b0e,5e +34b5b0f,70 +34b5b11,3 +34b5b12,d9 +34b5b15,c +34b5b16,b0 +34b5b19,bd +34b5b1a,20 +34b5b1c,9 +34b5b1d,e4 +34b5b20,d +34b5b21,ff +34b5b22,ff +34b5b23,c0 +34b5b31,6 +34b5b32,de +34b5b33,a0 +34b5b35,b +34b5b36,d3 +34b5b39,c +34b5b3a,b0 +34b5b3d,c +34b5b3e,b0 +34b5b41,5e +34b5b42,a0 +34b5b44,b +34b5b45,fd +34b5b46,20 +34b5b49,7e +34b5b4a,90 +34b5b4d,d +34b5b4e,b0 +34b5b51,c +34b5b52,b0 +34b5b55,c +34b5b56,b0 +34b5b59,b +34b5b5a,d4 +34b5b5d,5 +34b5b5e,de +34b5b5f,a0 +34b5b69,c +34b5b6a,a0 +34b5b6d,c +34b5b6e,a0 +34b5b71,c +34b5b72,a0 +34b5b75,c +34b5b76,a0 +34b5b79,c +34b5b7a,a0 +34b5b7d,c +34b5b7e,a0 +34b5b81,c +34b5b82,a0 +34b5b85,c +34b5b86,a0 +34b5b89,c +34b5b8a,a0 +34b5b8d,c +34b5b8e,a0 +34b5b91,c +34b5b92,a0 +34b5b95,c +34b5b96,a0 +34b5b99,c +34b5b9a,a0 +34b5ba0,b +34b5ba1,ed +34b5ba2,30 +34b5ba5,4e +34b5ba6,90 +34b5ba9,d +34b5baa,a0 +34b5bad,c +34b5bae,a0 +34b5bb1,b +34b5bb2,c4 +34b5bb5,5 +34b5bb6,ef +34b5bb7,a0 +34b5bb9,b +34b5bba,d5 +34b5bbd,c +34b5bbe,b0 +34b5bc1,d +34b5bc2,a0 +34b5bc5,d +34b5bc6,a0 +34b5bc9,5e +34b5bca,80 +34b5bcc,b +34b5bcd,ec +34b5bce,20 +34b5bf0,5d +34b5bf1,ed +34b5bf2,83 +34b5bf3,a7 +34b5bf4,98 +34b5bf5,38 +34b5bf6,de +34b5bf7,c3 diff --git a/data/symbols.json b/data/symbols.json new file mode 100644 index 000000000..0b6f0deb4 --- /dev/null +++ b/data/symbols.json @@ -0,0 +1,40 @@ +{ + "ADULT_INIT_ITEMS": "0348370C", + "ADULT_VALID_ITEMS": "03483718", + "COOP_GET_ITEM": "03481C01", + "EXTENDED_ITEM_DATA": "03482008", + "FAIRY_ITEMS": "03481D05", + "FAIRY_OCARINA_ITEM": "03481D04", + "FONT_TEXTURE": "034B4748", + "INITIAL_SAVE_DATA": "03481800", + "ITEM_OVERRIDES": "03481000", + "ITEM_TABLE": "03482050", + "LIGHT_ARROW_ITEM": "03481D03", + "PENDING_SPECIAL_ITEM": "03482018", + "PENDING_SPECIAL_ITEM_END": "0348201B", + "PLAYER_ID": "03481C00", + "PLAYER_NAMES": "03481C03", + "PLAYER_NAME_ID": "03481C02", + "PLAYER_OVERRIDE_DATA": "03482000", + "TIME_TRAVEL_SAVED_EQUIPS": "0348201C", + "cfg_dungeon_info_enable": "034B46F8", + "cfg_dungeon_info_mq_enable": "034B471C", + "cfg_dungeon_info_mq_need_map": "034B4718", + "cfg_dungeon_info_reward_need_altar": "034B4710", + "cfg_dungeon_info_reward_need_compass": "034B4714", + "cfg_dungeon_is_mq": "034B4728", + "cfg_dungeon_rewards": "034B45A8", + "cfg_file_select_hash": "034B4724", + "dungeon_count": "034B46FC", + "dungeons": "034B45CC", + "font_sprite": "034B4668", + "hash_sprites": "034B4700", + "hash_symbols": "034B46B8", + "heap_next": "034B4720", + "items_sprite": "034B4688", + "medal_colors": "034B45B8", + "medals_sprite": "034B4698", + "quest_items_sprite": "034B4678", + "setup_db": "034B4738", + "stones_sprite": "034B46A8" +} \ No newline at end of file diff --git a/data/title.bin b/data/title.bin new file mode 100644 index 000000000..4c566cef8 Binary files /dev/null and b/data/title.bin differ diff --git a/table.txt b/table.txt index 6dbe5e664..2ac97b8b9 100644 --- a/table.txt +++ b/table.txt @@ -1 +1 @@ -00000000001111100000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111101010101010101010101010101010101010101010101010101010101010101011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111010000000000000000 \ No newline at end of file +00000000001111100000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111101010101010101010101010101010101010101010101010101010101010101011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110010000000000000000 \ No newline at end of file diff --git a/version.py b/version.py new file mode 100644 index 000000000..e27481bf7 --- /dev/null +++ b/version.py @@ -0,0 +1 @@ +__version__ = '2.23.6 f.LUM'